[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:07:37 +06:00
parent 3a70f82edb
commit 7c1c0947f4
2 changed files with 134 additions and 39 deletions
+7 -1
View File
@@ -17,7 +17,6 @@ related:
- '[[family/how-to/truenas-access]]'
---
# 🏠 Умный дом — автоматика
> **Статус на 2026-09-14:** домашняя автоматизация **перенесена на HP t610** (HA OS).
> 📌 **Всё про миграцию** — хост, доступ, карта USB/гнёзд, аддоны, Zigbee, питфоллы, текущее состояние — **в единственном документе [[family/plans/t610-home-automation]]. НЕ дублировать сюда.**
> 📌 **Этот документ — справочник по ЖЕЛЕЗУ:** AT2 (параметры/PWM), карта Slave ID, регистры заслонок/реле, ZONT relays. Оборудование и адреса Modbus при миграции не меняются.
@@ -138,6 +137,13 @@ Hz : PWM
## Карта Slave ID — датчики и реле
> **📐 Правило распределения адресов (зафиксировано 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` и выше** (полностью — `104247`); у 100/102/103 свободны только регистры ≠ 100.
> - **Занятость проверять ВСЕГДА по двум источникам:** эта карта + реальный `/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` (запись). Правка только конфига — код менять не нужно.
```
Датчики
Гостиная - 1 (modbus bridge virt. sensor - 101)
+127 -38
View File
@@ -9,10 +9,11 @@
## 1. Состояние на 2026-09-14 (актуализировано 15:33 → дополнено вечерней сессией)
**Этап 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, ~19:45): 🔴 t610 ВЫКЛЮЧЕН** — Alex: *«Отправь ему shutdown»*, выполнено `ha host shutdown` (exit 0), probe доступности запрещён. Вся автоматизация офлайн; включение только физически. План на включение — §5-кватер-И-6.
**Последняя верификация: 2026-09-14 (вечер-13) — ✅✅ RTSP/WebRTC РЕШЕНО.** Камера работает через **аддон `go2rtc-hardware`** (ffmpeg-транскод MJPEG→H.264) → RTSP `rtsp://192.168.2.176:8554/usb_camera_h264`, WebRTC в приложении HA **работает** (Alex: «Супер, работает»). ustreamer остановлен (`boot: manual`). Канон, доказательства, питфоллы — **§5-кватер-И-6**.
**Последнее действие (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**.
**Открытая задача (ответы Alex получены, ждёт подтверждения адреса):** завести **Zigbee-реле котла `switch.boiler_controller_power`** в `modbus-bridge` — Alex подтвердил реле и аддон; **адрес `slave 104, рег. 1` предложен, ждёт ОК**. Инвентаризация свободных адресов, IEEE-адрес реле, готовый образец маппинга — **§5-кватер-И-7**.
**История (вечер-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.** **Осталось (обновлено вечер-12 → shutdown):** ① включить t610 физически; ② **сначала снять автозапуск у `local_ustreamer`** (иначе снова подерётся с go2rtc за `/dev/video0`); ③ поднять только go2rtc, проверить оживление камеры; ④ камеру в HA переключить на `rtsp://192.168.2.176:8554/usb_camera`, проверить WebRTC; ⑤ снять устаревшую строку `cam.*` из `truenas-infrastructure.md`. ⚠️ `/config/go2rtc.yaml` **НЕ удалять** — он нужен аддону go2rtc (прежняя пометка «удалить лишний» относилась к встроенному go2rtc Core и **опровергнута**).
**Предыдущая верификация (вечер-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 и **опровергнута**).
| Что | Факт |
|---|---|
@@ -21,7 +22,7 @@
| Зоны | 11 зон, **18 устройств** с зонами |
| Автоматизации | **16 шт.: 15 `on` + 1 `off`**, `unavailable` — 0 |
| Zigbee (z2m) | **15 устройств**, координатор EmberZNet 7.4.5 |
| Аддоны | `core_ssh`, `core_mosquitto`, `a0d7b954_nodered`, `45df7312_zigbee2mqtt`, `local_mbusd`, `local_modbus-bridge` все `started`. Камера: `local_ustreamer` (**stopped**, вечер-12) + **`a889bffc_go2rtc`** (установлен вечер-12, репо AlexxIT). ⚠️ **t610 выключен** — всё офлайн до включения |
| Аддоны | `core_ssh`, `core_mosquitto`, `a0d7b954_nodered`, `45df7312_zigbee2mqtt`, `local_mbusd`, `local_modbus-bridge`, **`a889bffc_go2rtc-hardware`** (камера, v1.9.14-hardware, `boot: auto`)`started`. Камера-откат: `local_ustreamer` (**`boot: manual`, `stopped`**). Ещё установлен неиспользуемый `a889bffc_go2rtc` (обычный, без ffmpeg — `stopped`) |
| modbus-bridge | MQTT + HA-опрос работают (без 404) |
### ✅ Верификация 2026-09-14 15:33 (только чтение, ничего не менялось)
@@ -49,7 +50,7 @@
| ~~`verify` как причина~~ | **ОПРОВЕРГНУТО как причина:** при верной привязке шин заслонки ожили при том же `verify` (`state_on:1`/`state_off:0`). Причина была в перепутанных шинах, не в `verify` |
| **`sensor.fan_at2_*` / `switch.fan_3_*` — сироты** | В `configuration.yaml` **весь блок slave 10 (AT2 fans) закомментирован** → эти сущности физически не могут получать данные. Не задача — просто известный факт состояния конфига |
| `switch.sauna` = `unknown` | Розетка физически отключена (`lastSeen` 8+ ч) — не баг |
| ZONT не перенаправлен | **✅ ПЕРЕНАПРАВЛЕН 2026-09-14 (вечер-3, §5-кватер-Д):** DNAT на роутере `192.168.2.2` (`redirect[0]` MQTT + `rule[3]`) переключён `.197``.176`; ZONT пишет в mosquitto **t610** (живой поток kids/bedroom). ⚠️ Не решено: `dining/*` не публикуется — **ответ на шине есть, bridge его не отдаёт** (§5-кватер-Д, задача №3) |
| ZONT не перенаправлен | **✅ ПЕРЕНАПРАВЛЕН 2026-09-14 (вечер-3, §5-кватер-Д):** DNAT на роутере `192.168.2.2` (`redirect[0]` MQTT + `rule[3]`) переключён `.197``.176`; ZONT пишет в mosquitto **t610** (живой поток kids/bedroom). `dining/*` **ПОЧИНЕН** (коммит `3748feb`, баг сборки RTU-кадров, см. §5-кватер-З) |
| Камера | ✅ **ГОТОВО (2026-09-14, вечер-13).** USB-вебка Logitech `046d:0825` (только MJPEG) → **аддон `a889bffc_go2rtc-hardware`** (ffmpeg-транскод MJPEG→H.264) → **RTSP `rtsp://192.168.2.176:8554/usb_camera_h264`****Generic Camera****`camera.192_168_2_176`** (имя «Камера котельной», **зона `kotelnaia`**, `unique_id 01M2FX50K72X2RSYY549QSG3XP`). **WebRTC в приложении HA работает** (Alex подтвердил), HLS тоже. `local_ustreamer``boot: manual`, `stopped` (откат). Детали, каноны, питфоллы — **§5-кватер-И-6**. **❌ ОТВЕРГНУТО:** `camera: platform: ffmpeg` в Core (`Resource busy` + нет `unique_id`); ustreamer как RTSP-источник (RTSP не умеет); обычный go2rtc без ffmpeg (транскод невозможен) |
---
@@ -2388,39 +2389,26 @@ streams:
`~/tmp-go2rtc/``go2rtc.yaml` (**итоговый конфиг**), `rtsp-check.py` (OPTIONS+DESCRIBE), `rtsp-play.py` / `rtsp-play-h264.py` (SETUP+PLAY, счёт байт), `rtsp-codec.py` (проверка кодека), `ws-caps.py` / `ws-webrtc.py` (websocket: capabilities + webrtc offer), `boot-off.sh` (boot→manual через Supervisor API), `cam-*.sh` (Generic Camera flow), `usb-reset.sh` (упёрлась в RO).
**Триггер:** Alex — *«добавь rtsp. на truenas был mjpg+rtsp почему ты так не сделал сразу?»* и *«ustreamer не подходит нам?»*.
### 📜 История попыток (вечер-12 → вечер-13, для контекста)
**Причина задачи:** в мобильном приложении HA при просмотре камеры — `Failed to start WebRTC stream: ... method DESCRIBE failed: 404 (Not Found)` для `rtsp://127.0.0.1:18554/generic_01M2FX50K72X2RSYY549QSG3XP`. **Диагноз (подтверждён):** источник — MJPEG; встроенный go2rtc Core не имеет потока `generic_01M2FX50K72X2RSYY549QSG3XP` → DESCRIBE 404. **HLS при этом работает** (`master_playlist.m3u8` валиден). Для WebRTC нужен **настоящий RTSP (H.264)**.
**Вечер-12 (❌ не дало WebRTC):** поставлен обычный аддон **`a889bffc_go2rtc`** (v1.9.14, без ffmpeg) — репозиторий `https://github.com/AlexxIT/hassio-addons` добавлен, `config.yaml` аддона: `host_network: true`, `video: true`, `map: [config:rw, media, ssl]`, `ingress_port: 1984`, `privileged: []`, `protected: true`. `/config/go2rtc.yaml` создан (аддон читает именно его — встроенный go2rtc Core игнорирует `/config/`). RTSP отвечал `200 OK`, MJPEG дал 2 424 832 байта за 10 с, **но** SDP отдавал `JPEG/90000` (не H.264, C270 H.264 не умеет), транскод не работал (ffmpeg в аддоне нет), Generic Camera ловил `stream_source: timeout`, а параллельный запуск с ustreamer залипил USB. ❌ Параметр `#video=h264` в URL **транскода не даёт** — go2rtc отдал JPEG на обоих треках.
**Почему ustreamer не подходит:** ustreamer отдаёт **только MJPEG и H.264 по HTTP**, **RTSP не умеет**. RTSP — отдельный протокол (свой сервер). На TrueNAS «mjpg+rtsp» — это была связка из двух сервисов, не один ustreamer. ✅ **go2rtc умеет всё три сразу** (MJPEG / RTSP :8554 / WebRTC) из одного источника.
### Что сделано (факты)
| Шаг | Результат |
|---|---|
| `ha store add https://github.com/AlexxIT/hassio-addons` | ✅ репозиторий добавлен (README — про go2rtc + SSH Tunnel) |
| Аддон **`a889bffc_go2rtc`** (v1.9.14) из репо AlexxIT | ✅ установлен; `config.yaml` аддона: `host_network: true`, `video: true`, `map: [config:rw, media, ssl]`, `ingress_port: 1984`, `privileged: []`, `protected: true` |
| ustreamer | ⏸ **остановлен** (камера = один процесс; иначе `Resource busy`) |
| `/config/go2rtc.yaml` | ✅ создан заново (аддон **читает именно его** — в отличие от встроенного go2rtc Core, который игнорирует) |
| go2rtc запущен | ✅ логи: `config path=/config/go2rtc.yaml`, слушает `:1984` (api), `:8554` (rtsp), `:8555` (webrtc) |
| **RTSP снаружи** | ✅ **РАБОТАЕТ**`OPTIONS rtsp://192.168.2.176:8554/usb_camera``RTSP/1.0 200 OK`; DESCRIBE отдаёт валидный SDP |
| MJPEG через go2rtc | ✅ **2 424 832 байта за 10 с** (`/api/stream.mjpeg?src=usb_camera`), producer `v4l2` жив, без ошибок |
### 🔑 КАНОН-1: синтаксис v4l2 в go2rtc ≥ 1.9.9
**🔑 КАНОН-1 (вечер-12, актуален): синтаксис v4l2 в go2rtc ≥ 1.9.9**
```
v4l2:device?video=/dev/video0&input_format=mjpeg&video_size=640x480
```
- **НЕ** `v4l2:device=/dev/video0` ошибка `streams: no such file or directory` (go2rtc не распознаёт источник; **и это НЕ означает «устройства нет»**).
- **Без `input_format`**`streams: v4l2: invalid input_format`. Формат указывать **обязательно**.
- Камера C270 отдаёт только **MJPEG** (`CAP: Using format: MJPEG` в логе ustreamer) — поэтому `input_format=mjpeg&video_size=640x480`.
- Целевой параметр `#video=h264` в URL **не дал эффекта** — go2rtc отдал JPEG на обоих треках (SDP: `a=rtpmap:96 JPEG/90000`). **ffmpeg-транскод в аддоне не сработал** (проверка `GET /api/ffmpeg` → пусто).
- **НЕ** `v4l2:device=/dev/video0``streams: no such file or directory` (и это **НЕ значит «устройства нет»**).
- **Без `input_format`**`streams: v4l2: invalid input_format` указывать **обязательно**.
- C270 отдаёт только **MJPEG** (`CAP: Using format: MJPEG`) — потому `input_format=mjpeg&video_size=640x480`.
**Вечер-13 (✅ финал):** нужен **`-hardware`** аддон (с ffmpeg) и транскод **отдельным `ffmpeg:`-потоком**. После этого RTSP отдаёт H.264, данные идут, Generic Camera валидируется, **WebRTC работает** — см. «🏁 РАБОЧЕЕ РЕШЕНИЕ» выше.
### 📜 Остатки вечер-12 (оставлено как история ошибок, не руководство)
- `ha core info`**`ip_address: 172.30.32.1`** — Core видит хост HA по этому адресу (NAT-шлюз hassio-сети).
- Аддон с `host_network: true` слушает на `0.0.0.0` → доступен и как `192.168.2.176`, и как `172.30.32.1`.
- ❌ **ОПРОВЕРГНУТО (вечер-13):** `stream_source: timeout` был не багом HA, а следствием **пустого RTSP-потока** (`a=recvonly`, 0 байт данных), потому что go2rtc отдавал **JPEG** без транскода. С настоящим **H.264** (через `ffmpeg:`-поток в `-hardware` аддоне) валидация проходит: `type: create_entry`, `errors: null`.
### 🔴 БЛОКЕР: залипание USB-уровня камеры
### ✅ БЫВШИЙ БЛОКЕР: залипание USB — ВЫЛЕЧЕНО power-cycle (вечер-13)
После манипуляций (go2rtc + ustreamer одновременно) камера залипла **на уровне драйвера ядра**:
```
uvcvideo 2-1:1.1: Failed to resubmit video URB (-1) ← в dmesg
@@ -2431,14 +2419,12 @@ uvcvideo 2-1:1.1: Failed to resubmit video URB (-1) ← в dmesg
> 🔴 **ФАКТ (2026-09-14, ~19:45): t610 ВЫКЛЮЧЕН.** Alex: *«Отправь ему shutdown»* → выполнено `ha host shutdown` (exit 0). Проверка доступности **НЕ производилась** (Alex запретил probe). **Следствие:** вся домашняя автоматизация офлайн (HA :80, go2rtc, ustreamer, mbusd, modbus-bridge, mosquitto, Zigbee2MQTT, Node-RED; ZONT без MQTT). Включение — **только физически кнопкой** (WoL не подтверждён). ⚠️ Пункты ① `ha host reboot` / ② перетк USB ниже — **УСТАРЕЛИ**: shutdown даёт тот же эффект (power-cycle лечит залипший USB при следующем включении).
>
> ⏸ **СТАТУС: НЕ ЗАВЕРШЕНО. ПЛАН НА ВКЛЮЧЕНИЕ (порядок важен):**
>**Сначала снять автозапуск у `local_ustreamer`** (boot auto → off) — иначе он снова вцепится в `/dev/video0` и подерётся с go2rtc (это и залипило камеру).
> ② Поднять **только go2rtc** (`boot: auto` у него уже стоит).
> ③ Проверить, что камера ожила: `dmesg` без `Failed to resubmit video URB`, MJPEG через go2rtc отдаёт байты.
> ④ Камеру в HA переключить на `rtsp://192.168.2.176:8554/usb_camera`, проверить WebRTC в приложении.
> ⑤ ustreamer не удалять — держать `stopped` на случай отката.
> **РЕШЕНО (вечер-13):** t610 включён → USB разлип сам (power-cycle). Далее по плану выполнено: ustreamer → `boot: manual` (не стартует), поднят **`go2rtc-hardware`** с `ffmpeg:`-потоком, камера в HA переведена на RTSP H.264 → **WebRTC работает**. Детали финала — выше в этой секции.
>
> 📜 **План на включение (выполнен, оставлен как история):**`local_ustreamer``boot: manual` ✅;поднять только go2rtc ✅ (`go2rtc-hardware`); ③ проверить `dmesg` без URB-ошибок ✅; ④ камера в HA на RTSP ✅; ⑤ ustreamer остаётся `stopped` для отката ✅.
### 📌 Питфоллы вечер-12 (не повторять)
### 📌 Питфоллы вечер-12/13 (не повторять)
> Таблица ниже — сводная. Финальные каноны (вечер-13) — выше в этой секции.
| Питфолл | Симптом | Решение |
|---|---|---|
| `v4l2:device=/dev/video0` | `streams: no such file or directory` | Синтаксис `v4l2:device?video=...&input_format=mjpeg` (go2rtc ≥ 1.9.9) |
@@ -2446,13 +2432,116 @@ uvcvideo 2-1:1.1: Failed to resubmit video URB (-1) ← в dmesg
| `video: true` + переустановка аддона | не помогает, если камера занята другим процессом | Сначала **остановить** держащий сервис, потом старт |
| Два сервиса на `/dev/video0` | `uvcvideo: Failed to resubmit video URB (-1)`, камера залипает | **Один процесс = одна камера.** Не запускать ustreamer и go2rtc вместе |
| Сброс USB через sysfs | `/sys/.../authorized: Read-only file system` | `/sys` RO в SSH-аддоне → **reboot хоста** или физический перетк |
| Generic Camera + RTSP | `{"errors":{"stream_source":"timeout"}}` | Не решено; причина не установлена |
| Generic Camera + RTSP | `{"errors":{"stream_source":"timeout"}}` | ✅ РЕШЕНО: был **пустой RTSP** (JPEG без транскода). Дать **H.264** (`ffmpeg:`-поток в `-hardware` аддоне) → валидация проходит |
| `netstat`/`ss` в SSH-аддоне | пусто (не видит сеть хоста) | Проверять порты **снаружи** (`curl`, socket-скрипт) |
| `ha store apps` вывод | **YAML, не JSON** | `jq` падает (`Invalid numeric literal`) — парсить `grep`, а не `jq` |
| `ffprobe` на Mac | не установлен | RTSP проверять socket-скриптом (`~/tmp-go2rtc/rtsp-check.py`) |
### Рабочие файлы (вечер-12, на Mac)
`~/tmp-go2rtc/``go2rtc.yaml` (итоговый конфиг), `rtsp-check.py` (OPTIONS+DESCRIBE, MJPEG-in-RTP), `rtsp-codec.py` (проверка кодека через `?video=h264`), `usb-reset.sh` (попытка sysfs-сброса, упёрлась в RO), `cam-list.sh` / `cam-opt.sh` / `cam-set.sh` / `cam-set2.sh` (Generic Camera flow на RTSP, оба адреса).
### Рабочие файлы (вечер-12/13, на Mac)
`~/tmp-go2rtc/`**`go2rtc.yaml`** (итоговый конфиг: `ffmpeg:device?video=/dev/video0&input_format=mjpeg&video_size=640x480#video=h264`), `rtsp-check.py` (OPTIONS+DESCRIBE), `rtsp-play.py` / `rtsp-play-h264.py` (SETUP+PLAY, счёт байт), `rtsp-codec.py` (проверка кодека), `ws-caps.py` / `ws-webrtc.py` (websocket: capabilities + webrtc offer), **`boot-off.sh`** (boot→manual через Supervisor API), `cam-list.sh` / `cam-opt.sh` / `cam-set.sh` / `cam-set2.sh` / `cam-h264.sh` / `cam-h264-ok.sh` / `cam-final.sh` / **`cam-ok2.sh`** (Generic Camera flow; успех = `confirmed_ok: true`), `cam-verify.sh` (кадр через HA), `usb-reset.sh` (попытка sysfs-сброса, упёрлась в RO).
---
## 5-кватер-И-7. 🔌 Zigbee-реле котла → bridge (2026-09-14, вечер-13) — ⏸ ОТКРЫТАЯ ЗАДАЧА
**Триггер:** Alex — *«и добавь в modbus bridge розетку modbus адаптеров котла как реле»* → уточнение: *«zigbee розетку»*.
**Суть:** есть **Zigbee-розетка (реле)**, через которую питаются **modbus-адаптеры котла**. Нужно завести её в bridge — **управлять вкл/выкл**.
### Что найдено фактами (HA API, вечер-13)
Zigbee-реле в HA (z2m, координатор EmberZNet 7.4.5, 15 устройств):
| Entity | Состояние | Комментарий |
|---|---|---|
| **`switch.boiler_controller_power`** | **on** | **Питание контроллера котла** — наиболее вероятный кандидат («розетка адаптеров котла») |
| `switch.heating_cable_plug` | off | Розетка греющего кабеля |
| `switch.recirculation_pump` | unknown | Насос рециркуляции |
| `switch.sauna` | unknown | Розетка физически отключена (`lastSeen` 8+ ч) |
| `switch.kitchen_hood_l1/l2/l3` | off/unknown/unknown | Вытяжка кухни |
| `switch.bed_dimmer_do_not_disturb` | unknown | Диммер спальни |
### ✅ ОТВЕТЫ ALEX (2026-09-14, вечер-13)
Alex: *«Да. Boiler controller. Modbus bridge»* → затем: *«Уточни из доков и конфига адреса свободные для нового виртуального реле»*.
1. **Реле:** **`switch.boiler_controller_power`** ✅ подтверждено.
2. **Куда:** **`modbus-bridge`** (наш аддон, ZONT 485) → станет **modbus-регистром**.
3. **Направление:** bidirectional (читать+писать) — по образцу «Socket 1».
### 🔑 IEEE-адрес реле (найдено в доке, строка 1704)
```
0xa4c1381694217e10 | boiler_controller_power | TS011F, питание контроллеров котлов | Котельная
```
Модель **TS011F** (Tuya Zigbee розетка). ⚠️ **Это НЕ `switch.0xa4c138f8da8bc478`** из конфига bridge — другое устройство.
### 🔍 Механика bridge — маппинг для реле УЖЕ есть (готовый образец)
В `modbus_ha_bridge.py` (шапка-пример, стр. 80–104) и в `config.template.yml` (стр. 118131) есть **рабочий образец**:
```yaml
- name: "Socket 1"
slave_id: 101
register_address: 1 # RTU offset 1 (PLC 40002)
register_count: 1
data_type: "int16"
divider: 1
source: "ha" # READ: состояние из HA
entity_id: "switch.0xa4c138f8da8bc478"
action: "ha" # WRITE: управление из modbus
ha_entity_id: "switch.0xa4c138f8da8bc478"
ha_service_on: "switch.turn_on"
ha_service_off: "switch.turn_off"
value_map: {0: 0, 256: 0, 512: 1}
```
**Правка только конфига-шаблона**, код `modbus_ha_bridge.py` менять НЕ нужно.
### 📊 ИНВЕНТАРИЗАЦИЯ АДРЕСОВ (проверено: дока `home-automation.md` + реальный конфиг на t610)
**Занято в bridge (фактически, `/addons/modbus-bridge/data/config.template.tmpl`):**
| Slave | Рег. | Что |
|---|---|---|
| 100 | 100 | Room temp (Tuya Zigbee датчик) |
| 101 | 1 | Socket 1 (write→switch) |
| 101 | 100 | Dining temp |
| 102 | 100 | Kids temp |
| 103 | 100 | Bedroom temp |
**Занято реальными 485-устройствами (не трогать):** `1, 2, 3` (датчики) · `10` (AT2 vent) · `11, 12, 13, 14` (relay-модули заслонок/радиаторов) · **`20` (газ-котёл вкл — живое устройство!)** · `100103` (виртуальные).
**🎯 ВЫВОД — свободно для нового виртуального реле:**
- **`slave_id: 104`** — **полностью свободен**, чисто, продолжает ряд 100–103 → **РЕКОМЕНДОВАНО**
- `105247` — свободны
- У 100/102/103 свободны только регистры (рег. 100 занят) — тесно, путается
**Предложенный маппинг:**
```yaml
- name: "Boiler controller power (Zigbee relay)"
slave_id: 104
register_address: 1
register_count: 1
data_type: "int16"
divider: 1
source: "ha"
entity_id: "switch.boiler_controller_power"
action: "ha"
ha_entity_id: "switch.boiler_controller_power"
ha_service_on: "switch.turn_on"
ha_service_off: "switch.turn_off"
value_map: {0: 0, 1: 1}
```
> ⚠️ **ТРЕБУЕТ ПОДТВЕРЖДЕНИЯ ALEX:** адрес `104:1`, направление (bidirectional vs write-only), значения (`0/1` vs `256/512` как у заслонок). Дока прямо фиксирует: **свободные адреса — за Alex** (стр. 2476).
### ⚠️ Замечание к задаче
На шине **уже есть `slave 20 = «Газ котёл вкл»`** (реальное реле, отвечает ✅). Если задача — управлять питанием котла, возможен **дубль**: ZONT уже умеет slave 20. Стоит уточнить у Alex, зачем именно Zigbee-реле при наличии 20.
**Питфоллы (уже известны):** `switch.sauna`/`recirculation_pump` в `unknown` — розетки физически отключены, не баг; управление таким реле «вслепую» вернёт ошибку.
**Zigbee2MQTT:** запущен (`45df7312_zigbee2mqtt`, v2.14.1-1, `started`), ingress-порт `8099` (наружу не выпущен), конфиг — не в `/addon_configs/45df7312_zigbee2mqtt/` (папка пуста; искать в data-каталоге аддона).
---
@@ -2468,7 +2557,7 @@ uvcvideo 2-1:1.1: Failed to resubmit video URB (-1) ← в dmesg
**Камера ustreamer (2026-09-14 вечер-11):** `~/tmp-ustreamer/` на Mac — `config.yaml`, `Dockerfile`, `run.sh` (**исходники аддона**, копируются в `/addons/ustreamer/` на t610), `rm-cam.sh` (снос ffmpeg-блока), `cam-flow.sh` / `cam-submit.sh` / `cam-confirm.sh` (Generic Camera flow, REST), `cam-check.sh` / `cam-frame.sh` (проверка состояния и кадра), `ws-check.py` / `ws-area.py` / `ws-rename.py` (websocket: реестр, зона, имя). Токен — `/tmp/.hatok` (Mac + t610), **читается через `read -r`** (см. обход маскировщика в §5-кватер-И-5).
**На t610 (аддон):** `/addons/ustreamer/{config.yaml,Dockerfile,run.sh}` (chmod 600). Аддон-слаг `local_ustreamer`.
**Бэкап конфига:** `/config/configuration.yaml.bak-rmcam-20260914-185240` (перед сносом ffmpeg-блока).
> ⚠️ **ОБНОВЛЕНО (вечер-12):** `/config/go2rtc.yaml` **НЕ удалять** — он **нужен аддону `go2rtc`** (AlexxIT), который читает именно этот файл. Прежняя пометка «создан по ошибке, HA его не читает» верна **только для встроенного go2rtc HA Core** (тот генерирует свой `/tmp/go2rtc_XXXX.yaml` и игнорирует `/config/`). Актуальный конфиг: `streams: usb_camera: v4l2:device?video=/dev/video0&input_format=mjpeg&video_size=640x480` — см. §5-кватер-И-6.
> ⚠️ **ОБНОВЛЕНО (вечер-13):** `/config/go2rtc.yaml` **НЕ удалять** — он **нужен аддону `go2rtc-hardware`** (AlexxIT), который читает именно этот файл. Прежняя пометка «создан по ошибке, HA его не читает» верна **только для встроенного go2rtc HA Core** (тот генерирует свой `/tmp/go2rtc_XXXX.yaml` и игнорирует `/config/`). **Актуальный конфиг (вечер-13):** `streams: usb_camera_h264: ffmpeg:device?video=/dev/video0&input_format=mjpeg&video_size=640x480#video=h264` — см. §5-кватер-И-6.
**Диагностика modbus (2026-09-14 позднейшая, второй заход):** `~/tmp-t610/``mb_backup.sh` (бэкап опций+конфига), `mb_fix_opts.sh` (правка опций — СЛОМАЛ mbusd), `mb_rollback.sh` (откат), `mb_dump_t610.sh`, `mb_stress.sh` (30 запросов — артефакт), `mb_master_test.sh` (`ha core stop` — повис), `mb_bus_check.sh`, `mb_bus_listen.sh`, `mb_whotraffic.sh`, `mb_bus2.sh`, `mb_bridge_check.sh`, `mb_zont.sh`, `mb_zont2.sh`, `mb_zont3.sh`, `mb_zont_now.sh`, `mb_after_zont.sh`, `mb_who.sh`.
> 🔴 **Урок по скриптам:** сырой замер шины (`cat /dev/ttyUSB*` + `nc`) **пока HA/mbusd опрашивают ту же шину — портит замер и мешает работе**. Плюс `cat /dev/ttyUSB0` при работающем `modbus-bridge` **всегда пусто** (bridge держит порт). Единственный чистый метод привязки — **физический: выдернуть шнур + `dmesg`**.
> ⚠️ Секреты в скриптах — только через обходных путей из §8 (маскировщик ломает литералы). Здесь секретов нет, использовался готовый `/tmp/curl.auth`.