Files
obsidian-vault/family/tech/ha-registry-operations.md
T

199 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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: топология, аддоны, доступ