# План: интеграция для Home Assistant (`fglair` custom component) Аудитория — агенты-реализаторы. Протокол — `docs/PROTOCOL.md`, библиотека — `docs/PLAN_CORE_LIBRARY.md` (`fglair-core`, C++20). ## 1. Архитектура ``` Home Assistant (custom component `fglair`) │ использует python-пакет pyfglair (cffi-bindings к libfglair-core.so) ▼ pyfglair (wheel: linux x86_64/aarch64; cffi; собирает fglair-core через cmake) │ ▼ fglair-core (C++) ←—— mock-тесты; тот же код, что и на ESP32 (ESP-IDF) ``` Компонент — тонкий: переводит API библиотеки в сущности HA. Вся протокольная логика (сессия, шифрование, pacing, re-key, восстановление) — в C-ядре. Обоснование: пользователь требует переиспользования библиотеки из п.2; cffi-wheel — рабочий путь (HA-контейнеры: x86_64/aarch64 debian; cibuildwheel покрывает). Fallback (если сборка wheel станет блокером): libfglair собирается в docker при старте интеграции один раз (dev-mode) — не рекомендуется для продакшна; чисто-Python повторная реализация протокола — запрещена (дубль логики, расползание с ESP32-веткой). ## 2. Состав репозиториев 1. **`pyfglair`** (python-пакет): * `pyfglair/_corebuild.py` — cmake-сборка при упаковке wheel; * `pyfglair/_cffi.py` — cffi-декларации поверх `include/fgl/c_api.h` (extern "C"-шейм ядра); * `pyfglair/session.py` — pythonic-обёртка: `Session(cfg)`, колбэки ядра мостятся в `asyncio` через `loop.call_soon_threadsafe`; * `pyfglair/provision.py` — облачный discovery (перенос `legacy/discovery.py` на современный aiohttp): вход e-mail/пароль/регион → dsn, ip, oem_model, lanip_key, lanip_key_id; * CLI: `python -m pyfglair discover` / `python -m pyfglair monitor`. 2. **`ha-fglair`** (custom component, HACS-совместимый): * `custom_components/fglair/…` (см. §4); * `manifest.json`: `requirements: ["pyfglair>=1.0.0"]`, `domain: fglair`, `config_flow: true`, `iot_class: local_push`. ## 3. Конфигурация (config flow) Вариант A — облачный (удобный): 1. Пользователь вводит e-mail/пароль FGLair + регион EU/US/CN. 2. Интеграция через `pyfglair.provision` получает список устройств (name, model, ip, dsn, lanip_key, lanip_key_id) и показывает их. 3. Выбор устройства → `ConfigEntry` (те же поля, что `config_kata.json`) → шаг «пробное подключение» (старт сессии, ожидание ONLINE ≤ 10 с). Вариант B — ручной: ввод ip/dsn/lanip_key/lanip_key_id по полям или импорт существующего `config_*.json` (миграция с legacy-скрипта). Ключ считается **статичным** (см. PLAN_CORE_LIBRARY §8): облако используется только здесь, при настройке. В рантайме — никогда. Repair-флоу (редкий, теоретический): * Состояние ядра `key_error` (несовпадение `key_id`) → repair «Ключ устройства изменён — перепровижинируйте». Повторный вход в облако по требованию пользователя, обновление полей ConfigEntry. Никаких автоматических перечитываний облака. **Диагностика**: Device-страница HA показывает `lanip_key`, `lanip_key_id`, `dsn`, ip — чтобы пользователь мог скопировать их в конфиг ESPHome (см. PLAN_ESPHOME). В redacted-дамп lanip_key маскируется, в полном — виден. ## 4. Структура компонента ``` custom_components/fglair/ manifest.json config_flow.py # flow + options flow + repair const.py fglair_client.py # FglairClient: владеет FglSession (фоновый поток) coordinator.py # push-driven coordinator (polling-интервал только watchdog) climate.py # ClimateEntity sensor.py # комнатная температура, error_code, op_status-флаги switch.py # economy, powerful, coil_dry, min_heat, outdoor_low_noise, # human_det_auto_save, wifi_led, indoor_fan_control select.py # af_vertical/horizontal_direction (если N>1), demand_control binary_sensor.py # connectivity diagnostics.py translations/{en,ru,...}.json ``` ## 5. Маппинг сущностей (шаблон A; B/F — по capabilities) **Climate**: * HVAC: `OFF`↔`operation_mode=0`; `COOL/HEAT/DRY/FAN_ONLY/AUTO`↔3/6/4/5/2; `turn_on` → `operation_mode=1`. * `target_temperature` ↔ `adjust_temperature` (×0.1 °C, шаг 0.5 °C); * `current_temperature` ← `display_temperature` ((v−5000)/100); * `fan_mode` ↔ `fan_speed` (quiet/low/medium/high/auto); * `swing_mode` ↔ `af_vertical_swing`+`af_horizontal_swing` (off/vertical/ horizontal/both); * presets: `ECO`→economy_mode, `BOOST`→powerful_mode (взаимоисключающие); * capabilities из `device_capabilities` скрывают недоступные режимы. **Sensors**: room temp, error_code (с текстами), op_status (флаги defrost / oil recovery / pump down / maintenance / check operation / запреты). **Binary sensor**: connectivity (ONLINE). **Switch/Select** — по списку §4. Записи идут batch'ем на действие пользователя (одно `batch_commit()` на вызов `set_temperature`/`set_hvac_mode`/…) — ядро само склеит в один local_reg notify. ## 6. Runtime-модель * Один `FglairClient` на `ConfigEntry`: фоновый daemon-thread с сессией ядра; колбэки → `asyncio` → coordinator push-update. * Состояния ядра транслируются: `online` → entities available; `recovering` — доступны (последние значения), помечено diagnostic-сенсором; `offline` → unavailable; `key_error` → unavailable + repair. * Keep-alive/rotация ключей/переподключение — полностью в ядре (15 с; самолечение десинхрона ≤15 с — PROTOCOL.md §4.4). * Выгрузка: `stop()` (delete_session, освобождает слот на модуле). ## 7. Требования к надёжности (acceptance) 1. 24 ч непрерывной работы: 0 рассинхронов; в логе ядра — штатные re-key каждые 45–60 с; сущности обновляются < 1 с после изменений с пульта. 2. Параллельная работа с приложением на телефоне: обе сессии живут (2 слота); без взаимных сбоев. 3. Вкл/выкл питания модуля: восстановление ≤ 120 с (backoff). 4. Burst 10 изменений уставки из UI: ≤ 2 local_reg notify. 5. `key_error` (симуляция смены lanip_key_id): repair отрабатывает. 6. Перезапуск HA: корректный delete_session, повторная регистрация. ## 8. Тесты * `pytest` + mock `pyfglair` (fake session, scripted callbacks): flow, entities, repair, unload. * Интеграционный тест с mock-модулем (`test/integration/mock_ac.py` ядра) через настоящий wheel: полный цикл в CI. * Ручной чек-лист на реальном приборе (совпадает с M5 ядра). ## 9. Этапы | # | Содержимое | |---|-----------| | H1 | wheel `pyfglair`: сборка, cffi-bindings, обёртка Session, CLI discover/monitor | | H2 | компонент: manifest, config_flow (облако + ручной + импорт), client/coordinator, climate | | H3 | sensor/switch/select/binary_sensor, capabilities, translations, диагностика с lanip_key | | H4 | repair-флоу, unload, тесты, публикация в HACS (custom) |