Работаем с Zigbee-устройствами через Zigbee2mqtt и Node-RED

В первой статье «Облачный умный дом: что нужно знать, чтобы избежать проблем» я рассмотрел преимущества и недостатки облачных решений, а также проблемы, с которыми за последние месяцы пришлось столкнуться пользователям разных облаков. Затем я перешел к практике: приобрел несколько устройств Aqara.

Во второй статье «Слезаем с облачной иглы Aqara и подключаем устройства к контроллеру Wiren Board» я отказался от фирменного облака Aqara, после чего перевел все устройства на контроллер с оболочкой Sprut.hub. Конечно, я прикрутил Алису от Яндекса для сбора статистики и голосового управления.

Настало время следующего этапа — использовать открытые бесплатные решения Zigbee2mqtt и Node-RED. В качестве хаба я возьму контроллер Wiren Board 7 с модулем WBE2R-R-ZIGBEE v. 2, но вы можете использовать любые другие решения, например, отдельный ПК. В таком случае вам понадобится USB Zigbee-стик, а также инструкции по установке, которые можно найти на официальных сайтах Node-RED и Zigbee2mqtt. В остальном приведенные ниже примеры и сценарии отличаться не будут.

Установка модуля Zigbee WBE2R-R-ZIGBEE v. 2

Я установил модуль WBE2R-R-ZIGBEE v. 2 в слот MOD1 контроллера Wiren Board 7, следуя руководству по настройке. Подробно процесс описывать я не буду, чтобы не повторяться.

Модуль Zigbee WBE2R-R-ZIGBEE v.2Модуль Zigbee WBE2R-R-ZIGBEE v. 2

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

Следующий этап — добавление в конфигурацию контроллера. Достаточно перейти в пункт Настройки — Конфигурационные файлы — Модули расширения и порты, после чего для Внутреннего слота 1 указать тип модуля WBE2R-R-ZIGBEE. Обмен данными осуществляется через последовательный порт /dev/ttyMOD1.

Добавляю модуль в интерфейсе контроллера Wiren Board 7Добавляю модуль в интерфейсе контроллера Wiren Board 7

Подключение устройств Zigbee

Следующий этап — подключение устройств Zigbee к контроллеру Wiren Board. Он тоже хорошо описан в руководстве, поэтому пробегусь лишь вкратце.

Сначала следует установить пакет Zigbee2mqtt командой

apt update && apt install zigbee2mqtt

Затем внести рекомендуемые в руководстве настройки в файл конфигурации.

Изменяю файл конфигурацииИзменяю файл конфигурации

Для добавления устройств нам понадобится плагин node-red-contrib-zigbee2mqtt, который я подробнее рассмотрю ниже, в разделе настроек Zigbee2mqtt. После установки плагина нужно развернуть ноду bridge и настроить ее на localhost. 

Ноды Bridge и DebugНоды Bridge и Debug

Напомню, что для получения информации с нод и отладки пригодится нода Debug. Например, она показана на скриншоте выше.

Нода BridgeНода Bridge

Для поиска устройств следует нажать кнопку «Start searching…» справа от Permit Join. Затем на устройствах необходимо инициировать режим сопряжения — удерживать кнопку пять секунд либо «поморгать» лампочкой пять раз.

Список устройств в ноде BridgeСписок устройств в ноде Bridge

При обнаружении устройств нода debug выдаст соответствующее сообщение.  Спустя примерно три минуты устройства будут обнаружены и выведены на вкладке Devices. Я успешно подключил все четыре устройства Aqara и задал им понятные имена Lamp, Socket, Motion Sensor, Temperature Sensor.

Настраиваю Zigbee2mqtt в Node-RED

Node-RED — довольно популярная оболочка, позволяющая с помощью логических блоков создавать сценарии автоматизации и управлять устройствами умного дома. Процесс установки Node-RED на контроллер Wiren Board подробно описан в руководстве, поэтому здесь я на нем останавливаться не буду.

Здесь есть два варианта. Если хотите напрямую работать с командами MQTT, то можно воспользоваться нодами mqtt in и mqtt out. Но гораздо проще настроить автоматизацию через один из популярных плагинов Node-RED. Я выбрал плагин node-red-contrib-zigbee2mqtt. Он позволит перейти от синтаксиса MQTT и JSON напрямую к формату данных JavaScript, привычному для пользователей Node-RED. Также плагин позволяет подключать устройства, смотреть структуру сети Zigbee и просматривать логи моста.

Ноды Zigbee2mqttНоды Zigbee2mqtt

Плагин предлагает четыре ноды: in, get, out, bridge. Удобство в том, что доступные устройства видны в выпадающем списке, а значит, их не нужно вписывать вручную в отличие от нод mqtt in/out. Также данные поступают и отсылаются не в формате строки JSON, а в формате объекта JavaScript, что избавляет от дополнительной ноды JSON.

Нода in, датчик температурыНода in, датчик температуры

Нода in позволяет получать сообщения от моста Zigbee2mqtt, нода out — отсылает команду mqtt на мост Zigbee2mqtt. С ноды in можно получить сразу значение, например, температуры в msg.payload, хотя с тем же успехом можно обрабатывать значение msg.payload.temperature, если выбрать полную выгрузку значений Complete Payload. Также сразу поддерживается формат данных Apple HomeKit.

Нода out, лампаНода out, лампа

Чтобы послать команду на устройство zigbee, следует установить ноду out, выбрать устройство и указать действие. Для лампы, например, сразу доступен выпадающий список с функциями, поэтому здесь тоже не придется разбираться в опциях моста Zigbee2mqtt для каждого устройства и синтаксисе команд JSON.

Нода inject, лампаНода inject, лампа

Для включения лампы я добавил узел Inject с командой ON. Команда OFF выключает лампу, а TOGGLE меняет состояние (включена/выключена).

Несколько нод inject для разных операций с лампойНесколько нод inject для разных операций с лампой

Нода bridge позволяет получить сообщения моста — она идентична MQTT теме zigbee2mqtt/bridge/#. Выше я использовал ноду bridge для добавления устройств. Сквозная нода get выдает последнее состояние устройства и будет полезна в некоторых алгоритмах.

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

Умная лампа Aqara LED Light Bulb, E27, 9Вт

В моей системе я назвал лампу просто Lamp. На странице Xiaomi ZNLDP12LM можно ознакомиться с функциями устройства, поддерживаемыми Zigbee2mqtt.

Используя ноду in с лампы можно получить информацию состояния, например.

Информация состояния лампыИнформация состояния лампы

Здесь можно взять данные о текущей яркости и цветовой температуре, а также состоянии (включена/выключена).

Несколько нод inject для разных операций с лампойНесколько нод inject для разных операций с лампой

Рассмотрим, какие команды можно подавать на лампу плагин out:

  • State — включение/выключение лампы. Варианты payload здесь следующие: ON, OFF или TOGGLE. Первые два включают или выключают лампу, последний меняет состояние между включена/выключена.

  • Brightness — изменение яркости лампы. Необходимо отправить значение яркости от 0 до 254.

  • Color temperature — изменение цветовой температуры в майредах. Отправляем в payload число от 153 до 370: чем выше, тем теплее цвет.

Нода out, лампаНода out, лампа

Для упомянутых функций есть возможность добавления задержки перехода. Она весьма удобна, например, для плавного выключения/включения лампы или постепенного изменения яркости. За функцию отвечает дополнительное поле transition в секундах.

Также весьма удобны функции move и step. Они позволяют выставить скорость уменьшения/увеличения параметра (move), либо изменить его с указанным шагом (step). Например, если выбрать на ноде out значение Color Temperature Mode и указать  значение 10, то цветовая температура будет повышаться с шагом 10 каждую 0,1 с, свет будет становиться более теплым. Значение -10 приведет к плавному снижению температуры и «похолоданию» света.

Если выставить на ноде out значение Brightness Step, то можно будет изменять яркость в диапазоне от 0 до 254, изменяя значения  на 50 или -50, например. 

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

Умная розетка Aqara Smart Plug

Я назвал умную розетку Socket, на странице Xiaomi ZNCZ04LM можно посмотреть функции устройства, поддерживаемые Zigbee2mqtt.

Нода in выводит следующую информацию состояния.

Информация состояния умной розеткиИнформация состояния умной розетки

Здесь можно взять сведения о наличии физически подключенного устройства, мгновенном токе и мощности, состоянии розетки (включена/выключена). Интересно, что у розетки есть датчик температуры — это позволяет контролировать состояния розетки, например, выключать розетку при перегреве или оповещать пользователя.

Нода out, умная розеткаНода out, умная розетка

Через ноду out можно подавать команду включения/выключения розетки state. Варианты payload здесь следующие: ON, OFF или TOGGLE. Первые два включают или выключают розетку, последний меняет состояние между включена/выключена.

Несколько нод inject для разных операций с умной розеткойНесколько нод inject для разных операций с умной розеткой

Датчик влажности и температуры Aqara Temperature and Humidity Sensor

Я назвал датчик влажности и температуры Temperature Sensor, на странице Xiaomi WSDCGQ11LM приведены функции устройства, поддерживаемые Zigbee2mqtt

Нода in позволяет получить с датчика следующую информацию.

Информация состояния датчика влажности и температурыИнформация состояния датчика влажности и температуры

Доступна информация о температуре в градусах Цельсия, влажности в процентах, давлении в гПа.

Датчик движения Aqara Motion Sensor

Я назвал датчик движения Motion Sensor, на странице Xiaomi RTCGQ11LM можно ознакомиться с функциями устройства, поддерживаемыми Zigbee2mqtt.

Вновь воспользуюсь нодой in, чтобы посмотреть доступную информацию датчика.

Информация состояния датчика движенияИнформация состояния датчика движения

Здесь можно получить сведения об определении движения (occupancy — true или false), освещенности в люксах, температуре в градусах Цельсия (в моем случае датчик «врал», показывая температуру на 5 градусов выше).

При определении движения сенсор посылает сообщение occupancy: true, иначе false. Интересно, что после определения движения сенсор «засыпает» на 90 секунд и не меняет статус occupancy. То есть повторное определение движения возможно только через 90 секунд после первого.

Сценарии автоматизации

Настало время внедрить мои сценарии автоматизации.

Включаем обогреватель

Первый сценарий: включение обогревателя, когда температура будет меньше 19 градусов, и выключение, когда она достигнет 23 градуса. Обогреватель я буду подключать через умную розетку, которая поддерживает мощность до 2,3 кВт. Затем остается разместить датчик в наиболее удобном месте комнаты, после чего все сценарии будут работать.

Нода in, датчик температурыНода in, датчик температуры

Первый шаг для сценария — нода in с выбранным датчиком Temperature Sensor и значением температуры в градусах Цельсия. 

Затем я добавил ноду ветвления switch, которая будет анализировать значение температуры msg.payload. Если температура меньше 19 градусов, то мы идем по первой ветке. Если 23 градуса или больше — по второй.

Нода switchНода switch

Обе ветки затем уходят на ноды change, которые меняют msg.payload. В первом случае я включаю обогреватель, поэтому msg.payload выставляется на ON. Во втором случае обогреватель выключается, msg.payload ставится на OFF. Последняя нода out отсылает msg.payload на устройство Socket.

Нода changeНода changeСценарий автоматизации нагревателяСценарий автоматизации нагревателя

Тесты прошли успешно, автоматизация работает.

Включаем лампу в темноте по движению

Второй сценарий: включение лампы по определению движения, если в помещении темно (яркость ниже определенного уровня). Я выставил уровень яркости в 30 люкс, при определении движения лампа включалась.

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

Нода in, датчик движенияНода in, датчик движения

Здесь первым шагом я вновь создал ноду in, указал устройство Motion Sensor. Мне потребуется информация как об освещенности, так и о наличии движения, поэтому я выведу полные сведения Complete Payload. 

Нода switchНода switch

Затем я добавил ветвление на основе msg.payload.illuminance, то есть уровня освещенности. Если освещенность меньше 30 люкс, то иду по первой ветке на проверку движения; если же больше или равно 30, то иду по второй ветке и выключаю лампу с двухминутной задержкой и сбросом задержки при наличии движения. 

Включение/выключение лампы выполняется через msg.payload ON или OFF с последующей отправкой через ноду out c выбранной лампой Lamp.

Нода switchНода switch

Продолжаю идти по первой ветке с яркостью меньше 30 люкс. Следующее ветвление по движению. Если msg.payload.occupancy равно true, то есть движение определено, то иду по первой ветке. В случае отсутствия движения (false) иду по второй. При наличии движения все просто: включаю лампу, отправляя msg.payload ON на ноду out. Если же движения нет, то ставлю задержку на две минуты, после чего выключаю лампу.

Нода changeНода change

Обратите внимание, что я добавил сброс задержки при детектировании движения (msg.reset). Если лампа горит тускло (ниже 30 люмен на датчике), но при этом в помещении есть человек, она не будет постоянно включаться/выключаться через две минуты.

Сценарий автоматизации лампы по датчику движенияСценарий автоматизации лампы по датчику движения

Сценарий успешно работает на практике.

Прикручиваю Алису

Напомню, что Алиса — это не только голосовое управление с помощью Яндекс-колонки, но и автоматизация через приложение «Умный дом». В нем можно управлять устройствами, создавать сценарии и отслеживать статистику показаний датчиков. Я не буду использовать приложение «Умный дом» для облачных сценариев автоматизации, так как у меня работает отличное локальное решение на Node-RED. А вот в качестве опции Алиса пригодится, поскольку добавляет удобное управление через приложение и голос. Подробно процесс добавления Алисы к Node RED описан здесь.

Сначала необходимо установить модуль node-red-contrib-alice. Затем добавить на рабочее поле ноду On/Off и настроить учетную запись Яндекса.

Ноды АлисыНоды Алисы

Затем следует создать виртуальное устройство, я выбрал для примера лампу. Виртуальное устройство Алисы «Лампа» в категории Light принимает на входе true/false, а также отдает true/false.

Управление лампой через АлисуУправление лампой через Алису

Сначала я настроил включение/выключение лампы через Алису. От ноды On/Off Алисы я сделал изменение логических true и false на строки msg.payload ON или OFF, которые отсылаются на ноду out с лампой.

Нода changeНода change

Затем я настроил передачу информации о состоянии лампы. Я установил ноду in с выбранной лампой Lamp и типом payload состояния лампы (ON/OFF). Осталось сделать изменение значений msg.payload ON или OFF на логические true или false, которые будут отсылаться на виртуальное устройство Алисы.

Управление розеткой через АлисуУправление розеткой через Алису

Все то же самое я повторил и для розетки. Я добавил виртуальное устройство Алисы «Розетка», выбрал для него категорию Socket. Настроил выход с устройства на включение/выключение розетки через msg.payload ON или OFF. Затем взял вход с ноды in для розетки и настроил подачу логических true и false на устройство Алисы в зависимости от значения msg.payload.

Теперь у меня состояния лампы и розетки стали видны в приложении умного дома Яндекса, там же можно включить/выключить оба устройства. Но как насчет датчиков?

Нода in, датчик температурыНода in, датчик температуры

Для добавления в Алису датчиков есть отдельная нода Sensor. Я выбрал сенсор Temperature Sensor и значение температуры. Здесь никаких преобразований не потребовалось, подключение к виртуальному датчику температуры Алисы прямое.

Нода Event АлисыНода Event Алисы

Следующим я добавил датчик движения. Он добавляется через ноду Алисы Event. Тип события в ноде следует указать Motion, обратите внимание на два входа: detected и not_detected. Я добавил ноду in для устройства Motion Sensor, при этом выбрал выдачу всех сведений Complete Payload, так как кроме движения потребуется еще и освещенность.

Нода changeНода changeНода changeНода change

Я перевел логическое значение msg.payload.occupancy (true/false) в msg.payload, а потом изменил msg.payload на строку detected или not_detected в зависимости от true/false. Затем я передал строку на устройство Алисы «Датчик движения».

Устройства Zigbee в приложении Умный домУстройства Zigbee в приложении Умный дом

Наконец, я добавил датчик освещенности через ноду Sensor. Я использовал уже развернутую ноду in, затем добавил ноду Change и переместил значение msg.payload.illuminance в msg.payload, потом подал на виртуальное устройство «Датчик освещенности».

Отправка информации датчиков в АлисуОтправка информации датчиков в Алису

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

Заключение

Вторым способом избавления от облачной иглы Aqara стал модуль WBE2R-R-ZIGBEE v. 2 и контроллер Wiren Board 7, на который я успешно перевел все устройства. Здесь помог бесплатный мост Zigbee2mqtt, в документации к которому можно посмотреть функции устройств Aqara и возможности.

Следующим шагом я установил на Wiren Board 7 оболочку Node-RED, в которой добавил лампу, розетку и сенсоры Aqara через ноды плагина node-red-contrib-zigbee2mqtt. Справился я и со сценариями автоматизации. Я настроил включение/выключение термостата по датчику температуры, а также включение лампы при наличии движения в темноте.

Наконец, я «прикрутил» Алису. В Node-RED добавляются виртуальные устройства, которые появляются в приложении «Умный дом» Яндекса. Затем осталось связать виртуальные устройства с Zigbee — и все готово! Теперь я снова могу включать голосом лампу или розетку, собирать статистику в облаке Яндекса.

Node-RED работает на контроллере Wiren Board 7 локально и никак не зависит от подключения к интернету. Если пропадет интернет или откажет облако, то я потеряю только Алису. А все остальное будет работать.

Примеры флоу из статьи вы найдёте на Github node-red-demo-zigbee2mqtt-alice, не забудьте установить необходимые модули для Node-RED перед импортом.

Надеюсь, приведенные сценарии отказа от облака будут полезны читателям. Пишите, какие эксперименты мне проводить дальше, какие темы исследовать.

В следующей статье я откажусь от Node-RED и для сценариев буду использовать встроенный в контроллеры Wiren Board движок правил wb-rules. Посмотрим, сложно ли писать скрипты автоматизации с помощью штатного инструмента.

© Habrahabr.ru