245 lines
22 KiB
Markdown
245 lines
22 KiB
Markdown
# ⚙️ HA — автоматизации
|
||
|
||
> **Справочник логики автоматизаций** (`automations.yaml` на t610). Топология/команды/Modbus — [[family/how-to/home-automation]].
|
||
|
||
> 🟢 **АКТУАЛЬНО 2026-09-15 (поздний вечер): 24 АВТОМАТИЗАЦИИ — 23 `on`, 1 `off` (`Ventilation automation on`, намеренно), `unavailable` = 0.** Zigbee работает на ZHA.
|
||
>
|
||
> 📌 **Сверка счёта:** в §1 ниже упоминается «26» — это счёт **включая 2 удалённые батарейные**, которые ещё числились сиротами в реестре. После чистки реестра фактически **24**. Брать 24.
|
||
>
|
||
> **➕ Добавлено в этот вечер: 12 автоматизаций контроля батарей** (id `8800000000000`…`8800000000011`, все `on`). Порог **20 %**, выдержка **2 ч**, двойной канал: `persistent_notification` + push `notify.mobile_app_sm_s931b`; при возврате заряда уведомление гасится (`notification_id: bat_<slug>`). Детали — §5.
|
||
> ⛔ **Удалены 2 прежние батарейные** (`1773451323415`, `1773459663218`) — были с порогом 10 и без push. Их осиротевшие записи в реестре вычищены (питфолл §5.1).
|
||
> 🔄 **Переименованы** ссылки после единообразия ID: `light.night_light_shower_2` → `light.dushevaia_night_light`, `sensor.tz3000_akqdg6g7_ts0201_batareia` → `sensor.kabinet_temperature_battery` → `sensor.garderobnaia_temperature_battery` (датчик перенесён в Гардеробную).
|
||
> 🔴 **`entity_id` автоматизаций HA перегенерировал по alias** — искать автоматизацию по `attributes.id`, не по `entity_id`. Пример: `automation.datchik_protechki_kotelnaia_batareia` → `automation.batareia_kotelnaia_datchik_protechki`.
|
||
> 📄 Полный отчёт о работах: [[family/plans/t610-zigbee-ids-battery-freshsensors-modbus]].
|
||
>
|
||
> Переезд Zigbee Z2M → ZHA выполнен. Автоматизации были сломаны не по `entity_id`, а глубже — они ссылались на `device_id` + внутренний `entity_id`-UUID, а устройства Z2M удалены. **Пересобраны заново** на ZHA-шные `device_id` + актуальные `entity_id`.
|
||
>
|
||
> **Что доделано после первичной пересборки:**
|
||
> - ✅ **4 «призрака»-автоматизации УДАЛЕНЫ** из `core.entity_registry` (тела не существовало: `GET /api/config/automation/config/<id>` → 404). Файл: 12 блоков vs 16 сущностей.
|
||
> - ✅ **2 сценария подсветки лестницы ПЕРЕСОЗДАНЫ** на `sensor.light_sensor_stairs_illuminance` (`light.light_stairs_left`/`_right`), оба `on`.
|
||
> - ✅ **`Toggle Dimmer bed` / `Dimmer bed cycle` — залиты и `on`**: триггер от кнопки, действия на `light.bed_dimmer` (было — реле сауны).
|
||
> - ⚠️ **Кнопка спальни:** события `remote_button_short_press` идут **только после `zha/devices/reconfigure`**. Дамп кластеров ДО reconfigure вводит в заблуждение.
|
||
>
|
||
> **Итог на 2026-09-15 (поздний вечер): 26 автоматизаций, `unavailable` = 0.**
|
||
>
|
||
> **Бэкап:** `/config/automations.yaml.bak-dimmer-fix` (последняя правка) + `.bak-before-autofix-20260915-212636` + `.bak-zha-20260915-211613` ✅
|
||
> **Рецепт пересборки + питфоллы — [[family/tech/zigbee-t610-z2m-i-zha]].**
|
||
>
|
||
> 🔴 **ПИТФОЛЛЫ, найденные при починке:**
|
||
> 1. **`device`-триггер батареи — тип `battery_level`, НЕ `battery`.** Иначе `Automation ... failed to setup triggers and has been disabled`.
|
||
> 2. **`binary_sensor` «battery_low» в ZHA нет** — только numeric `sensor.*_battery`, порог через `below: 10`.
|
||
> 3. **Домен `entity_id` не меняется переименованием:** `switch.office_table_light_switch_l1` → ZHA-имя `light.tz3000_5gey1ohx_ts0002_osveshchenie`. Автоматизации переписаны на `light.*`.
|
||
> 4. **`reload` — `POST /api/services/automation/reload`** с long-lived JWT, порт 80 (`http://172.30.32.1/api/`). Супервизорский токен → 401.
|
||
|
||
## 1. Где живёт
|
||
|
||
- **Файл:** `/config/automations.yaml` в HA Core на t610.
|
||
- **Всего:** **24 автоматизации — 23 `on`, 1 `off`** (`Ventilation automation on`, намеренно, `last_triggered` 12 марта), **`unavailable` = 0**. Файл = 228 строк.
|
||
- **Бэкапы перед правками 2026-09-15 (поздний вечер):** `/config/automations.yaml.bak-preids-20260915-223427`, `/config/automations.yaml.bak-gard-20260915-225404` (перед переносом датчика в Гардеробную); рабочая копия — `~/tmp-t610/autfix-20260915-223427/automations.yaml` (плюс `.pre-bat` — до добавления батарейных).
|
||
- **Удалены 4 «призрака»** (записи в реестре без тела): `svetlo_vykl_osveshchenie_lestnitsy`, `temno_vkl_podsvetku_lestnitsy`, `datchik_osveshchennosti_lestnitsa_batareia`, `light_switch_bed_batareia`. Тела не было (`config/automation/config/<id>` → 404) — лестничные сценарии **пересозданы заново** с теми же id.
|
||
- **Локальная копия:** `~/tmp-t610/automations/automations.yaml`; после пересборки — `~/tmp-t610/automations-new.yaml`, `~/tmp-t610/automations-fixed.yaml`.
|
||
- **Читать живьём через API** (не по памяти):
|
||
```bash
|
||
B="https://mallexxx.duckdns.org"
|
||
curl -s -H @/tmp/h1 "$B/api/config/automation/config/<ID>"
|
||
```
|
||
|
||
### 🔴 ПИТФОЛЛ (стоил пустой заливки)
|
||
|
||
REST `GET/POST /api/config/automation/config/<id>` использует поля **во множественном числе — `triggers` / `conditions` / `actions`** (в файле `automations.yaml` — `trigger`/`condition`/`action`).
|
||
Правка по единственному числу **молча уходит в пустые пути**: POST → `200 {"result":"ok"}`, значения НЕ меняются.
|
||
→ **ВСЕГДА читать конфиг обратно и сверять фактические значения.**
|
||
|
||
**Бэкап перед правкой:** `cp ~/tmp-t610/automations/automations.yaml{,.bak-$(date +%Y%m%d-%H%M%S)}`
|
||
|
||
---
|
||
|
||
## 2. Карта автоматизаций
|
||
|
||
| id | alias | Логика |
|
||
|---|---|---|
|
||
| `1768585827761` | Выключить циркуляцию ГВС | `time 23:00` → turn_off |
|
||
| `1768585922970` | Включить циркуляцию ГВС | `time 09:30` → turn_on |
|
||
| `1770404069135` | Ventilation automation on | `time 05:00` → `fan.turn_on fan.automation` *(off)* |
|
||
| `5735cb9f855e462dbdbdf680d0d6a66f` | **office_pass_switch_table** | кнопка L1 → toggle `light.smart_light_office_left` ⚠️ |
|
||
| `45b96f6f38f6488ba70266fa5da665f5` | **office_pass_switch_main** | кнопка L2 → toggle `light.smart_light_office_right` ⚠️ |
|
||
| `1771466806839` | Темно: вкл. подсветку лестницы | `illuminance below: 20` → `light.light_stairs_left`+`_right` turn_on |
|
||
| `1771466955010` | Светло: выкл. подсветку лестницы | `illuminance above: 60` → `light.light_stairs_left`+`_right` turn_off |
|
||
| `1771683420621` | Toggle Dimmer bed | кнопка `remote_button_short_press` → `light.toggle light.bed_dimmer` |
|
||
| `1771683677259` | Dimmer bed cycle | кнопка `long_press` → `light.turn_on` brightness 50 % на `light.bed_dimmer` |
|
||
| `1771997851260` | **Вкл. ночной свет душевая** | присутствие + темно → `light.dushevaia_night_light` on |
|
||
| `1771997918348` | **Выкл. ночной свет душевая** | нет присутствия / светло → off |
|
||
| `1773451257968` | Протечка котельная | `moist` → `notify.notify` |
|
||
| `8800000000000`…`8800000000011` | **Батарея: 12 шт.** | см. §6 |
|
||
|
||
> 🔄 **Переименовано 2026-09-15:** ссылки на `light.night_light_shower_2` → `light.dushevaia_night_light` (id `1771997851260`, `1771997918348`).
|
||
> ⛔ **Удалены из карты:** `1773451323415` «Датчик протечки котельная батарея» и `1773459663218` «Zigbee T sensor батарея» — заменены 12 единообразными (§6). Тела удалены, осиротевшие записи реестра вычищены.
|
||
|
||
> ⚠️ **Два сценария подсветки лестницы (id `1771466806839` / `1771466955010`) удалены как «призраки» и ПЕРЕСОЗДАНЫ** с теми же id на `sensor.light_sensor_stairs_illuminance`. Пороги 20/60.
|
||
> 🗑 **Удалённые «призраки», которых в файле НЕТ:** `automation.svetlo_vykl_osveshchenie_lestnitsy`, `automation.temno_vkl_podsvetku_lestnitsy`, `automation.datchik_osveshchennosti_lestnitsa_batareia`, `automation.light_switch_bed_batareia`.
|
||
|
||
> **Образец правильной защиты от дребезга:** «Темно/Светло подсветка лестницы» использует **гистерезис** (`below: 20` / `above: 60`). Брать как эталон.
|
||
|
||
---
|
||
|
||
## 3. 🔴 ДЕФЕКТ: свет кабинета мигает при перезагрузке HA
|
||
|
||
**Симптом:** при каждом рестарте HA свет в кабинете мигает.
|
||
|
||
**Первопричина:** триггеры `office_pass_switch_table` / `office_pass_switch_main` используют `platform: state` **без `to`/`from`** → срабатывают на **любую** смену состояния сущности кнопки.
|
||
|
||
При старте HA кнопки проходят `unavailable → unknown → on` — каждый переход дёргает `light.toggle`. Подтверждено историей: `switch.office_table_light_switch_l1` сменил состояние 3 раза в течение 5 минут в момент рестартов HA (`05:16:36 → unavailable`, `05:16:40 → on`, `05:18:39 → unavailable`, `05:18:46 → unknown`, `05:19:20 → on`).
|
||
|
||
**Текущий конфиг (сырой):**
|
||
```json
|
||
{
|
||
"alias": "office_pass_switch_table",
|
||
"mode": "restart",
|
||
"trigger": [{"platform": "state", "entity_id": ["switch.office_table_light_switch_l1"]}],
|
||
"action": [{"service": "light.toggle", "target": {"entity_id": "light.smart_light_office_left"}}]
|
||
}
|
||
```
|
||
|
||
**Направление фикса:** привязать триггер к конкретному состоянию (`to:`) ИЛИ заменить на триггер по событию нажатия. Требует определить фактическое поведение кнопки при физическом нажатии (сейчас кнопки в `on` — это состояние после старта, не нажатие).
|
||
|
||
**Статус:** ⚠️ **НЕ ИСПРАВЛЕНО.** Требует замера поведения кнопки при нажатии.
|
||
|
||
---
|
||
|
||
## 4. Ночной свет душевой 2
|
||
|
||
**Сущности** (device_id `4095e7c3b47b9dc9640cfb8c3aeff022` = радар, `4d6e55505ff7dbad13d2674cdcb18d5a` = лампа):
|
||
|
||
- `sensor.shower_2_presence_sensor_illuminance` — освещённость, lx
|
||
- `binary_sensor.shower_2_presence_sensor_presence` — занятость
|
||
- `light.dushevaia_night_light` — **само реле** (его дёргает автоматизация; бывш. `light.night_light_shower_2`)
|
||
|
||
> 📌 **2026-09-15:** хелпер `switch.night_light_shower_2` (`switch_as_x`) снесён при переезде на ZHA. Осталась одна сущность — `light.dushevaia_night_light`. Автоматизации ссылаются именно на неё.
|
||
|
||
**Автоматизации:**
|
||
|
||
| | id | Триггер | Условие |
|
||
|---|---|---|---|
|
||
| ВКЛ | `1771997851260` | `illuminance below: 6` + `occupied` | `below: 6` + `is_occupied` |
|
||
| ВЫКЛ | `1771997918348` | `not_occupied` + `illuminance above: 6` | ⚠️ **`conditions: []`** — пусто |
|
||
|
||
**История правки (2026-09-15):** порог `8 → 6`. Порог `8` лежал ровно в центре дребезга датчика (**7 ↔ 12**), рабочий диапазон датчика всего **0…15 lx** → ВКЛ/ВЫКЛ хлопали по кругу.
|
||
|
||
**⚠️ Остаточный риск (принят Alex):** при **2 lx** (покой) ВЫКЛ ждёт `above: 6` и может не наступить → свет залипнет. Гистерезис сознательно не сделан.
|
||
**Если залипнет — варианты:** ① гистерезис `вкл below 4 / выкл above 10`; ② гасить по факту включения основной лампы (**блокер: сущность основного освещения верхней душевой неизвестна**); ③ калибровка `illuminance_calibration` радара.
|
||
|
||
**Параметры радара:** `fading_time` = 10 с, `maximum_range` = 2.85 м — проверять, покрывает ли зона всю душевую.
|
||
|
||
---
|
||
|
||
## 5. 🔋 Контроль батарей — 12 автоматизаций (2026-09-15)
|
||
|
||
**Единый шаблон**, id `8800000000000`…`8800000000011`:
|
||
|
||
```yaml
|
||
- id: '8800000000000'
|
||
alias: 'Батарея: <место>'
|
||
description: 'Контроль заряда Zigbee-датчика. Порог 20%, выдержка 2ч.'
|
||
triggers:
|
||
- trigger: numeric_state
|
||
entity_id: sensor.<device>_battery
|
||
below: 20
|
||
for: '02:00:00'
|
||
id: low
|
||
- trigger: numeric_state
|
||
entity_id: sensor.<device>_battery
|
||
above: 20
|
||
id: ok
|
||
conditions: []
|
||
actions:
|
||
- choose:
|
||
- conditions: [{condition: trigger, id: low}]
|
||
sequence:
|
||
- action: persistent_notification.create
|
||
data:
|
||
title: '🔋 Батарея разряжена'
|
||
message: '<место> — заряд {{ states(''sensor.<device>_battery'') }}%. Замените батарейку.'
|
||
notification_id: bat_<slug>
|
||
- action: notify.mobile_app_sm_s931b
|
||
data:
|
||
title: '🔋 Батарея разряжена'
|
||
message: '<место> — заряд {{ states(''sensor.<device>_battery'') }}%. Замените батарейку.'
|
||
- conditions: [{condition: trigger, id: ok}]
|
||
sequence:
|
||
- action: persistent_notification.dismiss
|
||
data: {notification_id: bat_<slug>}
|
||
mode: single
|
||
```
|
||
|
||
| id | Место | Сущность заряда |
|
||
|---|---|---|
|
||
| `8800000000000` | Туалет 1 этаж (тёплый пол) | `sensor.toilet_1_floor_temperature_battery` |
|
||
| `8800000000001` | Лестница (освещённость) | `sensor.light_sensor_stairs_battery` |
|
||
| `8800000000002` | Душевая (тёплый пол) | `sensor.dushevaia_floor_temperature_battery` |
|
||
| `8800000000003` | Котельная (протечка) | `sensor.boiler_water_leak_battery` |
|
||
| `8800000000004` | Гардеробная (температура) — датчик перенесён из Кабинета 2026-09-15 | `sensor.garderobnaia_temperature_battery` |
|
||
| `8800000000005` | Гостиная (тёплый пол) | `sensor.living_room_floor_temperature_battery` |
|
||
| `8800000000006` | Серая (тёплый пол) | `sensor.severnaia_floor_temperature_battery` |
|
||
| `8800000000007` | Кабинет (тёплый пол) | `sensor.kabinet_floor_temperature_battery` |
|
||
| `8800000000008` | Кухня (тёплый пол) | `sensor.kitchen_floor_temperature_battery` |
|
||
| `8800000000009` | Ванная (тёплый пол) | `sensor.vannaia_floor_temperature_battery` |
|
||
| `8800000000010` | Прихожая (тёплый пол) | `sensor.prikhozhaia_floor_temperature_battery` |
|
||
| `8800000000011` | Спальня (кнопка) | `sensor.wireless_light_switch_bed_battery` |
|
||
|
||
### 5.1. 🔴 Питфоллы
|
||
|
||
1. **Выдержка `for: '02:00:00'` обязательна.** Батарейные TS0201 под нагрузкой дают кратковременные просадки — без выдержки прилетают ложные алерты.
|
||
2. **Двойной канал.** `persistent_notification` = видно в UI; `notify.mobile_app_sm_s931b` = push на телефон. Alex: «Видимо persistent с пушом на тел».
|
||
3. **Второй триггер `ok` (`above: 20`) гасит уведомление** через `notification_id` — иначе алерт висит вечно. Для этого у `persistent_notification.create` обязателен `notification_id: bat_<slug>`.
|
||
4. 🔴 **Сирота-автоматизация: `unavailable` при чистом YAML.** Тело удалено из `automations.yaml`, запись в реестре осталась. Удаление:
|
||
```python
|
||
# Если config/entity_registry/remove падает с id_reuse:
|
||
# "Identifier values have to increase"
|
||
{"type":"config/entity_registry/update","entity_id": E, "disabled_by": "user"} # сначала
|
||
{"type":"config/entity_registry/remove","entity_id": E} # потом
|
||
```
|
||
Реальный случай: после удаления тел `1773451323415` / `1773459663218` обе сущности остались `unavailable`.
|
||
5. ⚠️ **`sensor.wireless_light_switch_bed_battery` = `unknown`** — кнопка спальни спит. Автоматизация создана, но триггера не будет, пока датчик не проснётся (лечится нажатием кнопки).
|
||
6. ⚠️ **Проверять имена сущностей после переименований:** в ZHA домен бывает `_batareia`, но `trigger: battery_level` (не `battery`).
|
||
7. 🔴 **`id_reuse: Identifier values have to increase` при переименовании сущности** (проверено 2026-09-15: 6 из 7 упало, хотя целевые `entity_id` свободны). Это внутренний счётчик реестра, **не поломка**. Обход — промежуточное имя:
|
||
```python
|
||
{"type":"config/entity_registry/update","entity_id": old, "new_entity_id": tmp} # dom.tmp_xxx
|
||
{"type":"config/entity_registry/update","entity_id": tmp, "new_entity_id": new}
|
||
# при провале 2-го шага — откат: tmp → old
|
||
```
|
||
Общий принцип: **любая операция реестра, падающая с `id_reuse`, лечится промежуточным состоянием** (для сирот-автоматизаций — `disabled_by: user`, см. питфолл 4).
|
||
8. 🔴 **HA перегенерирует `entity_id` автоматизаций по alias при `reload`.** Проверять/искать по `attributes.id`, не по `entity_id`. Пример: `automation.datchik_protechki_kotelnaia_batareia` → `automation.batareia_kotelnaia_datchik_protechki`.
|
||
|
||
**Скрипты:** `~/tmp-t610/add_battery_autos.py` (генератор), `~/tmp-t610/rm_orphans.py`, `rm_orphan2.py`, `rm_orphan3.py`, `gard_fix.py` (правка ссылок при переносе датчика), `fix_aut_entid.py` (правка `entity_id` автоматизации).
|
||
|
||
> ⚠️ **ОТКРЫТО (на 2026-09-15):** Alex сообщил, что HA ругается на «**Office temperature sensor battery** — нет уникального id, устройство недоступно». **Проверено: призрака в бэкенде НЕТ** (нет в `/api/states`, нет в реестре из 572 записей, MQTT-сущностей без `unique_id` — 0, config entries все `loaded`). Вероятный источник — UI-кэш или дашборд-карточка. **Нужно уточнить у Alex экран** (Настройки → Устройства → MQTT / дашборд / Developer Tools) и вычистить прицельно.
|
||
|
||
> 📄 Полный отчёт о работах: [[family/plans/t610-zigbee-ids-battery-freshsensors-modbus]]
|
||
|
||
---
|
||
|
||
## 6. Диагностика
|
||
|
||
```bash
|
||
# История значения (доказательство дребезга)
|
||
T=$(date -u -v-3H '+%Y-%m-%dT%H:%M:%S')
|
||
curl -s -H @/tmp/h1 "$B/api/history/period/$T+00:00?filter_entity_id=<entity>&minimal_response&no_attributes" \
|
||
| jq -r '.[0][] | "\(.last_changed) -> \(.state)"'
|
||
|
||
# Состояния сущностей устройства (через шаблон)
|
||
curl -s -X POST -H @/tmp/h1 -H "Content-Type: application/json" \
|
||
-d '{"template":"{% set dev = device_id(\"sensor.x\") %}{% for e in device_entities(dev) %}{{ e }} = {{ states(e) }}\n{% endfor %}"}' \
|
||
"$B/api/template"
|
||
```
|
||
|
||
**Артефакты:** `~/tmp-t610/fix_shower_light_threshold.sh` (образец правки порога), `~/tmp-t610/ha_ws.py` (WS-реестры).
|
||
**Бэкап:** `~/tmp-t610/automations/automations.yaml.bak-20260915-105455`.
|
||
|
||
---
|
||
|
||
## Связанные
|
||
|
||
- [[family/how-to/home-automation]] — единый справочник: топология, железо, Zigbee, Modbus, команды, сценарии, питфоллы
|
||
- [[family/documents/home-automation-wishlist]] — роадмап идей и приоритетов
|
||
- [[family/how-to/vault-sync-pipeline]] — правки в vault не доедут до телефона без прогона sync-петли
|