From 03c9720ebff9e7bcc819e66b3bde8145ab35b8bb Mon Sep 17 00:00:00 2001 From: Alexey Martemyanov Date: Wed, 16 Sep 2026 12:19:45 +0600 Subject: [PATCH] [2026-09-16] eagle: family/how-to/ha-automations.md family/plans/t610-zigbee-ids-battery-freshsensors-modbus.md --- family/how-to/ha-automations.md | 9 ++ ...-zigbee-ids-battery-freshsensors-modbus.md | 82 ++++++++++++++++++- 2 files changed, 89 insertions(+), 2 deletions(-) diff --git a/family/how-to/ha-automations.md b/family/how-to/ha-automations.md index 4f5cc6dd..740303a2 100644 --- a/family/how-to/ha-automations.md +++ b/family/how-to/ha-automations.md @@ -307,6 +307,15 @@ mode: single Распределение по триггерам: **`lux` → sleep 2 → проверка присутствия → включить; `presence` → сразу.** +> ⚠️ **Не путать поведение по сценариям** (формулировка «включится через 2–3 с» — НЕВЕРНА): +> | Сценарий | Триггер | Когда включается | +> |---|---|---| +> | Заходишь в тёмную душевую | `presence` → `on` | **сразу**, доли секунды | +> | Уже внутри, свет погас | `lux` падает < 6 | sleep 2 → проверка присутствия → включить | +> +> Мгновенность ветки `presence` ограничена не задержкой, а **mmWave-радаром**: `detection_delay = 0.1 с`, `fading_time = 10 с`. Проверено историей: `presence 01:36:07.413` → `свет 01:36:08.195` = **0.78 с**. +> В истории видны и «медленные» пары (`04:53:27.744` → свет `04:53:45.979` = 18 с; `05:14:36.901` → `05:14:50.149` = 13 с) — это НЕ срабатывание по присутствию, а ветка `lux`: радар не переиздал `on`, присутствие уже было `true`, свет включился по падению освещённости. + > 🔴 **ПИТФОЛЛ: `condition: state` с числовым порогом НЕ принимает `below`.** HA отбивает POST: `Message malformed: not a valid option at 'conditions[0].below'`. Порог по освещённости задаётся **только** device-условием `type: is_illuminance`. Ошибка приходит валидацией — конфиг не портится (проверено: после отказа значения остались прежними). > 🔴 **ПИТФОЛЛ: `automation.trigger` НЕ подставляет `trigger.id`.** Прогон через него всегда уходит в `default` — ветку `choose` по `trigger.id` так **не протестировать**. Проверять воспроизведением логики временным скриптом (`/api/config/script/config/` → reload → вызов → DELETE). > ⚠️ `delay` живёт **только в `actions:`** — он не знает, какой триггер сработал. Различать ветки обязательно через `trigger.id` + `choose`. diff --git a/family/plans/t610-zigbee-ids-battery-freshsensors-modbus.md b/family/plans/t610-zigbee-ids-battery-freshsensors-modbus.md index f152506d..657d5f31 100644 --- a/family/plans/t610-zigbee-ids-battery-freshsensors-modbus.md +++ b/family/plans/t610-zigbee-ids-battery-freshsensors-modbus.md @@ -1,10 +1,10 @@ --- title: "План и результат: читаемые ID Zigbee, алерты батарей, виртуальные Modbus-датчики" created: '2026-09-15' -updated: '2026-09-16 (ночь: добавлены этапы 5–6 — снос призраков реестра, починка плана этажей и H2000_PRO)' +updated: '2026-09-16 (день: добавлен этап 7 — починка автоматизаций кабинета + задержка в душевой)' type: plan namespace: family -status: 🟢 ВЫПОЛНЕНО 2026-09-16. Шаги 1–4 закрыты 2026-09-15; 5–6 (вычистка призраков + починка UI) закрыты 2026-09-16 ночью. Всё проверено фактами. +status: 🟢 ВЫПОЛНЕНО 2026-09-16. Шаги 1–4 закрыты 2026-09-15; 5–6 (вычистка призраков + починка UI) — 2026-09-16 ночью; 7 (починка автоматизаций кабинета + задержка в душевой) — 2026-09-16 днём. Всё проверено фактами. tags: - t610 - zigbee @@ -324,6 +324,80 @@ Alex: «Office temperature sensor battery — HA ругается что у ус --- +## 4b. ✅ ЭТАП 7 — последствия переименования: починка автоматизаций кабинета + задержка в душевой (2026-09-16, день) + +**Контекст:** этапы 1–4 переименовали сущности в единый вид `_`, но **две автоматизации кабинета остались на старых ZHA-именах** — хабы симптомов, найденных на следующий день. + +### 7.1. Свитч у стола в кабинете не переключал свет + +**Симптом (Alex):** «свитч у стола не тригерит переключение света». Сначала прозвучало «вчера ещё работало». + +**Первопричина — урок №2 из §7, реализовавшийся буквально:** переименование рвёт ссылки в `automations.yaml` молча. Из 25 автоматизаций переехали 23, эти две — нет. + +| id | alias | Было (мёртвое, 404) | Стало (живое) | +|---|---|---|---| +| `5735cb9f855e462dbdbdf680d0d6a66f` | `office_pass_switch_table` | `light.tz3000_5gey1ohx_ts0002_osveshchenie` | `light.office_table_light_switch_light` | +| `45b96f6f38f6488ba70266fa5da665f5` | `office_pass_switch_main` | `light.tz3000_5gey1ohx_ts0002_osveshchenie_2` | `light.office_table_light_switch_light_2` | + +**Как доказано:** триггерные сущности → **404** в `/api/states`; реле при этом живы и щёлкали (нажатия доходили до Zigbee), но целевые `light.smart_light_office_left/right` висели `off` без изменений. + +> ⚠️ **Ключевой признак, который легко пропустить:** автоматизация с мёртвым триггером остаётся **`state: on`** — `unavailable` НЕ появляется, ошибок в UI нет. Единственный симптом — `last_triggered` не растёт. + +### 7.2. Свет мигал при перезагрузке HA — потерялась защита `not_from` + +**Причина:** на TrueNAS триггеры несли `not_from: [unavailable, unknown]` (`~/tmp-t610/stage3/truenas/automations.yaml` — эталон). При пересборке автоматизаций под ZHA поле **не перенесли** → голая `platform: state` срабатывала на старте HA (`unavailable → on`) и дёргала `light.toggle`. + +**Фикс:** восстановлен `not_from: [unavailable, unknown]` в обеих автоматизациях. + +**Верификация — реальный рестарт HA Core, а не рассуждение:** + +| Метрика | До | После | Итог | +|---|---|---|---| +| `office_pass_switch_table.last_triggered` | `05:43:07` | `05:43:07` | не изменился ✅ | +| `office_pass_switch_main.last_triggered` | `05:43:20` | `05:43:20` | не изменился ✅ | +| `light.smart_light_office_left/right` | `off` | `off` | не мигнул ✅ | + +В logbook: `automation.office_pass_switch_table → unavailable` (`05:45:02.156`), через 3 мс `→ on` — и **ни одной** записи `triggered by state`. Событие отфильтровано. + +> 🆕 **Урок №11:** защитные поля триггера (`not_from`/`to`) **теряются при пересборке автоматизаций**. При любой пересборке — сверять их наличие, а не только `entity_id`. `to:` как альтернатива **не нужен**: наблюдаемый порядок `unavailable → on` отсекается `not_from`. + +### 7.3. Задержка 2 с на ветке освещённости в душевой + +**Задача (Alex):** освещённость упала → sleep 2 → присутствие == true → включить. **Только на триггер по свету**, по присутствию — мгновенно. + +**Зачем:** радар mmWave отдаёт `presence` с задержкой; при падении освещённости присутствие не успевало выставиться → условие не проходило → свет не включался. + +**Решение:** триггеры размечены `trigger.id` (`lux` / `presence`), задержка повешена на ветку `lux` через `choose`: + +```yaml +triggers: +- {type: occupied, entity_id: binary_sensor.shower_2_presence_sensor_presence, id: presence} +- {type: illuminance, entity_id: sensor.shower_2_presence_sensor_illuminance, below: 6, id: lux} +actions: +- choose: + - conditions: [{condition: trigger, id: lux}] + sequence: + - {delay: {seconds: 2}} + - {condition: device, type: is_occupied, entity_id: binary_sensor...presence} + default: [] +- {action: light.turn_on, target: {entity_id: light.dushevaia_night_light}} +``` + +**Верификация:** замер по `last_changed` — вызов `06:13:34` → свет `06:13:37.24` (2 с выдержаны); ветка `lux` при `presence=off` свет **не** включает. + +> 🔴 **ПИТФОЛЛ:** `condition: state` с числовым порогом **не принимает `below`** → `Message malformed: not a valid option at 'conditions[0].below'`. Порог освещённости задаётся только device-условием `type: is_illuminance`. +> 🔴 **ПИТФОЛЛ:** `automation.trigger` **не подставляет `trigger.id`** → прогон всегда уходит в `choose.default`, ветку так не протестировать. Проверять временным скриптом (`/api/config/script/config/` → reload → вызов → DELETE). +> ⚠️ `delay` живёт только в `actions:` и не знает, какой триггер сработал — ветки различать через `trigger.id` + `choose`. + +**ВЫКЛ (`1771997918348`) НЕ тронут** — по решению Alex задержка нужна только на триггере по свету. + +**Бэкапы:** `/config/automations.yaml.bak-office-20260916-124244`, `.bak-showerdelay-20260916-131126` на t610; `~/tmp-t610/automations/automations.yaml.{office-before,shower-before}` локально. +**Скрипты:** `fix_office_switch.sh`, `fix_office_guard.sh`, `fix_shower_lux_delay.sh`, `test_shower_lux_branch.sh`, `test_delay_timing.sh` — все в `~/tmp-t610/`. + +**Детали:** [[family/how-to/ha-automations]] §2.2, §3, §4.1; питфоллы №27–32 в [[family/tech/zigbee-t610-z2m-i-zha]]. + +--- + ## 5. ✅ РЕЗУЛЬТАТ — Шаг 5: дока обновлена - `family/tech/zigbee-t610-z2m-i-zha.md` — карта 16 → 23 устройств, §2.1 «как переименовывать», §4 батареи, §5 виртуальные Modbus, питфоллы 17–21. @@ -359,6 +433,10 @@ Alex: «Office temperature sensor battery — HA ругается что у ус | 8 | `id_reuse: Identifier values have to increase` — штатная ошибка реестра, обходится промежуточным именем (`old → tmp → new`) | | 9 | HA перегенерирует `entity_id` автоматизаций по alias при `reload` — искать по `attributes.id` | | 10 | Датчик, «не находимый в UI», может быть переименован — искать по IEEE в реестре, а не по старому имени | +| 11 | **Защитные поля триггера (`not_from`) теряются при пересборке автоматизаций** — при пересборке сверять не только `entity_id`, но и их наличие. Симптом-близнец: свет мигает при рестарте HA | +| 12 | **Автоматизация с мёртвым триггером остаётся `state: on`** — `unavailable` не появляется. Признак один: `last_triggered` не растёт. Проверять сверкой всех `entity_id:` из YAML со `/api/states` | +| 13 | `automation.trigger` не подставляет `trigger.id` → ветку `choose` по `trigger.id` так не протестировать; нужен временный скрипт | +| 14 | `condition: state` не принимает числовой `below` — порог только device-условием `type: is_illuminance` | ## Связанные заметки