- PLAN_CORE: монорепозиторий (CMakeLists в корне; components/fglair,
custom_components/fglair, include/fgl-aircon, src/{ayla,aircon},
src/ayla/platform); логическое разделение ayla (протокол+цикл) /
aircon (конверсии+шаблоны+API); тесты зеркалят слои (tests/{ayla,aircon});
конверсии: шаблон / линейные коэффициенты / функция-указатель
(лямбды ESPHome); оценка httpd/json (jsmn вендор, свой мини-httpd на
BSD-сокетах, conan не нужен); README библиотеки в M4.
- PLAN_ESPHOME: host вместо ip_address (DNS + Ayla-mDNS :10276),
секреты в примерах, кастомные конверсии через !lambda, advanced-пример
(триггеры режимов + LVGL с пропусками), README-план, скрипт приёмки
(aioesphomeapi + HA REST).
- PLAN_HOME_ASSISTANT: шаг config flow с превью рассчитанных значений
шаблона (через cffi в C-ядро, без дублей), README с HACS-инструкцией
и заглушками под скриншоты с описаниями, приёмка (long-lived token).
- Убраны реальные dsn/ip/lanip_key/key_id из примеров; probe_mdns.py
принимает DSN аргументом.
11 KiB
План: интеграция Home Assistant (custom_components/fglair)
Аудитория — агенты-реализаторы. Протокол — docs/PROTOCOL.md; ядро —
docs/PLAN_CORE_LIBRARY.md (fgl-aircon, C++20, монорепо: библиотека в
корне, компонент HA здесь).
1. Архитектура
Home Assistant (custom component `fglair`)
│ использует python-пакет pyfglair (cffi-bindings к libfgl-aircon.so)
▼
pyfglair (wheel: linux x86_64/aarch64; cffi; собирает библиотеку из корня
репозитория через cmake)
│
▼
fgl-aircon (C++, корень монорепо) ←—— тот же код, что и на ESP32 (ESP-IDF)
Компонент — тонкий: переводит API библиотеки в сущности HA. Вся протокольная логика (сессия, шифрование, pacing, re-key, восстановление) — в C-ядре.
Обоснование: переиспользование библиотеки (требование владельца); cffi-wheel — рабочий путь (HA-контейнеры x86_64/aarch64 debian; cibuildwheel). Fallback, если сборка wheel станет блокером: сборка .so при старте в docker (dev-режим). Чисто-Python повторная реализация протокола — запрещена.
2. Состав
pyfglair(python-пакет):pyfglair/_corebuild.py— cmake-сборка при упаковке wheel;pyfglair/_cffi.py— cffi-декларации поверхinclude/fgl-aircon/c_api.h;pyfglair/session.py— обёрткаSession(cfg); колбэки ядра → asyncio черезloop.call_soon_threadsafe;pyfglair/templates.py— интроспекция шаблонов через cffi-вызовыfgl_template_info_get/fgl_convert_to_display(для превью в config flow; единый источник данных — C-таблицы, дублей нет);pyfglair/provision.py— облачный discovery (перенос логикиdocs/legacy/aircon/discovery.pyна современный aiohttp): e-mail/ пароль/регион → dsn, host/ip, oem_model, lanip_key, lanip_key_id;- CLI:
python -m pyfglair discover/monitor/--output esphome-secrets(печать блока для secrets.yaml ESPHome).
custom_components/fglair/:manifest.json # requirements: ["pyfglair>=1.0.0"], config_flow: true config_flow.py # flow + options + repair fglair_client.py # фоновый поток с FglSession coordinator.py # push-driven coordinator climate.py sensor.py switch.py select.py binary_sensor.py diagnostics.py # lanip_key/key_id/dsn видны для копирования в ESPHome translations/{en,ru}.json
3. Config flow
Шаг 1 — подключение (один из вариантов):
- A (облачный): e-mail/пароль FGLair + регион → список устройств (name, model, host) → выбор.
- B (ручной): host/dsn/lanip_key/lanip_key_id по полям, либо импорт
config_*.json(миграция с legacy).
Шаг 2 — пробное подключение: старт сессии, ожидание ONLINE ≤10 с, чтение базовых свойств. Ошибка → назад с сообщением.
Шаг 3 — выбор шаблона С ПРЕВЬЮ РЕЗУЛЬТАТОВ (требование): после выбора
шаблона (обычно определён по oem_model автоматически) — форма-предпросмотр
рассчитанных значений через pyfglair.templates (вызовы в C-ядро):
| Поле превью | Пример значения |
|---|---|
| hvac-режимы | off, cool, dry, fan, heat, auto (operation_mode 0–6) |
| fan-режимы | quiet/low/medium/high/auto (0–4) |
| Диапазон уставки | 16.0–30.0 °C, шаг 0.5 (adjust_temperature raw 160–300, ×0.1) |
| Текущая температура | display_temperature 7000 → 20.0 °C |
| Заслонки | vertical 0–4 (af_vertical_num_dir), horizontal 0–6 |
| Битмаска capabilities | heat, cool, economy, powerful, min_heat, swing … |
Пользователь оценивает корректность (сверяет с приложением FGLair) и
подтверждает → создаётся ConfigEntry. При расхождении — возможность
выбрать другой шаблон или задать конверсию коэффициентами (linear:
num/den/offset) и диапазон вручную на этом же шаге.
Repair (теоретический): key_error → «Ключ устройства изменён —
перепровижинируйте» (повторный облако-вход по требованию). Облако в рантайме
не используется, ключ статичен.
Диагностика: device-страница показывает dsn, lanip_key, lanip_key_id,
host — источник для копирования в secrets ESPHome. В redacted-дампе ключ
маскируется.
4. Сущности
Как раньше (climate: hvac/fan/swing/preset ECO-BOOST; current_temperature ←
display_temperature; sensors: room temp, error_code, op_status-флаги;
switch: economy/powerful/coil_dry/min_heat/outdoor_low_noise/
human_det_auto_save/wifi_led/indoor_fan_control; select: заслонки,
demand_control; binary_sensor: connectivity). capabilities фильтруют
режимы/пресеты. Записи — один batch_commit() на действие пользователя.
5. Runtime
Один FglairClient на ConfigEntry (daemon-thread, сессия ядра); колбэки →
asyncio → push-coordinator. Состояния: online → available;
recovering → доступны (последние значения) + diagnostic-сенсор;
offline → unavailable; key_error → unavailable + repair. Keep-alive 15 с
(самолечение десинхрона ≤15 с). Выгрузка: stop() (delete_session).
6. README компонента (после реализации; для людей, коротко)
Структура (screenshots/step-N.png — заглушки-плейсхолдеры, владелец заменит
реальными скриншотами; рядом с каждой — описание что должно быть видно):
- Установка через HACS:
- HACS → ⋮ → Custom repositories → URL репозитория, категория Integration → Add. Скриншот: диалог добавления custom repository с заполненным URL и выбранной категорией Integration.
- FGLair → Download → перезапуск HA. Скриншот: страница загрузки интеграции с кнопкой Download (версия видна).
- Добавление устройства: Settings → Devices & Services → Add Integration → «FGLair». Скриншот: диалог поиска интеграции с введённым «FGLair» и выделенным результатом.
- Вход в облако (шаг 1A): e-mail/пароль/регион. Скриншот: форма с заполненными регионом EU и e-mail (пароль скрыт).
- Выбор устройства: список найденных кондиционеров. Скриншот: список с одним устройством (имя, модель, host).
- Проверка шаблона с превью (шаг 3): Скриншот: форма превью — таблица рассчитанных значений (режимы, диапазон температур, пример конверсии температуры), кнопки Confirm/Change template.
- Готово: карточка устройства со списком сущностей. Скриншот: страница устройства с созданными climate/sensor/switch сущностями.
- Где взять ключ для ESPHome: диагностика устройства. Скриншот: страница Diagnostics с полями dsn/lanip_key/lanip_key_id.
- Troubleshooting: 503 (оба слота заняты — телефон+ESP?), key_error, недоступность.
7. Приёмка (полуавтоматическая, tests/acceptance/test_esphome_ha.py)
Совместно с ESPHome-компонентом (топология и детали — PLAN_ESPHOME §8).
Со стороны HA скрипт использует long-lived access token (профиль →
Security → Long-lived access tokens) и REST API: вызов сервисов
/api/services/climate/set_temperature|set_hvac_mode|set_fan_mode|set_swing_mode
и чтение /api/states/<entity_id>. Возможность подтверждена: это
стандартный документированный механизм HA REST API, отдельная авторизация
(OAuth-флоу) не нужна — пользователь просто создаёт токен и передаёт
скрипту (--ha-url, --ha-token).
Режимы: quick (матрица burst/не-burst, обе стороны, с возвратом) и --long
(24 ч, ежечасное изменение с проверкой и возвратом, CSV-отчёт). Скрипт НЕ
открывает собственную сессию к кондиционеру (оба слота заняты HA+ESP).
8. Этапы
| # | Содержимое |
|---|---|
| H1 | wheel pyfglair (сборка из корня монорепо), cffi-обёртки, CLI discover/monitor |
| H2 | компонент: manifest, config flow (облако/ручной/импорт) + пробное подключение |
| H3 | шаг «превью шаблона» с ручными конверсиями; climate + сущности |
| H4 | repair, диагностика (ключ для ESPHome), translations |
| H5 | README с HACS-инструкцией и заглушками скриншотов (§6), скрипт приёмки (§7), HACS-релиз |