Files
petr.polezhaev d1c02d7c4b ha(ux): мастер из трёх страниц, feature-модель и capabilities-фильтрация
- config flow: template (A/B/F с пояснениями, значения с устройства,
  определение по oem_model; для неизвестных моделей — пробинг A/B/F тремя
  короткими сессиями) -> capabilities (23 тумблера с описаниями, дефолты
  из device_capabilities/num_dir/ответов) -> limits (диапазон/шаг, ручная
  конверсия); каждая страница с пометкой «значения определены
  автоматически, можно пропустить»
- features.py: FeatureSet/LiveValues/device_default/resolve_features;
  entry.data["features"] хранит выбор пользователя; reconfigure
  предзаполняет; YAML-import получает дефолты
- сущности создаются только для включённых фич: climate (режимы/скорости/
  swing/пресеты), switch, select заслонок (caps+num_dir), датчик комнаты;
  исправлено появление select без ламелей
- trial: caps/num_dir и presence-зонды (необязательные свойства), answered;
  координатор ждёт первые свойства перед созданием сущностей (feature-
  дефолты без гонки)
- атрибут description у сущностей (HA не поддерживает тултипы) + описания
  фич в мастере (en/ru)
- тесты: features, probing, обновлённые flow/entities/repairs; 57 components
2026-09-29 17:39:34 +03:00

195 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# FGLair — интеграция Home Assistant
Локальное управление кондиционерами Fujitsu General (FGLair / Ayla LAN)
без облака в рантайме. Вся протокольная логика — в C++-ядре
[`fgl-aircon`](../../README.md) через python-пакет `pyfglair` (cffi).
> Скриншоты `screenshots/step-N.png` — заглушки-плейсхолдеры: владелец
> заменит их реальными снимками, описания «что должно быть видно» даны
> рядом с каждым шагом.
## Требования
* Home Assistant ≥ 2025.1 (Linux x86_64/aarch64).
* Пакет `pyfglair`. Манифест ставит его из PyPI; при внутренней установке
(Gitea, без публичного PyPI) поставьте вручную из PyPI-реестра пакетов
Gitea:
`pip install --index-url https://<user>:<token>@git.ratigorsk-12.ru/api/packages/<owner>/pypi/simple --no-deps pyfglair`
(подробности и сборка wheel — [`docs/RELEASE_HA.md`](../../docs/RELEASE_HA.md)).
* Модуль кондиционера в той же LAN. Модуль поддерживает **2 LAN-сессии**:
телефон с FGLair и HA уживаются; третья (например, ESPHome) получит 503.
## Установка
### Вариант A: HACS (нужно GitHub-зеркало)
HACS работает только с публичными репозиториями на **GitHub**; GitLab/Gitea
(включая текущий хостинг проекта) напрямую не поддерживаются. Зеркалируйте
репозиторий на GitHub и добавьте зеркало в HACS:
1. HACS → ⋮ → **Custom repositories** → URL GitHub-зеркала, категория
**Integration** → **Add**.
![шаг 1](screenshots/step-1.png)
*Должно быть видно: диалог добавления custom repository с заполненным URL
и выбранной категорией Integration.*
2. Найдите **FGLair** в HACS → **Download** → перезапустите Home Assistant.
![шаг 2](screenshots/step-2.png)
*Должно быть видно: страница загрузки интеграции с кнопкой Download и
версией.*
### Вариант B: вручную (любой хостинг)
Скопируйте каталог `custom_components/fglair/` в
`<config>/custom_components/fglair/` вашего HA и перезапустите Home
Assistant. Убедитесь, что `pyfglair` установлен в python-окружение HA
(см. «Требования»).
## Добавление устройства
3. Settings → Devices & Services → **Add Integration** → «FGLair».
![шаг 3](screenshots/step-3.png)
*Должно быть видно: диалог поиска интеграции с введённым «FGLair» и
выделенным результатом.*
4. **Вход в облако**: e-mail/пароль FGLair и регион. Облако
используется один раз — получить статический LAN-ключ модуля.
![шаг 4](screenshots/step-4.png)
*Должно быть видно: форма с заполненными регионом EU и e-mail, пароль
скрыт.*
5. **Выбор устройства**: список найденных кондиционеров (имя, модель, IP).
![шаг 5](screenshots/step-5.png)
*Должно быть видно: список с одним устройством (имя, модель, host).*
6. **Три страницы настройки** (все значения уже подставлены по данным
устройства — можно просто нажимать «Далее»):
1. **Шаблон модуля** — A/B/F с пояснениями; определяется по модели
модуля, а для неизвестных моделей — проверкой свойств. Рядом
показаны прочитанные с устройства значения.
2. **Возможности прибора** — тумблеры по «человекочитаемым» фичам
(режимы, скорости, swing, пресеты, флаги, заслонки) с описаниями;
включены/выключены по `device_capabilities` и ответам устройства.
Сущности создаются только для включённых возможностей.
3. **Уставка** — диапазон/шаг (у A/F 16–30 °C шаг 0.5, у B шаг 1.0) и,
при необходимости, ручная конверсия коэффициентами.
![шаг 6](screenshots/step-6.png)
*Должно быть видно: страница «Возможности прибора» с тумблерами и
описаниями, часть выключена по данным устройства.*
7. **Готово**: карточка устройства с сущностями climate/switch/select/
sensor/binary_sensor.
![шаг 7](screenshots/step-7.png)
*Должно быть видно: страница устройства с созданными сущностями.*
## Где взять ключ для ESPHome
Download diagnostics на странице устройства показывает `dsn`,
`lanip_key_id`, `host` и **маску** ключа. Полный ключ (для
`secrets.yaml` ESPHome) получите явным действием:
* **Настройка** (шестерёнка → Configure) на карточке интеграции: поле
«LAN IP key» содержит полный ключ — скопируйте его (там же можно
заменить ключ без облака); либо
* **Настроить заново** (Reconfigure) — повторный вход в облако FGLair
обновит ключ; либо
* `python -m pyfglair discover --region eu --email you@example.com
--format esphome-secrets` на хосте HA.
![шаг 8](screenshots/step-8.png)
*Должно быть видно: страница Diagnostics с полями dsn/lanip_key_id/host
и маской lanip_key.*
Альтернатива без облака — ручной ввод параметров (host, dsn, lanip_key,
lanip_key_id) или импорт `config_*.json` от `fglair-discover`/`fglctl`.
## Сущности
| Платформа | Что создаётся |
|---|---|
| climate | режим (off/cool/dry/fan/heat/auto), скорость, swing (верт./гориз.), preset ECO/BOOST, уставка, текущая температура |
| switch | economy, powerful, coil dry, min heat, outdoor low noise, human det auto save, Wi-Fi LED, indoor fan control (по шаблону и capabilities) |
| select | положение вертикальной/горизонтальной заслонки (0…N−1) |
| sensor | температура в помещении, код ошибки, диагностическое состояние связи |
| binary_sensor | connectivity + флаги op_status (defrost, maintenance, oil recovery, pump down, check operation, …) |
Список зависит от шаблона устройства (A/B/F), маски `device_capabilities`
и выбранных в мастере возможностей: то, что прибор не умеет или что
отключено, не создаётся. У каждой сущности есть краткое описание в
атрибуте `description` (карточка сущности → «Атрибуты»): HA не
поддерживает нативные тултипы, поэтому описание видно там.
## Диагностика и известные ситуации
* **`OSError: cannot load library ... ld-linux-x86-64.so.2: No such file
or directory`** — на HA OS (Alpine/musl) установился glibc-wheel. Нужна
musllinux-сборка `pyfglair`: переустановите пакет из индекса (см.
[`docs/RELEASE_HA.md`](../../docs/RELEASE_HA.md) §1.3) и перезапустите HA.
* **«Не удалось загрузить мастер настройки: Invalid handler specified»** —
HA не смог импортировать компонент (обычно нет пакета `pyfglair`).
Проверьте лог HA:
```sh
grep -iE "fglair|pyfglair" /config/home-assistant.log | tail -20
# ожидаемая причина: ModuleNotFoundError: No module named 'pyfglair'
```
Установите пакет в то же python-окружение, в котором работает HA, и
**полностью перезапустите** HA (не только интеграцию):
```sh
# HA OS / Supervised (SSH add-on с доступом к docker):
docker exec homeassistant python -m pip install --no-deps \
--index-url https://<user>:<token>@git.ratigorsk-12.ru/api/packages/<owner>/pypi/simple \
pyfglair
docker restart homeassistant
# HA Core в venv:
/srv/homeassistant/bin/python -m pip install --no-deps --index-url ... pyfglair
systemctl restart home-assistant@homeassistant
```
Проверка: `docker exec homeassistant python -c "import pyfglair; print(pyfglair.__version__)"` — должно печатать версию без ошибок.
Другие причины той же ошибки: компонент лежит не в
`<config>/custom_components/fglair/` (лишняя вложенность каталогов, нет
`__init__.py`), либо HA не перезапускался после копирования.
* **503 / оба слота заняты** — в LAN уже две сессии (телефон + ESPHome).
Освободите один слот и перезапустите интеграцию.
* **key_error** — LAN-ключ не совпал (`key_id` изменился). В HA появится
Repair; нажмите **Настроить заново** и повторите вход в облако (или
вставьте новый `config_*.json`).
* **unavailable** — модуль недоступен (сеть/питание) или нет слотов;
диагностический сенсор «Состояние связи» показывает детали
(idle/registering/online/recovering/offline/key_error).
* Записи не эхо-подтверждаются модулем: состояние обновляется
оптимистично и подтверждается push-обновлением.
## Приёмка на живом стенде
`tests/acceptance/test_esphome_ha.py` (stdlib) прогоняет матрицу изменений
через REST API HA по long-lived token, с возвратом к исходному состоянию:
```sh
python tests/acceptance/test_esphome_ha.py quick \
--ha-url http://homeassistant.local:8123 --ha-token TOKEN \
--entity climate.ac
python tests/acceptance/test_esphome_ha.py long \
--ha-url ... --ha-token ... --entity climate.ac \
--hours 24 --interval 3600 --report acceptance.csv
```