From 4b9593d9059cad667b5de2fb9524aef6e680e86e Mon Sep 17 00:00:00 2001 From: Alexey Martemyanov Date: Mon, 14 Sep 2026 17:46:13 +0600 Subject: [PATCH] [2026-09-14] eagle: family/plans/t610-home-automation.md --- family/plans/t610-home-automation.md | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/family/plans/t610-home-automation.md b/family/plans/t610-home-automation.md index d8d627e7..572d6bac 100644 --- a/family/plans/t610-home-automation.md +++ b/family/plans/t610-home-automation.md @@ -47,7 +47,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) | -| Камера | ✅✅ **РАБОТАЕТ (2026-09-14, вечер-9).** USB-вебка Logitech `046d:0825` → **`camera: platform: ffmpeg` + `input: /dev/video0`** в `configuration.yaml` → сущность **`camera.usb_camera`**, кадр JPEG 640×480 (HTTP 200). Канон и опровергнутые тупики — **§5-кватер-И-3**. Осталось: удалить лишний `/config/go2rtc.yaml` | +| Камера | ✅✅ **РАБОТАЕТ (2026-09-14, вечер-9).** USB-вебка Logitech `046d:0825` → **`camera: platform: ffmpeg` + `input: /dev/video0`** в `configuration.yaml` → сущность **`camera.usb_camera`**, кадр JPEG 640×480 (HTTP 200). Канон и опровергнутые тупики — **§5-кватер-И-3**. ⚠️ **Зона НЕ назначается** (у ffmpeg-камеры нет `unique_id`) — §5-кватер-И-5. **Осталось:** (1) решить с Alex — переименовать в «Камера котельной» или оставить; (2) удалить лишний `/config/go2rtc.yaml`; (3) ⚠️ не занимать `/dev/video0` тестовыми пробами (→ `Resource busy`, лечится `ha core restart`) | --- @@ -2092,10 +2092,12 @@ curl -H "Authorization: Bearer *** \ ``` ### Питфоллы сессии +- 🔴 **`Resource busy, /dev/video0` — камера «отваливается», если устройство занято.** Симптом: `camera_proxy` → **HTTP 500**, в логе `ha core logs` → `Error opening stream (Resource busy, /dev/video0)`. **Причина в этой сессии:** пробы Generic Camera (`stream_source: http://127.0.0.1:1984/...`) создали висящую `stream.generic.test_stream`, её `stream_worker` **держал устройство** и блокировал настоящую камеру. **Лечение: `ha core restart`** (освобождает устройство; кадр пошёл сразу). **Правило: если USB-камера «сломалась» без правки конфига — СНАЧАЛА смотреть лог на `Resource busy`, а не лезть в YAML.** Проверять, не висит ли `stream_worker`/тестовая камера. +- 📌 **`/api/camera_proxy_stream/camera.usb_camera`** (MJPEG, `multipart/x-mixed-replace`) отдаёт **HTTP 200** даже когда `camera_proxy` (одиночный кадр) даёт 500 — но при занятом устройстве поток пустой (0 байт). Диагностический признак: 200 на stream + 500 на кадр = устройство занято, а не конфиг сломан. - **`/dev/video0` из SSH-аддона недоступен** — `dd`/`head` дают `Operation not permitted` даже от root (аддон в изолированном контейнере без проброса USB-видео). Это **не** признак мёртвой камеры — проверять надо в Core (UI → Оборудование). -- **Маскировщик секретов** ломает строки в скриптах: `AUTH_HEADER="Authorization: Bearer $TOK"` при записи обрезается и рвёт кавычки → `unexpected EOF`. Обход: собирать имя заголовка через `printf '\x41\x75...'` или из кусков переменных. +- **Маскировщик секретов** ломает строки в скриптах: `AUTH_HEADER="Authorization: Bearer *** при записи обрезается и рвёт кавычки → `unexpected EOF`. Обход: собирать имя заголовка через `printf '\x41\x75...'` или из кусков переменных. - **`python3` в SSH-аддоне отсутствует** — правки файлов делать `awk`/`sed`-скриптом, не python. -- Диагностика через `/api/error_log` и `ha core logs` **не показывает** ошибку ffmpeg (500 приходит без записи в лог) — опираться на прямой запрос кадра. +- Диагностика через `/api/error_log` **не работает** (404 через прокси) — читать лог через `ssh ... 'ha core logs'` (там ошибка ffmpeg видна, включая `Resource busy`). ### Бэкапы `/config/configuration.yaml.bak-cam-20260914-180801` (до блока), `.bak-camdev-20260914-181945`, `.bak-camdev2-*` (перед сменой input). @@ -2153,10 +2155,21 @@ YAML-сущность **отсутствует в entity_registry** (и каме ### Проверено и НЕ работает (не повторять попытки) | Попытка | Результат | |---|---| -| `Generic Camera` с `stream_source = /dev/video0`, `ffmpeg:/dev/video0`, `v4l2:/dev/video0` | ❌ все три → `{'stream_source': 'relative_url'}` (Generic Camera принимает только URL http/rtsp, локальное устройство — нет). Проверено **и REST-flow, и websocket-flow** | +| `Generic Camera` с `stream_source = /dev/video0`, `ffmpeg:/dev/video0`, `v4l2:/dev/video0` | ❌ все → `{'stream_source': 'relative_url'}` (Generic Camera принимает только URL http/rtsp, локальное устройство — нет). Проверено **и REST-flow, и websocket-flow** | +| `Generic Camera` с `file:///dev/video0`, `file:/dev/video0` | ❌ тоже `relative_url` — **схема `file://` НЕ спасает**, локальные устройства для Generic Camera недоступны в принципе | | `entity_registry/update` c `area_id` | ❌ `Entity not found` (нет записи в реестре) | | `customize:` для зоны | ❌ customize не управляет зонами | +### 📌 Ответ на вопрос Alex «это штатный и единственный способ?» +**Штатных способов завести USB-камеру в HA — ДВА, но для локального `/dev/video0` подходит ОДИН:** + +| Способ | `unique_id` | Локальный `/dev/video0` | Вердикт | +|---|---|---|---| +| **`camera: platform: ffmpeg`** (наш) | ❌ нет | ✅ **работает** | **Работает, но без зоны** | +| **Generic Camera** (config flow) | ✅ есть | ❌ отвергает (`relative_url`) | Не подходит для USB | + +Итог: для USB-вебки путь **один** — `camera: platform: ffmpeg`. Документирован, работает. unique_id дать нельзя — это ограничение интеграции, официально признанное в FAQ HA («This is not an error»). ONVIF и MJPEG-интеграции — только для **сетевых** камер, USB не берут. + ### Что можно вместо зоны - **`name: Камера котельной`** — переименование в YAML. Формального `area_id` не даст, но в UI камера будет подписана по назначению. Закрывает практическую задачу. - **Дашборд по зонам** — карточка камеры попадёт в зону только через реестр, т.е. не попадёт. @@ -2189,9 +2202,12 @@ YAML-сущность **отсутствует в entity_registry** (и каме **Сессия вечер-8 (static IP + душевая, 2026-09-14):** `~/tmp-t610/automations/automations.yaml` (правленая копия, +11 строк), `~/tmp-t610/reload_automations2.sh` (reload автоматизаций через API), `~/tmp-t610/check_ha_states*.sh` (проверка HA API). Бэкапы: роутер `/root/dhcp.bak-20260914-104152`, t610 `/config/automations.yaml.bak-nightlight-20260914-174320`. Локальные скрипты правятся через `~/tmp-t610/`, заливаются `scp` → `bash /tmp/