Статья будет разбита на несколько частей, чтобы более подробно описать все аспекты данной темы.
В этой части я расскажу о проблеме и подходе к её решению.
Предисловие
Когда я читал анонс Яндекс Станции Миди, обрадовался наличию внутри этой крохи Zigbee модуля и улучшению скорости обработки команд управления умным домом в несколько раз, однако подробнее узнал, что ускорение обработки касалось только zigbee устройств, которые у меня подключены уже к умному дому на базе Home Assistant. Идея пришла спонтанно, но получилось придумать, как заставить Алису подавать команды в Home Assistant и организовать связь уровня «координатор‑координатор».
Задача
Zigbee в умном доме "из коробки" не подразумевает подключения формата "координатор-координатор", да и в целом это звучит не совсем логично, однако поскольку станция Миди и умный дом являлись координаторами, необходимо было сделать дополнительный узел в сети, который бы позволил одному из двух думать, что он общается с конечным устройством.
Проблема
Не смотря на простое решение в виду прослойки, у нас есть бревно в колесе нашей машины революции в управлении умным домом - конечное устройство может быть подключено только к одной Zigbee сети.
Соединяем "мама-мама" переходником "папа-папа"
Поскольку два устройства у нас могут только отдавать команды конечным устройствам, значит решение задачи стоит довольно просто — нужно сделать прослойку, которая будет говорить в обе стороны, что оно — конечное устройство и ретранслировать команды от одного координатора другому, принимая команду от одного и обновляя состояние для другого. Решением данной задачки является ESP32 контроллер с поддержкой Zigbee. Однако может возникнуть закономерный вопрос — как передавать и команду и изменение состояния двум координаторам, если конечное устройство может быть связано только с одной сетью? Ответ прост — никак. (занавес)
На самом деле именно поэтому и используется ESP32 контроллер. Мы принимаем команду от станции через Zigbee, а уже далее для Home Assistant мы передаем информацию об изменении состояния через USB. Бинго, но как?
Интеграция
Как вы могли заметить, в решении этой задачи я использовал плату ESP32-C6, которая имеет в себе поддержку Zigbee 3.0, что даст нам возможность подключаться к станции Миди.
Переходим от теории к практике. Купили плату, разобрались что с ней делать, но как заставить Home Assistant принимать изменения состояния? И снова Бинго - прослойка в виде интеграции. К сожалению, в интернете довольно мало информации о том, как разрабатывать свои интеграции для Home Assistant, поэтому я хотел бы вынести этот блок в отдельную статью, чтобы показать на примере этой интеграции как разрабатывать, устанавливать и выкладывать в магазин интеграций свои разработки. Поэтому на данный момент обойдемся скриншотами.
Я написал небольшую интеграцию с веб интерфейсом, в которой мы связываем канал Zigbee девайса с девайсом в Home Assistant. К сожалению на данный момент ссылки на репозиторий нет, поскольку интеграция еще не готова до стабильной версии.
Принцип работы интеграции не сложный:
Ищем среди USB устройств нашу ESP32-C6, подключаемся по серийному порту и передаем список каналов, которые нужно слушать.
При изменении состояния со стороны станции, ESP передает по USB JSON массив формата {'c':10,'st':0}, что означает 10 канал получил состояние выключен.
Через API Home Assistant отправляем соответствующему каналу устройству on\off событие в зависимости от полученного статуса.
Вокруг чего всё это крутится
Интеграция читает с серийного порта платы информацию о состоянии устройств. Как именно это реализовано, давайте разбираться.
Поскольку корневая задача состоит в том, чтобы станция могла изменять состояние чего‑либо, это самое «чего‑либо» должно быть поддерживаемым самой станцией. Что у нас умеет включаться и выключаться, иметь настраиваемые параметры (яркость, цвет) и так же хранить об этом информацию? Верно — лампочка! К тому же, согласно документации Яндекс, этот тип устройства самый «богатый» по возможным атрибутам.
Но если у нас одна плата, как мы будем управлять несколькими устройствами? Здесь нам помогает реализация самого Zigbee протокола. Каждое физическое устройство может иметь в себе несколько составных устройств (например датчик влажности и температуры может содержать в себе и датчик освещения), и каждое такое устройство инициализируется отдельно, представляя в итоге несколько независимых устройств для координатора. Мы как раз и будем использовать данную «фичу» протокола, создавая выключатель на каждый из заданных каналов (по классификации Zigbee это называется Endpoint).
Для реализации данного «обмана» станции я брал за основу прошивку на базе фреймворка ESP‑IDF, что даст нам возможность гибко сконфигурировать плату под наши задачи. Принцип работы прошивки выглядит следующим образом: Плата при включении сразу встает на ожидании ввода списка каналов с серийного порта, как только наша интеграция передала список, происходит инициализация устройства light на каждый из заданных каналов (эндпоинтов), после чего наша плата ESP подключается к сети станции. Теперь, если мы включим поиск устройств на станции, мы увидим столько «лампочек», сколько каналов мы задали в интеграции. Чтобы знать на какой канал что назначать в интеграции добавлено отображение статуса канала, поэтому мы просто по порядку включаем каждую из наших «ламп» и смотрим в интеграции, какой канал включился.
По итогу у нас получается инженерная магия с костылями вне Хогвартса, демонстрацию которой вы можете посмотреть на данном видео (записывалось для знакомого, поэтому такой «свободный» формат):
Что дальше?
В следующей части мы разберем, как создавать свою интеграцию для Home Assistant с нуля до установки в систему, а так же рассмотрим реализацию прошивки на ESP-IDF.
P.S.
Это моя первая публикация, поэтому просьба кидаться мягкими тапками, желательно не в лицо.
Так же хотел бы рассказать, что у меня были планы о создании коммерческого «свистка» для реализации подхода Plug'n'Play под ту аудиторию, которой не хотелось бы «возиться», а просто подключить и пользоваться. Если вам будет интересно данное устройство, дайте знать в комментариях, расскажу о нём подробнее.