[2026-09-14] eagle: family/how-to/t610-access.md family/plans/t610-addons-deployment.md

This commit is contained in:
Alexey Martemyanov
2026-09-14 11:44:50 +06:00
parent 9c624d4ada
commit 2158d683da
2 changed files with 107 additions and 3 deletions
+21
View File
@@ -457,6 +457,27 @@ ha core start # curl http://192.168.2.176/ → 200
**Порядок критичен:** сначала реестры, **потом** (после старта HA) правка `friendly_name` в z2m и `entity_id` в HA. Переименование до переноса реестров пропадёт — HA перезапишет реестр. **Порядок критичен:** сначала реестры, **потом** (после старта 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 '<uuid>'` и получают `unavailable`.
**Лечение:** перемапить `device_id` в `automations.yaml`/`scripts.yaml` по `identifiers` (`[["mqtt","zigbee2mqtt_<ieee>"]]`):
```bash
jq -r '.data.devices[] | select((.identifiers|tostring)|contains("<ieee_без_0x>")) | [.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 `<ieee>_<param>_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) ### 🔍 Где искать человеческие имена устройств (важный урок 2026-09-14)
**В реестрах HA имён устройств НЕТ.** Проверено на TrueNAS: `core.entity_registry` содержит `original_name` = имя **параметра** («Температура», «Влага», «Занятость»), а не устройства; `name`/`name_by_user``null`. Все 16 датчиков t° называются «Температура» → **по `original_name` устройство не определить.** **В реестрах HA имён устройств НЕТ.** Проверено на TrueNAS: `core.entity_registry` содержит `original_name` = имя **параметра** («Температура», «Влага», «Занятость»), а не устройства; `name`/`name_by_user``null`. Все 16 датчиков t° называются «Температура» → **по `original_name` устройство не определить.**
+86 -3
View File
@@ -16,7 +16,9 @@ related:
--- ---
# t610 — развёртывание через HA-аддоны # 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 в нём заменяется на этот документ). > Родительский план: [[family/plans/home-automation-migration-t610]] (Шаг 3 в нём заменяется на этот документ).
> Доступ к хосту, CLI и питфоллы: [[family/how-to/t610-access]]. > Доступ к хосту, 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`) -`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`** — СДЕЛАНО (автоматически переименованием реестра) -`binary_sensor.0xa4c1383d5fcaa063_water_leak`**`binary_sensor.boiler_water_leak_water_leak`** — СДЕЛАНО (автоматически переименованием реестра)
-`switch.0xa4c138f8da8bc478`**`switch.recirculation_pump`** — СДЕЛАНО (то же) -`switch.0xa4c138f8da8bc478`**`switch.recirculation_pump`** — СДЕЛАНО (то же)
- `light.0xa4c13882a4b42db0`**`light.bed_dimmer`** — осталось поправить ссылку в дашборде (в реестре переименовано, в дашборде ещё hex) - `light.0xa4c13882a4b42db0`**`light.bed_dimmer`** — **СДЕЛАНО** (`fix_dash2.sh`, jq-walk по `.data.config`; `sed` не использовали)
- `light.smart_light_stairs_l1` — в дашборде ОК (человеческое) - `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("<ieee_без_0x>")) | [.id, (.name//"—")] | @tsv' \
/config/.storage/core.device_registry
```
Связь: `identifiers` = `[["mqtt","zigbee2mqtt_<ieee>"]]``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) #### ✅ ФИНАЛ: имена приведены к единому виду (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 всё оживёт. > 📌 Дашборд ссылается на сущности по человеческим именам, которые уже есть в реестре (`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 ### Этап 4 — проверка и отключение TrueNAS
18. [ ] Чек-лист из родительского плана §6 18. [ ] Чек-лист из родительского плана §6
19. [ ] Caddy upstream → t610; GPON-редирект → t610 19. [ ] Caddy upstream → t610; GPON-редирект → t610