diff --git a/family/how-to/ha-automations.md b/family/how-to/ha-automations.md index 311de477..a7a39ba8 100644 --- a/family/how-to/ha-automations.md +++ b/family/how-to/ha-automations.md @@ -9,6 +9,8 @@ related: - "[[family/documents/home-automation-wishlist]]" --- +> **📌 Текущий статус (2026-09-15):** дефект «ночной свет душевой» — **порог исправлен** `8 → 6` (по решению Alex), применено через REST и подтверждено. **Открытый хвост:** у ВЫКЛ-автоматизации по-прежнему `conditions: []` — нет связи с основным освещением; при 2 lx свет может залипать. Ждём факта: залипнет или нет. + # ⚙️ HA — автоматизации (`automations.yaml`) > **Назначение документа:** разбор логики автоматизаций Home Assistant на t610, карта «устройство ↔ entity_id ↔ device_id», найденные дефекты. Карта железа/Modbus — [[family/how-to/home-automation]]. Хост/аддоны/доступ — [[family/plans/t610-home-automation]]. @@ -93,12 +95,12 @@ mode: single **Первопричина — асимметрия логики, а НЕ датчик:** 1. **Нет связи «основное освещение включено → ночной свет не нужен».** В ВЫКЛ-автоматизации `conditions: []` — она ничего не проверяет про основной свет. Гасит только по `not_occupied` или `above: 8`. -2. **Порог `8 lx` недостижим.** Факт-замер 2026-09-15: `illuminance` = **2 lx** при выключенном свете, но основное освещение не подняло значение выше 8 (у TS0601 `reportable_change: 5`, сенсор расположен в стороне от основного потока). Триггер `above: 8` **не срабатывает** → ВЫКЛ не запускается. +2. **Порог `8 lx` стоял ровно в центре дребезга датчика.** Факт-замер 2026-09-15: покой = **2 lx**, а при движении/свете значение металось **7 ↔ 12** (см. §3 «Обоснование цифрой»). Порог `8` попадал в мёртвую середину → ВКЛ и ВЫКЛ срабатывали по кругу. Триггер `above: 8` **срабатывал**, но нестабильно. 3. **`mode: single` + `occupied` держится** → человек в душевой, темно по показаниям → ночной свет горит поверх основного. **❌ Отвергнутые версии (не повторять):** - «датчик присутствия не видит порог / виноват датчик» — **неверно**: `binary_sensor..._presence` работает штатно (observed `on`/`off` в 04:49:15). -- «порог просто надо чуть поднять» — **частично**: порог лишь симптом; корень в отсутствии условия по основному свету. +- «порог просто надо чуть поднять» — **частично верно, и это и сделано**: порог `8` действительно лежал в центре дребезга (7↔12), поэтому его и сдвинули на `6`. Но **корень** — отсутствие условия по основному свету: порогом это не лечится (потолок датчика ~15 lx, он не отличает ночной свет от основного). **✅ Факт-замер (2026-09-15, 04:48–04:49 UTC):** @@ -110,11 +112,35 @@ mode: single | `number..._fading_time` | 10 с | | `number..._maximum_range` | 2.85 м | -### Предложенные правки (НЕ применены — ждут апрува Alex) +### ✅ Применённая правка (2026-09-15) — порог 8 → 6 -1. **Добавить в ВЫКЛ триггер/условие по основному освещению душевой** — гасить ночной свет, как только зажглось основное. ⚠️ **Блокер:** неизвестна сущность основного освещения верхней душевой (среди `light.*`/`switch.*` душевой найден только `night_light_shower_2`). Нужен ответ Alex. -2. Поднять порог `8 → 15–20 lx` **или** откалибровать `illuminance_calibration` радара (2 lx при внутреннем свете подозрительно мало). -3. `fading_time` = 10 с, `maximum_range` = **2.85 м** — проверить, покрывает ли зона всю душевую. +**Решение Alex (дословно): «ставь 6».** Применено через REST API и **подтверждено чтением конфига обратно**: + +| Автоматизация | Триггер | Условие | +|---|---|---| +| ВКЛ `1771997851260` | `illuminance below: 6` | `below: 6` + `is_occupied` | +| ВЫКЛ `1771997918348` | `illuminance above: 6` | — (по-прежнему пусто) | + +**📊 Обоснование цифрой (ключевой замер).** История `sensor.shower_2_presence_sensor_illuminance`: + +- **За 10 минут до правки (2026-09-15, 04:27–04:48 UTC):** `7 → 12 → 7 → 12 → 7 → 12 → 7` — метание **7 ↔ 12**. +- **2026-09-14 днём:** `15↔8`, `13↔8`, `5↔0` — тот же дребезг вокруг 8. +- **Рабочий диапазон датчика в этой точке — всего 0…15 lx.** Порог `8` стоял ровно в центре метания → ВКЛ/ВЫКЛ хлопали туда-сюда. + +**⚠️ Остаточный риск (предупреждён Alex, принят осознанно):** при **2 lx** (покой) ВЫКЛ ждёт `above: 6` и может не наступить → ночной свет залипнет. Гистерезис **сознательно не сделан** по прямому указанию Alex. +**Если залипнет — варианты (по возрастанию):** ① гистерезис `вкл below 4 / выкл above 10`; ② гасить ночной свет по факту включения основной лампы (**блокер: сущность основного освещения верхней душевой неизвестна** — среди `light.*`/`switch.*` душевой есть только `night_light_shower_2`); ③ калибровка `illuminance_calibration` радара. + +**Артефакты:** +- Скрипт-образец: `~/tmp-t610/fix_shower_light_threshold.sh` (читает конфиг → правит только `.below`/`.above` == 8 → POST → читает обратно). +- Бэкап файла: `~/tmp-t610/automations/automations.yaml.bak-20260915-105455`. + +**🔴 ПИТФОЛЛ (стоил одной пустой заливки):** REST `GET/POST /api/config/automation/config/` отдаёт и принимает поля **во МНОЖЕСТВЕННОМ числе — `triggers` / `conditions`** (в файле `automations.yaml` — `trigger`/`condition`). Правка по единственному числу через API **молча уходит в пустые пути**: `POST` возвращает `200 {"result":"ok"}`, но значения НЕ меняются. → **ВСЕГДА читать конфиг обратно и сверять фактические значения.** + +### Прочие наблюдения (не правки) + +- `fading_time` = 10 с, `maximum_range` = **2.85 м** — проверить, покрывает ли зона всю душевую. +- Калибровка `illuminance_calibration` радара: 2 lx при выключенном свете в закрытой душевой — правдоподобно, но потолок 15 lx подозрительно низок. +- **Луковичный вывод:** потолок датчика ~15 lx означает, что он **не отличает ночной свет от основного** — оба выше его шкалы. Поэтому порогом задача «гасить ночной при включении основного» **не решается в принципе**, нужен триггер по основной лампе (см. блокер выше). ## 4. Прочие содержательные автоматизации @@ -144,6 +170,17 @@ mode: single - **Секрет-маскировщик Hermes** подменяет `Bearer $(cat ...)` на `***` → собирать заголовок через `printf` в файл, затем `curl -H @/tmp/hdr.txt`. Рабочий `/tmp/.hatok` уже есть на Mac. - `ha apps logs ` обрезает вывод и отдаёт старый буфер → живой лог только через API. - Запросы к `http://192.168.2.176` (raw IP, plain HTTP, private network) **требуют апрува** в Hermes — предупреждать Alex заранее, не ретраить вслепую. +- **🔴 Форма полей через REST — МНОЖЕСТВЕННОЕ число:** `GET/POST /api/config/automation/config/` использует `triggers` / `conditions` (в файле — `trigger` / `condition`). Правка по единственному числу **молча уходит в пустые пути**: `POST` отдаёт `200 {"result":"ok"}`, значения НЕ меняются. **Всегда читать обратно и сверять.** +- **История значения (для доказательства дребезга) — эндпоинт истории:** + ``` + GET /api/history/period/?filter_entity_id=&minimal_response&no_attributes + ``` + Возвращает список списков; брать `.[0]`, печатать `last_changed` + `state`. Пример (последние 25 мин): + ``` + curl -s -H @/tmp/hdr.txt "http://192.168.2.176/api/history/period/$(date -u -v-25M '+%Y-%m-%dT%H:%M:%S')+00:00?filter_entity_id=sensor.shower_2_presence_sensor_illuminance&minimal_response&no_attributes" + ``` + Именно этим способом доказано метание 7↔12 вокруг порога 8. +- **Две сущности = одно реле:** `switch.night_light_shower_2` и `light.night_light_shower_2` — один и тот же физический реле (`switch_as_x`). Управлять надо той, к которой привязана автоматизация (`switch.`), иначе состояние «расходится» в UI. ## Связанные заметки diff --git a/family/how-to/nodered-ventilation.md b/family/how-to/nodered-ventilation.md index 494d22f3..7d82affa 100644 --- a/family/how-to/nodered-ventilation.md +++ b/family/how-to/nodered-ventilation.md @@ -152,21 +152,19 @@ Gate: current_state (manual override → block automation). ✅ **Все три комнаты (`bedroom`, `kids`, `dining`) публикуют данные в MQTT.** Датчик столовой (`slave 1`) был сломан багом сборки кадров в `modbus-bridge` — починен 2026-09-14 (см. [[family/plans/t610-home-automation]] §5-кватер-З). До фикса автоматика вентиляции по CO₂ работала без данных столовой. ⚠️ **`fan.fan_at2_1/2` (slave 10) — `unavailable`** (блок закомментирован в `configuration.yaml`) → исполнительный контур вентиляторов AT2 не работает. Задача по slave 10 Alex'ом не ставилась. -## 🔦 Ночной свет душевой 2 — пороги (правка 2026-09-15) +## 🔦 Ночной свет душевой 2 — ПЕРЕНЕСЕНО -**Сущности:** датчик освещённости `sensor.shower_2_presence_sensor_illuminance` (радар присутствия Tuya `ZY-M100-S_2` / `TS0601`, `ieee 0xa4c138c4a94a6a31`, устройство `shower_2_presence_sensor`); присутствие `binary_sensor.shower_2_presence_sensor_presence`; лампа `switch.night_light_shower_2` (`TS0001`, `ieee 0x84fd27fffed9e137`) + хелпер `light.night_light_shower_2` (switch_as_x, т.е. **две сущности на одно реле**). +> **Этот раздел переехал в [[family/how-to/ha-automations]] §3.** Документ `nodered-ventilation` — только про вентиляцию по CO₂. +> Кратко: порог освещённости ночного света душевой был **8 lx** и лежал ровно в центре дребезга датчика (**7 ↔ 12**, рабочий диапазон 0…15 lx) → свет мигал. **Правка 2026-09-15 по решению Alex: `below: 6` / `above: 6`**, применена через REST API, подтверждена чтением обратно. Полный разбор, замеры, питфоллы API и остаточный риск — в [[family/how-to/ha-automations]]. -**Автоматизации** (в HA по `id`): «Вкл. ночной свет душевая» `1771997851260`, «Выкл. ночной свет душевая» `1771997918348`. +**Сущности:** дублируются в [[family/how-to/ha-automations]] §2. Здесь не повторяем. -**❌ Причина мигания:** порог стоял **8 lx**, а реальный рабочий диапазон датчика в душевой — **0…15 lx**. Замеры 2026-09-14/15 показали метание **7 ↔ 12** (и 0↔5, 8↔13 в другие дни) — ровно вокруг 8. Отсюда дёрганье. +**Автоматизации:** `1771997851260` (вкл) / `1771997918348` (выкл) — разбор в [[family/how-to/ha-automations]] §3. -**✅ Поставлено (Alex: «ставь 6»):** `below: 6` (вкл) / `above: 6` (выкл). +**❌ Причина мигания и ✅ правка:** см. блок выше. Замеры и обоснование — в [[family/how-to/ha-automations]] §3. -⚠️ **Риск, о котором предупреждал:** при 2 lx (текущее состояние, покой) выключение ждёт `above: 6` и может не наступить → свет остаётся гореть. Гистерезис не сделан **осознанно** — по прямому указанию Alex. Если свет будет залипать — варианты: гистерезис `вкл below 4 / выкл above 10`, либо гасить ночной свет по факту включения основной лампы. +**🔴 ПИТФОЛЛ (нужен для любой правки автоматизаций):** REST `GET/POST /api/config/automation/config/` использует **`triggers`/`conditions`** (мн. ч.; в файле — `trigger`/`condition`). Правка по единственному числу **молча уходит в пустые пути**: POST → `200 {"result":"ok"}`, значения НЕ меняются. **Всегда читать обратно.** Подробнее — [[family/how-to/ha-automations]] §5. -**Питфолл (важно для будущих правок):** REST `GET/POST /api/config/automation/config/` отдаёт и принимает поля **во множественном числе — `triggers` / `conditions`** (в файле `automations.yaml` это `trigger`/`condition`). Правка по `trigger`/`condition` через API молча уходит в пустые пути, POST возвращает `200 {"result":"ok"}`, но значения НЕ меняются. **Всегда читать конфиг обратно и сверять значения.** - -**Рабочий скрипт:** `~/tmp-t610/fix_shower_light_threshold.sh` (читает конфиг → правит только `.below`/`.above` == 8 → POST → читает обратно). -Бэкап файла: `~/tmp-t610/automations/automations.yaml.bak-20260915-105455`. +**Артефакты:** скрипт `~/tmp-t610/fix_shower_light_threshold.sh`; бэкап `~/tmp-t610/automations/automations.yaml.bak-20260915-105455`. ---