From 8e9d4f3745fed4c45a0311d23d1845c0f2e3e57f Mon Sep 17 00:00:00 2001 From: Alexey Martemyanov Date: Mon, 14 Sep 2026 13:06:15 +0600 Subject: [PATCH] [2026-09-14] eagle: family/how-to/t610-access.md family/plans/home-automation-migration-t610.md family/plans/t610-addons-deployment.md --- family/how-to/t610-access.md | 13 ++- .../plans/home-automation-migration-t610.md | 3 +- family/plans/t610-addons-deployment.md | 89 +++++++++++++++++++ 3 files changed, 100 insertions(+), 5 deletions(-) diff --git a/family/how-to/t610-access.md b/family/how-to/t610-access.md index b1940493..d219158e 100644 --- a/family/how-to/t610-access.md +++ b/family/how-to/t610-access.md @@ -4,13 +4,18 @@ > План переноса: [[family/plans/home-automation-migration-t610]] > Развёртывание сервисов: [[family/plans/t610-addons-deployment]] -> ✅ **Состояние на 2026-09-14 (Этап 3 ЗАКРЫТ, z2m = 15 устройств):** z2m, mbusd (порт 502), modbus-bridge (MQTT + HA-опрос) — развёрнуты аддонами и **работают**. В HA добавлена **MQTT-интеграция**. **HA-конфиг перенесён с TrueNAS** (`.storage` реестры + конфиги + `www/`): HA запущен, **11 зон, MQTT-интеграция цела, ошибок нет**. Zigbee-розетки добавлены: `heating_cable_plug` (NEO NAS-WR01B, греющий кабель) и **`boiler_controller_power`** (`0xa4c1381694217e10`, TS011F, Котельная — питание контроллеров котлов), мёртвые устройства (3 шт.) **удалены из z2m**. Реестр HA = **332 сущности, hex = 0**. -> ✅ **Автоматизации: 16 шт., 15 `on` + 1 `off`, 0 `unavailable`** (было 13 «мёртвых» — `device_id` перемаплены + hex-`entity_id` почищен). +> ✅ **Состояние на 2026-09-14 (Этап 3 ЗАКРЫТ, z2m = 15 устройств):** z2m, mbusd (порт 502), modbus-bridge (MQTT + HA-опрос) — развёрнуты аддонами и **работают**. В HA добавлена **MQTT-интеграция**. **HA-конфиг перенесён с TrueNAS** (`.storage` реестры + конфиги + `www/`): HA запущен, **11 зон, MQTT-интеграция цела, ошибок нет**. Zigbee-розетки добавлены: `heating_cable_plug` (NEO NAS-WR01B, греющий кабель) и **`boiler_controller_power`** (`0xa4c1381694217e10`, TS011F, Котельная — питание контроллеров котлов), мёртвые устройства (3 шт.) **удалены из z2m**. Реестр HA = **332 сущности, hex = 0**. **Зоны проставлены у 18 устройств.** +> ✅ **Автоматизации: 16 шт., 15 `on` + 1 `off`, 0 `unavailable`** (было 13 «мёртвых» — `device_id` перемаплены + hex-`entity_id` почищен **и в триггерах**). > ✅ **HTTP-варнинг устранён** (блок `http:` → `.storage/http`), **`modbus.host` = `192.168.2.176`** (НЕ `127.0.0.1` — см. питфолл ниже), **modbus-bridge 404 исправлены** (+rebuild аддона). > ⏸️ **ОСТАЛСЯ ОДИН БЛОКЕР — аппаратный:** 32 заслонки вентиляции `unavailable` (шина не отвечает, exception 0x0B) → CH340 #2 нужно физически подключить к линиям A/B шины. Конфиг верный. > -> 🔑 **Ключевой вывод:** HA связывает сущности по **`unique_id`**, а не по `entity_id`. Смена `friendly_name` в z2m **сохраняет человеческие `entity_id`** — дублей нет, автоматизации не ломаются. -> 🔑 **`device_id` НЕ переносится между инстансами HA** — автоматизации, ссылающиеся на `device_id`, надо перемапить по `identifiers`. Подробно: [[family/plans/t610-addons-deployment]] §«ПИТФОЛЛ: device_id ломаются при переносе реестра». +> 🔑 **Ключевой вывод:** HA связывает сущности по **`unique_id`**, а не по `entity_id`. Смена `friendly_name` в z2m **сохраняет человеческие `entity_id`** — дублей нет. +> 🔑 **При переносе HA между инстансами теряются ВСЕ инстанс-локальные привязки** (устройства ре-регистрируются): +> - **`device_id`** — новый у каждого устройства → перемапить в `automations.yaml`/`scripts.yaml` по `identifiers` (`zigbee2mqtt_`); +> - **`area_id`** (зона устройства) — теряется → проставить заново по эталону; +> - **ссылки на `entity_id`** в автоматизациях/дашбордах — не обновляются автоматически, даже если реестр переименован (грепать `[a-z_]+\.0x[0-9a-f]{16}` **везде**, включая `platform: state`-триггеры). +> Подробно: [[family/plans/t610-addons-deployment]] §«ДОБАВЛЕНО В КОНЦЕ СЕССИИ». +> 🔑 **z2m не публикует состояние пассивно** — реле остаются `unknown` до первого события. Живость проверять по **`lastSeen`** в `database.db`. После рестарта HA — физически нажать кнопки. ## Основное diff --git a/family/plans/home-automation-migration-t610.md b/family/plans/home-automation-migration-t610.md index 4c37d4d2..f18d5380 100644 --- a/family/plans/home-automation-migration-t610.md +++ b/family/plans/home-automation-migration-t610.md @@ -19,7 +19,8 @@ related: --- # Перенос домашней автоматизации на HP t610 -> **Статус: В ПРОЦЕССЕ. Этап 1 ✅. Этап 2 ✅ ПОЛНОСТЬЮ ВЫПОЛНЕН (z2m — 16 устройств, mbusd — порт 502, modbus-bridge — MQTT + HA-опрос, MQTT-интеграция в HA добавлена). Этап 3 (перенос HA-конфига + `.storage/`) 🔄 В РАБОТЕ — разведка выполнена, решения приняты (БД с нуля, реестры заменить, HACS на согласовании, Zigbee-имена чистить); ждём ответа Alex.** +> **Статус: Этап 1 ✅. Этап 2 ✅ ПОЛНОСТЬЮ. Этап 3 ✅ ЗАКРЫТ (2026-09-14).** z2m — 15 устройств, mbusd — порт 502, modbus-bridge — MQTT + HA-опрос. HA-конфиг перенесён с TrueNAS, автоматизации 16/16 живы, реестр 332 сущности (hex=0), зоны у 18 устройств. Детали Этапа 3 и питфоллы переноса — [[family/plans/t610-addons-deployment]]. +> **⏸️ Остался один блокер — аппаратный:** 32 заслонки вентиляции `unavailable` (шина не отвечает, exception 0x0B) → CH340 #2 подключить к линиям A/B шины. Далее — Этап 4 (Caddy upstream → t610, GPON-редирект, отключение TrueNAS). > Цель: убрать всю домашнюю автоматизацию с TrueNAS (он перегружен — 17/21 ГБ RAM) на выделенный HP t610, с бэкапом конфигов на TrueNAS и в git. > > **Прогресс 2026-09-14 (вечер) — Этап 2 ЗАКРЫТ, Modbus-сервисы работают:** diff --git a/family/plans/t610-addons-deployment.md b/family/plans/t610-addons-deployment.md index 366eb966..473f356b 100644 --- a/family/plans/t610-addons-deployment.md +++ b/family/plans/t610-addons-deployment.md @@ -23,6 +23,8 @@ related: > **modbus.host исправлен: `127.0.0.1` → `192.168.2.176`** (mbusd в отдельном контейнере — `127.0.0.1` изнутри HA его не видел). > **modbus-bridge: HTTP 404 → 200.** Опрашивал HA по hex-`entity_id`; правился `modbus_ha_bridge.py` + `data/config.template.tmpl` + **обязательный rebuild аддона**. > ⚠️ **ЕДИНСТВЕННЫЙ ОСТАВШИЙСЯ БЛОКЕР (физика, не конфиг): 32 заслонки вентиляции `unavailable`.** mbusd работает (TCP отвечает), но шина **не отвечает** — exception **0x0B** (GATEWAY TARGET DEVICE FAILED TO RESPOND). Вывод: **CH340 #2 воткнут в USB, но линии A/B вентиляционной шины к нему не подключены / шина обесточена.** За Alex. +> **✅ ЗОНЫ ВОССТАНОВЛЕНЫ (18 устройств):** при переносе `area_id` теряются так же, как `device_id` (устройства ре-регистрируются) → все 14 zigbee были **без зон**. Проставлены по эталону с TrueNAS по zigbee-адресу. См. §«ДОБАВЛЕНО В КОНЦЕ СЕССИИ» ①. +> **✅ office-переключатель управляет светом:** устранены hex-`entity_id` **в триггерах** автоматизаций (`switch.0xa4c13873b5c1575b_l1/l2` → человеческие) + реле выведены из `unknown` физическим нажатием. Цепочка `light → switch_as_x → z2m → реле` проверена. См. §«ДОБАВЛЕНО В КОНЦЕ СЕССИИ» ②③. > Сервисы: z2m (14 устройств), mbusd (502), modbus-bridge (MQTT + HA-опрос), MQTT-интеграция в HA. > Родительский план: [[family/plans/home-automation-migration-t610]] (Шаг 3 в нём заменяется на этот документ). > Доступ к хосту, CLI и питфоллы: [[family/how-to/t610-access]]. @@ -842,6 +844,90 @@ update.0xa4c1381694217e10 -> update.boiler_controller_power **⚠️ Питфолл сессии (важный для будущих сессий):** Alex **устал апрувать** запуск python-скриптов (`execute_code` и `/usr/bin/python3 -c`) — ТРЕБУЕТ bash+jq/curl. Пользоваться shell-скриптами, python только когда без него никак (и предупреждать). +#### 🧩 ДОБАВЛЕНО В КОНЦЕ СЕССИИ 2026-09-14 — ЗОНЫ и office-переключатель + +**Три отдельных дефекта, найденных Alex'ом после «всё готово». Все устранены.** + +##### ① Зоны (`area_id`) потерялись при ре-регистрации устройств — ГЛАВНЫЙ питфолл + +**Симптом (Alex):** «на всех устройствах зоны верно поставлены? Чето в ui кажется что не все девайсы имеют зону». +**Факт:** **14 из 14 zigbee-устройств были БЕЗ зоны** (`area_id = null`). Зона была только у только что добавленной `boiler_controller_power` (её я прописал руками). + +**Причина — ТРЕТИЙ слой той же болезни, что `device_id`:** при переносе `.storage` я скопировал `core.area_registry` (**11 зон созданы**), но `area_id` живёт **в `core.device_registry`**. Zigbee-устройства при подключении к локальной MQTT-интеграции **зарегистрировались заново** → новые записи устройств пришли **без `area_id`**. Зоны (как сущности реестра зон) остались, а привязка устройство→зона — нет. + +> 🔑 **Обобщение (важно для будущих миграций):** при переносе HA между инстансами **теряются все инстанс-локальные привязки**, а не только `device_id`: +> - `device_id` — новый у каждого устройства; +> - `area_id` (зона устройства) — теряется, если устройство ре-регистрируется; +> - `entity_id` (в `entity_registry`) — сохраняется по `unique_id`, но **ссылки на него в автоматизациях/дашбордах — нет**. +> Переносится **только** то, что задано явными `id` в реестрах (`area_registry`, `floor_registry`). + +**Лечение (выполнено):** эталон зон взят с TrueNAS (`/mnt/RED_2TB/docker/ha/.storage/core.device_registry`) — там 17 устройств с зонами. Маппинг построен **по zigbee-адресу** (`identifiers[0][1]` = `zigbee2mqtt_`), проставлен через jq при остановленном HA. + +**Итоговые зоны (18 устройств):** + +| Зона | Устройства | +|------|-----------| +| **Котельная** `kotelnaia` | `boiler_controller_power`, `boiler_water_leak`, `heating_cable_plug`, `recirculation_pump` | +| **Кабинет** `kabinet` | `smart_light_office`, `office_table_light_switch`, `office_temperature_sensor` | +| **Спальня** `bedroom` | `bed_dimmer`, `wireless_light_switch_bed`, `Bedroom Sensor` (modbus) | +| **Душевая** `dushevaia` | `night_light_shower_2`, `shower_2_presence_sensor` | +| **Лестница** `lestnitsa` | `light_stairs`, `light_sensor_stairs` | +| **Кухня** `kitchen` | `kitchen_hood` | +| **Туалет** `tualet` | `sauna` | +| **Гостиная** `living_room` | `Dining Sensor` (modbus) | +| **Детская** `detskaia` | `Kids Sensor` (modbus) | + +> ℹ️ `office_temperature_sensor` на TrueNAS зоны не имел → поставлен `kabinet` по расположению. `heating_cable_plug` заменил Wi-Fi-розетку `local_bf8821e863abe84816qmbo` (была `kotelnaia`) → унаследовал зону. + +**Скрипт:** `~/tmp-t610/etap3-fix/set_all_areas.jq` (jq-фильтр `map` по `identifiers[0][1]`). Применение: `jq -f set_all_areas.jq core.device_registry > …` → HA stop → scp → HA start. + +##### ② Office table switch не управлял светом — ДВЕ причины + +**Симптом (Alex):** «office table switch не управляет светом в кабинете». + +**Причина A — hex-`entity_id` в ТРИГГЕРАХ автоматизаций.** Триггеры `office_pass_switch_table`/`_main` ссылались на **hex**: +```yaml +entity_id: switch.0xa4c13873b5c1575b_l1 # ← в реестре уже switch.office_table_light_switch_l1 +``` +При переименовании реестра я поправил `entity_id` в **actions** и **device-триггерах** (`platform: state` с `device_id`), но **НЕ в обычных `platform: state`-триггерах**. HA загрузил автоматизацию, но подписался на несуществующую сущность → кнопка не срабатывала. +> 🔑 **Правило проверки:** после переименования `entity_id` грепать **весь** `automations.yaml` + `scripts.yaml` на `[a-z_]+\.0x[0-9a-f]{16}` — не только `device_id`, не только actions. Найдено ровно 2 (строки 46, 60). + +**Причина B — `unknown` у реле из-за пассивной публикации z2m (см. ③).** Триггер имел `not_from: [unavailable, unknown]` → пока состояние `unknown`, он **не сработает по определению**. + +**Проверка на живом (рабочий рецепт):** +```bash +# слушаем топики, Alex физически нажимает кнопки +ssh root@192.168.2.176 'timeout 60 mosquitto_sub -h core-mosquitto -u zont -P "…" \ + -t "zigbee2mqtt/office_table_light_switch/#" -t "zigbee2mqtt/smart_light_office/#" -v' +# → state_l1/state_l2 (office_table_light_switch идут как state_l1/l2) +# → state_left/state_right (smart_light_office) + +# управление светом через HA (проверка цепочки light → switch_as_x → z2m → реле) +curl -s -X POST -K curl.auth -H "Content-Type: application/json" \ + http://192.168.2.176/api/services/light/turn_on -d '{"entity_id":"light.smart_light_office_left"}' +``` +**Результат:** `light.smart_light_office_left` off→on→off, `switch.smart_light_office_left` off→on→off — **цепочка работает целиком**. + +> ℹ️ Разные устройства публикуют **разные имена полей**: `office_table_light_switch` (TS0002) → `state_l1`/`state_l2`; `smart_light_office` (TS0012) → `state_left`/`state_right`. Discovery z2m генерирует корректный `value_template` под каждое — трогать не нужно. + +##### ③ z2m НЕ публикует состояние пассивно → реле «залипают» в `unknown` + +**Ключевое открытие сессии.** После перезапуска HA все `switch.*` (реле) были `unknown`, при этом устройства **живы** (`lastSeen` в секундах). +**Причина:** z2m публикует payload **только при получении данных от устройства**. Питаемые реле не отчитываются сами по себе — ждут события (нажатия) или запроса. +**Лечение (практическое):** после перезапуска **физически нажать кнопки** на реле — сеть «прогревается», все `unknown` уходят. Проверено: `switch.office_table_light_switch_l1/l2` стали `on`, `switch.smart_light_office_left/right` — `off`. + +> 🔑 **Диагностический приём:** чтобы понять, жив ли узел, смотреть **`lastSeen` в `database.db`** (`/config/zigbee2mqtt/database.db`, JSON-lines, читать **построчно** — это НЕ единый JSON!): +> ```bash +> while IFS= read -r line; do +> echo "$line" | jq -r 'select(.type=="EndDevice" or .type=="Router") | "\(.ieeeAddr)\t\(.lastSeen // "нет")"' +> done < db.json +> ``` +> `lastSeen` обновляется по **любым** пакетам → зелёный флаг живости, даже если `state` в HA = `unknown`. + +**Итог по всем трём:** `light.smart_light_office_left/right`, `switch.*_office_table_light_switch_l1/l2`, `switch.smart_light_office_left/right` — все корректны, цепочка управления проверена. Зоны проставлены (18 устройств). Розетка котельной видна (её не было в UI именно из-за `area_id = null`). + +> ℹ️ После правок реестров **обновить страницу в браузере (Ctrl+Shift+R)** — UI держит кэш и может не показать новые зоны сразу. + ### Этап 4 — проверка и отключение TrueNAS 18. [ ] Чек-лист из родительского плана §6 19. [ ] Caddy upstream → t610; GPON-редирект → t610 @@ -880,6 +966,9 @@ update.0xa4c1381694217e10 -> update.boiler_controller_power - [x] ✅ **ВЫПОЛНЕНО 2026-09-14 (поздняя сессия) — Zigbee-розетка `boiler_controller_power` добавлена** (`0xa4c1381694217e10`, TS011F, зона Котельная) как питание контроллеров котлов; 13 сущностей переименованы из hex. **Итого z2m = 15 устройств, реестр = 332 сущности, hex = 0.** - [ ] ⏸️ **ГЛАВНЫЙ ОСТАВШИЙСЯ БЛОКЕР (аппаратный, за Alex):** 32 заслонки вентиляции `unavailable` — шина не отвечает (exception 0x0B). Подключить линии A/B к CH340 #2 (`by-path ...0:4:1.0-port0`, slave 11). Конфиг верный, оживут сами. - [ ] Камера (§8 родительского плана) — не аддон, разбираться отдельно +- [x] ✅ **ВЫПОЛНЕНО 2026-09-14 (конец сессии) — ЗОНЫ восстановлены у 18 устройств.** `area_id` теряется при ре-регистрации устройств (как `device_id`) — все 14 zigbee были без зон. Проставлены по эталону с TrueNAS по `identifiers[0][1]` (`zigbee2mqtt_`). Скрипт: `~/tmp-t610/etap3-fix/set_all_areas.jq`. +- [x] ✅ **ИСПРАВЛЕНО 2026-09-14 (конец сессии) — office-переключатель:** hex-`entity_id` в **триггерах** автоматизаций (`switch.0xa4c13873b5c1575b_l1/l2` → `switch.office_table_light_switch_l1/l2`); реле выведены из `unknown` нажатием кнопок. Цепочка управления светом проверена на живом. +- [x] ✅ **УСТАНОВЛЕНО 2026-09-14 (конец сессии) — z2m не публикует состояние пассивно:** реле «залипают» в `unknown` до первого события. Живость проверять по `lastSeen` в `database.db` (JSON-lines, читать построчно). - [ ] ⚠️ Незакреплённое: `sensor.0xa4c138f8da8bc478_voltage/energy/power/current` (11 hex-сущностей розетки Насос обратки) — проживут ли под новым `friendly_name` или создадутся дубли; проверить после шага 8. ## Связанные заметки