199 lines
10 KiB
Markdown
199 lines
10 KiB
Markdown
---
|
||
title: "Реестры Home Assistant — операции (справочник)"
|
||
created: '2026-09-16'
|
||
updated: '2026-09-16'
|
||
type: tech
|
||
namespace: family
|
||
status: 🟢 Проверено фактами на t610 (HA 2026.9.2). Переиспользуемый справочник — не привязан к Zigbee.
|
||
tags:
|
||
- home-assistant
|
||
- haos
|
||
- t610
|
||
- registry
|
||
- websocket
|
||
related:
|
||
- '[[family/tech/zigbee-t610-z2m-i-zha]]'
|
||
- '[[family/how-to/home-automation]]'
|
||
---
|
||
|
||
# Реестры Home Assistant — операции
|
||
|
||
> **Справочник по работе с `core.entity_registry` / `core.device_registry` / `core.area_registry`.** Все факты проверены на t610.
|
||
> ⚠️ Записи реестра — **только WebSocket**. REST `/api/config/*_registry/list` отдаёт **404**.
|
||
|
||
---
|
||
|
||
## 1. Структура `core.entity_registry`
|
||
|
||
```json
|
||
{
|
||
"version": 1,
|
||
"minor_version": 23,
|
||
"key": "core.entity_registry",
|
||
"data": {
|
||
"entities": [...], // ЖИВЫЕ сущности
|
||
"deleted_entities": [...], // АРХИВ удалённых (их HA не грузит, но UI показывает!)
|
||
"settings": {...}
|
||
}
|
||
}
|
||
```
|
||
|
||
> 🔴 **Ключевой факт: `entities` и `deleted_entities` — разные секции одного файла.**
|
||
> Призраки живут в `deleted_entities` — поэтому их НЕ видно в `/api/states` и WS-реестре, но они вылезают в UI «Обслуживание» и в ссылках дашбордов.
|
||
|
||
```bash
|
||
jq '.data.entities|length' /config/.storage/core.entity_registry # живое
|
||
jq '.data.deleted_entities|length' /config/.storage/core.entity_registry # архив
|
||
jq -r '.data.entities[].entity_id' ... # список живых
|
||
jq -r '.data.deleted_entities[].entity_id' ... # список архивных
|
||
```
|
||
|
||
---
|
||
|
||
## 2. WS API — рабочие команды
|
||
|
||
| Задача | Команда |
|
||
|---|---|
|
||
| Список сущностей (живых) | `config/entity_registry/list` |
|
||
| Список устройств | `config/device_registry/list` |
|
||
| Список зон | `config/area_registry/list` |
|
||
| Получить сущность | `config/entity_registry/get {entity_id}` |
|
||
| Переименовать сущность | `config/entity_registry/update {entity_id, new_entity_id}` |
|
||
| Переименовать устройство | `config/device_registry/update {device_id, name_by_user}` |
|
||
| Сменить зону устройства | `config/device_registry/update {device_id, area_id}` |
|
||
| Удалить запись | `config/entity_registry/remove {entity_id}` |
|
||
| Проблемы (Обслуживание) | `repairs/list_issues` |
|
||
| Записи интеграций | `config_entries/get` |
|
||
|
||
> ⚠️ `/api/config/*_registry/list` (REST) → **404**. Только WS.
|
||
> ⚠️ `repairs/list_issues` может быть **пуст**, даже когда UI «Обслуживание» что-то показывает — если источник в `deleted_entities`.
|
||
|
||
---
|
||
|
||
## 3. 🔴 Переименование сущности
|
||
|
||
### 3.1. `name_by_user` НЕ переименовывает `entity_id`
|
||
|
||
Смена имени устройства (`device_registry/update`) меняет только `name_by_user`. HA **не перегенерирует** `entity_id` существующих сущностей — только у новых.
|
||
|
||
```python
|
||
# Шаг 1 — имя устройства
|
||
{"type":"config/device_registry/update","device_id": D, "name_by_user": "new_name"}
|
||
# Шаг 2 — КАЖДАЯ сущность отдельно
|
||
{"type":"config/entity_registry/update","entity_id":"sensor.old","new_entity_id":"sensor.new"}
|
||
```
|
||
|
||
### 3.2. Обход `id_reuse: Identifier values have to increase`
|
||
|
||
Внутренний счётчик реестра. **Штатный случай, не поломка.** Обход — через промежуточное имя:
|
||
|
||
```
|
||
sensor.old → sensor.tmp_xxx → sensor.new
|
||
```
|
||
|
||
### 3.3. Сироты-автоматизации
|
||
|
||
Тело удалено из `automations.yaml`, но запись в реестре осталась → сущность `unavailable`.
|
||
`config/entity_registry/remove` → если `id_reuse` → **сначала** `update` c `disabled_by: "user"`, **затем** `remove`.
|
||
|
||
> 🔴 **После любого переименования — проверять ссылки:**
|
||
> - в `automations.yaml` (все `entity_id:` сверить со `/api/states`);
|
||
> - в дашбордах (`lovelace.*`), см. §5;
|
||
> - в маппингах `modbus-bridge`, см. [[family/tech/zigbee-t610-z2m-i-zha]] §5.
|
||
|
||
---
|
||
|
||
## 4. 🔴 Опции сущности: `options_domain` — важно какой
|
||
|
||
Опции хранятся по доменам. Пример структуры:
|
||
|
||
```json
|
||
"options": {
|
||
"conversation": {"should_expose": false},
|
||
"sensor": {"suggested_display_precision": 1},
|
||
"sensor.private": {"suggested_unit_of_measurement": "°F"}
|
||
}
|
||
```
|
||
|
||
Обновление:
|
||
|
||
```python
|
||
{"type":"config/entity_registry/update",
|
||
"entity_id":"sensor.x",
|
||
"options_domain":"sensor.private", # ⚠️ ТОЧНЫЙ домен, не общий
|
||
"options":{"suggested_unit_of_measurement": None}}
|
||
```
|
||
|
||
> 🔴 **ПИТФОЛЛ: `options_domain: "sensor"` даёт `success: true`, но единицу НЕ меняет.** Проверено фактом на H2000_PRO: заход через `"sensor"` не подействовал, после смены на `"sensor.private"` — сработало.
|
||
> **Всегда читать обратно** (`config/entity_registry/get`) и сверять результат в `/api/states`.
|
||
|
||
### Кейс: датчик показывает °F вместо °C
|
||
|
||
Причина — ручной override `sensor.private.suggested_unit_of_measurement: "°F"`. Значения тоже конвертируются (55.22 °F = 12.9 °C), поэтому цифры выглядят правдоподобно и ошибку легко не заметить.
|
||
**Фикс:** сброс в `null` через `options_domain: "sensor.private"`.
|
||
|
||
---
|
||
|
||
## 5. Проверка ссылок дашбордов
|
||
|
||
```bash
|
||
# все ссылки плана этажей (picture-elements)
|
||
jq -r '.data.config.views[].sections[].cards[]?
|
||
| select(.type=="picture-elements")
|
||
| .elements[]? | select(.entity?!=null) | .entity' \
|
||
/config/.storage/lovelace.home_plan | sort -u
|
||
# затем сверить список со живыми из /api/states
|
||
```
|
||
|
||
> 🔴 **Правило: после сноса призраков — проверять ссылки дашбордов.** План этажей показывает «недоступно» из-за мёртвой ссылки, а не из-за поломки устройства.
|
||
|
||
Дашборды t610: `home_plan` (storage-mode, `/config/.storage/lovelace.home_plan`, карта `/config/www/floorplan/*.svg`), реестр дашбордов — `lovelace_dashboards`.
|
||
|
||
---
|
||
|
||
## 6. Контролируемый снос призраков
|
||
|
||
**Принцип: только то, что в архиве И не живое. Никогда по grep — только по точному `entity_id`.**
|
||
|
||
Скрипт `~/tmp-t610/ghost_purge.sh`:
|
||
1. строит `live_all` (`.data.entities`) и `ghost_all` (`.data.deleted_entities`);
|
||
2. `comm -23` → в архиве и НЕ живое;
|
||
3. `grep -viE 'fan|at2|damper|vent|shopping_list'` → исключает вентиляцию (по требованию Alex);
|
||
4. dry-run по умолчанию, `--apply` — снос;
|
||
5. `--apply` → бэкап `*.bak-ghostpurge-<ts>` → `jq`-фильтр → отчёт.
|
||
|
||
**Обязательно после сноса:** рестарт HA (`POST /api/services/homeassistant/restart`), иначе правка `.storage` не подхватится. Проверить: `entities` не изменилось, `deleted_entities` уменьшилось.
|
||
|
||
```bash
|
||
scp ~/tmp-t610/ghost_purge.sh root@192.168.2.176:/tmp/
|
||
ssh root@192.168.2.176 'bash /tmp/ghost_purge.sh /config/.storage/core.entity_registry' # dry-run
|
||
ssh root@192.168.2.176 'bash /tmp/ghost_purge.sh /config/.storage/core.entity_registry --apply'
|
||
```
|
||
|
||
> ⚠️ **Питфолл `set -e` в bash:** `comm`/`grep` возвращают 1 при пустом результате и валят скрипт молча. Использовать `set -uo pipefail` (без `-e`) + `|| true` на таких строках.
|
||
> ⚠️ **На t610 нет `python3`.** Только `jq` 1.8.1 (`/usr/bin/jq`). Скрипты для t610 писать на jq/bash, не на Python.
|
||
|
||
---
|
||
|
||
## 7. Питфоллы (сводка)
|
||
|
||
| # | Питфолл | Обход |
|
||
|---|---|---|
|
||
| 1 | REST `/api/config/*_registry/list` → 404 | Только WebSocket |
|
||
| 2 | `name_by_user` не меняет `entity_id` | Переименовывать устройство И сущности отдельно |
|
||
| 3 | `id_reuse: Identifier values have to increase` | Промежуточное имя: `old → tmp → new` |
|
||
| 4 | Сирота-автоматизация `unavailable` | `remove`, при `id_reuse` — сначала `disabled_by: user` |
|
||
| 5 | `options_domain: "sensor"` не меняет единицу | Точный домен: `"sensor.private"` |
|
||
| 6 | Призраки не видны в API, но видны в UI | Они в `deleted_entities`, а не в `entities` |
|
||
| 7 | Правка `.storage` без рестарта не действует | `POST /api/services/homeassistant/restart` |
|
||
| 8 | После сноса призраков дашборд ругается | Проверить ссылки дашбордов (§5) |
|
||
| 9 | Удаление `device_id` сбрасывает `area_id` | Восстановить через `device_registry/update` |
|
||
| 10 | На t610 нет `python3` | Скрипты на `jq`/bash |
|
||
|
||
---
|
||
|
||
## Связанные заметки
|
||
|
||
- [[family/tech/zigbee-t610-z2m-i-zha]] — Zigbee на ZHA, §13 вычистка призраков
|
||
- [[family/how-to/home-automation]] — t610: топология, аддоны, доступ
|