diff --git a/family/how-to/ha-automations.md b/family/how-to/ha-automations.md index eeaee32e..87a0c6f4 100644 --- a/family/how-to/ha-automations.md +++ b/family/how-to/ha-automations.md @@ -2,7 +2,12 @@ > **Справочник логики автоматизаций** (`automations.yaml` на t610). Топология/команды/Modbus — [[family/how-to/home-automation]]. -> 🟢 **АКТУАЛЬНО 2026-09-15: 14 АВТОМАТИЗАЦИЙ — 13 `on`, 1 `off` (`Ventilation automation on`, намеренно), `unavailable` = 0.** Zigbee работает на ZHA. +> 🟢 **АКТУАЛЬНО 2026-09-15 (поздний вечер): 26 АВТОМАТИЗАЦИЙ — 25 `on`, 1 `off` (`Ventilation automation on`, намеренно), `unavailable` = 0.** Zigbee работает на ZHA. +> +> **➕ Добавлено в этот вечер: 12 автоматизаций контроля батарей** (id `8800000000000`…`8800000000011`, все `on`). Порог **20 %**, выдержка **2 ч**, двойной канал: `persistent_notification` + push `notify.mobile_app_sm_s931b`; при возврате заряда уведомление гасится (`notification_id: bat_`). Детали — §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`. +> 📄 Полный отчёт о работах: [[family/plans/t610-zigbee-ids-battery-freshsensors-modbus]]. > > Переезд Zigbee Z2M → ZHA выполнен. Автоматизации были сломаны не по `entity_id`, а глубже — они ссылались на `device_id` + внутренний `entity_id`-UUID, а устройства Z2M удалены. **Пересобраны заново** на ZHA-шные `device_id` + актуальные `entity_id`. > @@ -12,7 +17,7 @@ > - ✅ **`Toggle Dimmer bed` / `Dimmer bed cycle` — залиты и `on`**: триггер от кнопки, действия на `light.bed_dimmer` (было — реле сауны). > - ⚠️ **Кнопка спальни:** события `remote_button_short_press` идут **только после `zha/devices/reconfigure`**. Дамп кластеров ДО reconfigure вводит в заблуждение. > -> **Итог: 14 автоматизаций, `unavailable` = 0.** +> **Итог на 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]].** @@ -26,7 +31,8 @@ ## 1. Где живёт - **Файл:** `/config/automations.yaml` в HA Core на t610. -- **Всего:** **14 автоматизаций — 13 `on`, 1 `off`** (`Ventilation automation on`, намеренно, `last_triggered` 12 марта), **`unavailable` = 0**. Файл = 189 строк. +- **Всего:** **26 автоматизаций — 25 `on`, 1 `off`** (`Ventilation automation on`, намеренно, `last_triggered` 12 марта), **`unavailable` = 0**. Файл = 228 строк. +- **Бэкапы перед правками 2026-09-15 (поздний вечер):** `/config/automations.yaml.bak-preids-20260915-223427`; рабочая копия — `~/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/` → 404) — лестничные сценарии **пересозданы заново** с теми же id. - **Локальная копия:** `~/tmp-t610/automations/automations.yaml`; после пересборки — `~/tmp-t610/automations-new.yaml`, `~/tmp-t610/automations-fixed.yaml`. - **Читать живьём через API** (не по памяти): @@ -58,11 +64,13 @@ REST `GET/POST /api/config/automation/config/` использует поля | `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` | **Вкл. ночной свет душевая** | присутствие + темно → `switch.night_light_shower_2` on | +| `1771997851260` | **Вкл. ночной свет душевая** | присутствие + темно → `light.dushevaia_night_light` on | | `1771997918348` | **Выкл. ночной свет душевая** | нет присутствия / светло → off | | `1773451257968` | Протечка котельная | `moist` → `notify.notify` | -| `1773451323415` | Датчик протечки котельная батарея | `bat_low` → notify | -| `1773459663218` | Zigbee T sensor батарея | `battery_level below 10` → 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`. @@ -101,10 +109,9 @@ REST `GET/POST /api/config/automation/config/` использует поля - `sensor.shower_2_presence_sensor_illuminance` — освещённость, lx - `binary_sensor.shower_2_presence_sensor_presence` — занятость -- `switch.night_light_shower_2` — **само реле** (его дёргает автоматизация) -- `light.night_light_shower_2` — хелпер `switch_as_x` поверх того же реле +- `light.dushevaia_night_light` — **само реле** (его дёргает автоматизация; бывш. `light.night_light_shower_2`) -> ⚠️ **Две сущности = одно реле.** Управлять надо `switch.` — той, к которой привязана автоматика, иначе состояние «расходится» в UI. +> 📌 **2026-09-15:** хелпер `switch.night_light_shower_2` (`switch_as_x`) снесён при переезде на ZHA. Осталась одна сущность — `light.dushevaia_night_light`. Автоматизации ссылаются именно на неё. **Автоматизации:** @@ -122,7 +129,83 @@ REST `GET/POST /api/config/automation/config/` использует поля --- -## 5. Диагностика +## 5. 🔋 Контроль батарей — 12 автоматизаций (2026-09-15) + +**Единый шаблон**, id `8800000000000`…`8800000000011`: + +```yaml +- id: '8800000000000' + alias: 'Батарея: <место>' + description: 'Контроль заряда Zigbee-датчика. Порог 20%, выдержка 2ч.' + triggers: + - trigger: numeric_state + entity_id: sensor._battery + below: 20 + for: '02:00:00' + id: low + - trigger: numeric_state + entity_id: sensor._battery + above: 20 + id: ok + conditions: [] + actions: + - choose: + - conditions: [{condition: trigger, id: low}] + sequence: + - action: persistent_notification.create + data: + title: '🔋 Батарея разряжена' + message: '<место> — заряд {{ states(''sensor._battery'') }}%. Замените батарейку.' + notification_id: bat_ + - action: notify.mobile_app_sm_s931b + data: + title: '🔋 Батарея разряжена' + message: '<место> — заряд {{ states(''sensor._battery'') }}%. Замените батарейку.' + - conditions: [{condition: trigger, id: ok}] + sequence: + - action: persistent_notification.dismiss + data: {notification_id: bat_} + 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` | Кабинет (температура) | `sensor.kabinet_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_`. +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`). + +**Скрипты:** `~/tmp-t610/add_battery_autos.py` (генератор), `~/tmp-t610/rm_orphans.py`, `rm_orphan2.py`, `rm_orphan3.py`. + +> 📄 Полный отчёт о работах: [[family/plans/t610-zigbee-ids-battery-freshsensors-modbus]] + +--- + +## 6. Диагностика ```bash # История значения (доказательство дребезга) diff --git a/family/plans/t610-zigbee-ids-battery-freshsensors-modbus.md b/family/plans/t610-zigbee-ids-battery-freshsensors-modbus.md index 72b3fdcc..6b5d2522 100644 --- a/family/plans/t610-zigbee-ids-battery-freshsensors-modbus.md +++ b/family/plans/t610-zigbee-ids-battery-freshsensors-modbus.md @@ -1,5 +1,5 @@ --- -title: "План: читаемые ID Zigbee, алерты батарей, виртуальные Modbus-датчики" +title: "План и результат: читаемые ID Zigbee, алерты батарей, виртуальные Modbus-датчики" created: '2026-09-15' updated: '2026-09-15' type: plan @@ -17,55 +17,39 @@ related: - '[[family/how-to/ha-automations]]' --- -# План: читаемые ID, алерты батарей, виртуальные Modbus-датчики +# План и результат: читаемые ID, алерты батарей, виртуальные Modbus-датчики > Задача от Alex (2026-09-15): 1) убедиться, что у **всех** Zigbee-устройств читаемые ID; 2) каждому **батарейному** — оповещение о низком заряде; 3) каждый **температурный** Zigbee-датчик прописать как виртуальное устройство Modbus в bridge; 4) обновить доку. +> +> ✅ **Всё выполнено в тот же вечер.** Ниже — план И фактический результат. -## 0. Что установлено фактами (снимок 2026-09-15) +--- -### 0.1. Новые устройства (8 всего, +1 был в доке) -ZHA: **24 записи** (23 устройства + координатор). Было 17. +## 0. Исходная точка (снимок до работ) -| # | Устройство (name_by_user) | IEEE | Модель | Зона | Батарея | -|---|---|---|---|---|---| -| 1 | `Темп теплый пол гостиная` | `a4c13827ea585609` | TS0201 | living_room | ✅ | -| 2 | `Температура серая` | `a4c1382ac15720dd` | TS0201 | severnaia | ✅ | -| 3 | `Темп теплый пол кабинет` | `a4c1382dac5e10e2` | TS0201 | kabinet | ✅ | -| 4 | `Темп теплый пол кухня` | `a4c13837021f5298` | TS0201 | kitchen | ✅ | -| 5 | `Темп теплый пол ванная` | `a4c13867875ee7d3` | TS0201 | vannaia | ✅ | -| 6 | `Темп теплый пол прихожая` | `a4c138cde6eed013` | TS0201 | prikhozhaia | ✅ | -| 7 | `Темп теплый пол душевая` | `a4c13865e226312d` | TS0201 | dushevaia | ✅ (был ранее) | -| 8 | `shower_2_presence_sensor` | `a4c138c4a94a6a31` | TS0601 | dushevaia | ❌ mains | +Пришло **+7 новых TS0201** (датчики тёплых полов). ZHA: 24 записи (23 устройства + координатор), было 17. -Все 12 TS0201 — **батарейные EndDevice**, сущность `Батарея` есть у каждого. - -### 0.2. 🔴 Дефекты ID, найденные при проверке - -| # | Дефект | Пример | Оценка | +| IEEE | Исходное `name_by_user` | Модель | Зона | |---|---|---|---| -| D1 | **Имя устройства по-русски** (HA транслитерирует) | `Темп теплый пол гостиная` → `sensor.temp_teplyi_pol_gostinaia_temperatura` | 🔴 громоздко, ломает консистентность | -| D2 | **Перепутан префикс: `tualet_` при зоне `prikhozhaia`** | `sensor.tualet_temp_teplyi_pol_prikhozhaia_temperatura` | 🔴 прямая ошибка в имени | -| D3 | **Дубли `_2` / `_3` у LQI/RSSI** (остатки миграции) | `sensor.tz3000_gjnozsaz_ts011f_lqi_2`, `_3` | 🟡 косметика, `disabled_by=integration` | -| D4 | `sauna` — **зона `tualet`**, хотя это реле | `switch.sauna` в зоне ТУАЛЕТ | 🔴 неверная зона | -| D5 | `select`-сущности `sauna` названы `bed_dimmer_*` | `select.bed_dimmer_power_on_behavior` под устройством `sauna` | 🟡 ошибка выбора при переименовании | +| `a4c13827ea585609` | `Темп теплый пол гостиная` | TS0201 | living_room | +| `a4c1382ac15720dd` | `Температура серая` | TS0201 | severnaia | +| `a4c1382dac5e10e2` | `Темп теплый пол кабинет` | TS0201 | kabinet | +| `a4c13837021f5298` | `Темп теплый пол кухня` | TS0201 | kitchen | +| `a4c13867875ee7d3` | `Темп теплый пол ванная` | TS0201 | vannaia | +| `a4c138cde6eed013` | `Темп теплый пол прихожая` | TS0201 | prikhozhaia | +| `a4c13865e226312d` | `Темп теплый пол душевая` | TS0201 | dushevaia | -Остальные 16 устройств (реле, свет, кнопки, диммер) — ID читаемые ✅. +### 0.1. 🔴 Дефекты ID, найденные при проверке -### 0.3. Батарейные устройства и их сущности (7 шт.) +| # | Дефект | Пример | Итог | +|---|---|---|---| +| D1 | **Имя устройства по-русски** (HA транслитерирует) | `Темп теплый пол гостиная` → `sensor.temp_teplyi_pol_gostinaia_temperatura` | ✅ исправлено | +| D2 | **Перепутан префикс: `tualet_` при зоне `prikhozhaia`** | `sensor.tualet_temp_teplyi_pol_prikhozhaia_temperatura` | ✅ исправлено | +| D3 | **Дубли `_2` / `_3` у LQI/RSSI** (остатки миграции) | `sensor.tz3000_gjnozsaz_ts011f_lqi_2`, `_3` | ✅ исправлено | +| D4 | `sauna` — зона `tualet` | `switch.sauna` в зоне ТУАЛЕТ | ⛔ **НЕ дефект** — Alex: «Её зона туалет 1». Оставлено | +| D5 | `select`-сущности `sauna` названы `bed_dimmer_*` | `select.bed_dimmer_power_on_behavior` | ✅ исправлено | -| Устройство | Сущность батареи | Текущий заряд | -|---|---|---| -| `toilet_1_floor_temperature` | `sensor.toilet_1_floor_temperature_battery` | 100.0 | -| `light_sensor_stairs` | `sensor.light_sensor_stairs_battery` | 100.0 | -| `Темп теплый пол душевая` | `sensor.shower_2_floor_battery` | 100.0 | -| `boiler_water_leak` | `sensor.boiler_water_leak_battery` | 100.0 | -| `wireless_light_switch_bed` | `sensor.tz3000_kccru4oi_ts0041_batareia` | ? | -| `office_temperature_sensor` | `sensor.tz3000_akqdg6g7_ts0201_batareia` | ? | -| 6 × новых TS0201 | `sensor.*_batareia` | ? | - -**Оповещений о низком заряде — НЕТ ни у одного** (проверено: автоматизаций на `battery` нет). - -### 0.4. Modbus-bridge — занятость адресов +### 0.2. Исходная занятость Modbus-адресов bridge | Slave | Что | Регистр | |---|---|---| @@ -75,116 +59,219 @@ ZHA: **24 записи** (23 устройства + координатор). Б | 103 | снифф `bedroom_temperature` | 100 | | 104 | Zigbee-реле `switch.boiler_controller_power` | 1 | -**Свободно: `105+`** (у 100/102/103 — регистры ≠ 100). +Свободно: **105+**. Оповещений о низком заряде не было ни у одного батарейного. --- -## 1. План действий +## 1. ✅ РЕЗУЛЬТАТ — Шаг 1: единый вид ID (23 устройства) -### Шаг 1. Переименовать устройства в читаемые ID (ZHA) -Живой конфиг bridge — **не трогать** до подтверждения имён. +**Формат: `<устройство>_<роль>`.** Для датчиков `_temperature` / `_humidity` / `_battery` / `_lqi` / `_rssi`, плюс `button._identify` и `update._firmware`. Для реле `_power` / `_voltage` / `_current` / `_energy`, `select._indicator_mode` / `_power_outage_memory`. -Предлагаемая схема имён (единый стиль `<зона>_floor_temperature`): +| Было | Стало | +|---|---| +| `Темп теплый пол гостиная` | `living_room_floor_temperature` | +| `Температура серая` | `severnaia_floor_temperature` | +| `Темп теплый пол кабинет` | `kabinet_floor_temperature` | +| `Темп теплый пол кухня` | `kitchen_floor_temperature` | +| `Темп теплый пол ванная` | `vannaia_floor_temperature` | +| `Темп теплый пол прихожая` | `prikhozhaia_floor_temperature` | +| `Темп теплый пол душевая` | `dushevaia_floor_temperature` | +| `office_temperature_sensor` | `kabinet_temperature` | +| `light.night_light_shower_2` | `light.dushevaia_night_light` | +| `binary_sensor.tz3000_hy6ncvmw_ts0222` | `binary_sensor.light_sensor_stairs` | -| Текущее | Предлагаемое | Итоговые сущности | -|---|---|---| -| `Темп теплый пол гостиная` | `living_room_floor_temperature` | `sensor.living_room_floor_temperature_temperature` | -| `Температура серая` | `severnaia_floor_temperature` | `sensor.severnaia_floor_temperature_temperature` | -| `Темп теплый пол кабинет` | `kabinet_floor_temperature` | `sensor.kabinet_floor_temperature_temperature` | -| `Темп теплый пол кухня` | `kitchen_floor_temperature` | `sensor.kitchen_floor_temperature_temperature` | -| `Темп теплый пол ванная` | `vannaia_floor_temperature` | `sensor.vannaia_floor_temperature_temperature` | -| `Темп теплый пол прихожая` | `prikhozhaia_floor_temperature` | `sensor.prikhozhaia_floor_temperature_temperature` | -| `Темп теплый пол душевая` | `dushevaia_floor_temperature` | `sensor.dushevaia_floor_temperature_temperature` | -| `office_temperature_sensor` | `kabinet_temperature` | `sensor.kabinet_temperature_temperature` | +**Масштаб:** **140 переименований** (8 устройств + 68 + 16 + 56 + 2 сущностей). Все 23 устройства в зонах, «без зоны» — нет. -> ⚠️ **Переименование душевой затронет уже используемые ID** `sensor.shower_2_floor_temperature/humidity/battery` — их надо либо оставить как есть, либо обновить все ссылки. **Требует решения Alex.** +### 1.1. 🔴 Механика — `name_by_user` НЕ переименовывает `entity_id` -Механика: ZHA **не читает** `friendly_name` из Z2M → задавать через `config/device_registry/update` (WS) с `name_by_user`. -⚠️ Питфолл: удаление `device_id` сбрасывает `area_id`; переименование не сбрасывает, но проверять `area_id` после каждой операции. +HA перегенерирует `entity_id` только у **новых** сущностей. Нужны **два** шага: -### Шаг 2. Починить зону `sauna` (D4) и `select`-имена (D5) -- `sauna` → зона `kotelnaia` (уточнить у Alex: сауна или котельная?) -- `select.bed_dimmer_*` под `sauna` → переименовать в `sauna_*` +```python +# Шаг 1 — имя устройства +{"type":"config/device_registry/update","device_id": D, "name_by_user": "living_room_floor_temperature"} +# Шаг 2 — КАЖДАЯ сущность отдельно +{"type":"config/entity_registry/update","entity_id":"sensor.old_name","new_entity_id":"sensor.new_name"} +``` -### Шаг 3. Оповещения о низком заряде (7 батарейных) -На каждое устройство — автоматизация: +### 1.2. Команды (воспроизведение) + +```bash +# Полный аудит: устройства + сущности + зоны +cd ~/tmp-t610 && python3 zha_devs.py +# Переименование устройств (WS) +python3 rename_step1.py +# Переименование сущностей пакетом +python3 gen_rename_all.py # → /tmp/rename_all_plan.json (защита от конфликтов) +python3 apply_rename_all.py +# Аудит остатка нечитаемых +python3 audit_rest.py +``` + +**Скрипты:** `~/tmp-t610/{zha_devs,rename_step1,gen_rename_all,apply_rename_all,audit_rest,rename_ents,fix_last}.py` + +### 1.3. 🔴 Побочный эффект: рвутся ссылки в автоматизациях + +После переименования **молча** сломались 2 ссылки в `automations.yaml`: +- `light.night_light_shower_2` (×2) → `light.dushevaia_night_light` +- `sensor.tz3000_akqdg6g7_ts0201_batareia` → `sensor.kabinet_temperature_battery` + +**Проверка (обязательна после любого переименования):** +```bash +curl -s -H @/tmp/h1 "$B/api/states" | jq -r '[.[].entity_id]' > /tmp/all_ents.json +ssh -i ~/.ssh/id_rsa root@192.168.2.176 'cat /config/automations.yaml' \ + | grep -oE 'entity_id: [a-z_]+\.[a-zA-Z0-9_]+' | awk '{print $2}' | sort -u \ + | while read e; do jq -e --arg e "$e" 'index($e)' /tmp/all_ents.json >/dev/null || echo "BROKEN: $e"; done +``` + +--- + +## 2. ✅ РЕЗУЛЬТАТ — Шаг 2: чиста наследия миграции + +- `select.bed_dimmer_power_on_behavior` / `_switch_type` под `sauna` → `select.sauna_power_on_behavior` / `_switch_type` +- Все дубли `_2`/`_3` у LQI/RSSI/energy/identify приведены к `_` +- `sauna` в зоне `tualet` — **оставлено** (не дефект, подтверждено Alex) + +--- + +## 3. ✅ РЕЗУЛЬТАТ — Шаг 3: 12 автоматизаций контроля батарей + +**Порог 20 %, выдержка 2 ч, двойной канал:** `persistent_notification` (видно в UI) + `notify.mobile_app_sm_s931b` (push). При возврате заряда выше порога уведомление гасится само. ```yaml -- id: - alias: "Батарея: <устройство> разряжена" +- id: '8800000000000' # …8800000000011 — 12 штук + alias: 'Батарея: <место>' triggers: - - trigger: numeric_state - entity_id: sensor._battery - below: 20 - for: "02:00:00" + - trigger: numeric_state + entity_id: sensor._battery + below: 20 + for: '02:00:00' + id: low + - trigger: numeric_state + entity_id: sensor._battery + above: 20 + id: ok actions: - - action: persistent_notification.create - data: - title: "🔋 Батарея разряжена" - message: "<устройство>: {{ states('sensor._battery') }}%" + - choose: + - conditions: [{condition: trigger, id: low}] + sequence: + - action: persistent_notification.create + data: {title: '🔋 Батарея разряжена', notification_id: 'bat_'} + - action: notify.mobile_app_sm_s931b + - conditions: [{condition: trigger, id: ok}] + sequence: + - action: persistent_notification.dismiss + data: {notification_id: 'bat_'} + mode: single ``` -Порог **20 %**, выдержка **2 ч** (защита от просадки под нагрузкой). -⚠️ Домен триггера в ZHA — `battery` → `battery_level`. Проверять имена сущностей (`_battery` vs `_batareia`). -Способ доставки: `persistent_notification` — обсуждаемо (могут быть мобильные нотификации). +**Покрытие (12 сущностей):** туалет 1 · лестница · душевая · котельная (протечка) · кабинет (воздух) · гостиная · серая · кабинет (пол) · кухня · ванная · прихожая · спальня (кнопка). -### Шаг 4. Виртуальные Modbus-датчики в bridge -Добавить в `data/config.template.tmpl` секцию `mappings`: +### 3.1. Заменённые старые -| Slave | Источник (HA entity) | Регистр | Имя | -|---|---|---|---| -| 105 | `sensor.living_room_floor_temperature_temperature` | 100 | Living room floor temp | -| 106 | `sensor.severnaia_floor_temperature_temperature` | 100 | Severnaia floor temp | -| 107 | `sensor.kabinet_floor_temperature_temperature` | 100 | Kabinet floor temp | -| 108 | `sensor.kitchen_floor_temperature_temperature` | 100 | Kitchen floor temp | -| 109 | `sensor.vannaia_floor_temperature_temperature` | 100 | Vannaia floor temp | -| 110 | `sensor.prikhozhaia_floor_temperature_temperature` | 100 | Prikhozhaia floor temp | -| 111 | `sensor.dushevaia_floor_temperature_temperature` | 100 | Dushevaia floor temp | -| 112 | `sensor.toilet_1_floor_temperature_temperature` | 100 | Toilet 1 floor temp | +Две прежние автоматизации (`1773451323415`, `1773459663218`) **удалены** — были с порогом 10 и без push. -Формат (по образцу существующего): -```yaml - - name: "Living room floor temp" - source: "ha" - entity_id: "sensor.living_room_floor_temperature_temperature" - slave_id: 105 - register_address: 100 - register_count: 1 - data_type: "int16" - divider: 10 +### 3.2. 🔴 Сироты: `unavailable` при чистом YAML + +Тело удалено из `automations.yaml`, запись в реестре осталась → `unavailable`. Удаление: + +```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} # потом это ``` -⚠️ **Проверить свободно ли 105+** по двум источникам: эта карта + сам шаблон (сделано ✅). -⚠️ **`rebuild` обязателен** — шаблон впекается в образ. -⚠️ Только температурные. `dining/kids/bedroom` — уже есть (сниффы). +**Скрипты:** `~/tmp-t610/{add_battery_autos,rm_orphans,rm_orphan2,rm_orphan3}.py` -### Шаг 5. Обновить доку -- `family/tech/zigbee-t610-z2m-i-zha.md` — карта устройств 16 → 23, новые TS0201, дефекты ID. -- `family/how-to/home-automation.md` §6 — карта slave'ов 100–112. -- `family/how-to/ha-automations.md` — 7 новых автоматизаций батарей. +### 3.3. Границы + +`sensor.wireless_light_switch_bed_battery` = `unknown` — кнопка спальни спит. Автоматизация создана, но триггера не будет, пока датчик не проснётся (лечится нажатием кнопки). --- -## 2. Вопросы к Alex (до начала работ) +## 4. ✅ РЕЗУЛЬТАТ — Шаг 4: виртуальные Modbus-датчики (slave 100 + 105–112) -1. **Схема имён** — устраивает `living_room_floor_temperature` / `severnaia_floor_temperature`? Или другой стиль? -2. **Переименовывать ли `office_temperature_sensor`** → `kabinet_temperature`? (затронет slave 100 в bridge) -3. **Душевая:** оставить `shower_2_floor_*` или переименовать в `dushevaia_floor_temperature_*`? (переименование = правка ссылок) -4. **`sauna` в зоне «Туалет»** — куда правильно: котельная? -5. **Порог/доставка алертов:** 20 %, 2 ч, `persistent_notification` — или мобильные push? -6. **Нужны ли в Modbus влажность/CO2**, или только температура? +Добавлены в `/addons/modbus-bridge/data/config.template.tmpl`, `int16`, `divider: 10`: -## 3. Порядок выполнения и риски +| Slave | HA-сущность | +|---|---| +| **100** | `sensor.kabinet_temperature_temperature` (исторический «Room temp») | +| 105 | `sensor.living_room_floor_temperature_temperature` | +| 106 | `sensor.severnaia_floor_temperature_temperature` | +| 107 | `sensor.kabinet_floor_temperature_temperature` | +| 108 | `sensor.kitchen_floor_temperature_temperature` | +| 109 | `sensor.vannaia_floor_temperature_temperature` | +| 110 | `sensor.prikhozhaia_floor_temperature_temperature` | +| 111 | `sensor.dushevaia_floor_temperature_temperature` | +| 112 | `sensor.toilet_1_floor_temperature_temperature` | -| Шаг | Риск | Откат | -|---|---|---| -| 1. Переименование | Средний — меняются entity_id, ломаются ссылки в автоматизациях/дашбордах | Бэкап `core.entity_registry` + список старых ID | -| 2. Зона/select | Низкий | Вернуть `area_id` | -| 3. Автоматизации | Низкий | Бэкап `automations.yaml` | -| 4. Modbus mappings | Средний — rebuild аддона, возможен RCU/нагрузка | Бэкап `config.template.tmpl`, `rollback` | +Итого в шаблоне **14 маппингов**. Свободно: `113+`. -**Обязательно перед началом:** -- Бэкап `/config/.storage/core.entity_registry`, `core.device_registry`, `core.restore_state` -- Бэкап `/config/automations.yaml` -- Бэкап `/addons/modbus-bridge/data/config.template.tmpl` (новый `.bak-idmodbus-<дата>`) -- Снять снапшот HA (`POST /backups/new/full`) +### 4.1. 🔴 НАЙДЕНА И ИСПРАВЛЕНА РЕАЛЬНАЯ ПОЛОМКА: slave 100 отдавал `0` + +Slave 100 ссылался на **старое** имя `sensor.office_temperature_sensor_temperature` — после переименования сущность стала `kabinet_temperature_temperature`. Bridge молча возвращал `0 [00 00]`. + +``` +ДО: → Response: 1 register(s) from 100 (ha:sensor.kabinet_temperature_temperature) = 0 [00 00] +ПОСЛЕ: → Response: 1 register(s) from 100 (ha:sensor.kabinet_temperature_temperature) = 23.97 [00 F0] +``` + +> 📌 **ПРАВИЛО: переименовал HA-сущность → проверь маппинг в `config.template.tmpl` + `rebuild`.** +> 📌 **Проверка slave'а без ZONT'а невозможна** — bridge это serial-slave, отвечает только на запрос. Признаки работы: +> 1. `ha apps logs local_modbus-bridge | grep "HA poll -> sensor."` — поллер кэширует HA-значение. +> 2. `... | grep -A3 "Slave: 100"` → `Response: ... = []`. + +### 4.2. Дубликат slave 113 — убран + +При правке добавился «Kabinet air temp» (113) на ту же сущность, что slave 100. Удалён как дубль. + +### 4.3. Команды + +```bash +# правка шаблона → rebuild ОБЯЗАТЕЛЕН (Dockerfile: COPY data/config.template.tmpl) +scp config.template.tmpl root@192.168.2.176:/addons/modbus-bridge/data/config.template.tmpl +ssh root@192.168.2.176 'ha apps rebuild local_modbus-bridge && ha apps start local_modbus-bridge' +``` + +**Скрипты:** `~/tmp-t610/{add_modbus_temps,dedup_slave113,fix_slave100}.py` + +--- + +## 5. ✅ РЕЗУЛЬТАТ — Шаг 5: дока обновлена + +- `family/tech/zigbee-t610-z2m-i-zha.md` — карта 16 → 23 устройств, §2.1 «как переименовывать», §4 батареи, §5 виртуальные Modbus, питфоллы 17–21. +- `family/how-to/home-automation.md` — шапка, §1 итог, §6 карта slave'ов 100–112. +- `family/how-to/ha-automations.md` — карта автоматизаций 14 → 26, батарейные. +- Коммит vault: **`ddba016`**. + +--- + +## 6. Бэкапы, снятые перед работами (2026-09-15 22:34) + +| Что | Где | +|---|---| +| Снапшот HA (full) | `23a119f4.tar` в `/backup/` на t610 | +| Реестры (entities/devices/areas) | `~/tmp-t610/backup-preids-20260915-223427/registries-before.json` | +| Реестры (на t610) | `/config/.storage.bak-preids-20260915-223427/` | +| `automations.yaml` | `/config/automations.yaml.bak-preids-20260915-223427` | +| `config.template.tmpl` | `/addons/modbus-bridge/data/config.template.tmpl.bak-preids-20260915-223427` | + +--- + +## 7. Ключевые уроки + +| # | Урок | +|---|---| +| 1 | `name_by_user` и `entity_id` — **разные вещи**, менять оба | +| 2 | Переименование рвёт ссылки в `automations.yaml` **молча** — проверять всегда | +| 3 | Переименование рвёт маппинг bridge → slave отдаёт `0` **молча** | +| 4 | Сирота-автоматизация (`unavailable` при чистом YAML) → `remove`, а при `id_reuse` — сначала `disabled_by: user` | +| 5 | Bridge нельзя проверить без ZONT'а иначе, чем через `HA poll ->` в логе | +| 6 | `rebuild` (не `restart`) после правки `data/config.template.tmpl` | +| 7 | Русские имена устройств → HA транслитерирует в мусорные `entity_id` | + +## Связанные заметки + +- [[family/tech/zigbee-t610-z2m-i-zha]] — справочник ZHA: устройства, рецепт переименования, батареи, Modbus slave'ы +- [[family/how-to/home-automation]] — топология, аддоны, Modbus §6 +- [[family/how-to/ha-automations]] — логика автоматизаций