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

Термостат на ESP32 с удаленным управлением. Часть 10. Охранно-пожарная и аварийная сигнализация

Добрый день, уважаемые читатели!

В данной статье я расскажу как подключить к вашему проекту на ESP32 и ESP-IDF модуль reAlarm, и тем самым добавить в него функции охранно-пожарной и аварийной сигнализации. Данная статья является логичным продолжением и завершением серии статей “Термостат + ОПС”, но никто не запрещает вам применить его и в других ваших проектах. Краткое содержание предыдущих серий:

 


Концепция библиотеки reAlarm

Для начала определимся с терминами и понятиями, которые будут использоваться в дальнейшем в данной статье. А заодно разберемся с принципами функционирования библиотеки на текущий момент времени.

Дисклеймер.

  1. Все, что описано в данной статье – применимо в первую очередь для частных домовладений и квартир, где пока что не требуется обязательная установка только сертифицированных устройств охранно-пожарных сигнализаций, лицензирование и контроль со стороны соответствующих “органов”.
  2. Все что вы делаете – исключительно на ваш страх и риск, я не могу дать никаких предварительных гарантий в ваших самодельных конструкциях и прошивках.
  3. Я не являюсь профессиональным монтажником или инженером ОПС, поэтому некоторые фразы или термины могут показаться профессионалам из данной области некорректными или неуместными. Что ж, в этом случае можете поправить меня в комментариях.

 

Используемые датчики или сенсоры

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

Это могут быть:

  • Герконы или датчики дверей и окон, ворот и т.д. которые размыкаются при открытии окна или двери
  • PIR-датчики движения для обнаружения движения теплых объектов внутри охраняемых помещений
  • Датчики протечки, уровня воды, угарного и горючих газов – то есть датчики для контроля технического состояния инженерных коммуникаций дома
  • Датчики дыма и открытого пламени – позволяют своевременно обнаружить пожар и принять меры к его ликвидации (или хотя бы к эвакуации)
  • Датчики контроля сетевого напряжения – позволяют обнаружить пропадание основного сетевого питания дома или квартиры
  • Кнопки от дверных 433-MHz звонков – можно использовать как тревожные кнопки, либо просто прислать уведомление на телефон

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

Проводные датчики подключаются к входам устройства путем двухпроводного или трехпроводного шлейфа. Количество проводных датчиков ограничено только наличием свободных GPIO на вашем микроконтроллере, а также можно задействовать расширители различные GPIO. Поддерживаются как нормально замкнутые датчики, так и датчики с нормально разомкнутым выходом. Питание датчиков не зависит от напряжения питания микроконтроллера – например это могут быть стандартные промышленные 12-вольтовые PIR. Если рассматривать устройство “Термостат + ОПС”, то схема подключения проводных датчиков выглядит следующим образом:

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

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

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

В качестве датчиков так же могут выступать различные беспроводные пульты управления для переключения режима охраны – но учтите, что их довольно легко перехватить и имитировать. Впрочем, в подавляющем большинстве китайских WiFi и GSM-сигнализаций беспроводные 433 МГц датчики и пульты используются вообще без зазрения совести. Да и от деревенских синяков, ищущих чем-бы поживиться на вашей даче, уж точно защитят.

Также вы можете использовать в качестве датчиков множество DIY-модулей с AliExpress, как пяти-вольтовых, так и трех-вольтовых, при условии соответствующего подключения к микроконтроллеру. Здесь всё зависит только от вашей фантазии и бюджета.

Виртуальные датчики. Кроме датчиков, которые подключены тем или иным способом к вашему устройству, библиотека позволяет использовать данные с других “умных” устройств, созданных по той же самой технологии. Для этого можно использовать разные способы обмена данными между ESP, но проще всего – использовать локальный MQTT-брокер со специальными скрытыми  от внешних систем топиками. Это позволяет задействовать в работе “центрального пульта” сенсоры, которые физически подключены к другому контроллеру. А так же передавать данные о сигналов с датчиков на другие устройства. Локальный MQTT брокер позволяет сделать это с минимальными задержками, даже есть отсутствует доступ к “глобальному” интернету. 

Например, у меня имеется несколько относительно автономных устройств: в доме, в гараже, в бане, в теплице. Все они подключены к моей локальной сети и локальному брокеру, который запущен на домашнем роутере. Да, использование wifi-это не 100% надежно, но зато очень просто и очень легко. Но потребуется предпринять дополнительные меры по поддержанию бесперебойной работы роутера.

В гараже установлены несколько проводных датчиков движения и датчики двери и подъемных ворот. Контроллер гаража использует данные с них для управления освещением. Но вместе с этим, сигналы с этих датчиков одновременно передаются на центральное устройство, которые выполняет функции ОПС (кроме прочих). Получается, что одни и те же датчики одновременно используются для двух совершенно разных целей – автоматики освещения и охраны. Там же есть датчики дыма, сигналы с которых так же передаются на центральный “пульт” дома.

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

 

Сигналы (сообщения) с датчиков

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

  • alarm (тревога) – это сигнал на пульт о любом событии, на которое рассчитан ваш датчик: открытие двери, движение в зоне охраны, нажатие кнопки, дым, протечка воды и т.д.
  • alarm cancel – отмена (сброс) тревоги – сигнал о восстановлении спокойствия: закрытие двери, устранение протечки, восстановление нормального процесса и т.д. 
  • tamper – сигнал о попытке вскрытия или повреждения датчика или шлейфа охраны
  • low power – низкий уровень заряда батареи – для устройств с автономным питанием
  • и  т.д.

Как правило, “отмена тревоги” генерируется только проводными датчиками (например самыми обычными герконами или концевиками), поэтому в беспроводных сенсорах сброс тревоги происходит автоматически спустя какое-то время по таймеру. Иногда необходимо сбросить сам датчик после сигнала тревоги путем кратковременного снятия питания – например для пожарных датчиков, что также может делаться автоматически.

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

 

Зоны охраны

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

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

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

Список зон вы можете расширить или изменить по своим вкусам и понятиям. Разные сигналы одного и того же датчика можно направлять в разные зоны с разными типами реакции.

 

Режимы работы

На текущий момент библиотека поддерживает четыре режима работы:

  • ASM_DISABLED  – Режим охраны отключен. Реакции на датчики движения внутри охраняемой зоны и по её периметры (двери, окна) – нет. Инженерные и пожарные датчики обрабатываются в полном объеме.
  • ASM_ARMEDПолный режим охраны. Система реагирует на сигналы любых датчиков, подключенных к устройству тем или иным способом. При нарушении включается сирена и световой маячок.
  • ASM_PERIMETERРежим охраны периметра. Система не реагирует на датчики, установленные внутри охраняемого помещения, однако двери и окна охраняются как при полном режиме охраны. Инженерные и пожарные датчики обрабатываются в полном объеме.
  • ASM_OUTBUILDINGSРежим охраны внешних помещений. Для постановки на охрану только внешних строений, например гаража. Инженерные и пожарные датчики обрабатываются в полном объеме. Вот честно говоря, сам не пользовался ни разу. 

Переключать режимы охраны можно:

  • С помощью MQTT панели управления со смартфона или компьютера
  • С 433 МГц радиопульта
  • С помощью кнопочной станции на панели управления устройством (опционально)

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

 

Оповещения о событиях

Предусмотрены несколько типов оповещений о событиях:

  • Сирена 12в
  • Световой маячок 12в
  • Уведомления в telegram

Сирена включается только в режиме тревоги на заданное время (например 3 минуты). При включении и отключении режима охраны выдается несколько коротких звуковых сигналов – для индикации переключения режима. Сирену можно отключить удаленно, если не вы хотите беспокоить соседей, например.

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

Уведомления в telegram отправляются в группу, в которую вы можете включить всех заинтересованных лиц. Например так:

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

 

Типы реакции на события

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

  • ASR_ALARM_INC – Увеличить счетчик тревог
  • ASR_ALARM_DEC  – Уменьшить счетчик тревог
  • ASR_MQTT_EVENT  – Публикация события на MQTT
  • ASR_MQTT_STATUS – Публикация состояния охраны на MQTT
  • ASR_TELEGRAM – Уведомление в Telegram
  • ASR_SIREN – Включить сирену
  • ASR_FLASHER – Включить маячок
  • ASR_BUZZER – Звуковой сигнал на пульте
  • ASR_RELAY_ON – Включить реле (нагрузку)
  • ASR_RELAY_OFF – Выключить реле (нагрузку)
  • ASR_RELAY_SWITCH – Переключить реле (нагрузку)

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

// "Стандартные" наборы реакций
ASRS_NONE         = 0x0000; // Никакой реакции (по умолчанию)
ASRS_CONTROL      = ASR_MQTT_EVENT | ASR_MQTT_STATUS;
ASRS_REGISTER     = ASR_MQTT_EVENT | ASR_MQTT_STATUS;
ASRS_ONLY_NOTIFY  = ASR_MQTT_EVENT | ASR_MQTT_STATUS | ASR_TELEGRAM;
ASRS_FLASH_NOTIFY = ASR_MQTT_EVENT | ASR_MQTT_STATUS | ASR_TELEGRAM | ASR_FLASHER;
ASRS_ALARM_NOTIFY = ASR_ALARM_INC | ASR_MQTT_EVENT | ASR_MQTT_STATUS | ASR_TELEGRAM | ASR_BUZZER;
ASRS_ALARM_SILENT = ASR_ALARM_INC | ASR_MQTT_EVENT | ASR_MQTT_STATUS | ASR_TELEGRAM | ASR_BUZZER | ASR_FLASHER;
ASRS_ALARM_SIREN  = ASR_ALARM_INC | ASR_MQTT_EVENT | ASR_MQTT_STATUS | ASR_TELEGRAM | ASR_BUZZER | ASR_SIREN | ASR_FLASHER;
ASRS_POWER_ON     = ASR_MQTT_EVENT | ASR_MQTT_STATUS | ASR_TELEGRAM | ASR_FLASHER;
ASRS_POWER_OFF    = ASR_ALARM_INC | ASR_MQTT_EVENT | ASR_MQTT_STATUS | ASR_TELEGRAM | ASR_BUZZER | ASR_FLASHER;

Таким образом ASRS_NONE означает полный игнор, ASRS_ONLY_NOTIFY – только уведомления в telegram,  ASRS_ALARM_SILENT – тихую тревогу без сирены, а ASRS_ALARM_SIREN – тревогу по полной программе, с сиреной, блекджеком и …

 

С концепцией разобрались, переходим к практической части – добавим в наш проект соответствующие функции.

 


Подключаем библиотеку к проекту

Все настройки датчиков, зон охраны и реакций на них осуществляются только программистом на этапе создания прошивки. Никаких экранных меню, web-интерфейсов и прочих способов настройки системы охраны в run-time не предусмотрено (и не будет предусмотрено в моем варианте исполнения). Я не вижу никакой необходимости усложнять прошивку, добавлять сохранение всех этих параметров на flash, и кроме того, выполнять эти настройки не очень удобными способами. При необходимости внесения изменений мне гораздо проще внести изменения сразу в программный код и обновить устройство посредством OTA-технологии из любой точки, где есть интернет. Это и проще, и экономичнее, и быстрее, и зачастую удобнее.

Итак, приступим.

Первым делом нужно добавить ещё одну “локальную библиотеку” (подкаталог) в наш проект. В ней мы создадим файл, в котором и будет производиться вся настройка системы охраны и технического контроля помещений. Назовем эту “библиотеку” – security.cpp, а хедер к ней – security.h. Каталог, соответственно, можно назвать security:

В них объявим одну единственную функцию (пока пустую), которая и будут производить всю работу (один раз при запуске устройства), например так:

Саму эту функцию мы рассмотрим ниже, а пока не забудем добавить её в void app_main(void):

Кроме того, нам потребуются некоторые новые константы, которые необходимо добавить в project_config.h:

Кликните для увеличения

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

Далее нам необходимо запустить задачу (её код уже написан в недрах библиотеки) и настроить “оборудование”, которое будет работать в нашей системе – сирену, маячок, приемник 433 Mhz. Для этого напишем такую функцию:

Кликните для увеличения

Вызов этой функции добавим в ранее созданную void alarmStart().

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

 


Настраиваем зоны охраны и контроля

Вначале нам необходимо определить зоны охраны и настроить реакции в различных режимах работы. Делается это с помощью функций alarmZoneAdd() и alarmResponsesSet().

Добавить зону в список не просто, а очень просто: alarmZoneHandle_t zoneVariable = alarmZoneAdd("Понятное имя зоны", "topic", callback);

Например, это может выглядеть так:

Топик в данном случае – только часть полного топика устройства, полный топик будет сформирован автоматически библиотекой. Последний параметры – указатель на функцию обратного вызова для управления реле или иной нагрузкой, в общем случае в ней нет необходимости.

Далее нам необходимо настроить реакции для данной зоны для всех четырех режимов работы:

Пример использования:

То есть для данной зоны:

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

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

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

 


Добавляем датчики охраны и контроля инженерных систем

Как я уже писал выше, датчики могут быть трех типов – проводные, беспроводные и виртуальные. Причем проводные могут быть подключены через встроенные GPIO микроконтроллера и через расширители GPIO. А могут быть пожарные дымовые датчики, которые необходимо сбрасывать после срабатывания. 

После настройки зон уже можно добавлять в систему сами датчики с помощью функции alarmSensorAdd(alarm_sensor_type_t type, const char* name, const char* topic, bool local_publish, uint32_t address):

Тип датчика должен быть может принимать значения:

  • AST_WIRED – проводная зона (любого типа)
  • AST_RX433_GENERIC – беспроводной сенсор, без выделения команд
  • AST_RX433_20A4C – беспроводной сенсор, общая длина кода 24 бит: 20 бит – адрес, последние 4 бита – команда
  • AST_MQTT – виртуальный сенсор, получение данных с других устройств через локальный MQTT брокер

После этого необходимо настроить события (команды) для этого датчика. Всего можно добавить до 4 событий включительно, но для проводных датчиков он всегда один (даже если ваш датчик имеет tamper – в этом случае его следует настроить как отдельный gpio датчик). Делается это с помощью следующей другой функции:

Некоторые параметры, возможно, требуют особого пояснения:

  • type определяет, какого типа сигнал мы получили: тревога, tamper, нажатие кнопки на пульте и т.д.
  • value_set и value_clear – определяют логические уровни для установки и снятия тревоги, а для беспроводных датчиков – это коды сообщений (команд).
  • message_set и message_clr – сообщения для отправки уведомлений в telegram при получении данного события (в режиме охраны, разумеется), например
    #define CONFIG_ALARM_EVENT_MESSAGE_MOTION "? Обнаружено движение".
  • timeout_clr – если ваш датчик не может уведомлять об сбросе тревоги (например для беспроводных датчиков), то можно добавить таймер для автоматической отмены тревоги спустя заданное время в миллисекундах
  • alarm_confirm – если вы хотите настроить датчик так, чтобы он вызывал тревогу только после подтверждающих сигналов с этого же или других датчиков в течение заданного времени – это позволит минимизировать ложные тревоги.

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

 


Подключение проводных датчиков ко встроенным GPIO микроконтроллера

Рассмотрим подключение проводных датчиков к встроенным GPIO микроконтроллера. Можно использовать датчики и устройства как с нормально-замкнутыми контактами, так и с нормально-разомкнутыми (но на разных GPIO, разумеется). В данном случае вы можете использовать:

  • дверные и оконные датчики на основе геркона и магнита, либо любые концевые выключатели
  • промышленные PIR-датчики движения, которые используются в промышленных ОПС, например Paradox
  • DIY-модули с AliExpress, например те же самые датчики движения, датчики ИК-излучения (пламени), лазерные датчики и т.д. и т.п. – то есть любые DIY-модули с цифровым выходом
  • можно использовать выходы “сухой контакт” промышленных сенсоров, например газовых сигнализаторов.

В простейшем случае GPIO-входы можно защитить только RC-фильтром; для промышленных 12-вольтовых ОПС-датчиков я рекомендую такую схему, она позволяет согласовать уровни и не спалить микроконтроллер при случайном замыкании сигнального провода шлейфа на +12в:

 

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

Здесь мы указали номера выводов, к которым будут подключены проводные датчики, и их активный уровень – в данном примере он одинаков для всех выводов сразу #define CONFIG_GPIO_ALARM_LEVEL 0x01. Затем необходимо настроить эти GPIO с помощью метода initGPIO().

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

Для примера я настроил проводные входы как (вы это сможете найти в примере прошивки с комментариями): 

  1. Датчик двери
  2. PIR-датчик
  3. Подключение к выходу промышленного газосигнализатора
  4. Контроль наличия питания 220В
  5. Контроль уровня напряжения на аккумуляторе (только низкий уровень)

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

 


Подключение проводных датчиков через I2C расширитель входов

Однако встроенных GPIO иногда не хватает для всех хотелок. На помощь придут I2C-расширители входов, например MCP23017. Про них я уже писал ранее на данном сайте.

Вначале необходимо объявить экземпляры драйверов для MCP23017 и GPIO, которые будут использоваться для обработки прерываний от этих расширителей. Например у меня их сразу два:

Затем напишем обработчик прерываний для gpioIsrZones1 и gpioIsrZones2, он общий для всех микросхем:

Теперь осталось добавить настройки расширителей в alarmInitDevices():

Теперь прерывания с этих микросхем будут перенаправляться в общий поток ввода, как и для обычных GPIO, и мы сможем их использовать почти также, как и в предыдущем случае: 

Основное отличие – адрес сенсора “кодируется” с помощью макроса #define CONFIG_ALARM_IOEXP_SENSOR(bus, address, pin) ((((bus)+1) << 16) | ((address) << 8) | (pin)),  то есть в нём зашит номер шины и адрес микросхемы и собственно номер её вывода. Это позволяет однозначно определить, с какого именно вывода поступил сигнал.

 


Подключение проводных дымовых датчиков со сбросом по питанию

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

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

Обработчики событий для таймеров:

В заключении в настройках зоны указываем callback-функцию для запуска функции сброса:

 


Подключение беспроводных датчиков 433 МГц

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

Как правило, кодовая посылка с такого датчика приходит в виде сообщения длиной 24 бит, причем 20 бит – это адрес собственно датчика, а последние 4 бита – это собственно полезный сигнал или команда. Сами датчики в данной статье я рассматривать не собираюсь – так как их много разных, и у разных датчиков разные команды и возможности.

При получении кодовой посылки она также, как и сигналы с GPIO, автоматически направляется в общий входной поток данных ОПС и там обрабатывается. Как это происходит – в рамках данной статьи я описывать также не буду, если интересно – загляните в недра библиотеки. Рассмотрим только их настройку.

Прежде чем вы добавить датчик в систему, вы должны узнать адрес данного датчика и какие команды он может выдать. Узнать адрес датчика можно и из отладочного вывода c com-порта устройства: 09:12:04 [W] ALARM :: Failed to identify RX433 signal [0x004D1D09]!, но вот со списком поддерживаемых команд сложнее. Некоторые датчики умеют передавать только сигнал тревоги, некоторые – дополнительно сигнал tamper и (или) предупреждение о низком уровне заряда батареи питания. Их определить можно только либо из данных производителя, либо опытным путем – вскрывая датчик и (или) изменяя его напряжение питания и следя за кодами. В следующих статьях я постараюсь рассмотреть некоторые из популярных датчиков, которые попадали мне в лапы.

А пока рассмотрим только процесс добавления оных в прошивку:

Основные отличия от рассмотренных ранее проводных датчиков здесь следующие:

  • Тип датчика теперь другой, и вместо номера вывода мы теперь должны указать его адрес
  • Датчик теперь поддерживает сразу две команды – 0x09 и 0x0D
  • Но “отменять” команды он уже не умеет, и вы должны сделать это с помощью таймера (при повторных сигналах с датчика таймер “сдвигается”)
  • Разные команды с одного и того же датчика могут (но не обязаны) быть включены в разные зоны (для разных реакций).

 


Подключение беспроводных пультов управления 433 МГц

Настройка беспроводных пультов управления 433 МГц осуществляется очень похожим образом, так как принцип передачи команд собственно тот же самый.

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

 


Подключение виртуальных датчиков

Под виртуальными датчиками в данном понимаются датчики, подключенные к какому-либо другом устройству; сигнал с которых передается в ОПС с помощью MQTT-брокера (или иным способом). Я делаю это так:

  • Добавляю в систему фиктивные параметры без сохранения значений в памяти – это позволит MQTT-клиенту подписаться на нужные локальные топики
  • Добавляю подписчика на события изменения данных параметров
  • При получении события отправляем его в недра библиотеки с помощью alarmPostQueueExtId

Например: у меня имеется два “внешних” датчика движения, которые изначально не были связаны с ОПС:

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

Приспособим их для функций сигнализации:

Разумеется, вначале нужно сделать так, чтобы устройство в вытяжке и в санузле публиковали данные с сенсоров в нужные топики.

Далее пишем функцию подписчика:

И в конце регистрируем все это:

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

 


MQTT-топики

Теперь можно скомпилировать код и залить его в наше устройство. Если все прошилось успешно, то вы получите кучку новых топиков, например так:

Основные топики системы ОПС “вынесены за пределы” устройства, то есть начинаются они не с location/device/, а просто location/. Сделано это так потому, чтобы иметь единую систему управления, если по каким либо причинам придется разделить ОПС на несколько разных ESP32. Но это поведение можно изменить с помощью макроса CONFIG_ALARM_MQTT_DEVICE_MODE в project_config.h, который мы и добавили ранее.

Итак, для локации dzen топики будут такими:

  • dzen/config/security/mode – этот топик отвечает за текущий режим работы, здесь его можно посмотреть и изменить при необходимости (без топика подтверждения)
  • dzen/security/events/… – сюда публикуются данные с сенсоров ОПС
  • dzen/local/security/… – сюда публикуются данные с сенсоров ОПС для передачи на другие устройства в пределах локальной сети

В примерах дублирование данных в  dzen/local и dzen/security кажется излишним, но это только потому, что в примере настроен только один публичный сервер MQTT. Для локального брокера картина другая, топики dzen/local не покидают пределов локальной сети (мост на них не реагирует).

Данные в топики сенсоров попадают в “открытом” виде – только статус, и в виде JSON-пакетов с дополнительными атрибутами, например:

  • dzen/local/security/indoor/room1/pir/alarm/json – {“status”: 0,“time”: “03.03.2024 10:55:15”,“time_short”: “03.03.24 10:55”,“unixtime”: 1709452515,“count”: 1}
  • dzen/local/security/indoor/room1/pir/alarm/status – 0 или 1 

Соответственно, топики /status – это машиночитаемые топики, а /json – для настройки на клиенте.

 

Топики дополнительных настроек (как обычно, с подтверждением /config/… + …/confirm/…):

  • dzen/thermostat/config/security/buzzer – разрешить звуковые сигналы на встроенном зуммере
  • dzen/thermostat/config/security/confirmation – время в миллисекундах для подтверждения тревоги, например 60000 – 60 секунд
  • dzen/thermostat/config/security/exit_time – время выхода из помещения в секундах до постановки на охрану, по умолчанию 60 секунд
  • dzen/thermostat/config/security/fix_433_codes – сохранять новые коды RX433 в специальных топиках для “удаленного” поиска новых датчиков, но все “ошибки” тоже будут попадать в этот список
  • dzen/thermostat/config/security/flash_duration – длительность мигания светового маячка в секундах
  • dzen/thermostat/config/security/siren_duration – длительность звуковой сирены в секундах
  • dzen/thermostat/config/security/silent_enabled – разрешить тихий режим для сирены (не включать сирену в указанный ниже период времени)
  • dzen/thermostat/config/security/silent_period – временной интервал для тихого режима сирены

 


Настройка MQTT-клиента

На текущий момент я использую для управления своими устройствами mqtt dash. Про него я писал уже не раз, я думаю вам не составит труда настроить клиент под описываемое устройство.

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

var sJSON = event.getLastPayload();
if (sJSON != '') {
  var data = JSON.parse(sJSON);

  // Формируем текст состояния из трех строк: статус, 
  // последний активный сенсор (или пульт) и время его сработки
  event.text = data['status'] + '\n'
             + data['event']['sensor'] + '\n'
             + data['event']['time_short'];

  var iMode = data['mode'];
  if (iMode == 0) {
    // Охрана отключена
    if (data['annunciator']['summary'] > 0) {
      // Тревога по зонам 24 в настоящий момент
      event.textColor = '#FF0000';
      event.blink = true;
    } else {
      // Тревоги нет, всё тихо
      event.textColor = '#9ACD32';
      event.blink = false;
    };
  } else {
    // Мигание, если были зафиксированы тревоги с момента последнего включения
    if ((data['alarms'] > 0) || (data['annunciator']['summary'] > 0)) {
      event.textColor = '#FF0000';
      event.blink = true;
    } else {
      event.textColor = '#FFFF00';
      event.blink = false;
    };
  };
} else {
  // Нет данных
  event.text = 'Устройство выключено или не доступно';
  event.textColor = '#FF0000';
  event.blink = true;
};

 

Есть еще небольшая “хитрость” – я использую ещё один простой JavaScript-ик для более “красивого” отображения состояния всех датчиков на отдельной вкладке:

 


Как заменить пассивный зуммер на активный

Изначально схема была рассчитана на пассивный зуммер, то есть такой, который сам по себе при подаче напряжения могут только щелкать. Чтобы заставить такой зуммер звучать – необходимо подавать на него импульсы с заданной частотой и скважностью. Этим занимается библиотечка reBeep посредством LEDC API ESP32 (по сути это просто PWM).

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

Во первых – нужно закомментировать макрос CONFIG_GPIO_BUZZER 13 и заменить его на #define CONFIG_GPIO_BUZZER_ACTIVE 13.

Во вторых, дабы пищалка могла звучать не непрерывно, а “импульсами”, добавим для её управления тот же объект, что и для управления светодиодами. Я это сделал в той же функции настройки устройств ОПС, но можно и main.cpp это сделать, например. А затем не забыть передать указатель на входящую очередь светодиода в функцию запуска задачи:

Вот в общем-то и всё, этого достаточно.

На этом я завершаю цикл “Термостат+ОПС”, однако если я чего-то забыл – материал, возможно, будет дополнен.

 


На этом разрешите откланяться, надеюсь материал был вам полезен. С сами был Александр aka kotyara12. Благодарю за внимание.

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


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

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

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