From 6a690f89219c07490c03344e397cac2adbd24a1c Mon Sep 17 00:00:00 2001 From: Alexey Martemyanov Date: Mon, 14 Sep 2026 13:16:26 +0600 Subject: [PATCH] [2026-09-14] eagle: family/how-to/t610-access.md family/plans/home-automation-migration-t610.md family/plans/t610-addons-deployment.md --- family/how-to/t610-access.md | 1 + .../plans/home-automation-migration-t610.md | 1 + family/plans/t610-addons-deployment.md | 37 +++++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/family/how-to/t610-access.md b/family/how-to/t610-access.md index d219158e..5d3af86b 100644 --- a/family/how-to/t610-access.md +++ b/family/how-to/t610-access.md @@ -16,6 +16,7 @@ > - **ссылки на `entity_id`** в автоматизациях/дашбордах — не обновляются автоматически, даже если реестр переименован (грепать `[a-z_]+\.0x[0-9a-f]{16}` **везде**, включая `platform: state`-триггеры). > Подробно: [[family/plans/t610-addons-deployment]] §«ДОБАВЛЕНО В КОНЦЕ СЕССИИ». > 🔑 **z2m не публикует состояние пассивно** — реле остаются `unknown` до первого события. Живость проверять по **`lastSeen`** в `database.db`. После рестарта HA — физически нажать кнопки. +> 🔑 **⚠️ `unknown` после рестарта HA ВОЗВРАЩАЕТСЯ — проверено экспериментом 2026-09-14.** Зафиксировано → `homeassistant.restart` → снято: всё, что было `on`/`off`, стало `unknown` (`office_table_light_switch`, `smart_light_office`, `heating_cable_plug`, `boiler_controller_power`). **`retain: true`, `cache_state`, `cache_state_persistent`, `cache_state_send_on_startup` в z2m стоят — но retained на топиках устройств не публикуется** (контроль: `zigbee2mqtt/bridge/state` retained **есть** → брокер умеет). **Следствие: первое нажатие кнопки после рестарта не срабатывает** (`not_from: [unknown]` блокирует триггер). **Открытый фикс: убрать `not_from: [unknown]` из триггеров кнопок** — не применён. Полное описание и таблица «до/после»: [[family/plans/t610-addons-deployment]] §«ДОБАВЛЕНО В КОНЦЕ СЕССИИ» ③‑бис. ## Основное diff --git a/family/plans/home-automation-migration-t610.md b/family/plans/home-automation-migration-t610.md index f18d5380..3ed7c583 100644 --- a/family/plans/home-automation-migration-t610.md +++ b/family/plans/home-automation-migration-t610.md @@ -21,6 +21,7 @@ related: > **Статус: Этап 1 ✅. Этап 2 ✅ ПОЛНОСТЬЮ. Этап 3 ✅ ЗАКРЫТ (2026-09-14).** z2m — 15 устройств, mbusd — порт 502, modbus-bridge — MQTT + HA-опрос. HA-конфиг перенесён с TrueNAS, автоматизации 16/16 живы, реестр 332 сущности (hex=0), зоны у 18 устройств. Детали Этапа 3 и питфоллы переноса — [[family/plans/t610-addons-deployment]]. > **⏸️ Остался один блокер — аппаратный:** 32 заслонки вентиляции `unavailable` (шина не отвечает, exception 0x0B) → CH340 #2 подключить к линиям A/B шины. Далее — Этап 4 (Caddy upstream → t610, GPON-редирект, отключение TrueNAS). +> **⚠️ Проверено экспериментом 2026-09-14:** `unknown` у реле/кнопок **возвращается после каждой перезагрузки HA** — `retain`/`cache_state` в z2m не спасают; первое нажатие кнопки после рестарта не срабатывает. Открытый фикс — убрать `not_from: [unknown]` из триггеров (не применён). Детали: [[family/plans/t610-addons-deployment]] §«ДОБАВЛЕНО В КОНЦЕ СЕССИИ» ③‑бис. > Цель: убрать всю домашнюю автоматизацию с TrueNAS (он перегружен — 17/21 ГБ RAM) на выделенный HP t610, с бэкапом конфигов на TrueNAS и в git. > > **Прогресс 2026-09-14 (вечер) — Этап 2 ЗАКРЫТ, Modbus-сервисы работают:** diff --git a/family/plans/t610-addons-deployment.md b/family/plans/t610-addons-deployment.md index 473f356b..d849f923 100644 --- a/family/plans/t610-addons-deployment.md +++ b/family/plans/t610-addons-deployment.md @@ -23,6 +23,7 @@ related: > **modbus.host исправлен: `127.0.0.1` → `192.168.2.176`** (mbusd в отдельном контейнере — `127.0.0.1` изнутри HA его не видел). > **modbus-bridge: HTTP 404 → 200.** Опрашивал HA по hex-`entity_id`; правился `modbus_ha_bridge.py` + `data/config.template.tmpl` + **обязательный rebuild аддона**. > ⚠️ **ЕДИНСТВЕННЫЙ ОСТАВШИЙСЯ БЛОКЕР (физика, не конфиг): 32 заслонки вентиляции `unavailable`.** mbusd работает (TCP отвечает), но шина **не отвечает** — exception **0x0B** (GATEWAY TARGET DEVICE FAILED TO RESPOND). Вывод: **CH340 #2 воткнут в USB, но линии A/B вентиляционной шины к нему не подключены / шина обесточена.** За Alex. +> ⚠️ **`unknown` после рестарта HA — ПРОВЕРЕНО ЭКСПЕРИМЕНТОМ 2026-09-14, воспроизводится.** Реле/кнопки слетают в `unknown` при каждой перезагрузке HA; `retain: true` + `cache_state*` в z2m стоят, но не помогают. Практический эффект: первое нажатие кнопки после рестарта не срабатывает. **Открытый фикс: убрать `not_from: [unknown]` из триггеров** (не применён). См. §«ДОБАВЛЕНО В КОНЦЕ СЕССИИ» ③‑бис. > **✅ ЗОНЫ ВОССТАНОВЛЕНЫ (18 устройств):** при переносе `area_id` теряются так же, как `device_id` (устройства ре-регистрируются) → все 14 zigbee были **без зон**. Проставлены по эталону с TrueNAS по zigbee-адресу. См. §«ДОБАВЛЕНО В КОНЦЕ СЕССИИ» ①. > **✅ office-переключатель управляет светом:** устранены hex-`entity_id` **в триггерах** автоматизаций (`switch.0xa4c13873b5c1575b_l1/l2` → человеческие) + реле выведены из `unknown` физическим нажатием. Цепочка `light → switch_as_x → z2m → реле` проверена. См. §«ДОБАВЛЕНО В КОНЦЕ СЕССИИ» ②③. > Сервисы: z2m (14 устройств), mbusd (502), modbus-bridge (MQTT + HA-опрос), MQTT-интеграция в HA. @@ -916,6 +917,40 @@ curl -s -X POST -K curl.auth -H "Content-Type: application/json" \ **Причина:** z2m публикует payload **только при получении данных от устройства**. Питаемые реле не отчитываются сами по себе — ждут события (нажатия) или запроса. **Лечение (практическое):** после перезапуска **физически нажать кнопки** на реле — сеть «прогревается», все `unknown` уходят. Проверено: `switch.office_table_light_switch_l1/l2` стали `on`, `switch.smart_light_office_left/right` — `off`. +##### ③‑бис ✅ ПРОВЕРЕНО на перезагрузке (2026-09-14): `unknown` ВОЗВРАЩАЕТСЯ, `retain` не спасает + +**Проведён эксперимент** (не гипотеза): зафиксировано состояние → `homeassistant.restart` через API → состояние снято снова. + +| Сущность | До рестарта | **После рестарта** | +|---|---|---| +| `switch.office_table_light_switch_l1/l2` | `on` | **`unknown`** | +| `switch.smart_light_office_left/right` | `off` | **`unknown`** | +| `switch.heating_cable_plug` | `off` | **`unknown`** | +| `switch.boiler_controller_power` | `off` | **`unknown`** | +| `switch.kitchen_hood_l1/l2/l3`, `switch.light_stairs_l1/l2` | `unknown` | `unknown` | + +**Вывод:** всё, что было `on`/`off`, после перезагрузки слетает в `unknown`. **Поведение воспроизводимо.** + +**Что НЕ помогло (проверено на живом):** в z2m стоят все три штатных механизма — +`retain: true` (подтверждено дважды: `bridge/request/options` → `{"data":{"restart_required":false},"status":"ok"}`), +`cache_state: true`, `cache_state_persistent: true`, `cache_state_send_on_startup: true` — +но **retained-сообщения на топиках устройств фактически не появляются**, состояния при старте не переопубликовываются. +Контроль: `zigbee2mqtt/bridge/state` **retained есть** (прилетает мгновенно при свежей подписке) → брокер retained умеет, дело не в нём. + +> 🔬 **Питфолл диагностики retained:** флаг **`-R` (retained-only) у `mosquitto_sub` в аддоне работает НЕ как ожидается** — с ним вывод пустой даже там, где retained есть. **Надёжный способ:** подписаться и смотреть **с timestamp, что прилетает СРАЗУ при подписке** (retained приходит мгновенно, живой трафик — только по событию): +> ```bash +> timeout 4 mosquitto_sub -h 192.168.2.176 -u zont -P "$P" -t 'zigbee2mqtt/bridge/state' -v \ +> | while IFS= read -r l; do echo "$(date +%H:%M:%S.%N | cut -c1-12) | $l"; done +> ``` + +**Практическое следствие:** триггер `platform: state` с `not_from: [unavailable, unknown]` **не сработает на первое нажатие после рестарта** (`unknown` блокирует) — нужно второе. + +**Фикс (точечный, не зависит от z2m):** убрать `not_from: [unknown]` из триггеров кнопок в `automations.yaml`. +⚠️ На момент записи фикс **НЕ применён** — ожидает решения Alex (альтернатива: копать, почему `cache_state_send_on_startup` не отрабатывает — без гарантии). + +> ℹ️ Датчики (t°/освещённость/радар) выходят из `unknown` сами за секунды-минуты — страдают только **реле и кнопки**. +> ℹ️ Проверка живости узла без нажатия — `get`-запрос: `mosquitto_pub … -t 'zigbee2mqtt//get' -m '{"state_l1":""}'` → устройство отвечает текущим состоянием. + > 🔑 **Диагностический приём:** чтобы понять, жив ли узел, смотреть **`lastSeen` в `database.db`** (`/config/zigbee2mqtt/database.db`, JSON-lines, читать **построчно** — это НЕ единый JSON!): > ```bash > while IFS= read -r line; do @@ -969,6 +1004,8 @@ curl -s -X POST -K curl.auth -H "Content-Type: application/json" \ - [x] ✅ **ВЫПОЛНЕНО 2026-09-14 (конец сессии) — ЗОНЫ восстановлены у 18 устройств.** `area_id` теряется при ре-регистрации устройств (как `device_id`) — все 14 zigbee были без зон. Проставлены по эталону с TrueNAS по `identifiers[0][1]` (`zigbee2mqtt_`). Скрипт: `~/tmp-t610/etap3-fix/set_all_areas.jq`. - [x] ✅ **ИСПРАВЛЕНО 2026-09-14 (конец сессии) — office-переключатель:** hex-`entity_id` в **триггерах** автоматизаций (`switch.0xa4c13873b5c1575b_l1/l2` → `switch.office_table_light_switch_l1/l2`); реле выведены из `unknown` нажатием кнопок. Цепочка управления светом проверена на живом. - [x] ✅ **УСТАНОВЛЕНО 2026-09-14 (конец сессии) — z2m не публикует состояние пассивно:** реле «залипают» в `unknown` до первого события. Живость проверять по `lastSeen` в `database.db` (JSON-lines, читать построчно). +- [x] ✅ **ПРОВЕРЕНО ЭКСПЕРИМЕНТОМ 2026-09-14 — `unknown` возвращается после рестарта HA.** Зафиксировано состояние → рестарт → состояние снято: всё `on`/`off` слетело в `unknown`. `retain: true` + `cache_state*` в z2m стоят, но retained на топиках устройств фактически не публикуется (контроль: `bridge/state` retained есть). Питфолл: `mosquitto_sub -R` в аддоне врёт. См. §«ДОБАВЛЕНО В КОНЦЕ СЕССИИ» ③‑бис. +- [ ] ⚠️ **ОТКРЫТО (на решение Alex): убрать `not_from: [unknown]` из триггеров кнопок** в `automations.yaml` — иначе первое нажатие после рестарта HA не срабатывает (`unknown` блокирует триггер). Альтернатива — копать `cache_state_send_on_startup`. **Фикс не применён.** - [ ] ⚠️ Незакреплённое: `sensor.0xa4c138f8da8bc478_voltage/energy/power/current` (11 hex-сущностей розетки Насос обратки) — проживут ли под новым `friendly_name` или создадутся дубли; проверить после шага 8. ## Связанные заметки