diff --git a/family/plans/t610-addons-deployment.md b/family/plans/t610-addons-deployment.md index 7f3fee97..a3d0a93b 100644 --- a/family/plans/t610-addons-deployment.md +++ b/family/plans/t610-addons-deployment.md @@ -16,7 +16,7 @@ related: --- # t610 — развёртывание через HA-аддоны -> **Статус (2026-09-14): Этап 1 ✅. Этап 2 ✅ ПОЛНОСТЬЮ. Этап 3 🚧 ПОЧТИ ЗАКРЫТ — файлы залиты, HA запущен (248 сущностей, 11 зон, 0 ошибок). Осталась одна операция: правка `friendly_name` в z2m.** Удалено мёртвое `Mini Smart Switch 1`, добавлена Zigbee-розетка `0xa4c138eb6fbe9d19` (z2m = 16 устройств). Имена согласованы. Ключевое открытие: **сущности связаны по `unique_id`, поэтому смена `friendly_name` НЕ пересоздаёт `entity_id`** — человеческие имена из реестра сохранятся. Сервисы: z2m (16), 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. Осталось: правка ссылки `light.bed_dimmer` в дашборде, проверка автоматизаций, Этап 4.** Сервисы: z2m (14), mbusd (502), modbus-bridge (MQTT + HA-опрос), MQTT-интеграция в HA. > Родительский план: [[family/plans/home-automation-migration-t610]] (Шаг 3 в нём заменяется на этот документ). > Доступ к хосту, CLI и питфоллы: [[family/how-to/t610-access]]. @@ -350,7 +350,7 @@ curl -s -X POST -H "Authorization: Bearer $T" -H "Content-Type: application/json 5. ✅ Залиты конфиги + `www/` (3 файла) 6. ✅ `ha core check` — ошибок нет; `ha core start` → веб `200` 7. ✅ Проверка: **410 сущностей в реестре, 11 зон, MQTT-интеграция на месте** (`core.config_entries` не тронут) -8. ⏳ **ОСТАЛОСЬ:** `friendly_name` в z2m = человеческие имена + чистка hex-остатков в HA +8. ✅ **ВЫПОЛНЕНО 2026-09-14:** `friendly_name` в z2m = человеческие имена (14 устройств) + переименование всех hex-`entity_id` в реестре HA → **hex-сущностей 0**. **Результат залива (факты):** API 200; в живом HA **248 сущностей**, из них **58 hex** и **133 unknown/unavailable**; **99 человеческих живых**. Ошибок в `home-assistant.log` нет. @@ -523,9 +523,81 @@ timeout 10 mosquitto_sub -h core-mosquitto -p 1883 -u zont -P "$MPW" \ **Автоматизации TrueNAS (`automations.yaml`, 15 шт.):** Выключить/Включить циркуляцию ГВС, Ventilation automation on, office_pass_switch_table/main, Светло/Темно подсветку лестницы, Toggle/Cycle Dimmer bed, Вкл./Выкл. ночной свет душевая, Протечка котельная, Датчик протечки котельная батарея, Датчик освещённости лестница батарея, Light switch bed батарея, Zigbee T sensor батарея. **Дашборд `home_plan` — правки ссылок (статус 2026-09-14):** -- ✅ `switch.vvod_vody_greiushchii_kabel` → **`heating_cable_plug`** — **СДЕЛАНО** (в staged-файле перед заливом, скрипт `fix_dashboard.py`) -- ⏳ `binary_sensor.0xa4c1383d5fcaa063_water_leak` → `boiler_water_leak` — заменится автоматически после смены `friendly_name` в z2m (шаг 8) -- ⏳ `switch.0xa4c138f8da8bc478` → `nasos_obratki` — то же +- ✅ `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` — в дашборде ОК (человеческое) + +#### ✅ ФИНАЛ: имена приведены к единому виду (2026-09-14) + +**Результат:** +| Показатель | Значение | +|---|---| +| Hex-`entity_id` в реестре HA | **0** (было 126) | +| Сущностей в реестре | 319 | +| Устройств в z2m | **14 живых** (было 17 — удалены 3 мёртвых) | +| `friendly_name` в z2m | все человеческие, латиница snake_case | + +**Итоговая таблица (14 устройств, СОГЛАСОВАНО Alex):** + +| IEEE | `friendly_name` | Роль | Зона | +|---|---|---|---| +| `0xa4c13862d39377e6` | `office_temperature_sensor` | датчик t°/влажности (в кабинете, временно) | Кабинет | +| `0xa4c138f8da8bc478` | `recirculation_pump` | розетка насоса обратки (P/V/I/E) | Котельная | +| `0x84fd27fffed9e137` | `night_light_shower_2` | ночной свет | Душевая | +| `0xa4c1386d40ddb67b` | `light_sensor_stairs` | датчик освещённости | Лестница | +| `0xa4c1381186ed1a32` | `smart_light_office` | выключатель 2-кл | Кабинет | +| `0xa4c13873b5c1575b` | `office_table_light_switch` | реле 2 канала L1/L2 | Кабинет | +| `0xa4c13807b64c7fd4` | `kitchen_hood` | реле 3 канала (вытяжка) | Кухня | +| `0xa4c1386d0839706a` | `light_stairs` | реле (лестница) | Лестница | +| `0xa4c1384fbe0b3a6b` | `sauna` | розетка без мониторинга | Туалет | +| `0xa4c138b0f9e674a5` | `wireless_light_switch_bed` | беспроводной выключатель | Спальня | +| `0xa4c13882a4b42db0` | `bed_dimmer` | диммер 1 канал | Спальня | +| `0xa4c138c4a94a6a31` | `shower_2_presence_sensor` | радар присутствия | Душевая | +| `0xa4c1383d5fcaa063` | `boiler_water_leak` | датчик протечки | Котельная | +| `0xa4c138eb6fbe9d19` | `heating_cable_plug` | NEO NAS-WR01B, розетка греющего кабеля | — | + +**Удалены как мёртвые (3 шт., `lastSeen` 5–8 месяцев назад, не используются ни в одной автоматизации/дашборде):** +`0xcc86ecfffe1347fd` (Mini Smart Switch 1), `0xa4c138dc6d856eca` (Presense Sensor 1, радар), `0xa4c138cefeee19fd` (Zigbee dimmer 2ch). Все три были `unavailable`/`unknown`, `state.json` пуст. + +#### 🔑 КЛЮЧЕВОЙ МЕХАНИЗМ: почему HA не переименовал сущности сам + +**HA связывает сущность по `unique_id`, а `entity_id` — вторичен.** z2m при смене `friendly_name` **НЕ меняет `unique_id`** (он вида `__zigbee2mqtt`). Значит: +- Смена `friendly_name` меняет MQTT-топики (`state_topic`) и `default_entity_id` в discovery. +- Но HA видит **тот же `unique_id`** → считает сущность существующей и **НЕ переименовывает её `entity_id`**. +- Итог: после смены имён в z2m (шаг 1) надо **вручную переименовать `entity_id` в реестре HA** (шаг 2). + +**Порядок (выполнен):** +1. ✅ Заменить `devices:` в `/config/zigbee2mqtt/configuration.yaml` (friendly_name = человеческие) → `ha apps restart 45df7312_zigbee2mqtt`. Проверка: z2m публикует в `zigbee2mqtt/`, `bridge/devices` показывает человеческие имена. +2. ✅ `ha core stop` → переименовать `entity_id` в `core.entity_registry` (regex `.[_suffix]` → `.[_suffix]`) → `ha core start`. + +**Команда переименования (jq, т.к. python3 в аддоне НЕТ):** +```bash +REG=/config/.storage/core.entity_registry +cp "$REG" "${REG}.bak-rename-$(date +%Y%m%d-%H%M%S)" +MAP='{"0xa4c13862d39377e6":"office_temperature_sensor", ...}' +jq --argjson map "$MAP" ' + .data.entities |= map( + if (.entity_id | test("^[a-z_]+\\.0x[0-9a-f]+")) then + (.entity_id | capture("^(?[a-z_]+)\\.(?0x[0-9a-f]+)(?.*)$")) as $m + | if $map[$m.h] != null then .entity_id = ($m.d + "." + $map[$m.h] + $m.s) else . end + else . end + )' "$REG" > /tmp/reg.new.json +# проверить: jq -e '(.data.entities|length) > 300' /tmp/reg.new.json +cp /tmp/reg.new.json "$REG"; chown root:root "$REG"; chmod 644 "$REG" +``` +Скрипты: `~/tmp-t610/{gen_names.py,do_rename_jq.sh,apply_names.sh,build_z2m_config.py}`, `z2m-new-config.yaml`. + +⚠️ **Питфолл jq:** конструкция `(.entity_id) as $eid | capture(...)` падает с `object cannot be matched, not a string` — нужно `if (.entity_id | test(...)) then (.entity_id | capture(...)) as $m | ...`. + +⚠️ **Питфолл bash:** круглые скобки в `echo "..."` ломают скрипт (`syntax error near unexpected token '('`) — избегать `()` в строках вывода. + +#### ℹ️ Наблюдение: `unknown` у части сущностей — НЕ баг + +После переименования часть сущностей остаётся `unknown`, при этом `sensor.X_voltage` работает, а `switch.X` — нет. Это **нормально**: z2m публикует payload **только при получении данных от устройства**. Router'ы (питаемые от сети) отчитываются постоянно, EndDevice (батарейные) — редко/по событию. `switch.sauna` вечно `unknown`, потому что розетка **физически отключена** (`lastSeen` 8+ часов). Проверка живости: `jq` по `database.db` → `lastSeen` в мс. + +#### ✅ Zigbee `friendly_name` — корень generic-имён (разведка 2026-09-14) > 📌 Дашборд ссылается на сущности по человеческим именам, которые уже есть в реестре (`switch.sauna`, `light.smart_light_office_left`, `light.smart_light_stairs_l1`, `binary_sensor.shower_2_presence_sensor_presence`). После шага 8 всё оживёт.