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

Добрый день, уважаемые читатели! Данная статья является в первую продолжением серии “Термостат на ESP32 с удаленным управлением“, но описанное в статье в полной мере относится и к “Автоматической теплице“, и к “Автоматическому поливу“, да и к вообще к любым устройствам автоматики, собранным на ESP32 и запрограммированным с помощью ESP-IDF и моих библиотек для этой платформы. Поэтому  вынес её в “общий” раздел под названием “Прошивка K12 для ESP32“. А поговорим мы в ней о командах управления.

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

  • перезапустить устройство
  • обновить прошивку через технологию OTA
  • сбросить сохраненные данные о зафиксированных минимумах и максимумах для сенсоров
  • выполнить какую-либо другую команду поверх логики встроенного конечного автомата

Конечно, это легко можно сделать, “прикрутив” в прошивку подписки на какие-нибудь специальные “управляющие” топики для каждой команды в отдельности. Но я поступил по другому – создал всего два “специальных” топика, в которые можно отправлять заранее определенные текстовые команды:

  • %location%/%device%/system/terminal – в этот топик можно отправлять текстовые команды управления ( почему именно terminal а не commands? – на момент создания этого функционала топик commands был “занят” под другие команды, но потом я от него избавился совсем; впрочем это можно изменить )
  • %location%/%device%/system/ota – а сюда вы должны отправить ссылку на BIN-файл прошивки для “обновления по воздуху” ( OTA ) в формате “https://server/…/firmware.bin”

где %location%/%device% – параметры-макросы CONFIG_MQTTx_PUB_LOCATION и CONFIG_MQTTx_PUB_DEVICE из файла project_config.h. Про обновление прошивки через OTA поговорим в следующей статье, а в данной обсудим только команды управления, а также как можно добавить свои собственные команды в прошивку.

Поскольку эти топики работают только в одном направлении (на вход), их нельзя увидеть через программу MQTT Explorer.

 


Как это работает?

После запуска микроконтроллера и подключения устройства к MQTT-брокеру, оно “подписывается” на указанный выше топик “%location%/%device%/system/terminal” и ждет новых сообщений. Про поступлении нового сообщения в указанном топике устройство обрабатывает его и само стирает данные из топика, отправив туда NULL. Это является подтверждением того, что команда была получена и обработана должным образом. Дополнительно отправляется сообщение в telegram-канал управления:

 

Вся “физическая” обработка команд реализована в функции paramsExecCmd() в модуле reParams.cpp

Нажмите для увеличения картинки

Для простоты понимания здесь я выделил блоки:

  • синий – отправка сообщения в telegram о получении команды
  • желтый – удаление полученной команды из топика
  • красный – выполнение встроенных команд (пока одна – подробнее см. ниже)
  • зеленый – если команда не встроенная, то отправляем событие RE_SYSTEM_EVENTS.RE_SYS_COMMAND в прикладной цикл событий с текстом полученной команды. Ваше приложение должно подписаться на это событие, получить его и соответствующим образом обработать. Как это сделать – будет рассказано ниже.

 


Встроенные команды

На текущий момент устройства (например термостат) имеют всего одну “встроенную” команду: restart – программный перезапуск устройства.

Получив сообщение с текстом “restart” в топик “…/system/terminal” устройство проведет все необходимые “заключительные процедуры” (например сохранит оперативные данные на флеш-память и отключит нагрузку), а затем выполнит программный сброс через системную функцию esp_restart()

Через какое-то время устройство выполнит указанное действие:

Вот, в общем-то и все “встроенные” команды.

 


Пользовательские команды

Но не все так грустно – вы можете легко и просто добавлять обработчики своих, кастомных команд по своему разумению. Более того, в перечисленных выше прошивках “Термостат“, “Автоматическая теплица” и “Автополив” уже имеются такие “пользовательские команды, даже несколько.

ClrExtr – cброс экстремумов сенсоров

Если вы читали статью про класс rSensor и для чего он нужен, то, наверное, помните, что любой драйвер сенсора или датчика, построенный на базе этого класса, умеет накапливать данные об экстремумах измеренных значений, то есть минимумах и максимумах за текущие сутки, неделю и все время работы. Эти данные сохраняются в энергонезависимой памяти ( NVS ) по при следующем включении устройства будут восстановлены. Но иногда необходимо “сбросить” эти сохраненные данные, например если были получены явно неверные данные по каким-либо причинам. Дабы иметь возможность для такого сброса, предусмотрена специальная “пользовательская” команда – clrextr (CLear EXTRemums), которая уже имеется в прошивках. 

Кроме того, команда clrextr – не совсем простая команда. Она может быть выполнена в нескольких вариантах:

  • clrextr – сброс всех экстремумов у всех датчиков, подключенных к данному устройству
  • clrextr daily – сброс только суточных экстремумов у всех датчиков, подключенных к данному устройству
  • clrextr weekly – сброс только недельных экстремумов у всех датчиков, подключенных к данному устройству
  • clrextr entirely – сброс только абсолютных экстремумов у всех датчиков, подключенных к данному устройству
  • clrextr датчик – сброс всех экстремумов только для конкретно указанного датчика
  • clrextr датчик daily – сброс только суточных экстремумов и только для конкретно указанного датчика
  • clrextr датчик weekly – сброс только недельных экстремумов и только для конкретно указанного датчика
  • clrextr датчик entirely – сброс только абсолютных экстремумов и только для конкретно указанного датчика

Системное имя датчика задается программистом при написании прошивки.

Но почему эта команда не “встроенная”? Дело в том, что заранее никогда не известно сколько и каких датчиков будет подключено к устройству. А “дернуть за хвост” приходится каждый конкретный экземпляр (объект) датчика. Вот и приходится каждый раз копипастить этот код из прошивки в прошивку с необходимыми изменениями. На её примере я и расскажу, как добавлять свои команды при необходимости.

Итак, как я уже рассказал выше, нам нужно подписаться на событие RE_SYSTEM_EVENTS.RE_SYS_COMMAND и обработать его. Для этого напишем функцию: void sensorsCommandsEventHandler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data), затем зарегистрируем её с помощью другой функции eventHandlerRegister(RE_SYSTEM_EVENTS, RE_SYS_COMMAND, &sensorsCommandsEventHandler, nullptr).

Функция – обработчик достаточно громоздкая, но тем не менее, если разобраться, не сложная (картинка кликабельна):

Нажмите для увеличения картинки

Её вы можете более подробно рассмотреть в модуле sensors.cpp. На что здесь стоит обратить внимание:

  • Любые прикрепленные к событию данные будут автоматически уничтожены после того как цикл событий отправит его всем подписчикам. Поэтому стоит создать локальную копию полученной команды-строки с помощью malloc_string((char*)event_data), дабы чего не вышло. Впрочем, наверное я перестраховываюсь.
  • Далее разбиваем полученную строку на токены , разделенные пробелами с помощью системной функции strtok(buf, seps); чтобы получить (возможно) параметры команды – имя сенсора и тип экстремума. А затем уже вызываем соответствующую функцию: sensorsResetExtremumsSensors(mode) для сброса всех сенсоров или sensorsResetExtremumsSensor(&sensorBoiler, SENSOR_BOILER_TOPIC, imode) для конкретного сенсора. Реализации этих дополнительных функций вы можете посмотреть самостоятельно – в них нет ничего сложного, я надеюсь.

А теперь посмотрим как это работает (измените имя датчика на необходимое):

В ответ мы должны получить следующее:

 


Дополнительные команды для теплицы

Наверное, предыдущие пример вам показался ужасно сложным и непонятным. Не расстраивайтесь! Все не так грустно! Просто посмотрите как реализованы дополнительные команды для “полоумной теплицы“:

Вот видите – всё просто – сравнили с “образцом” – выполнили. Только не стоит из обработчика событий выполнять долгие и нудные действия – иначе можете словить малоприятные и н сложно обнаруживаемые глюки – тормоза. Я здесь просто “взвожу” соответствующие флаги в группе событий.

 


Команды ОПС

Забегая вперед, перечислю дополнительные команды для модуля “охранно-пожарная сигнализация” доступны дополнительные команды:

  • alarm off – отключить режим охраны
  • alarm full – включить полный режим охраны
  • alarm perimiter – включить режим охраны только периметра (режим “дома”)
  • alarm garage – включить режим охраны только внешних помещений (если установлены соответствующие зоны)
  • alarm cancel – отменить тревогу (выключить сирену) без отключения режима охраны
  • alarm reset – сбросить счетчик тревог без отключения сирены и изменения режима охраны

Переключить режим охраны можно и другими способами (с пульта 433 Мгц или через MQTT, например), а вот две последние команды можно выполнить только через топик команд system/terminal.

 


А баба Яга против!

А что если мне не нравится название топиков и (или) команд? Что ж, это легко исправить: открываете файл с:\PlatformIO\libs\consts\def_mqtt_commands.h  и исправляете название топика команд по своему разумению:

Ну а сами команды вы можете легко поправить, просто кликнув на соответствующий макрос с клавишей [ctrl]:

 


На этом, пожалуй, на сегодня закончим. Всем добра и до следующих встреч!

💠 Полный архив статей вы найдете здесь


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

Добавить комментарий

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