auto-sync: 2026-04-15 14:10:01
This commit is contained in:
@@ -89,9 +89,31 @@ sensor.avail_light_bra_v_spalne:
|
||||
- ✅ **Плюсы:** без AppDaemon
|
||||
- ❌ **Минусы:** `python_script` ограничен в импортах, сложнее batch
|
||||
|
||||
### Рекомендация: Вариант A (AppDaemon)
|
||||
### Рекомендация: Вариант A (AppDaemon) ✅ ВЫБРАН
|
||||
Оптимальный баланс. Изолированный Python-скрипт, batch-обработка, легко масштабировать.
|
||||
|
||||
**Установлено:** AppDaemon 4.5.13, HA 2026.4.2, Python 3.12.13
|
||||
**Путь конфига:** `/addon_configs/a0d7b954_appdaemon/appdaemon.yaml`
|
||||
**Путь приложений:** `/addon_configs/a0d7b954_appdaemon/apps/`
|
||||
**Путь apps.yaml:** `/addon_configs/a0d7b954_appdaemon/apps/apps.yaml`
|
||||
**Slug аддона:** `a0d7b954_appdaemon`
|
||||
**Подключение к HA:** автоматическое через SUPERVISOR_TOKEN (WebSocket), ha_url/token НЕ указывать
|
||||
|
||||
### Первая фаза: только light + switch
|
||||
Начинаем с минимального набора — только домены `light` и `switch`. После обкатки расширяем на остальные.
|
||||
|
||||
**Устройств после фильтрации:** ~32 (2 light + 30 switch)
|
||||
|
||||
**Дополнительные исключения для switch (настройки реле — не основные устройства):**
|
||||
- `*_delayed_power_on_state`
|
||||
- `*_detach_relay_mode`
|
||||
- `*_network_indicator`
|
||||
- `*_turbo_mode`
|
||||
- `*_do_not_disturb`
|
||||
- `switch.zigbee2mqtt_bridge_permit_join`
|
||||
|
||||
После этих исключений — ~18 основных устройств.
|
||||
|
||||
### Cold-start (первичная загрузка и перезапуск)
|
||||
При запуске AppDaemon (или после перезапуска HA) — **полный пересчёт текущего активного периода** для всех устройств. Не ждать следующего расписания — данные должны быть актуальны сразу.
|
||||
|
||||
@@ -168,9 +190,18 @@ sensor.avail_light_bra_v_spalne:
|
||||
|
||||
## Технические детали
|
||||
|
||||
### Путь приложения AppDaemon
|
||||
```
|
||||
/addon_configs/a0d7b954_appdaemon/apps/
|
||||
├── apps.yaml # регистрация приложений
|
||||
├── availability.py # основной модуль расчёта доступности
|
||||
└── availability_utils.py # вспомогательные функции (фильтрация, форматирование)
|
||||
```
|
||||
|
||||
### Источник данных
|
||||
- HA History API: `/api/history/period/<start>?filter_entity_id=<ids>&minimal_response&no_attributes`
|
||||
- Возвращает массив пар `(state, last_changed)` — достаточно для расчёта времени
|
||||
- AppDaemon подключён к HA через WebSocket — использует `self.get_entity_history()` или REST API через `self.hass`
|
||||
|
||||
### Расчёт (алгоритм)
|
||||
```python
|
||||
@@ -192,9 +223,40 @@ def calc_availability(history_entries, period_start, period_end):
|
||||
```
|
||||
|
||||
### Хранение результатов
|
||||
- Каждый результат — `sensor.avail_<sanitized_id>_<period>`
|
||||
- Атрибуты: `entity_id`, `period`, `availability_%`, `last_updated`
|
||||
- Группировка: `group.availability_day`, `group.availability_week`, `group.availability_month`
|
||||
- Каждый результат — `sensor.avail_<sanitized_id>` (один sensor, период в атрибуте)
|
||||
- Атрибуты: `entity_id`, `period`, `availability_pct`, `area`, `down_count`, `max_downtime_minutes`, `sparkline`, `trend`, `last_downtime`, `color`, `last_updated`
|
||||
- Группировка по комнатам: `sensor.avail_area_<sanitized_name>`
|
||||
- Прогресс расчёта: `sensor.avail_calc_progress` (`"47/180"` или `"idle"`)
|
||||
|
||||
### Дашборд: имеющиеся кастомные карточки
|
||||
Установлены через HACS:
|
||||
- **mini-graph-card** — для sparkline
|
||||
- **auto-entities** — автоподхват устройств
|
||||
- **card-mod** — кастомный CSS (мобильная адаптация)
|
||||
- **stack-in-card** — группировка карточек
|
||||
|
||||
**Нужно доустановить:**
|
||||
- **button-card** — для строк устройств с прогресс-баром
|
||||
- **custom:hui-element** — для input_select на дашборде (или использовать стандартный entities card)
|
||||
|
||||
### AppDaemon: как писать приложение
|
||||
|
||||
```python
|
||||
import appdaemon.plugins.hass.hassapi as hass
|
||||
|
||||
class Availability(hass.Hass):
|
||||
def initialize(self):
|
||||
# Cold-start: сразу пересчёт
|
||||
self.run_in(self.calc_all, 30) # через 30 сек после старта
|
||||
|
||||
# Расписания
|
||||
self.run_every(self.calc_24h, "now+30", 5 * 60) # каждые 5 мин
|
||||
self.run_every(self.calc_7d, "now+60", 15 * 60) # каждые 15 мин
|
||||
self.run_every(self.calc_30d, "now+120", 2 * 3600) # каждые 2 часа
|
||||
|
||||
# Подписка на переключение периода
|
||||
self.listen_state(self.period_changed, "input_select.avail_period")
|
||||
```
|
||||
|
||||
### Нагрузка
|
||||
- ~180 устройств
|
||||
@@ -208,7 +270,9 @@ def calc_availability(history_entries, period_start, period_end):
|
||||
- Если устройство удалено — перестать показывать на дашборде
|
||||
|
||||
## Что нужно от Славы
|
||||
1. Подтвердить вариант реализации (рекомендую A — AppDaemon/Python)
|
||||
1. ~~Подтвердить вариант реализации~~ → ✅ AppDaemon (Вариант A)
|
||||
2. Увеличить `purge_keep_days` до 35 (иначе не будет данных за месяц)
|
||||
3. Установить AppDaemon (если выбран вариант A) — или подтвердить другой вариант
|
||||
4. Подтвердить список исключений (какие entity не отслеживать)
|
||||
3. ~~Установить AppDaemon~~ → ✅ Установлен (4.5.13)
|
||||
4. ~~Подтвердить список исключений~~ → ✅ Согласовано (см. выше)
|
||||
5. Доустановить **button-card** через HACS
|
||||
6. Создать `input_select.avail_period` (опции: 24ч, 7д, 30д)
|
||||
|
||||
Reference in New Issue
Block a user