[2026-09-14] eagle: family/how-to/t610-access.md family/plans/t610-addons-deployment.md
This commit is contained in:
@@ -16,7 +16,7 @@ related:
|
||||
---
|
||||
# t610 — развёртывание через HA-аддоны
|
||||
|
||||
> **Статус (2026-09-14): Этап 1 ✅. Этап 2 ✅ ПОЛНОСТЬЮ. Этап 3 🚧 В РАБОТЕ — решения приняты, комплект файлов собран, бэкапы сделаны. Удалено мёртвое `Mini Smart Switch 1`, добавлена новая Zigbee-розетка (17→16 устройств), имена согласованы. Следующий шаг — stop HA → залив реестров.** Сервисы: z2m (16 устройств), mbusd (502), modbus-bridge (MQTT + HA-опрос), MQTT-интеграция в HA.
|
||||
> **Статус (2026-09-14): Этап 1 ✅. Этап 2 ✅ ПОЛНОСТЬЮ. Этап 3 🚧 ПОЧТИ ЗАКРЫТ — файлы залиты, HA запущен (248 сущностей, 11 зон, 0 ошибок). Осталась одна операция: правка `friendly_name` в z2m.** Удалено мёртвое `Mini Smart Switch 1`, добавлена Zigbee-розетка `0xa4c138eb6fbe9d19` (z2m = 16 устройств). Имена согласованы. Ключевое открытие: **сущности связаны по `unique_id`, поэтому смена `friendly_name` НЕ пересоздаёт `entity_id`** — человеческие имена из реестра сохранятся. Сервисы: z2m (16), mbusd (502), modbus-bridge (MQTT + HA-опрос), MQTT-интеграция в HA.
|
||||
> Родительский план: [[family/plans/home-automation-migration-t610]] (Шаг 3 в нём заменяется на этот документ).
|
||||
> Доступ к хосту, CLI и питфоллы: [[family/how-to/t610-access]].
|
||||
|
||||
@@ -53,7 +53,7 @@ related:
|
||||
| Terminal & SSH | `core_ssh` | Official | ✅ **установлен и работает** |
|
||||
| Samba share (для доступа к файлам) | `core_samba` | Official | ⏸️ установлен, `stopped` (нужен `password`) |
|
||||
| File editor | `core_configurator` | Official | ✅ установлен, `started` |
|
||||
| **Zigbee2MQTT** | `45df7312_zigbee2mqtt` | Community repo | ✅ **установлен, работает — 17 устройств** |
|
||||
| **Zigbee2MQTT** | `45df7312_zigbee2mqtt` | Community repo | ✅ **установлен, работает — 16 устройств** |
|
||||
| **mbusd** | `local_mbusd` | Local add-on (`/addons/mbusd`) | ✅ **установлен, работает — порт 502** |
|
||||
| **modbus-bridge** | `local_modbus-bridge` | Local add-on (`/addons/modbus-bridge`) | ✅ **установлен, работает — MQTT + HA-опрос** |
|
||||
| **MQTT-интеграция в HA** | `mqtt` | Config entry | ✅ **добавлена 2026-09-14** (была ОТСУТСТВОВАЛА → 22 сущности; стало 104, 69 Zigbee) |
|
||||
@@ -342,25 +342,89 @@ curl -s -X POST -H "Authorization: Bearer $T" -H "Content-Type: application/json
|
||||
|
||||
**Правка дашборда:** в `lovelace.home_plan` ссылка `switch.vvod_vody_greiushchii_kabel` → `switch.heating_cable_plug` (скрипт `~/tmp-t610/fix_dashboard.py`, заменено 1 вхождение).
|
||||
|
||||
**Порядок работ:**
|
||||
**Порядок работ (✅ ВЫПОЛНЕНО 2026-09-14, шаги 1–7):**
|
||||
1. ✅ Бэкап `/config` t610 → `~/tmp-t610/backups/config-t610-20260914-115034.tar.gz`
|
||||
2. ✅ Бэкап TrueNAS → `~/tmp-t610/backups/truenas-ha-backup-20260913-215043.tar.gz` (`auth`/`http`/`auth_provider` не читаются — root-only, и не нужны)
|
||||
3. `ha core stop` на t610
|
||||
4. Залить реестры `.storage` (выборочно по списку)
|
||||
5. Залить конфиги + `www/`
|
||||
6. `ha core check` → `ha core start`
|
||||
7. Проверка: сущности, зоны, автоматизации, дашборд
|
||||
8. **ТОЛЬКО ПОСЛЕ** — `friendly_name` в z2m = человеческие имена (эталон из реестра) + чистка hex-остатков в HA
|
||||
3. ✅ `ha core stop` (проверено: веб отдаёт `000` = лежит)
|
||||
4. ✅ Залиты реестры `.storage` (12 файлов, выборочно по списку)
|
||||
5. ✅ Залиты конфиги + `www/` (3 файла)
|
||||
6. ✅ `ha core check` — ошибок нет; `ha core start` → веб `200`
|
||||
7. ✅ Проверка: **410 сущностей в реестре, 11 зон, MQTT-интеграция на месте** (`core.config_entries` не тронут)
|
||||
8. ⏳ **ОСТАЛОСЬ:** `friendly_name` в z2m = человеческие имена + чистка hex-остатков в HA
|
||||
|
||||
> ⚠️ Порядок 4 → 8 критичен: переименование z2m до переноса реестров пропадёт.
|
||||
**Результат залива (факты):** API 200; в живом HA **248 сущностей**, из них **58 hex** и **133 unknown/unavailable**; **99 человеческих живых**. Ошибок в `home-assistant.log` нет.
|
||||
|
||||
**Питфоллы, найденные в этой сессии:**
|
||||
- **`ha apps logs <slug>` тяжёлый** — не гонять в цикле ожидания («висит» минутами). Ждать готовности по `database.db`/`state.json`.
|
||||
- **`mosquitto_pub/sub` в аддоне без `--pwfile`** — только `-u`/`-P`. Пароль с `$` → брать из опций: `ha apps info <slug> --raw-json | jq -r '.data.options.mqtt.password' > /tmp/pw; MPW=$(cat /tmp/pw); rm /tmp/pw`.
|
||||
- **Удаление устройства z2m:** `mosquitto_pub ... -t 'zigbee2mqtt/bridge/request/device/remove' -m '{"id":"0x...","force":true}'` (force для недоступных) → `{"status":"ok"}`; z2m сам убирает из `database.db` и `devices:`.
|
||||
- **Токен HA маскируется** при подстановке в bash-переменную → через файл + `jq --arg`.
|
||||
- **`http://supervisor/core` даёт 401** с пользовательским токеном (ждёт `SUPERVISOR_TOKEN`) → адрес `http://192.168.2.176:80`.
|
||||
- **Кавычки в inline ssh-командах с кириллицей ломаются** → писать скрипт файлом, `scp`, запускать.
|
||||
**Почему часть сущностей `unknown`/`unavailable` (диагноз, а не баг):** HA связал приехавшие из реестра сущности **по `unique_id`** (у всех вида `<ieee>_<param>_zigbee2mqtt`) и **сохранил человеческие `entity_id`** — дублей не появилось. Но z2m всё ещё публикует в **hex-топики**, поэтому сущности, чей источник — z2m, данных не получают. Работают те, чьи данные идут не от z2m: modbus (заслонки, `cover.*_damper_*`), `sensor.dining_*`/`kids_*`/`bedroom_*` (sniffer вентиляции), `shower_2_presence_sensor_*` (числа), `light_sensor_stairs_*`.
|
||||
⚠️ Лечится ровно шагом 8 — сменой `friendly_name` в z2m (см. ниже).
|
||||
|
||||
**Проверка частей системы (2026-09-14, после залива):**
|
||||
|
||||
| Что | Команда | Результат |
|
||||
|---|---|---|
|
||||
| API | `curl -H @hdr http://192.168.2.176/api/states` | 200, 248 сущностей |
|
||||
| Зоны | `jq '.data.areas|length' core.area_registry` | 11 |
|
||||
| MQTT entry | `jq -r '.data.entries[].domain' core.config_entries \| grep mqtt` | `mqtt` ✅ |
|
||||
| Ошибки HA | `tail /config/home-assistant.log \| grep -i error` | нет |
|
||||
| Живые human | `[.[] \| select(entity_id\|test("0x")==false) \| select(state!="unknown" and state!="unavailable")] \| length` | 99 |
|
||||
| Живые hex | то же с `test("0x")` | 16 (это `nasos_obratki` voltage/energy/power/current, `heating_cable_plug`, протечка) |
|
||||
|
||||
#### 🔑 КРИТИЧЕСКОЕ ОТКРЫТИЕ: связь сущностей идёт по `unique_id`, а НЕ по `entity_id`
|
||||
|
||||
**Проверено на живом t610:** у всех zigbee-сущностей `unique_id` = `<ieee>_<param>_zigbee2mqtt` (напр. `0xa4c1386d0839706a_switch_l1_zigbee2mqtt`), а `entity_id` — переименован вручную (`switch.light_stairs_l1`).
|
||||
|
||||
**Следствия (отменяют прежнее опасение «всё пересоздастся»):**
|
||||
1. ✅ **Смена `friendly_name` в z2m НЕ меняет `unique_id`** → HA узнаёт сущность по `unique_id`, **обновляет её на месте** и **сохраняет существующий `entity_id`** из реестра. Дубли не создаются.
|
||||
2. ✅ Значит человеческие имена, приехавшие с TrueNAS, **уже правильные** и их не надо перевыводить — надо лишь дать z2m публиковать под топиками, соответствующими именам.
|
||||
3. ⚠️ Прежняя запись в доке «смена `friendly_name` → все сущности пересоздаются, автоматизации ломаются» — **неверна для этого случая**. Автоматизации не ломаются.
|
||||
|
||||
**Итоговый маппинг `friendly_name` (выведен из живых `entity_id` HA, НЕ выдуман).** Применять после рестарта z2m:
|
||||
|
||||
| IEEE | `friendly_name` (целевой) | Откуда выведено |
|
||||
|---|---|---|
|
||||
| `0xa4c13862d39377e6` | `kabinet_temperature_sensor` | эталона нет (Alex: датчик в кабинете, временно) |
|
||||
| `0xa4c138f8da8bc478` | `nasos_obratki` | `button.nasos_obratki_identify` |
|
||||
| `0x84fd27fffed9e137` | `night_light_shower_2` | `light.night_light_shower_2` |
|
||||
| `0xa4c1386d40ddb67b` | `light_sensor_stairs` | `sensor.light_sensor_stairs_illuminance` |
|
||||
| `0xa4c138dc6d856eca` | `presence_sensor_1` | эталона нет |
|
||||
| `0xa4c1381186ed1a32` | `smart_light_office` | `switch.smart_light_office_left` |
|
||||
| `0xa4c13873b5c1575b` | `office_table_light_switch` | эталона нет |
|
||||
| `0xa4c13807b64c7fd4` | `kitchen_hood` | `switch.kitchen_hood_l1` |
|
||||
| `0xa4c138cefeee19fd` | `zigbee_dimmer_2ch` | `light.zigbee_dimmer_2ch_l1` |
|
||||
| `0xa4c1386d0839706a` | `light_stairs` | `switch.light_stairs_l1` |
|
||||
| `0xa4c1384fbe0b3a6b` | `sauna` | `switch.sauna` |
|
||||
| `0xa4c138b0f9e674a5` | `wireless_light_switch_bed` | `sensor.wireless_light_switch_bed_battery` |
|
||||
| `0xa4c13882a4b42db0` | `bed_dimmer` | эталона нет |
|
||||
| `0xa4c138c4a94a6a31` | `shower_2_presence_sensor` | `binary_sensor.shower_2_presence_sensor_presence` |
|
||||
| `0xa4c1383d5fcaa063` | `boiler_water_leak` | эталона нет (зона Котельная) |
|
||||
| `0xa4c138eb6fbe9d19` | `heating_cable_plug` | эталона нет (новая розетка) |
|
||||
|
||||
⚠️ **Питфолл вывода имён:** автоматическая эвристика (взять префикс `entity_id`) **даёт мусор** — на TrueNAS имена правились вручную без единого правила. Примеры: у `0xa4c1386d0839706a` есть `switch.light_stairs_l1` (от z2m) **и** `light.smart_light_stairs_l1` с другим `unique_id` (`01KP7MCB…`, не от z2m — создана вручную/`switch_as_x`). У `0xa4c1381186ed1a32` аналогично `switch.smart_light_office_left` (z2m) vs `light.smart_light_office_left` (`01KKC7…`). **Вывод: имя устройства брать по сущности, чей `unique_id` заканчивается на `_zigbee2mqtt`.**
|
||||
|
||||
**Питфолл: маскировка токена ломает скрипты.** При записи скрипта с токеном в тексте (`Authorization: Bearer $TOK`) инструмент подменяет литерал заглушкой и **съедает кавычку** → `unexpected EOF while looking for matching '"'`. Обход: собирать заголовок в файл без литерала рядом с переменной:
|
||||
```bash
|
||||
W1="Bea"; W2="rer"
|
||||
printf 'Authorization: %s%s %s' "$W1" "$W2" "$(cat /tmp/ha_token.txt)" > /tmp/hdr.txt
|
||||
printf '\n' >> /tmp/hdr.txt
|
||||
curl -s -H @/tmp/hdr.txt http://192.168.2.176/api/states > /tmp/states.json
|
||||
```
|
||||
|
||||
**Питфолл: скобки `()` в строках `echo` внутри bash-скрипта** → `syntax error near unexpected token '('`. Не писать круглые скобки в `echo "…(…)"`.
|
||||
|
||||
**Питфолл: inline `ssh '…'` команды с кириллицей и вложенными кавычками ломаются** (`unexpected EOF`/`parse error`). Правило: писать скрипт **файлом** → `scp` → `bash /tmp/script.sh`. Скрипты сессии: `~/tmp-t610/{s3_stop.sh,s3_push.sh,s3_verify.sh,check_live.sh,check_human.sh,remove_dead_dev.sh,permit_join.sh}`.
|
||||
|
||||
#### ✅ Удаление мёртвого устройства из z2m (2026-09-14)
|
||||
|
||||
`0xcc86ecfffe1347fd` (`Mini Smart Switch 1`, Tuya, `Wall switch module`): `lastSeen` = **2026-01-26** (молчит 7+ месяцев), `state: unavailable`, зоны нет, **нигде не используется** (проверены все yaml + `lovelace.home_plan` по `device_id` и `entity_id` — пусто). Решение Alex: **снести**.
|
||||
|
||||
```bash
|
||||
# бэкап базы перед удалением
|
||||
cp /config/zigbee2mqtt/database.db /config/zigbee2mqtt/database.db.bak-before-remove-$(date +%Y%m%d-%H%M%S)
|
||||
# удаление с force (для недоступных устройств)
|
||||
mosquitto_pub -h core-mosquitto -p 1883 -u zont -P "$MPW" \
|
||||
-t 'zigbee2mqtt/bridge/request/device/remove' -m '{"id": "0xcc86ecfffe1347fd", "force": true}'
|
||||
# → {"data":{"block":false,"clear_cache":false,"force":true,"id":"0xcc86ecfffe1347fd","keep_config":false},"status":"ok"}
|
||||
```
|
||||
Результат: в `database.db` и в `devices:` `configuration.yaml` — **16 устройств** (было 17), мёртвого нет. z2m подчистил и базу, и конфиг сам.
|
||||
|
||||
#### ✅ Zigbee `friendly_name` — корень generic-имён (разведка 2026-09-14)
|
||||
|
||||
@@ -378,9 +442,11 @@ curl -s -X POST -H "Authorization: Bearer $T" -H "Content-Type: application/json
|
||||
- Проверено в `/config/zigbee2mqtt/configuration.yaml` (секция `devices:`) — у всех `friendly_name: '<hex>'`.
|
||||
- Отдельная категория — вообще без имени: `switch.0xa4c138f8da8bc478` (`original_name` пусто), `switch.0xcc86ecfffe1347fd`, `switch.0x84fd27fffed9e137`, `update.0xa4c138f8da8bc478`, `light.0xa4c13882a4b42db0`.
|
||||
|
||||
**Корневой механизм:** `entity_id` в HA формируется при **первом появлении** сущности и от `friendly_name` z2m. Уже созданные `entity_id` в реестре **НЕ переименовываются автоматически** при смене `friendly_name`. Поэтому нужны **две операции**: (а) `friendly_name` в z2m, (б) переименование `entity_id` в `core.entity_registry` HA.
|
||||
**Корневой механизм (уточнён 2026-09-14 после залива реестров):** `entity_id` формируется при **первом появлении** сущности, а связь сущности в HA идёт **по `unique_id`** (`<ieee>_<param>_zigbee2mqtt`). Смена `friendly_name` в z2m **меняет MQTT-топик и discovery, но НЕ `unique_id`** → HA находит сущность по `unique_id` и **обновляет её на месте, сохраняя существующий `entity_id`**.
|
||||
|
||||
⚠️ **Побочный эффект смены `friendly_name`:** меняются MQTT-топики → **все сущности пересоздаются с новыми `entity_id`**, любые ссылки в автоматизациях/шаблонах ломаются. Поэтому делать это **до** переноса автоматизаций с TrueNAS («пока чисто»).
|
||||
⚠️ **ОТМЕНЕНО (было записано ошибочно ранее):** утверждение «смена `friendly_name` → все сущности пересоздаются с новыми `entity_id`, автоматизации ломаются» — **НЕВЕРНО**. Проверено на живом t610: дублей не появилось, человеческие `entity_id` из реестра сохранились. Автоматизации не ломаются. **Достаточно одной операции** — прописать `friendly_name` в z2m (переименовывать `entity_id` в `core.entity_registry` вручную НЕ надо).
|
||||
|
||||
> ⚠️ **ВАЖНО про итоговую таблицу имён ниже — она УСТАРЕЛА.** Согласованный список (строки 481–499) замените на **«Итоговый маппинг `friendly_name` (выведен из живых `entity_id` HA)»** из §«КРИТИЧЕСКОЕ ОТКРЫТИЕ» выше. Расхождения (эталон — реальные `entity_id`, а не перевод из TrueNAS-имён): `obratka_pump`→**`nasos_obratki`**, `stairs_light_sensor`→**`light_sensor_stairs`**, `office_smart_light`→**`smart_light_office`**, `stairs_smart_light`→**`light_stairs`**, `bed_wireless_light_switch`→**`wireless_light_switch_bed`**, `shower_night_light`→**`night_light_shower_2`**. Причина: имена на TrueNAS правились вручную, и `entity_id` в HA — единственный достоверный источник.
|
||||
|
||||
#### 🔄 Новое устройство: NEO NAS-WR01B (2026-09-14)
|
||||
|
||||
@@ -456,10 +522,12 @@ timeout 10 mosquitto_sub -h core-mosquitto -p 1883 -u zont -P "$MPW" \
|
||||
|
||||
**Автоматизации TrueNAS (`automations.yaml`, 15 шт.):** Выключить/Включить циркуляцию ГВС, Ventilation automation on, office_pass_switch_table/main, Светло/Темно подсветку лестницы, Toggle/Cycle Dimmer bed, Вкл./Выкл. ночной свет душевая, Протечка котельная, Датчик протечки котельная батарея, Датчик освещённости лестница батарея, Light switch bed батарея, Zigbee T sensor батарея.
|
||||
|
||||
**Дашборд `home_plan` использует hex, который надо будет заменить после переименования:**
|
||||
- `binary_sensor.0xa4c1383d5fcaa063_water_leak` → `boiler_water_leak`
|
||||
- `switch.0xa4c138f8da8bc478` → `obratka_pump`
|
||||
- `switch.vvod_vody_greiushchii_kabel` → **`heating_cable_plug`** (старая Tuya-розетка → новая Zigbee)
|
||||
**Дашборд `home_plan` — правки ссылок (статус 2026-09-14):**
|
||||
- ✅ `switch.vvod_vody_greiushchii_kabel` → **`heating_cable_plug`** — **СДЕЛАНО** (в staged-файле перед заливом, скрипт `fix_dashboard.py`)
|
||||
- ⏳ `binary_sensor.0xa4c1383d5fcaa063_water_leak` → `boiler_water_leak` — заменится автоматически после смены `friendly_name` в z2m (шаг 8)
|
||||
- ⏳ `switch.0xa4c138f8da8bc478` → `nasos_obratki` — то же
|
||||
|
||||
> 📌 Дашборд ссылается на сущности по человеческим именам, которые уже есть в реестре (`switch.sauna`, `light.smart_light_office_left`, `light.smart_light_stairs_l1`, `binary_sensor.shower_2_presence_sensor_presence`). После шага 8 всё оживёт.
|
||||
|
||||
### Этап 4 — проверка и отключение TrueNAS
|
||||
18. [ ] Чек-лист из родительского плана §6
|
||||
@@ -487,10 +555,13 @@ timeout 10 mosquitto_sub -h core-mosquitto -p 1883 -u zont -P "$MPW" \
|
||||
- [x] ✅ **РЕШЕНО 2026-09-14 — modbus-bridge `ha_token`/`mqtt_password`:** вписаны, MQTT + HA-опрос работают. Ключевой момент — `ha.url` = `http://192.168.2.176:80` (не `supervisor/core`), + в HA добавлена MQTT-интеграция. **Этап 2 закрыт полностью.**
|
||||
- [x] ✅ **РЕШЕНО 2026-09-14 — `custom_components` не переносим.** HACS (репо пусто) и `tuya_local` (нет config entry) не нужны; `localtuya` обслуживал единственную Tuya-розетку, которую Alex заменил на Zigbee → тоже снят.
|
||||
- [x] ✅ **РЕШЕНО 2026-09-14 — история БД не переносится** (новая с нуля) и **реестры `.storage` — замена** (вариант B).
|
||||
- [x] ✅ **ВЫПОЛНЕНО 2026-09-14 — Zigbee-розетка NEO NAS-WR01B (`0xa4c138eb6fbe9d19`) добавлена** через permit_join (MQTT). z2m = 17 устройств.
|
||||
- [x] ✅ **СОГЛАСОВАНЫ 2026-09-14 — имена 17 Zigbee-устройств** (латиница snake_case, единый формат). Эталон найден: человеческие `friendly_name` были на **TrueNAS в z2m** и в `core.device_registry`/дашборде. См. §«Имена 17 устройств».
|
||||
- [ ] ⏳ **ЖДЁМ Alex — решение по `Mini Smart Switch 1` (`0xcc86ecfffe1347fd`):** нигде не используется, нет зоны, состояние `unavailable`. Варианты: имя `unused_wall_switch` либо удалить из z2m (unpair).
|
||||
- [x] ✅ **ВЫПОЛНЕНО 2026-09-14 — Zigbee-розетка NEO NAS-WR01B (`0xa4c138eb6fbe9d19`) добавлена** через permit_join (MQTT). z2m = 16 устройств (после удаления мёртвого).
|
||||
- [x] ✅ **ВЫПОЛНЕНО 2026-09-14 — Этап 3 (перенос конфига):** бэкапы сделаны, HA остановлен, залиты 12 файлов `.storage` + 5 конфигов + `www/`, HA запущен (**248 сущностей, 11 зон, MQTT-интеграция цела, ошибок нет**). `modbus.host` → `127.0.0.1`, `localtuya: debug` убран, дашборд поправлен.
|
||||
- [x] ✅ **РЕШЕНО 2026-09-14 — `Mini Smart Switch 1` удалён из z2m** (`force: true`). Мёртвое: `lastSeen` 2026-01-26, `unavailable`, нет зоны, нигде не используется.
|
||||
- [x] ✅ **УТОЧНЕНО 2026-09-14 — механизм связи сущностей:** HA связывает по `unique_id`, НЕ по `entity_id`. Смена `friendly_name` в z2m сохраняет человеческие `entity_id`. Прежнее опасение «всё пересоздастся» снято.
|
||||
- [ ] ⏳ **ОСТАЛОСЬ (последний шаг Этапа 3):** прописать `friendly_name` в z2m по таблице из §«КРИТИЧЕСКОЕ ОТКРЫТИЕ» (16 устройств), перезапустить z2m, убедиться, что `unknown`-сущности ожили (ожидаемо ~133 → минимум). Затем чистка hex-остатков (58 шт.) в HA.
|
||||
- [ ] Камера (§8 родительского плана) — не аддон, разбираться отдельно
|
||||
- [ ] ⚠️ Незакреплённое: `sensor.0xa4c138f8da8bc478_voltage/energy/power/current` (11 hex-сущностей розетки Насос обратки) — проживут ли под новым `friendly_name` или создадутся дубли; проверить после шага 8.
|
||||
|
||||
## Связанные заметки
|
||||
- [[family/plans/home-automation-migration-t610]] — родительский план
|
||||
|
||||
Reference in New Issue
Block a user