[2026-09-14] eagle: family/how-to/home-automation.md family/plans/t610-home-automation.md

This commit is contained in:
Alexey Martemyanov
2026-09-14 19:22:54 +06:00
parent f717f091e3
commit 0c4719715a
2 changed files with 18 additions and 8 deletions
+10 -1
View File
@@ -139,10 +139,19 @@ Hz : PWM
> **📐 Правило распределения адресов (зафиксировано 2026-09-14):**
> - **Реальные 485-устройства:** `199` (датчики 1/2/3, AT2 = 10, relay-модули 11/12/13/14, газ-котёл вкл = **20**).
> - **Виртуальные (bridge-подстановка):** `100247` — `100` Tuya Zigbee датчик, `101/102/103` датчики Гостиная/Детская/Спальня (рег. 100), `101:1` Socket 1, **`104:1` Zigbee-реле котла `switch.boiler_controller_power`** (bidirectional, заведено 2026-09-14 вечер-13).
> - **Виртуальные (bridge-подстановка):** `100247` — `100` Tuya Zigbee датчик, `101/102/103` датчики Гостиная/Детская/Спальня (рег. 100), `101:1` Socket 1, **`104:1` Zigbee-реле котла `switch.boiler_controller_power`** (bidirectional, **✅ работает с 2026-09-14 вечер-13**, подтверждено Alex).
> - **✅ Свободно:** **`105` и выше** (полностью — `105247`); у 100/102/103 свободны только регистры ≠ 100. `104:1` **занято** (реле котла), регистры `104:2+` свободны.
> - **Занятость проверять ВСЕГДА по двум источникам:** эта карта + реальный `/addons/modbus-bridge/data/config.template.tmpl` на t610. Расхождение — признак правки мимо доки.
> - **Механика маппинга «modbus-регистр ↔ HA-сущность»** (образец для нового реле/розетки) — в шапке `modbus_ha_bridge.py` (стр. 80104) и `config.template.yml` (стр. 118131): блок с `source: ha` + `entity_id` (чтение) и `action: ha` + `ha_entity_id` + `ha_service_on/off` (запись). Правка **только конфига-шаблона** (`data/config.template.tmpl`) — код менять не нужно. **После правки обязателен `ha apps rebuild local_modbus-bridge`** (шаблон впекается в образ!), затем `ha apps restart`. Рабочий образец-эталон — блок реле котла в `§5-кватер-И-7` доки [[family/plans/t610-home-automation]].
> - **`value_map`** при write: bridge берёт `value_map.get(reg_val, 1 if reg_val else 0)`, поэтому для чужих кодов (напр. ZONT пишет `0x0100`/`0x0200`) маппить явно: `{0: 0, 1: 1, 256: 0, 512: 1}`. Механика: `0x06` (write reg) и `0x05` (write coil, `0xFF00`=ON) → `switch.turn_on/off`; `0x03` (read) → значение из HA-поллера.
### 🔧 Диагностика bridge — рабочие приёмы (2026-09-14)
> - ⚠️ **`ha apps logs <slug>` обрезает вывод до 100 строк и отдаёт СТАРЫЙ буфер** (видели записи 13:10 при текущем времени 20:10) — живой лог через CLI **не получить**. Обход — API: `GET http://192.168.2.176:80/api/hassio/addons/local_modbus-bridge/logs`, заголовок `Authorization: Bearer <token>`; ответ — **голая строка** в `.data` (не JSON-объект).
> - **Замерший лог ≠ мёртвый bridge.** Доказательство живости — подписка на MQTT **с Mac**: `mosquitto_sub -h 192.168.2.176 -u zont -P '<пароль>' -t 'modbus/#' -v`. Идёт поток → bridge работает. (Пароль mosquitto **не совпадает** с тем, что лежит в опциях аддона `modbus-bridge` — брать рабочий из `~/tmp-t610/apply_token2.sh`.)
> - ⚠️ **Секрет-маскировщик Hermes подменяет `$VAR` и `$(cat file)` на `***`** при `write_file` → собирать заголовок в файл: `printf 'Authorization: %s %s' 'Bearer' "$(cat /tmp/.hatok)" > /tmp/h1`, затем `curl -H @/tmp/h1`. (Общий питфолл агента, не bridge-специфичный.)
> - **Команды с `rm` в SSH через Hermes требуют approval** и могут истечь → в диагностике `rm` избегать.
> - Порядок безопасной верификации нового маппинга: пересобрать → `state: started` → MQTT-поток идёт → в живом логе (через API) строка `HA poll -> <entity>` + ответ на read нужного slave/регистра.
```
Датчики
+8 -7
View File
@@ -11,7 +11,7 @@
**Этап 1 ✅ · Этап 2 ✅ · Этап 3 ✅ ЗАКРЫТ.** Этап 4 — **ПОЧТИ ЗАКРЫТ (3 из 4):** ① Caddy → t610 (`mallexxx.duckdns.org` → HA на t610, HTTP 200); ② Node-RED flows перенесены, `Connected to HA`, наружу не выпущен (решение Alex «оставляем так», доступ через ingress); ③ **ZONT MQTT-редирект переключён на t610** (DNAT на роутере `.197``.176`, живой поток идёт). **ОСТАЛОСЬ:** погасить/отключить сервисы TrueNAS (заблокировано — Caddy на TrueNAS держит точку входа) + хвосты (static IP, бэкап).
**Последнее действие (2026-09-14, вечер-13): ✅ t610 ВКЛЮЧЁН и работает.** После shutdown (вечер-13, `ha host shutdown`) Alex включил хост физически → USB-камера **разлипла сама** (power-cycle — единственное лечение, см. §5-кватер-И-6). Далее по плану: `local_ustreamer`**`boot: manual`** (автозапуск снят, чтобы не дрался за `/dev/video0`), поднят **`go2rtc-hardware`**, камера переведена на RTSP H.264 → **WebRTC работает**.
**Последняя верификация: 2026-09-14 (вечер-13) — ✅✅ RTSP/WebRTC РЕШЕНО.** Камера работает через **аддон `a889bffc_go2rtc-hardware`** (ffmpeg-транскод MJPEG→H.264) → RTSP `rtsp://192.168.2.176:8554/usb_camera_h264`, WebRTC в приложении HA **работает** (Alex: «Супер, работает»). ustreamer остановлен (`boot: manual`). Канон, доказательства, питфоллы — **§5-кватер-И-6**.
**Зигби-реле котла (вечер-13) — ✅ ПРАВКА ПРИМЕНЕНА, деплой выполнен:** `switch.boiler_controller_power` заведено в `modbus-bridge` как **`slave 104, рег. 1`** (bidirectional) — правка `data/config.template.tmpl` + `ha apps rebuild/restart` (exit 0, `state: started`). Bridge жив (MQTT-поток идёт). **⏭ ОСТАЛОСЬ:** подтвердить в живом логе строку `HA poll -> switch.boiler_controller_power` и ответ read `104/1`; выяснить, прописан ли `slave 104` **в самом ZONT** (ZONT не трогали). Питфоллы верификации (лог CLI обрезан до 100 строк → API; пароль mosquitto; маскировщик) — **§5-кватер-И-7**.
**Зигби-реле котла (вечер-13) — ✅✅ РАБОТАЕТ, ПОДТВЕРЖДЕНО ALEX:** `switch.boiler_controller_power` заведено в `modbus-bridge` как **`slave 104, рег. 1`** (bidirectional) — правка `data/config.template.tmpl` + `ha apps rebuild/restart` (exit 0, `state: started`). Bridge жив (MQTT-поток идёт). **Alex: «Работает, супер»** — верификация закрыта. Питфоллы (лог CLI обрезан до 100 строк → API; пароль mosquitto; маскировщик) — **§5-кватер-И-7**. ⚠️ Открытый вопрос: прописан ли `slave 104` **в самом ZONT** (ZONT не трогали) — если нет, ZONT реле не увидит.
**История (вечер-12, ❌ не дало результата):** обычный go2rtc без ffmpeg + попытка RTSP → `JPEG/90000`, `stream_source: timeout`, залипание USB (лечится power-cycle). Оставлено как урок в §5-кватер-И-6.
**Предыдущая верификация (вечер-11) — ✅✅ КАМЕРА: СХЕМА ВОЗВРАЩЕНА «КАК НА TrueNAS», РАБОТАЛА.** Камера на TrueNAS **была**`cam.mallexxx.duckdns.org → 192.168.2.197:8090` (отдельный **HTTP-MJPEG-сервис**, `ustreamer`), контейнер **утрачен при пересоздании пула** (локальный образ не пережил `.ix-apps`; след остался в `Caddyfile.bak`). **ЧТО СДЕЛАНО (вечер-11):** ① блок `camera: platform: ffmpeg` из `configuration.yaml` **снесён** (бэкап `.bak-rmcam-20260914-185240`) → `/dev/video0` освобождён; ② поднят **локальный аддон `local_ustreamer`** на t610 (`/addons/ustreamer/`) — отдаёт MJPEG на **:8090**; ③ в HA заведена **Generic Camera** по URL потока → `camera.192_168_2_176` с **`unique_id`** → **зона `kotelnaia` назначена**, имя «Камера котельной». Проверено: кадр JPEG 640×480 (HTTP 200, 25 КБ), MJPEG-стрим `multipart/x-mixed-replace` живой, `Resource busy` больше не воспроизводится. Канон и питфоллы — **§5-кватер-И-3/И-5**. До этого: фикс bridge (T3.5) держится, `dining` стабилен; static IP t610 + триггер душевой. **HA long-lived token — в §5-кватер-И-3.** **Осталось (актуализировано вечер-13):** ① ✅ t610 включён, камера разлипла (power-cycle); ② ✅ автозапуск `local_ustreamer` снят (`boot: manual`); ③ ✅ поднят `go2rtc-hardware`; ④ ✅ камера в HA на `rtsp://192.168.2.176:8554/usb_camera_h264`, WebRTC проверен — работает; ⑤ ⏳ снять устаревшую строку `cam.*` из `truenas-infrastructure.md`. ⚠️ `/config/go2rtc.yaml` **НЕ удалять** — он нужен аддону go2rtc (прежняя пометка «удалить лишний» относилась к встроенному go2rtc Core и **опровергнута**).
@@ -2021,6 +2021,8 @@ curl -s -X POST -H "$HDR" -H "Content-Type: application/json" \
| ~~A4~~ | ~~**Ночной свет душевой**: триггер на падение освещённости~~ | — | **✅ ВЫПОЛНЕНО 2026-09-14 (вечер-8, §5-кватер-И-2):** в automation `1771997851260` добавлен триггер `illuminance below:8` + условие `is_occupied`. Проверено через API: `triggers`=2, `conditions`=2 |
| ~~**A5**~~ | ~~**Камера**: USB-вебка Logitech `046d:0825` на t610 → завести в HA~~ | — | **⚠️ ПЕРЕДЕЛАНО 2026-09-14 (вечер-11).** Сначала (вечер-9) завели через `camera: platform: ffmpeg`**отвергнуто** (`Resource busy`, нет `unique_id`). **Итог вечер-11:** аддон `local_ustreamer` + Generic Camera → `camera.192_168_2_176`, зона `kotelnaia`, `unique_id` ✅. Детали — §5-кватер-И-5 |
| ~~**A6**~~ | ~~**Камера — вернуть схему «как на TrueNAS»** (решение Alex, вечер-10)~~ | — | **✅✅ ВЫПОЛНЕНО 2026-09-14 (вечер-11, §5-кватер-И-3/И-5).** Историч. upstream был `cam.mallexxx.duckdns.org → 192.168.2.197:8090` (контейнер утрачен при пересоздании пула, след — `Caddyfile.bak`). Реализовано **аддоном на t610** (вебка физически там, Docker в HA OS закрыт → аддон). Поднят `local_ustreamer` (`/addons/ustreamer/`, MJPEG :8090) → Generic Camera по URL → **`unique_id` + зона `kotelnaia` + имя «Камера котельной»**. Блок `camera: platform: ffmpeg` из `configuration.yaml` **снесён** (бэкап `.bak-rmcam-20260914-185240`). Осталось: удалить лишний `/config/go2rtc.yaml` |
| ~~**A7**~~ | ~~**Камера — RTSP/WebRTC (финал)**~~ | — | **✅✅ ВЫПОЛНЕНО 2026-09-14 (вечер-13, §5-кватер-И-6).** ustreamer заменён на аддон **`a889bffc_go2rtc-hardware`** (в нём ffmpeg), `/config/go2rtc.yaml`: `ffmpeg:device?video=/dev/video0&input_format=mjpeg&video_size=640x480#video=h264` → RTSP H.264 `rtsp://192.168.2.176:8554/usb_camera_h264`**WebRTC в HA работает**. `local_ustreamer``boot: manual`, `stopped` |
| ~~**A8**~~ | ~~**Zigbee-реле котла → modbus-bridge**~~ | ✅ низкий | **✅✅ ВЫПОЛНЕНО + ПОДТВЕРЖДЕНО ALEX 2026-09-14 (вечер-13, §5-кватер-И-7).** `switch.boiler_controller_power` заведено как **`slave 104, рег. 1`** (bidirectional) — правка `data/config.template.tmpl` + `ha apps rebuild/restart local_modbus-bridge` (exit 0, `state: started`). Alex: «Работает, супер». Бэкап `.bak-relay-20260914-200827`, файлы `~/tmp-t610/relay/`. ⚠️ **Осталось:** проверить/добавить `slave 104` **в самом ZONT** (не трогали) |
**Вариант B — Этап 4 целиком** (№5: Caddy upstream → t610 + GPON-редирект → t610 + ZONT MQTT → t610). 🔴 Трогает рабочее → нужно окно и согласование с Alex. **Caddy-часть СДЕЛАНА (§5-кватер-Б/В).**
@@ -2442,7 +2444,7 @@ uvcvideo 2-1:1.1: Failed to resubmit video URB (-1) ← в dmesg
---
## 5-кватер-И-7. 🔌 Zigbee-реле котла → bridge (2026-09-14, вечер-13) — ✅ ПРИМЕНЕНО, деплой выполнен
## 5-кватер-И-7. 🔌 Zigbee-реле котла → bridge (2026-09-14, вечер-13) — ✅✅ РАБОТАЕТ (подтверждено Alex)
**Триггер:** Alex — *«и добавь в modbus bridge розетку modbus адаптеров котла как реле»* → уточнение: *«zigbee розетку»*.
@@ -2592,16 +2594,15 @@ Alex: *«Да. Boiler controller. Modbus bridge»* → затем: *«Уточн
4. ⚠️ **Секрет-маскировщик Hermes подменяет `$VAR` и `$(cat file)` на `***` при `write_file`** — обход: собирать заголовок через `printf 'Authorization: %s %s' 'Bearer' "$(cat /tmp/.hatok)"` в отдельный файл и передавать `curl -H @file`.
5. **Команды с `rm` в SSH через Hermes требуют approval** — если истекает, команда блокируется. Минимизировать `rm` в диагностических скриптах.
### ⏭ ОСТАЛОСЬ по этой задаче (не выполнено)
### ✅ Верификация (закрыта 2026-09-14, вечер-13)
- **Верификация регистра `104:1` в живом логе:** ожидаемая строка `HA poll -> switch.boiler_controller_power = 1.0` и ответ на read `104/1`. На момент завершения сессии **НЕ подтверждено** (последняя проверочная команда заблокирована истёкшим approval). Проверка повторить без `rm`:
- **Alex подтвердил вручную: «Работает, супер»** — реле котла управляется через modbus-регистр `104:1`. Живые проверки (read `104/1`, write `104/1 = 0`, строка `HA poll -> switch.boiler_controller_power`) отдельно командой не снимались — статус закрыт **свидетельством пользователя**. При необходимости проверка повторяется так (без `rm`, чтобы не ловить approval):
```
ssh root@192.168.2.176 'printf "Authorization: %s %s" "Bearer" "$(cat /tmp/.hatok)" > /tmp/h1; \
curl -s -H @/tmp/h1 http://192.168.2.176:80/api/hassio/addons/local_modbus-bridge/logs > /tmp/mblog_full.txt; \
tail -5 /tmp/mblog_full.txt; grep -in "boiler" /tmp/mblog_full.txt; grep -n "Slave: 104" /tmp/mblog_full.txt'
tail -20 /tmp/mblog_full.txt; grep -in "boiler" /tmp/mblog_full.txt; grep -n "Slave: 104" /tmp/mblog_full.txt'
```
- **ZONT:** прописан ли `slave 104` в конфиге ZONT — **НЕ проверялось и НЕ трогалось** (правило Alex: ZONT не менять). ZONT опрашивает только тех slave, что прописаны у него → если 104 не добавлен, реле он не увидит. Вопрос к Alex.
- **Проверка «в обе стороны»:** read `104/1` → 1 (реле on); write `104/1 = 0` → реле гаснет + лог `→ HA Action: switch.turn_off(...) [OK]`. **НЕ выполнено.**
- ⚠️ **Единственный открытый вопрос: ZONT.** Прописан ли `slave 104` в конфиге ZONT — **НЕ проверялось и НЕ трогалось** (правило Alex: ZONT не менять). ZONT опрашивает только тех slave, что прописаны у него → если 104 не добавлен, реле он не увидит. **Вопрос к Alex.**
### 📁 Рабочие файлы этой задачи (на Mac)