--- title: t610 — развёртывание через HA-аддоны status: in-progress tags: - family - plan - homeautomation - t610 - haos - addons created: '2026-09-13' updated: '2026-09-14' related: - '[[family/plans/home-automation-migration-t610]]' - '[[family/how-to/home-automation]]' --- # t610 — развёртывание через HA-аддоны > **Статус (2026-09-14): Этап 1 ✅. Этап 2 ✅ ПОЛНОСТЬЮ. Этап 3 — решения приняты, имена Zigbee согласованы; ждём решения по одному устройству (`Mini Smart Switch 1`) и приступаем к переносу.** Сервисы: z2m (**17 устройств** — добавлено NEO NAS-WR01B), mbusd (502), modbus-bridge (MQTT + HA-опрос), MQTT-интеграция в HA. Разведка конфига TrueNAS выполнена, эталон имён найден. > Родительский план: [[family/plans/home-automation-migration-t610]] (Шаг 3 в нём заменяется на этот документ). > Доступ к хосту, CLI и питфоллы: [[family/how-to/t610-access]]. ## Ключевые решения (кратко, для быстрого входа в контекст) | Решение | Что выбрано | Почему | |---------|-------------|--------| | Формат развёртывания сервисов | **HA-аддоны** (не docker-compose) | из SSH-аддона host docker не виден; аддоны штатны и снимают udev-гонку | | Источник z2m | **community-repo** `zigbee2mqtt/hassio-zigbee2mqtt` | в официальном сторе z2m нет | | mbusd / modbus-bridge | **local add-ons** (`/addons/...`) | кастомный код, в сторе нет | | Привязка CH340 (2 одинаковых адаптера) | **`/dev/serial/by-path/...`** | by-id у обоих идентичен (нет серийников) | | Как аддон видит serial | **флаг `uart: true`** в манифесте аддона | даёт доступ ко всем serial (by-id + by-path) автоматически; `devices:` не нужен | | udev-алиасы `ttyZONT`/`ttyVent` | **отменены** | на HA OS невозможны (SSH-аддон = Alpine-контейнер); by-path функционально эквивалентен | | Доступ к хостовому шеллу | **не нужен** | debug-SSH 22222 включается только флешкой; всё делается через Supervisor API | ## Контекст: почему аддоны, а не docker-compose 1:1 Изначально в родительском плане (Шаг 3, Вариант B) предполагалось перенести `docker-compose.yml` с TrueNAS 1:1. При проверке живого t610 выяснилось: - HA OS 18.2 внутри использует **host docker 29.6.2** (overlayfs, journald) — docker есть, `ha docker info` подтверждает. - Но **из SSH-аддона docker CLI не виден** — аддон живёт в своём контейнере. Доступ к host docker только через Supervisor (`ha docker`) или через Portainer-аддон. - Поэтому штатный и наименее хрупкий путь — **аддоны**. **Решение Alex (2026-09-13): «Делай всё аддонами».** ## Состав аддонов | Сервис | Slug | Источник | Статус | |--------|------|----------|--------| | Mosquitto broker (MQTT) | `core_mosquitto` | Official (core) | ✅ установлен, `started` (1883/1884) | | Node-RED | `a0d7b954_nodered` | Community | ✅ установлен, `started` (1880) | | Advanced SSH & Web Terminal | `a0d7b954_ssh` | Community | ✅ есть в сторе (запасной путь) | | Terminal & SSH | `core_ssh` | Official | ✅ **установлен и работает** | | Samba share (для доступа к файлам) | `core_samba` | Official | ⏸️ установлен, `stopped` (нужен `password`) | | File editor | `core_configurator` | Official | ✅ установлен, `started` | | **Zigbee2MQTT** | `45df7312_zigbee2mqtt` | Community repo | ✅ **установлен, работает — 17 устройств** | | **mbusd** | `local_mbusd` | Local add-on (`/addons/mbusd`) | ✅ **установлен, работает — порт 502** | | **modbus-bridge** | `local_modbus-bridge` | Local add-on (`/addons/modbus-bridge`) | ✅ **установлен, работает — MQTT + HA-опрос** | | **MQTT-интеграция в HA** | `mqtt` | Config entry | ✅ **добавлена 2026-09-14** (была ОТСУТСТВОВАЛА → 22 сущности; стало 104, 69 Zigbee) | ### Про Zigbee2MQTT В официальном сторе z2m нет (есть только deCONZ `core_deconz` и `core_silabs_multiprotocol`). Варианты: - **A. Community-репозиторий z2m** — у сообщества есть репо (`https://github.com/zigbee2mqtt/hassio-zigbee2mqtt`), добавляется как app repository, дальше штатная установка. - **B. Local add-on** — свой Dockerfile в `/addons/zigbee2mqtt`. **Решение: A (community repo)** — меньше ручной работы, поддерживается сообществом, обновления через UI. ✅ Реализовано 2026-09-14. ### Про mbusd и modbus-bridge В сторе нет и быть не может (кастомный код). Только **local add-ons**: ``` /addons/mbusd/ → Dockerfile + config /addons/modbus-bridge/ → Dockerfile + modbus_ha_bridge.py + config.yml ``` Local add-ons требуют **Advanced Mode** в профиле HA (Settings → Apps появляются только с ним) + репозиторий «Local apps» уже подключён (проверено: `addons_repositories` содержит `Local apps`). ## ✅ USB-устройства подключены (2026-09-14) — блокер снят **Все 3 устройства воткнуты и видны** (карта by-id/by-path: [[family/how-to/t610-access]] §USB). ``` /dev/ttyUSB0 → CH340 #1 by-path: pci-0000:00:12.0-usb-0:3:1.0-port0 (порт 3) → ZONT / modbus-bridge /dev/ttyUSB1 → CH340 #2 by-path: pci-0000:00:12.0-usb-0:4:1.0-port0 (порт 4) → Vent / mbusd /dev/ttyACM0 → Zigbee Inswift ZBP-MG21 by-id: usb-Inswift_Zigbee_ZBP-MG21_535A000001-if00 ``` ⚠️ **Два CH340 неразличимы по by-id** (у обоих `1a86:7523`, serial отсутствует) → привязка только по **by-path / адресу шины**. ### 🔑 РЕШЕНИЕ: привязка по `by-path` вместо udev-алиасов Проверено на живом t610 (2026-09-14): **udev-алиасы (`ttyZONT`/`ttyVent`) на HA OS не нужны и сделать их «как на TrueNAS» нельзя** — SSH-аддон это Alpine-контейнер, у него нет `/etc/udev/rules.d` и нет `udevadm`. Хостовый доступ = только debug-SSH 22222, который на t610 выключен и включается лишь флешкой с ключом в разделе `CONFIG` (по сети — никак: `ha host` без ssh-команд, Supervisor API `/host/services/ssh` → 403, роль аддона `manager`). **Рабочая схема — штатный механизм Supervisor: `uart: true`.** - В `config.yaml` (или `config.json`) аддона флаг **`uart: true`** даёт контейнеру доступ ко **всем** serial-устройствам хоста — вместе с симлинками `/dev/serial/by-id/` **и** `/dev/serial/by-path/`. - Подтверждено: `core_ssh` имеет `uart: true` → из него виден весь `/dev/serial/by-path/`. z2m-аддон тоже имеет `uart: true`. - **`devices:` в конфиг аддона прописывать НЕ надо** — при `uart: true` проброс serial автоматический. **Как прописывать путь в конфиге сервиса:** ```yaml # zigbee2mqtt (Settings → Apps → Zigbee2MQTT → Configuration → serial) serial: adapter: ember port: /dev/serial/by-path/pci-0000:04:00.0-usb-0:1:1.0 # Zigbee — by-id тоже ок (уникальный серийник) ``` Для mbusd / modbus-bridge (local add-ons) — в их `config.yaml`/опциях указывать **by-path**: ``` ZONT → /dev/serial/by-path/pci-0000:00:12.0-usb-0:3:1.0-port0 Vent → /dev/serial/by-path/pci-0000:00:12.0-usb-0:4:1.0-port0 ``` Это **функциональный аналог** udev-алиасов с TrueNAS: имя не «прыгает» при перезагрузке, привязка к физическому порту. Разница только в том, что вместо `ttyZONT` пишется полный by-path. > ⚠️ **by-path привязан к физическому порту.** CH340 #1 обязан остаться в порту 3, CH340 #2 — в порту 4. Если поменять — пути поедут. Порты зафиксированы (проверено). ### ✅ z2m на t610 — ВЫПОЛНЕНО (2026-09-14) **Что сделано:** 1. **Бэкап с TrueNAS** → Mac `~/tmp-t610/z2m-backup-20260914/` (`database.db`, `configuration.yaml`, `state.json`, `coordinator_backup.json`). Источник на TrueNAS: `/mnt/RED_2TB/docker/zigbee2mqtt/`. 2. Установлен аддон `45df7312_zigbee2mqtt` v**2.14.1-1** (community repo). Манифест содержит **`uart: true`** → доступ ко всем serial, `devices:` не нужен. 3. **Mosquitto**: добавлен логин `zont` (тот же пароль, что на TrueNAS) через Supervisor API → `POST /addons/core_mosquitto/options` → `ha apps restart core_mosquitto`. Нужен, чтобы HA-интеграция и ZONT продолжили работать по старым креденшелам. 4. **Опции z2m** (Supervisor API `POST /addons/45df7312_zigbee2mqtt/options`): ```json serial: { "port": "/dev/serial/by-id/usb-Inswift_Zigbee_ZBP-MG21_535A000001-if00", "adapter": "ember", "baudrate": 115200, "rtscts": false } mqtt: { "server": "mqtt://core-mosquitto:1883", "user": "zont", "password": "<как на TrueNAS>" } ``` 5. **База перенесена 1:1.** ⚠️ `data_path` аддона = **`/config/zigbee2mqtt`** — внутри HA-конфига, НЕ `/addon_configs/...`. Создана `/config/zigbee2mqtt/`, залиты `database.db` + `configuration.yaml` (тот же `network_key`/`pan_id`/`ext_pan_id`/`channel: 11`, но serial → by-id, MQTT → core-mosquitto). 6. `ha apps start 45df7312_zigbee2mqtt` → **работает.** **Лог подтверждает успех** (`/config/zigbee2mqtt/log//log.log`): ``` zh:ember: [INIT TC] Adapter network matches config. z2m: Coordinator firmware: EmberZNet 7.4.5 [GA], EZSP 13 z2m: Currently 16 devices are joined. z2m: Connected to MQTT server ``` ✅ **16 устройств на месте, переспаривание НЕ потребовалось.** (Tuya: модули реле, диммеры, розетки, датчики t°/влажности, протечки, радар присутствия, светильник.) **Питфоллы z2m-переноса:** - **Пароль MQTT содержит `$`** (`mqtt1z3$`) → при передаче через `sed`/интерполяцию в шелле ломается экранирование, скрипт падает с `unmatched '|'`. Надёжный путь: файл `configuration.yaml` готовить **локально**, заливать копированием файла, значения с `$` не подставлять в bash-строки. Для Supervisor API — JSON собирать через `jq`, а не конкатенацией. - Supervisor API требует **полный** набор опций (схема валидирует все ключи) — брать текущие и менять нужное. - Пароль в выводе `ha`/API маскируется как `***` — это нормально, значение применяется. - `uart: true` = автоматический проброс всех serial (by-id + by-path). `devices:` в конфиг аддона прописывать не надо. - В SSH-аддоне **нет python3**, и он неустойчив к сложному экранированию строк — готовые конфиги заливать файлом, а не генерировать на хосте. ## План по шагам ### Этап 1 — базовые аддона (не требуют USB) — ✅ ВЫПОЛНЕНО 2026-09-13 1. [x] Advanced Mode — не понадобился для CLI (всё сделано через `ha apps`), понадобится позже для local add-ons 2. [x] **Mosquitto broker** (`core_mosquitto` v7.1.1) — установлен, `started`, порты **1883** (MQTT) + **1884** (WS) открыты, discovery отправлен в HA автоматически 3. [x] **Node-RED** (`a0d7b954_nodered` v22.0.6) — установлен, `started`, порт **1880** открыт, **уже подключился к HA** (`Connected to http://supervisor/core`) 4. [ ] **Samba share** (`core_samba`) — установлен, но `stopped`: требует задать `password` (по умолчанию `null`) → логин `homeassistant`. Задать в UI: Settings → Apps → Samba → Configuration 5. [x] **File editor** (`core_configurator`) — установлен, `started` 6. [x] Репозиторий Zigbee2MQTT добавлен: `ha store add https://github.com/zigbee2mqtt/hassio-zigbee2mqtt` → появился как `Home Assistant App: Zigbee2MQTT` (slug `45df7312`) 7. [x] ✅ **HA MQTT-интеграция на `core-mosquitto` — ДОБАВЛЕНА 2026-09-14** (её не было → z2m/bridge не создавали сущности). Сущностей: 22 → **104** (69 Zigbee). Рецепт — §«HA MQTT-интеграция» ниже. **Питфоллы, выявленные при установке:** - **`ha apps` НЕ имеет команды для изменения опций** (только install/start/stop/restart/logs/info/update/uninstall). Настройка опций — только через **UI** или **Supervisor API** (`POST http://supervisor/addons//options`). - **Node-RED по умолчанию `ssl: true`** → падает при старте без сертификата (`init-nginx: command exited 1`, `state: error`). Фикс: `ssl: false` через API (см. ниже). - API требует **полный** набор опций (схема валидирует все ключи) — нельзя послать только `{"ssl": false}`, будет `Missing option 'certfile'`. Надо взять текущие опции и поменять нужное. - **В SSH-аддоне нет python3** (только bash/curl/jq/`ha`). Скрипты для t610 писать на bash+jq. - `ha store add ` (не `ha store repositories add`). **Рабочий рецепт смены опций аддона (bash+jq через SSH-аддон):** ```bash SLUG="a0d7b954_nodered" API="http://supervisor/addons/${SLUG}" AUTH=*** Bearer ${SUPERVISOR_TOKEN}" curl -s -H "${AUTH}" "${API}/info" | jq '.data.options | .ssl = false' > /tmp/o.json jq -n --slurpfile o /tmp/o.json '{options: $o[0]}' > /tmp/post.json curl -s -X POST -H "${AUTH}" -H "Content-Type: application/json" -d @/tmp/post.json "${API}/options" ha apps restart "$SLUG" ``` > ⚠️ Если строка `AUTH=` выглядит искажённой — это артефакт маскировки секретов при записи доки. В живом скрипте: `AUTH=*** Bearer ${SUPERVISOR_TOKEN}"`. Рабочие скрипты лежат на Mac в `~/tmp-t610/*.sh`. Скрипты лежат локально: `~/tmp-t610/nr_set_ssl.sh`. ### Этап 2 — USB-устройства — ✅ ВЫПОЛНЕНО 2026-09-14 8. [x] Alex втыкает 3 USB в t610 — **ВЫПОЛНЕНО 2026-09-14**. Порты зафиксированы: CH340 #1 → USB1 порт 3, CH340 #2 → USB1 порт 4, Zigbee → USB3 порт 1. **Устройства из портов не вынимать!** 9. [x] Пути определены (`ls /dev/serial/by-id/`, `by-path`, sysfs) — подробная карта: [[family/how-to/t610-access]] §USB 10. [x] Карта составлена: ttyUSB0 = CH340 #1 (ZONT), ttyUSB1 = CH340 #2 (Vent), ttyACM0 = Zigbee 11. [x] **СПОСОБ ПРИВЯЗКИ РЕШЁН 2026-09-14** — привязка по **`by-path`**, никаких udev-алиасов. Механизм: флаг `uart: true` в манифесте аддона даёт доступ ко **всем** serial включая `/dev/serial/by-path/` (проверено на живом t610: `core_ssh` uart:true видит все by-path; z2m тоже uart:true). `devices:` прописывать не надо. Подробности: [[family/how-to/t610-access]] §USB. **Блокер снят.** 12. [x] ✅ **z2m-аддон УСТАНОВЛЕН И РАБОТАЕТ (2026-09-14)** — аддон `45df7312_zigbee2mqtt` v2.14.1-1, serial по by-id, база перенесена 1:1, **16 устройств на месте, переспаривание не потребовалось.** Подробности — §«z2m на t610 (ВЫПОЛНЕНО)» выше. 13. [x] ✅ **mbusd local add-on СОБРАН И РАБОТАЕТ (2026-09-14)** — slug `local_mbusd`, порт **502 открыт** (проверено `nc` с Mac), устройство by-path CH340 #2 (порт 4). Подробности — §«Local add-ons mbusd / modbus-bridge» ниже. 14. [x] ✅ **modbus-bridge local add-on РАБОТАЕТ (2026-09-14)** — slug `local_modbus-bridge`, устройство by-path CH340 #1 (порт 3), конфиг валиден, **MQTT подключён, 13 discovery-сообщений, HA-опрос работает** (`HA poll -> sensor..._temperature = 73.454`). Плюс в HA добавлена **MQTT-интеграция** (её НЕ БЫЛО) — см. §«HA MQTT-интеграция» ниже. #### ✅ HA MQTT-интеграция + `ha.url` для modbus-bridge (2026-09-14) **Симптомы по цепочке:** HTTP **401** при `ha.url = http://supervisor/core` → HTTP **404** при `http://192.168.2.176:80` → в HA всего **22 сущности**, Zigbee нет. **Причины (по порядку):** 1. **`http://supervisor/core` НЕ принимает пользовательский long-lived token** — эндпоинт рассчитан на внутренний `SUPERVISOR_TOKEN`. С пользовательским токеном → **401**. ✅ **Правильный адрес: `http://192.168.2.176:80`** (прямой HA Core). Проверено curl'ом из аддона: `supervisor/core` → 401, `192.168.2.176:80` → **200**. 2. **404** — не из-за адреса, а из-за **отсутствия MQTT-интеграции в HA**: discovery-сообщения z2m/bridge не превращались в сущности (было 22 системные сущности). 3. После добавления MQTT-интеграции → сущностей **104** (69 Zigbee), опрос пошёл, 404 исчез. **Рецепт добавления MQTT-интеграции (Config Entry Flow API):** ```bash T= BASE="http://192.168.2.176/api/config/config_entries/flow" FID=$(curl -s -X POST -H "Authorization: Bearer $T" -H "Content-Type: application/json" \ -d '{"handler":"mqtt","show_advanced_options":false}' "$BASE" | jq -r .flow_id) curl -s -X POST -H "Authorization: Bearer $T" -H "Content-Type: application/json" \ -d '{"next_step_id":"addon"}' "$BASE/$FID" # → "type":"create_entry" = готово ``` Проверка: `jq -r '.data.entries[].domain' /config/.storage/core.config_entries | grep mqtt` → `mqtt`. Скрипт: `~/tmp-t610/setup_mqtt_integration.sh`. **⚠️ ПИТФОЛЛ: токен маскируется при подстановке в bash-переменную** - Любая подстановка токена в `echo`/`sed`/переменную окружения давала в опциях заглушку `` вместо токена. - **Рабочий способ:** записать токен в **файл** → `scp` на t610 (`/tmp/ha_token.txt`) → читать на месте `TOK=$(tr -d '\n\r' < /tmp/ha_token.txt)` → подавать через `jq --arg t "$TOK"`. Не интерполировать в строки. - **Проверка токена:** `curl -o /dev/null -w '%{http_code}' -H "Authorization: Bearer $T" http://192.168.2.176/api/` → **200** ок, **401** — токен от другого пользователя. - ⚠️ **Ложный след (не повторять):** гипотеза «`iss` в JWT должен равняться `core.uuid`» — **НЕВЕРНА**. У рабочего токена `iss=e75d1d6f...`, `core.uuid=d3b24dad...` — не совпадают, и это норма. Единственный надёжный тест — HTTP-код на `/api/`. - Скрипты: `~/tmp-t610/{apply_token2.sh,setup_mqtt_integration.sh,verify_token.sh}`, токен: `~/tmp-t610/ha_token.txt`. ### ✅ Local add-ons mbusd / modbus-bridge — ВЫПОЛНЕНО (2026-09-14) **Структура (на t610, `/addons/`):** ``` /addons/mbusd/ Dockerfile, config.yaml, run.sh /addons/modbus-bridge/ Dockerfile, config.yaml, run.sh, modbus_ha_bridge.py, data/config.template.tmpl ``` Локальные аддоны видны Supervisor как **`local_mbusd`** и **`local_modbus-bridge`** (repo `local` = «Local apps»). **mbusd (`local_mbusd`):** - База: **готовый образ `3cky/mbusd:latest`** (как на TrueNAS), НЕ сборка из исходников. В манифесте `uart: true`, порт `502/tcp`. - `run.sh` генерирует `/etc/mbusd/mbusd.conf` из опций (`/data/options.json` через `jq`) и запускает `mbusd -d -L - -c`. - Опции: `device` = `/dev/serial/by-path/pci-0000:00:12.0-usb-0:4:1.0-port0`, speed 9600, mode 8n1, trx_control `addc`. - ✅ Порт 502 слушается (`nc -z 192.168.2.176 502` → OK). **modbus-bridge (`local_modbus-bridge`):** - База: `python:3.11-alpine` + `pyserial paho-mqtt py3-yaml py3-requests`; `uart: true`, `host_network: true`. - `run.sh`: из `/data/options.json` берёт `device`/`baudrate`/`ha_token`/`mqtt_user`/`mqtt_password`, генерирует runtime `/app/config.yml` из шаблона (`ha.url` → **`http://192.168.2.176:80`**, `mqtt.broker` → `core-mosquitto`), экспортит env `HA_TOKEN`/`MQTT_USER`/`MQTT_PASS` и запускает `modbus_ha_bridge.py`. - Опции: `device` = `/dev/serial/by-path/pci-0000:00:12.0-usb-0:3:1.0-port0`, baudrate 9600, `ha_token` (183 симв.), `mqtt_user` = `zont`, `mqtt_password`. - ✅ Конфиг валиден, serial открыт, sniffer работает, **MQTT подключён, HA-опрос `= 73.454` без ошибок**. - ⚠️ `ha.url` ОБЯЗАН быть `http://192.168.2.176:80` — НЕ `http://supervisor/core` (тот требует `SUPERVISOR_TOKEN` и даёт 401 с пользовательским токеном). **Питфоллы local add-ons (HA OS 18.2) — важные:** - **`${BUILD_FROM}` в Dockerfile пустой**, если нет `build.yaml` с базовыми образами по arch. Решения: (a) добавить `build.yaml` c `build_from: {amd64: ..., aarch64: ...}`, либо (b) **взять готовый образ напрямую** (`FROM 3cky/mbusd:latest`) — тогда `build.yaml` не нужен. - **Supervisor парсит все `*.yml`/`*.yaml` в папке аддона РЕКУРСИВНО** как манифесты → служебный шаблон конфига (`config.template.yml`) вызывает `Invalid app config!`. Фикс: переименовать в **`.tmpl`** (не `.yml`). - **`ENTRYPOINT` базового образа перебивает `CMD`** — контейнер запускал `mbusd` напрямую, минуя `/run.sh` → `can't read config file /etc/mbusd.conf`. Фикс: в Dockerfile `ENTRYPOINT []` + `CMD ["/bin/bash","/run.sh"]`. - После правки Dockerfile/манифеста нужен **`ha apps uninstall ` → `ha store reload` → `ha apps install`** (обновление образа не подхватывается само). - **Пакета `mbusd` в репозиториях Alpine НЕТ** (`apk add mbusd` → `no such package`) — только готовый образ или сборка из исходников. - Сборка локальных аддонов идёт через `docker buildx` на хосте, занимает несколько минут, требует интернета (pull базового образа). **Рабочий рецепт диагностики сборки:** `ha apps install ` → при ошибке `ha supervisor logs | tail -60` (там полный вывод docker build). ### Этап 3 — перенос HA-конфига — 🔄 В РАБОТЕ (разведка 2026-09-14, решения приняты) **Решения Alex (2026-09-14):** - **История БД (`home-assistant_v2.db`, 142 МБ) — НЕ переносить**, начинаем с нуля. - **Реестры `.storage` — ЗАМЕНИТЬ** (вариант B: взять реестры TrueNAS целиком, а не сливать). Zigbee-сущности пересоздадутся z2m автоматически по `database.db` + discovery. Минус: переименования `entity_id`, сделанные в UI на TrueNAS, потеряются. - **HACS и custom_components — РЕШЕНО: НЕ переносим ничего** (см. §«Инвентарь custom_components»). - **Zigbee generic-имена — привести к единому виду, пока реестр чистый** (см. §«Zigbee friendly_name»). ⏳ Ждём от Alex имена для 17 устройств. #### Разведано: что на TrueNAS (`/mnt/RED_2TB/docker/ha/`) | Файл/папка | Размер | Решение | |---|---|---| | `configuration.yaml` | 29 954 б (~30КБ) | ✅ переносить + правка `modbus.host` | | `automations.yaml` | 7 045 б | ✅ переносить | | `scripts.yaml` | 30 728 б | ✅ переносить | | `secrets.yaml` | 161 б | ✅ переносить | | `scenes.yaml` | 0 б | пусто, можно не тащить | | `www/card-mod.js` | 99 373 б | ✅ переносить (на него ссылается `lovelace_resources`) | | `www/floorplan/floor1_ha.svg`, `floor2_ha.svg` | 131КБ + 198КБ | ✅ переносить (нужны для дашборда `home_plan`) | | `blueprints/` | 3 файла, все штатные homeassistant | ❌ не переносить (дефолтные) | | `home-assistant_v2.db` | 142 МБ (+`-wal` 1.9МБ) | ❌ **не переносить** (решение: с нуля) | | `home-assistant_v2.db.corrupt.2026-04-30*` | 152 МБ | ❌ не переносить | | `.storage/` | **35 файлов** | ⚠️ переносить **выборочно** — деление ниже | | `custom_components/` | `hacs`, `localtuya`, `tuya_local` | ⚠️ по инвентарю ниже | **Версии совпадают:** `.HA_VERSION` на TrueNAS и на t610 = **2026.9** (t610: `2026.9.2`) → миграция реестров допустима. #### `.storage` — что НЕЛЬЗЯ перезаписывать ⚠️ **Копировать `.storage/` целиком НЕЛЬЗЯ** — там смешаны системные файлы t610 и контентные TrueNAS: **❌ НЕ трогать (идентичность/система t610):** `core.uuid` (подменит `instance_id`), `auth`, `auth_provider.homeassistant` (сломает логин `ha_admin`), `http`, `http.auth`, `onboarding`, `core.config`, `homeassistant.exposed_entities`, `core.config_entries` (там уже правильная MQTT-интеграция t610). **✅ Переносить (контент):** - **`core.entity_registry` — КРИТИЧНО** (без него `entity_id` не совпадут с `configuration.yaml`) - `core.device_registry`, `core.area_registry`, `core.floor_registry`, `core.restore_state` - `lovelace.home_plan` (+ `.bak`, `.bak2`), `lovelace_dashboards`, `lovelace_resources` - `person`, `zone` (⚠️ `hacs.*` **не переносим** — HACS снят с переноса) #### Инвентарь `custom_components` — ✅ РЕШЕНО: не переносим ничего (Alex, 2026-09-14) | Компонент | Версия | Config entry | Решение | |---|---|---|---| | `localtuya` | 5.2.3 | ✅ **был** (Tuya-облако: client_id/secret, devices, region, user_id) | ❌ **НЕ переносить** — см. ниже | | `hacs` | 2.0.5 | ✅ есть, но **репозиториев НЕТ** (`hacs.repositories` пуст) | ❌ не переносить (нагрузки не несёт) | | `tuya_local` | 2026.7.2 | ❌ нет | ❌ не переносить | **`localtuya` — ОТКАЗ (2026-09-14).** Компонент обслуживал **ровно одно** устройство: Tuya-розетку **«Ввод воды греющий кабель»** (IP `192.168.2.194`, `protocol_version 3.4`, platform `switch`). Alex **заменил эту розетку на Zigbee-розетку NEO NAS-WR01B** (`0xa4c138eb6fbe9d19`, добавлена в z2m 2026-09-14) → `localtuya` больше не нужен. В `configuration.yaml` на TrueNAS единственная отсылка к компоненту — строка `localtuya: debug` (в блоке `logger:`); при переносе **убрать**. **Итог: папка `custom_components/` не переносится вообще.** Никаких HACS-компонентов в системе нет. #### Порядок работ Этапа 3 (важно — не перепутать) 1. **Бэкап** текущего `/config` t610 → Mac (`~/tmp-t610/config-t610-backup-<дата>/`) 2. **Бэкап** нужного с TrueNAS → Mac 3. `ha core stop` (иначе HA перезапишет `.storage` при выходе) 4. Перенести реестры `.storage` (замена, выборочно по списку выше) 5. Перенести `configuration.yaml` + правка `modbus.host` → `127.0.0.1` 6. Перенести `automations.yaml`, `scripts.yaml`, `secrets.yaml`, `www/` 7. `custom_components/` — **НЕ переносим** (решено) → шаг пропускается 8. Старт HA, проверка: конфиг валиден, сущности на месте, автоматизации, дашборд `home_plan` 9. **ТОЛЬКО ПОСЛЕ этого** — правка `friendly_name` в z2m + чистка `entity_id` в HA > ⚠️ Порядок шагов 4 → 9 критичен: если переименовать z2m до переноса реестров, работа пропадёт (HA перезапишет реестр). #### ✅ Zigbee `friendly_name` — корень generic-имён (разведка 2026-09-14) **Найден корень:** в z2m **ВСЕ устройства имеют `friendly_name` = свой hex-адрес** (`0xa4c13862d39377e6` и т.д.). Это состояние приехало с TrueNAS — HA их так не называл. Человеческие имена есть **только в HA** (`original_name`: «Температура», «Влага», «Занятость»), а `entity_id` и z2m-топики — технические. **Расхождение HA vs z2m (таблица):** | Где | Значение | Пример | |---|---|---| | HA — `original_name` (видно в UI) | ✅ человеческое | «Температура» | | HA — `entity_id` (YAML/автоматизации) | ❌ техническое | `sensor.0xa4c13862d39377e6_temperature` | | z2m — `friendly_name` | ❌ hex | `0xa4c13862d39377e6` | | MQTT-топик | ❌ hex | `zigbee2mqtt/0xa4c13862d39377e6` | - Проверено в `/config/zigbee2mqtt/configuration.yaml` (секция `devices:`) — у всех `friendly_name: ''`. - Отдельная категория — вообще без имени: `switch.0xa4c138f8da8bc478` (`original_name` пусто), `switch.0xcc86ecfffe1347fd`, `switch.0x84fd27fffed9e137`, `update.0xa4c138f8da8bc478`, `light.0xa4c13882a4b42db0`. **Корневой механизм:** `entity_id` в HA формируется при **первом появлении** сущности и от `friendly_name` z2m. Уже созданные `entity_id` в реестре **НЕ переименовываются автоматически** при смене `friendly_name`. Поэтому нужны **две операции**: (а) `friendly_name` в z2m, (б) переименование `entity_id` в `core.entity_registry` HA. ⚠️ **Побочный эффект смены `friendly_name`:** меняются MQTT-топики → **все сущности пересоздаются с новыми `entity_id`**, любые ссылки в автоматизациях/шаблонах ломаются. Поэтому делать это **до** переноса автоматизаций с TrueNAS («пока чисто»). #### 🔄 Новое устройство: NEO NAS-WR01B (2026-09-14) Alex заменил Tuya Smart Plug (греющий кабель воды) на **Zigbee-розетку**. - **IEEE:** `0xa4c138eb6fbe9d19` - **Модель:** NEO NAS-WR01B, «Smart plug (with electrical measurements)» — P/V/I/E - **powerSource:** Mains (single phase) - Проверка: `Successfully configured '0xa4c138eb6fbe9d19' (definition v0.0.1)`, `voltage: 223`, `state: OFF`, `linkquality: 232`; discovery ушёл, сущности создались. - **Итого в z2m — 17 устройств.** - При участии `localtuya`: розетка была на Tuya (`192.168.2.194`) → сменилась на Zigbee → `localtuya` снят с переноса. **Рецепт permit_join (спаривание без UI, через MQTT):** в z2m `permit_join` не задан → окно закрыто. Открывается так (пароль из опций аддона, БЕЗ интерполяции — `$` в пароле ломает bash): ```bash ha apps info 45df7312_zigbee2mqtt --raw-json | jq -r '.data.options.mqtt.password' > /tmp/pw MPW=$(cat /tmp/pw); rm -f /tmp/pw mosquitto_pub -h core-mosquitto -p 1883 -u zont -P "$MPW" \ -t 'zigbee2mqtt/bridge/request/permit_join' -m '{"value": true, "time": 180}' timeout 10 mosquitto_sub -h core-mosquitto -p 1883 -u zont -P "$MPW" \ -t 'zigbee2mqtt/bridge/response/permit_join' -t 'zigbee2mqtt/bridge/event' -C 3 ``` ⚠️ `mosquitto_pub/sub` в аддоне **НЕ знают `--pwfile`** (Unknown option) — только `-u`/`-P`. ⚠️ **`ha apps logs ` тяжёлый** — не гонять его в цикле ожидания («висит» минутами). Ждать готовности интервью по `database.db`/`state.json`. Подробнее: [[family/how-to/t610-access]] §USB → «Спаривание нового Zigbee-устройства». #### ✅ Имена 17 устройств — СОГЛАСОВАНЫ 2026-09-14 (латиница snake_case, единый формат) **Источник эталона — НЕ выдумка:** на **TrueNAS в z2m `friendly_name` уже были человеческими** (файл `/mnt/RED_2TB/docker/zigbee2mqtt/configuration.yaml`, сохранился в бэкапе `~/tmp-t610/z2m-backup-20260914/configuration.yaml`). Дополнительно человеческие имена есть в **`core.device_registry` TrueNAS** и в **дашборде `lovelace.home_plan`** (он ссылается на `switch.sauna`, `light.smart_light_office_left`, `binary_sensor.shower_2_presence_sensor_presence` и т.п.). **Что произошло (моя ошибка при переносе):** на t610 залит `configuration.yaml` z2m **без секции `devices:`** → z2m при старте сам дописал `devices:` с `friendly_name` = IEEE для всех 17 устройств. Т.е. hex-имена на t610 — артефакт переноса, а не исходное состояние. **Итоговая таблица (латиница, исправлены опечатки вроде `Presense`→`presence`):** | # | IEEE | Было (TrueNAS) | **Стало (согласовано)** | Роль | |---|---|---|---|---| | 1 | `0xa4c13862d39377e6` | hex | `kabinet_temperature_sensor` | датчик t°/влажности (в кабинете, временно) | | 2 | `0xa4c138f8da8bc478` | Насос обратки | `obratka_pump` | розетка с измерением P/V/I/E | | 3 | `0xcc86ecfffe1347fd` | Mini Smart Switch 1 | ⏳ `unused_wall_switch` **или удалить** | реле, **нигде не используется, `unavailable`, нет зоны** | | 4 | `0x84fd27fffed9e137` | Zigbee Mini Switch 2 | `shower_night_light` | зона Душевая; автоматизации «Вкл./Выкл. ночной свет душевая» | | 5 | `0xa4c1386d40ddb67b` | Light Sensor Stairs | `stairs_light_sensor` | датчик освещённости | | 6 | `0xa4c138dc6d856eca` | Presense Sensor 1 | `presence_sensor_1` | радар присутствия mmWave | | 7 | `0xa4c1381186ed1a32` | Smart light Office | `office_smart_light` | выключатель 2-кл | | 8 | `0xa4c13873b5c1575b` | Light switch Table Office | `office_table_light_switch` | реле 2 канала L1/L2 | | 9 | `0xa4c13807b64c7fd4` | Kitchen hood | `kitchen_hood` | реле 3 канала (вытяжка) | | 10 | `0xa4c138cefeee19fd` | Zigbee dimmer 2ch | `zigbee_dimmer_2ch` | светильник 2 канала | | 11 | `0xa4c1386d0839706a` | Smart Light Stairs | `stairs_smart_light` | реле | | 12 | `0xa4c1384fbe0b3a6b` | Sauna | `sauna` | розетка без мониторинга | | 13 | `0xa4c138b0f9e674a5` | Wireless light switch bed | `bed_wireless_light_switch` | беспроводной выключатель | | 14 | `0xa4c13882a4b42db0` | Dimmer bed | `bed_dimmer` | диммер 1 канал | | 15 | `0xa4c138c4a94a6a31` | Shower 2 presence sensor | `shower_2_presence_sensor` | радар присутствия 2-й | | 16 | `0xa4c1383d5fcaa063` | hex | `boiler_water_leak` | датчик протечки, зона **Котельная** | | 17 | `0xa4c138eb6fbe9d19` | — (новая) | `heating_cable_plug` | NEO NAS-WR01B, розетка греющего кабеля | **Зоны (11, из `core.area_registry` TrueNAS):** Гостиная `living_room`, Кухня `kitchen`, Спальня `bedroom`, Детская `detskaia`, Кабинет `kabinet`, Ванная `vannaia`, Душевая `dushevaia`, Туалет `tualet`, Северная `severnaia`, Котельная `kotelnaia`, Лестница `lestnitsa`. Этажи: 1, 2. **Модели (из `database.db`, JSON-lines — НЕ sqlite):** `modelID` пуст, но `manufName` даёт модель Tuya: `_TZ3000_akqdg6g7`, `_TZ3000_gjnozsaz`, `_TZ3000_3a9beq8a`, `_TZ3000_hy6ncvmw`, `_TZE200_crq3r3la`, `_TZ3000_0e6uvexf`, `_TZ3000_5gey1ohx`, `_TZ3000_odzoiovu`, `_TZ3000_kvwrdf47`, `_TZ3210_nhqka112`, `_TZ3000_kccru4oi`, `_TZ3000_ooc8illt`, `_TZE204_qasjif9e`, `Zbeacon` (протечка). > 📌 **Питфолл:** база z2m `database.db` — это **JSON Lines** (объект на строку), НЕ SQLite. `sqlite3 database.db` → `file is not a database`. Читать: `jq -r 'select(.type!="Coordinator") | [.ieeeAddr,.type,.manufName] | @tsv' z2m-live.db`. > Также в SSH-аддоне **нет `sqlite3`** — базу копировать на Mac (`scp` → `/Users/admin/tmp-t610/z2m-live.db`). #### ℹ️ Как читать «человеческие имена» в HA (важно для будущих сессий) **Имена устройств НЕ лежат в реестрах HA** — их надо искать в трёх местах: 1. **z2m** `/config/zigbee2mqtt/configuration.yaml` → секция `devices:` → `friendly_name`. 2. **HA `core.device_registry`** → `data.devices[].name` (и `name_by_user`), связь через `identifiers: [["mqtt","zigbee2mqtt_0x..."]]`. 3. **Дашборд `lovelace.home_plan`** → `entity` в `picture-elements` (самый надёжный источник рабочей схемы имён). Поля сущностей: `original_name` = **имя параметра** («Температура», «Влага») — НЕ имя устройства; `name`/`name_by_user` часто `null`. **Вывод: `original_name` для определения устройства бесполезен** — все 16 датчиков t° будут «Температура». **Пифолл поиска:** если автоматизация ссылается на устройство, искать надо по `device_id`, а не `entity_id` — в `automations.yaml` триггеры вида `type: battery_level / device_id: ...` не содержат имени устройства. Связь: `device_id` → `core.device_registry` → `identifiers` → IEEE. **Инвентарь `configuration.yaml` TrueNAS (30КБ):** секции — `default_config`, `http`, `logger`, `modbus` (17: шина вентиляции — заслонки intake/exhaust, AT2), `input_number`, `input_boolean`, `template` (summary-сенсоры `dining_summary`, `kids_summary`, `bedroom_summary`, `at2_1_summary`), `frontend` (темы), `automation/script/scene: !include`. **Секции `mqtt:` в конфиге НЕТ.** Датчики `sensor.dining_*`/`kids_*`/`bedroom_*` (`platform: mqtt`) — это **Modbus RTU Sniffer** (шина вентиляции), НЕ Zigbee, и уже названы правильно. **Автоматизации TrueNAS (`automations.yaml`, 15 шт.):** Выключить/Включить циркуляцию ГВС, Ventilation automation on, office_pass_switch_table/main, Светло/Темно подсветку лестницы, Toggle/Cycle Dimmer bed, Вкл./Выкл. ночной свет душевая, Протечка котельная, Датчик протечки котельная батарея, Датчик освещённости лестница батарея, Light switch bed батарея, Zigbee T sensor батарея. **Дашборд `home_plan` использует hex, который надо будет заменить после переименования:** - `binary_sensor.0xa4c1383d5fcaa063_water_leak` → `boiler_water_leak` - `switch.0xa4c138f8da8bc478` → `obratka_pump` - `switch.vvod_vody_greiushchii_kabel` → **`heating_cable_plug`** (старая Tuya-розетка → новая Zigbee) ### Этап 4 — проверка и отключение TrueNAS 18. [ ] Чек-лист из родительского плана §6 19. [ ] Caddy upstream → t610; GPON-редирект → t610 20. [ ] Остановить + отключить автозапуск на TrueNAS (§7) ## Отличия от родительского плана (что меняется) | Было (родительский план) | Стало (этот план) | |--------------------------|-------------------| | docker-compose 1:1 на HA OS | HA-аддоны | | udev-алиасы `99-tty-alias.rules` на t610 | **не нужно** — аддоны с `uart: true` видят `/dev/serial/by-path/...` и `/dev/serial/by-id/...` автоматически; в конфиге сервиса указывается by-path | | Скрипт ожидания tty + systemd | **не нужно** — Supervisor сам ждёт устройство при старте аддона | | Ручной `docker compose up` | `ha apps start ` / UI | | Пути `/mnt/data/...` | `/addon_configs//` и `/share`, `/config` | | Хостовый SSH (как на TrueNAS) | **недоступен** — SSH-аддон = Alpine-контейнер; debug-SSH 22222 только через флешку `CONFIG`. Привязка serial решается штатным `uart: true`, хостовый шелл не нужен | > ✅ Плюс: проблема **udev-гонки на t610 снимается** — Supervisor управляет зависимостями и пробросом устройств. Это была самая опасная часть старого плана. ## Открытые вопросы - [x] ✅ **РЕШЕНО 2026-09-14 — способ привязки CH340 в аддонах:** привязка по `/dev/serial/by-path/...`; механизм Supervisor — флаг `uart: true` в манифесте аддона (доступ ко всем serial автоматически, `devices:` не нужен). Проверено на живом t610. Детали: [[family/how-to/t610-access]] §USB. - [x] ✅ **РЕШЕНО 2026-09-14 — куда переносить данные z2m:** `data_path` аддона = **`/config/zigbee2mqtt`** (внутри HA-конфига), НЕ `/addon_configs/`. Туда залиты `database.db` и `configuration.yaml`. - [x] ✅ **Проверено 2026-09-14 — совместимость community-repo z2m с HA OS 18.2 / Core 2026.9.2:** работает (v2.14.1-1, координатор EmberZNet 7.4.5, 17 устройств). - [x] ✅ **РЕШЕНО 2026-09-14 — `uart: true` для local add-ons:** подтверждено на mbusd/modbus-bridge — в их манифестах `uart: true`, by-path виден, устройства открываются (mbusd порт 502, bridge sniffer на шине ZONT). Тот же механизм, что у z2m и core_ssh. - [x] ✅ **РЕШЕНО 2026-09-14 — modbus-bridge `ha_token`/`mqtt_password`:** вписаны, MQTT + HA-опрос работают. Ключевой момент — `ha.url` = `http://192.168.2.176:80` (не `supervisor/core`), + в HA добавлена MQTT-интеграция. **Этап 2 закрыт полностью.** - [x] ✅ **РЕШЕНО 2026-09-14 — `custom_components` не переносим.** HACS (репо пусто) и `tuya_local` (нет config entry) не нужны; `localtuya` обслуживал единственную Tuya-розетку, которую Alex заменил на Zigbee → тоже снят. - [x] ✅ **РЕШЕНО 2026-09-14 — история БД не переносится** (новая с нуля) и **реестры `.storage` — замена** (вариант B). - [x] ✅ **ВЫПОЛНЕНО 2026-09-14 — Zigbee-розетка NEO NAS-WR01B (`0xa4c138eb6fbe9d19`) добавлена** через permit_join (MQTT). z2m = 17 устройств. - [x] ✅ **СОГЛАСОВАНЫ 2026-09-14 — имена 17 Zigbee-устройств** (латиница snake_case, единый формат). Эталон найден: человеческие `friendly_name` были на **TrueNAS в z2m** и в `core.device_registry`/дашборде. См. §«Имена 17 устройств». - [ ] ⏳ **ЖДЁМ Alex — решение по `Mini Smart Switch 1` (`0xcc86ecfffe1347fd`):** нигде не используется, нет зоны, состояние `unavailable`. Варианты: имя `unused_wall_switch` либо удалить из z2m (unpair). - [ ] Камера (§8 родительского плана) — не аддон, разбираться отдельно ## Связанные заметки - [[family/plans/home-automation-migration-t610]] — родительский план - [[family/how-to/home-automation]] — карта slave ID, ZONT, регистры - [[family/how-to/t610-access]] — доступ к хосту, CLI, карта USB, питфоллы - [[family/how-to/zont-modbus-bridge-udev-race-protection]] — старая проблема гонки udev (на аддонах неактуальна) - [[family/how-to/truenas-infrastructure]] — текущий docker-стек TrueNAS