132 lines
6.2 KiB
Markdown
132 lines
6.2 KiB
Markdown
# HA Availability Dashboard
|
||
|
||
## Описание
|
||
Дашборд доступности устройств в Home Assistant — показывает uptime устройств в % за три периода (24ч / 7д / 30д) с группировкой по комнатам, цветовой индикацией и sparkline.
|
||
|
||
## Статус
|
||
🟡 **В разработке** — бэкенд работает, дашборд не построен
|
||
|
||
## Ссылки
|
||
- **ТЗ:** `TZ.md`
|
||
- **Исходники AppDaemon:** `appdaemon/` (локальная копия, деплой → HA)
|
||
- **HA:** `https://ha.homenet542.keenetic.pro`
|
||
|
||
## Архитектура
|
||
|
||
```
|
||
HA History API ──► AppDaemon (availability.py) ──► sensor.avail_* ──► Lovelace Dashboard
|
||
│
|
||
├── REST API (supervisor/core/api) — история, states
|
||
└── WebSocket (homeassistant:8123) — area/entity/device registry
|
||
```
|
||
|
||
## Файловая структура
|
||
|
||
### На HA (`/addon_configs/a0d7b954_appdaemon/apps/`)
|
||
```
|
||
apps/
|
||
├── apps.yaml # регистрация: hello_world + availability
|
||
├── availability.py # основной модуль (Availability class)
|
||
├── availability_utils.py # утилиты (фильтрация, расчёт, форматирование)
|
||
└── hello.py # тестовое приложение (оставлено)
|
||
```
|
||
|
||
### Локально (`tasks/ha-availability-dashboard/`)
|
||
```
|
||
├── TZ.md # полное ТЗ
|
||
├── PROJECT.md # этот файл
|
||
└── appdaemon/ # локальная копия для редактирования
|
||
├── availability.py
|
||
├── availability_utils.py
|
||
└── apps.yaml
|
||
```
|
||
|
||
## Компоненты
|
||
|
||
### AppDaemon
|
||
- **Версия:** 4.5.13
|
||
- **Addon slug:** `a0d7b954_appdaemon`
|
||
- **Python:** 3.12.13
|
||
- **Конфиг:** `/addon_configs/a0d7b954_appdaemon/appdaemon.yaml`
|
||
- **Таймзона:** Europe/Moscow
|
||
|
||
### availability.py
|
||
Класс `Availability(hass.Hass)`:
|
||
- **Cold-start:** полный пересчёт через 30 сек после запуска
|
||
- **Расписания:** 24ч/5мин, 7д/15мин, 30д/2ч
|
||
- **Подписка:** `input_select.avail_period` — пересчёт при переключении
|
||
- **REST API:** `http://supervisor/core/api` с SUPERVISOR_TOKEN
|
||
- **WebSocket:** `ws://homeassistant:8123/api/websocket` с ha_token из args
|
||
|
||
Методы:
|
||
| Метод | Назначение |
|
||
|-------|-----------|
|
||
| `_fetch_entities()` | Получение списка устройств + фильтрация |
|
||
| `_fetch_areas()` | WebSocket → area/entity/device registry → маппинг |
|
||
| `_fetch_history()` | Batch-запросы по 20 entity, пауза 1 сек |
|
||
| `_calc_period()` | Полный цикл расчёта для периода |
|
||
| `_set_progress()` | Обновление sensor.avail_calc_progress |
|
||
|
||
### availability_utils.py
|
||
| Функция | Назначение |
|
||
|---------|-----------|
|
||
| `is_excluded()` | Фильтрация entity по правилам исключения |
|
||
| `sanitize_entity_id()` | `light.bra` → `light_bra` |
|
||
| `sanitize_area_name()` | `Без комнаты` → `bez_komnaty` (транслитерация) |
|
||
| `compute_availability()` | Расчёт pct, down_count, max_downtime, last_downtime |
|
||
| `compute_sparkline()` | Ежедневные точки за N дней |
|
||
| `get_color()` | ≥99→green, 95-99→yellow, 90-95→orange, <90→red |
|
||
| `calc_trend()` | Сравнение с предыдущим периодом (up/down/stable) |
|
||
|
||
### Sensors
|
||
- `sensor.avail_<entity_id>` — доступность устройства (state = %)
|
||
- `sensor.avail_area_<name>` — средняя доступность по комнате
|
||
- `sensor.avail_calc_progress` — прогресс расчёта (`"1/2"` или `"idle"`)
|
||
|
||
### input_select
|
||
- `input_select.avail_period` — переключатель периода (24h / 7d / 30d)
|
||
|
||
## Аутентификация
|
||
|
||
| Канал | URL | Токен |
|
||
|-------|-----|-------|
|
||
| REST API | `http://supervisor/core/api` | SUPERVISOR_TOKEN (авто) |
|
||
| WebSocket | `ws://homeassistant:8123/api/websocket` | ha_token (Long-Lived Access Token из apps.yaml) |
|
||
|
||
⚠️ SUPERVISOR_TOKEN **не подходит** для прямого WebSocket к HA — только для REST через supervisor proxy.
|
||
|
||
## Известные баги / ограничения
|
||
|
||
1. **Sparkline для 24ч** — даёт 1 точку, а не 7. Нужна логика по часам
|
||
2. **Area cache** — `_fetch_areas()` запрашивает registry при каждом расчёте. Можно кэшировать
|
||
3. **30д тренд** — запрашивает 60д истории, нужен `purge_keep_days ≥ 65`
|
||
4. **Новые устройства** — `compute_availability` вернёт 100% (нет истории = нет падений). Корректно, но не информативно
|
||
5. **`minimal_response`** — HA может не возвращать entity_id в каждой записи. Fallback на первый entity из батча
|
||
|
||
## Деплой
|
||
|
||
```bash
|
||
# Обновить файлы на HA
|
||
SKILL=~/.openclaw/skills/installer/scripts
|
||
$SKILL/ssh_exec.sh --host ha --cmd "cat > /addon_configs/a0d7b954_appdaemon/apps/availability.py << 'ENDOFFILE'
|
||
$(cat appdaemon/availability.py)
|
||
ENDOFFILE"
|
||
|
||
$SKILL/ssh_exec.sh --host ha --cmd "cat > /addon_configs/a0d7b954_appdaemon/apps/availability_utils.py << 'ENDOFFILE'
|
||
$(cat appdaemon/availability_utils.py)
|
||
ENDOFFILE"
|
||
|
||
# Перезапустить AppDaemon
|
||
$SKILL/ssh_exec.sh --host ha --cmd "ha addons restart a0d7b954_appdaemon"
|
||
```
|
||
|
||
## TODO
|
||
|
||
- [ ] Назначить areas устройствам в HA
|
||
- [ ] Увеличить purge_keep_days до 35
|
||
- [ ] Установить button-card через HACS
|
||
- [ ] Построить Lovelace-дашборд
|
||
- [ ] Расширить на другие домены (sensor, binary_sensor, climate, ...)
|
||
- [ ] Кэшировать area registry (не запрашивать каждый цикл)
|
||
- [ ] Исправить sparkline для 24ч (часовые точки вместо дневных)
|