![](https://habrastorage.org/getpro/habr/upload_files/797/047/62c/79704762c00b57fd7496d9642e3bfcb4.png)
Статья будет разбита на несколько частей, чтобы более подробно описать все аспекты данной темы.
В этой части я расскажу о проблеме и подходе к её решению.
Предисловие
Когда я читал анонс Яндекс Станции Миди, обрадовался наличию внутри этой крохи Zigbee модуля и улучшению скорости обработки команд управления умным домом в несколько раз, однако подробнее узнал, что ускорение обработки касалось только zigbee устройств, которые у меня подключены уже к умному дому на базе Home Assistant. Идея пришла спонтанно, но получилось придумать, как заставить Алису подавать команды в Home Assistant и организовать связь уровня «координатор‑координатор».
Задача
Zigbee в умном доме "из коробки" не подразумевает подключения формата "координатор-координатор", да и в целом это звучит не совсем логично, однако поскольку станция Миди и умный дом являлись координаторами, необходимо было сделать дополнительный узел в сети, который бы позволил одному из двух думать, что он общается с конечным устройством.
Проблема
Не смотря на простое решение в виду прослойки, у нас есть бревно в колесе нашей машины революции в управлении умным домом - конечное устройство может быть подключено только к одной Zigbee сети.
![конечное устройство может работать только с одним координатором конечное устройство может работать только с одним координатором](https://habrastorage.org/getpro/habr/upload_files/ebe/115/bf5/ebe115bf51fc4a2b153ac609d66b4e06.png)
Соединяем "мама-мама" переходником "папа-папа"
Поскольку два устройства у нас могут только отдавать команды конечным устройствам, значит решение задачи стоит довольно просто — нужно сделать прослойку, которая будет говорить в обе стороны, что оно — конечное устройство и ретранслировать команды от одного координатора другому, принимая команду от одного и обновляя состояние для другого. Решением данной задачки является ESP32 контроллер с поддержкой Zigbee. Однако может возникнуть закономерный вопрос — как передавать и команду и изменение состояния двум координаторам, если конечное устройство может быть связано только с одной сетью? Ответ прост — никак. (занавес)
На самом деле именно поэтому и используется ESP32 контроллер. Мы принимаем команду от станции через Zigbee, а уже далее для Home Assistant мы передаем информацию об изменении состояния через USB. Бинго, но как?
![Решение проблемы - передача информации по другому каналу. Решение проблемы - передача информации по другому каналу.](https://habrastorage.org/getpro/habr/upload_files/f49/9ef/ad4/f499efad458e91c872f54016d141b8ec.png)
Интеграция
Как вы могли заметить, в решении этой задачи я использовал плату ESP32-C6, которая имеет в себе поддержку Zigbee 3.0, что даст нам возможность подключаться к станции Миди.
Переходим от теории к практике. Купили плату, разобрались что с ней делать, но как заставить Home Assistant принимать изменения состояния? И снова Бинго - прослойка в виде интеграции. К сожалению, в интернете довольно мало информации о том, как разрабатывать свои интеграции для Home Assistant, поэтому я хотел бы вынести этот блок в отдельную статью, чтобы показать на примере этой интеграции как разрабатывать, устанавливать и выкладывать в магазин интеграций свои разработки. Поэтому на данный момент обойдемся скриншотами.
Я написал небольшую интеграцию с веб интерфейсом, в которой мы связываем канал Zigbee девайса с девайсом в Home Assistant. К сожалению на данный момент ссылки на репозиторий нет, поскольку интеграция еще не готова до стабильной версии.
![Интеграция ZigBridge Интеграция ZigBridge](https://habrastorage.org/getpro/habr/upload_files/f82/941/e9e/f82941e9e7682cfee0e99a5e08565509.png)
Принцип работы интеграции не сложный:
Ищем среди USB устройств нашу ESP32-C6, подключаемся по серийному порту и передаем список каналов, которые нужно слушать.
При изменении состояния со стороны станции, ESP передает по USB JSON массив формата {'c':10,'st':0}, что означает 10 канал получил состояние выключен.
Через API Home Assistant отправляем соответствующему каналу устройству on\off событие в зависимости от полученного статуса.
Вокруг чего всё это крутится
Интеграция читает с серийного порта платы информацию о состоянии устройств. Как именно это реализовано, давайте разбираться.
Поскольку корневая задача состоит в том, чтобы станция могла изменять состояние чего‑либо, это самое «чего‑либо» должно быть поддерживаемым самой станцией. Что у нас умеет включаться и выключаться, иметь настраиваемые параметры (яркость, цвет) и так же хранить об этом информацию? Верно — лампочка! К тому же, согласно документации Яндекс, этот тип устройства самый «богатый» по возможным атрибутам.
![Здесь можно наблюдать, что у типа устройства light (свет) больше всего поддерживаемых типов устройств (от простого OnOff до ColorDimmable\ColorTemperature, что дает больше возможностей в будущем) Здесь можно наблюдать, что у типа устройства light (свет) больше всего поддерживаемых типов устройств (от простого OnOff до ColorDimmable\ColorTemperature, что дает больше возможностей в будущем)](https://habrastorage.org/getpro/habr/upload_files/015/c19/848/015c19848f11c3072ac1c7c2102b1db3.png)
Но если у нас одна плата, как мы будем управлять несколькими устройствами? Здесь нам помогает реализация самого Zigbee протокола. Каждое физическое устройство может иметь в себе несколько составных устройств (например датчик влажности и температуры может содержать в себе и датчик освещения), и каждое такое устройство инициализируется отдельно, представляя в итоге несколько независимых устройств для координатора. Мы как раз и будем использовать данную «фичу» протокола, создавая выключатель на каждый из заданных каналов (по классификации Zigbee это называется Endpoint).
Для реализации данного «обмана» станции я брал за основу прошивку на базе фреймворка ESP‑IDF, что даст нам возможность гибко сконфигурировать плату под наши задачи. Принцип работы прошивки выглядит следующим образом: Плата при включении сразу встает на ожидании ввода списка каналов с серийного порта, как только наша интеграция передала список, происходит инициализация устройства light на каждый из заданных каналов (эндпоинтов), после чего наша плата ESP подключается к сети станции. Теперь, если мы включим поиск устройств на станции, мы увидим столько «лампочек», сколько каналов мы задали в интеграции. Чтобы знать на какой канал что назначать в интеграции добавлено отображение статуса канала, поэтому мы просто по порядку включаем каждую из наших «ламп» и смотрим в интеграции, какой канал включился.
По итогу у нас получается инженерная магия с костылями вне Хогвартса, демонстрацию которой вы можете посмотреть на данном видео (записывалось для знакомого, поэтому такой «свободный» формат):
Что дальше?
В следующей части мы разберем, как создавать свою интеграцию для Home Assistant с нуля до установки в систему, а так же рассмотрим реализацию прошивки на ESP-IDF.
P.S.
Это моя первая публикация, поэтому просьба кидаться мягкими тапками, желательно не в лицо.
Так же хотел бы рассказать, что у меня были планы о создании коммерческого «свистка» для реализации подхода Plug'n'Play под ту аудиторию, которой не хотелось бы «возиться», а просто подключить и пользоваться. Если вам будет интересно данное устройство, дайте знать в комментариях, расскажу о нём подробнее.
Комментарии (41)
NutsUnderline
06.04.2024 10:02+3С точки зрения "обественной" пользы мне кажется было бы полезно рассказать немного о програмировании zigbee на esp32, наверняка есть подводные камни. Мне кажется многие заинтересованные и не знают что есть такое.
kallibr44 Автор
06.04.2024 10:02+2Как раз поэтому весь код я хотел бы описать в отдельной статье, иначе тут было бы чтиво на часа полтора)
На самом деле, фреймворк от Espressiff (ESP-IDF) очень сильно упрощает это дело, но без подводных камней действительно не обошлось.
nikolz
06.04.2024 10:02Вместо ESP32 я бы взял TLSR825x:
Protocols: Supports Bluetooth LE 5.3, Bluetooth Mesh, Zigbee 3.0, Apple HomeKit (Bluetooth LE), and 2.4GHz proprietary
Bluetooth LE PHY: 1Mbps, 2Mbps, Long Range S2 (500Kbps), S8 (125Kbps)
Bluetooth LE Multi Connection:Master x 4 , Slave x 4
Location Service: RSSI, AoA/AoD (AoD is only supported in some Part Numbers)
MCU: Telink 32-bit, 48MHz;SRAM: 32~64KB;Flash: 512KB~1MB;GPIO: 10~32
I2C: 1;UART: 0~1;SPI: 1;USB: 0~1;PWM: 4~6;ADC: 14bit;AMIC: 1;DMIC: 0~1
Supply Voltage: 1.8V ~ 3.6V
Power Consumption: RX mode: 5.3mA TX mode: 4.8mA @ 0dBm with DCDC
Sleep Consumption: 0.4~1.4uA
Tx Output Power: 10dBm @ BLE mode
Rx Sensitivity: -96dBm @ BLE 1Mbps
Security: AES-128, ECC, TRNG
===================
У ESP32-C6 ток потребления в активном режиме при включенном приемнике в 14 раз больше. А при работе передатчика в 20 раз больше.
-------------------------------
Telink можно питать от CR2032.
kallibr44 Автор
06.04.2024 10:02Здесь есть одна деталь, которая позволяет не смотреть на ток потребления - ESP по факту у нас выступает не как отдельное устройство, а как USB свисток по типу Zigbee приёмника от того же Sonoff (для интеграции zigbee2mqtt например) т.е. у нас постоянное питание от USB.
nikolz
06.04.2024 10:02А почему Вы не передаете в home assistant по Zigbee?
kallibr44 Автор
06.04.2024 10:02Этот аспект как раз описан в разделе "Проблема". Zigbee девайс может быть связан только с одним координатором, а Home Assistant и Яндекс станция оба являются координаторами сети.
nikolz
06.04.2024 10:02Не понял. Что мешает сначала включиться в одну сеть, потом в другую?
Ваш ESP32 должен зарегистрироваться в двух сетях и потом переключаться между ними.
kallibr44 Автор
06.04.2024 10:02+3изначально идея как раз была именно такая, однако потом пришел к следующим выводам:
это довольно накладно по ресурсам т.к. придется для банальной передачи состояния вкл\выкл проводить инициализацию протокола 3 раза (для приема, потом для передачи и снова для приёма), что затратно по времени
Переключение между сетями делает крайне проблемным использование двух сетей, поскольку вы сможете отправлять по сути только одну команду за одну операцию, потому что после подачи сигнала одному каналу, ESP уйдет переподключаться и не будет слушать остальные команды
Банально нет необходимости в такой автономности, поскольку home assistant устанавливается на устройства с нормальными USB портами, что решает сразу две проблемы - задержки в передаче данных и питание платы.
Для реализации такого подхода придется писать прошивку с полного нуля без фреймворков, поскольку последние ориентированы на разработку конечных устройств и "из коробки" такого не умеют, что уже накладно по человеко-часам и ценности разработки.
nikolz
06.04.2024 10:02Правильно я понял, что проблема в том, чтобы подсунуть cтанции яндекс Home Assistant как устройство, которое уже зарегистрировано в станции?
adeep
06.04.2024 10:02а почему бы не передавать в ha все команды через mqtt?
kallibr44 Автор
06.04.2024 10:02Можно и через mqtt, я пошел по пути websocket в интеграции, потому что это сокращает время отклика, поскольку я не использую pub\sub подход, а напрямую делаю emit действие для устройства (подробнее будет во 2 части). MQTT более стандартизирован для таких дел, WebSocket дает побольше возможностей.
Slaxery
06.04.2024 10:02Интересно получилось, я вот расстроился, когда со станции миди перешёл на Home Assistant, лишившись локального управления устройствами голосом. Жду продолжения)
kallibr44 Автор
06.04.2024 10:02+1вторую часть планирую написать когда доведу до ума интеграцию) Она сейчас вроде и работает, но много чего отсутствует для стабильной работы. Эту часть решил написать раньше, потому что я как программист не идеален и возможно знающим людям дам возможность разработать свой аналог, основываясь на моём решении.
saturn017
06.04.2024 10:02Разве в НА нет интеграции с Алисой? Использую majordomo и zigbee2mqqt, все устройства через zigbee2mqqt интегрированы в мажордомо а из него уже взаимодействуют с Алисой (правда только через облако)
kallibr44 Автор
06.04.2024 10:02Есть и товарищ во 2 комменте сверху оставил на них ссылки и да, они только с интернетом работают. Я же реализую фичу Zigbee станций с оффлайн управлением (почему-то тут его все путают с локальным, но речь идет не про локальную сеть, а про отсутствие интернета для станции)
ZhenyaRUS39
06.04.2024 10:02А Марусю кто-то смог интегрировать в HA?
beeline09
06.04.2024 10:02Я смог, но пока только через интернет и белый айпи...
ZhenyaRUS39
06.04.2024 10:02Можете рассказать подробнее?
HA виден в интернете (DuckDNS), но без https.
Создал в Марусе умный дом, но в приложении маруси при входе в HA (ввожу логин и пароль) и выбрасывает обратно).
beeline09
06.04.2024 10:02Я руководствовался этой статьей: https://habr.com/ru/articles/649571/
Там надо руками делать yaml файл и скармливать сервису умного дома. А то что у вас на скрине - скорее всего надо зайти в ВК в настройки двухфакторной аутентификации и создать пароль приложения.ZhenyaRUS39
06.04.2024 10:02Да вот пробовал. Настроил аутентификацию, но вот пишет с восклицательным знаком "Получение доступа к https://vc.go.mail.ru" и дальше ничего не происходит...
Formyurik
06.04.2024 10:02Статью можно не читать. Автор изобретает мегакостыль, который нормально работать не будет.
Есть готовая Интеграция Yaha Cloud, в котором все реализовано, все работает более чем отлично. Нужно сделать пару нажатий кнопки. Никаких плат и прослоек не надо, возможна работа как через облако, так и напрямую.
https://docs.yaha-cloud.ru/v0.6.x/
Там же на сайте супердоккментация на Русском языке. Там описано абсолютно все.
Solexid
06.04.2024 10:02+3Вы забыли нюанс - всё это работает только с интернетом. А фишка миди как раз в том что она умеет работать в офлайне, но только с зигби
kallibr44 Автор
06.04.2024 10:02+1почему же не будет нормально работать?
Как интеграция реализует оффлайн управление устройствами Home Assistant голосом когда интернет отсутствует?
Не вводите людей в заблуждение, интеграция и моя реализация решают разные задачи.
AotD
06.04.2024 10:02Яндекс подвёз "Быстрые команды". Т.о. интерпретация "включи свет", "выключи свет" уже работает локально на колонке.
И если б всё было zigbee и локально сопряжено с Алисой - локальное управление бы работало (предполагаю). "шлюз" в HA выглядит странненько, но так же потенциально через zigbee в Алису можно засунуть и не zigbee устройства? :)
kallibr44 Автор
06.04.2024 10:02Быстрые команды - фича не связанная с оффлайн и локальным управлением. Это возможность выполнять команды, не вызывая помощника триггер-словом "Алиса". И увы, но быстрые команды не работают в оффлайн режиме. Как раз уточнение в конце 1 скриншота наводит на выводы, что они работают всё же не локально.
Касательно обратной совместимости - это побочная фича моей реализации) Через плату мы по сути подключаем в УДЯ много лампочек, а на стороне HA можно навешать on\off триггер на что угодно, так что да, по факту мы имеем возможность управлять вообще чем угодно, что подключено к home assistant в т.ч. локальные wifi\bluetooth девайсы.
Antonzlo
06.04.2024 10:02+1А Matter не позволит с 2 хабами говорить? Правда не знаю какие библиотеки есть для него
kallibr44 Автор
06.04.2024 10:02Matter интересная технология, о ней пока что еще мало что известно как для готового решения, поскольку всё же должна быть поддержка непосредственно в прошивке девайсов этой технологии. Здесь всё же более фундаментальная проблема в том, что HA и УДЯ являются роутерами, к тому же, например в данный момент УДЯ не умеет работать с bluetooth устройствами, как и с Wifi девайсами напрямую (нужен хаб). Аналогию я привел в одном из заголовков - HA и УДЯ являются разъёмами "мама-мама" т.е. напрямую мы не может их чисто технически никак связать, это устройства одного класса, они не умеют хранить какие-либо состояния как объекта, поэтому и нужна такая прослойка-ретранслятор в виде программируемого конечно девайса, который получается как переходник "папа-папа".
Matter это что-то вроде универсального SDK, как например Unity - один проект можно собрать и на пк, и на андроид, и на ios и в VR. Matter стандартизирует общение девайсов, но вроде как никаких новых фич он не привносит.
УДЯ получил поддержку Matter, но устройств, как и информации со стороны поддержки в HA у меня нет, поэтому эта тема остается неизвестной.
nav68
06.04.2024 10:02Есть локально работающая распознавалка голосовых комманд "Ирина" (автор присутствует на Хабре), которая элементарно вяжется с хоме-ассистент.
kallibr44 Автор
06.04.2024 10:02у самого Home Assistant уже есть встроенная поддержка голосовых ассистентов, но здесь всё же речь именно про станции Яндекс и их оффлайн работу с Home Assistant
garageman
06.04.2024 10:02+1Тут основное - нужны достойные микрофоны (массивы микрофонов, как на самой станции) если Ирину заводить на "обычном" -работает, но хуже.
Сам сейчас в поиске, есть несколько плат, но дороговато.
Ridok48
06.04.2024 10:02Хочу переустановить HA, смогу все интеграции восстановить из резервной копии? Проблем не будет? А то там все что настраивал, уже забыл как делать. Будут какие нибудь подводные камни?
kallibr44 Автор
06.04.2024 10:02полный бэкап системы сохраняет и данные интеграций, так что проблем не будет.
UbuRus
Т.е у яндекс станции с zigbee все еще нет нативной интеграции в home assistant? Мне кажется для гиков которые собирают умный дом (а умный дом это все еще занятие для гиков) это был бы большой плюс, чтобы купить яндекс станцию, а не home pod.
Ведь в HomeKit через bridge все устройства появляются в экосистеме apple и управляются без облака почти со всех устройств.
С HomePod можно слушать музыку с любым приложением с iphone и не тратить деньги на подписку яндекс.музыку
В общем яндекс впереди планеты всей :)
NutsUnderline
Яндекс наверное не для (2-3) гиков делает, а для простых пользователей и чтоб наименее замарочено было
kallibr44 Автор
Имхо, но и не будет. Умный Дом Яндекс (УДЯ) - Самостоятельная экосистема и ей банально не выгодно (в отличии от партнерства с Aqara) делать бесплатный и свободный доступ к их главному детищу. К тому же, станции по-прежнему полноценно без серверов не умеют работать из-за технических особенностей (но станция Миди уже имеет прогресс в этом направлении)