From 2158d683daa29c69db7afce4fd91ebfe2a199805 Mon Sep 17 00:00:00 2001 From: Alexey Martemyanov Date: Mon, 14 Sep 2026 11:44:50 +0600 Subject: [PATCH] [2026-09-14] eagle: family/how-to/t610-access.md family/plans/t610-addons-deployment.md --- family/how-to/t610-access.md | 21 ++++++ family/plans/t610-addons-deployment.md | 89 +++++++++++++++++++++++++- 2 files changed, 107 insertions(+), 3 deletions(-) diff --git a/family/how-to/t610-access.md b/family/how-to/t610-access.md index 6ab225f4..d46ebaf3 100644 --- a/family/how-to/t610-access.md +++ b/family/how-to/t610-access.md @@ -457,6 +457,27 @@ ha core start # curl http://192.168.2.176/ → 200 **Порядок критичен:** сначала реестры, **потом** (после старта HA) правка `friendly_name` в z2m и `entity_id` в HA. Переименование до переноса реестров пропадёт — HA перезапишет реестр. +### 🔴 Питфоллы переноса HA-конфига между инстансами (2026-09-14, дорого выучено) + +**1. `device_id` НЕ переносятся.** `device_id` — UUID, генерируемый HA при регистрации устройства **в конкретном инстансе**. Даже с перенесённым `core.device_registry` MQTT-интеграция на новом хосте регистрирует устройства заново → выдаёт **новые** `device_id`. +**Следствие:** все автоматизации/скрипты с device-триггерами (в UI это почти все) падают с `Unknown device ''` и получают `unavailable`. +**Лечение:** перемапить `device_id` в `automations.yaml`/`scripts.yaml` по `identifiers` (`[["mqtt","zigbee2mqtt_"]]`): +```bash +jq -r '.data.devices[] | select((.identifiers|tostring)|contains("")) | [.id, (.name//"—")] | @tsv' \ + /config/.storage/core.device_registry +``` +Проверить битые ссылки: `ha core logs 2>&1 | grep "Unknown device"`. +⚠️ `entity_id` и `unique_id` — переносятся; `area_id`/`floor_id` — переносятся (задаются в реестре); `device_id` — **НЕТ**. + +**2. `core.config_entries` нужен, если есть виртуальные сущности.** `switch_as_x`, `template`, helper'ы ссылаются на entry в `core.config_entries`. Не перенесёшь → сущности-сироты `unavailable`. +⚠️ **Конфликт:** на новом хосте `core.config_entries` свой (там свежая MQTT-интеграция). Если перенести целиком — потеряешь локальные интеграции; если не перенести — потеряешь `switch_as_x`/helpers. **Решение:** не переносить целиком, а **точечно добавить** нужные entry (мы так добавили 4 `switch_as_x`). + +**3. HA не переименовывает `entity_id` при смене `friendly_name`.** Связь — по `unique_id` (у z2m `__zigbee2mqtt`, не меняется). Смена `friendly_name` меняет MQTT-топики и `default_entity_id` в discovery, но `entity_id` в реестре остаётся старым → переименовывать вручную (`jq` по `core.entity_registry`). + +**4. `switch_as_x` с hex-ссылкой.** Восстановленные entry могут ссылаться на старое hex-имя (`switch.0x84...`) → обязательно поправить `options.entity_id` на новое человеческое имя. + +**Общий вывод для будущих переносов HA:** либо переносить конфиг+реестры **вместе с `core.config_entries`**, либо после переноса делать **два фикса**: (а) перемап `device_id`, (б) добор виртуальных entry. Иначе половина автоматизаций будет `unavailable`. + ### 🔍 Где искать человеческие имена устройств (важный урок 2026-09-14) **В реестрах HA имён устройств НЕТ.** Проверено на TrueNAS: `core.entity_registry` содержит `original_name` = имя **параметра** («Температура», «Влага», «Занятость»), а не устройства; `name`/`name_by_user` — `null`. Все 16 датчиков t° называются «Температура» → **по `original_name` устройство не определить.** diff --git a/family/plans/t610-addons-deployment.md b/family/plans/t610-addons-deployment.md index a3d0a93b..b646135f 100644 --- a/family/plans/t610-addons-deployment.md +++ b/family/plans/t610-addons-deployment.md @@ -16,7 +16,9 @@ related: --- # t610 — развёртывание через HA-аддоны -> **Статус (2026-09-14): Этап 1 ✅. Этап 2 ✅ ПОЛНОСТЬЮ. Этап 3 ✅ ОСНОВНОЕ ВЫПОЛНЕНО — реестры и конфиг перенесены, БД с нуля, `localtuya`/HACS сняты, z2m приведён к **14 живым** устройствам (удалены 3 мёртвых), все `entity_id` в HA переименованы в человеческие (**hex = 0**), `friendly_name` в z2m — латиница snake_case. Осталось: правка ссылки `light.bed_dimmer` в дашборде, проверка автоматизаций, Этап 4.** Сервисы: z2m (14), mbusd (502), modbus-bridge (MQTT + HA-опрос), MQTT-интеграция в HA. +> **Статус (2026-09-14): Этап 1 ✅. Этап 2 ✅ ПОЛНОСТЬЮ. Этап 3 ✅ ОСНОВНОЕ ВЫПОЛНЕНО — реестры и конфиг перенесены, БД с нуля, `localtuya`/HACS сняты, z2m приведён к **14 живым** устройствам (удалены 3 мёртвых), все `entity_id` в HA переименованы в человеческие (**hex = 0**), `friendly_name` в z2m — латиница snake_case, `switch_as_x` восстановлены (виртуальные `light.*` работают), дашборд поправлен.** +> ⚠️ **ОСТАЛОСЬ ПОЧИНИТЬ (блокер): 13 из 16 автоматизаций `unavailable` — ссылаются на `device_id` с TrueNAS, которых нет на t610.** Маппинг собран, см. §«ПИТФОЛЛ: device_id ломаются при переносе реестра». Далее: `sensor.*_summary` template-ошибки (`default(0)`), Этап 4. +> Сервисы: z2m (14), mbusd (502), modbus-bridge (MQTT + HA-опрос), MQTT-интеграция в HA. > Родительский план: [[family/plans/home-automation-migration-t610]] (Шаг 3 в нём заменяется на этот документ). > Доступ к хосту, CLI и питфоллы: [[family/how-to/t610-access]]. @@ -526,8 +528,73 @@ timeout 10 mosquitto_sub -h core-mosquitto -p 1883 -u zont -P "$MPW" \ - ✅ `switch.vvod_vody_greiushchii_kabel` → **`switch.heating_cable_plug`** — СДЕЛАНО (в staged-файле, скрипт `fix_dashboard.py`) - ✅ `binary_sensor.0xa4c1383d5fcaa063_water_leak` → **`binary_sensor.boiler_water_leak_water_leak`** — СДЕЛАНО (автоматически переименованием реестра) - ✅ `switch.0xa4c138f8da8bc478` → **`switch.recirculation_pump`** — СДЕЛАНО (то же) -- ⏳ `light.0xa4c13882a4b42db0` → **`light.bed_dimmer`** — осталось поправить ссылку в дашборде (в реестре переименовано, в дашборде ещё hex) -- ⏳ `light.smart_light_stairs_l1` — в дашборде ОК (человеческое) +- ✅ `light.0xa4c13882a4b42db0` → **`light.bed_dimmer`** — **СДЕЛАНО** (`fix_dash2.sh`, jq-walk по `.data.config`; `sed` не использовали) +- ✅ `light.smart_light_stairs_l1` — в дашборде ОК (человеческое) + +**Итог по дашборду:** hex-ссылок в `lovelace.home_plan` **не осталось** (проверено `grep '"entity": *"[^"]*0x'` → пусто). + +#### ✅ `switch_as_x` восстановлены (2026-09-14) — виртуальные `light.*` + +**Симптом:** `light.night_light_shower_2`, `light.smart_light_office_left/right`, `light.smart_light_stairs_l1` были `unavailable`. + +**Причина:** эти сущности — `platform: switch_as_x` (виртуальный «выключатель как свет»), созданные вручную на TrueNAS. Их `config_entry_id` ссылался на записи в `core.config_entries`, которых мы **не переносили** → сущности-сироты. + +**Фикс:** на TrueNAS найдено 4 entry `switch_as_x`, добавлены в t610 (с исправлением hex-ссылки): + +| title | `options.entity_id` | +|---|---| +| `Office table light` | `switch.smart_light_office_right` | +| `Office main light` | `switch.smart_light_office_left` | +| `0x84fd27fffed9e137` | → исправлено на `switch.night_light_shower_2` | +| `L1` | `switch.light_stairs_l1` | + +Порядок: `ha core stop` → добавить entry в `core.config_entries` → `ha core start`. Результат: все 5 `light.*` работают (`off` вместо `unavailable`). +Скрипты: `~/tmp-t610/{add_switchasx.py,apply_switchasx.sh}`, данные `t610-config-entries-new.json`. + +⚠️ **Питфолл:** при переносе реестров **`core.config_entries` тоже нужен**, если есть виртуальные сущности (`switch_as_x`, `template`, helper'ы) — иначе их entry теряются и сущности висят `unavailable`. Мы не переносили его ради сохранения MQTT-интеграции → добавляли `switch_as_x` точечно. + +#### 🔴 ПИТФОЛЛ: `device_id` ломаются при переносе реестра (ОТКРЫТО, 2026-09-14) + +**Симптом:** после переноса реестров и старта HA **13 из 16 автоматизаций стали `unavailable`**. В `ha core logs`: +``` +ERROR (MainThread) [homeassistant.components.automation] Automation with alias 'Протечка котельная' +failed to setup triggers and has been disabled: Unknown device 'c42ce32c73731941884bcbf0c2b2d077' +``` + +**Причина:** `device_id` — это **UUID, генерируемый HA при регистрации устройства в КОНКРЕТНОМ инстансе**. Хотя `core.device_registry` перенесён с TrueNAS, MQTT-интеграция t610 **зарегистрировала устройства заново** (запись MQTT-интеграции у нас своя, t610-шная) → выдала **новые** `device_id`. Реестр потом перезаписался перенесённым, но `device_id` в нём остались TrueNAS-овские... а фактические — другие. + +⚠️ **Главный вывод: `device_id` НЕ переносятся между инстансами HA.** `entity_id` и `unique_id` — переносятся; `device_id` — НЕТ. Автоматизации/скрипты, ссылающиеся на `device_id` (а это все device-trigger'ы в UI), ломаются. + +**Маппинг (TrueNAS → t610), собран 2026-09-14:** + +| Устройство | `device_id` в автоматизациях (TrueNAS) | Актуальный на t610 | +|---|---|---| +| `recirculation_pump` (Насос обратки, `f8da8bc478`) | `234686e6c83f7d19c9e10b2f0d1fcc59` | `16d2c6f64ec399e5261c89b35c1e75c6` | +| `light_sensor_stairs` (`6d40ddb67b`) | `7f102ad2e78960fff6ebc5f01c0bba93` | `1ea8bbc2612dde303e4279bc5fbad57a` | +| `boiler_water_leak` (`3d5fcaa063`) | `c42ce32c73731941884bcbf0c2b2d077` | `b9d384a51b780a7924ed9504eddec12e` | +| `shower_2_presence_sensor` (`c4a94a6a31`) | `7f74e7077d7fa23e405f2c5e25f6fa17` | `4095e7c3b47b9dc9640cfb8c3aeff022` | +| `wireless_light_switch_bed` (`b0f9e674a5`) | `757e0e9b1e5771e0c700a9df852b0549` | `5cd5d9d2d289b5e470bbeaac0eb7905c` | +| `office_temperature_sensor` (`62d39377e6`) | `52266a1b4a9d301f0da0dfa6f97c4ea2` | `bcf47eeae909877978bdaf6c705210f8` | + +**Как получить актуальные `device_id` (bash+jq на t610):** +```bash +jq -r '.data.devices[] | select((.identifiers|tostring)|contains("")) | [.id, (.name//"—")] | @tsv' \ + /config/.storage/core.device_registry +``` +Связь: `identifiers` = `[["mqtt","zigbee2mqtt_"]]` → `id` = искомый `device_id`. + +**План починки (НЕ выполнено):** `ha core stop` → заменить 6 UUID в `automations.yaml` (9 вхождений `device_id` + 12 `entity_id`-UUID) и в `scripts.yaml`, если есть → `ha core start` → проверить, что автоматизации `on`. Скрипт писать файлом (в аддоне **нет python3** — только bash+jq). + +⚠️ **Мораль для будущих переносов HA:** либо переносить `core.config_entries` целиком вместе с реестрами (тогда `device_id` согласуются), либо **после переноса обязательно перемапить `device_id`** в `automations.yaml`/`scripts.yaml` по `identifiers`. Мы выбрали не переносить `core.config_entries` (чтобы сохранить MQTT-интеграцию t610) — отсюда и разрыв. + +#### ⚠️ `sensor.*_summary` — TemplateError (косметика, самоизлечится) + +В логе после старта: +``` +TemplateError: ValueError: Template error: round got invalid input 'unknown' +when rendering template '{{ states('sensor.kids_temperature')|round(0)|int }}° ...' +``` +Причина: sniffer-датчики (`kids_*`, `bedroom_*`, `dining_*` — Modbus RTU) ещё не прислали данные → `states()` = `'unknown'`. Уйдёт, когда пойдут значения. Если раздражает — добавить `|default(0)` в `configuration.yaml` (§template, сенсоры `dining_summary`, `kids_summary`, `bedroom_summary`). #### ✅ ФИНАЛ: имена приведены к единому виду (2026-09-14) @@ -601,6 +668,22 @@ cp /tmp/reg.new.json "$REG"; chown root:root "$REG"; chmod 644 "$REG" > 📌 Дашборд ссылается на сущности по человеческим именам, которые уже есть в реестре (`switch.sauna`, `light.smart_light_office_left`, `light.smart_light_stairs_l1`, `binary_sensor.shower_2_presence_sensor_presence`). После шага 8 всё оживёт. +#### 📍 СОСТОЯНИЕ НА КОНЕЦ СЕССИИ 2026-09-14 (для следующей сессии) + +**Факты (проверено API):** HA `http://192.168.2.176` → 200; z2m `started`, 14 устройств; реестр 319 сущностей, **hex = 0**; `light.*` (5 шт.) работают; MQTT-интеграция на месте; `switch_as_x` (4) восстановлены. + +**Счётчики живого API:** 233 сущности, `unavailable` 45, `unknown` 82. + +**🔴 ПЕРВООЧЕРЕДНОЕ (блокер):** починить `device_id` в 13 автоматизациях — см. §«ПИТФОЛЛ: device_id ломаются при переносе реестра». Маппинг из 6 UUID уже собран. + +**Далее:** +1. Проверить `scripts.yaml` на те же битые `device_id` (в нём device-ссылок не нашли, но перепроверить). +2. `sensor.*_summary` — добавить `|default(0)` в template-сенсоры `configuration.yaml` (косметика). +3. Проверить дашборд `home_plan` визуально (ссылки теперь человеческие). +4. Этап 4: Caddy upstream → t610, GPON-редирект → t610, отключить TrueNAS. + +**Ключевые пути/скрипты сессии:** `~/tmp-t610/` — `stage3/out/` (staged комплект), `backups/` (2 tar.gz), `z2m-new-config.yaml`, `do_rename_jq.sh`, `add_switchasx.py`, `apply_switchasx.sh`, `fix_dash2.sh`, `ha_token.txt`, `t610-config-entries.json`. На t610: `/config/.storage/*.bak-*`, `/config/zigbee2mqtt/configuration.yaml.bak-*`, `/tmp/stage3-prev/`. + ### Этап 4 — проверка и отключение TrueNAS 18. [ ] Чек-лист из родительского плана §6 19. [ ] Caddy upstream → t610; GPON-редирект → t610