[2026-09-14] eagle: family/plans/t610-home-automation.md

This commit is contained in:
Alexey Martemyanov
2026-09-14 14:53:10 +06:00
parent 3b9bba8412
commit 826cefa40a
+135 -12
View File
@@ -643,13 +643,13 @@ modbus/sensors/bedroom/humidity 36.0
Если вписать `\|default(0)`, сводка выдаст **`0° 0ppm`** — то есть на дашборде появится «ложный ноль» вместо честного «нет данных». **Alex'у нужен факт, а не зелёная плашка.** Правка кода **не делается** до ответа на вопрос ниже.
### ❓ ОТКРЫТЫЙ ВОПРОС К ALEX (блокирует решение)
### ❓ ОТКРЫТЫЙ ВОПРОС К ALEX — ✅ ОТВЕТ ПОЛУЧЕН 2026-09-14 (см. §5-кватер ниже)
**Есть ли датчик температуры/CO2 в столовой физически** (тот, что ZONT должен видеть на 485-шине)?
| Ответ | Что делать |
|---|---|
| **Да, есть** | Чинить ZONT: почему не опрашивает датчик (не зарегистрирован в ZONT / обрыв / датчик сдох). Проверить по карте: **Гостиная = slave 1, Детская = 2, Спальня = 3** ([[family/how-to/home-automation]]) — «столовая» в ZONT может называться «Гостиная» или это отдельный слейв |
| **Да, есть** ← **ЭТО ОТВЕТ ALEX'А (2026-09-14)** | Чинить ZONT: почему не опрашивает датчик (не зарегистрирован в ZONT / обрыв / датчик сдох). Проверить по карте: **Гостиная = slave 1, Детская = 2, Спальня = 3** ([[family/how-to/home-automation]]) — «столовая» в ZONT может называться «Гостиная» или это отдельный слейв |
| **Нет** | 8 сущностей `sensor.dining_*` — **мусор с TrueNAS**. Чистить из `core.entity_registry` (при остановленном HA, бэкап реестра), а не «чинить» формулой |
> 📌 **Метод (переиспользуемый) — как отвечать на «почему сущность недоступна»:**
@@ -665,6 +665,103 @@ modbus/sensors/bedroom/humidity 36.0
---
## 5-кватер. 🔬 Датчик столовой ОТВЕЧАЕТ, но отдаёт НОЛЬ + развязка Caddy (2026-09-14, вечерняя сессия)
> **Задача сессии (Alex):** «Что дальше по плану?» → далее по ходу: «Датчик есть. Что с ним??» → «Ок. Делай. Меняй правила caddy на truenas чтобы указывали на t610».
### 5-кватер-А. Датчик столовой: причина найдена — шина отвечает нулём, bridge отбрасывает
**Alex подтвердил: датчик в столовой физически ЕСТЬ.** Значит ветка «чистить мусор» отпала — идём чинить источник.
**Что показал лог `modbus-bridge` (`ha apps logs local_modbus-bridge`, фильтр по `dining`):**
```
2026-09-14 08:43:45 Slave: 1 Func: 0x3 CRC OK: True
→ Response: 1 register(s) from 100 (sniff:dining_temperature) = 0 [00 00]
2026-09-14 08:43:50 Slave: 1 Func: 0x3 CRC OK: True
→ Response: 1 register(s) from 100 (sniff:dining_temperature) = 0 [00 00]
```
**Расшифровка (ключевой факт):**
| Наблюдение | Значение |
|---|---|
| `Slave: 1` | Столовая = **slave 1** (совпадает с картой: Гостиная=1) |
| `CRC OK: True` | Кадр целый — **проводка и обмен в порядке** |
| `Func: 0x3` | Чтение holding-регистра |
| `from 100` | Регистр **100** (температура) |
| `= 0 [00 00]` | 🔴 **Датчик отвечает ЗНАЧЕНИЕМ 0**, а не молчит |
| опрос каждые 5 с, стабильно | Не «иногда», а **постоянно ноль** |
> 🔴 **ВЫВОД: ZONT датчик ОПРАШИВАЕТ (slave 1, reg 100, каждые 5 с), датчик ОТВЕЧАЕТ — но отдаёт ноль.** `modbus-bridge` считает `0` невалидной температурой → **не публикует** в `modbus/sensors/dining/*` → HA-сущности остаются `unknown` → `dining_summary` падает в `unavailable`. **Проблема НЕ в HA и НЕ в проводке/обмене, а в самом датчике или его регистрации в ZONT.**
**Дополнительное наблюдение (зацепка):** в логе для столовой виден **только** `sniff:dining_temperature` (reg 100). Сущности CO2/влажности/TVOC/PM на датчик завязаны, но **ZONT эти регистры для столовой не читает** → значит либо датчик только-температурный, либо в ZONT он заведён частично.
**Почему `|default(0)` — по-прежнему НЕ фикс** (подтверждено): он дал бы `0° 0ppm`, что совпало бы с реальным «нулём» и замаскировало бы поломку. **Правильно — найти, почему датчик отдаёт 0**: не откалиброван / не сконфигурирован в ZONT / просело питание по шине (485-датчики питаются от линии).
> 📌 **Не путать с §5-тер:** там зафиксировано, что `modbus/sensors/dining/*` не публикуется. Здесь — **почему** (датчик отвечает нулём), после того как Alex подтвердил наличие датчика.
> ⛔ **Alex переключил внимание на план миграции** — задачу по датчику столовой **не доделывали** (не чинили ZONT, не трогали реестр). Остаётся в бэклоге как отдельная задача.
### 5-кватер-Б. Развязка Caddy — архитектура и подготовленная правка
**Вопрос Alex:** «GPON всё редиректит на OpenWrt. Как развязываем Caddy? Перенос на OpenWrt?»
**Ответ: НЕТ, Caddy на OpenWrt не переносится.** Разведка показала реальную топологию:
| Компонент | Факт |
|---|---|
| Caddy | **docker-контейнер на TrueNAS** (`/mnt/RED_2TB/docker/caddy/`), порты **8088:80 / 8443:443** |
| OpenWrt `192.168.2.2` | **только пробрасывает** трафик (DNAT), Caddy на нём НЕТ |
| OpenWrt 80/443 | заняты **своим `uhttpd`** (веб-морда LuCI) — конфликт, Caddy туда не встанет |
| DNAT-правила | `firewall.caddy_http` `wan:80 → 192.168.2.197:8088`, `firewall.caddy_https` `wan:443 → 192.168.2.197:8443` |
| Доп. находка | `/etc/config/dhcp`: `list address '/mallexxx.duckdns.org/192.168.0.10'` — внутренний DNS-пин для ZONT |
**Caddyfile на TrueNAS — 20 доменов. Из них на t610 идут ровно ДВА:**
| Домен | Было | Стало (правка) |
|---|---|---|
| `mallexxx.duckdns.org` | `reverse_proxy 192.168.2.197:8123` | **`reverse_proxy 192.168.2.176:80`** |
| `nodered.mallexxx.duckdns.org` | `reverse_proxy 192.168.2.197:1880` | **`reverse_proxy 192.168.2.176:1880`** |
> 🔴 **Урок архитектуры:** 17 из 20 доменов Caddy — это сервисы самого TrueNAS (immich, webdav, git, jellyfin, radarr, sonarr, prowlarr, syncthing, portainer, books, library, transmission, truenas, cam, docs, vpn-panel, vpn). **Уносить Caddy на t610 нельзя** — падение t610 положило бы все медиасервисы. **Правильно: Caddy остаётся на TrueNAS, правим только 2 upstream.**
> ⚠️ **Следствие для Этапа 4:** пока Caddy на TrueNAS — **TrueNAS гасить нельзя**, он держит точку входа. «Погасить TrueNAS» (задача №6) требует отдельного решения о том, где живёт вход (внешний reverse-proxy / отдельный хост). **Записать как открытый вопрос Этапа 4.**
> ⚠️ Порт HA на t610 = **80**, а НЕ 8123 (у t610 `8123` закрыт!) — при правке upstream это главная ловушка.
**Что было подготовлено (правка НЕ применена — упёрлись в sudo):**
| Артефакт | Путь | Статус |
|---|---|---|
| Оригинал (снят с TrueNAS) | `~/tmp-caddy/Caddyfile.orig` | sha256 `25acb94a…` |
| Бэкап оригинала (Mac) | `~/tmp-caddy/Caddyfile.orig.20260914-145006.bak` | 2134 байта, 94 строки |
| Отредактированная версия (2 строки) | `~/tmp-caddy/Caddyfile.orig` | ✅ **`caddy validate` → `Valid configuration`** |
**Порядок, который был выполнен (всё безопасное):**
1. ✅ Правка файла **локально** на Mac (не на хосте — правило «copy → edit → upload»).
2. ✅ Проверка синтаксиса в docker: `docker run --rm -v ~/tmp-caddy/Caddyfile.orig:/etc/caddy/Caddyfile:ro caddy:latest caddy validate --config /etc/caddy/Caddyfile` → **`Valid configuration`** (warnings — предсуществующие, про `header_up` в webdav и форматирование).
3. ✅ Контроль `grep`: остальные 6 upstream на `192.168.2.197` **не тронуты**; diff — ровно 2 строки.
4. ✅ Проверка живости целевых портов: t610 `:80` → **200**, t610 `:1880` → **401** (Node-RED требует логин — норма). Старые адреса TrueNAS тоже живы (есть куда откатываться).
5. ❌ **ЗАЛИВКА НЕ ВЫПОЛНЕНА — блокер: `sudo` на TrueNAS требует пароль.**
**🔴 БЛОКЕР (не решён):** `Caddyfile` на TrueNAS — `root:root 644`, папка root-owned. `cp`/`tee` без sudo → `Permission denied`. `ssh truenas_admin@mallexxx.duckdns.org 'sudo -S tee …'` → `3 incorrect password attempts`. **`truenas_admin` не имеет passwordless sudo** (см. [[family/how-to/truenas-infrastructure]] — «root-операции только через midclt или TrueNAS UI»).
**Варианты обхода (ждём решения Alex):**
| Путь | Как |
|---|---|
| **A** | Передать пароль `truenas_admin` через stdin (`sudo -S`) — Alex присылает пароль |
| **B** | Правит Alex сам (я отдаю готовый файл + diff) |
| **C** | Через TrueNAS UI (File editor / Shell) |
| **D** | ~~Caddy admin API `localhost:2019`~~ — не проброшен наружу, всё равно нужен `docker exec` → снова sudo |
**Откат (если понадобится):** вернуть `~/tmp-caddy/Caddyfile.orig.20260914-145006.bak` на место + `docker restart caddy`.
**Проверка после заливки (по плану):** `docker restart caddy` → `curl -I https://mallexxx.duckdns.org` (должен отдать HA с t610) и `curl -I https://nodered.mallexxx.duckdns.org`.
> 📌 **Питфолл sudo на TrueNAS:** `ssh truenas_admin@mallexxx.duckdns.org 'sudo …'` в неинтерактивном режиме **не работает без пароля** (`a terminal is required to read the password`). Для чтения файлов docker-конфигов sudo часто не нужен (права 644) — но запись в `/mnt/RED_2TB/docker/*` требует root.
> ⚠️ **ПРОЦЕССНЫЙ УРОК СЕССИИ (Alex, жёстко):** агент ушёл в глубокую диагностику датчика столовой, **хотя Alex вёл к плану миграции**. Реплики: «Какая-то с ним хуйня. Какого хуя мы этим занимаемся вообще. В плане миграции блядь чё». **Правило: когда Alex спрашивает «что дальше по плану» — отвечать ПО ПЛАНУ, не уходить в побочную диагностику без его явного запроса.** Диагностика датчика — только после «Что с ним??».
---
## 6. Zigbee (z2m)
### Данные и файлы
@@ -939,10 +1036,11 @@ curl -s -X POST -H "$HDR" -H "Content-Type: application/json" \
| ~~1b~~ | ~~`verify` в заслонках~~ — **✅ ОПРОВЕРГНУТО:** заслонки ожили при том же `verify`. Не причина. | — |
| ~~1c~~ | ~~ZONT-шина на других гнёздах~~ — **✅ СДЕЛАНО:** физический тест доказал (ZONT = гнездо 4, вентиляция = гнездо 3), привязки аддонов обменяны, док приведён в соответствие. Осталась только проверка «① подтвердить у Alex» — **закрыто**: он сам это и тестировал. | — |
| ~~2~~ | ~~Раскомментировать slave 10 (AT2 fans)~~ — **СНЯТО с плана (Alex 2026-09-14): задачи по slave 10 НЕ БЫЛО.** | — |
| 3 | **`sensor.dining_summary` / `dining_air_summary`** — ❌ **ПРЕЖНЯЯ ФОРМУЛИРОВКА ОПРОВЕРГНУТА 2026-09-14 15:39.** Это **НЕ** `\|default(0)`. Причина: 8 сущностей `sensor.dining_*` (`_co2`, `_temperature_2`, `_humidity`, `_tvoc`, `_pm10`, `_pm2_5`, `_formaldehyde`) сидят на MQTT, но **ZONT не публикует `modbus/sensors/dining/*` ВООБЩЕ** (проверено подпиской на MQTT живьём: в трафике только `kids/*` и `bedroom/*`). `int`/`round` на `unknown` → сводка `unavailable`. **Фикс формулой = враньё** (`0° 0ppm`). **Открытый вопрос к Alex: датчик в столовой есть физически?** Если нет — 8 сущностей мусор с TrueNAS, чистить реестр. Если да — чинить ZONT (регистрация/обрыв датчика). Кода не менять до ответа (§5-тер) | — |
| 3 | **`sensor.dining_summary` / `dining_air_summary`** — **🔬 ПРИЧИНА НАЙДЕНА 2026-09-14 (см. §5-кватер-А).** Это **НЕ** `\|default(0)`. Цепочка: 8 сущностей `sensor.dining_*` сидят на MQTT (`modbus_dining_sensor`, создаёт `modbus-bridge`), но **ZONT не публикует `modbus/sensors/dining/*`**. Alex подтвердил: **датчик есть физически**. Лог bridge показал: **ZONT ОПРАШИВАЕТ slave 1 / reg 100 каждые 5 с, датчик ОТВЕЧАЕТ, но значением `0` (`[00 00]`, `CRC OK`)** → bridge считает `0` невалидным → не публикует. **Фикс формулой = враньё** (`0° 0ppm` замаскирует поломку). **Что делать:** искать, почему датчик отдаёт 0 — не откалиброван / не зарегистрирован в ZONT / питание по шине. **НЕ ДОДЕЛАНО** — Alex переключил на план миграции | отдельно |
| 4 | **Камера** — найти образ/папку, поднять на t610, поправить upstream в Caddy | отдельно |
| 5 | **Этап 4:** Caddy upstream → t610, GPON-редирект → t610, перенаправить ZONT на MQTT t610 | — |
| 6 | Остановить + отключить автозапуск сервисов на TrueNAS (не удалять — откат) | — |
| 5 | **Этап 4:** Caddy upstream → t610, GPON-редирект → t610, перенаправить ZONT на MQTT t610. **🔶 ЧАСТИЧНО ПОДГОТОВЛЕНО 2026-09-14 (см. §5-кватер-Б):** правка Caddyfile сделана и **провалидирована** (`Valid configuration`), но **НЕ ЗАЛИТА** — блокер `sudo` на TrueNAS (нужен пароль `truenas_admin`). Меняются ровно 2 upstream: `mallexxx.duckdns.org` → `192.168.2.176:80`, `nodered.*` → `192.168.2.176:1880`. **🔴 Архитектурный вывод: Caddy НЕ переносить** (17 из 20 доменов — сервисы TrueNAS) | — |
| ~~5-арх~~ | ~~«Перенести Caddy на OpenWrt/t610»~~ — **❌ ОТВЕРГНУТО (§5-кватер-Б):** на OpenWrt 80/443 заняты `uhttpd`; у Caddy 17 доменов TrueNAS → при переносе падение t610 положит все медиасервисы. **Caddy остаётся на TrueNAS.** | — |
| 6 | Остановить + отключить автозапуск сервисов на TrueNAS (не удалять — откат). **⚠️ ЗАБЛОКИРОВАНО:** пока Caddy на TrueNAS — он держит точку входа, гасить нельзя. Нужно решение, где живёт вход (§5-кватер-Б) | — |
| 7 | Static IP для t610 на роутере (сейчас DHCP) | — |
| 8 | Бэкап конфигов t610 → TrueNAS + git (Gitea `git.mallexxx.duckdns.org`) | — |
@@ -973,21 +1071,24 @@ curl -s -X POST -H "$HDR" -H "Content-Type: application/json" \
- ✅ **ЗАКРЫТО 2026-09-14 15:33:** гнездо 4 (ZONT-линия) **воткнуто**, `by-path/pci-0000:00:12.0-usb-0:4:1.0-port0` существует, `lsusb` видит оба CH340. `mbusd` работает с гнездом 3, `modbus-bridge` — с гнездом 4. Вся вентиляция/ZONT-линия **в дауне НЕ находится**. Доп. деталь: `by-path` **нестабилен по имени tty** — `usb-0:4` на момент проверки вёл на `ttyUSB1`, а `usb-0:3` на `ttyUSB0` (порядок регистрации не гарантирован). **Привязка только по by-path, tty-номера не запоминать.**
- **Осталось проверить при возврате к теме:** стабильность bridge (см. «НОВОЕ НАБЛЮДЕНИЕ» выше — лог замирал на 7 ч).
**🗺 ПРЕДЛОЖЕННЫЙ ПЛАН НА СЛЕДУЮЩУЮ СЕССИЮ (2026-09-14 15:33, ожидает выбора Alex):**
**🗺 ПЛАН НА СЛЕДУЮЩУЮ СЕССИЮ (обновлено 2026-09-14, вечерняя сессия — A1 снят, Caddy наполовину сделан):**
**Вариант A — безопасный заход (рекомендован агентом):**
> ⚠️ **ОБНОВЛЕНО 2026-09-14 15:39:** шаг **A1 (`|default(0)`) СНЯТ** — его посылка опровергнута (см. §9 задача 3 и §5-тер): `dining_summary` падает не из-за отсутствия `default`, а потому что **ZONT не публикует `modbus/sensors/dining/*`**. Фикс формулой дал бы `0° 0ppm` = враньё на дашборде. **Ждём ответ Alex: датчик в столовой физически есть?**
> ⚠️ **ОБНОВЛЕНО 2026-09-14 (вечер):** шаг **A1 (`|default(0)`) ОКОНЧАТЕЛЬНО СНЯТ** — Alex подтвердил, что датчик есть, и причина найдена: **датчик отвечает нулём** (§5-кватер-А). Фикс формулой замаскировал бы поломку. **Задача №3 переехала в «искать, почему датчик отдаёт 0»** — отдельная, ждёт решения Alex.
| Шаг | Задача | Риск | Действие |
|---|---|---|---|
| ~~A1~~ | ~~№3: `\|default(0)` в template-сенсоры~~ — **❌ СНЯТ, посылка опровергнута** | — | См. §5-тер. Вместо правки кода — вопрос Alex про физику + (если датчика нет) чистка 8 сущностей из реестра |
| ~~A1~~ | ~~№3: `\|default(0)`~~ — **❌ СНЯТ ОКОНЧАТЕЛЬНО** | — | Причина: датчик отвечает `0` (§5-кватер-А). Формула не чинится |
| **B1** | **№5 (Этап 4): ДОЛИТЬ Caddyfile** — главный незакрытый шаг сессии | 🔶 средний | Файл готов и провалидирован (`~/tmp-caddy/`). **Блокер: `sudo` на TrueNAS.** Нужен пароль `truenas_admin` (или Alex правит сам через UI). Затем `docker restart caddy` + проверка двух доменов |
| A2 | **№7**: Static IP для t610 | ✅ низкий | На роутере `192.168.2.2` (SSH root) привязать MAC `9c:8e:99:ef:3f:c5` → `192.168.2.176`. Сервисы не трогаются |
| A3 | **№8**: Бэкап конфигов t610 | ✅ низкий | `tar` конфигов t610 → Mac + TrueNAS + коммит в Gitea `git.mallexxx.duckdns.org` |
**Вариант B — сразу Этап 4** (№5: Caddy upstream → t610, GPON-редирект → t610, ZONT MQTT → t610). 🔴 Трогает рабочее → нужно окно и согласование с Alex.
**Вариант B — Этап 4 целиком** (№5: Caddy upstream → t610 + GPON-редирект → t610 + ZONT MQTT → t610). 🔴 Трогает рабочее → нужно окно и согласование с Alex. **Caddy-часть уже наполовину готова (§5-кватер-Б).**
**Открытый вопрос к Alex:** по «замерзанию» лога bridge — копать сейчас или отложить.
**Открытые вопросы к Alex:**
1. **Caddy:** как заливать файл — дать пароль `truenas_admin` / правишь сам / через UI? (§5-кватер-Б)
2. **Датчик столовой:** почему отдаёт 0 — копать ZONT сейчас или в бэклог? (§5-кватер-А)
3. **«Замерзание» лога bridge** — копать сейчас или отложить.
4. **Этап 4 / погасить TrueNAS:** где живёт точка входа, если Caddy нельзя уносить с TrueNAS? (§5-кватер-Б)
---
@@ -1026,6 +1127,8 @@ docker restart caddy
**Бэкап опций на t610:** `/config/mb-fix-backup-20260914-145419/` (`mbusd-options.json`, `configuration.yaml`).
**Эталон TrueNAS:** `/mnt/RED_2TB/docker/ha/configuration.yaml` (читать без sudo, права 644).
**Развязка Caddy (2026-09-14, вечерняя сессия):** `~/tmp-caddy/` — `Caddyfile.orig` (рабочая копия: скачан с TrueNAS → отредактирован локально, 2 строки → провалидирован), `Caddyfile.orig.20260914-145006.bak` (нетронутый оригинал, sha256 `25acb94a…`). Запуск валидации: `docker run --rm -v ~/tmp-caddy/Caddyfile.orig:/etc/caddy/Caddyfile:ro caddy:latest caddy validate --config /etc/caddy/Caddyfile`. Порядок работы: `scp` вниз → правка локально → `caddy validate` → `grep`-контроль → заливка (⛔ НЕ ЗАВЕРШЕНА — sudo).
---
## 11. История документа
@@ -1084,6 +1187,26 @@ docker restart caddy
> ✅ **Вывод на будущее (правило работы с доком):** при появлении финального объяснения — **сразу переписывать промежуточные гипотезы в статус «опровергнуто с причиной»**, не оставлять их в утвердительном тоне рядом с финалом. §11 — журнал, а не второй источник истины: устаревшие выводы в нём тоже помечать.
### 2026-09-14 (вечерняя сессия: датчик столовой + начало развязки Caddy)
**Контекст:** Alex спросил «что делаем дальше по плану». Агент ушёл в побочную диагностику датчика столовой → Alex дважды осадил («Какая-то с ним хуйня… Какого хуя мы этим занимаемся вообще. В плане миграции блядь чё»). Затем Alex попросил Caddy.
**Что установлено (новое):**
| Тема | Результат |
|---|---|
| Датчик столовой | **Alex подтвердил: датчик физически ЕСТЬ.** Лог bridge: ZONT опрашивает **slave 1 / reg 100 каждые 5 с**, `CRC OK`, но датчик **отвечает `0` (`[00 00]`)** → bridge отбрасывает → `modbus/sensors/dining/*` пусто → `dining_summary` `unavailable`. **Причина НЕ в HA/проводке, а в датчике/ZONT** (см. §5-кватер-А). Фикс формулой = враньё |
| Топология Caddy | Caddy = **docker на TrueNAS** (`8088/8443`), OpenWrt **только DNAT** (`caddy_http`/`caddy_https` → `192.168.2.197`). 80/443 на OpenWrt заняты `uhttpd`. **Перенос на OpenWrt невозможен** (§5-кватер-Б) |
| Состав Caddyfile | **20 доменов, 17 из них — сервисы TrueNAS** → **уносить Caddy нельзя**, правим только 2 upstream |
| Подготовленная правка | `mallexxx.duckdns.org` → `192.168.2.176:80`; `nodered.*` → `192.168.2.176:1880`. **`caddy validate` → `Valid configuration`** |
| Блокер | `Caddyfile` root-owned, `sudo` на TrueNAS **требует пароль****заливка НЕ выполнена** |
**Что менялось в железе:** ничего. Только чтение + подготовка файла локально на Mac.
**Правило (добавлено в процессные уроки):** когда Alex спрашивает «что дальше по плану» — **отвечать по плану**, не уходить в побочную диагностику без явного запроса.
**Открытые вопросы на конец сессии:** ① как заливать Caddyfile (пароль/UI); ② копать ли «0» датчика столовой; ③ «замерзание» лога bridge; ④ где живёт точка входа, если TrueNAS нельзя гасить.
---
## Связанные заметки