[2026-09-15] eagle: family/how-to/home-automation.md
This commit is contained in:
@@ -26,16 +26,20 @@ updated: 2026-09-15
|
||||
|
||||
### Топология
|
||||
|
||||
```
|
||||
```text
|
||||
Caddy ──▶ HP t610 · HA OS · 192.168.2.176
|
||||
mallexxx.duckdns.org │
|
||||
│ USB
|
||||
┌──────────────────────┼──────────────────────┐
|
||||
[USB1-3] CH340 [USB1-4] CH340 [USB3-1] Inswift
|
||||
mbusd modbus-bridge Zigbee ZBP-MG21
|
||||
→ шина ВЕНТИЛЯЦИИ → шина ZONT 485 → zigbee2mqtt (ttyACM0)
|
||||
[USB1-2] Inswift [USB1-3] CH340 [USB1-4] CH340
|
||||
Zigbee ZBP-MG21 mbusd modbus-bridge
|
||||
→ zigbee2mqtt → шина ВЕНТИЛЯЦИИ → шина ZONT 485
|
||||
(ttyACM0) (ttyUSB0) (ttyUSB1)
|
||||
└── [USB3-1] Logitech 046d:0825 (камера) — ТОЛЬКО xHCI!
|
||||
```
|
||||
|
||||
> 🔴 **Камера обязана сидеть на xHCI (`USB3-1`), Zigbee — на OHCI (`USB1-2`).** См. §3.1 — почему.
|
||||
|
||||
---
|
||||
|
||||
## 2. ⚡ Команды без апрува — использовать ТОЛЬКО это
|
||||
@@ -137,11 +141,62 @@ ha apps restart local_modbus-bridge
|
||||
|---|---|---|---|
|
||||
| CH340 #1 | `pci-0000:00:12.0-usb-0:3:1.0-port0` | ttyUSB0 | USB1-**3** (вентиляция/mbusd) |
|
||||
| CH340 #2 | `pci-0000:00:12.0-usb-0:4:1.0-port0` | ttyUSB1 | USB1-**4** (ZONT/modbus-bridge) |
|
||||
| Inswift ZBP-MG21 | `usb-Inswift_Zigbee_ZBP-MG21_535A000001-if00` | ttyACM0 | USB3-1 (Zigbee) |
|
||||
| Inswift ZBP-MG21 | `usb-Inswift_Zigbee_ZBP-MG21_535A000001-if00` | ttyACM0 | USB1-**2** (Zigbee) — ⚠️ было USB3-1 |
|
||||
| Logitech 046d:0825 | `usb-046d_0825_505CE330-video-index0/1` | video0/1 | USB**3-1** (камера) — ⚠️ было USB2-1 |
|
||||
|
||||
> ⚠️ Два CH340 **без серийников** → by-id идентичен. Только **by-path**.
|
||||
> `uart: true` в конфиге аддона — udev-алиасы не нужны. В аддоне нет `udevadm`, `/etc/udev/rules.d`.
|
||||
|
||||
### 3.1. 🔴 КАНОН: камера — ТОЛЬКО на xHCI-порту (USB3-1). Иначе RCU stall + смерть хоста
|
||||
|
||||
**Симптом (2026-09-15):** хост t610 перестаёт отвечать по сети и в HA-веб (`192.168.2.176:8123` timeout, ARP no entry, ping 100% loss). В консоли/по UART — лавина:
|
||||
```
|
||||
rcu: rcu_preempt kthread starved for 981401 jiffies! g2228457 f0x2 RCU_GP_WAIT_FQS(5) ->state=0x0 ->cpu=1
|
||||
rcu: INFO: rcu_preempt detected stalls on CPUs/tasks:
|
||||
rcu: 0-...0: (188 ticks this GP) idle=73a4/1/0x4000000068ed2b48 softirq=1212952/1212953 fqs=35918
|
||||
rcu: (detected by 1, t=1155092 jiffies, g=2228457, q=172 ncpus=2)
|
||||
rcu: Unless rcu_preempt kthread gets sufficient CPU time, OOM is now expected behavior.
|
||||
```
|
||||
⚠️ **Строка «OOM is now expected behavior» — НЕ диагноз OOM.** Это стандартное предупреждение ядра о голодании kthread. Память тут ни при чём.
|
||||
|
||||
**Причина:** Logitech `046d:0825` (C270), воткнутая в **USB2/EHCI**-порт, уходила в **reset-loop**: ДО перестановки `usb 2-1: reset high-speed USB device number 2 using ehci-pci` каждые ~7 с (t=133 и t=140).
|
||||
- `bMaxPower = 500mA`, `speed = 480` — камера просит весь лимит порта.
|
||||
- На EHCI `power/control = auto` усыплял камеру: `runtime_suspended_time = 123923` (124 с в suspend) → пробуждение ломается → reset.
|
||||
- Каждый reset = пересборка драйвера `uvcvideo` в **hardirq** — вне cgroup, вне планировщика. Одно ядро занято прерываниями, RCU grace period не завершается → stall.
|
||||
|
||||
**Почему 2 ядра не спасают:** нагрузка не вычислительная, а прерыванийная. RCU grace period требует прохождения quiescent state на **ВСЕХ** CPU; залипло одно — второй тоже не может прогрессировать, и htop показывает 100% на обоих. Контейнерные лимиты бесполезны: hardirq обрабатывается ядром.
|
||||
|
||||
**Фикс (сработал, проверено фактом):**
|
||||
|
||||
| | До | После |
|
||||
|---|---|---|
|
||||
| Камера | `Bus 002` (EHCI, USB2-1) | `Bus 003` (xHCI, USB**3**-1) |
|
||||
| Zigbee | `Bus 003` (xHCI) | `Bus 001` (OHCI, USB1-2) |
|
||||
| Load avg | 4.47 | **0.76** |
|
||||
| CPU idle | 0% (iowait 90% → 10%) | **100%** |
|
||||
| Reset USB | каждые 7 с | **0** |
|
||||
|
||||
Диагностический признак перестановки успешной: `runtime_suspended_time = 0` на новом порту (против 123923 на старом) — на xHCI камера вообще не засыпает.
|
||||
|
||||
**Диагностика при «HA не отвечает» — порядок:**
|
||||
1. Пинг + ARP хоста (`/sbin/ping`, `/usr/sbin/arp -an`) — жив ли вообще. `ARP no entry` = L2-ответа нет.
|
||||
2. Если не отвечает — питание. Если отвечает — `ssh root@192.168.2.176`.
|
||||
3. `uptime` + `top -b -n 1 | head -5` — смотреть **`% io` и `% sirq`**, не только usr/sys.
|
||||
4. `dmesg | grep -iE "usb|reset"` — вся причина обычно здесь.
|
||||
5. `/sys/bus/usb/devices/<port>/power/runtime_suspended_time` — растёт = устройство засыпает и не просыпается.
|
||||
|
||||
> ⚠️ На t610 **BusyBox**, не GNU coreutils: нет `ping`/`arp`/`netstat`/`ifconfig` в PATH Mac-стороны (на Mac звать `/sbin/ping`, `/usr/sbin/arp`); **на t610** нет `dmesg -T`, `top -b -n1` есть, `fuser -v` НЕТ (`fuser -m` только), `ps -eo` работает, `cat /proc/interrupts` может быть пуст (не поломка). `lsusb -t` — есть.
|
||||
|
||||
### 3.2. Перезапуск Zigbee2MQTT после перестановки USB
|
||||
|
||||
Z2M **не переподключается сам**: в логе `Adapter disconnected, stopping` + `(restart=false, code=2)` — аддон остаётся в состоянии `error`.
|
||||
```bash
|
||||
ha addons 2>/dev/null | grep -E "^ (name|slug|state):" | paste - - - # быстрый скан статусов
|
||||
ha addons logs 45df7312_zigbee2mqtt 2>/dev/null | tail -25 # причина
|
||||
ha apps restart 45df7312_zigbee2mqtt # поднять
|
||||
```
|
||||
> 💡 `ha addons logs <slug>` в этой сессии **отработал** (вопреки питфоллу №8 про старый буфер) — годится как первый заход, но для верности сверять с `GET /api/hassio/addons/<slug>/logs`.
|
||||
|
||||
### Температура CPU
|
||||
|
||||
```bash
|
||||
@@ -198,6 +253,7 @@ IEEE-адреса — источник истины `/config/zigbee2mqtt/configu
|
||||
**Logitech `046d:0825`** (счётчик газа BK-G4T), отдаёт только MJPEG. Схема: аддон `a889bffc_go2rtc-hardware` → транскод MJPEG→H.264 → RTSP `rtsp://192.168.2.176:8554/usb_camera_h264` → HA Generic Camera `camera.192_168_2_176` (зона `kotelnaia`, `rtsp_transport: tcp`).
|
||||
Поворот: `#rotate=90` в `ffmpeg:`-строке `/config/go2rtc.yaml` → поток `480x640`.
|
||||
> ⚠️ **Камера = ОДИН процесс.** ustreamer + go2rtc вместе → залипание USB, лечится power-cycle. `local_ustreamer` → `boot: manual`, `stopped` (для отката).
|
||||
> 🔴 **Камера — ТОЛЬКО в USB3-порт (xHCI).** На USB2/EHCI уходит в reset-loop и валит хост в RCU stall — см. §3.1. Пины `go2rtc` и `go2rtc-hardware` оба `started`, это норма (два разных потока одной камеры), но при шторме смотреть в первую очередь на них.
|
||||
|
||||
### ZONT / MQTT-маршрутизация
|
||||
|
||||
|
||||
Reference in New Issue
Block a user