From f5c13ecacc038442695622b4f0d08dc8b9ba8ca5 Mon Sep 17 00:00:00 2001 From: Stream Date: Wed, 15 Apr 2026 14:10:01 +0300 Subject: [PATCH] auto-sync: 2026-04-15 14:10:01 --- tasks/ha-availability-dashboard/TZ.md | 78 ++++++++++++++++++++++++--- 1 file changed, 71 insertions(+), 7 deletions(-) diff --git a/tasks/ha-availability-dashboard/TZ.md b/tasks/ha-availability-dashboard/TZ.md index 99fa043..52b5517 100644 --- a/tasks/ha-availability-dashboard/TZ.md +++ b/tasks/ha-availability-dashboard/TZ.md @@ -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/?filter_entity_id=&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__` -- Атрибуты: `entity_id`, `period`, `availability_%`, `last_updated` -- Группировка: `group.availability_day`, `group.availability_week`, `group.availability_month` +- Каждый результат — `sensor.avail_` (один sensor, период в атрибуте) +- Атрибуты: `entity_id`, `period`, `availability_pct`, `area`, `down_count`, `max_downtime_minutes`, `sparkline`, `trend`, `last_downtime`, `color`, `last_updated` +- Группировка по комнатам: `sensor.avail_area_` +- Прогресс расчёта: `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д)