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

Термостат на ESP32 с удаленным управлением. Часть 7. Автоматический контроль диапазонов температуры

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

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

 

На текущий момент данная прошивка “умеет” считывать данные с подключенных сенсоров и отправлять их на различные сервера – MQTT брокер, Open Monitoring или (и) Thing Speak. В данном варианте устройство можно с успехом использовать как устройство телеметрии для дачи, гаража или, скажем, курятника. С помощью него можно периодически проверять температуру в доме и температуру “на выходе” из котла, дабы быть уверенным, что котел не погас и система не разморожена.

Но, согласитесь, не очень удобно всё время “вручную” контролировать заданные параметры температуры. У нас таки умный дом или что?

Гораздо удобнее было бы, если бы могли задать какие-то пороговые значения, и при выходе температуры за пределы заданных диапазонов устройство могло само уведомить вас о возникших проблемах, например посредством Telegram. Это позволит оперативно обнаружить неполадки без необходимости постоянного рутинного “ручного” мониторинга.

Пример уведомлений в выходе параметра из диапазона

Пример уведомлений в выходе параметра из диапазона

Вот этим мы и займемся в данной статье. А заодно я познакомлю вас с одной из своих библиотек – Range Monitor.

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

Немного про гистерезис

Сама по себе логика контроля диапазонов (не только температуры, а и любых других физических параметров – влажности, напряжения, уровня воды и т.д. и т.п.) кажется очень-очень простой – задал границы диапазонов и всё. Это может быть только нижний предел диапазона (ниже которого опускаться нельзя); или только верхний предел (выше которого подниматься не рекомендуется); или же оба сразу. Далее просто сравниваем измеренное значение с заданным с помощью операторов < и > и всё. Как только измеряемая величина вышла за пределы – отправляем уведомление. Все? Да нет, не совсем…

Температура в доме – вещь непостоянная. Я бы даже сказал “ветренная”. Да и не только температура – и влажность, и напряжение и т.д. и т.п. Да и не только в доме – где угодно. За пару секунд температура может “пересечь” заданную вами границу несколько раз “туда” и “обратно”. Совсем не как у Толкиена. Сенсоры, с помощью которых эта самая температура измеряется, так же вещь несовершенная, и дают некую погрешность. Всё это приводит к тому, что при приближении контролируемой температуры к заданной границе могут происходить множественные срабатывания алгоритма контроля, что обязательно приведет к парочке десятков уведомлений, то есть спаму со стороны умного дома. Что нам отнюдь не нужно.

Например мы задали “погоду в доме” не ниже 20 °С. При достижении этой отметки отправляем уведомление – “похолодало, примите меры”. Но при следующем измерении сенсор выдал уже 20.01 °С. И устройство вновь шлет уведомление – “потеплело, расслабьтесь”. А через еще пару секунд – 19,99 °С. И цикл начинается по новой….

Поэтому вводим ещё один параметр – так называемый гистерезис.

Источник: Яндекс Картинки

Источник: Яндекс Картинки

Гистерезис позволяет несколько “сместить” границу в зависимости от того, в каком состоянии находится контролирующая система. Например устройство будет отправлять уведомление при снижении температуры до заданной границы 20°С, а вот при возвращении в заданный диапазон уведомление будет отправлено только при 21°С или даже 23°С. То есть гистерезис по сути позволяет организовать небольшую зону “нечувствительности” в зависимости от состояния. Можно организовать гистерезис:

  • при выходе из диапазона – например отправлять уведомление о снижении температуры при 19°С, а при увеличении температуры – при 20°С
  • при возвращении в диапазон – например отправлять уведомление о снижении температуры при 20°С, а при увеличении температуры – при 21°С
  • симметрично – например отправлять уведомление о снижении температуры при 19,5°С, а при увеличении температуры – при 20,5°С (ну или не симметрично, никто не запрещает, но потребуется еще одна переменная)

 


Закат солнца вручную

Давайте таки уже будем писать наш г… хм, код. Как я уже писал выше, логика контроля диапазонов не представляет собой особых премудростей.

Для начала создадим новый тип – перечисление для хранения текущего состояния системы мониторинга, например так:

Добрый день, уважаемые читатели! Данная статья продолжает цикл статей, посвященных самодельному устройству на базе ESP32 DevKitC WROOM-32x и фреймворка Espressif IoT Development Framework.-4

Затем, само собой, создаем переменные для хранения этого самого состояния, для границ диапазонов и гистерезиса:

Добрый день, уважаемые читатели! Данная статья продолжает цикл статей, посвященных самодельному устройству на базе ESP32 DevKitC WROOM-32x и фреймворка Espressif IoT Development Framework.-5

Ну и осталось написать несложную функцию:

Добрый день, уважаемые читатели! Данная статья продолжает цикл статей, посвященных самодельному устройству на базе ESP32 DevKitC WROOM-32x и фреймворка Espressif IoT Development Framework.-6

Как я и говорил – ничего сложного. Здесь я применил готовую функцию отправки уведомлений в телегу из своих библиотек. Вы тоже можете её легко использовать, раз уж пишете код с использованием этих библиотек.

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

Добрый день, уважаемые читатели! Данная статья продолжает цикл статей, посвященных самодельному устройству на базе ESP32 DevKitC WROOM-32x и фреймворка Espressif IoT Development Framework.-7

Если вам нужен контроль диапазона температуры ещё по одному датчику – повторяем шаги описанные выше. Ровно столько раз, сколько вам требуется, с разными переменными и значениями.

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

 


Используем класс reRangeMonitor

Спустя какое-то время приходит понимание, что уведомления-то они то хорошо, да маловато будет. Например уведомление может и не прийти из-за отсутствия интернета. Хотелось бы зафиксировать время “перехода” значения из одного состояния в другое. А если уж мы фиксируем состояние и время, то хотелось бы публиковать все это добро на MQTT-брокере для отображения всего этого в программе управления.

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

Итак, представляю вам небольшую “классную” библиотечку:

GitHub – kotyara12/reRangeMonitor: Контроль значений (температуры, влажности, напряжения и т.д.) в заданных пределахgithub.com

Какие функции она предоставляет:

  • Хранение текущего состояния (как я описывал выше)
  • Хранение меток времени последнего пересечения заданных границ и возвращения в нормальный диапазон
  • Хранение текущего значения (только для публикации на MQTT-брокере в виде JSON-пакета)
  • Генерацию JSON-пакета со всеми зафиксированными минимумами и максимумами, а также временными отметками для публикации на MQTT-брокере.
  • Хранение динамически созданного MQTT-топика (в моих проектах топики могут изменяться в зависимости от того, к какому брокеру – основному или резервному, подключено в данным момент устройство)
  • Отправка уведомлений осуществляется за счет подключенной callback функции, поэтому вы можете придумать свой способ уведомлений, например на email или в viber, например.

 

Как этим пользоваться

Конструктор класса выглядит следующим образом:

Добрый день, уважаемые читатели! Данная статья продолжает цикл статей, посвященных самодельному устройству на базе ESP32 DevKitC WROOM-32x и фреймворка Espressif IoT Development Framework.-8

Здесь мы сразу же задаем:

  • начальные границы диапазона и гистерезис (их можно будет потом изменить через MQTT-брокер)
  • имя для сохранения внутренних данных в NVS-хранилище
  • функцию обратного вызова для отправки уведомлений при изменении состояния
  • функцию обратного вызова для публикации данных на брокере

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

Перво-наперво объявим статическую переменную, в которой будет храниться указатель на экземпляр класса reRangeMonitor. Здесь я как раз не стал указывать функции обратного вызова, так как переменная объявлена в заголовочном файле h, а все callback-и описаны в cpp. Их я подключу позже.

В данном случае тексты сообщений и некоторые константы вынесены в макросы #define. Это не обязательно, но лично мне так гораздо удобнее. Вы можете поступать по другому и вставлять их прямо в код, как в примере выше

Далее, напишем как раз эти самые функции обратного вызова:

Callback для отправки уведомлений. Выглядит непонятно, а на самом деле это все просто константы из #define выше

Callback для публикации строки на MQTT-брокере

Инициализация мониторинга выглядит следующим образом:

Добрый день, уважаемые читатели! Данная статья продолжает цикл статей, посвященных самодельному устройству на базе ESP32 DevKitC WROOM-32x и фреймворка Espressif IoT Development Framework.-12

Здесь:

  • восстанавливается последнее состояние объекта из NVS-раздела
  • подключаются callback-и
  • регистрируются параметры (границы диапазонов и гистерезис) на MQTT-клиенте. Придуманная мной система управления параметрами выполнит всю необходимую работу, в том числе подписку на MQTT-брокере и хранение данных в NVS-разделе. Об этом я постараюсь рассказать как-нибудь позже, напомните мне, если я забуду.

Ну и осталось немного изменить код проверки внутри основного цикла прикладной задачи:

Добрый день, уважаемые читатели! Данная статья продолжает цикл статей, посвященных самодельному устройству на базе ESP32 DevKitC WROOM-32x и фреймворка Espressif IoT Development Framework.-13

Можно пробовать… Уведомления приходить уже будут (если вы правильно настроили токены telegram бота(ов) в project_config.h.

Но вот на MQTT брокере пока ничего не появится. Это потому, что мы не сгенерировали топик(и) для публикации. Для этого придется создать обработчики системных событий подключения и отключения MQTT-клиента к брокеру:

Обработчик события RE_MQTT_EVENT

Топики могут быть разными в зависимости от того, основной или резервный сервер используется

Регистрируем обработчики

Про циклы событий и как с ними работать, я уже писал ранее: Библиотека циклов событий

Теперь при изменении состояния класс сам опубликует всю доступную ему информацию на брокере (ну и уведомление отправит, само собой). До выхода из границ никакой информации на брокере не появится. Если вы хотите принудительно публиковать данные с заданным интервалом, то можно добавить такую строчку в основной цикл задачи:

Добрый день, уважаемые читатели! Данная статья продолжает цикл статей, посвященных самодельному устройству на базе ESP32 DevKitC WROOM-32x и фреймворка Espressif IoT Development Framework.-17

Ах да… Если вы желаете сохранять состояние и после перезапуска устройства, то нужно вызывать функцию nvsStore(…); перед перезапуском устройства.

Добрый день, уважаемые читатели! Данная статья продолжает цикл статей, посвященных самодельному устройству на базе ESP32 DevKitC WROOM-32x и фреймворка Espressif IoT Development Framework.-18

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

 

 


А что на MQTT-брокере?

На MQTT брокере должны быть вот такие топики (если вы все сделали правильно):

Добрый день, уважаемые читатели! Данная статья продолжает цикл статей, посвященных самодельному устройству на базе ESP32 DevKitC WROOM-32x и фреймворка Espressif IoT Development Framework.-19

Данные из них уже можно извлечь и отобразить в каком-нибудь MQTT Dashboard.

Настройки границ, как им и полагается, расположены в разделе config / confirm:

Добрый день, уважаемые читатели! Данная статья продолжает цикл статей, посвященных самодельному устройству на базе ESP32 DevKitC WROOM-32x и фреймворка Espressif IoT Development Framework.-20

Как я уже писал в предыдущих статьях цикла, здесь общее правило таково:

  • с телефона мы отправляем новые значения в топик device/config/bla-bla-bla, а в ответ мы должны получить то же самое значение в device/confirm/bla-bla-bla. Это позволяет гарантировать, то наши настройки успешно получены устройством и обработаны.

 


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

 

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

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

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

 

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

 


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

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

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