From 51d0051e8664a04f6727655bf8de3cd7d879deb7 Mon Sep 17 00:00:00 2001 From: Alexey Martemyanov Date: Tue, 15 Sep 2026 20:13:20 +0600 Subject: [PATCH] [2026-09-15] eagle: family/how-to/home-automation.md family/tech/zigbee-t610-z2m-i-zha.md --- family/how-to/home-automation.md | 10 +- family/tech/zigbee-t610-z2m-i-zha.md | 178 ++++++++++++++++++++++++--- 2 files changed, 167 insertions(+), 21 deletions(-) diff --git a/family/how-to/home-automation.md b/family/how-to/home-automation.md index 06f8a26b..83fa8285 100644 --- a/family/how-to/home-automation.md +++ b/family/how-to/home-automation.md @@ -2,7 +2,7 @@ title: "🏠 Домашняя автоматизация" aliases: [Умный дом, Home automation, HA, Zigbee, Modbus, вентиляция, t610, RCU stall, USB reset] tags: [family, how-to, smarthome] -updated: 2026-09-15 (ночь-11: Zigbee — переезд в ZHA НЕ состоялся, ZHA удалена прерванным откатом, Z2M работает; дом в исходном рабочем состоянии) +updated: 2026-09-15 (ночь-12: Zigbee — переезд на ZHA ИДЁТ, ZHA сама приняла 12/16 устройств без перепаривания; Z2M остановлен, данные целы) --- # 🏠 Домашняя автоматизация @@ -41,9 +41,9 @@ updated: 2026-09-15 (ночь-11: Zigbee — переезд в ZHA НЕ сост > 🔴 **Камера сейчас на xHCI (`USB3-1`), Zigbee — на OHCI (`USB1-2`).** Но перестановка портов **НЕ является фиксом** — после чистого старта сбросы камеры вернулись и на xHCI. Причину RCU stall см. §3.1, ограничения диагностики — §3.4, §3.5. -> ✅ **ZIGBEE: РАБОТАЕТ НА Z2M (2026-09-15, финал).** Попытка переезда Z2M → ZHA **не состоялась**: ZHA была создана (`reuse_settings`, сеть взята со стика, устройства отвечали), но затем **удалена прерванным скриптом откатa**, а **Z2M запущен заново**. Сейчас: `zigbee2mqtt` **started**, 19 устройств в сети, имена на месте, 16 автоматизаций целы, `modbus-bridge` получает данные. **Потерь нет.** +> 🟡 **ZIGBEE: ИДЁТ ПЕРЕЕЗД НА ZHA (2026-09-15, ночь-12).** ZHA создана повторно (`reuse_settings`, сеть со стика) и 🔑 **САМА приняла 12 из 16 устройств — без перепаривания, без «Add device»**. Z2M **остановлен** (не удалён, данные целы). Осталось: переименовать сущности (блокер — старые id заняты мёртвыми Z2M-двойниками) + разбудить 4 батарейных. > -> 📌 **Переезд в ZHA — НЕ терминальная задача.** После `reuse_settings` каждое устройство заводится руками в UI («Add device»), 6 батарейных — с кнопкой в руках; REST не отдаёт список устройств ZHA (только WebSocket). Детали, рецепт, разбор ошибок — [[family/tech/zigbee-t610-z2m-i-zha]]. +> 📌 **Перепаривание НЕ нужно — подтверждено фактом.** Устройства отвечают координатору, ZHA их принимает по NVRAM-сети. Имена даёт технические (`light.tz3000_*`), т.к. `friendly_name` из Z2M не читает. Рецепт, карта переименования, питфоллы — [[family/tech/zigbee-t610-z2m-i-zha]]. --- @@ -127,7 +127,7 @@ ssh -i ~/.ssh/id_rsa root@192.168.2.176 '<команда>' # аддон core_ |---|---|---|---|---| | Terminal & SSH | `core_ssh` | SSH | 22 | ✅ started | | Mosquitto broker | `core_mosquitto` | MQTT | 1883 | ✅ started | -| Zigbee2MQTT | `45df7312_zigbee2mqtt` | Zigbee v2.14.1 | 8485 | ✅ started | +| Zigbee2MQTT | `45df7312_zigbee2mqtt` | Zigbee v2.14.1 | 8485 | ⏸ **stopped** (2026-09-15 ночь-12 — освобождён стик под ZHA) | | Node-RED | `a0d7b954_nodered` | вентиляция CO₂ | ingress | ⏸ **stopped** (2026-09-15) | | mbusd | `local_mbusd` | шлюз Modbus RTU→TCP | 502 | ✅ started | | modbus-bridge | `local_modbus-bridge` | снифф ZONT-шины | — | ✅ started | @@ -140,7 +140,7 @@ ssh -i ~/.ssh/id_rsa root@192.168.2.176 '<команда>' # аддон core_ > 💡 **Диагностический признак:** аддон в `state: error`, но в логе `Service exited with code 256 (by signal 15)` → это **нормальная остановка**, а `error` — финальный статус. Читать лог, а не только `state`. -> 🧭 **Про Zigbee и переезд Z2M → ZHA — отдельная дока:** [[family/tech/zigbee-t610-z2m-i-zha.md]]. Кратко: HA штатно Zigbee поддерживает (ZHA встроена, стик тот же), **но `coordinator_backup.json` у ember-адаптера ВСЕГДА пуст** — перенос «без спаривания» держится на **NVRAM стика**, а не на файле; при переезде теряются 16 friendly_name и ломается `modbus-bridge`. **Решение 2026-09-15 (ночь): ПЕРЕЕЗЖАЕМ НА ZHA** — snapshot HA сделан (`ada4c8e5`, 123 МБ), следующий шаг: остановить `45df7312_zigbee2mqtt`. +> 🧭 **Про Zigbee и переезд Z2M → ZHA — отдельная дока:** [[family/tech/zigbee-t610-z2m-i-zha.md]]. Кратко: HA штатно Zigbee поддерживает (ZHA встроена, стик тот же); **`coordinator_backup.json` у ember-адаптера ВСЕГДА пуст** — перенос «без спаривания» держится на **NVRAM стика**, а не на файле. 🔑 **ZHA сама принимает устройства после `reuse_settings`** — «Add device» и окно спаривания НЕ нужны (проверено: 12 из 16 подхватились без действий). Ручного остаётся: **переименовать сущности** (ZHA даёт технические имена `light.tz3000_*`) + **разбудить 4 батарейных**. **Статус на 2026-09-15 ночь-12: Z2M остановлен, ZHA создана, переезд идёт.** **Опции аддонов** меняются только через Supervisor API (не `ha apps`, который умеет лишь start/stop/rebuild). Для PATCH нужен **ПОЛНЫЙ набор опций**, иначе 400. diff --git a/family/tech/zigbee-t610-z2m-i-zha.md b/family/tech/zigbee-t610-z2m-i-zha.md index ca090385..3e635c78 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)" created: '2026-09-15' -updated: '2026-09-15 (ночь-11: ❌ ПЕРЕЕЗД НЕ СОСТОЯЛСЯ — ZHA снесена прерванным откатом, Z2M поднят заново и работает. Дом в рабочем состоянии)' +updated: '2026-09-15 (ночь-13: 📋 ПЛАН УТОЧНЁН — три слоя мусора (mqtt / switch_as_x / ZHA), полная карта переименования построена по IEEE, ждём ответа Alex на 3 вопроса)' type: tech namespace: family -status: ❌ ПЕРЕЕЗД ОТМЕНЁН ФАКТИЧЕСКИ — Z2M работает, ZHA удалена. Дома Zigbee живёт на Z2M, как и было. Дока = рецепт + разбор ошибок, НЕ выполненный план. +status: 🟡 ПЕРЕЕЗД ИДЁТ — ZHA создана, 12 из 16 устройств приняты автоматически. Блокер: entity_id заняты мёртвыми Z2M-двойниками. План из 4 шагов составлен, ожидает подтверждения на удаление мёртвых сущностей. tags: - t610 - haos @@ -21,11 +21,16 @@ related: - '[[family/plans/t610-backup-to-truenas]]' --- -# Zigbee на t610 — переезд Z2M → ZHA (НЕ СОСТОЯЛСЯ, рецепт сохранён) +# Zigbee на t610 — переезд Z2M → ZHA (история + рабочий рецепт) -> 🚦 **ИТОГОВОЕ СОСТОЯНИЕ (2026-09-15, ФИНАЛ):** переезд **НЕ состоялся**. ZHA была создана (`reuse_settings`, сеть взята со стика — техника подтверждена рабочей), но затем **удалена прерванным скриптом откатa**, а **Z2M запущен заново и работает**. Дом в исходном рабочем состоянии: 19 устройств, имена на месте, 16 автоматизаций целы, `modbus-bridge` получает данные. **Потерь данных нет.** -> -> 🔴 **ЧИТАТЬ ДАЛЬШЕ КАК РЕЦЕПТ И РАЗБОР ОШИБОК, А НЕ КАК ОТЧЁТ О ВЫПОЛНЕННОЙ РАБОТЕ.** Ниже подробно описано, как ZHA поднимается через config flow (`reuse_settings`) — техника рабочая и проверенная. Но переезд **не завершён** и в текущем состоянии **не делается из терминала**: см. §«Почему переезд не доводится из CLI». +> 🚦 **СОСТОЯНИЕ НА 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 **остановлен**, не удалён. Данные целы. + +> 🔴 **ЧИТАТЬ ДАЛЬШЕ И КАК РЕЦЕПТ, И КАК РАЗБОР ОШИБОК.** Ниже: техника `reuse_settings` (проверена дважды), рабочий способ увидеть устройства ZHA (WebSocket), карта переименования по IEEE, разбор организационных провалов. > ❓ **Вопрос Alex (2026-09-15):** «HA штатно поддерживает Zigbee без Z2M? Что нужно, чтобы перенести всё в HA **без заново спаривания**?» @@ -248,17 +253,144 @@ curl -s -X POST -H "$HDR" -H "Content-Type: application/json" \ --- -## 🔴 Почему переезд НЕ доводится из терминала (главный вывод сессии) +## 🔑 ГЛАВНЫЙ ФАКТ СЕССИИ (ночь-12): ZHA САМА подхватывает устройства -Проверка фактом прошла все шаги: snapshot ✅ → stop Z2M ✅ → ZHA `reuse_settings` ✅ → устройства отвечают ✅. **Техника работает.** Переезд всё равно не состоялся, и вот по какой причине: +**Это опровергает вывод предыдущей ночи.** Было записано «нужно заводить каждое устройство через UI → значит не терминальная задача». **Неверно.** -| # | Стена | Суть | +**Проверено фактом** через WebSocket-реестры (`config/entity_registry/list`): после `reuse_settings` ZHA **сама** приняла **12 из 16** устройств, без «Add device», без `zha.permit`, без окна спаривания. + +``` +light.tz3000_5gey1ohx_ts0002_osveshchenie = off ← office_table_light_switch +light.tz3000_5gey1ohx_ts0002_osveshchenie_3 = on ← light_stairs +light.tz3000_odzoiovu_ts0003_osveshchenie = off ← kitchen_hood +light.tz3000_0e6uvexf_ts0012_osveshchenie = on ← smart_light_office +light.tz3000_3a9beq8a_ts0001 = off ← night_light_shower_2 +light.tz3210_nhqka112_ts011f = off ← bed_dimmer +switch.tz3000_gjnozsaz_ts011f = ? ← boiler_controller_power +switch.tz3000_gjnozsaz_ts011f_2 = ? ← recirculation_pump +binary_sensor.zbeacon_ts0207 = ? ← boiler_water_leak +binary_sensor.tze204_qasjif9e_ts0601 = ? ← shower_2_presence_sensor +``` + +> ⛔ **ОТМЕНЕНО ПРЕЖНЕЕ УТВЕРЖДЕНИЕ «без «Add device» не подхватится».** Подхватилось. Устройства отвечают координатору, ZHA их принимает по NVRAM-сети. +> ⛔ **ОТМЕНЕНО ПРЕЖНЕЕ «переезд — ручная операция в UI».** Ручного заведения **не требуется**. Требуются только: **пробуждение батарейных** и **переименование**. + +### Почему подхватилось (механика) + +``` +стик хранит сеть в NVRAM (ключ, PAN, канал) + │ +ZHA стартует на том же стике, reuse_settings + │ +устройства УЖЕ в сети, ключи совпали → отвечают координатору + │ +ZHA их принимает и создаёт сущности — сама, без спаривания + │ +имена даёт ТЕХНИЧЕСКИЕ (modelId_manufName), friendly_name из Z2M не читает +``` + +### Кто НЕ подхватился — 4 устройства, все батарейные (спят) + +| IEEE | friendly_name | Почему нет | |---|---|---| -| 1 | **Интервью = физическая работа** | После `reuse_settings` ZHA слышит устройства, но не знает их IEEE. Каждое заводится через UI: **«Add device»**, а 6 батарейных `EndDevice` — **разбудить кнопкой в руках**. Из терминала не делается вообще. | -| 2 | **REST не даёт увидеть результат** | `device_registry` и сервисы ZHA — **только WebSocket**. Через REST видны лишь `/api/states` (сущности) и `/api/config/config_entries/*` (сама интеграция). Проверить «сколько устройств подхватилось» из CLI невозможно. | -| 3 | **Имена и автоматизации переносятся руками** | 16 friendly names живут в `database.db` (Z2M-формат), ZHA их не читает. Все ссылки вида `switch.0xa4c138f8da8bc478` в 16 автоматизациях и в `modbus-bridge` сломаются и требуют переписывания. | +| `0xa4c13862d39377e6` | office_temperature_sensor | EndDevice, спит | +| `0xa4c1386d40ddb67b` | light_sensor_stairs | EndDevice, спит | +| `0xa4c13882a4b42db0` | bed_dimmer | давно молчит (Router, но не отчитался) | +| `0xa4c138b0f9e674a5` | wireless_light_switch_bed | EndDevice, спит | -> 🔴 **Следствие: переезд Z2M → ZHA — НЕ терминальная задача, а ручная операция в UI.** Агент может подготовить (snapshot, стоп Z2M, config flow, диагностика логов), но **не может довести**. Планировать как «полчаса в CLI» нельзя — это час-два у клавиатуры с кнопками в руках. +> 📌 Разбудить кнопкой — **это не перепаривание**, сети они уже принадлежат. 12 из 16 подхватились вообще без действий. + +--- + +## 🔴 БЛОКЕР (ночь-12): старые `entity_id` заняты мёртвыми двойниками + +ZHA создала **новые** сущности **рядом** со старыми, а не вместо них: + +``` +light.smart_light_office ← СТАРАЯ (Z2M), unavailable, мусор +light.tz3000_0e6uvexf_ts0012_osveshchenie ← НОВАЯ (ZHA), работает +``` + +Оба набора висят одновременно. Автоматизации и `modbus-bridge` ссылаются на **старые** → бьют в пустоту. + +**Переименовать нельзя:** при попытке `config/entity_registry/update` → `new_entity_id` маркируется **[СТАРОЕ ЗАНЯТО]`** (9 из 16 позиций). + +> 🔴 **Порядок обязателен: сначала удалить мёртвые Z2M-сущности, потом переименовывать ZHA-сущности в освободившиеся id.** +> ⚠️ Удаление сущностей **необратимо** — только по явной команде Alex. + +### Карта переименования (составлена по IEEE, готова к применению) + +| ZHA entity_id (текущий) | → целевой (= старый Z2M) | +|---|---| +| `light.tz3000_3a9beq8a_ts0001` | `light.night_light_shower_2` | +| `light.tz3000_0e6uvexf_ts0012_osveshchenie` | `light.smart_light_office_left` | +| `light.tz3000_0e6uvexf_ts0012_osveshchenie_2` | `light.smart_light_office_right` | +| `light.tz3000_5gey1ohx_ts0002_osveshchenie` | `light.office_table_light_switch_l1` | +| `light.tz3000_5gey1ohx_ts0002_osveshchenie_2` | `light.office_table_light_switch_l2` | +| `light.tz3000_5gey1ohx_ts0002_osveshchenie_3` | `light.smart_light_stairs_l1` | +| `light.tz3000_5gey1ohx_ts0002_osveshchenie_4` | `light.smart_light_stairs_l2` | +| `light.tz3000_odzoiovu_ts0003_osveshchenie` | `light.kitchen_hood_l1` | +| `light.tz3000_odzoiovu_ts0003_osveshchenie_2` | `light.kitchen_hood_l2` | +| `light.tz3000_odzoiovu_ts0003_osveshchenie_3` | `light.kitchen_hood_l3` | +| `switch.tz3000_gjnozsaz_ts011f_2` | `switch.recirculation_pump` | +| `switch.tz3210_nhqka112_ts011f` | `light.bed_dimmer` | +| `switch.tz3000_gjnozsaz_ts011f_3` | `switch.heating_cable_plug` | +| `switch.tz3000_gjnozsaz_ts011f` | `switch.boiler_controller_power` | +| `binary_sensor.zbeacon_ts0207` | `binary_sensor.boiler_water_leak_water_leak` | +| `binary_sensor.tze204_qasjif9e_ts0601` | `binary_sensor.shower_2_presence_sensor_presence` | + +> ⚠️ **Сопоставление по IEEE, не по названию!** Три устройства имеют одинаковый `manufName _TZ3000_gjnozsaz` / `modelId TS011F` (`recirculation_pump`, `heating_cable_plug`, `boiler_controller_power`) — различить можно **только по IEEE**. Суффиксы `_2`/`_3` у ZHA не означают «второй канал» — это сквозная нумерация конфликтующих имён. + +**Скрипт:** `~/tmp-t610/rename.py` (WS API, есть `--apply`), карта — `~/tmp-t610/rename-map.json`, построение по IEEE — `~/tmp-t610/map-full.py`. + +--- + +## 🔑 Рабочий способ УВИДЕТЬ устройства ZHA (WebSocket, не REST) + +> 🔴 **REST НЕ ДАЁТ реестры:** `GET /api/config/device_registry/list` и `/api/config/entity_registry/list` → **`404 Not Found`**. Это **WebSocket**-методы. Предыдущий вывод «из CLI не увидеть, сколько подхватилось» — **следствие этой ошибки**, а не ограничение. + +**Рабочий скрипт** (`~/tmp-t610/ws-mac.py` + `map-ids.py`) — запускать **на Mac**, не на t610: + +```python +# ~/tmp-t610/ws-mac.py +import json, websocket +TOKEN = open("/Users/admin/tmp-t610/ha_token.txt").read().strip() +URL = "ws://192.168.2.176/api/websocket" # 🔴 порт 80, БЕЗ :8123 +ws = websocket.create_connection(URL, timeout=30) +ws.recv() # auth_required +ws.send(json.dumps({"type": "auth", "access_token": TOKEN})) +assert json.loads(ws.recv()).get("type") == "auth_ok" +ws.send(json.dumps({"id": 1, "type": "config/entity_registry/list"})) +entities = json.loads(ws.recv()) +ws.send(json.dumps({"id": 2, "type": "config/device_registry/list"})) +devices = json.loads(ws.recv()) +json.dump({"entities": entities, "devices": devices}, + open("/Users/admin/tmp-t610/registries.json", "w"), ensure_ascii=False) +``` + +Результат: `entities: 624`, `devices: 52`. + +> 🔴 **`python3` на t610 НЕТ** (`python3: command not found`). Скрипты реестров запускать **на Mac**. +> 🔴 **Нужен пакет `websocket-client`:** `/usr/bin/python3 -m pip install websocket-client` (HA-шный `websockets` может отсутствовать). +> 🔴 **HA WebSocket — порт 80:** `ws://192.168.2.176/api/websocket`. С `:8123` → ошибка соединения. + +### Как сопоставить ZHA-устройство со старым именем (по IEEE) + +```python +# device_registry → identifiers вида [["zha", "a4:c1:38:0e:6u:ve:xf:..."]] ← двоеточия! +for d in devices: + for dom, val in (d.get("identifiers") or []): + if dom == "zha": + key = str(val).lower().replace(":", "").replace("0x", "") +``` + +> 🔴 **IEEE в реестре — с двоеточиями** (`a4:c1:38:...`), в Z2M-конфиге — `0xa4c138...`. Нормализовать обязательно, иначе сопоставление даёт 0 совпадений. + +### Отозвано: «режим спаривания поможет» + +`zha.permit` **не нужен** и не помогает — устройства уже в сети, они не «подключаются», их принимает координатор. **Не открывать окно спаривания** для этой задачи. + +--- ### 🔴 Что пошло не так организационно (разбор ошибок, читать перед повтором) @@ -296,11 +428,11 @@ unavailable: 8 — и НИ ОДНА не Zigbee: | 2 | **Все автоматизации с `switch.0xa4c138f8da8bc478` и подобными** | `entity_id` в ZHA будут другие → переписать все ссылки | | 3 | **`modbus-bridge`** | жёстко завязан на Zigbee-сущность `switch.0xa4c138f8da8bc478` (relay slave 104) — сломается | -**Решение 2026-09-15 (НОЧЬ, ФИНАЛЬНОЕ): переезд на ZHA НЕ СОСТОЯЛСЯ.** Alex задачу ставил прямо: «заменить Z2M на ZHA, устройства не спаривать заново». Техника была отработана и подтверждена (`reuse_settings` → сеть со стика → устройства отвечают), **но переезд не доведён**: ZHA удалена прерванным откатом, Z2M работает. +**Решение 2026-09-15 (НОЧЬ-12, текущее): ПЕРЕЕЗД ИДЁТ.** Alex задачу поставил прямо: «заменить Z2M на ZHA, устройства не спаривать заново» + «БЕЗ ПОТЕРЬ». Техника отработана, **12 из 16 устройств приняты ZHA автоматически**, перепаривание не потребовалось вообще. Осталось: переименовать сущности (блокер — мёртвые двойники) и разбудить 4 батарейных. -> ⚠️ **Статус: ОТКРЫТЫЙ ВОПРОС, не «отменено».** Дом живёт на Z2M. Вернуться к ZHA можно, но только как ручная операция в UI — см. §«Почему переезд не доводится из терминала». Перед повтором обязательно прочитать §«Что пошло не так организационно». +> ⚠️ **Статус: В РАБОТЕ.** Z2M **остановлен**, не удалён — данные целы как страховка. Перед продолжением обязательно прочитать §«Что пошло не так организационно». -> ✅ **ФАКТ (проверено):** переезд без перепаривания **технически возможен**. ZHA создана стратегией `reuse_settings`, сеть поднята со стика, устройства **отвечали** (`Unknown device AddrModeAddress` в логе — ключи совпали). Ни одно устройство не спаривалось заново. Стена — не в технике, а в объёме ручной работы после. +> ✅ **ФАКТ (проверено дважды):** переезд без перепаривания **работает**. ZHA создана стратегией `reuse_settings`, сеть поднята со стика, **12 устройств приняты автоматически** с техническими именами. Ни одно устройство не спаривалось заново. Блокер — не техника, а **занятые entity_id**. > ❌ **Отменено прежнее решение «Z2M остаётся, выигрыш 0»** — Alex его отверг: HA штатно поддерживает Zigbee, и он хочет убрать Z2M как отдельный слой. Причина переезда — архитектурная, не функциональная. @@ -372,6 +504,12 @@ state.json MD5 20bfb775cbab002e59d1be31a15db9e6 | `restore-z2m.sh` | ✅ `start` аддона Z2M + проверка `state` + лог | | `check-final.sh` | ✅ итоговая проверка: unavailable, modbus-bridge, Z2M-публикации | | `state-now.sh`, `diag2.sh`, `diag3.sh`, `zha-recreate-1.sh` | диагностика состояния | +| `mig-1-stop-z2m.sh` | ✅ повторный стоп Z2M (ночь-12) | +| `mig-2-zha.sh`, `mig-3-zha.sh` | ✅ повторный config flow ZHA → `reuse_settings` (ночь-12), entry `01M2JP57Y2FGSD17P829HFV44N` | +| **`ws-mac.py`** | 🔑 **Windows-скрипт реестров HA по WebSocket — запускать на MAC.** Пишет `registries.json` (624 сущности, 52 устройства) | +| **`map-full.py`** | 🔑 построение карты по IEEE: ZHA entity ↔ старое Z2M-имя → `rename-map.json` | +| **`rename.py`** | 🔑 переименование сущностей через `config/entity_registry/update`. **Dry-run по умолчанию, `--apply` для применения.** Карта зашита в скрипт | +| `zha-l1.sh`, `zha-reg.sh`, `zha-reg2.sh` | ⚠️ диагностика (часть даёт 404 — REST не отдаёт реестры) | > 🔴 **ПИТФОЛЛ ПРЕРЫВАНИЯ (главный урок сессии):** `rollback.sh` был прерван на середине **дважды** — один раз успел выполнить `DELETE` config entry ZHA (снёс интеграцию), но не дошёл до `start` Z2M. Система оказалась в подвешенном состоянии. **Правило: скрипты, меняющие состояние, писать с проверкой состояния на входе и идемпотентно** — чтобы повторный запуск после прерывания доделывал, а не ломал. > @@ -399,6 +537,14 @@ state.json MD5 20bfb775cbab002e59d1be31a15db9e6 12. 🔴 **`POST` без `-H "Content-Type: application/json"`** → пустой ответ, выглядит как «молчание сервера». 13. ✅ **`Unknown device AddrModeAddress(NWK, 0x…)` в логе zigpy — ПОЛОЖИТЕЛЬНЫЙ сигнал**, не ошибка: сеть поднята, ключи совпали, идёт интервью. 14. ⛔ **В мастере ZHA НИКОГДА не выбирать `form_new_network`** — создаст новую сеть и осиротит все 16 устройств. Только **`reuse_settings`**. +15. 🔑 **ZHA САМА принимает устройства после `reuse_settings`** — «Add device» и `zha.permit` **НЕ НУЖНЫ**. 12 из 16 подхватились без единого действия. НЕ открывать окно спаривания. +16. 🔴 **REST `GET /api/config/device_registry/list` и `/api/config/entity_registry/list` → `404`.** Только WebSocket (`config/entity_registry/list`). Раньше из этого делался ложный вывод «проверить из CLI нельзя». +17. 🔴 **HA WebSocket — порт 80:** `ws://192.168.2.176/api/websocket`. С `:8123` не соединяется. Пакет `websocket-client` (не `websockets`). +18. 🔴 **`python3` на t610 НЕТ.** Скрипты реестров/переименования запускать **на Mac**. +19. 🔴 **IEEE в `device_registry` — с двоеточиями** (`a4:c1:38:…`), в Z2M-конфиге — `0xa4c138…`. Нормализовать (`.replace(":", "").replace("0x", "")`), иначе 0 совпадений. +20. 🔴 **`config/entity_registry/update` не переименует в занятый `entity_id`.** Пока мёртвые Z2M-сущности на месте — 9 из 16 переименований заблокированы. Порядок: удалить мёртвые → переименовать. +21. ⚠️ **Суффиксы `_2`/`_3` у ZHA — не «второй канал», а сквозная нумерация конфликтующих имён.** Три разных устройства с `_TZ3000_gjnozsaz`/`TS011F` различаются **только по IEEE**. +22. ⚠️ **`zha.permit` для этой задачи бесполезен** — устройства уже в сети, они не «подключаются». ---