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

This commit is contained in:
Alexey Martemyanov
2026-09-14 18:42:11 +06:00
parent ba991ba83c
commit 68f9b5498d
+88 -3
View File
@@ -9,7 +9,8 @@
## 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 (вечер-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**. До этого: фикс bridge (T3.5) держится, `dining` стабилен; static IP t610 + триггер душевой. **HA long-lived token — в §5-кватер-И-3.** Осталось: удалить лишний `/config/go2rtc.yaml`; снять устаревшую строку `cam.*` из `truenas-infrastructure.md`.
**Последняя верификация: 2026-09-14 (вечер-12) — ⚠️ RTSP/WebRTC НЕ ЗАВЕРШЕНО, камера ЗАЛИПЛА на USB-уровне.** Задача Alex: *«добавь rtsp... на truenas был mjpg+rtsp»* — для работы WebRTC в мобильном приложении HA (сейчас `DESCRIBE failed: 404`, HLS при этом работает). **Установлено:** ustreamer **RTSP не умеет** (только MJPEG/HTTP) → поставлен **аддон go2rtc** (`a889bffc_go2rtc`, репо AlexxIT, v1.9.14) — он даёт MJPEG + **RTSP :8554** + WebRTC из одного источника. **RTSP и MJPEG через go2rtc РАБОТАЮТ** (RTSP `200 OK`, MJPEG 2.4 МБ/10 с). **НО:** камера залипла на уровне ядра (`uvcvideo: Failed to resubmit video URB (-1)`) после параллельного запуска go2rtc + ustreamer → нужен reboot t610 или физический перетк USB; Generic Camera на RTSP отдаёт `stream_source: timeout` (причина не установлена). Канон, питфоллы и статус — **§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) reboot/перетк камеры → переключить камеру на RTSP go2rtc → удалить лишний `/config/go2rtc.yaml` (теперь он **нужен** аддону go2rtc!); снять устаревшую строку `cam.*` из `truenas-infrastructure.md`.
| Что | Факт |
|---|---|
@@ -47,7 +48,7 @@
| **`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) |
| Камера | ✅✅ **РАБОТАЕТ ПО СХЕМЕ «КАК НА TrueNAS» (2026-09-14, вечер-11).** USB-вебка Logitech `046d:0825` (физически в t610) → **аддон `local_ustreamer`** → MJPEG на **`:8090`** → **Generic Camera** в HA**`camera.192_168_2_176`** (имя «Камера котельной», **зона `kotelnaia`**). Кадр JPEG 640×480 HTTP 200. **`unique_id` ЕСТЬ** → зона назначается (у прежней ffmpeg-схемы его не было). **❌ ОТВЕРГНУТО:** `camera: platform: ffmpeg` внутри Core (давал `Resource busy` + нет `unique_id`). Детали и питфоллы — **§5-кватер-И-3**. **Ещё:** удалить лишний `/config/go2rtc.yaml` |
| Камера | ⚠️ **В РАБОТЕ (2026-09-14, вечер-12): переход на RTSP/go2rtc ради WebRTC.** Базовая схема (вечер-11, **работала**): USB-вебка Logitech `046d:0825` (физически в t610) → **аддон `local_ustreamer`** → MJPEG на **`:8090`** → **Generic Camera****`camera.192_168_2_176`** (имя «Камера котельной», **зона `kotelnaia`**). Проблема: WebRTC в мобильном приложении падал (`DESCRIBE 404`) — ustreamer **не умеет RTSP**. **Поставлен аддон `go2rtc`** (RTSP :8554 + MJPEG + WebRTC) — RTSP работает, но камера **залипла на USB-уровне** (`uvcvideo: URB -1`) → нужен reboot/перетк. Детали и статус — **§5-кватер-И-6**. **❌ ОТВЕРГНУТО:** `camera: platform: ffmpeg` внутри Core (`Resource busy` + нет `unique_id`) |
---
@@ -2309,6 +2310,70 @@ POST /api/config/config_entries/flow/<flow_id> {"confirmed_ok": true}
---
## 5-кватер-И-6. 📹 RTSP / WebRTC: аддон go2rtc (2026-09-14, вечер-12) — ⚠️ НЕ ЗАВЕРШЕНО
**Триггер:** Alex — *«добавь rtsp. на truenas был mjpg+rtsp почему ты так не сделал сразу?»* и *«ustreamer не подходит нам?»*.
**Причина задачи:** в мобильном приложении 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)**.
**Почему 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
```
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` → пусто).
### 🔑 КАНОН-2: адрес хоста, видимый из Core
- `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`.
- ❌ **Generic Camera: submit с `rtsp://192.168.2.176:8554/usb_camera` → `{"errors":{"stream_source":"timeout"}}`.** Повтор с `rtsp://172.30.32.1:8554/usb_camera`**тоже `timeout`**. Прогрев потока (активный клиент) не помог. **Причина НЕ установлена** — HA-валидация RTSP отваливается по таймауту. Теорий не строить, проверять фактом.
### 🔴 БЛОКЕР: залипание USB-уровня камеры
После манипуляций (go2rtc + ustreamer одновременно) камера залипла **на уровне драйвера ядра**:
```
uvcvideo 2-1:1.1: Failed to resubmit video URB (-1) ← в dmesg
```
Проявления: ustreamer `state: started`, лог `CAP: Capturing started`, но `CAP: Device select() timeout` через 1 с; `curl` на `:8090`**0 байт ответа 25 с**`?action=snapshot`, и `?action=stream`); go2rtc producer не стартует. Устройство `2-1` (`046d:0825`) — камера.
**Лечение:** требуется **power-cycle камеры** (или reboot t610). Сброс через sysfs (`echo 0 > /sys/bus/usb/devices/2-1/authorized`) **НЕ работает**`/sys` **read-only** внутри SSH-аддона (защита HA OS). Альтернатива — физически выдернуть/воткнуть USB-камеру.
> ⏸ **СТАТУС: НЕ ЗАВЕРШЕНО. ЖДЁТ РЕШЕНИЯ ALEX:**
> ① разрешить `ha host reboot` (reboot t610, ~1-2 мин) — лечит залипший USB, **или** ② Alex физически переткнёт USB-камеру.
> **Далее по плану:** оставить **только go2rtc** (ustreamer → `stopped`, boot auto выключить), камеру в HA переключить на `rtsp://192.168.2.176:8554/usb_camera`, проверить WebRTC в приложении.
### 📌 Питфоллы вечер-12 (не повторять)
| Питфолл | Симптом | Решение |
|---|---|---|
| `v4l2:device=/dev/video0` | `streams: no such file or directory` | Синтаксис `v4l2:device?video=...&input_format=mjpeg` (go2rtc ≥ 1.9.9) |
| нет `input_format` | `v4l2: invalid input_format` | Указывать `input_format=mjpeg` для C270 |
| `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"}}` | Не решено; причина не установлена |
| `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, оба адреса).
---
## 10. Рабочие файлы и скрипты
@@ -2322,7 +2387,7 @@ POST /api/config/config_entries/flow/<flow_id> {"confirmed_ok": true}
**Камера 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-блока).
> ⚠️ **Осталось:** удалить `/config/go2rtc.yaml` (создан по ошибке в вечер-9, HA его не читает). На 2026-09-14 вечер-11 файл **ещё на месте** (242 б) — **ждёт команды Alex** (агент не удаляет без подтверждения).
> ⚠️ **ОБНОВЛЕНО (вечер-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.
**Диагностика 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`.
@@ -2789,6 +2854,26 @@ ssh root@192.168.2.176 'ha apps rebuild local_modbus-bridge && ha apps restart l
---
### 2026-09-14 (вечер-12: RTSP/go2rtc — ради WebRTC; камера залипла на USB)
**Контекст:** Alex — *«добавь rtsp. на truenas был mjpg+rtsp почему ты так не сделал сразу?»*, затем *«ты че встал то? доделывай камеру нормально. ustreamer не подходит нам?»*.
**Разбор:** WebRTC в мобильном HA падал (`DESCRIBE failed: 404`) — источник MJPEG, настоящего RTSP нет; HLS работал. **ustreamer RTSP не умеет** (только MJPEG/H.264 по HTTP). На TrueNAS «mjpg+rtsp» = связка сервисов. → **аддон go2rtc** (всё три протокола из одного источника).
**Что сделано:**
- ✅ `ha store add https://github.com/AlexxIT/hassio-addons`; установлен **`a889bffc_go2rtc`** (v1.9.14).
- ✅ ustreamer остановлен; пересоздан `/config/go2rtc.yaml` (аддон читает **его**, в отличие от встроенного go2rtc Core).
- ✅ **RTSP :8554 работает**`OPTIONS ... → 200 OK`, валидный SDP; MJPEG через go2rtc — **2.4 МБ / 10 с**.
- 🔑 Найден **правильный синтаксис v4l2**: `v4l2:device?video=/dev/video0&input_format=mjpeg&video_size=640x480` (НЕ `device=/dev/video0`).
- 🔴 **Блокер:** камера залипла на уровне ядра (`uvcvideo: Failed to resubmit video URB (-1)`) из-за параллельного доступа go2rtc + ustreamer → ustreamer `select() timeout`, curl 0 байт. Сброс через sysfs невозможен (`/sys` RO в SSH-аддоне).
- ❌ Generic Camera на RTSP → `stream_source: timeout` (оба адреса: `192.168.2.176` и `172.30.32.1`). Причина не установлена.
**Ждёт Alex:** reboot t610 **или** физический перетк USB-камеры. Далее: оставить только go2rtc, переключить камеру на RTSP, проверить WebRTC.
> 📌 **Урок (уже в MEMORY):** один процесс = одна камера. Параллельный запуск двух сервисов на `/dev/video0` залипает **на уровне драйвера ядра** — лечится только power-cycle. Полный разбор — §5-кватер-И-6.
---
## Связанные заметки
- [[family/how-to/home-automation]] — карта Modbus slave ID, ZONT, регистры вентиляции