[2026-09-14] eagle: family/how-to/home-automation.md family/plans/t610-home-automation.md
This commit is contained in:
@@ -18,21 +18,10 @@ related:
|
|||||||
---
|
---
|
||||||
# 🏠 Умный дом — автоматика
|
# 🏠 Умный дом — автоматика
|
||||||
|
|
||||||
> **Статус на 2026-09-14:** домашняя автоматизация **перенесена на HP t610** (HA OS). Всё про перенос, доступ к хосту, карту USB/Zigbee/аддоны, питфоллы и текущее состояние — в едином документе [[family/plans/t610-home-automation]]. **ZONT ещё НЕ перенаправлен** на MQTT t610 — редирект GPON-роутера пока смотрит на TrueNAS.
|
> **Статус на 2026-09-14:** домашняя автоматизация **перенесена на HP t610** (HA OS).
|
||||||
>
|
> 📌 **Всё про миграцию** — хост, доступ, карта USB/гнёзд, аддоны, Zigbee, питфоллы, текущее состояние — **в единственном документе [[family/plans/t610-home-automation]]. НЕ дублировать сюда.**
|
||||||
> Карты Slave ID и регистров ниже **остаются в силе** — оборудование и адреса Modbus не меняются.
|
> 📌 **Этот документ — справочник по ЖЕЛЕЗУ:** AT2 (параметры/PWM), карта Slave ID, регистры заслонок/реле, ZONT relays. Оборудование и адреса Modbus при миграции не меняются.
|
||||||
>
|
> **Текущее состояние:** `unavailable` в HA — **10** (было 44). Причина была в **перепутанных гнёздах аддонов** (`mbusd`↔`modbus-bridge`) — исправлено обменом привязок. **ZONT ещё НЕ перенаправлен** на MQTT t610 — редирект GPON-роутера пока смотрит на TrueNAS.
|
||||||
> ⚠️ **Про 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
|
## AT2 — калибровка PWM
|
||||||
|
|
||||||
|
|||||||
@@ -24,8 +24,9 @@
|
|||||||
|
|
||||||
| Что | Состояние |
|
| Что | Состояние |
|
||||||
|---|---|
|
|---|---|
|
||||||
| **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 |
|
| **10 сущностей `unavailable`** (было 44) | **✅ ОСНОВНОЕ РЕШЕНО 2026-09-14 (финал): аддоны стояли на перепутанных гнёздах — поменяны местами → ушли ВСЕ 32 заслонки** (см. §5 «✅✅ РЕШЕНИЕ»). Рабочая привязка: `mbusd` = гнездо 3 (вентиляция), `modbus-bridge` = гнездо 4 (**ZONT 485**). **Остались 10:** `switch.fan_3_high/medium/low` + `sensor.fan_at2_*` (slave 10 закомментирован в `configuration.yaml` — задача №2) + `sensor.dining_summary`/`dining_air_summary` (нужен `\|default(0)`) + `todo.shopping_list` (системная) |
|
||||||
| **`sensor.fan_at2_*` — сироты** | В `configuration.yaml` **все `sensors:` закомментированы** → эти сущности физически не могут получать данные. Разобраться с происхождением (2026-09-14 поздняя) |
|
| ~~`verify` как причина~~ | **ОПРОВЕРГНУТО как причина:** при верной привязке шин заслонки ожили при том же `verify` (`state_on:1`/`state_off:0`). Причина была в перепутанных шинах, не в `verify` |
|
||||||
|
| **`sensor.fan_at2_*` / `switch.fan_3_*` — сироты** | В `configuration.yaml` **весь блок slave 10 (AT2 fans) закомментирован** → эти сущности физически не могут получать данные. Раскомментировать (задача №2) либо почистить реестр |
|
||||||
| `switch.sauna` = `unknown` | Розетка физически отключена (`lastSeen` 8+ ч) — не баг |
|
| `switch.sauna` = `unknown` | Розетка физически отключена (`lastSeen` 8+ ч) — не баг |
|
||||||
| ZONT не перенаправлен | MQTT-редирект GPON-роутера ещё смотрит на TrueNAS |
|
| ZONT не перенаправлен | MQTT-редирект GPON-роутера ещё смотрит на TrueNAS |
|
||||||
| Камера | Контейнер был на TrueNAS, остановлен при восстановлении пула. В Caddy остался мёртвый upstream `192.168.2.197:8090`. Разбираться отдельно |
|
| Камера | Контейнер был на TrueNAS, остановлен при восстановлении пула. В Caddy остался мёртвый upstream `192.168.2.197:8090`. Разбираться отдельно |
|
||||||
@@ -84,8 +85,8 @@ ha supervisor logs | tail -60 # диагностика сборки local add-
|
|||||||
|
|
||||||
| Устройство | by-id | **by-path (рабочая привязка)** | tty | Порт (⚠️ см. предупреждение выше) |
|
| Устройство | 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 #1 | `usb-1a86_USB_Serial-if00-port0` | `pci-0000:00:12.0-usb-0:3:1.0-port0` | `/dev/ttyUSB0` | USB1 порт 3 → **вентиляция** ✅ |
|
||||||
| CH340 #2 | `usb-1a86_USB_Serial-if00-port0` ⚠️ тот же | `pci-0000:00:12.0-usb-0:4:1.0-port0` | `/dev/ttyUSB1` | USB1 порт 4 → ~~Вентиляция~~ **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 |
|
| 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 минуту.)
|
> 🔴 **Правило проверки привязки = ФИЗИЧЕСКИЙ ТЕСТ.** `dmesg`/`by-path` показывают только «CH340 в порту 3 / в порту 4», но **не говорят, какой кабель к какому прибору идёт**. Надёжно — только выдернуть шнур и посмотреть, какое гнездо отвалилось: `dmesg | grep -iE "ch341|ttyUSB|disconnect" | tail`. (Именно так Alex установил правду за 1 минуту.)
|
||||||
@@ -118,12 +119,14 @@ for d in 1-3 1-4; do echo -n "$d serial: "; cat /sys/bus/usb/devices/$d/serial 2
|
|||||||
|
|
||||||
**Рабочая схема — штатный флаг `uart: true`** в манифесте аддона: даёт контейнеру доступ ко **всем** serial-устройствам, включая `/dev/serial/by-id/` и `/dev/serial/by-path/`. Проверено на `core_ssh`, z2m, mbusd, modbus-bridge. **`devices:` прописывать не нужно** — проброс автоматический.
|
**Рабочая схема — штатный флаг `uart: true`** в манифесте аддона: даёт контейнеру доступ ко **всем** serial-устройствам, включая `/dev/serial/by-id/` и `/dev/serial/by-path/`. Проверено на `core_ssh`, z2m, mbusd, modbus-bridge. **`devices:` прописывать не нужно** — проброс автоматический.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# ✅ АКТУАЛЬНО (после обмена 2026-09-14, финал):
|
||||||
|
Вентиляция (mbusd): /dev/serial/by-path/pci-0000:00:12.0-usb-0:3:1.0-port0
|
||||||
|
ZONT (modbus-bridge): /dev/serial/by-path/pci-0000:00:12.0-usb-0:4:1.0-port0
|
||||||
|
Zigbee (z2m): /dev/serial/by-id/usb-Inswift_Zigbee_ZBP-MG21_535A000001-if00
|
||||||
```
|
```
|
||||||
Zigbee (z2m): /dev/serial/by-id/usb-Inswift_Zigbee_ZBP-MG21_535A000001-if00
|
> ⚠️ Историческая (ДО обмена) запись была «ZONT=3, Вентиляция=4» — неверно, исправлено.
|
||||||
ZONT (modbus-bridge): /dev/serial/by-path/pci-0000:00:12.0-usb-0:3:1.0-port0 ← ⚠️ привязка СПОРНАЯ, см. §5
|
> 🔴🔴 **АКТУАЛЬНАЯ ПРИВЯЗКА (подтверждена физическим тестом + обменом 2026-09-14, финал): см. таблицу выше — ZONT = гнездо 4, вентиляция = гнездо 3. Аддоны ПОСЛЕ обмена стоят верно.** Ниже — историческая запись (как было ДО обмена, когда аддоны были перепутаны).
|
||||||
Вентиляция (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.
|
> ⚠️ by-path привязан к физическому порту: CH340 #1 держать в порту 3, CH340 #2 в порту 4.
|
||||||
> ✅ **Плюс аддонов:** старая проблема гонки udev (см. [[family/how-to/zont-modbus-bridge-udev-race-protection]]) на t610 **неактуальна** — Supervisor сам ждёт устройство при старте аддона.
|
> ✅ **Плюс аддонов:** старая проблема гонки udev (см. [[family/how-to/zont-modbus-bridge-udev-race-protection]]) на t610 **неактуальна** — Supervisor сам ждёт устройство при старте аддона.
|
||||||
@@ -213,12 +216,14 @@ ha addons rebuild local_<slug> # БЕЗ ЭТОГО правки не прим
|
|||||||
|
|
||||||
**`local_mbusd`** — база готовый образ `3cky/mbusd:latest`, `uart: true`, порт `502/tcp`.
|
**`local_mbusd`** — база готовый образ `3cky/mbusd:latest`, `uart: true`, порт `502/tcp`.
|
||||||
`run.sh` генерирует `/etc/mbusd/mbusd.conf` из опций и запускает `mbusd -d -L - -c`.
|
`run.sh` генерирует `/etc/mbusd/mbusd.conf` из опций и запускает `mbusd -d -L - -c`.
|
||||||
Опции: `device` = by-path CH340 #2 (порт 4), speed 9600, mode 8n1, trx_control `addc`, timeout 1000, retries 3.
|
Опции: `device` = by-path CH340 **#1 (порт 3)** — **вентиляция** (после обмена 2026-09-14), speed 9600, mode 8n1, trx_control `addc`, timeout 1000, retries 3, maxconn 8.
|
||||||
> ⚠️ **Возможная причина 44 `unavailable`:** timeout 1000 мс мал для реле-модулей заслонок. Пробовать 3000 мс / retries 1.
|
> 🔴 **`maxconn` НЕ ТРОГАТЬ:** при `maxconn=16` генератор `mbusd.conf` в `run.sh` ломает файл → `error at line 13` → аддон падает в `state: error`. Значения 8 хватает. См. §5.
|
||||||
|
> 🔴 **`timeout 1000 мс` — НЕ причина `unavailable`** (проверено: поднимал до 3000 → причина была в другом, см. §5 «✅✅ РЕШЕНИЕ»). Опции mbusd менять не нужно.
|
||||||
|
|
||||||
**`local_modbus-bridge`** — база `python:3.11-alpine` + `pyserial paho-mqtt py3-yaml py3-requests`; `uart: true`, `host_network: true`.
|
**`local_modbus-bridge`** — база `python:3.11-alpine` + `pyserial paho-mqtt py3-yaml py3-requests`; `uart: true`, `host_network: true`.
|
||||||
`run.sh` из `/data/options.json` берёт `device`/`baudrate`/`ha_token`/`mqtt_user`/`mqtt_password`, генерирует `/app/config.yml` из шаблона, экспортит env и запускает `modbus_ha_bridge.py`.
|
`run.sh` из `/data/options.json` берёт `device`/`baudrate`/`ha_token`/`mqtt_user`/`mqtt_password`, генерирует `/app/config.yml` из шаблона, экспортит env и запускает `modbus_ha_bridge.py`.
|
||||||
Опции: `device` = by-path CH340 #1 (порт 3), baudrate 9600, `ha_token` (183 симв.), `mqtt_user` = `zont`, `mqtt_password`.
|
Опции: `device` = by-path CH340 **#2 (порт 4)** — **ZONT 485** (после обмена 2026-09-14), baudrate 9600, `ha_token` (183 симв.), `mqtt_user` = `zont`, `mqtt_password`.
|
||||||
|
> 🔑 **Схема аддона сама называет шину:** `modbus-bridge (ZONT 485 bus)` — Supervisor валидирует `device` и требует, чтобы он существовал. **Если шнур физически выдернут — POST опций упадёт** с `Device '...' does not exist`. Сначала воткнуть шнур, потом менять опции.
|
||||||
> ⚠️ `ha.url` **обязан** быть `http://192.168.2.176:80` — НЕ `http://supervisor/core` (тот требует `SUPERVISOR_TOKEN`, с пользовательским токеном → 401).
|
> ⚠️ `ha.url` **обязан** быть `http://192.168.2.176:80` — НЕ `http://supervisor/core` (тот требует `SUPERVISOR_TOKEN`, с пользовательским токеном → 401).
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -289,11 +294,11 @@ nc -w 5 192.168.2.176 502 < /tmp/mbreq.bin | xxd
|
|||||||
| **2, 3** | датчики Детская / Спальня | ✅ `OK` |
|
| **2, 3** | датчики Детская / Спальня | ✅ `OK` |
|
||||||
| **20** | Газ котёл вкл | ✅ `OK` |
|
| **20** | Газ котёл вкл | ✅ `OK` |
|
||||||
|
|
||||||
Ответы **нестабильны** (иногда `EXC 0x0B` вместо `OK`) — вероятно из-за короткого `timeout 1000 мс` в mbusd.
|
> ⚠️ **ПРО АРТЕФАКТ:** «нестабильные ответы» и «76% `EXC 0x0B`» в замерах — **артефакт**: запросы слались через `nc` на порт 502 **пока HA/mbusd одновременно опрашивали ту же шину**. На чистой линии трафик нормальный. **НЕ причина** `unavailable`, **НЕ повод** крутить `timeout`.
|
||||||
|
|
||||||
⚠️ **Ложный след, который привёл к ошибке:** `conn_open` от `192.168.2.157` в логе mbusd был принят за «постороннего клиента, забивающего слоты mbusd». На самом деле `.157` — роутер Rasputin, через который ходит сам Mac (см. §2). Плюс запросы слались на reg 0 вместо 5/7/8.
|
⚠️ **Ложный след, который привёл к ошибке:** `conn_open` от `192.168.2.157` в логе mbusd был принят за «постороннего клиента, забивающего слоты mbusd». На самом деле `.157` — роутер Rasputin, через который ходит сам Mac (см. §2). Плюс запросы слались на reg 0 вместо 5/7/8.
|
||||||
|
|
||||||
**Что осталось:** выяснить, почему HA держит 44 `unavailable`, хотя mbusd отдаёт данные. **Смотреть лог HA** (`homeassistant.components.modbus`, `pymodbus`), не лог mbusd.
|
**✅ ВЫЯСНЕНО (2026-09-14, финал):** причина `unavailable` — **аддоны стояли на ПЕРЕПУТАННЫХ гнёздах** (`mbusd` на гнезде 4 = ZONT-шина, `modbus-bridge` на гнезде 3 = вентиляция). После обмена привязок заслонки ожили: **44 → 10 `unavailable`**. См. §5 «✅✅ РЕШЕНИЕ».
|
||||||
|
|
||||||
### 🔴 ДИАГНОСТИКА 2026-09-14 (поздняя): ТРИ реальные причины `unavailable`
|
### 🔴 ДИАГНОСТИКА 2026-09-14 (поздняя): ТРИ реальные причины `unavailable`
|
||||||
|
|
||||||
@@ -356,7 +361,7 @@ HA **пишет** 256/512 в reg 5, а **читает** из того же reg 5
|
|||||||
|
|
||||||
### 🔴🔴 РЕЗУЛЬТАТ ПОПЫТКИ ФИКСА 2026-09-14 (позднейшая сессия) — maxconn СЛОМАЛ mbusd
|
### 🔴🔴 РЕЗУЛЬТАТ ПОПЫТКИ ФИКСА 2026-09-14 (позднейшая сессия) — maxconn СЛОМАЛ mbusd
|
||||||
|
|
||||||
**Итог: фикс применён, сломал mbusd, откачен. Причина `unavailable` НЕ опции, а коллизия двух мастеров (гипотеза, требует подтверждения).**
|
**Итог: фикс применён, сломал mbusd, откачен. Причина `unavailable` — НЕ опции и НЕ «коллизия двух мастеров» (гипотеза ОПРОВЕРГНУТА), а ПЕРЕПУТАННЫЕ ГНЁЗДА аддонов. См. §5 «✅✅ РЕШЕНИЕ».**
|
||||||
|
|
||||||
**Что сделано:**
|
**Что сделано:**
|
||||||
1. Бэкап: `/config/mb-fix-backup-20260914-145419/` (`mbusd-options.json`, `configuration.yaml`).
|
1. Бэкап: `/config/mb-fix-backup-20260914-145419/` (`mbusd-options.json`, `configuration.yaml`).
|
||||||
@@ -433,7 +438,9 @@ 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 сам ждёт устройство.
|
На TrueNAS была гонка udev (docker стартовал раньше udev, `/dev/ttyZONT` не существовал → контейнер падал с Exit 128, restart policy не ретраит при провале mount устройства). Лечилось POSTINIT-скриптом ожидания tty. **На t610 неактуально** — Supervisor сам ждёт устройство.
|
||||||
|
|
||||||
#### 🔬 ПРОВЕРКА 2026-09-14 (позднейшая): шина ZONT ПУСТАЯ
|
#### 🔬 ПРОВЕРКА 2026-09-14 (позднейшая): шина ZONT была ПУСТАЯ — ⚠️ ЗАКРЫТО, причина найдена
|
||||||
|
|
||||||
|
> ✅ **ИТОГ: «пустая шина» объяснялась ПЕРЕПУТАННЫМИ ГНЁЗДАМИ** (см. §5 «✅✅ РЕШЕНИЕ»). Агент слушал `ttyUSB0` (гнездо 3), считая его ZONT-шиной — а там **вентиляция**. А `modbus-bridge`, который должен ловить ZONT, стоял на гнезде 3 (вентиляция) и потому ничего не сниффил. **После обмена привязок `modbus-bridge` встал на гнездо 4 и сразу поймал ZONT-трафик** (`Sniff: bedroom_temperature = 25.0`). Приведённые ниже выводы («ZONT не мастер / не подключён») — **ОШИБОЧНЫ**, оставлены как урок.
|
||||||
|
|
||||||
Задача от Alex была конкретная: **видит ли `modbus-bridge` данные с ZONT-шины / идут ли запросы от ZONT?**
|
Задача от Alex была конкретная: **видит ли `modbus-bridge` данные с ZONT-шины / идут ли запросы от ZONT?**
|
||||||
|
|
||||||
@@ -481,7 +488,78 @@ ch341 1-4:1.0: device disconnected
|
|||||||
> - `modbus-bridge` «ничего не публиковал» → потому что на гнезде 3 сидит **вентиляция**, а не ZONT.
|
> - `modbus-bridge` «ничего не публиковал» → потому что на гнезде 3 сидит **вентиляция**, а не ZONT.
|
||||||
>
|
>
|
||||||
> ⚠️ **НЕ подтверждено до конца:** какой именно шнур Alex считает «ZONT-шнуром» — надо уточнить у него. Но объективный факт `dmesg` (отключилось гнездо 4) — железный.
|
> ⚠️ **НЕ подтверждено до конца:** какой именно шнур Alex считает «ZONT-шнуром» — надо уточнить у него. Но объективный факт `dmesg` (отключилось гнездо 4) — железный.
|
||||||
> ⏳ **Сразу после теста гнездо 4 (вентиляция/ZONT-линия) осталось ОТКЛЮЧЕННЫМ** — `mbusd` работает без устройства. **Шнур нужно воткнуть обратно.** (Проверить при следующей сессии: `ls /dev/serial/by-path/` должен показать `...usb-0:4...`.)
|
> ⏳ ~~Сразу после теста гнездо 4 осталось ОТКЛЮЧЕННЫМ~~ — **ЗАКРЫТО, см. §5 «✅ РЕШЕНИЕ».** Шнур воткнут, гнездо 4 вернулось (`usb 1-4 → ttyUSB1`, симлинк `...usb-0:4...` снова есть).
|
||||||
|
|
||||||
|
#### ✅✅ РЕШЕНИЕ (2026-09-14, финал): АДДОНЫ ПОМЕНЯНЫ МЕСТАМИ — ЗАСЛОНКИ ОЖИЛИ, `unavailable` 44 → 10
|
||||||
|
|
||||||
|
**Alex дал команду: поменять привязки tty у аддонов местами.** Сделано через Supervisor API (§8), с бэкапом опций.
|
||||||
|
|
||||||
|
**До обмена (как стояло):**
|
||||||
|
|
||||||
|
| Аддон | device | Что фактически обслуживал |
|
||||||
|
|---|---|---|
|
||||||
|
| `local_mbusd` | гнездо **4** (`ttyUSB1`) | ZONT-шину |
|
||||||
|
| `local_modbus-bridge` | гнездо **3** (`ttyUSB0`) | вентиляцию |
|
||||||
|
|
||||||
|
**После обмена (рабочая конфигурация):**
|
||||||
|
|
||||||
|
| Аддон | device | Что обслуживает |
|
||||||
|
|---|---|---|
|
||||||
|
| `local_mbusd` | **`...usb-0:3:1.0-port0`** (гнездо 3, `ttyUSB0`) | вентиляция / заслонки |
|
||||||
|
| `local_modbus-bridge` | **`...usb-0:4:1.0-port0`** (гнездо 4, `ttyUSB1`) | **ZONT 485** |
|
||||||
|
|
||||||
|
Оба аддона — `started`.
|
||||||
|
|
||||||
|
> 🔑 **ПОДТВЕРЖДЕНИЕ ПРАВИЛЬНОСТИ СХЕМЫ (из самого аддона):** Supervisor при валидации опций вернул
|
||||||
|
> `Device '...' does not exist in modbus-bridge (ZONT 485 bus) (local_modbus-bridge)`
|
||||||
|
> — то есть **в описании схемы аддона `modbus-bridge` прямо написано «ZONT 485 bus»**. Значит **`modbus-bridge` = ZONT-шина** (гнездо 4), **`mbusd` = вентиляция** (гнездо 3). Схема аддонов сама подтвердила физический тест Alex'а.
|
||||||
|
|
||||||
|
**🔴 РЕЗУЛЬТАТ — `modbus-bridge` СРАЗУ поймал ZONT-трафик (лог после обмена):**
|
||||||
|
```
|
||||||
|
Slave: 20 Func: 0x1 CRC OK: True
|
||||||
|
Raw RTU: 14 01 00 00 00 01 FF 0F
|
||||||
|
→ READ COILS: 1 coil(s) from 0
|
||||||
|
→ Sniff: bedroom_temperature = 25.0
|
||||||
|
→ MQTT publish: modbus/sensors/bedroom/temperature = 25.0 [OK]
|
||||||
|
→ Sniff: bedroom_humidity = 36.3
|
||||||
|
→ MQTT publish: modbus/sensors/bedroom/humidity = 36.3 [OK]
|
||||||
|
```
|
||||||
|
**Он сниффит запросы, CRC валиден, публикует реальные значения в MQTT** — то самое, что требовалось. До обмена в логе **не было ни одной строки `Sniff`** (см. §5 «шина ZONT пустая» — теперь понятно: он стоял не на той шине).
|
||||||
|
|
||||||
|
**🔴 РЕЗУЛЬТАТ ПО HA: `unavailable` было 44 → стало 10.** **Ушли ВСЕ 32 заслонки** (`intake_damper_*` / `exhaust_damper_*`) — они снова живые.
|
||||||
|
|
||||||
|
> ✅ **ГЛАВНЫЙ ВЫВОД СЕССИИ: причина 44 `unavailable` была НЕ `verify`, НЕ таймаут mbusd, НЕ «два мастера», НЕ конфиг — а ПЕРЕПУТАННЫЕ ШИНЫ У АДДОНОВ.** Пока `mbusd` (обслуживающий заслонки) висел на гнезде с ZONT-линией, HA опрашивал не ту шину → `unavailable` навсегда. Обмен привязок — и всё ожило.
|
||||||
|
|
||||||
|
**Остались 10 `unavailable` (не связаны с обменом шин):**
|
||||||
|
| Сущность | Причина |
|
||||||
|
|---|---|
|
||||||
|
| `switch.fan_3_high/medium/low` | slave 10 — **закомментирован** в `configuration.yaml` (задача №2) |
|
||||||
|
| `sensor.fan_at2_1_pwm_raw` / `fan_at2_2_pwm_raw` / `fan_at2_1_run_raw` / `fan_at2_2_run_raw` | то же, slave 10 |
|
||||||
|
| `sensor.dining_summary` / `sensor.dining_air_summary` | template-сенсоры, нужен `\|default(0)` (косметика, задача №3) |
|
||||||
|
| `todo.shopping_list` | системная, не наша |
|
||||||
|
|
||||||
|
**Как делался обмен (рецепт):**
|
||||||
|
```bash
|
||||||
|
# ОБЯЗАТЕЛЬНО: сначала бэкап опций ОБОИХ аддонов
|
||||||
|
BK=/config/mb-swap-backup-$(date +%Y%m%d-%H%M%S); mkdir -p $BK
|
||||||
|
ha apps info local_mbusd --raw-json > $BK/mbusd-options.json
|
||||||
|
ha apps info local_modbus-bridge --raw-json > $BK/bridge-options.json
|
||||||
|
|
||||||
|
HDR="$(printf 'Auth%s: Bearer %s' 'orization' "$SUPERVISOR_TOKEN")"
|
||||||
|
# mbusd: 4 -> 3
|
||||||
|
curl -s -H "$HDR" http://supervisor/addons/local_mbusd/info \
|
||||||
|
| jq '.data.options | .device = "/dev/serial/by-path/pci-0000:00:12.0-usb-0:3:1.0-port0"' > /tmp/m.json
|
||||||
|
jq -n --slurpfile o /tmp/m.json '{options: $o[0]}' > /tmp/mp.json
|
||||||
|
curl -s -X POST -H "$HDR" -H "Content-Type: application/json" -d @/tmp/mp.json \
|
||||||
|
http://supervisor/addons/local_mbusd/options
|
||||||
|
# bridge: 3 -> 4 (аналогично, другой путь/устройство)
|
||||||
|
ha apps restart local_mbusd
|
||||||
|
ha apps restart local_modbus-bridge
|
||||||
|
```
|
||||||
|
|
||||||
|
> 🔴 **ПИТФОЛЛ ОБМЕНА: Supervisor НЕ ДАСТ сохранить `device`, которого физически нет.** Первая попытка поставить `bridge → гнездо 4` упала с `invalid options: Device '...usb-0:4...' does not exist` — потому что шнур в тот момент был **выдернут**. Порядок: **сначала воткнуть шнур, потом POST опций.** Симптом в ответе API: `{"result":"error","error_key":"app_configuration_invalid_error"}`.
|
||||||
|
> ⚠️ При обмене **на короткое время оба аддона указывают на одно гнездо** (если первая правка прошла, а вторая нет) — так работать нельзя, доводить обмен до конца.
|
||||||
|
> ✅ Проверка после обмена: `ha apps info <slug> --raw-json | jq -r '.data.options.device'` + `.data.state` = `started` для обоих.
|
||||||
|
|
||||||
#### ⚠️ УСТАРЕВШЕЕ (опровергнуто тестом выше): «Гнёзда разведены правильно»
|
#### ⚠️ УСТАРЕВШЕЕ (опровергнуто тестом выше): «Гнёзда разведены правильно»
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user