From 7c1c0947f4fd5c05a66c36cc5f222cb0546d3455 Mon Sep 17 00:00:00 2001 From: Alexey Martemyanov Date: Mon, 14 Sep 2026 19:07:37 +0600 Subject: [PATCH] [2026-09-14] eagle: family/how-to/home-automation.md family/plans/t610-home-automation.md --- family/how-to/home-automation.md | 8 +- family/plans/t610-home-automation.md | 165 +++++++++++++++++++++------ 2 files changed, 134 insertions(+), 39 deletions(-) diff --git a/family/how-to/home-automation.md b/family/how-to/home-automation.md index 7adfd6a5..0244ea51 100644 --- a/family/how-to/home-automation.md +++ b/family/how-to/home-automation.md @@ -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-устройства:** `1–99` (датчики 1/2/3, AT2 = 10, relay-модули 11/12/13/14, газ-котёл вкл = **20**). +> - **Виртуальные (bridge-подстановка):** `100–247` — `100` Tuya Zigbee датчик, `101/102/103` датчики Гостиная/Детская/Спальня (рег. 100), `101:1` Socket 1. +> - **✅ Свободно:** **`104` и выше** (полностью — `104–247`); у 100/102/103 свободны только регистры ≠ 100. +> - **Занятость проверять ВСЕГДА по двум источникам:** эта карта + реальный `/addons/modbus-bridge/data/config.template.tmpl` на t610. Расхождение — признак правки мимо доки. +> - **Механика маппинга «modbus-регистр ↔ HA-сущность»** (образец для нового реле/розетки) — в шапке `modbus_ha_bridge.py` (стр. 80–104) и `config.template.yml` (стр. 118–131): блок с `source: ha` + `entity_id` (чтение) и `action: ha` + `ha_entity_id` + `ha_service_on/off` (запись). Правка только конфига — код менять не нужно. + ``` Датчики Гостиная - 1 (modbus bridge virt. sensor - 101) diff --git a/family/plans/t610-home-automation.md b/family/plans/t610-home-automation.md index 1dc2eb46..f2c1ecce 100644 --- a/family/plans/t610-home-automation.md +++ b/family/plans/t610-home-automation.md @@ -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` (стр. 118–131) есть **рабочий образец**: + +```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` (газ-котёл вкл — живое устройство!)** · `100–103` (виртуальные). + +**🎯 ВЫВОД — свободно для нового виртуального реле:** +- **`slave_id: 104`** — **полностью свободен**, чисто, продолжает ряд 100–103 → **РЕКОМЕНДОВАНО** +- `105–247` — свободны +- У 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`.