
В этой части разберёмся с разработкой аддона для Home Assistant и публикацией проекта в репозиторий для дальнейшего использования.
Часть 2. Аппаратная часть.
Часть 3. Теория по аддонам Home Assistant (вы здесь)
Часть 4. Установка интеграции Zigbridge в Home Assistant
Ну что же, с теорией мы разобрались, ESP32-C6 подготовили, теперь переходим к самому главному - разработки аддона (дополнения) с Home Assistant (далее - HA).
Add-on vs Интеграция
Для начала давайте разберёмся с тем, в чем отличия Add-on и Интеграции и почему мы не можем реализовать задуманное на обычном Home Assistant. Интеграция помогает реализовать непосредственную связку устройств с HA или расширить функционал системы путем добавления кастомных компонентов, в то время, как аддон это именно сервис, позволяющий запускать независимые сервисы в Docker контейнерах, но данный функционал доступен только в варианте установке Home Assistant Operating System (далее - HAOS).
HAOS это не просто сервис HA, это полноценная операционная система, которая включает в себя как HA, так и расширенные возможности окружения, в том числе и запуск аддонов. Сама ОС реализована в формате сервиса т.е. мы не имеем прямого доступа к файлам системы, а только лишь оболочку HA CLI (есть аддон, через который можно управлять самой системой через SSH). Общение HA с аддонами происходит через служебный контейнер Supervisor, который управляет доступами аддонов, а так же предоставляет транспортный слой через внутренний websocket.
Структура аддона
Сам аддон доступен по ссылке - репозиторий. Общие требования к аддонам довольно подробно описаны в официальной документации. Рассмотрим структуру нашей интеграции подробнее:

Красным выделены те файлы, которые обязательно должны присутствовать в репозитории и без них аддон работать не будет.
build.yaml - в этом файле перечисляются базовые образы для сборки аддона на разные архитектуры. Подставляется в окружение в переменную BUILD_ARG (понадобится позднее)
config.yaml - это главный файл настройки аддона, в нём указывается вся основная информация о проекте, которую будет читать HA.
repository.json - это, скажем так, краткое описание репозитория. Информация из этого файла отображается в списке репозиториев, когда мы добавляем в него репозиторий с интеграцией
Dockerfile,entrypoint - думаю не стоит объяснять, это непосредственно главные файлы для сборки образа контейнера аддона (от entrypoint можно избавиться, если запуск в одну команду происходит)
README - многие пренебрегают этим файликом, но он используется не только в самом репозитории, но и отображает информацию в самом аддоне в интерфейсе HA.
ingress.conf - в нашем случае он необходим, поскольку наш аддон содержит в себе веб панель, которая будет работать через ingress контроллер HAOS т.е. нам не придется пробрасывать порты или прописывать домены, это будет сделано автоматически.
Так же в репозитории видно папки data,static,templates - это непосредственно код аддона.
Необязательной является папка translations - из названия понимаем, что там находятся файлы локализации. В нашем случае мы ими пренебрегаем.
Локальная установка аддона
Для разработки и отладки нам необязательно сразу идти по пути git репозитория, аддоны можно устанавливать как из удаленных источников (например, github), так и локально.
Для того, чтобы мы могли проводить локальную разработку, необходимо развернуть инстанс HAOS (можно на физическом девайсе, можно скачать образ виртуальной машины *ремарка: рекомендую использовать VMWare для варианта с ВМ, поскольку VirtualBox отказывается пробрасывать ESP32-C6 в виртуальную машину*). Как только мы имеем development стенд в виду установленного и настроенного HAOS, первым делом идем в раздел аддонов ("Настройки" -> "Дополнения" -> "Магазин дополнений") и устанавливаем два аддона:
Advanced SSH & Web Terminal - позволит получить полный доступ к bash оболочке системы HA. После установки аддона необходимо зайти в его конфигурацию и задать пароль ssh.
Samba share - позволит создать SMB шару на нашем HA, чтобы была возможность работать с файлами удаленно. После установки аддона необходимо зайти в его конфигурацию и задать пароль smb. (Еще в списке аддонов есть sftp дополнение, smb просто как пример)
После приготовлений подключаемся к шаре на сервере. Все локальные дополнения должны быть сложены в папку /addons (т.е. путь для подключения будет выглядеть так для smb: \\(адресс HA)\addons). Папку можно назвать произвольно, на название в системе она не влияет.
Настройка аддона
И так мы создали папку нашего аддона, теперь нам нужно его настроить, чтобы Home Asistsnat понимал с чем ему предстоит работать.
Первым делом создаем файл config.yaml со следующим содержимым:
name: "название дополнения (отображается в магазине дополнений). Обязательно"
description: "описание дополнения (отображается в магазине дополнений). Обязательно"
version: Версия дополнения. Обязательно
url: "ссылка на репозиторий. Необязательно"
slug: "доменное имя приложения. Будет использоваться для внутренней коммуникации. Можно дублировать имя"
uart: true // говорим HA что нам нужен доступ к UART устройствам
init: false // всегда ставим false
arch: // список архитектур, на которых будет работать дополнение.
- aarch64
- amd64
- armhf
- armv7
- i386
startup: services // порядок автозапуска. В нашем случае services запускаются в последнюю очередь после HA
ingress: true // указываем, что аддону нужен ingress
timeout: 30 // время, которое будет ожидать supervisor запуска контейнера
homeassistant_api: true // запрашиваем доступ к внутреннему API
options: // пример разметки конфигурации, данные переменные будут доступны контейнеру через окружение ENV.
ttyPort: "/dev/ttyACM0"
schema: // схема данных для переменных конфигураций. Заполнение должно совпадать с options.
ttyPort: str
Это пример минимального конфига, который, в том числе, будет использоваться в нашем кейсе. Полный список переменных доступен в официальной документации.
Далее создаем repository.json, он содержит в себе только 3 пункта
{
"name": "Название проекта",
"url": "Ссылка на репозиторий, для перехода в проект по кнопке",
"maintainer": "Информация о разработчике"
}
Следом делаем файл build.yaml, файл универсален, поэтому лучше просто его скопировать из блока ниже.
---
build_from:
aarch64: ghcr.io/home-assistant/aarch64-base:3.14
amd64: ghcr.io/home-assistant/amd64-base:3.14
armhf: ghcr.io/home-assistant/armhf-base:3.14
armv7: ghcr.io/home-assistant/armv7-base:3.14
i386: ghcr.io/home-assistant/i386-base:3.14
codenotary:
signer: notary@home-assistant.io
base_image: notary@home-assistant.io
И в завершении создаем Dockerfile, и при необходимости entrypoint. Dockerfile стоит начинать с получения названия образа, поскольку при сборке\установке аддона (если мы укажем build: true в конфиге) HA будет передавать образ, соответствующий архитектуре из build.yaml
ARG BUILD_FROM
FROM $BUILD_FROM
Важный момент: при проектировании контейнера Docker стоит учитывать то, что в каждый контейнер монтируется постоянное хранилище по пути /data внутри контейнера, соответственно, по данному пути нельзя ничего сохранять, поскольку при запуске эта папка будет перезаписана. Исходя из информации выше, если вам что-то нужно сохранять постоянно (например, локальная база данных), то необходимо настроить в коде создание таких объектов по пути /data.
На этом настройка окружения завершена, можно переходить к разработке кода дополнения.
Установка локального дополнения
Установка происходит предельно просто. Когда вы подготовите аддон к запуску, необходимо сложить все файлы на сервер HA по пути addons/(папка аддона)/, после чего перейти в магазин дополнений, откуда мы ставили SSH и SMB дополнения, обновить список и если вы всё настроили правильно, то увидите в списке своё дополнение в разделе Local Addons.

Особенности работы с Home Assistant
Рейтинг доверия дополнения (фактор доверия)
Все дополнения сканируются системой HA на запрашиваемые доступы и возможности, исходя из чего строится, так называемый, рейтинг доверия. Фактически не влияет на работоспособность, однако если вы делаете публичный проект с полной интеграцией в HA, приложение получит рейтинг 1, что может оттолкнуть пользователей использовать его.

Получение событий из Home Assistant
Зачастую дополнения взаимодействуют с системой Home Assistant, позволяя автоматизировать некоторые процессы в отдельно сервисе. Рассмотрим несколько вариантов работы с событиями и устройствами в HA:
REST API. требует ручного создания API токена на пользователя, позволяет ограничить права доступа дополнения к системе.
внутренний Websocket. Как мы говорили ранее, у HAOS есть служебный контейнер Supervisor - данная служба отвечает за транспортировку всех событий внутри HAOS между контейнерами, в том числе и аддонами. Данный вебсокет работает по принципу брокера сообщений т.е. события из системы отправляются на всех подписантов канала общим эмитом. Данный вариант работы открывает широкие возможности работы с системой (как минимум получение событий изменений в HA в реальном времени по pull модели), но очень сильно понижает фактор доверия дополнения, поскольку Websocket никак не ограничивает права дополнений.
если по методу REST API достаточно базовой документации, то с Websocket не всё так однозначно. Документация рассказывает про отдельные методы, но весь флоу работы не описан, поэтому мы рассмотрим как всё же работать с Websocket.
Схематично работа с Websocket выглядит следующим образом

Теперь давайте разбираться в деталях работы:
1. Сокет требует постоянного поддержания соединения. Явного указания таймаута я не нашел, но экспериментальным путем выведено, что лучше отправлять пинг каждые 5 секунд.
2. Каждый запрос, на который система будет отдавать ответ, вне зависимости от того, принимаете ли вы его, или нет, требует уникального идентификатора запроса, который передается ключом id. Идентификатор должен быть всегда уникальным в рамках сессии (с получения от сервера auth_ok), поэтому самым простым будет решение глобального инкремента. Необходимость указания идентификатора нужно смотреть в документации к методу.
3. Адрес Supervisor вебсокета всегда используется внутренний и является постоянным, а именно ws://supervisor/core/websocket т.е. всегда ссылается по Docker домену на супервизора.
Без постоянного пинга, если вы не отправите ничего на сокет, он закроет соединение и придется повторять весь цикл аутентификации и подписки на события. На схеме я не случайно указал access_token как SUPERVISOR_TOKEN. Дело в том, что когда мы запрашиваем доступ к работе с вебсокетом, Supervisor выдает на наш контейнер токен, по которому идентифицирует наш аддон, а получить мы его можем просто из окружения по переменной SUPERVISOR_TOKEN. Пример работы с сокетом вы можете найти в моём аддоне, который мы детальнее рассмотрим в следующей части.
В остальном же работа с данным сокетом происходит без каких-либо особенностей и зависит от выбранного вами стека.
Установка аддона ZigBridge
С теорией разобрались, теперь давайте перейдем к завершающей части, а именно установке созданного аддона ZigBridge. Весь код проекта находится в данном репозитории,
Переходим в репозиторий, в описании нажимаем на синюю кнопку "Add Add-on repsotiry". Откроется окно перенаправления на ваш Home Assistant, проверьте, что снизу написан верный адрес панели Home Assistant и нажимаем "Open Link". После перенаправления в магазин дополнений нажимаем "Добавить" рядом с вставленной ссылкой.

Обновляем страницу и листаем в самый низ, где наблюдаем добавленное дополнение.

Запускаем дополнение и переходим в веб панель. Никаких настроек делать не нужно.

Для того, чтобы настроить работу Яндекс Алисы с Home Assistant, достаточно ввести в новой строке номер канала (нужно вписать любое число от 1 до 254), выбрать из выпадающего списка нужное устройство, которое будет отвечать за данный канал и нажать слева символ +, после чего добавится связка устройства и ESP будет перезагружено для получения нового канала. И всё, теперь достаточно перейти в Умный дом от Яндекс и найти новое zigbee устройство. Демонстрация работы дополнения со стороны настройки ниже в видео.
Демонстрация работы
В итоге мы получили работающую интеграцию Яндекс станции с Home Assistant, которая позволит управлять устройствами Home Assistant не выходя в интернет. Надеюсь данная серия статей помогла вам понять работу с дополнениями в Home Assistant, а на этом у меня всё (:
kirovilya
Сложная реализация, хотя я сам тоже баловался подобным пару лет назад. А сейчас я бы посоветовал обратить внимание на Matter-мосты, которые можно подключать к УДЯ - там прокидываются сразу несколько устройств. Да, не все типы устройств еще реализованы в Matter УДЯ, впрочем как и в Zigbee для УДЯ. Но зато тоже нативная интеграция, без облачных навыков.
И будет работать на всех Я.Станциях, а не только с Zigbee
positroid
Старые колонки, приобретенные до начала поддержки Matter разве поддерживают его? Или там софтовая поддержка при обновлении прошивки прилетает?
kirovilya
софтовая https://alice.yandex.ru/support/ru/smart-home/supported-matter-devices