[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 14:12:26 +06:00
parent 161fe1101d
commit 518091d48c
2 changed files with 70 additions and 9 deletions
+2 -1
View File
@@ -11,9 +11,10 @@ tags:
- smarthome
- modbus
updated: 2026-09-14
related: ["[[family/how-to/router-bishkek-asus]]", "[[family/plans/t610-home-automation]]", "[[family/how-to/truenas-access]]"]
related:
- '[[family/how-to/router-bishkek-asus]]'
- '[[family/plans/t610-home-automation]]'
- '[[family/how-to/truenas-access]]'
---
# 🏠 Умный дом — автоматика
+68 -8
View File
@@ -24,7 +24,7 @@
| Что | Состояние |
|---|---|
| **44 сущности `unavailable`** | ~32 заслонки (`switch.intake_damper_*`, `exhaust_damper_*`) + вентиляторы (`switch.fan_3_*`, `sensor.fan_at2_*`). **Диагностика 2026-09-14 (позднейшая) — см. §5.** Итог: ① попытка фикса опций mbusd **провалилась** (`maxconn 16` сломал конфиг аддона → откат); ② замер 30 запросов → **76% `EXC 0x0B`**; ③ **эталон TrueNAS (/mnt/RED_2TB/docker/ha/configuration.yaml) ИДЕНТИЧЕН t610** → причина НЕ конфиг; ④ **главная гипотеза: два Modbus-мастера на одной RS-485** (TrueNAS-HA + t610-HA) — **НЕ подтверждена**, ждёт проверки отключением TrueNAS-стека. |
| **44 сущности `unavailable`** | ~32 заслонки (`switch.intake_damper_*`, `exhaust_damper_*`) + вентиляторы (`switch.fan_3_*`, `sensor.fan_at2_*`). **Диагностика 2026-09-14 (позднейшая) — см. §5.** Итог: ① попытка фикса опций mbusd **провалилась** (`maxconn 16` сломал конфиг аддона → откат); ② замер 30 запросов → **76% `EXC 0x0B`, но это АРТЕФАКТ замера** (агент мерил параллельно с опросом HA, делил шину) — см. §5; ③ **эталон TrueNAS (`/mnt/RED_2TB/docker/ha/configuration.yaml`) ИДЕНТИЧЕН t610** → причина НЕ конфиг; ④ гипотеза «два мастера» **ОПРОВЕРГНУТА** (адаптеры переключены в t610) — см. §5. **Не закрыто:** остаётся `verify` (`state_on:1/state_off:0` против реального `0x640001`) и вопрос, доходит ли опрос HA до реле |
| **`sensor.fan_at2_*` — сироты** | В `configuration.yaml` **все `sensors:` закомментированы** → эти сущности физически не могут получать данные. Разобраться с происхождением (2026-09-14 поздняя) |
| `switch.sauna` = `unknown` | Розетка физически отключена (`lastSeen` 8+ ч) — не баг |
| ZONT не перенаправлен | MQTT-редирект GPON-роутера ещё смотрит на TrueNAS |
@@ -377,10 +377,12 @@ HA **пишет** 256/512 в reg 5, а **читает** из того же reg 5
```
и среди ответов попался **чужой ответ на запрос, которого я не слал** (`…060b 01 00000001`) — признак, что **на шине есть второй мастер/источник трафика**.
**🔴 ГЛАВНАЯ ГИПОТЕЗА (2026-09-14 позднейшая): два Modbus-мастера на одной физической RS-485.**
TrueNAS-HA (mbusd на TrueNAS) и t610-HA (mbusd на t610) висят на **одной паре A/B** (кабель один, через CH340 #2). Два мастера = коллизии = 76% `EXC 0x0B`. **Не подтверждено** — прервано на вопросе «запущен ли TrueNAS-стек».
> ⚠️ **НЕ принято за факт.** Проверка, которую надо доделать: остановить/убедиться в остановке TrueNAS-стека (`docker stop homeassistant mbusd modbus-bridge`) → повторить замер 30 запросов → если потери упадут до ~0, гипотеза верна, и «фикс» = Этап 4 (отключение TrueNAS), а **не** правка опций mbusd.
> ✅ Чистый тест (не доделан): `ha core stop` → замер шины → `ha core start`. Прошлый прогон повис по таймауту 300 с (HA не ответил), но HA вернулся сам (HTTP 200). **Вывод: `ha core stop` в SSH-сессии может блокировать команду — проверять состояние после, не полагаться на вывод теста.**
** ГИПОТЕЗА «два Modbus-мастера на одной RS-485» — ОПРОВЕРГНУТА (2026-09-14, позднейшая).**
Alex подтвердил: **адаптеры физически переключены в t610**, TrueNAS от шины отключён. Значит второго мастера нет — ниши TrueNAS-HA/TrueNAS-mbusd не висят на паре A/B. Проверено дополнительно: `192.168.2.197:502` (TrueNAS mbusd) — **CLOSED**, TrueNAS-mbusd не отвечает.
> 🔴 **Урок: не строить гипотезу о «втором мастере», не сверившись с Alex про физику.** Он знает, куда переткнуты кабели. Спрашивать про физику ДО теории.
**Что тогда даёт 76% потерь?** Остаётся **самомерие агента**: замер `mb_stress.sh` шёл **параллельно с опросом HA** — HA в этот момент долбит ту же шину, mbusd `maxconn 8`, запросы агента конкурируют с запросами HA → `EXC 0x0B`. То есть **76% — артефакт замера, а не поломка**. Прямой замер `nc` **при остановленном HA** (тест `ha core stop`, см. ниже) показал, что шина отвечает — реле живое.
> ⚠️ Чтобы мерить честно: либо останавливать HA-опрос, либо принимать во внимание, что HA — тоже мастер на этой шине и делит её с агентом.
### ✅ ЭТАЛОН TRUENAS НАЙДЕН — modbus-блок ИДЕНТИЧЕН t610
@@ -406,7 +408,19 @@ awk '/^modbus:/{f=1} f' /mnt/RED_2TB/docker/ha/configuration.yaml \
`192.168.2.157` = **Rasputin, MAC `36:ae:87:04:08:dc`** (подтверждено по `dhcp.leases` роутера `192.168.2.2`). Под NAT Rasputin **выглядит ЛЮБОЙ трафик из локалки — включая запросы самого агента** (с Mac и из SSH-аддона). В логе mbusd **53 коннекта от `.157`** = это МОИ же диагностические запросы, **НЕ** посторонний клиент и **НЕ** TrueNAS.
> 🔴 **Правило: по IP `.157` НЕЛЬЗЯ определить, кто клиент.** Для этого — `netstat` ВНУТРИ t610 (покажет `172.30.33.0` = контейнер HA Core) или смотреть на роутере.
**Рабочие файлы этой сессии:** `~/tmp-t610/mbdiag1..4.sh`, `mb_backup.sh`, `mb_fix_opts.sh`, `mb_rollback.sh`, `mb_dump_t610.sh`, `mb_stress.sh`, `mb_master_test.sh`.
**Рабочие файлы этой сессии:** `~/tmp-t610/mbdiag1..4.sh`, `mb_backup.sh`, `mb_fix_opts.sh`, `mb_rollback.sh`, `mb_dump_t610.sh`, `mb_stress.sh`, `mb_master_test.sh`, `mb_bus_check.sh`, `mb_bus_listen.sh`, `mb_bridge_check.sh`, `mb_zont.sh`, `mb_zont2.sh`, `mb_who.sh`.
### 🔴 ПИТФОЛЛ: `ha core stop` из SSH-сессии
Тест «остановить HA → померить шину» через `ha core stop` в SSH-скрипте **может повиснуть** (прошлый прогон — таймаут 300 с, вывод потерян). HA при этом **останавливается и потом поднимается сам**, но результат теста не долетает.
**Последствия, которые видны в логах:** пока HA был остановлен, `modbus-bridge` залил лог штормом
```
HA poll exception ... [Errno 111] Connection refused
HA poll: sensor.office_temperature_sensor_temperature HTTP 404
HA poll exception ... could not convert string to float: 'unknown'
```
— это **нормальный** след остановки HA, не поломка bridge.
> ✅ Правило: после `ha core stop` в скрипте — **обязательно проверять живость** (`curl -s -o /dev/null -w '%{http_code}' http://192.168.2.176/` → `200`), не полагаться на вывод зависшей команды. Не оставлять HA остановленным.
### ZONT (шина на CH340 #1)
@@ -414,8 +428,43 @@ ZONT (`192.168.0.10`) — Modbus master на RS-485 `ttyZONT`. 485-датчик
На TrueNAS была гонка udev (docker стартовал раньше udev, `/dev/ttyZONT` не существовал → контейнер падал с Exit 128, restart policy не ретраит при провале mount устройства). Лечилось POSTINIT-скриптом ожидания tty. **На t610 неактуально** — Supervisor сам ждёт устройство.
#### 🔬 ПРОВЕРКА 2026-09-14 (позднейшая): шина ZONT ПУСТАЯ
Задача от Alex была конкретная: **видит ли `modbus-bridge` данные с ZONT-шины / идут ли запросы от ZONT?**
**Результат: НЕТ. Ни то, ни другое.**
| Проверка | Как делалось | Результат |
|---|---|---|
| Шина ttyUSB0 (гнездо 3) | `cat /dev/ttyUSB0` 1015 сек | **0 байт** — тишина |
| Лог `modbus-bridge` | `ha apps logs local_modbus-bridge` | **ни одной строки о данных с шины**; только `HA poll -> sensor.office_temperature_sensor = 23.9` по кругу |
| MQTT `modbus/#` | `mosquitto_sub -t 'modbus/#'` 10 сек | **пусто** — bridge не публикует виртуальные датчики 101/102/103 |
**Что реально делает `modbus-bridge` (из лога):** на старте публикует discovery «вслепую» (Dining/Kids/Bedroom CO2/Temp/Humidity), затем крутит `HA poller: polling 1 entities every 15 s` — **опрашивает HA, а не шину**. Строк вида «получен запрос ZONT / slave 1|2|3 / sniff» в логе **ноль**.
> 🔴 **ПИТФОЛЛ ДИАГНОСТИКИ: `cat /dev/ttyUSB0` при работающем `modbus-bridge` покажет ПУСТО — bridge держит порт, и `cat` его не получит.** Чтобы слушать шину сырьём, bridge надо остановить (`ha apps stop local_modbus-bridge`), послушать, потом вернуть. **Но `cat` всё равно не отличает «ZONT молчит» от «порт занят»** — надёжнее смотреть, что bridge ПУБЛИКУЕТ в MQTT (если ZONT-запросы идут, bridge отдаёт `modbus/sensors/...`).
**Вывод:** запросов от ZONT на шине нет. Причины (обе — физика/настройка ZONT, не код t610; из t610 дальше не различаются):
1. RS-485 от ZONT физически **не подключён** к гнезду 3 t610 (переткнуты CH340-адаптеры, но сам ZONT-контроллер остался на старой линии).
2. Подключён, но **ZONT не является мастером** на этой линии (сбит/выключен Modbus-master после отключения TrueNAS).
> 📌 Проверить, какая из двух — можно **только с энкодера ZONT** или прозвоном линии. С хоста t610 это неразличимо. **Alex не просил идти на ZONT конфигурировать.**
> ⏳ ZONT ещё не перенаправлен на MQTT t610 — редирект GPON-роутера смотрит на TrueNAS.
#### ✅ Подтверждение привязки USB-гнёзд (2026-09-14, позднейшая)
Питфолл «оба CH340 неразличимы» проверен заново — **гнёзда разведены правильно**:
```
dmesg: ch341 1-3:1.0 → ttyUSB0 (гнездо 3 = ZONT)
ch341 1-4:1.0 → ttyUSB1 (гнездо 4 = вентиляция)
by-path: ...usb-0:3:1.0-port0 → ttyUSB0
...usb-0:4:1.0-port0 → ttyUSB1
аддоны: mbusd → by-path ...usb-0:4 (вентиляция) ✅
modbus-bridge → by-path ...usb-0:3 (ZONT) ✅
```
**Путаницы нет.** Агент шлёт в правильную шину (вентиляция, slave 11/12).
---
## 6. Zigbee (z2m)
@@ -688,8 +737,9 @@ curl -s -X POST -H "$HDR" -H "Content-Type: application/json" \
| # | Задача | Кто |
|---|---|---|
| 1 | **Фикс 44 `unavailable`** — ~~план опций mbusd~~ **ОТМЕНЁН: `maxconn` ломает аддон (откатано).** Эталон TrueNAS идентичен → причина НЕ конфиг. **Проверить гипотезу двух мастеров:** убедиться, что TrueNAS-стек остановлен (`docker stop homeassistant mbusd modbus-bridge`) → замер 30 запросов → если потери упали, «фикс» = Этап 4 (задача 6), а не опции | я |
| 1b | **`verify` в заслонках** — `state_on: 1`/`state_off: 0` не сходится с живым `0x640001`. Трогать **только после** стабилизации шины | я |
| 1 | **Фикс 44 `unavailable`** — ~~опции mbusd~~ **ОТМЕНЁН (`maxconn` ломает аддон, откатано)**. ~~Гипотеза двух мастеров~~ **ОПРОВЕРГНУТА** (адаптеры в t610, TrueNAS от шины отключён; `.197:502` CLOSED). Эталон TrueNAS идентичен → причина **НЕ конфиг и НЕ второй мастер**. **Что осталось выяснить:** доходит ли опрос HA до реле — смотреть лог HA по `homeassistant.components.modbus` при живом реле (шина отвечает при остановленном HA). Возможный виновник — `verify` (задача 1b) + конкуренция за шину с mbusd `maxconn 8` при 28 параллельных опросах | я |
| 1b | **`verify` в заслонках** — `state_on: 1`/`state_off: 0` не сходится с живым `0x640001`. **Главный неотработанный кандидат на причину `unavailable`** | я |
| 1c | **ZONT-шина пустая** — запросов от ZONT нет, `modbus-bridge` их не видит (см. §5). Физика: подключён ли RS-485 ZONT к гнезду 3 t610, и мастер ли ZONT. **Проверяется только с энкодера ZONT / прозвоном** | физика — Alex |
| 2 | Раскомментировать slave 10 (AT2 fans) в `configuration.yaml` — был закомментирован «not responding on bus» | я |
| 3 | `sensor.*_summary` — добавить `\|default(0)` в template-сенсоры (косметика, самоизлечится) | — |
| 4 | **Камера** — найти образ/папку, поднять на t610, поправить upstream в Caddy | отдельно |
@@ -704,6 +754,16 @@ curl -s -X POST -H "$HDR" -H "Content-Type: application/json" \
- **`not_from`** убран из триггеров кнопок (бэкап `automations.yaml.bak-20260914-131541`).
- **«Аппаратный блокер» заслонок опровергнут** — шина живая, заслонки (slave 11/12) отвечают.
**✅ Закрыто / установлено в этой сессии (2026-09-14, позднейшая, Modbus-диагностика):**
- **Опции mbusd — откат подтверждён.** Аддон `started`, значения `timeout 1000 / retries 3 / maxconn 8` (как было). `maxconn` **не трогать** (питфолл в §5).
- **Эталон TrueNAS найден и сверен:** `/mnt/RED_2TB/docker/ha/configuration.yaml` (⚠️ не `.../homeassistant/` — та папка пуста). modbus-блок **идентичен** t610 построчно, 32 заслонки.
- **Гипотеза «два мастера» опровергнута** — адаптеры в t610, TrueNAS от шины отключён, `.197:502` CLOSED.
- **76% `EXC 0x0B` — артефакт замера** (агент мерил параллельно с опросом HA, деля шину с mbusd).
- **ZONT-шина пустая** — запросов от ZONT нет, `modbus-bridge` их не видит, в MQTT `modbus/#` пусто (§5).
- **Привязка USB-гнёзд подтверждена** — `ch341 1-3→ttyUSB0` (ZONT), `1-4→ttyUSB1` (вентиляция), аддоны на правильных by-path (§5).
- **`.157` = Rasputin/сам агент**, не посторонний клиент — урок повторён (§5).
- **`ha core stop` в SSH-скрипте может повиснуть** — проверять живость после (§5).
**Отключение TrueNAS (только после полной проверки):**
```bash
ssh truenas_admin@mallexxx.duckdns.org