From 6a4decf977f28af3676dad24cec4ce54d0ff080a Mon Sep 17 00:00:00 2001 From: Alexey Martemyanov Date: Mon, 14 Sep 2026 14:22: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 | 12 ++++- family/plans/t610-home-automation.md | 78 ++++++++++++++++++++++------ 2 files changed, 72 insertions(+), 18 deletions(-) diff --git a/family/how-to/home-automation.md b/family/how-to/home-automation.md index 4fc3b149..29e3ca83 100644 --- a/family/how-to/home-automation.md +++ b/family/how-to/home-automation.md @@ -22,7 +22,17 @@ related: > > Карты Slave ID и регистров ниже **остаются в силе** — оборудование и адреса Modbus не меняются. > -> ⚠️ **Про 44 `unavailable` заслонок на t610:** конфиг `modbus:` на t610 **построчно ИДЕНТИЧЕН** эталону TrueNAS (`/mnt/RED_2TB/docker/ha/configuration.yaml`) — сверено 2026-09-14. Значит проблема **не в адресах/регистрах**, а в шине: замер дал **76% `EXC 0x0B`**, главная гипотеза — **два Modbus-мастера на одной RS-485** (TrueNAS-HA + t610-HA). Детали и питфоллы — §5 в [[family/plans/t610-home-automation]]. +> ⚠️ **Про 44 `unavailable` заслонок на t610 (итог 2026-09-14):** +> ① Конфиг `modbus:` на t610 **построчно ИДЕНТИЧЕН** эталону TrueNAS (`/mnt/RED_2TB/docker/ha/configuration.yaml`) — сверено. Проблема **НЕ в адресах/регистрах**. +> ② Замер «**76% `EXC 0x0B`**» — **АРТЕФАКТ ЗАМЕРА**: запросы слались через `nc` на порт 502, пока HA/mbusd одновременно опрашивали ту же шину. На чистой линии (mbusd остановлен, замер без сторонних запросов) трафик нормальный. +> ③ Гипотеза «**два Modbus-мастера на одной RS-485**» — **ОПРОВЕРГНУТА**. Кабели физически переключены в t610, TrueNAS от шины отключён. Не повторять эту гипотезу. +> ④ 🔴 **ГЛАВНОЕ ОТКРЫТИЕ (физический тест): приборы сидят на ДРУГИХ гнёздах, чем считалось.** +> Alex выдернул шнур, который считал ZONT'ом → в `dmesg` отвалилось **гнездо 4** (`ttyUSB1`), гнездо 3 (`ttyUSB0`) осталось на месте. +> Значит: **ZONT = гнездо 4**, **вентиляция = гнездо 3**. +> Следствие: `mbusd` (настроен на гнездо 4) обслуживает **ZONT-шину**, а `modbus-bridge` (гнездо 3) — **вентиляцию**. Документация описывала это наоборот. +> Отсюда ложные выводы: слушая `ttyUSB0` (гнездо 3) и считая его ZONT-шиной, получали «0 байт / тишина» — потому что там вентиляция; а лог `mbusd` читали как «вентиляцию», хотя это ZONT-шина. +> Детали и питфоллы — §5 в [[family/plans/t610-home-automation]]. +> **Не закрыто:** сверить привязку гнёзд с Alex + разобраться с `verify` (`state_on:1/state_off:0` vs реальный `0x640001`). ## AT2 — калибровка PWM diff --git a/family/plans/t610-home-automation.md b/family/plans/t610-home-automation.md index 74f947da..4569da29 100644 --- a/family/plans/t610-home-automation.md +++ b/family/plans/t610-home-automation.md @@ -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`, но это АРТЕФАКТ замера** (агент мерил параллельно с опросом HA, делил шину) — см. §5; ③ **эталон TrueNAS (`/mnt/RED_2TB/docker/ha/configuration.yaml`) ИДЕНТИЧЕН t610** → причина НЕ конфиг; ④ гипотеза «два мастера» **ОПРОВЕРГНУТА** (адаптеры переключены в t610) — см. §5. **Не закрыто:** остаётся `verify` (`state_on:1/state_off:0` против реального `0x640001`) и вопрос, доходит ли опрос HA до реле | +| **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); ③ **эталон TrueNAS идентичен t610** → причина НЕ конфиг; ④ гипотеза «два мастера» **ОПРОВЕРГНУТА**; ⑤ **🔴 физический тест Alex'а: приборы сидят на ДРУГИХ гнёздах** — ZONT = гнездо 4, вентиляция = гнездо 3, т.е. `mbusd` (гнездо 4) обслуживает **ZONT-шину**, а `modbus-bridge` (гнездо 3) — **вентиляцию** (см. §5 «ГЛАВНОЕ ОТКРЫТИЕ»). **Не закрыто:** `verify` (`state_on:1/state_off:0` vs реальный `0x640001`) + сверить привязку с Alex | | **`sensor.fan_at2_*` — сироты** | В `configuration.yaml` **все `sensors:` закомментированы** → эти сущности физически не могут получать данные. Разобраться с происхождением (2026-09-14 поздняя) | | `switch.sauna` = `unknown` | Розетка физически отключена (`lastSeen` 8+ ч) — не баг | | ZONT не перенаправлен | MQTT-редирект GPON-роутера ещё смотрит на TrueNAS | @@ -80,12 +80,16 @@ ha supervisor logs | tail -60 # диагностика сборки local add- ## 3. USB-устройства (карта зафиксирована 2026-09-14) -| Устройство | by-id | **by-path (рабочая привязка)** | tty | Порт | +> 🔴🔴 **ВНИМАНИЕ: привязка «гнездо ↔ прибор» в таблице НИЖЕ ОКАЗАЛАСЬ НЕВЕРНОЙ** (опровергнуто физическим тестом Alex'а 2026-09-14, см. §5 «ГЛАВНОЕ ОТКРЫТИЕ»): **ZONT = гнездо 4**, **вентиляция = гнездо 3**. То есть в колонке «Порт» ZONT и Вентиляция **поменяны местами**. Таблица ниже — как было записано ранее (по `dmesg`/`by-path`, без физической проверки). **Сверить перед следующим перетыканием.** + +| Устройство | by-id | **by-path (рабочая привязка)** | tty | Порт (⚠️ см. предупреждение выше) | |---|---|---|---|---| -| CH340 #1 | `usb-1a86_USB_Serial-if00-port0` | `pci-0000:00:12.0-usb-0:3:1.0-port0` | `/dev/ttyUSB0` | USB1 порт 3 → **ZONT** | -| CH340 #2 | `usb-1a86_USB_Serial-if00-port0` ⚠️ тот же | `pci-0000:00:12.0-usb-0:4:1.0-port0` | `/dev/ttyUSB1` | USB1 порт 4 → **Вентиляция** | +| CH340 #1 | `usb-1a86_USB_Serial-if00-port0` | `pci-0000:00:12.0-usb-0:3:1.0-port0` | `/dev/ttyUSB0` | USB1 порт 3 → ~~ZONT~~ **вентиляция** | +| CH340 #2 | `usb-1a86_USB_Serial-if00-port0` ⚠️ тот же | `pci-0000:00:12.0-usb-0:4:1.0-port0` | `/dev/ttyUSB1` | USB1 порт 4 → ~~Вентиляция~~ **ZONT** | | Zigbee Inswift ZBP-MG21 | `usb-Inswift_Zigbee_ZBP-MG21_535A000001-if00` | `pci-0000:04:00.0-usb-0:1:1.0` | `/dev/ttyACM0` | USB3 порт 1 | +> 🔴 **Правило проверки привязки = ФИЗИЧЕСКИЙ ТЕСТ.** `dmesg`/`by-path` показывают только «CH340 в порту 3 / в порту 4», но **не говорят, какой кабель к какому прибору идёт**. Надёжно — только выдернуть шнур и посмотреть, какое гнездо отвалилось: `dmesg | grep -iE "ch341|ttyUSB|disconnect" | tail`. (Именно так Alex установил правду за 1 минуту.) + ### ⚠️ ГЛАВНЫЙ ПИТФОЛЛ: два CH340 неразличимы по by-id Оба CH340 — `1a86:7523`, **`serial` пуст, `manufacturer` пуст, `product = "USB Serial"`** (одинаковые). Следствие: в `/dev/serial/by-id/` для двух адаптеров существует **ровно ОДИН симлинк** (`usb-1a86_USB_Serial-if00-port0 → ttyUSB1` — занял зарегистрировавшийся последним). **Ссылки на `ttyUSB0` через by-id нет вообще.** @@ -116,9 +120,10 @@ for d in 1-3 1-4; do echo -n "$d serial: "; cat /sys/bus/usb/devices/$d/serial 2 ``` Zigbee (z2m): /dev/serial/by-id/usb-Inswift_Zigbee_ZBP-MG21_535A000001-if00 -ZONT (modbus-bridge): /dev/serial/by-path/pci-0000:00:12.0-usb-0:3:1.0-port0 -Вентиляция (mbusd): /dev/serial/by-path/pci-0000:00:12.0-usb-0:4:1.0-port0 +ZONT (modbus-bridge): /dev/serial/by-path/pci-0000:00:12.0-usb-0:3:1.0-port0 ← ⚠️ привязка СПОРНАЯ, см. §5 +Вентиляция (mbusd): /dev/serial/by-path/pci-0000:00:12.0-usb-0:4:1.0-port0 ← ⚠️ привязка СПОРНАЯ, см. §5 ``` +> 🔴🔴 **Это то, что НАСТРОЕНО в аддонах** (и что НЕ менялось — проверено бэкапом опций). Но **физический тест Alex'а показал, что приборы сидят на других гнёздах** (ZONT = гнездо 4, вентиляция = гнездо 3) → **фактически `mbusd` обслуживает ZONT-шину, а `modbus-bridge` — вентиляцию.** Кто прав (дока или тест) — уточнить у Alex. См. §5. > ⚠️ by-path привязан к физическому порту: CH340 #1 держать в порту 3, CH340 #2 в порту 4. > ✅ **Плюс аддонов:** старая проблема гонки udev (см. [[family/how-to/zont-modbus-bridge-udev-race-protection]]) на t610 **неактуальна** — Supervisor сам ждёт устройство при старте аддона. @@ -452,18 +457,41 @@ ZONT (`192.168.0.10`) — Modbus master на RS-485 `ttyZONT`. 485-датчик > ⏳ ZONT ещё не перенаправлен на MQTT t610 — редирект GPON-роутера смотрит на TrueNAS. -#### ✅ Подтверждение привязки USB-гнёзд (2026-09-14, позднейшая) +#### 🔴🔴 ГЛАВНОЕ ОТКРЫТИЕ (2026-09-14, финал сессии): ZONT СИДИТ НА ГНЕЗДЕ 4, НЕ 3 -Питфолл «оба CH340 неразличимы» проверен заново — **гнёзда разведены правильно**: +**Физический тест Alex'а:** Alex **выдернул шнур ZONT** → в `dmesg` отключилось **гнездо 4**: ``` -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) ✅ +usb 1-4: USB disconnect, device number 3 +ch341-uart ttyUSB1: ch341-uart converter now disconnected from ttyUSB1 +ch341 1-4:1.0: device disconnected ``` -**Путаницы нет.** Агент шлёт в правильную шину (вентиляция, slave 11/12). +Гнездо 3 (`usb 1-3 → ttyUSB0`) **осталось на месте** → значит отсоединился **не то, что докой называлось ZONT-ом**, а именно **гнездо 4**. + +**Следствия:** +| Что | Факт из теста | +|---|---| +| ZONT физически | **гнездо 4** (`ttyUSB1`) | +| Вентиляция физически | **гнездо 3** (`ttyUSB0`) | +| `local_mbusd` настроен на | **гнездо 4** → значит **mbusd опрашивает ZONT-шину** | +| `local_modbus-bridge` настроен на | **гнездо 3** → значит **bridge слушает ВЕНТИЛЯЦИЮ** | + +> 🔴 **В ДОКЕ ШИНЫ БЫЛИ ПЕРЕПУТАНЫ МЕСТАМИ.** Всё, что раньше писалось как «шина вентиляции (mbusd, гнездо 4)» и «шина ZONT (bridge, гнездо 3)» — читалось **не с той стороны**. Отсюда ВСЁ замешательство сессии: +> - Агент слушал `ttyUSB0` и звал это «ZONT» → там **вентиляция**. +> - Агент смотрел лог `mbusd` и звал это «вентиляцией» → он опрашивает **ZONT-шину** (там реле 11/12 — да, они на линии ZONT/485). +> - `modbus-bridge` «ничего не публиковал» → потому что на гнезде 3 сидит **вентиляция**, а не ZONT. +> +> ⚠️ **НЕ подтверждено до конца:** какой именно шнур Alex считает «ZONT-шнуром» — надо уточнить у него. Но объективный факт `dmesg` (отключилось гнездо 4) — железный. +> ⏳ **Сразу после теста гнездо 4 (вентиляция/ZONT-линия) осталось ОТКЛЮЧЕННЫМ** — `mbusd` работает без устройства. **Шнур нужно воткнуть обратно.** (Проверить при следующей сессии: `ls /dev/serial/by-path/` должен показать `...usb-0:4...`.) + +#### ⚠️ УСТАРЕВШЕЕ (опровергнуто тестом выше): «Гнёзда разведены правильно» + +Ранее в этой же сессии было записано (по `dmesg`+by-path, БЕЗ физического теста): +``` +ch341 1-3 → ttyUSB0 (гнездо 3 = ZONT) ← ОШИБКА +ch341 1-4 → ttyUSB1 (гнездо 4 = вентиляция) ← ОШИБКА +``` +**Это опровергнуто физическим тестом Alex'а** (см. выше): ZONT = гнездо 4. +> 🔴 **УРОК ДИАГНОСТИКИ:** соответствие «гнездо ↔ устройство» **НЕЛЬЗЯ вывести из `dmesg`/`by-path`** — там видно только, что CH340 воткнут в порт 3 и порт 4, но **не видно, какой кабель к какому прибору идёт**. Единственный надёжный способ — **физический тест: выдернуть шнур и посмотреть, какое гнездо отвалилось в `dmesg`.** Это то, что Alex сделал за минуту там, где агент полчаса строил теории. --- @@ -739,7 +767,7 @@ curl -s -X POST -H "$HDR" -H "Content-Type: application/json" \ |---|---|---| | 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 | +| 1c | **🔴 ZONT-шина: ПРИБОРЫ СИДЯТ НА ДРУГИХ ГНЁЗДАХ, ЧЕМ ЗАПИСАНО В ДОКЕ** (см. §5 «ГЛАВНОЕ ОТКРЫТИЕ»). Физический тест Alex'а: выдернул ZONT-шнур → отвалилось **гнездо 4** → **ZONT = гнездо 4**, **вентиляция = гнездо 3**. Значит `mbusd` (гнездо 4) фактически обслуживает **ZONT-шину**, а `modbus-bridge` (гнездо 3) — **вентиляцию**. **Разобраться:** ① подтвердить у Alex, какой шнур он считает ZONT-шнуром; ② решить, менять ли привязку аддонов/доку или физику. | я + Alex | | 2 | Раскомментировать slave 10 (AT2 fans) в `configuration.yaml` — был закомментирован «not responding on bus» | я | | 3 | `sensor.*_summary` — добавить `\|default(0)` в template-сенсоры (косметика, самоизлечится) | — | | 4 | **Камера** — найти образ/папку, поднять на t610, поправить upstream в Caddy | отдельно | @@ -756,14 +784,28 @@ curl -s -X POST -H "$HDR" -H "Content-Type: application/json" \ **✅ Закрыто / установлено в этой сессии (2026-09-14, позднейшая, Modbus-диагностика):** - **Опции mbusd — откат подтверждён.** Аддон `started`, значения `timeout 1000 / retries 3 / maxconn 8` (как было). `maxconn` **не трогать** (питфолл в §5). +- **Привязку tty агент НЕ менял** — доказано бэкапом опций `/config/mb-fix-backup-20260914-145419/mbusd-options.json` (`device` был и остался `...usb-0:4...`). - **Эталон 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). +- **🔴 ГЛАВНОЕ: физический тест Alex'а вскрыл, что приборы сидят на ДРУГИХ гнёздах** — ZONT = гнездо 4, вентиляция = гнездо 3 (см. §5). Дока и прежние записи сессии были **перепутаны местами**. - **`.157` = Rasputin/сам агент**, не посторонний клиент — урок повторён (§5). - **`ha core stop` в SSH-скрипте может повиснуть** — проверять живость после (§5). +**⏳ СРОЧНО, при следующей сессии (состояние железа после теста):** +- 🔴 **Гнездо 4 (по тесту — ZONT-линия) ОСТАЛОСЬ ОТКЛЮЧЕННЫМ** — Alex выдернул шнур, не воткнул обратно. `mbusd` сейчас работает **без устройства**. +- **Проверка:** `ls /dev/serial/by-path/` должен показать **`pci-0000:00:12.0-usb-0:4:1.0-port0`**. Если нет — шнур не воткнут. `ha apps info local_mbusd --raw-json | jq -r '.data.options.device'` → должен указывать на `...usb-0:4...`. +- Если шнур не вернуть — **вся вентиляция/ZONT-линия в дауне**, а `44 unavailable` могут измениться. + +**🔴 ПРОЦЕССНЫЙ УРОК СЕССИИ (для будущих сессий):** +Агент потратил ~полсессии на теории (второй мастер, шторм коннектов, шторм `.157`), слал запросы в шину (засоряя её и портя собственные замеры), сломал mbusd, останавливал HA — вместо **одного физического теста**, который Alex сделал за минуту: *выдернуть шнур → посмотреть `dmesg`*. Правила: +1. **Соответствие «гнездо ↔ прибор» проверять ФИЗИЧЕСКИ** (выдернуть шнур + `dmesg`), а не выводить из `by-path`/`dmesg`-именования. Имя `usb-0:3`/`usb-0:4` не говорит, какой кабель к какому прибору. +2. **Не мерить шину, пока HA её же опрашивает** — иначе замер = артефакт (76% потерь). +3. **Не строить гипотезы о физике — спрашивать Alex.** Он знает, куда что переткнуто. +4. **Причину искать в той шине, где она есть** — не «диагностировать» вслепую обе. +5. Alex устаёт от споров и повторов. Если он говорит «проверяй» — **проверять, а не возражать**. Его вопрос = команда. + **Отключение TrueNAS (только после полной проверки):** ```bash ssh truenas_admin@mallexxx.duckdns.org @@ -780,6 +822,8 @@ docker restart caddy **На Mac:** `~/tmp-t610/` — `stage3/out/`, `backups/`, `ha_token.txt`, `addons/`, `etap3-fix/` (`automations.fixed.yaml`, `set_all_areas.jq`, `devid_mapping.json`, `mbtest.sh`), скрипты `*.sh`/`*.py`. **Диагностика modbus (2026-09-14 поздняя, только чтение):** `~/tmp-t610/mbdiag1.sh` … `mbdiag4.sh` — снятие опций аддонов, блока `modbus:` из `configuration.yaml`, лога mbusd, лога HA по modbus, прямого опроса регистров. Запуск: `scp -i ~/.ssh/id_rsa