diff --git a/family/how-to/ha-automations.md b/family/how-to/ha-automations.md index 23b8e195..94033fe1 100644 --- a/family/how-to/ha-automations.md +++ b/family/how-to/ha-automations.md @@ -2,15 +2,15 @@ > **Справочник логики автоматизаций** (`automations.yaml` на t610). Топология/команды/Modbus — [[family/how-to/home-automation]]. -> 🟢 **25 АВТОМАТИЗАЦИЙ — 24 `on`, 1 `off`** (`Ventilation automation on`, намеренно), `unavailable` = 0. Zigbee работает на ZHA. +> 🟢 **24 АВТОМАТИЗАЦИИ — 23 `on`, 1 `off`** (`Ventilation automation on`, намеренно), `unavailable` = 0. Zigbee работает на ZHA. > > 🔴 **ПАПКА ПРОЕКТА — `~/Automation/HA-ZONT-Modbus`** (git-репозиторий). Файл автоматизаций в проекте: `homeassistant/automations.yaml`. **НЕ** `~/tmp-t610/automations/` — это рабочая свалка скриптов, а не проект. Синхронизировать проект с HA: `scp root@192.168.2.176:/config/automations.yaml ~/Automation/HA-ZONT-Modbus/homeassistant/automations.yaml` → патч → заливка → **коммит в git**. > > ✅ **РАБОЧИЙ REST-ПУТЬ К HA НАЙДЕН (2026-09-16, поздний вечер): `https://mallexxx.duckdns.org`.** Отвечает `401` без токена, `200` с токеном. Это единственный подтверждённый транспорт. `192.168.2.176:8123` и `172.30.32.1:8123` — не нужны. > -> **Состав:** 12 контроля батарей (§5) + 2 циркуляция ГВС + 2 свет кабинета (§2.2, §3) + 2 подсветка лестницы + 2 ночной свет душевой (§4.1–§4.6.2) + 2 диммер спальни + 1 протечка котельная + 1 вентиляция + **1 греющий кабель ввода воды (§7)**. +> **Состав:** 12 контроля батарей (§5) + 2 циркуляция ГВС + 2 свет кабинета (§2.2, §3) + 2 подсветка лестницы + **1 ночной свет душевой (§4.7)** + 2 диммер спальни + 1 протечка котельная + 1 вентиляция + **1 греющий кабель ввода воды (§7)**. > -> ✅ **ПРИМЕНЕНО 2026-09-16 (поздний вечер): объединение двух автоматизаций душевой в ОДНУ по таблице истинности — см. §4.7.** Один сценарий `1771997851260` (`mode: restart`, 4 триггера, 4 ветки `choose`), вторая `1771997918348` **отключена** (`off`). Залито через REST с внешнего адреса, прочитано обратно, закоммичено. Дрожание радара (§4.6.2) лечится структурно: `mode: restart` гарантирует **ровно одно выполнение** — новый триггер убивает предыдущее ожидание. Отдельный выбор по `fading_time` снят с повестки. +> ✅ **ПРИМЕНЕНО, ПРОВЕРЕНО («Работает!») И ЗАВЕРШЕНО 2026-09-16 (поздний вечер): объединение двух автоматизаций душевой в ОДНУ по таблице истинности — см. §4.7.** Один сценарий `1771997851260` (`mode: restart`, 4 триггера, 4 ветки `choose`). **Старая автоматизация `1771997918348` СНЕСЕНА ПОЛНОСТЬЮ** (не «отключена») — тело удалено через `DELETE /api/config/automation/config/1771997918348` (`200 ok`, затем `GET` → `404`), блок убран из файла проекта (коммит `d019477`). Дрожание радара (§4.6.2) лечится структурно: `mode: restart` гарантирует **ровно одно выполнение** — новый триггер убивает предыдущее ожидание. Отдельный выбор по `fading_time` снят с повестки. > > 🔴 **ТРАНСПОРТ К HA НА t610 (§4.7):** `192.168.2.176:8123` **НЕ работает** — это ssh-аддон `core_ssh`, не HA. ✅ **Рабочий путь — `https://mallexxx.duckdns.org`** (см. строку выше и §4.7 «Транспорт»). `172.30.32.1:8123` (Docker-сеть супервизора) отвечает, но практического применения не потребовалось. На t610 **нет `python3`**, только `jq`. Заголовок `Authorization: Bearer ` **нельзя** собирать через `$(cat file)` в ssh-строке/here-doc — рвётся фильтром секретов; читать токен через `read -r T < file` (bash) или `fh.readline().strip()` (python на Mac). > @@ -28,11 +28,14 @@ > - 🔴 **Трассировки автоматизаций — ТОЛЬКО 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`, значения НЕ меняются. **Всегда читать обратно.** -> - 🔴 **АДРЕС HA на t610 — `172.30.32.1:8123`, НЕ `192.168.2.176:8123`.** `192.168.2.176` — ssh-аддон `core_ssh`, порт `8123` там закрыт. HA живёт в Docker-сети супервизора (`getent hosts homeassistant`). На t610 **нет `python3`** — только `jq`. Заголовок с токеном **нельзя** собирать через `$(cat tokenfile)` внутри ssh-строки — рвётся фильтром секретов; читать токен `read -r T < file`. Подробно — §4.7 «Транспорт». -> - 🔴 **Не склеивать `automations.yaml` вручную через `awk`.** Трижды в сессии 2026-09-16 потерялась автоматизация из-за отсутствия ведущего `- ` в подставляемом блоке. Перед записью — обязательная сверка `comm -23` по списку `^- id:`. Лучше: REST POST изнутри HA, UI, или python на Mac + `scp`. +> - 🔴 **РАБОЧИЙ АДРЕС HA — `https://mallexxx.duckdns.org`, НЕ `192.168.2.176:8123`.** `192.168.2.176` — ssh-аддон `core_ssh`, порт `8123` там закрыт (`ConnectionRefused`). `172.30.32.1:8123` (Docker-сеть супервизора, `getent hosts homeassistant`) отвечает, но на практике не понадобился. На t610 **нет `python3`** — только `jq`. Заголовок с токеном **нельзя** собирать через `$(cat tokenfile)` внутри ssh-строки — рвётся фильтром секретов; читать токен `read -r T < file`, в python — `fh.readline().strip()`. Подробно — §4.7 «Транспорт». +> - 🔴 **Пустые `triggers: []` НЕ выключают автоматизацию** — после `reload` она остаётся `on`. Нужен явный `POST /api/services/automation/turn_off` с `entity_id`. **Полное удаление — `DELETE /api/config/automation/config/`** (`200 ok`, проверка `GET` → `404`) + `automation/reload` (§4.7). +> - 🔴 **Пайплайн правки (требование Alex):** `scp` файла с HA в проект → **коммит ДО** → патч `patch`-инструментом → заливка REST → чтение обратно → **живая проверка Alex'ом** → **коммит ПОСЛЕ**. Не коммитить результат до проверки (§4.7). +> - 🔴 **Не склеивать `automations.yaml` вручную через `awk`.** Трижды в сессии 2026-09-16 потерялась автоматизация из-за отсутствия ведущего `- ` в подставляемом блоке. **Замена — `patch`-инструмент по якорям** (сработал с первого раза). Перед записью — обязательная сверка `comm -23` по списку `^- id:` + `yaml.safe_load`. > - ⚠️ **Кнопка спальни** шлёт `remote_button_short_press` только после `zha/devices/reconfigure`. > -> **Бэкапы сессии 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/`. +> **Бэкапы сессии 2026-09-16 (все — в `/config` на t610):** `.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`, `.bak-shower-merge-20260916-214012` (эталон перед объединением), `.bak-before-restore-20260916-214949`. +> 🔴 **Бэкапы в папке проекта НЕ делать — там git.** Alex: «Нахуя бэкап в папке проекта у тебя гит есть». В проекте `*.bak` покрыт `.gitignore`; страховка боевого HA — только файлы в `/config` на t610. > 📄 Рецепт пересборки после Z2M→ZHA и питфоллы — [[family/tech/zigbee-t610-z2m-i-zha]]. > > 🔴 **ПИТФОЛЛЫ, найденные при починке:** @@ -45,10 +48,12 @@ ## 1. Где живёт - **Файл:** `/config/automations.yaml` в HA Core на t610. -- **Всего:** **25 автоматизаций — 24 `on`, 1 `off`** (`Ventilation automation on`, намеренно), **`unavailable` = 0**. Файл = 780 строк. -- **Бэкапы перед правками:** `automations.yaml.bak-cable3-` (кабель, 2026-09-16), `.bak-preids-*`, `.bak-gard-*`; локально — `~/tmp-t610/bak-cable-20260915-234837/automations.yaml`. +- **Всего:** **24 автоматизации — 23 `on`, 1 `off`** (`Ventilation automation on`, намеренно), **`unavailable` = 0**. +- **Бэкапы перед правками:** `automations.yaml.bak-cable3-` (кабель, 2026-09-16), `.bak-preids-*`, `.bak-gard-*`, `.bak-shower-merge-20260916-214012` (эталон 25 автоматизаций перед объединением душевой). - **Удалены 4 «призрака»** (записи в реестре без тела): `svetlo_vykl_osveshchenie_lestnitsy`, `temno_vkl_podsvetku_lestnitsy`, `datchik_osveshchennosti_lestnitsa_batareia`, `light_switch_bed_batareia`. Тела не было (`config/automation/config/` → 404) — лестничные сценарии **пересозданы заново** с теми же id. -- **Локальная копия:** `~/tmp-t610/automations/automations.yaml`; после пересборки — `~/tmp-t610/automations-new.yaml`, `~/tmp-t610/automations-fixed.yaml`. +- 🔴 **ПРОЕКТ (git, источник правок):** `~/Automation/HA-ZONT-Modbus` → `homeassistant/automations.yaml`. + **Свалка скриптов (НЕ проект):** `~/tmp-t610/` — там живут рабочие скрипты, бэкапы, `ha_duck.sh`, `trace_dump.py`. + **Синхронизация:** `scp root@192.168.2.176:/config/automations.yaml ~/Automation/HA-ZONT-Modbus/homeassistant/automations.yaml` - **Читать живьём через API** (не по памяти): ```bash B="https://mallexxx.duckdns.org" @@ -130,7 +135,7 @@ action: | `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` | **Душевая: ночной свет** (объединённый) | `mode: restart`, 4 триггера: `P` (occupied) / `Poff` (not_occupied) / `Llow` (illuminance below 6) / `Lhi` (above 6). 4 ветки `choose`, действие ВНУТРИ ветки: `P`+presence on+lux<6 → вкл; `Llow`+presence on+lux<6 → delay 3 s → вкл; `Poff`+lux<6+свет вкл → delay 10 s → выкл; `Lhi`+lux>6+свет вкл → выкл. ✅ §4.7 | -| `1771997918348` | **ОТКЛЮЧЕНО: Душевая выключение** | ⛔ **Отключена** (`state: off`, `triggers: []`). Логика перенесена в `1771997851260`. ✅ §4.7 | +| `1771997918348` | ~~Выкл. ночной свет душевая~~ | ⛔ **СНЕСЕНА 2026-09-16** — тело удалено из HA (`DELETE` → 200, `GET` → 404), блок убран из файла проекта (коммит `d019477`). Логика перенесена в `1771997851260`. Всего автоматизаций стало **24**. ✅ §4.7 | | `1773451257968` | Протечка котельная | `moist` → `notify.notify` | | `8800000000000`…`8800000000011` | **Батарея: 12 шт.** | см. §6 | | `heating_cable_ctl_0001` | **Греющий кабель: управление** | `time_pattern /15` + `numeric_state ZONT below −8` + отвал датчика → `choose` 5 веток на `switch.heating_cable_plug`. См. §7 | @@ -617,15 +622,20 @@ mode: single ## 4.7. ✅ ОБЪЕДИНЕНИЕ двух автоматизаций душевой в ОДНУ (2026-09-16, вечер) — ПРИМЕНЕНО И ПРОВЕРЕНО -> **Статус: ✅ ПРИМЕНЕНО И ПРОВЕРЕНО ALEX («Работает!»), 2026-09-16 поздний вечер.** Один сценарий `1771997851260` (`mode: restart`, 4 триггера, 4 ветки `choose`), вторая `1771997918348` отключена. Залито через REST `https://mallexxx.duckdns.org`, прочитано обратно, закоммичено. +> **Статус: ✅ ПРИМЕНЕНО, ПРОВЕРЕНО («Работает!») И ЗАВЕРШЕНО, 2026-09-16 поздний вечер.** Один сценарий `1771997851260` (`mode: restart`, 4 триггера, 4 ветки `choose`). **Старая автоматизация `1771997918348` СНЕСЕНА ПОЛНОСТЬЮ** (не «отключена»): тело удалено из HA через `DELETE /api/config/automation/config/1771997918348` (`200 ok`, затем `GET` → `404`), блок убран из файла проекта. Залито через REST `https://mallexxx.duckdns.org`, закоммичено. +> +> **Итог HA после сноса: 24 автоматизации — 23 `on`, 1 `off`** (вентиляция, намеренно), `unavailable` = 0. > > **Коммиты проекта (`~/Automation/HA-ZONT-Modbus`):** > - `2eaa704` — «Sync automations.yaml from t610 prod (14 → 25 automations)» — коммит **ДО** работ. > - `0f5924f` — «Merge shower automations: 2 scenarios -> 1 (mode restart, 4-branch truth table)» — коммит **ПОСЛЕ проверки** Alex. +> - `d019477` — «Remove old shower off-automation (1771997918348)» — снос старой автоматизации. > > 🔴 **ПОРЯДОК РАБОТЫ, ПОДТВЕРЖДЁННЫЙ ALEX (соблюдать буквально):** синхронизация файла → **коммит ДО** → патч → заливка через API → чтение обратно → **проверка Alex'ом вживую** → **коммит ПОСЛЕ**. Alex: «Я тебе сказал сделать один комит ДО. ВТОРОЙ-ПОСЛЕ ПРОВЕРКИ». Преждевременный второй коммит пришлось откатывать (`git reset --soft`). **Не коммитить результат до его проверки.** > -> 🔴 **ОТКЛЮЧЕНИЕ ВТОРОЙ АВТОМАТИЗАЦИИ — ДВА ШАГА, не один.** Пустые `triggers: []` в конфиге НЕ выключают автоматизацию: после `reload` она по-прежнему `on`. Нужен явный `POST /api/services/automation/turn_off` с `entity_id`. Проверено: без него вторая висела `on`, после — `off`. +> 🔴 **УДАЛЕНИЕ АВТОМАТИЗАЦИИ — через `DELETE /api/config/automation/config/`**, затем `automation/reload`. Проверено: `DELETE` → `200 {"result":"ok"}`, повторный `GET` → `404`. Только после этого блок убирается из файла проекта. +> +> ⚠️ **Бэкап-файлы в папке проекта НЕ нужны — там git.** Alex: «Нахуя бэкап в папке проекта у тебя гит есть». Бэкапы делать **только в `/config` на t610** (страховка боевого HA). Правило `*.bak` в `.gitignore` репозитория уже покрывает такие файлы. **Проблема, которую решаем.** Две автоматизации (`1771997851260` ВКЛ + `1771997918348` ВЫКЛ) реагируют на **одни и те же** события presence/lux и тянут свет в противоположные стороны. Одно движение радара = оба сценария подряд. HA **не имеет** взаимной блокировки между автоматизациями: `mode` действует только внутри своей автоматизации (у ВКЛ `single`, у ВЫКЛ `restart`) — запуск одной не останавливает другую. Это и есть источник гонок. @@ -729,35 +739,39 @@ actions: 7. **Вторая автоматизация выключена явно:** `POST /api/services/automation/turn_off` (`entity_id: automation.vykl_nochnoi_svet_dushevaia`) → `state: off`. После `reload` она оставалась `on` — пустых триггеров недостаточно. 8. **✅ ПРОВЕРЕНО ALEX ВЖИВУЮ: «Работает!»** 9. **Коммит после проверки: `0f5924f`** — «Merge shower automations: 2 scenarios -> 1 (mode restart, 4-branch truth table)» (+ `.gitignore` для бэкапов проекта). +10. **По команде Alex «Сноси» старая автоматизация удалена ПОЛНОСТЬЮ:** `DELETE /api/config/automation/config/1771997918348` → `200 {"result":"ok"}`; повторный `GET` → **404**; блок убран из файла проекта; `reload`. +11. **Коммит `d019477`** — «Remove old shower off-automation (1771997918348)». **Итог HA: 24 автоматизации — 23 `on`, 1 `off`**, `unavailable` = 0. +12. **Убраны два бэкап-файла из папки проекта** (в git вся история — Alex: «Нахуя бэкап в папке проекта у тебя гит есть»). **Исправлен `.gitignore`:** была склеенная строка `project_home.pdfhomeassistant/automations.yaml.bak-*` (ошибка записи) → `project_home.pdf`. Отдельное правило для `.bak-*` удалено — `*.bak` уже покрыто. ⚠️ **Порядок коммитов пришлось исправлять:** я закоммитил результат до проверки Alex, пришлось откатывать (`git reset --soft 2eaa704`) и коммитить заново после подтверждения. **Урок: коммит результата — строго ПОСЛЕ живой проверки Alex.** **Скрипты:** `~/tmp-t610/ha_duck.sh` (чтение через внешний адрес), скрипты заливки писались на Mac (python3 `urllib`, читать токен через `readline()` — `pathlib.read_text()` рвётся фильтром секретов). -### 🚧 Исторические питфоллы транспорта (первая попытка, провалена) +### 🚧 Историческая заметка: что НЕ работает (не тратить время) > 🔴 **`192.168.2.176:8123` НЕ работает.** `192.168.2.176` — это **SSH-аддон `core_ssh`** на t610, а не HA. Порты на нём: `22` (ssh), `8099` (ttyd/веб-терминал), `45073`. Порт `8123` закрыт — `ConnectionRefused`. -> ✅ **HA живёт на `172.30.32.1:8123`** внутри Docker-сети супервизора (`getent hosts homeassistant` → `172.30.32.1`, `supervisor` → `172.30.32.2`). Проверено: `curl` на `172.30.32.1:8123` отвечает. -> ✅ **API через супервизор:** `http://supervisor/core/api/` доступен изнутри аддона (отвечает `401` без токена — эндпоинт существует). -> 🔴 **`python3` на t610 НЕТ.** Есть только `/usr/bin/jq`. Любая обработка — `jq`, `awk`, `sed` в шелле, либо сборка файла **на Mac** и `scp`. -> ⛔ **КРИТИЧНЫЙ ПИТФОЛЛ ШЕЛЛА: строку `Authorization: Bearer ` нельзя генерировать через `$(cat tokenfile)` или `$TOKEN` внутри ssh-команды / here-doc / `printf`** — фильтр секретов и парсер рвут конструкцию, в файл попадает `Bearer ***` или строка обрывается, curl получает битый заголовок и молча не пишет файл (`-o` → `No such file or directory`). Рабочий обход — **читать токен через `read -r T < file` и собирать заголовок `printf`-ом на целевой машине**, либо использовать `hermes`-путь через `ha_ws.py`. Классические `TOKEN=$(cat …)` + `-H "Authorization: Bearer $TOKEN"` в одной ssh-строке — **не работают**. -> 🔴 **SSH-туннель к HA:** `ssh -f -N -L 127.0.0.1:18124:127.0.0.1:8123 root@192.168.2.176` — туннель поднимается, но **соединение ресетится** (`ConnectionResetError`), потому что на удалённой стороне порт `8123` не слушается. Туннель к `172.30.32.1:8123` — рабочий вариант, если понадобится. -> 🔴 **Склейка `automations.yaml` через `awk` — ПРОВАЛЕНО трижды.** Границы блоков задаются по `grep -n "^- id:"`; потеря автоматизации происходит из-за отсутствия ведущего `- ` в подставляемом блоке (`id:` вместо `- id:`), из-за чего `grep -c "^- id:"` не считает его. **Обязательная проверка перед записью:** сравнить `comm -23 <(grep "^- id:" bak | sort) <(grep "^- id:" new | sort)` — пустой вывод = ничего не потеряно. Только после этого `cp`. -> 💡 **Вывод на будущее:** ручная склейка YAML ненадёжна. Предпочтительный путь — REST `POST /api/config/automation/config/` из HA-аддона **изнутри** на `172.30.32.1`, либо правка через UI HA, либо python на Mac + `scp` готового файла. +> ✅ **Рабочий транспорт — `https://mallexxx.duckdns.org`** (см. §4.7 «Транспорт»). `172.30.32.1:8123` внутри Docker-сети супервизора отвечает, но на практике не понадобился. +> 🔴 **`python3` на t610 НЕТ.** Есть только `/usr/bin/jq`. Любая обработка — `jq`, `awk`, `sed` в шелле, либо скрипты **на Mac** и `scp`. +> ⛔ **КРИТИЧНЫЙ ПИТФОЛЛ ШЕЛЛА: строку `Authorization: Bearer ` нельзя генерировать через `$(cat tokenfile)` или `$TOKEN` внутри ssh-команды / here-doc / `printf`** — фильтр секретов и парсер рвут конструкцию, в файл попадает `Bearer ***` или строка обрывается, curl получает битый заголовок и молча не пишет файл (`-o` → `No such file or directory`). Рабочий обход — **писать скрипт файлом на Mac**, читать токен `read -r TOK < file` (bash) или `fh.readline().strip()` (python), запускать `bash script.sh`. +> 🔴 **SSH-туннель к HA:** `ssh -f -N -L 127.0.0.1:18124:127.0.0.1:8123 root@192.168.2.176` — туннель поднимается, но **соединение ресетится** (`ConnectionResetError`), потому что на удалённой стороне порт `8123` не слушается. Не тратить время — внешний адрес решает всё. +> 🔴 **Склейка `automations.yaml` через `awk` — ПРОВАЛЕНО трижды.** Границы блоков задаются по `grep -n "^- id:"`; потеря автоматизации происходит из-за отсутствия ведущего `- ` в подставляемом блоке (`id:` вместо `- id:`), из-за чего `grep -c "^- id:"` не считает его. **Замена — `patch`-инструмент по якорям** (сработал с первого раза). При любом способе перед записью обязательна сверка: `comm -23 <(grep "^- id:" bak | sort) <(grep "^- id:" new | sort)` — пустой вывод = ничего не потеряно, плюс `yaml.safe_load`. -### 🗓 Итог сессии 2026-09-16 (поздний вечер) +### 🗓 Итог сессии 2026-09-16 (поздний вечер) — ✅ ЗАДАЧА ЗАКРЫТА + +**Итог:** объединение сценариев душевой **применено в HA и проверено Alex'ом вживую («Работает!»)**. Порядок и подробности — в начале §4.7. Коммиты проекта: `2eaa704` (синхронизация, ДО) и `0f5924f` (результат, ПОСЛЕ проверки). **Сделано:** -1. Прочитан живой конфиг обеих автоматизаций душевой через ssh-аддон (файл `/config/automations.yaml`, строки 96–140 и 141–176). -2. Дизайн §4.7 дожат до финала с двумя правками Alex (убраны `wait_for_trigger` и проверки `presence`). -3. Бэкап `automations.yaml.bak-shower-merge-20260916-214012` (25 автоматизаций) — **сделан**. -4. Финальный конфиг собран: `~/tmp-t610/shower_merged_final.yaml` (91 строка, с ведущим `- id:`). Черновик `shower_merged.yaml` (без дефиса) — брак. +1. Прочитан живой конфиг обеих автоматизаций душевой (строки 96–140 и 141–176 `/config/automations.yaml`). +2. Дизайн §4.7 дожат до финала с правками Alex (убраны `wait_for_trigger` и проверки `presence`). +3. Бэкап `automations.yaml.bak-shower-merge-20260916-214012` (25 автоматизаций). +4. Файл проекта `~/Automation/HA-ZONT-Modbus/homeassistant/automations.yaml` синхронизирован с HA (14 → 25 автоматизаций) и отпатчен. +5. Заливка через `POST /api/config/automation/config/` → чтение обратно → `reload` → `turn_off` второй → проверка 25/24 `on`/1 `off`/`unavailable` = 0. +6. **Живая проверка Alex'а.** Коммит результата. -**НЕ сделано (применение провалено):** -1. REST-путь к HA не найден: `192.168.2.176:8123` закрыт, `172.30.32.1:8123` доступен но не задействован, ssh-туннель ресетится. -2. Склейка файла через `awk` трижды дала потерю автоматизации (`1771997851260`). -3. **По команде Alex выполнен откат:** `/config/automations.yaml` восстановлен из `bak-shower-merge-20260916-214012`. Предыдущее состояние сохранено в `.bak-before-restore-20260916-214949`. Хэши совпадают: `652f921c9086981b55d994a74d5650f7`. -4. **ХА НЕ перезагружал автоматизации** после отката — HA держит в памяти версию, прочитанную при старте. Требуется `POST /api/services/automation/reload`, чтобы HA перечитал файл. Алекс об этом уведомлён, команды не дал. +**Что узнали по ходу (сохранено как питфоллы):** +1. **Ошибочная попытка №1:** транспорт `192.168.2.176:8123` не работал, `awk`-склейка теряла автоматизацию. По команде Alex выполнен откат из `bak-shower-merge-20260916-214012`; состояние перед откатом — `.bak-before-restore-20260916-214949`. Хэши совпали: `652f921c9086981b55d994a74d5650f7`. +2. **Пустые `triggers: []` НЕ выключают автоматизацию** — после `reload` она остаётся `on`, нужен явный `POST /api/services/automation/turn_off`. +3. **Коммит результата — только после живой проверки Alex'а.** Преждевременный коммит откатывался через `git reset --soft`. **Бэкапы этой части сессии:** - `/config/automations.yaml.bak-shower-merge-20260916-214012` — эталон, 25 автоматизаций (состояние **до** всех вечерних попыток). diff --git a/family/plans/t610-zigbee-ids-battery-freshsensors-modbus.md b/family/plans/t610-zigbee-ids-battery-freshsensors-modbus.md index 2a00ff32..f08aa206 100644 --- a/family/plans/t610-zigbee-ids-battery-freshsensors-modbus.md +++ b/family/plans/t610-zigbee-ids-battery-freshsensors-modbus.md @@ -1,7 +1,7 @@ --- title: "План и результат: читаемые ID Zigbee, алерты батарей, виртуальные Modbus-датчики" created: '2026-09-15' -updated: 2026-09-16 (поздний вечер, ФИНАЛ: объединение сценариев душевой применено в HA и проверено Alex'ом — «Работает!». Коммиты проекта `2eaa704` (до) и `0f5924f` (после проверки). Старая автоматизация `1771997918348` отключена, не удалена — как откат) +updated: 2026-09-16 (поздний вечер, ФИНАЛ: объединение сценариев душевой применено в HA и проверено Alex'ом — «Работает!». Коммиты проекта `2eaa704` (до), `0f5924f` (после проверки), `d019477` (снос старой). Старая автоматизация `1771997918348` УДАЛЕНА ПОЛНОСТЬЮ через `DELETE /api/config/automation/config/` — итог 24 автоматизации) type: plan namespace: family 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. @@ -476,7 +476,7 @@ python3 ~/tmp-t610/trace_dump.py 14:02:33 **Задача Alex:** убрать гонку двух автоматизаций (`1771997851260` ВКЛ + `1771997918348` ВЫКЛ), реагирующих на одни события presence/lux. HA **не имеет** взаимной блокировки между автоматизациями — `mode` работает только внутри своей. -**Решение (согласовано Alex, дожато до финала):** одна автоматизация `1771997851260`, **4 триггера** (`P`/`Poff`/`Llow`/`Lhi`), **4 ветки `choose`**, `mode: restart`. Вторая (`1771997918348`) — отключена (пустые `triggers`/`actions`), не удалена. +**Решение (согласовано Alex, дожато до финала):** одна автоматизация `1771997851260`, **4 триггера** (`P`/`Poff`/`Llow`/`Lhi`), **4 ветки `choose`**, `mode: restart`. Вторая (`1771997918348`) — **УДАЛЕНА ПОЛНОСТЬЮ** 2026-09-16 по команде Alex «Сноси». **Правки Alex поверх первой редакции — не откатывать:** 1. `wait_for_trigger` из ветки 3 **убран** («Триггер должен перезапустить сценарий») — `mode: restart` уже убивает текущий запуск при новом триггере. @@ -498,10 +498,12 @@ python3 ~/tmp-t610/trace_dump.py 14:02:33 5. 🔴 **Вторую пришлось выключать явно** — `POST /api/services/automation/turn_off` (`entity_id: automation.vykl_nochnoi_svet_dushevaia`). **Пустых `triggers: []` НЕДОСТАТОЧНО:** после `reload` автоматизация остаётся `on`. Проверено: без `turn_off` висела `on`. 6. **✅ ПРОВЕРКА ALEX'ОМ ВЖИВУЮ: «Работает!»** 7. **Коммит `0f5924f`** «Merge shower automations: 2 scenarios -> 1 (mode restart, 4-branch truth table)» (+ `.gitignore` для бэкапов проекта). +8. **Снос старой автоматизации (Alex: «Сноси»):** `DELETE /api/config/automation/config/1771997918348` → `200 {"result":"ok"}`, повторный `GET` → **404**; блок убран из файла проекта (816 строк, 24 `^- id:`); `reload`. **Коммит `d019477`** «Remove old shower off-automation». +9. **Бэкап-файлы убраны из папки проекта** — в git вся история; Alex: «Нахуя бэкап в папке проекта у тебя гит есть». **Исправлен `.gitignore`:** склеенная строка `project_home.pdfhomeassistant/automations.yaml.bak-*` → `project_home.pdf` (отдельное правило `.bak-*` снято, `*.bak` уже покрыто). -**Состояние:** HA — `1771997851260` `on` / `1771997918348` `off`, 25 автоматизаций, `unavailable` = 0. Старая автоматизация **отключена, не удалена** (откат доступен правкой; история — в git). +**Состояние (ФИНАЛ):** HA — **24 автоматизации: 23 `on`, 1 `off`**, `unavailable` = 0. Работает только `1771997851260` (`on`). Старая `1771997918348` **удалена** — тело в HA отсутствует (`GET` → 404), блок убран из проекта; вернуть можно только из git-истории. **Инструменты:** `~/tmp-t610/ha_duck.sh` (рабочее чтение); скрипты заливки писались на Mac (python3 `urllib`), токен читать `fh.readline().strip()` — `pathlib.read_text()` рвётся фильтром секретов. -**Бэкапы:** `~/Automation/HA-ZONT-Modbus/homeassistant/automations.yaml.bak-20260916-205509`; на t610 — `.bak-shower-merge-20260916-214012` (эталон 25 автоматизаций), `.bak-before-restore-20260916-214949`. +**Бэкапы (только в `/config` на t610):** `.bak-shower-merge-20260916-214012` (эталон 25 автоматизаций), `.bak-before-restore-20260916-214949`. **В папке проекта бэкапы НЕ хранить — там git.** **Детали:** [[family/how-to/ha-automations]] §4.7.