From 61bd507a1fc9b9e92c20568ee2d92fd72e588ce5 Mon Sep 17 00:00:00 2001 From: Alexey Martemyanov Date: Wed, 16 Sep 2026 20:17:42 +0600 Subject: [PATCH] [2026-09-16] eagle: family/how-to/ha-automations.md family/how-to/home-automation.md family/plans/t610-zigbee-ids-battery-freshsensors-modbus.md family/tech/zigbee-t610-z2m-i-zha.md --- family/how-to/ha-automations.md | 66 +++++++++++++++- family/how-to/home-automation.md | 1 + ...-zigbee-ids-battery-freshsensors-modbus.md | 71 +++++++++++++++-- family/tech/zigbee-t610-z2m-i-zha.md | 78 +++++++++++++++++-- 4 files changed, 197 insertions(+), 19 deletions(-) diff --git a/family/how-to/ha-automations.md b/family/how-to/ha-automations.md index 78bee951..90a977c9 100644 --- a/family/how-to/ha-automations.md +++ b/family/how-to/ha-automations.md @@ -4,19 +4,25 @@ > 🟢 **25 АВТОМАТИЗАЦИЙ — 24 `on`, 1 `off`** (`Ventilation automation on`, намеренно), `unavailable` = 0. Zigbee работает на ZHA. > -> **Состав:** 12 контроля батарей (§5) + 2 циркуляция ГВС + 2 свет кабинета (§2.2, §3) + 2 подсветка лестницы + 2 ночной свет душевой (§4.1–§4.5) + 2 диммер спальни + 1 протечка котельная + 1 вентиляция + **1 греющий кабель ввода воды (§7)**. +> **Состав:** 12 контроля батарей (§5) + 2 циркуляция ГВС + 2 свет кабинета (§2.2, §3) + 2 подсветка лестницы + 2 ночной свет душевой (§4.1–§4.6.2) + 2 диммер спальни + 1 протечка котельная + 1 вентиляция + **1 греющий кабель ввода воды (§7)**. > -> 🗓 **Сессия 2026-09-16 (день):** починены два дефекта автоматизаций кабинета — мёртвые `entity_id` в триггерах (§2.2) и потерянная защита `not_from` (§3). В душевой: задержка на ветку по освещённости (§4.1), `fading_time` 10→2 с + задержка 10 с в сценарии ВЫКЛ (§4.2). ⛔ **Задержка ВКЛ `2 → 3 → 5 с` проблему НЕ решила** — фиксированный таймер отброшен, ветка `lux` переведена на `wait_for_trigger` по событию `presence → off` (§4.5). +> 🗓 **Сессия 2026-09-16 (день):** починены три дефекта автоматизаций — мёртвые `entity_id` в триггерах кабинета (§2.2), потерянная защита `not_from` (§3), ложные включения ночного света душевой (§4.4). В душевой также: задержка на ветку по освещённости (§4.1), `fading_time` 10→2 с + задержка 10 с в сценарии ВЫКЛ (§4.2). **Итог приёмки (§4.6.1):** ложное включение при выходе устранено; осталось дрожание радара (§4.6.2). > -> 🟡 **ОСТАЁТСЯ ОТКРЫТЫМ — только один вопрос (§4.4):** feedback loop через собственную лампу (пороги ВКЛ/ВЫКЛ совпадают: `6`/`6`, мёртвая зона нулевая → дребезг `2–4` ↔ `11–12`). Гистерезис `< 4` / `> 10` **предложен, но отклонён Alex** — пороги не менять без явной команды. Ложные включения при выходе переведены на событийную проверку (§4.5) — **ждёт подтверждения на практике**. +> 🔴 **ГЛАВНЫЙ УРОК СЕССИИ (§4.4):** `condition:` внутри `sequence:` НЕ отменяет остальные `actions` — прерывает только свою `sequence`, а родительский список продолжается. `light.turn_on`, стоявший **после** `choose`, выполнялся **всегда**, даже когда проверка присутствия вернула `false` (доказано трассировкой: `result: false` и через 1 мс — включение). **Действие обязано быть ВНУТРИ ветки `choose`, после проверки.** Это была ошибка проектирования, а не настройки. +> +> 🟡 **ОСТАЁТСЯ ОТКРЫТЫМ — два вопроса:** +> 1. **§4.6 — feedback loop через собственную лампу** (пороги ВКЛ/ВЫКЛ совпадают: `6`/`6`, мёртвая зона нулевая → дребезг `2–4` ↔ `11–12`). Гистерезис `< 4` / `> 10` **предложен, но отклонён Alex** — пороги не менять без явной команды. +> 2. **§4.6.2 — дрожание радара** (серии `on/off`, включая `on` на 1.8 с). Усилено снижением `fading_time` до 2 с. Предложен возврат к 10 с — **решения Alex нет**. > > **Ключевые факты:** > - 🔴 **ЗАЩИТА ТРИГГЕРА ОБЯЗАТЕЛЬНА для `platform: state` на реле/кнопках:** `not_from: [unavailable, unknown]`. Без неё автоматизация срабатывает при старте HA (`unavailable → on`) и дёргает действие. Реальный случай 2026-09-16 — мигание света в кабинете. **При пересборке автоматизаций это поле теряется молча** (§3). +> - 🔴 **Действие — ВНУТРИ ветки `choose`, после проверки.** Не на верхнем уровне `actions` (§4.4). +> - 🔴 **Трассировки автоматизаций — ТОЛЬКО WebSocket** (`trace/list` + `trace/get`, `item_id` = **внутренний ID**, не `entity_id`; REST → 404). **Читать трассировку ДО перебора гипотез.** Инструмент: `~/tmp-t610/trace_dump.py` (на t610 python3 НЕТ). > - 🔴 **`entity_id` автоматизаций HA перегенерирует по alias** — искать по `attributes.id`, не по `entity_id`. > - 🔴 **REST `GET/POST /api/config/automation/config/` использует поля во множественном числе** — `triggers`/`conditions`/`actions` (в файле — единственное). Ошибка молча уходит в пустоту: POST → `200 ok`, значения НЕ меняются. **Всегда читать обратно.** > - ⚠️ **Кнопка спальни** шлёт `remote_button_short_press` только после `zha/devices/reconfigure`. > -> **Бэкапы перед правками:** `automations.yaml.bak-cable3-20260915-*` (кабель), `.bak-preids-*`, `.bak-gard-*` (единообразие ID). Локальные копии в `~/tmp-t610/`. +> **Бэкапы сессии 2026-09-16:** `.bak-office-20260916-124244` (кабинет), `.bak-showerdelay-20260916-131126`, `.bak-shower-off-20260916-205245`, `.bak-shower-delay3-20260916-205557`, `.bak-shower-delay5-20260916-205953`, `.bak-shower-final-20260916-211051` (душевая). Локальные копии в `~/tmp-t610/`. > 📄 Рецепт пересборки после Z2M→ZHA и питфоллы — [[family/tech/zigbee-t610-z2m-i-zha]]. > > 🔴 **ПИТФОЛЛЫ, найденные при починке:** @@ -503,6 +509,58 @@ mode: single **Что применено в рамках этого разбора:** `fading_time 10 → 2` + задержка 10 с в сценарии ВЫКЛ (§4.2), затем перевод ветки ВКЛ на событийную проверку `wait_for_trigger` (§4.5) — всё по прямому указанию Alex. +### 4.6.1. ✅ ПРИЁМКА Alex (2026-09-16, вечер) — что подтверждено, что осталось + +**Подтверждено Alex после фикса §4.4:** + +| Сценарий | Поведение | Статус | +|---|---|---| +| Вышел + выключил свет | подсветка **НЕ** зажглась | ✅ работает | +| Не выходя — выключил свет | подсветка зажглась через 5 с | ✅ работает (так и задумано) | +| Зашёл в тёмную | зажигается **сразу** | ✅ (ветка `presence`) | + +**Остаточные симптомы, зафиксированные Alex (НЕ закрыты):** + +1. **«Зашёл — зажглась будто с задержкой».** Причина: если одновременно с приходом дёрнулась освещённость, срабатывает **ветка `lux`** (с `delay: 5`), а не ветка `presence` (мгновенная). Ощущение задержки — цена 5-секундной паузы в `lux`. +2. **«Зажглось и сразу погасло»** — при заходе без света. Разобрано в §4.6.2: дрожание радара. + +### 4.6.2. 🔴 ДРОЖАНИЕ РАДАРА — источник серий `on/off` (2026-09-16) + +**Измерено фактом.** Радар `shower_2_presence_sensor` выдаёт `on`/`off` короткими интервалами: + +``` +14:11:17.97 on +14:11:25.35 off (7.4 с) +14:11:33.92 on (8.6 с) +14:11:42.10 off (8.2 с) +14:11:43.90 on (1.8 с!) ← радар потерял присутствие, хотя человек внутри +14:11:48.68 off (4.8 с) +14:11:55.86 on (36.3 с) +14:12:24.18 off +``` + +**Пары `LIGHT=on → LIGHT=off` за 0.12–0.13 с происходят БЕЗ записи `AUT-OFF` в logbook:** +``` +14:11:43.897 AUT-ON triggered by presence +14:11:44.082 LIGHT=on +14:11:44.201 LIGHT=off ← 0.12 с, триггера ВЫКЛ НЕТ +14:11:48.683 AUT-OFF triggered by presence +``` +Между `44.201` и `48.683` прошло **4.5 с** — сценарий ВЫКЛ сработал позже, значит погасил **не он**. + +> 🔴 **Усилитель проблемы — `fading_time = 2 с` (снижен мной по прямому указанию Alex, §4.2).** Радар отпускает присутствие за 2 с вместо 10, поэтому любое замирание даёт `off`, а следующее движение — `on`. **Исходное значение 10 с как раз прощало неподвижность в душевой.** + +**Проверено, что реле исправно:** ручной `light.turn_on` → **27 опросов подряд с шагом 200 мс** — состояние `on` стабильно, сброса нет. Значит железо удерживает состояние, а дрожание идёт от логики/датчика. + +**Предложенные варианты (НЕ применены, ждут решения Alex):** +| # | Мера | Что лечит | +|---|---|---| +| 1 | Вернуть `fading_time` → **10 с** | дрожание радара, серии `on/off` | +| 2 | Поднять `minimum_range` / сузить зону | если радар задевает движение за дверью | +| 3 | Оставить как есть, наблюдать | — | + +> ⚠️ **Методическое замечание:** при диагностике Alex **сам дёргал `light.turn_on`/`turn_off` через API** для проверки удержания реле — это загрязняло логи. Записи `LIGHT=on` **без** `AUT-ON` рядом = внешний вызов, а не сценарий. Учитывать при разборе. + --- ## 4.5. ⛔ ЧТО НЕ СРАБОТАЛО: полная хронология перебора (2026-09-16) diff --git a/family/how-to/home-automation.md b/family/how-to/home-automation.md index 7b2bc7fd..ddd327c2 100644 --- a/family/how-to/home-automation.md +++ b/family/how-to/home-automation.md @@ -11,6 +11,7 @@ updated: 2026-09-16 > **Автоматизации** (25 шт., логика, дефекты) — [[family/how-to/ha-automations]]. > 📄 Правка этой доки не появится на телефоне после `git push` — нужен прогон sync-петли: [[family/how-to/vault-sync-pipeline]]. > 🧰 Локальные скрипты диагностики: `~/tmp-t610/diag.sh`, `diag2.sh`, `diag3.sh`, `diag4.sh`, `stats.sh` (снимаются на t610 через `scp` + `sh /tmp/…`). +> 🔎 **Диагностика автоматизаций — трассировки (WebSocket-only):** `~/tmp-t610/trace_dump.py ` — печатает каждый шаг запуска с результатами условий. `item_id` = внутренний ID, не `entity_id`. Читать **до** перебора гипотез — см. [[family/how-to/ha-automations]] §4.4. --- diff --git a/family/plans/t610-zigbee-ids-battery-freshsensors-modbus.md b/family/plans/t610-zigbee-ids-battery-freshsensors-modbus.md index cb2b46a1..53809d89 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 (день: этап 7 расширен — починка автоматизаций кабинета, задержки ночного света душевой, `fading_time` 10→2 с, тюнинг задержки ВКЛ до 5 с)' +updated: '2026-09-16 (день: этап 8 — КОРЕНЬ дефекта душевой найден трассировкой: `condition` внутри `sequence` не отменяет остальные `actions`)' type: plan namespace: family -status: 🟢 ВЫПОЛНЕНО 2026-09-16. Шаги 1–4 закрыты 2026-09-15; 5–6 (вычистка призраков + починка UI) — 2026-09-16 ночью; 7 (починка автоматизаций кабинета + душевая: задержки, `fading_time`) — 2026-09-16 днём. Всё проверено фактами. 🟡 Открыт один вопрос — feedback loop по порогам душевой (§4.4 в [[family/how-to/ha-automations]]), правка отклонена Alex. +status: 🟢 ВЫПОЛНЕНО 2026-09-16. Шаги 1–4 закрыты 2026-09-15; 5–6 (вычистка призраков + починка UI) — 2026-09-16 ночью; 7–8 (автоматизации кабинета — 2 дефекта; душевая — `fading_time` 10→2, задержка 10 с в ВЫКЛ, ложные включения ВКЛ) — 2026-09-16 днём. Всё проверено фактами. 🟡 Открыт один вопрос — feedback loop по порогам душевой (§4.6 в [[family/how-to/ha-automations]]), правка отклонена Alex. tags: - t610 - zigbee @@ -409,15 +409,66 @@ actions: **Замер (цикл `13:58`):** при `fading_time = 2 с` радар отпускает присутствие **через 3.2 с после выключения света**. Задержка 3 с заканчивалась в `13:58:13.54`, presence сбрасывался в `13:58:13.73` — **на 0.19 с позже**, поэтому проверка `is_occupied` проходила и свет включался. -**Фикс:** `delay` в ветке `lux` поднят до **5 с** (запас 1.8 с). Итоговое состояние — `delay: 5 s`. +**Фикс (шаг 7):** `delay` в ветке `lux` поднят до **5 с** (запас 1.8 с). > 🔴 **ПРАВИЛО ПОДБОРА: задержка должна быть больше ОКНА ОТПУСКАНИЯ радара (не `fading_time`).** Измеренное окно при `fading_time = 2 с` = **3.2 с**. -> ⚠️ Надёжная альтернатива фиксированной задержке: `wait_for_trigger` на `presence → off` — проверка идёт после отпускания, независимо от `fading_time`. **Предложено Alex, ждёт решения** — если 5 с не хватит. -**Бэкапы:** `/config/automations.yaml.bak-office-20260916-124244`, `.bak-showerdelay-20260916-131126`, `.bak-shower-off-20260916-205245`, `.bak-shower-delay3-20260916-205557`, `.bak-shower-delay5-20260916-205953` на t610; `~/tmp-t610/automations/automations.yaml.{office-before,shower-before}` локально. -**Скрипты:** `fix_office_switch.sh`, `fix_office_guard.sh`, `fix_shower_lux_delay.sh`, `fix_shower_as_requested.sh`, `fix_shower_delay3.sh`, `fix_shower_delay5.sh`, `test_shower_lux_branch.sh`, `test_delay_timing.sh`, `check_shower_timing.sh` — все в `~/tmp-t610/`. +⛔ **НО 5 с ТОЖЕ НЕ ПОМОГЛИ.** Шаг 8 (см. ниже) показал, что причина была не в задержке вообще. -**Детали:** [[family/how-to/ha-automations]] §2.2, §3, §4.1–§4.4; питфоллы №27–35 в [[family/tech/zigbee-t610-z2m-i-zha]]. +**Бэкапы:** `/config/automations.yaml.bak-office-20260916-124244`, `.bak-showerdelay-20260916-131126`, `.bak-shower-off-20260916-205245`, `.bak-shower-delay3-20260916-205557`, `.bak-shower-delay5-20260916-205953`, `.bak-shower-final-20260916-211051` на t610; `~/tmp-t610/automations/automations.yaml.{office-before,shower-before}` локально. +**Скрипты:** `fix_office_switch.sh`, `fix_office_guard.sh`, `fix_shower_lux_delay.sh`, `fix_shower_as_requested.sh`, `fix_shower_delay3.sh`, `fix_shower_delay5.sh`, **`fix_shower_final.sh`** (итог), `test_shower_lux_branch.sh`, `test_delay_timing.sh`, `check_shower_timing.sh`, **`trace_dump.py` / `trace_read.py`** (трассировки) — все в `~/tmp-t610/`. + +**Детали:** [[family/how-to/ha-automations]] §2.2, §3, §4.1–§4.6; питфоллы №27–41 в [[family/tech/zigbee-t610-z2m-i-zha]]. + +--- + +## 4.8. ✅ РЕЗУЛЬТАТ — Шаг 8: КОРЕНЬ ложных включений душевой (2026-09-16, день) + +**Симптом:** свет включался после выхода из душевой, несмотря на проверку присутствия. Задержка 2→3→5 с и `fading_time` 10→2 **не помогали** — ни один вариант не дал результата. + +**Первопричина — найдена трассировкой HA, а не перебором настроек:** + +``` +14:02:38.426597 action/0/choose/0/sequence/1/entity_id/0 + {"result": false, "state": "off", "wanted_state": "on"} ← проверка ОТБИЛА +14:02:38.427615 action/1 → light.turn_on ← ВКЛЮЧИЛ +``` + +🔴 **`condition:` внутри `sequence:` прерывает ТОЛЬКО свою `sequence`.** Управление возвращается в родительский список `actions` и продолжает выполнять следующие шаги. `light.turn_on`, стоявший **после** `choose` (на верхнем уровне `actions`), выполнялся **всегда** — при любом результате проверки. + +**Это была ошибка проектирования автоматизации, а не настройки.** Alex трижды просил «чинить то, что просили», а я подбирал числа вместо того, чтобы прочитать трассировку, которая всё время лежала в HA. + +**Фикс:** оба `light.turn_on` перенесены **внутрь** веток `choose`: +```yaml +actions: +- choose: + - conditions: [{condition: trigger, id: presence}] + sequence: [{action: light.turn_on, ...}] # заход → мгновенно + - conditions: [{condition: trigger, id: lux}] + sequence: + - {delay: {seconds: 5}} + - {condition: state, entity_id: presence, state: "on"} + - {action: light.turn_on, ...} # ✅ внутри, после проверки + default: [] +``` + +**Как искать причину (переиспользуемый рецепт):** + +```bash +# 1. Трассировки — ТОЛЬКО WebSocket, REST → 404 +# item_id = ВНУТРЕННИЙ ID автоматизации (1771997851260), НЕ entity_id +python3 ~/tmp-t610/trace_dump.py 14:02:33 +# 2. Сопоставить три ряда в одном окне: history/period по presence + illuminance + light +# 3. logbook С ПОЛЕМ message → «triggered by numeric state of ...» = какая ветка choose +``` + +**Верификация:** конфиг прочитан обратно (оба `light.turn_on` внутри `choose`); автоматизации 25/24 `on`/`1` `off`, `unavailable` = 0. +**Бэкап:** `/config/automations.yaml.bak-shower-final-20260916-211051`. +**Скрипт:** `~/tmp-t610/fix_shower_final.sh`. + +> ⏳ **Ждёт практического подтверждения Alex:** зайти в тёмную душевую (должно включиться сразу) и выйти, выключив свет (должно не зажечься). + +**Детали:** [[family/how-to/ha-automations]] §4.4 (корневой разбор), §4.5 (что не сработало), §4.6 (предыстория). --- @@ -460,6 +511,12 @@ actions: | 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` | +| 15 | 🔴 **`condition:` внутри `sequence:` НЕ отменяет остальные `actions`** — прерывает только свою `sequence`, родительский список продолжается. **Действие ставить ВНУТРИ ветки `choose`.** Иначе проверка вернёт `false`, а действие всё равно выполнится. Ошибка молчаливая | +| 16 | 🔴 **Трассировки автоматизаций — ТОЛЬКО WebSocket** (`trace/list` + `trace/get`; `item_id` = ВНУТРЕННИЙ ID, не `entity_id`; REST → 404). **Читать трассировку ДО перебора гипотез** — в этой сессии три итерации подбора задержек ушли впустую, потому что трассировка не читалась | +| 17 | 🔴 **Не строить `wait_for_trigger` с взаимоисключающими условиями** — `from: on, to: off` + требование `presence == on` невыполнимо, свет не включится никогда. Проверять выполнимость цепочки до заливки в прод | +| 18 | **Фиксированный `delay` ненадёжен для «дождаться, пока датчик отпустит»** — момент проверки плавает (замерено ~1.1 с накладных на диспетчеризацию). Окно отпускания радара тоже плавает (3.19–3.59 с) | +| 19 | ⚠️ **`condition: device / is_occupied` может не отражать свежий `state`** — для проверок по только что изменившемуся состоянию использовать `condition: state` | +| 20 | Проверенная тактика диалога: Alex не принимает объяснения вместо факта — на «не работает» нужно читать логи/трассировки, а не перебирать настройки | ## Связанные заметки diff --git a/family/tech/zigbee-t610-z2m-i-zha.md b/family/tech/zigbee-t610-z2m-i-zha.md index f069adb5..c2153590 100644 --- a/family/tech/zigbee-t610-z2m-i-zha.md +++ b/family/tech/zigbee-t610-z2m-i-zha.md @@ -2,10 +2,10 @@ title: "Zigbee на t610 — ZHA (справочник)" created: '2026-09-15' updated: 2026-09-16 -note: "ночь: вычищены 185 призраков Z2M из архива реестра deleted_entities 360→175; план этажей починен — ссылка на снесённого light.smart_light_stairs_l1 → light.light_stairs_left; H2000_PRO °F→°C сбросом sensor.private override; 🍳 kitchen_hood — ZHA отдаёт как 3 × light.*; ✅ выведен в 🌀 fan.kitchen_hood Template-хелпером → [[family/tech/kitchen-hood-fan-template]]" +note: "ночь: вычищены 185 призраков Z2M из архива реестра deleted_entities 360→175; план этажей починен — ссылка на снесённого light.smart_light_stairs_l1 → light.light_stairs_left; H2000_PRO °F→°C сбросом sensor.private override; 🍳 kitchen_hood — ZHA отдаёт как 3 × light.*; ✅ выведен в 🌀 fan.kitchen_hood Template-хелпером → [[family/tech/kitchen-hood-fan-template]]; вечер: §13.5 — трассировки HA только по WebSocket, дрожание радара душевой, floor `fading_time` = 2 с, проверка удержания реле" type: tech namespace: family -status: "🟢 РАБОТАЕТ. ZHA: 24 записи (23 устройства + координатор), unavailable = 0. Все устройства с читаемыми ID в едином виде, все в зонах. 24 автоматизации: 23 on, 1 off намеренно. Bridge: 9 Zigbee-температур отдаются ZONT'у (slave 100–112). Призраки Z2M в архиве реестра вычищены; план этажей и H2000_PRO исправлены. unavailable всего 8 — вентиляция AT2 + todo.shopping_list (намеренно)." +status: "🟢 РАБОТАЕТ. ZHA: 24 записи (23 устройства + координатор), unavailable = 0. Все устройства с читаемыми ID в едином виде, все в зонах. 25 автоматизаций: 24 on, 1 off намеренно (обновлено 2026-09-16 вечер). Bridge: 9 Zigbee-температур отдаются ZONT'у (slave 100–112). Призраки Z2M в архиве реестра вычищены; план этажей и H2000_PRO исправлены. unavailable всего 8 — вентиляция AT2 + todo.shopping_list (намеренно). 🔴 Радар душевой `shower_2_presence_sensor` дрожит (`on`/`off` сериями, вплоть до `on` на 1.8 с) — усилено снижением `fading_time` до 2 с; см. [[family/how-to/ha-automations]] §4.6.2" tags: - t610 - haos @@ -413,12 +413,12 @@ curl -s -H "$HDR" http://supervisor/backups | jq | 33 | 🔴 **`fading_time` радара `_TZE204_qasjif9e` (TS0601) не опускается ниже 2 с** | HA показывает `min: 1` и отдаёт `state: 1.0` в ответе `number.set_value`, но сущность откатывается к `2.0`. Проверено: `1.0` → `2.0`, `1.5` → `2.0`, `2.5` → `2.5`. Прошивка молча игнорирует < 2. **Всегда читать обратно** | | 34 | 🔴 **`condition:` внутри `sequence:` НЕ отменяет остальные `actions`** | Прерывает только свою `sequence`; управление возвращается в родительский список `actions` и выполняет следующие шаги. `light.turn_on` **после** `choose` выполнится ВСЕГДА, даже если проверка вернула `false`. Действие обязано быть **внутри** ветки, после проверки. Доказано трассировкой: `sequence/1/entity_id/0 → {"result": false}` и через 1 мс `action/1 → light.turn_on`. Разбор: [[family/how-to/ha-automations]] §4.4 | | 35 | 🔴 **Трассировки автоматизаций — ТОЛЬКО WebSocket** | REST (`/api/trace/...`) → 404. Команды `trace/list` + `trace/get`, домен `automation`. 🔴 `item_id` = **внутренний ID** (`1771997851260`), **НЕ** `entity_id`. `.storage/trace.saved_traces` хранит только сохранённые вручную через UI; живые — в памяти. 🧰 `~/tmp-t610/trace_dump.py` (Mac; на t610 python3 НЕТ). **Читать трассировку ДО перебора гипотез** | -| 34 | 🔴 **Фиксированный `delay` ненадёжен для «дождаться, пока датчик отпустит»** | Момент проверки плавает: замер `call → свет on` при `delay: 5` дал **6.1 с** (≈1.1 с накладных на диспетчеризацию). Окно отпускания радара тоже плавает (замерено 3.19–3.59 с). Таймер `2 → 3 → 5 с` в ветке `lux` душевой **не сработал ни разу**. Использовать `wait_for_trigger` по событию: `- {platform: state, entity_id: ..., to: "off"}` + `timeout` + `continue_on_timeout: true` + `{{ wait.trigger is none }}`. Разбор: [[family/how-to/ha-automations]] §4.5 | -| 35 | 🔴 **`wait_for_trigger` с взаимоисключающими условиями — свет не включится никогда** | Ошибка проектирования: `wait_for_trigger` на `from: on, to: off` + следующее условие `presence == on` требует presence одновременно `off` и `on`. Проверять выполнимость цепочки **до** заливки. ⚠️ Семантика: `wait.completed` = `true` при срабатывании, `false` при таймауте → «дождаться ухода» = `{{ wait.trigger is none }}`, «дождаться возврата» = `{{ wait.completed }}` | -| 36 | 🔴 **`logbook` без поля `message` не различает ветки `choose`** | Версию по `presence` и по `lux` не отличить. Читать с `message`: `jq -r '.[] \| "\(.when) \(.state) \(.message // "")"'` → видно `triggered by state of ` (какая именно ветка). Диагностика ложных включений: сопоставить три ряда `history/period` (`presence` + `illuminance` + `light`) с логбуком обеих автоматизаций в одном окне | -| 37 | ⚠️ **`condition: device / is_occupied` может не отражать свежий `state`** | При проверке присутствия сразу после сброса радара device-условие давало «занято», тогда как `condition: state` на той же сущности корректно читала `off`. Для проверок по свежему состоянию использовать `condition: state`, не device-условие | -| 38 | 🔴 **`wait_for_trigger` + `wait.completed` в `choose` требует `mode: restart`** | В сценарии «ждать возврат присутствия N секунд, иначе гасить»: `wait_for_trigger` с `timeout` + `continue_on_timeout: true`, затем `condition: template` с `value_template: "{{ wait.completed }}"` внутри `choose.sequence`. При `mode: single` повторный триггер игнорируется и ожидание НЕ перезапускается → старый таймер догасит свет, хотя человек вернулся. Ставить `mode: restart` | -| 39 | 🔴 **Задержка проверки присутствия обязана БЫТЬ БОЛЬШЕ окна отпускания радара** | Симптом: свет включается, хотя человек уже вышел. Замерено при `fading_time = 2 с`: окно «выключил свет → `presence` → `off`» = **3.2 с**. Задержка 3 с проверялась в `13:58:13.54`, presence сбросился в `13:58:13.73` — **на 0.19 с позже** → проверка прошла, свет включился. ⛔ **5 с тоже не помогли — таймер отброшен, см. п.34 и §4.5.** Подробно: [[family/how-to/ha-automations]] §4.3 | +| 36 | 🔴 **Фиксированный `delay` ненадёжен для «дождаться, пока датчик отпустит»** | Момент проверки плавает: замер `call → свет on` при `delay: 5` дал **6.1 с** (≈1.1 с накладных на диспетчеризацию). Окно отпускания радара тоже плавает (замерено 3.19–3.59 с). Таймер `2 → 3 → 5 с` в ветке `lux` душевой **не сработал ни разу**. Использовать `wait_for_trigger` по событию: `- {platform: state, entity_id: ..., to: "off"}` + `timeout` + `continue_on_timeout: true` + `{{ wait.trigger is none }}`. Разбор: [[family/how-to/ha-automations]] §4.5 | +| 37 | 🔴 **`wait_for_trigger` с взаимоисключающими условиями — свет не включится никогда** | Ошибка проектирования: `wait_for_trigger` на `from: on, to: off` + следующее условие `presence == on` требует presence одновременно `off` и `on`. Проверять выполнимость цепочки **до** заливки. ⚠️ Семантика: `wait.completed` = `true` при срабатывании, `false` при таймауте → «дождаться ухода» = `{{ wait.trigger is none }}`, «дождаться возврата» = `{{ wait.completed }}` | +| 38 | 🔴 **`logbook` без поля `message` не различает ветки `choose`** | Версию по `presence` и по `lux` не отличить. Читать с `message`: `jq -r '.[] \| "\(.when) \(.state) \(.message // "")"'` → видно `triggered by state of ` (какая именно ветка). Диагностика ложных включений: сопоставить три ряда `history/period` (`presence` + `illuminance` + `light`) с логбуком обеих автоматизаций в одном окне | +| 39 | ⚠️ **`condition: device / is_occupied` может не отражать свежий `state`** | При проверке присутствия сразу после сброса радара device-условие давало «занято», тогда как `condition: state` на той же сущности корректно читала `off`. Для проверок по свежему состоянию использовать `condition: state`, не device-условие | +| 40 | 🔴 **`wait_for_trigger` + `wait.completed` в `choose` требует `mode: restart`** | В сценарии «ждать возврат присутствия N секунд, иначе гасить»: `wait_for_trigger` с `timeout` + `continue_on_timeout: true`, затем `condition: template` с `value_template: "{{ wait.completed }}"` внутри `choose.sequence`. При `mode: single` повторный триггер игнорируется и ожидание НЕ перезапускается → старый таймер догасит свет, хотя человек вернулся. Ставить `mode: restart` | +| 41 | 🔴 **Задержка проверки присутствия обязана БЫТЬ БОЛЬШЕ окна отпускания радара** | Симптом: свет включается, хотя человек уже вышел. Замерено при `fading_time = 2 с`: окно «выключил свет → `presence` → `off`» = **3.2 с**. Задержка 3 с проверялась в `13:58:13.54`, presence сбросился в `13:58:13.73` — **на 0.19 с позже** → проверка прошла, свет включился. ⛔ **5 с тоже не помогли — таймер отброшен, см. п.36 и §4.5.** Подробно: [[family/how-to/ha-automations]] §4.3 | --- @@ -500,6 +500,68 @@ ssh root@192.168.2.176 'bash /tmp/fix_plan_stairs.sh /config/.storage/lovelace.h --- +## 13.5. 📡 Диагностика HA через трассировки и параметры радара (2026-09-16, вечер) + +### 13.5.1. 🔴 Трассировки автоматизаций — ТОЛЬКО WebSocket + +**Единственный способ увидеть реальные значения условий в момент выполнения.** Три итерации подбора задержек в душевой провалились именно потому, что трассировку не читали (разбор — [[family/how-to/ha-automations]] §4.4). + +| Что | Значение | +|---|---| +| REST `/api/trace/...` | **404** — не использовать | +| WS `trace/list`, `trace/get` | рабочие, домен `automation` | +| `item_id` | 🔴 **внутренний ID** (`1771997851260`), **НЕ** `entity_id` | +| `.storage/trace.saved_traces` | только сохранённые вручную через UI; живые — в памяти | + +🧰 Инструмент: `~/tmp-t610/trace_dump.py` (Mac, `python3` + `websocket-client`, токен из `/tmp/.hatok`). +🔴 **На t610 `python3` НЕТ** — скрипты выполнять с Mac. + +### 13.5.2. ⚠️ Радар `shower_2_presence_sensor` дрожит + +**Измерено:** присутствие выдаётся короткими сериями, включая `on` длительностью **1.8 с**, хотя человек находился в помещении. + +``` +14:11:17.97 on → 14:11:25.35 off (7.4 с) +14:11:33.92 on → 14:11:42.10 off (8.2 с) +14:11:43.90 on → 14:11:48.68 off (1.8 с) +14:11:55.86 on → 14:12:24.18 off (36.3 с) +``` + +**Причина — сниженный `fading_time`.** Радар отпускает присутствие через `fading_time` после последнего движения. При **2 с** любое замирание даёт `off`, следующее движение — `on`. Исходные **10 с** прощали неподвижность. + +**Параметры устройства `shower_2_presence_sensor`** (`_TZE204_qasjif9e`, TS0601, mmWave): + +| Сущность | Значение | Диапазон | Смысл | +|---|---|---|---| +| `number.*_detection_delay` | `0.1` | 1…10 | задержка **до** объявления «есть» | +| `number.*_fading_time` | `2.0` | 1…1500 (факт: ≥2) | удержание **после** ухода | +| `number.*_radar_sensitivity` | `7` | — | чувствительность | +| `number.*_minimum_range` | `0.6` | — | ближняя граница зоны, м | +| `number.*_maximum_range` | `2.85` | — | дальняя граница зоны, м | + +> 🔴 **`fading_time` не опускается ниже 2 с**, хотя HA показывает `min: 1` и ответ `number.set_value` возвращает `state: 1.0`. Проверено: `1.0` → `2.0`, `1.5` → `2.0`, `2.5` → принято. Прошивка молча игнорирует < 2 — **всегда читать обратно**. + +### 13.5.3. ✅ Проверка, что реле исправно + +**Реле `night_light_shower_2` (TS0001) удерживает состояние:** ручной `light.turn_on` → 27 опросов подряд с шагом 200 мс — стабильно `on`, сброса нет. + +→ Значит **подсекундные пары `on→off` (0.12–0.13 с) в истории идут от логики/команд, а не от поломки реле**. Проверять это первым, прежде чем чинить алгоритм. + +### 13.5.4. ⚠️ Как отличить внешний вызов от сценария + +**Правило:** изменение состояния сущности **без** соответствующей записи триггера автоматизации в `logbook` = **внешний вызов** (ручной `light.turn_on`, другая интеграция), а не сценарий. + +Сверять два ряда в одном окне: +```bash +# изменения цели +curl -s -H "$H" "$B/api/history/period/$T+00:00?filter_entity_id=light.x&minimal_response&no_attributes" +# триггеры автоматизации (поле message = какая ветка) +curl -s -H "$H" "$B/api/logbook/$T+00:00?entity=automation." +``` +Без этого легко «найти» баг автоматизации там, где был ручной тестовый вызов. + +--- + ## Связанные заметки - [[family/how-to/home-automation]] — топология, аддоны t610, первопричина RCU stall, Modbus