9.7 KiB
9.7 KiB
ТЗ: Дашборд доступности устройств в Home Assistant
Цель
Дашборд, показывающий uptime устройств в процентах за три периода: день, неделю, месяц. С сортировкой по убыванию доступности.
Метрика
Доступность = время в статусе «доступен» / общее время периода × 100%
- «Доступен» — любой статус, кроме
unavailableиunknown - «Недоступен» — статус
unavailableилиunknown - Результат: процент (0%–100%), один знак после точки
Периоды
| Период | Формула | Обновление |
|---|---|---|
| День | за последние 24 часа | каждые 5 мин |
| Неделя | за последние 7 дней | каждые 30 мин |
| Месяц | за последние 30 дней | каждые 2 часа |
Какие устройства отслеживать
Все entity из доменов физических устройств:
binary_sensor,sensor,switch,lightclimate,cover,lock,media_playerdevice_tracker,vacuum,fan,humidifierwater_heater,siren,button
Исключения (не показывать на дашборде):
- Вспомогательные entity Zigbee2MQTT (
sensor.*_update_state,update.*,button.zigbee2mqtt_*) - Entity с суффиксами
_battery_low,_battery,_linkquality,_update,_identify - Виртуальные/template сенсоры (без device_id)
- Автоматически создаваемые Select/Number для Zigbee-устройств (настройки radar_sensitivity и т.п.)
Архитектура решения
1. Вычисление доступности — через长期的 sensor
Для каждого отслеживаемого устройства создать template sensor (или один Python-скрипт через REST), который:
- Запрашивает историю из
/api/history/period/<start>?filter_entity_id=<id>&minimal_response&no_attributes - Считает суммарное время в
unavailable/unknown - Вычисляет процент доступности
- Записывает результат как sensor state
2. Варианты реализации
Вариант A: Utility Meter + Template Sensor (нативный HA)
- На каждое устройство —
binary_sensorдоступности (доступен/нет) utility_meterсчитает время в каждом статусе- Template sensor вычисляет процент
- ❌ Минус: нужен
custom:utility_meterилиhistory_stats— много entity на каждое устройство, сложная конфигурация при 180+ устройствах
Вариант B: Python-скрипт + AppDaemon (рекомендуемый)
- Один Python-скрипт, работающий по расписанию
- Читает историю через HA API для всех устройств сразу
- Вычисляет доступность за все 3 периода
- Создаёт/обновляет
sensor.availability_<entity_id>_<period>черезstatesAPI - ✅ Плюсы: один скрипт, легко масштабировать, минимальная нагрузка на HA
- ⚠️ Требует: AppDaemon или HA Python script / custom component
Вариант C: Custom HA Integration (HACS)
- Кастомная интеграция, регистрирует sensor-ы через
async_setup_platform - Берёт данные из recorder напрямую (SQL)
- ✅ Плюсы: максимально нативно, работает через recorder без API
- ⚠️ Минусы: сложнее разработка, нужен доступ к БД recorder
Вариант D: SQL Sensor + Jinja (самый простой)
sqlintegration — прямые запросы к MariaDB/SQLite recorder- Один sensor на устройство×период с SQL-запросом
- ✅ Плюсы: без внешних зависимостей, работает из коробки
- ❌ Минусы: 180 устройств × 3 периода = 540 SQL-запросов по расписанию — нагрузка на БД
Рекомендация: Вариант B (AppDaemon / Python-скрипт)
Оптимальный баланс сложности и производительности. Один скрипт, batch-обработка, минимальная нагрузка.
Дашборд
Карточка: таблица доступности
┌──────────────────────────┬────────┬────────┬────────┐
│ Устройство │ День │ Неделя │ Месяц │
├──────────────────────────┼────────┼────────┼────────┤
│ 💡 Бра в спальне │ 99.8% │ 98.5% │ 95.2% │
│ 🔌 Лесной колодец насос │ 100.0% │ 99.1% │ 97.8% │
│ 🌡️ Улица температура │ 85.3% │ 92.1% │ 88.7% │
│ ... │ ... │ ... │ ... │
└──────────────────────────┴────────┴────────┴────────┘
Функциональность:
- Сортировка по любому столбцу (по умолчанию — по месячной доступности, убывание)
- Цветовая индикация:
- 🟢 99-100% — зелёный
- 🟡 95-99% — жёлтый
- 🟠 90-95% — оранжевый
- 🔴 <90% — красный
- Фильтр по домену (switch, sensor, light...)
- Обновление: при загрузке дашборда + по расписанию
Карточка: сводка
┌──────────────────────────────────┐
│ 📊 Доступность устройств │
│ │
│ Средняя за день: 97.3% │
│ Средняя за неделю: 96.1% │
│ Средняя за месяц: 94.8% │
│ │
│ Устройств <95% (месяц): 5 │
│ Устройств <90% (месяц): 2 │
└──────────────────────────────────┘
Технические детали
Источник данных
- HA History API:
/api/history/period/<start>?filter_entity_id=<ids>&minimal_response&no_attributes - Возвращает массив пар
(state, last_changed)— достаточно для расчёта времени
Расчёт (алгоритм)
def calc_availability(history_entries, period_start, period_end):
unavailable_seconds = 0
for entry in history_entries:
state = entry['state']
changed = parse_datetime(entry['last_changed'])
if state in ('unavailable', 'unknown'):
# Сколько времени устройство было в этом статусе
# до следующего изменения или до period_end
next_change = get_next_change(entry) or period_end
unavailable_seconds += (next_change - changed).total_seconds()
total_seconds = (period_end - period_start).total_seconds()
availability = (1 - unavailable_seconds / total_seconds) * 100
return round(availability, 1)
Хранение результатов
- Каждый результат —
sensor.avail_<sanitized_id>_<period> - Атрибуты:
entity_id,period,availability_%,last_updated - Группировка:
group.availability_day,group.availability_week,group.availability_month
Нагрузка
- ~180 устройств
- History API batch-запрос (можно передать несколько entity_id через запятую)
- За день: ~180 × 3 = 540 точек данных (при batch — 3 API-вызова)
- За неделю/месяц: данные уже рассчитаны, обновляются реже
Ограничения
purge_keep_daysв recorder — по умолчанию 10 дней. Для месячной статистики нужно увеличить до 35 дней- Если устройство добавлено недавно — показывать доступность с момента добавления (не с начала периода)
- Если устройство удалено — перестать показывать на дашборде
Что нужно от Славы
- Подтвердить вариант реализации (рекомендую B — AppDaemon/Python)
- Увеличить
purge_keep_daysдо 35 (иначе не будет данных за месяц) - Установить AppDaemon (если выбран вариант B) — или подтвердить другой вариант
- Подтвердить список исключений (какие entity не отслеживать)