Перейти к содержимому

Термостат на ESP32 с удаленным управлением. Часть 5. Добавляем выгрузку данных на внешние сервисы

Добрый день, уважаемый читатель! В прошлых статьях я рассказывал, как собрать устройство телеметрии на базе микроконтроллера ESP32 DevKitC WROOM-32x и фреймdорка Espressif IoT Development Framework. Если вы ещё не знакомы с данными статьями – рекомендую начать с них, иначе может быть непонятно – “что, зачем и почему”.

 

Но данное устройство пока что умеет работать только с протоколом MQTT. Теперь давайте расширим функционал – добавим к нашему устройству функции отправки данных на внешние сервисы для хранения данных и построения графиков:

Вы можете использовать любой из предложенных сервисов или любую их комбинацию, в том числе и все сразу. Ранее я публиковал мини-обзор этих сервисов в другой статье на этом сайте.

Данную статью, в принципе, можно рассматривать не только как продолжение серии про термостат с удаленным управлением, но и как “самостоятельное” руководство по использованию библиотеки reDataSend.

 


Используемая библиотека

Для отправки данных на все три сервиса используется одна и та же библиотека – reDataSend. Я пока что не буду касаться “внутренностей” этой библиотеки, так как для этого придется обсуждать различные тонкости вроде TLS-подключений и HTTPS-запросов. Поэтому в рамках данной статьи рассматривать подробности не будем, пока достаточно понять принцип работы библиотеки.

Перед началом работы (один раз при запуске программы) необходимо инициализировать контроллер с помощью функции dsChannelInit(). При вам потребуется указать:

  • kind – тип контроллера (EDS_OPENMON / EDS_NARODMON / EDS_THINGSPEAK)
  • uid – идентификатор контроллера/канала/устройства, обычно он выдается самим сервисом при создании контроллера (но для народного мониторинга вы можете взять любой случайный)
  • key – ключ доступа к сервису (токен или MAC-адрес)
  • min_interval – минимальный интервал отправки данных на сервис в секундах в нормальном режиме
  • err_interval – минимальный интервал повторной отправки данных на сервис в секундах в случае ошибки

Инициализация – это громкое название для простого добавления указанных выше сведений в общем списке, дабы не указывать их при каждой отправке данных, а также для контроля минимального интервала обращения к сервису (иначе вы запросто можете словить бан от сервиса). Никакого физического обмена данными с сервисом при инициализации не происходит. При всех последующих обращениях к контроллеру вам потребуется указывать только его uid.

Для отправки данных в канал/контроллер заранее подготовьте данные в формате используемого сервиса:

  • для народного мониторинга имена параметров могут быть произвольными, например Tout=10.00&Tin=25.00&...
  • для open-monitoring имена полей обозначены буквой p и номером по порядку: p1=10,00&p2=25.00&...
  • для thing speak используется похожий принцип, но имена полей обозначены словом field: field1=10,00&field2=25.00&...

Никакие дополнительные поля к этим данным добавлять не нужно – библиотека сама добавит идентификатор и токен доступа при отправке.

Пример инициализации устройства для Народного Мониторинга

Затем отправьте подготовленные данные в очередь с помощью функции

bool dsSend(ext_data_service_t kind, uint32_t uid, char *data, bool free_data)

где:

  • data – указатель на строку данных в куче
  • free_data – если указать здесь true, то после добавления задания в очередь строка data будет удалена из кучи, в противном случае вы должны сделать это самостоятельно.

Как работает отправка? После вызова dsSend() данные попадают в исходящую очередь. Если добавление задания в очередь прошло успешно, функция вернет true.

Далее специальная задача проверяет, как давно происходила отправка в этот самый контроллер. Если время превышает минимальный интервал отправки, то делается попытка немедленно отправить данные. Если минимальный интервал ещё не истёк, то данные остаются в очереди. Но если во время ожидания поступят новые данные в этот же самый контроллер, то они будут заменены новыми данными. Этот механизм позволяет отправлять данные в очередь не заботясь об минимальных интервалах отправки.

Но я, как правило, добавляю ещё по одному псевдотаймеру (читай – счетчику) для возможности run-time изменения интервалов отправки с помощью настроек.

 


Народный мониторинг

Для начала, разумеется, необходимо зарегистрироваться на сервисе, если вы это не сделали ранее. Перед подключением устройства к сайту пожалуйста убедитесь, что вы можете добавить устройство, так как лимиты на народном мониторинге довольно жёсткие:

Я могу подключить ещё один прибор

Далее нам потребуется узнать MAC-адрес микроконтроллера. Проще всего его найти, посмотрев список подключенных WiFi устройств на вашем роутере:

В вашем случае интерфейс может быть совершенно другим

Открываем проект, файл project_config.h, и ищем в нем секцию для https://narodmon.ru/. Для подключения отправки данных на сайт необходимо включить всего два параметра:

#define CONFIG_NARODMON_ENABLE 1
#define CONFIG_NARODMON_DEVICE01_KEY "aa:bb:cc:dd:ee:ff"

Например так:

CONFIG_NARODMON_DEVICE01_ID никакого существенного значения не имеет, его можно не изменять. Главное чтобы этот идентификатор отличался от других идентификаторов устройств на внешних сервисах внутри прошивки.

Но это ещё не всё. Теперь нам необходимо написать код для отправки данных на этот сервис. Откройте в редакторе кода файл <каталог_проекта>\lib\sensors\sensors.cpp и найдите в нем функцию задачи void sensorsTaskExec(void *pvParameters). В нем есть несколько секций кода, оформленных макросами #if CONFIG_NARODMON_ENABLE ... #endif

В первой секции происходит инициализация устройства. Пока в прошивке только одно устройство НМ, то здесь ничего корректировать не требуется.

Чуть ниже инициализируются “псевдотаймеры” (на самом деле это простые счетчики тиков) для отправки данных. Здесь тем более ничего делать не нужно.

Ну и наконец, находим третью секцию, которая как раз нам требуется:

По идее, здесь можно тоже ничего не менять, но тогда на народный мониторинг будут отправляться только данные с уличного сенсора. Напомню, у нас в устройстве “по умолчанию” три сенсора – уличный, комнатный и температура теплоносителя. Давайте добавим их все.

Так как НМ позволяет задавать произвольные названия полям запрос, то условимся считать данные с уличного сенсора как Tout и Hout, с комнатного – Tin и Hin, температура теплоносителя – Tboiler. Впрочем, вы можете использовать другие обозначения – как вам более удобно.

Добавим новую переменную char * nmValues для хранения параметров GET-запроса, а затем немного модифицируем код:

Что здесь происходит? Если статус последнего чтения данных с сенсора “НОРМА”, то берем с него обработанные (фильтрованные) значения температуры ( getValue2(false) ) и влажности ( getValue1(false) ) и “склеиваем” с исходной строкой. false в данном означает, что физического чтения данных у устройства не происходит, а берем последние полученные данные.

Что такое rawValue “сырые” и filteredValue “обработанные” значения, я постараюсь рассказать в одной из следующих статей. А пока примите это как данность, что для целей автоматизации, да и для отображения требуется использованием именно filteredValue.

Почему вначале идет влажность, а только потом температура? Потому что так было в драйвере какого-то сенсора от Adafruit, а потом так и закрепилось.

Ок, добавим ещё пару сенсоров:

В итоге, если все сенсоры исправны, получим примерно такую строку для отправки данных:

Tout=-18,78&Hout=87.12&Tin=22,33&Hout=37.88&Tboiler=55.00

Её и отправляем в очередь задачи отправки на сервер с помощью dsSend(). Далее задача отправки сама проверит время последней отправки данных на сайт CONFIG_NARODMON_SEND_INTERVAL и отправит данные.

Осталось скомпилировать прошивку, загрузить её в устройство и дождаться первой отправки данных на сайт. Только после этого вы сможете добавить устройство в свой профиль по заданному MAC-адресу.

 


Open Monitoring

Отправка данных на open-monitoring.online происходит аналогичным образом, отличие состоит в том, что вы можете зарегистрировать на сайте сразу множество контроллеров. Поэтому – ни в чем себе не отказывайте. Более подробно вы можете прочитать об этом в другой статье: https://kotyara12.ru/iot/open-monitoring/

Перво-наперво разблокируем работу с сервисом:

Для работы с open-monitoring.online создадим два отдельных контроллера. На первый мы будем отправлять данные о температуре и состоянии реле, на второй – системную информацию с устройства. Вообще, их можно создать сколько угодно, но для примера вполне достаточно двух.

Создаем контроллер для климатических данных.

Для примера создадим такие поля:

Не забудьте оставить несколько полей “в резерв”, так как потом в этот контроллер добавить поля уже не получится. После сохранения контроллера можно увидеть его идентификатор и код для записи:

Эти данные сохраняем в project_config.h:


Создаем контроллер для служебных данных.

Если вы не стали отключать в настройках проекта проверку доступа в интернет посредством ping-а и желаете отправлять на сервис служебные данные, то вам потребуется создать ещё один специальный контроллер. Но вы вполне можете обойтись без этого, просто отключив опцию CONFIG_OPENMON_PINGER_ENABLE.

Для климатических данных вы могли создавать поля произвольно – какие хотите и в какой хотите последовательности, ведь вы сами формируете HTML-запрос. Для работы библиотеки отправки служебной информации требуется набор полей в строгом формате:

По умолчанию “пингуется” два хоста – google и yandex, поэтому создаем такой контроллер:

Переносим данные этого контроллера в project_config.h:

Теперь нам вновь необходимо написать код для отправки данных. Для отправки служебной информации никакого кода писать не требуется, всё делается автоматически. А вот для климатических данных все делается практически точно так же, как мы обсуждали выше для народного мониторинга:

Разница только в названиях полей и переменных. В дальнейшем мы сможем добавить сюда отправку состояния реле управления климатом.

Компилируем проект, заливаем в устройство и наслаждаемся видами:

Совмещенные графики температуры за последнюю неделю. Видны изменения режима работы котла

При необходимости, вы можете создать ещё несколько контроллеров и организовать отправку из одного устройства сразу в несколько. Не проблема. Только не забудьте добавить данные об этих контроллерах не только в код отправки, но и в блок инициализации.

 


Thing Speak

Ну и в заключение добавим аналогичную отправку данных на буржуинский сервис – ThingSpeak. В принципе, отправка данных на него выглядит абсолютно аналогично, я даже не совсем уверен, стоит ли повторяться. Ну, пусть будет.

Регистрируемся на сервисе thingspeak.com (если у вас ещё нет аккаунта) и создаем новый канал (канал это тоже самое, что и контроллер или устройство). Данный сервис довольно прижимист в бесплатном режиме, поэтому тестовый канал я создать для примера не могу. Но сложного там ничего нет.

Активируем отправку на этот сервис с помощью макроса CONFIG_THINGSPEAK_ENABLE 1, указываем ID канала и токен записи в него:

Допустим набор полей у канала будет таким же, как и в предыдущем случае. По аналогии, добавляем код отправки:

Компилируем проект, загружаем в устройство и проверяем. Если вы всё сделали правильно, можно настраивать виджеты:

Данные с моей персональной метеостанции


 


Где скачать пример?

Как всегда – на GitHub. Только в данном случае нам нужна ветка “02_telemeter_charts” или “master” (в master последнее состояние проекта, со всеми доработками на текущий момент):

На этом пока всё, до встречи на сайте и на dzen-канале!


Все статьи цикла “Термостат и ОПС”:

Прошивка K12 для ESP32 и ESP-IDF:

Дополнительные статьи, которые применимы к любым устройствам, запрограммированным с помощью тех же самых библиотек.


Пожалуйста, оцените статью:
[ 0 из 5, всего 0 оценок ]

1 комментарий для “Термостат на ESP32 с удаленным управлением. Часть 5. Добавляем выгрузку данных на внешние сервисы”

Добавить комментарий для bola online Отменить ответ

Ваш адрес email не будет опубликован. Обязательные поля помечены *