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

This commit is contained in:
Alexey Martemyanov
2026-09-14 15:08:25 +06:00
parent 826cefa40a
commit e1552e86b4
+135 -25
View File
@@ -6,10 +6,10 @@
--- ---
## 1. Состояние на 2026-09-14 (актуализировано 15:33) ## 1. Состояние на 2026-09-14 (актуализировано 15:33 → дополнено вечерней сессией)
**Этап 1 ✅ · Этап 2 ✅ · Этап 3 ✅ ЗАКРЫТ.** Остался Этап 4 (переключение трафика и отключение TrueNAS). **Этап 1 ✅ · Этап 2 ✅ · Этап 3 ✅ ЗАКРЫТ.** Этап 4 — **ЧАСТИЧНО СДЕЛАН:** Caddy переключён на t610 (`mallexxx.duckdns.org` → HA на t610, работает), осталось: `nodered.*` (порт), GPON-редирект, ZONT MQTT.
**Последняя верификация: 2026-09-14 15:33 — регресс-проверка после обмена гнёзд пройдена, всё живо (см. ниже). Ничего не менялось (только чтение).** **Последняя верификация: 2026-09-14 (вечер) — Caddyfile залит, Caddy рестартнут, `trusted_proxies` исправлен, `mallexxx.duckdns.org` → HTTP 200.** Детали — §5-кватер-Б и §5-кватер-В.
| Что | Факт | | Что | Факт |
|---|---| |---|---|
@@ -727,30 +727,36 @@ modbus/sensors/bedroom/humidity 36.0
> ⚠️ **Следствие для Этапа 4:** пока Caddy на TrueNAS — **TrueNAS гасить нельзя**, он держит точку входа. «Погасить TrueNAS» (задача №6) требует отдельного решения о том, где живёт вход (внешний reverse-proxy / отдельный хост). **Записать как открытый вопрос Этапа 4.** > ⚠️ **Следствие для Этапа 4:** пока Caddy на TrueNAS — **TrueNAS гасить нельзя**, он держит точку входа. «Погасить TrueNAS» (задача №6) требует отдельного решения о том, где живёт вход (внешний reverse-proxy / отдельный хост). **Записать как открытый вопрос Этапа 4.**
> ⚠️ Порт HA на t610 = **80**, а НЕ 8123 (у t610 `8123` закрыт!) — при правке upstream это главная ловушка. > ⚠️ Порт HA на t610 = **80**, а НЕ 8123 (у t610 `8123` закрыт!) — при правке upstream это главная ловушка.
**Что было подготовлено (правка НЕ применена — упёрлись в sudo):** **✅ ЧТО БЫЛО СДЕЛАНО В ИТОГЕ (2026-09-14, вечерняя сессия — ЗАЛИВКА ЗАВЕРШЕНА):**
| Артефакт | Путь | Статус | | Артефакт | Путь | Статус |
|---|---|---| |---|---|---|
| Оригинал (снят с TrueNAS) | `~/tmp-caddy/Caddyfile.orig` | sha256 `25acb94a…` | | Оригинал (снят с TrueNAS) | `~/tmp-caddy/Caddyfile.orig` → отредактирован; отдельно `Caddyfile.new` | sha256 orig `25acb94a…` → new **`c8c2a5c0…`** |
| Бэкап оригинала (Mac) | `~/tmp-caddy/Caddyfile.orig.20260914-145006.bak` | 2134 байта, 94 строки | | Бэкап оригинала (Mac) | `~/tmp-caddy/Caddyfile.orig.20260914-145006.bak` | 2134 байта, 94 строки |
| Отредактированная версия (2 строки) | `~/tmp-caddy/Caddyfile.orig` | ✅ **`caddy validate` → `Valid configuration`** | | Отредактированная версия (2 строки) | `~/tmp-caddy/Caddyfile.new` | ✅ **`caddy validate` → `Valid configuration`** |
| Файл на TrueNAS (стейджинг) | `/tmp/Caddyfile.new` (от `truenas_admin`) | ✅ sha256 совпал с локальным |
| **Залит на место + Caddy рестартнут** | `/mnt/RED_2TB/docker/caddy/Caddyfile` | ✅ **Alex подменил файл руками и сделал `docker restart caddy`** |
> 🔑 **Финальный обход блокера sudo:** Alex взял готовый файл из `/tmp/Caddyfile.new` и **подменил сам** (путь B из таблицы ниже). `cp` на место root-owned каталога делает он, не агент.
> ✅ **РЕЗУЛЬТАТ: `https://mallexxx.duckdns.org` → HTTP 200 (HA на t610). Alex подтвердил: «HA работает на mallexxx.duckdns».**
**Порядок, который был выполнен (всё безопасное):** **Порядок, который был выполнен (всё безопасное):**
1. ✅ Правка файла **локально** на Mac (не на хосте — правило «copy → edit → upload»). 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 и форматирование). 2. ✅ Проверка синтаксиса в docker: `docker run --rm -v ~/tmp-caddy/Caddyfile.new:/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 строки. 3. ✅ Контроль `grep`: остальные 6 upstream на `192.168.2.197` **не тронуты**; diff — ровно 2 строки.
4. ✅ Проверка живости целевых портов: t610 `:80` → **200**, t610 `:1880` → **401** (Node-RED требует логин — норма). Старые адреса TrueNAS тоже живы (есть куда откатываться). 4. ✅ Проверка живости целевых портов: t610 `:80` → **200**, t610 `:1880` → **401** (Node-RED требует логин — норма). Старые адреса TrueNAS тоже живы (есть куда откатываться).
5. ❌ **ЗАЛИВКА НЕ ВЫПОЛНЕНА — блокер: `sudo` на TrueNAS требует пароль.** 5. ✅ Файл загружен в `/tmp/` на TrueNAS (`scp`), sha256 сверен.
6. ✅ **Alex подменил файл и рестартнул Caddy** → `mallexxx.duckdns.org` работает.
**🔴 БЛОКЕР (не решён):** `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»). **🔴 ПИТФОЛЛ (не решён кодом, обойдён вручную):** `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»). **Рабочий обход на практике: агент готовит и стейджит файл в `/tmp/`, Alex подменяет руками.**
**Варианты обхода (ждём решения Alex):** **Варианты обхода (для будущих правок root-owned файлов TrueNAS):**
| Путь | Как | | Путь | Как | Проверено |
|---|---| |---|---|---|
| **A** | Передать пароль `truenas_admin` через stdin (`sudo -S`) — Alex присылает пароль | | **A** | Передать пароль `truenas_admin` через stdin (`sudo -S`) | ❌ не сработал (3 попытки) |
| **B** | Правит Alex сам (я отдаю готовый файл + diff) | | **B** | **Правит Alex сам (агент отдаёт готовый файл + diff)** | ✅ **ТАК И СДЕЛАЛИ — работает** |
| **C** | Через TrueNAS UI (File editor / Shell) | | **C** | Через TrueNAS UI (File editor / Shell) | не пробовали |
| **D** | ~~Caddy admin API `localhost:2019`~~ — не проброшен наружу, всё равно нужен `docker exec` → снова sudo | | **D** | ~~Caddy admin API `localhost:2019`~~ — не проброшен наружу, всё равно нужен `docker exec` → снова sudo | — |
**Откат (если понадобится):** вернуть `~/tmp-caddy/Caddyfile.orig.20260914-145006.bak` на место + `docker restart caddy`. **Откат (если понадобится):** вернуть `~/tmp-caddy/Caddyfile.orig.20260914-145006.bak` на место + `docker restart caddy`.
@@ -760,6 +766,82 @@ modbus/sensors/bedroom/humidity 36.0
> ⚠️ **ПРОЦЕССНЫЙ УРОК СЕССИИ (Alex, жёстко):** агент ушёл в глубокую диагностику датчика столовой, **хотя Alex вёл к плану миграции**. Реплики: «Какая-то с ним хуйня. Какого хуя мы этим занимаемся вообще. В плане миграции блядь чё». **Правило: когда Alex спрашивает «что дальше по плану» — отвечать ПО ПЛАНУ, не уходить в побочную диагностику без его явного запроса.** Диагностика датчика — только после «Что с ним??». > ⚠️ **ПРОЦЕССНЫЙ УРОК СЕССИИ (Alex, жёстко):** агент ушёл в глубокую диагностику датчика столовой, **хотя Alex вёл к плану миграции**. Реплики: «Какая-то с ним хуйня. Какого хуя мы этим занимаемся вообще. В плане миграции блядь чё». **Правило: когда Alex спрашивает «что дальше по плану» — отвечать ПО ПЛАНУ, не уходить в побочную диагностику без его явного запроса.** Диагностика датчика — только после «Что с ним??».
### 5-кватер-В. 🔴 Пост-заливочные фиксы: `trusted_proxies` (HA за обратным прокси) + порт Node-RED
> Появилось **после** заливки Caddyfile и рестарта. Оба пункта — **новые находки**, которых не было в подготовительной части.
#### В-1. `mallexxx.duckdns.org` отдавал **400 Bad Request** через Caddy — фикс `trusted_proxies`
**Симптом:** снаружи `https://mallexxx.duckdns.org/` → **HTTP 400**, тело `400: Bad Request`, заголовки `server: Python/3.14 aiohttp/3.14.3` + `via: 1.1 Caddy`. При этом **напрямую** `http://192.168.2.176/` отдавал **200** (HTML Home Assistant) — с любым `Host`.
**Диагноз (после ложного следа):**
- ⚠️ **Ложный след (не повторять):** сначала решено было, что `aiohttp`/`Python` — это `modbus-bridge`. **НЕВЕРНО.** `aiohttp` на Python — это **сам HA Core** (HA написан на Python/aiohttp). Признак: `via: 1.1 Caddy` в ответе = ответ прошёл через Caddy от upstream.
- **Настоящая причина:** в `/config/.storage/http` HA настроен `"use_x_forwarded_for": true` при `"trusted_proxies": ["172.16.0.0/12"]` — доверяет только docker-подсетям. **Caddy живёт на ДРУГОМ хосте (`192.168.2.197`, TrueNAS)** → HA видит источник `.197` не из доверенной подсети → **отбивает 400**.
**Фикс (применён 2026-09-14):**
```json
"trusted_proxies": ["172.16.0.0/12", "192.168.2.197/32"]
```
Добавлен `/32` именно адрес TrueNAS (где Caddy), форма CIDR как у остальных записей.
**Порядок применения (`.storage/http` перезаписывается HA на ходу!):**
```bash
# 1) БЭКАП (обязательно)
cp /config/.storage/http /config/.storage/http.bak-$(date +%Y%m%d-%H%M%S)
# 2) ОСТАНОВИТЬ HA (иначе перезапишет правку)
ha core stop # проверить: curl http://192.168.2.176/ → 000
# 3) Правка (локально → scp → cp на место, chmod 600, chown root:root)
# jq '.data.stable.trusted_proxies = ["172.16.0.0/12","192.168.2.197/32"]'
# 4) СТАРТ
ha core start
# 5) Проверка: curl -I https://mallexxx.duckdns.org → 200
```
**Бэкапы:** `/config/.storage/http.bak-20260914-155707` (до правки), `/config/.storage/http.pre-trusted-*`. Рабочая копия на Mac: `~/tmp-t610/httpfix/http.orig` + `http.new` (sha256 orig `a250d277…` → new `ad892817…`).
> ✅ **РЕЗУЛЬТАТ: Alex подтвердил — «HA работает на mallexxx.duckdns».**
> 🔑 **Обобщение (важно для Этапа 4 и любого внешнего reverse-proxy перед HA):** если перед HA стоит прокси с **другого хоста** — его IP **обязан** быть в `trusted_proxies`, иначе `use_x_forwarded_for: true` даёт **400**. Docker-подсети (`172.16.0.0/12`) этого не покрывают.
> ⚠️ Альтернатива (не выбрана): запретить Caddy передавать `X-Forwarded-For` — но тогда HA видит все запросы как «от Caddy», теряются реальные IP (и `ip_ban`/логи бесполезны). Хуже.
#### В-2. `nodered.mallexxx.duckdns.org` — **401 от nginx HA**, а не страница Node-RED
**Симптом (Alex):** «вижу basic http auth, а не страницу логина Node-RED — и мой логин/пароль от nodered на truenas не подходит».
**Что показал ответ:**
```
GET https://nodered.mallexxx.duckdns.org/
HTTP/2 401
server: nginx
www-authenticate: Basic realm="Home Assistant Authentication" ← это НЕ Node-RED
```
И напрямую на t610 — то же: `GET http://192.168.2.176:1880/` → `401 Server: nginx ... realm="Home Assistant Authentication"`.
**🔴 ДИАГНОЗ: порт `1880` на t610 занят nginx'ом HA OS (ingress-прокси аддонов), а НЕ Node-RED.** Basic auth, который видит Alex, — это **HA**, не Node-RED. Отсюда и «пароль от nodered не подходит»: логин вообще не Node-RED-овский.
**Почему Node-RED не торчит наружу, хотя `host_network: true` (разбор Alex'а — верный вопрос):**
```json
"host_network": true,
"network": { "80/tcp": 1880 }
```
- Маппинг читается как «порт **80** контейнера → **1880** хоста». Но Node-RED слушает **1880 внутри** контейнера (`uiPort` в `settings.js` не задан → дефолт 1880). **Порт 80 контейнера пустой** → наружу Node-RED не выходит.
- Признак, что `host_network: true` фактически **не применился**: `ha apps info a0d7b954_nodered` → `"ip_address": "172.30.32.1"` (**docker-сеть supervisor'а**, а при реальном host-network был бы `192.168.2.176`).
- Порт-скан снаружи t610: живы только **80** (HA) и **1880** (nginx HA). Node-RED-порта нет ни на 1880/11880/3000/… Хостовые порты `netstat` из SSH-аддона **не видит** (песочница аддона) — только 22/8099.
**Проверено попутно:**
| Факт | Значение |
|---|---|
| `flows.json` на t610 | **124 байта — ПУСТО, ни одного потока** (Node-RED не настроен) |
| `uiPort` в `settings.js` | не задан → дефолт **1880** |
| Node-RED доступен через ingress | `/api/hassio_ingress/4vUcCxEpYJMbQ64z-kWPCvFadq8ayl4lzvzJPDUaZzE/` (работает без Caddy) |
| Конфиг аддона | `/addon_configs/a0d7b954_nodered/` (`settings.js`, `flows.json`) |
**План правки (выбран Alex — «порт продерни», Вариант 3; НЕ ВЫПОЛНЕН — сессия прервана):**
- В опциях аддона `a0d7b954_nodered`: `network` `{ "80/tcp": 1880 }` → **`{ "1880/tcp": 11880 }`** (порт 1880 контейнера → 11880 хоста; **1880 хоста занят nginx HA — брать нельзя**), `host_network` **убрать**.
- Затем Caddyfile: `nodered.*` → `192.168.2.176:11880` + reload.
- ⚠️ **Порт-маппинг при `host_network: true` игнорируется** — потому и не выставлялся наружу.
- ⚠️ **Открытый вопрос к Alex (задан, ответа нет):** на t610 Node-RED **пустой**, на TrueNAS — со всеми потоками. Нужен ли t610-Node-RED вообще, или переносить flows?
> 📌 **Питфолл диагностики:** «basic auth вместо страницы X» + `server: nginx` + `realm="Home Assistant Authentication"` = **это nginx HA OS (ingress), а не целевой сервис**. Смотреть `server:` и `www-authenticate`, прежде чем искать логин.
--- ---
## 6. Zigbee (z2m) ## 6. Zigbee (z2m)
@@ -1038,11 +1120,12 @@ curl -s -X POST -H "$HDR" -H "Content-Type: application/json" \
| ~~2~~ | ~~Раскомментировать slave 10 (AT2 fans)~~ — **СНЯТО с плана (Alex 2026-09-14): задачи по slave 10 НЕ БЫЛО.** | — | | ~~2~~ | ~~Раскомментировать slave 10 (AT2 fans)~~ — **СНЯТО с плана (Alex 2026-09-14): задачи по slave 10 НЕ БЫЛО.** | — |
| 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 переключил на план миграции | отдельно | | 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 | отдельно | | 4 | **Камера** — найти образ/папку, поднять на t610, поправить upstream в Caddy | отдельно |
| 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~~ | ~~**Этап 4:** Caddy upstream → t610~~ — ** ЧАСТЬ «CADDY» ЗАКРЫТА 2026-09-14 (см. §5-кватер-Б/В):** Caddyfile залит (Alex подменил файл + `restart caddy`), `mallexxx.duckdns.org` → **HTTP 200** (HA на t610, подтверждено Alex'ом), попутно исправлен `trusted_proxies` в `.storage/http` (§5-кватер-В-1). **ОСТАЛОСЬ из Этапа 4:** ① `nodered.*` — починить порт (см. задачу 5-нр ниже); ② GPON-редирект → t610; ③ ZONT MQTT → t610. **🔴 Архитектурный вывод: Caddy НЕ переносить** (17 из 20 доменов — сервисы TrueNAS) | — |
| 5-нр | **Node-RED наружу** — `nodered.mallexxx.duckdns.org` сейчас отдаёт **401 от nginx HA**, не Node-RED (порт `1880` на t610 занят nginx'ом HA OS). Alex выбрал: **выставить порт наружу** — опции аддона `network { "80/tcp": 1880 }` → `{ "1880/tcp": 11880 }`, `host_network` убрать; затем Caddy → `192.168.2.176:11880`. Подробно и с питфоллами — **§5-кватер-В-2**. ⚠️ **НЕ ВЫПОЛНЕНО** (сессия прервана). ⚠️ Открытый вопрос: на t610 Node-RED **пустой** (124 B flows), на TrueNAS — с потоками | — |
| ~~5-арх~~ | ~~«Перенести Caddy на OpenWrt/t610»~~ — **❌ ОТВЕРГНУТО (§5-кватер-Б):** на OpenWrt 80/443 заняты `uhttpd`; у Caddy 17 доменов TrueNAS → при переносе падение t610 положит все медиасервисы. **Caddy остаётся на TrueNAS.** | — | | ~~5-арх~~ | ~~«Перенести Caddy на OpenWrt/t610»~~ — **❌ ОТВЕРГНУТО (§5-кватер-Б):** на OpenWrt 80/443 заняты `uhttpd`; у Caddy 17 доменов TrueNAS → при переносе падение t610 положит все медиасервисы. **Caddy остаётся на TrueNAS.** | — |
| 6 | Остановить + отключить автозапуск сервисов на TrueNAS (не удалять — откат). **⚠️ ЗАБЛОКИРОВАНО:** пока Caddy на TrueNAS — он держит точку входа, гасить нельзя. Нужно решение, где живёт вход (§5-кватер-Б) | — | | 6 | Остановить + отключить автозапуск сервисов на TrueNAS (не удалять — откат). **⚠️ ЗАБЛОКИРОВАНО:** пока Caddy на TrueNAS — он держит точку входа, гасить нельзя. Нужно решение, где живёт вход (§5-кватер-Б) | — |
| 7 | Static IP для t610 на роутере (сейчас DHCP) | — | | 7 | Static IP для t610 на роутере (сейчас DHCP) | — |
| 8 | Бэкап конфигов t610 → TrueNAS + git (Gitea `git.mallexxx.duckdns.org`) | — | | 8 | Бэкап конфигов t610 → TrueNAS + git (Gitea `git.mallexxx.duckdns.org`). **📌 Добавить в бэкап:** `/config/.storage/http` (после фикса `trusted_proxies`) и сам `Caddyfile` | — |
**✅ Закрыто в этой сессии (2026-09-14, поздняя):** **✅ Закрыто в этой сессии (2026-09-14, поздняя):**
- **Office table switch** — не управлял светом. Две причины: ① hex-`entity_id` в **триггерах** автоматизаций; ② `not_from: [unknown]` блокировал первое нажатие. Оба фикса применены, проверено на живом (оба канала). - **Office table switch** — не управлял светом. Две причины: ① hex-`entity_id` в **триггерах** автоматизаций; ② `not_from: [unknown]` блокировал первое нажатие. Оба фикса применены, проверено на живом (оба канала).
@@ -1071,21 +1154,23 @@ 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-номера не запоминать.** - ✅ **ЗАКРЫТО 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 ч). - **Осталось проверить при возврате к теме:** стабильность bridge (см. «НОВОЕ НАБЛЮДЕНИЕ» выше — лог замирал на 7 ч).
**🗺 ПЛАН НА СЛЕДУЮЩУЮ СЕССИЮ (обновлено 2026-09-14, вечерняя сессия — A1 снят, Caddy наполовину сделан):** **🗺 ПЛАН НА СЛЕДУЮЩУЮ СЕССИЮ (обновлено 2026-09-14, вечерняя сессия — B1 СДЕЛАН, добавлен Node-RED):**
> ⚠️ **ОБНОВЛЕНО 2026-09-14 (вечер):** шаг **A1 (`|default(0)`) ОКОНЧАТЕЛЬНО СНЯТ** — Alex подтвердил, что датчик есть, и причина найдена: **датчик отвечает нулём** (§5-кватер-А). Фикс формулой замаскировал бы поломку. **Задача №3 переехала в «искать, почему датчик отдаёт 0»** — отдельная, ждёт решения Alex. > ⚠️ **ОБНОВЛЕНО 2026-09-14 (вечер, позже):** шаг **B1 (Caddyfile) ВЫПОЛНЕН** — файл залит, Caddy рестартнут, домен работает. Дополнительно **применён фикс `trusted_proxies`** (§5-кватер-В-1). Появилась новая задача — **Node-RED-порт** (§5-кватер-В-2).
| Шаг | Задача | Риск | Действие | | Шаг | Задача | Риск | Действие |
|---|---|---|---| |---|---|---|---|
| ~~A1~~ | ~~№3: `\|default(0)`~~ — **❌ СНЯТ ОКОНЧАТЕЛЬНО** | — | Причина: датчик отвечает `0` (§5-кватер-А). Формула не чинится | | ~~A1~~ | ~~№3: `\|default(0)`~~ — **❌ СНЯТ ОКОНЧАТЕЛЬНО** | — | Причина: датчик отвечает `0` (§5-кватер-А). Формула не чинится |
| **B1** | **№5 (Этап 4): ДОЛИТЬ Caddyfile** — главный незакрытый шаг сессии | 🔶 средний | Файл готов и провалидирован (`~/tmp-caddy/`). **Блокер: `sudo` на TrueNAS.** Нужен пароль `truenas_admin` (или Alex правит сам через UI). Затем `docker restart caddy` + проверка двух доменов | | ~~B1~~ | ~~**№5 (Этап 4): ДОЛИТЬ Caddyfile**~~**✅ СДЕЛАН + `trusted_proxies` фикс** | — | Alex подменил файл + `docker restart caddy`. `mallexxx.duckdns.org` → 200. Затем `.storage/http` → `trusted_proxies += 192.168.2.197/32` (§5-кватер-В) |
| **B2** | **Node-RED наружу** — выставить порт аддона и поправить Caddy | 🔶 средний | Опции `a0d7b954_nodered`: `{ "1880/tcp": 11880 }`, `host_network` убрать → рестарт → Caddy `nodered.*` → `192.168.2.176:11880` + reload. **Сначала ответить: нужен ли пустой t610-Node-RED?** (§5-кватер-В-2) |
| **B3** | **Этап 4, остаток:** GPON-редирект → t610, ZONT MQTT → t610 | 🔴 высокий | Трогает живое → окно + согласование |
| A2 | **№7**: Static IP для t610 | ✅ низкий | На роутере `192.168.2.2` (SSH root) привязать MAC `9c:8e:99:ef:3f:c5` → `192.168.2.176`. Сервисы не трогаются | | 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` | | A3 | **№8**: Бэкап конфигов t610 | ✅ низкий | `tar` конфигов t610 (`/config`, **`.storage/http`**, Caddyfile) → Mac + TrueNAS + коммит в Gitea `git.mallexxx.duckdns.org` |
**Вариант B — Этап 4 целиком** (№5: Caddy upstream → t610 + GPON-редирект → t610 + ZONT MQTT → t610). 🔴 Трогает рабочее → нужно окно и согласование с Alex. **Caddy-часть уже наполовину готова (§5-кватер-Б).** **Вариант B — Этап 4 целиком** (№5: Caddy upstream → t610 + GPON-редирект → t610 + ZONT MQTT → t610). 🔴 Трогает рабочее → нужно окно и согласование с Alex. **Caddy-часть СДЕЛАНА (§5-кватер-Б/В).**
**Открытые вопросы к Alex:** **Открытые вопросы к Alex:**
1. **Caddy:** как заливать файл — дать пароль `truenas_admin` / правишь сам / через UI? (§5-кватер-Б) 1. **Node-RED:** на t610 **пустой** (124 B flows), на TrueNAS — с потоками. Нужен ли t610-Node-RED, или переносить flows? Порт выставляем? (§5-кватер-В-2)
2. **Датчик столовой:** почему отдаёт 0 — копать ZONT сейчас или в бэклог? (§5-кватер-А) 2. **Датчик столовой:** почему отдаёт 0 — копать ZONT сейчас или в бэклог? (§5-кватер-А)
3. **«Замерзание» лога bridge** — копать сейчас или отложить. 3. **«Замерзание» лога bridge** — копать сейчас или отложить.
4. **Этап 4 / погасить TrueNAS:** где живёт точка входа, если Caddy нельзя уносить с TrueNAS? (§5-кватер-Б) 4. **Этап 4 / погасить TrueNAS:** где живёт точка входа, если Caddy нельзя уносить с TrueNAS? (§5-кватер-Б)
@@ -1127,7 +1212,9 @@ docker restart caddy
**Бэкап опций на t610:** `/config/mb-fix-backup-20260914-145419/` (`mbusd-options.json`, `configuration.yaml`). **Бэкап опций на t610:** `/config/mb-fix-backup-20260914-145419/` (`mbusd-options.json`, `configuration.yaml`).
**Эталон TrueNAS:** `/mnt/RED_2TB/docker/ha/configuration.yaml` (читать без sudo, права 644). **Эталон 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). **Развязка Caddy (2026-09-14, вечерняя сессия) — ✅ ЗАВЕРШЕНА:** `~/tmp-caddy/` — `Caddyfile.orig` (оригинал с TrueNAS, sha256 `25acb94a…`) и `Caddyfile.new` (рабочий, 2 правки, sha256 **`c8c2a5c0…`**, `Valid configuration`), `Caddyfile.orig.20260914-145006.bak` (бэкап оригинала). `local.sha256`. Рабочий процесс: `scp` вниз → правка локально → `caddy validate` в docker → `grep`-контроль → `scp` в `/tmp/` на TrueNAS → **Alex подменяет файл + `docker restart caddy`**. Валидация: `docker run --rm -v ~/tmp-caddy/Caddyfile.new:/etc/caddy/Caddyfile:ro caddy:latest caddy validate --config /etc/caddy/Caddyfile`.
**Фикс `trusted_proxies` (2026-09-14, вечерняя сессия):** `~/tmp-t610/httpfix/` — `http.orig` (sha256 `a250d277…`), `http.orig.<ts>.bak`, `http.new` (sha256 `ad892817…`, добавлен `192.168.2.197/32`). На t610: `/config/.storage/http.bak-20260914-155707`, `/config/.storage/http.pre-trusted-*`.
--- ---
@@ -1207,6 +1294,29 @@ docker restart caddy
**Открытые вопросы на конец сессии:** ① как заливать Caddyfile (пароль/UI); ② копать ли «0» датчика столовой; ③ «замерзание» лога bridge; ④ где живёт точка входа, если TrueNAS нельзя гасить. **Открытые вопросы на конец сессии:** ① как заливать Caddyfile (пароль/UI); ② копать ли «0» датчика столовой; ③ «замерзание» лога bridge; ④ где живёт точка входа, если TrueNAS нельзя гасить.
### 2026-09-14 (вечерняя сессия, продолжение: Caddy ЗАЛИТ, фикс trusted_proxies, порт Node-RED)
**Контекст:** Alex подтвердил заливку Caddyfile и рестарт Caddy → домен заработал, но вылезли два новых дефекта.
**Что сделано / установлено (новое):**
| Тема | Результат |
|---|---|
| Caddyfile залит | ✅ Alex подменил файл руками (из `/tmp/Caddyfile.new`) + `docker restart caddy`. **`https://mallexxx.duckdns.org` → HTTP 200** (HA на t610). Подтверждено Alex'ом |
| 🔴 `trusted_proxies` | `mallexxx.duckdns.org` сначала отдавал **400 Bad Request** (`server: Python/aiohttp`, `via: 1.1 Caddy`). Причина: HA `use_x_forwarded_for: true` при `trusted_proxies: ["172.16.0.0/12"]` — **Caddy с другого хоста (`.197`) не в доверенных** → 400. **Фикс:** добавить `192.168.2.197/32` в `/config/.storage/http` (при остановленном HA). Применено → 200 (§5-кватер-В-1) |
| ⚠️ Ложный след | `aiohttp`/`Python` в ответе — это **сам HA Core**, НЕ `modbus-bridge` (поспешный вывод, исправлен) |
| 🔴 `nodered.*` = 401 от nginx HA | Порт **1880 на t610 занят nginx'ом HA OS** (ingress), не Node-RED → basic auth HA, не логин Node-RED. Причина, почему Node-RED не торчал: `network { "80/tcp": 1880 }` при `host_network: true` — **маппинг не туда**, Node-RED слушает 1880 внутри (§5-кватер-В-2) |
| Node-RED пустой | `flows.json` = **124 байта**, ни одного потока. На TrueNAS — с потоками. Открытый вопрос Alex'у |
| Решение Alex | «порт продерни» → `{ "1880/tcp": 11880 }`, `host_network` убрать, Caddy → `:11880`. **НЕ ВЫПОЛНЕНО** — сессия прервана на подтверждении плана |
**Что менялось в железе:** `Caddyfile` на TrueNAS (залит Alex'ом), `/config/.storage/http` на t610 (`trusted_proxies += 192.168.2.197/32`, применено с `ha core stop/start`). **HA на t610 пережил остановку/старт** — проверено Alex'ом (домен 200).
**Бэкапы:** `~/tmp-caddy/Caddyfile.orig.20260914-145006.bak` (оригинал), `~/tmp-t610/httpfix/http.orig.<ts>.bak`, на t610 `/config/.storage/http.bak-20260914-155707`.
**Правило (в процессные уроки):** **root-owned файлы TrueNAS агент не пишет** — готовит и стейджит в `/tmp/`, **подменяет Alex**. `sudo -S` с паролем у `truenas_admin` не прошёл.
**Открытые вопросы:** ① нужен ли пустой t610-Node-RED / переносить flows? ② копать ли «0» датчика столовой; ③ «замерзание» лога bridge; ④ GPON-редирект и ZONT MQTT → t610 (остаток Этапа 4); ⑤ где живёт точка входа, если TrueNAS нельзя гасить.
--- ---
## Связанные заметки ## Связанные заметки