From 811e02c6b75353baad663cdfd70527b23d0197ba Mon Sep 17 00:00:00 2001 From: Alexey Martemyanov Date: Tue, 15 Sep 2026 20:23:32 +0600 Subject: [PATCH] [2026-09-15] eagle: family/how-to/ha-automations.md family/tech/zigbee-t610-z2m-i-zha.md --- family/how-to/ha-automations.md | 13 +- family/tech/zigbee-t610-z2m-i-zha.md | 198 ++++++++++++++++++++++++--- 2 files changed, 189 insertions(+), 22 deletions(-) diff --git a/family/how-to/ha-automations.md b/family/how-to/ha-automations.md index 819c288a..9165eac9 100644 --- a/family/how-to/ha-automations.md +++ b/family/how-to/ha-automations.md @@ -2,7 +2,18 @@ > **Справочник логики автоматизаций** (`automations.yaml` на t610). Топология/команды/Modbus — [[family/how-to/home-automation]]. -> 🔴 **ВНИМАНИЕ НА 2026-09-15: идёт переезд Zigbee Z2M → ZHA.** Сущности, перечисленные ниже, **сейчас `unavailable`** — они `platform=mqtt` (Z2M) и мертвы. Автоматизации будут бить в пустоту, пока ZHA-сущности не переименованы обратно в эти id. **Порядок восстановления и карта переименования — [[family/tech/zigbee-t610-z2m-i-zha]] §БЛОКЕР.** Не «чинить» автоматизации правкой до завершения переименования — иначе получится двойная миграция ссылок. +> 🔴 **ВНИМАНИЕ НА 2026-09-15 (ночь-14): ПЕРЕЕЗД Zigbee Z2M → ZHA ВЫПОЛНЕН, но АВТОМАТИЗАЦИИ СЛОМАНЫ.** +> +> Сущности переименованы обратно ✅, зоны восстановлены ✅, но **16 автоматизаций всё равно не работают**. Причина не в `entity_id`, а глубже: +> +> **Автоматизации ссылаются на `device_id` + внутренний `entity_id`-UUID** (`fa72bc65e5cf9e9249a5b0d377e5a3f4`), а устройства Z2M **удалены**. Проверено (`verify_state.py`): **все 10 используемых `device_id` — GONE.** +> → Переименование сущностей такие автоматизации **не лечит**. Нужна замена `device_id` + UUID на ZHA-шные. +> +> **Единственное исключение:** `office_pass_switch_table` / `office_pass_switch_main` ссылаются на `entity_id` напрямую — но их триггер `switch.office_table_light_switch_l1` **не переименовался** (домен `light`→`switch` запрещён HA), так что и они битые. +> +> **Порядок:** 1) собрать карту старый `device_id` → новый (по IEEE); 2) заменить `device_id` + `entity_id`-UUID в `/config/automations.yaml`; 3) reload + проверить `last_triggered`. +> **Бэкап:** `/config/automations.yaml.bak-zha-20260915-211613` ✅ (локально `~/tmp-t610/automations.yaml`). +> Детали и полный список мёртвых `device_id` — [[family/tech/zigbee-t610-z2m-i-zha]] §ОСТАЛОСЬ. > > Класс сущностей тоже меняется: `switch.night_light_shower_2` → ZHA даёт `light.*`; `switch.recirculation_pump` → ZHA `switch.*` (та же роль); `light.bed_dimmer` → ZHA отдаёт `switch.tz3210_nhqka112_ts011f` (домен `switch`, не `light`). diff --git a/family/tech/zigbee-t610-z2m-i-zha.md b/family/tech/zigbee-t610-z2m-i-zha.md index e38e0c96..ec83fdd2 100644 --- a/family/tech/zigbee-t610-z2m-i-zha.md +++ b/family/tech/zigbee-t610-z2m-i-zha.md @@ -1,10 +1,10 @@ --- -title: "Zigbee на t610 — переезд Z2M → ZHA (в работе, 2026-09-15)" +title: "Zigbee на t610 — переезд Z2M → ZHA (выполнен, 2026-09-15)" created: '2026-09-15' -updated: '2026-09-15 (ночь-13: 📋 ПЛАН УТОЧНЁН — три слоя мусора (mqtt / switch_as_x / ZHA), полная карта переименования построена по IEEE, ждём ответа Alex на 3 вопроса)' +updated: '2026-09-15 (ночь-14: ✅ МИГРАЦИЯ ВЫПОЛНЕНА — три слоя мусора удалены, сущности и УСТРОЙСТВА переименованы, зоны восстановлены. Осталось: автоматизации (device_id мёртвые) + 4 батарейных)' type: tech namespace: family -status: 🟡 ПЕРЕЕЗД ИДЁТ — ZHA создана, 12 из 16 устройств приняты автоматически. Блокер: entity_id заняты мёртвыми Z2M-двойниками. План из 4 шагов составлен, ожидает подтверждения на удаление мёртвых сущностей. +status: 🟢 ПЕРЕЕЗД ВЫПОЛНЕН — ZHA работает, 12 устройств приняты автоматически, мусор Z2M удалён, сущности + устройства + зоны переименованы/восстановлены. Осталось: переназначить device_id в 16 автоматизациях (ссылаются на удалённые Z2M-устройства) и разбудить 4 батарейных. tags: - t610 - haos @@ -23,12 +23,14 @@ related: # Zigbee на t610 — переезд Z2M → ZHA (история + рабочий рецепт) -> 🚦 **СОСТОЯНИЕ НА 2026-09-15 (ночь-12) — ПЕРЕЕЗД ИДЁТ:** -> - ZHA создана **повторно** (`entry_id` `01M2JP57Y2FGSD17P829HFV44N`, `reuse_settings`), сеть взята со стика. -> - 🔑 **ZHA САМА подхватила 12 из 16 устройств** — **без «Add device», без окна спаривания, без перепаривания**. Это главный факт сессии: перепаривание не нужно вообще. -> - Имена, которые дала ZHA: **технические** (`light.tz3000_5gey1ohx_ts0002_osveshchenie`), потому что `friendly_name` из Z2M она не читает. -> - **Блокер:** старые `entity_id` **заняты мёртвыми Z2M-двойниками** (`unavailable`) → переименовать нельзя, пока они на месте. -> - ⚠️ Z2M **остановлен**, не удалён. Данные целы. +> 🚦 **СОСТОЯНИЕ НА 2026-09-15 (ночь-14) — ПЕРЕЕЗД ВЫПОЛНЕН:** +> - ✅ **Три слоя мусора удалены:** 127 сущностей `platform=mqtt` + 18 устройств-призраков Z2M. Реестр: 624 → 493 сущности, 52 → 34 устройства. +> - ✅ **13 modbus-датчиков СОХРАНЕНЫ** (проверено фактом: пишут данные) — они тоже `platform=mqtt`, но живые. +> - ✅ **51 операция переименования сущностей:** 42 выполнены, 8 отбиты (`light`→`switch` запрещён HA), 1 пропущена. +> - ✅ **12/12 устройств переименованы** — в UI больше нет `_TZ3000_5gey1ohx TS0002`. Это то, что Alex видел руками. +> - ✅ **12 устройств получили ЗОНЫ обратно** (11 зон целы, все ZHA-устройства были без зоны). +> - ⏳ **Осталось:** 16 автоматизаций ссылаются на удалённые Z2M `device_id` + 4 батарейных не разбужены. +> - ⚠️ Z2M **остановлен**, не удалён. Данные целы в `/config/zigbee2mqtt/`. > 🔴 **ЧИТАТЬ ДАЛЬШЕ И КАК РЕЦЕПТ, И КАК РАЗБОР ОШИБОК.** Ниже: техника `reuse_settings` (проверена дважды), рабочий способ увидеть устройства ZHA (WebSocket), карта переименования по IEEE, разбор организационных провалов. @@ -367,17 +369,163 @@ ZHA их принимает и создаёт сущности — сама, б > ⚠️ **`smart_light_office`: неоднозначность каналов.** ZHA дала `_osveshchenie` и `_osveshchenie_2`, а в Z2M было `left`/`right`. Слепое сопоставление неверно — **проверять вживую**: включить один канал, посмотреть, какая лампа загорелась. > ⚠️ **`bed_dimmer`: смена класса домена.** В Z2M был `light.bed_dimmer` (обёртка `switch_as_x`), в ZHA — `switch.tz3210_nhqka112_ts011f`. Переименование в `light.*` потребует правки `entity_id` вместе с доменом; проверить, что автоматизации ждут именно `light`. -### План из 4 шагов (ожидает подтверждения Alex) +### ✅ План из 4 шагов — ВЫПОЛНЕН (ночь-14) -1. **Удалить слой A** — ~120 мёртвых `platform=mqtt` сущностей + их устройства-призраки. Необратимо. -2. **Удалить слой B** — ~6 `switch_as_x`. Прослойка была под Z2M, ZHA отдаёт `light` сама. -3. **Переименовать слой C** — 16 главных сущностей по таблице выше (второстепенные оставить техническими). -4. **Проверить** 16 автоматизаций + `modbus-bridge`. +1. ✅ **Слой A удалён** — 127 мёртвых `platform=mqtt` сущностей + 18 устройств-призраков Z2M. +2. ✅ **Слой B удалён** — 4 `switch_as_x` (удалились вместе с устройствами). +3. ✅ **Слой C переименован** — 42 сущности получили старые id (8 отбиты, см. ниже). +4. ⏳ **Автоматизации** — 16 штук ссылаются на удалённые `device_id`, требуют пересборки. -**Три вопроса, на которые нужен ответ Alex:** -1. Удалять A и B? (страховка — snapshot `ada4c8e5`) -2. Как развести каналы `smart_light_office` — проверкой вживую? -3. Второстепенные сущности переименовывать или оставить техническими? +--- + +## ✅ ВЫПОЛНЕНО (ночь-14): удаление мусора + переименование + +### Шаг 1 — удаление слоя A и B (необратимо, по команде Alex «все исправляй») + +**Удалено:** 127 сущностей + 18 устройств. +**Результат по реестрам:** 624 → **493** сущности, 52 → **34** устройства. +**Механизм:** `config/entity_registry/remove` + `config/device_registry/remove` по WebSocket, последовательно, с подсчётом успехов. + +> 🔴 **КРИТИЧНО: НЕ всё `platform=mqtt` — мусор Z2M.** Среди mqtt-сущностей нашлись **живые modbus-датчики** (`modbus_dining_sensor`, `modbus_kids_sensor`, `modbus_bedroom_sensor` — модель «Modbus RTU Sniffer / Custom»). Это `modbus-bridge`, они пишут данные прямо сейчас. **Их удаление сломало бы CO2/температуру/влажность в трёх комнатах.** +> +> **Различитель — `identifiers` в device_registry:** +> - `['mqtt', 'zigbee2mqtt_0xA4C138…']` → мёртвые Z2M, **удалять** +> - `['mqtt', 'modbus__sensor']` → живые modbus, **НЕ трогать** +> +> **Проверка перед удалением (обязательна):** прочитать состояния `sensor.dining_*`, `sensor.kids_*`, `sensor.bedroom_*` — если `last_changed` свежий, отлично от `unavailable` у Z2M-призраков, значит живы. + +**Сохранено (13 сущностей):** `sensor.dining_temperature_2`, `_humidity`, `_pm2_5`, `_pm10`, `_formaldehyde`, `_tvoc`, `_co2`; `sensor.kids_co2`, `_temperature`, `_humidity`; `sensor.bedroom_co2`, `_temperature`, `_humidity`. + +### Шаг 3 — переименование сущностей: 42 из 51 + +**Скрипты:** `~/tmp-t610/mk_delete_list.py` (фильтр: оставить modbus), `del_exec.py` (удаление), `mk_rename.py` → `rename-plan.json` (51 операция), `ren_exec.py` (применение), `verify_state.py` (проверка). + +> 🔴 **8 переименований ОТБИТЫ API:** `{'code': 'invalid_info', 'message': 'New entity ID should be same domain'}`. **HA не позволяет менять домен `entity_id`.** ZHA отдаёт 2/3-ганговые модули Tuya как `light.*`, а Z2M давал `switch.*`: +> +> | Не переименовалось | Хотели | +> |---|---| +> | `light.tz3000_5gey1ohx_ts0002_osveshchenie` | `switch.office_table_light_switch_l1` | +> | `light.tz3000_5gey1ohx_ts0002_osveshchenie_2` | `switch.office_table_light_switch_l2` | +> | `light.tz3000_odzoiovu_ts0003_osveshchenie` | `switch.kitchen_hood_l1` | +> | `light.tz3000_odzoiovu_ts0003_osveshchenie_2` | `switch.kitchen_hood_l2` | +> | `light.tz3000_odzoiovu_ts0003_osveshchenie_3` | `switch.kitchen_hood_l3` | +> | `light.tz3000_5gey1ohx_ts0002_osveshchenie_3` | `switch.light_stairs_l1` | +> | `light.tz3000_5gey1ohx_ts0002_osveshchenie_4` | `switch.light_stairs_l2` | +> | `switch.tz3210_nhqka112_ts011f` | `light.bed_dimmer` | +> +> **Решение:** оставить ZHA-домен (`light.*`) или переписать автоматизации на новые имена. **Домены не меняются в принципе** — это ограничение HA, не ZHA. +> 📌 Урок: если Z2M-имя имело домен `switch`, а ZHA даёт `light` — переименование сущности невозможно, только замена ссылок. + +### 🔑 Шаг, который Alex поймал: ИМЯ УСТРОЙСТВА ≠ `entity_id` + +**Alex: «я до сих пор в HA UI вижу девайсы вида `_TZ3000_5gey1ohx TS0002`».** + +Это **две разные вещи в HA**, и я переименовал только первую: + +| Что | Где живёт | Метод WS | +|---|---|---| +| **Имя устройства** | `device_registry` | `config/device_registry/update` → `name_by_user` | +| **`entity_id` сущности** | `entity_registry` | `config/entity_registry/update` → `new_entity_id` | + +> 🔴 **ZHA при `reuse_settings` даёт техническое имя САМОМУ УСТРОЙСТВУ** (`_TZ3000_5gey1ohx TS0002` — конкатенация modelId + manufName). В UI оно видно как заголовок карточки/в списке устройств. Переименование `entity_id` его **не трогает вообще**. +> ✅ **Фикс:** `config/device_registry/update`, поле **`name_by_user`** (не `name`). Скрипты: `~/tmp-t610/devrename_show.py` (карта), `devrename_apply.py` (применение), `devrename_verify.py` (проверка). Результат: **12/12**. + +**Переименованные устройства (device → `name_by_user`):** + +| device_id | было | стало | +|---|---|---| +| `39c0030e33954169d8eff8fda0ac27df` | `_TZ3000_gjnozsaz TS011F` | `recirculation_pump` | +| `fd52114b516a79055c7add0393f2486d` | `_TZ3000_3a9beq8a TS0001` | `night_light_shower_2` | +| `7e86be41536935ed3054aaf0543db04b` | `_TZ3000_0e6uvexf TS0012` | `smart_light_office` | +| `4540b3e9bbb43d90f2ff4f62fa09804e` | `_TZ3000_5gey1ohx TS0002` | `office_table_light_switch` | +| `200ea4fb25daaa907279045e47a330b5` | `_TZ3000_odzoiovu TS0003` | `kitchen_hood` | +| `c18eb99f487691cb7244cd520bfbcde8` | `_TZ3000_5gey1ohx TS0002` | `light_stairs` | +| `700e14b7d1710526b00f098b8506826d` | `_TZ3210_nhqka112 TS011F` | `bed_dimmer` | +| `c9d62c9d04a231c4642c705088633121` | `_TZE204_qasjif9e TS0601` | `shower_2_presence_sensor` | +| `39771e837372d488a1145ab7316fbd23` | `Zbeacon TS0207` | `boiler_water_leak` | +| `dc5f276b6d5f6e4564a3a4ddc1b7a1c9` | `_TZ3000_gjnozsaz TS011F` | `heating_cable_plug` | +| `56a2ab2e500c00737c1fcea12616dd1f` | `_TZ3000_gjnozsaz TS011F` | `boiler_controller_power` | +| `095fcc912178281c8c9c10b554bffb24` | `_TZ3000_dowj6gyi TS0201` | `toilet_1_floor_temperature` | + +> ⚠️ **Два устройства `office_table_light_switch` и `light_stairs` имеют ОДИНАКОВОЕ техническое имя** (`_TZ3000_5gey1ohx TS0002`) — различаются только по IEEE. При переименовании устройств это не мешает (ключ — `device_id`), но в UI до правки они выглядели идентично. + +### ✅ ЗОНЫ ВОССТАНОВЛЕНЫ (ночь-14) + +**Alex: «и зоны не забудь вернуть» / «зоны девайсов».** + +При пересоздании ZHA **все 13 устройств оказались без зоны** (`area_id: null`), хотя реестр зон уцелел полностью. + +> 📌 **Зоны (Areas) НЕ удаляются вместе с устройствами** — это отдельный реестр `area_registry`. Проверено: 11 зон на месте, но пересозданные ZHA-устройства к ним не привязаны. **После любой миграции зоны надо проставлять заново.** + +**Механизм:** `config/device_registry/update` с полем **`area_id`** (строка, `slug` зоны, не имя). Скрипты: `~/tmp-t610/areas_show.py` (снять зоны + состояние привязок), `areas_apply.py` (проставить). + +**11 зон на t610:** `living_room` Гостиная, `kitchen` Кухня, `bedroom` Спальня, `detskaia` Детская, `kabinet` Кабинет, `vannaia` Ванная, `dushevaia` Душевая, `tualet` Туалет, `severnaia` Серая, `kotelnaia` Котельная, `lestnitsa` Лестница. + +**Раскладка устройств по зонам (12 шт):** + +| Зона | Устройства | +|---|---| +| `kotelnaia` Котельная | recirculation_pump, boiler_controller_power, heating_cable_plug, boiler_water_leak | +| `kabinet` Кабинет | office_table_light_switch, smart_light_office | +| `dushevaia` Душевая | night_light_shower_2, shower_2_presence_sensor | +| `lestnitsa` Лестница | light_stairs | +| `tualet` Туалет | toilet_1_floor_temperature | +| `bedroom` Спальня | bed_dimmer | +| `kitchen` Кухня | kitchen_hood | + +> 📌 Координатор `Inswift ZBP-MG21` **без зоны** — стик, ему зона не нужна. + +--- + +## ⏳ ОСТАЛОСЬ (ночь-14): автоматизации + +### Факт: 16 автоматизаций ссылаются на УДАЛЁННЫЕ device_id Z2M + +> 🔴 **ГЛАВНОЕ ОТКРЫТИЕ: автоматизации ссылаются НЕ на `entity_id`, а на `device_id` + внутренний `entity_id`-UUID** (16-символьные хеши вида `fa72bc65e5cf9e9249a5b0d377e5a3f4`). Переименование сущностей **не лечит** их. Все 16 загружены (`state: on`), но бьют в пустоту. + +**Проверено (`verify_state.py`):** все 10 `device_id`, на которые ссылаются автоматизации, — **GONE** (удалены вместе с Z2M-устройствами): + +``` +16d2c6f64ec399e5261c89b35c1e75c6 GONE ← Циркуляция ГВС +1ea8bbc2612dde303e4279bc5fbad57a GONE ← Светло/Темно лестница, батарея датчика +5cd5d9d2d289b5e470bbeaac0eb7905c GONE ← Dimmer bed, батарея кнопки +098a641cb1d30f08f1ae293e00d9885b GONE ← Toggle Dimmer bed +4d6e55505ff7dbad13d2674cdcb18d5a GONE ← Ночной свет душевая +4095e7c3b47b9dc9640cfb8c3aeff022 GONE ← Датчик присутствия душевая +b9d384a51b780a7924ed9504eddec12e GONE ← Протечка котельная +bcf47eeae909877978bdaf6c705210f8 GONE ← Zigbee T sensor батарея +028b7d9f489c87bdc9e563473a1d61e8 GONE ← Подсветка лестницы +f6422d760457b7d8657240135edbb3c3 GONE ← (entity-UUID датчика освещённости) +``` + +**Что реально работает:** только `office_pass_switch_table` / `office_pass_switch_main` — они ссылаются на `entity_id` (`switch.office_table_light_switch_l1/l2`, `light.smart_light_office_left/right`), а эти сущности переименованы ✅. + +> ⚠️ **Нюанс:** `office_pass_switch_*` триггерятся на `switch.office_table_light_switch_l1` — сущностью, которая **не переименовалась** (домен). Ссылка битая. + +**План починки автоматизаций:** +1. Прочитать `automations.yaml` с t610 (`/config/automations.yaml`, 282 строки) — бэкап уже есть: `/config/automations.yaml.bak-zha-20260915-211613` ✅ +2. Построить карту: старый `device_id` → новый `device_id` (по IEEE) +3. Заменить `device_id` + сопутствующие `entity_id`-UUID +4. Перезагрузить автоматизации, проверить `last_triggered` + +**Бэкапы автоматизаций и скриптов:** `/config/automations.yaml.bak-zha-20260915-211613` (7273 б). Локальная копия: `~/tmp-t610/automations.yaml`. + +**Скрипты ночи-14 (`~/tmp-t610/`):** +| Скрипт | Что делает | +|---|---| +| `ws_dump.py` | ✅ реестры по WebSocket (env `HAHOST`/`HAPORT`/`HATOK`) → `regs.json` | +| `collect_delete.py` → `to-delete.json` | сбор кандидатов на удаление (mqtt + switch_as_x + устройства) | +| `inspect_mqtt_devs.py` | 🔑 **разбор `identifiers`: отличить Z2M-призраки от живых modbus** | +| `check_alive.py` | проверка живости датчиков по `last_changed` | +| `mk_delete_list.py` → `delete-list.json` | финальный список с фильтром modbus | +| `del_exec.py` | удаление (127 сущностей + 18 устройств) | +| `mk_rename.py` → `rename-plan.json` | 51 операция переименования (карта по функции) | +| `ren_exec.py` | применение (42/51) | +| `verify_state.py` | проверка: что переименовалось, какие device_id GONE | +| `devrename_show.py` / `devrename_apply.py` / `devrename_verify.py` | 🔑 **переименование УСТРОЙСТВ (`name_by_user`)** | +| `areas_show.py` / `areas_apply.py` | 🔑 **зоны: снять состояние / проставить `area_id`** | +| `mb_check.sh` / `mb_check2.sh` | диагностика modbus-bridge через Supervisor API | +| `read_autos.py` | чтение автоматизаций | **Скрипт:** `~/tmp-t610/rename.py` (WS API, есть `--apply`), карта — `~/tmp-t610/rename-map.json`, построение по IEEE — `~/tmp-t610/map-full.py`. **Скрипты ночи-13:** `~/tmp-t610/ws_dump.py` (реестры по WebSocket, env `HAHOST`/`HAPORT`/`HATOK`), `map_build.py` (ZHA-устройства по IEEE → сверка с `rename-map.json`), `map_ents.py` (сущности на устройство + поиск мёртвых по именам), `plan_build.py` → `plan-rows.json` (сводка по каждому устройству), `plan_show.py` (парное сравнение «старое ↔ ZHA»). @@ -469,11 +617,13 @@ unavailable: 8 — и НИ ОДНА не Zigbee: | 2 | **Все автоматизации с `switch.0xa4c138f8da8bc478` и подобными** | `entity_id` в ZHA будут другие → переписать все ссылки | | 3 | **`modbus-bridge`** | жёстко завязан на Zigbee-сущность `switch.0xa4c138f8da8bc478` (relay slave 104) — сломается | -**Решение 2026-09-15 (НОЧЬ-12, текущее): ПЕРЕЕЗД ИДЁТ.** Alex задачу поставил прямо: «заменить Z2M на ZHA, устройства не спаривать заново» + «БЕЗ ПОТЕРЬ». Техника отработана, **12 из 16 устройств приняты ZHA автоматически**, перепаривание не потребовалось вообще. Осталось: переименовать сущности (блокер — мёртвые двойники) и разбудить 4 батарейных. +**Решение 2026-09-15 (НОЧЬ-14, ТЕКУЩЕЕ): ПЕРЕЕЗД ВЫПОЛНЕН.** Alex задачу поставил прямо: «заменить Z2M на ZHA, устройства не спаривать заново» + «БЕЗ ПОТЕРЬ», затем «все исправляй» и «зоны девайсов». Техника отработана, **12 из 16 устройств приняты ZHA автоматически**, перепаривание не потребовалось. Мусор удалён, сущности и устройства переименованы, зоны восстановлены. Осталось: **16 автоматизаций** (ссылаются на удалённые `device_id`) и **4 батарейных**. -> ⚠️ **Статус: В РАБОТЕ.** Z2M **остановлен**, не удалён — данные целы как страховка. Перед продолжением обязательно прочитать §«Что пошло не так организационно». +> 🟢 **Статус: ПЕРЕЕЗД ВЫПОЛНЕН.** Z2M **остановлен**, не удалён — данные целы как страховка. Осталось: автоматизации + батарейные. Перед продолжением обязательно прочитать §«Что пошло не так организационно». -> ✅ **ФАКТ (проверено дважды):** переезд без перепаривания **работает**. ZHA создана стратегией `reuse_settings`, сеть поднята со стика, **12 устройств приняты автоматически** с техническими именами. Ни одно устройство не спаривалось заново. Блокер — не техника, а **занятые entity_id**. +> ✅ **ФАКТ (проверено дважды):** переезд без перепаривания **работает**. ZHA создана стратегией `reuse_settings`, сеть поднята со стика, **12 устройств приняты автоматически** с техническими именами. Ни одно устройство не спаривалось заново. Блокер был не в технике, а в **занятых entity_id** — теперь снят. + +> ✅ **ФАКТ (ночь-14):** `modbus-bridge` **не сломался** — он ссылается на `switch.recirculation_pump`, а это имя восстановлено переименованием. Аддон `state=started`, правок не потребовал. (Прогноз «сломается» не подтвердился.) > ❌ **Отменено прежнее решение «Z2M остаётся, выигрыш 0»** — Alex его отверг: HA штатно поддерживает Zigbee, и он хочет убрать Z2M как отдельный слой. Причина переезда — архитектурная, не функциональная. @@ -591,6 +741,12 @@ state.json MD5 20bfb775cbab002e59d1be31a15db9e6 25. ⚠️ **Тип `Router` в Z2M-инвентаре не гарантирует, что устройство отзовётся ZHA.** `sauna` числится Router'ом, но в сеть не вернулась. Проверять по WebSocket-реестру фактом. 26. 🔴 **Токен НЕ передавать в python через argv/файл** — фильтр секретов режет строку при записи и портит файл (получал `TOKEN=os.env...`). **Фикс: читать из env (`os.environ["HATOK"]`), значение подставлять в bash-команде через `$(tr -d '\n\r ' < ha_token.txt)`.** Искажение видно только в отображении чата — файл на диске цел, проверять `grep -n` по нему. 27. 🔴 **Свой мини-клиент WebSocket без зависимостей.** `ws_dump.py` использует голый `socket` + `struct` + `base64`: рукопожатие `Sec-WebSocket-Key`, маскирование кадров, **обязательный pong на ping (opcode 0x9)** — без pong HA рвёт соединение. Пакет `websocket-client` больше не нужен. +28. 🔴 **НЕ ВСЁ `platform=mqtt` — мусор Z2M!** Среди mqtt-сущностей живут **живые modbus-датчики** (`modbus_dining_sensor`, `modbus_kids_sensor`, `modbus_bedroom_sensor`) — это `modbus-bridge` (модель «Modbus RTU Sniffer / Custom»), они пишут данные. **Различитель — `identifiers` в device_registry:** `['mqtt','zigbee2mqtt_0x…']` → мёртвое Z2M; `['mqtt','modbus__sensor']` → живое. **Удалять только `zigbee2mqtt_*`.** Перед удалением проверять `last_changed` — у Z2M-призраков `unavailable`. +29. 🔴 **ИМЯ УСТРОЙСТВА ≠ `entity_id` — две отдельные операции.** Alex видел в UI технические имена после того, как все `entity_id` были переименованы. Причина: переименованы сущности, а **имя устройства** (`device_registry.name_by_user`) осталось техническим. Разные WS-методы: сущность — `config/entity_registry/update` → `new_entity_id`; устройство — `config/device_registry/update` → **`name_by_user`** (не `name`). +30. 🔴 **HA НЕ ПОЗВОЛЯЕТ менять домен `entity_id`.** `{'code': 'invalid_info', 'message': 'New entity ID should be same domain'}`. ZHA отдаёт 2/3-ганговые Tuya-модули как `light.*`, Z2M давал `switch.*` → 8 переименований невозможны. Решение: оставить ZHA-домен или переписать ссылки в автоматизациях. +31. 🔴 **Автоматизации ссылаются на `device_id` + `entity_id`-UUID, а НЕ на `entity_id`.** Удаление устройств Z2M **убивает все 16 автоматизаций**, даже если сущности переименованы обратно. Проверять `config/device_registry/list` — если `device_id` из автоматизации в списке нет, триггер мёртв. Правка — только пересборка привязок по новым `device_id`. +32. 🔴 **Зоны (Areas) НЕ удаляются вместе с устройствами, но и НЕ восстанавливаются автоматически.** Отдельный реестр `area_registry` (11 зон уцелели). Пересозданные ZHA-устройства получают `area_id: null`. **После любой миграции зоны проставлять заново:** `config/device_registry/update` + поле **`area_id`** (= `slug` зоны, не отображаемое имя). +33. ⚠️ **Два устройства могут иметь ОДИНАКОВОЕ техническое имя.** `office_table_light_switch` и `light_stairs` — оба `_TZ3000_5gey1ohx TS0002`, различаются только по IEEE. В UI выглядят идентично; при массовых правках ключ — `device_id`, не имя. ---