ha(H5): исправления по ревью — GitHub/HACS, рабочий ESPHome-канал, restore, manylinux

- critical: README честно описывает HACS (только публичный GitHub-зеркало)
  + ручная установка копированием; RELEASE_HA — шаг зеркала и codeowners
- critical: ESPHome-канал приёмки реализован реально (aioesphomeapi:
  connect/list_entities/climate_command для режима и уставки; fan/swing —
  только HA); unit-тест на фейковом модуле
- major: quick/long восстанавливают исходное состояние в finally даже при
  сбое; quick ждёт восстановления; ошибки шага пишутся в результат (rc 1),
  а не фаталят (rc 2)
- major: RELEASE_HA — manylinux через auditwheel repair (PyPI отклоняет
  linux_x86_64), build/twine, aarch64, корректные проверки .so, тег/версия
- major: полный ключ для ESPHome теперь реально виден в options flow
  («Настройка» на карточке интеграции, поле LAN IP key, можно заменить) —
  README/diagnostics синхронизированы
- minor: non-JSON ответ → rc 2; CSV quick+long и инкрементальная запись;
  допуск _matches в long; --settle-timeout; hacs.json homeassistant=2025.1;
  brand/{icon,logo}.png заглушки; план §6/§7 уточнён
- тесты: acceptance self-test 11 (restore-after-failure, long fail, non-JSON,
  esphome channel), options flow (2), всего 28+11+49
This commit is contained in:
2026-09-29 14:54:50 +03:00
parent 8013781e09
commit a03458f9bc
15 changed files with 609 additions and 178 deletions
+8 -4
View File
@@ -118,8 +118,9 @@ asyncio → push-coordinator. Состояния: `online` → available;
Структура (`screenshots/step-N.png` — заглушки-плейсхолдеры, владелец заменит
реальными скриншотами; рядом с каждой — описание что должно быть видно):
1. **Установка через HACS**:
* HACS → ⋮ → Custom repositories → URL репозитория, категория
1. **Установка через HACS** (нужно публичное GitHub-зеркало — HACS не
поддерживает GitLab/Gitea; либо ручное копирование `custom_components/`):
* HACS → ⋮ → Custom repositories → URL GitHub-зеркала, категория
Integration → Add. Скриншот: диалог добавления custom repository с
заполненным URL и выбранной категорией Integration.
* FGLair → Download → перезапуск HA. Скриншот: страница загрузки
@@ -152,8 +153,11 @@ Security → Long-lived access tokens) и REST API: вызов сервисов
(OAuth-флоу) не нужна — пользователь просто создаёт токен и передаёт
скрипту (`--ha-url`, `--ha-token`).
Режимы: quick (матрица burst/не-burst, обе стороны, с возвратом) и `--long`
(24 ч, ежечасное изменение с проверкой и возвратом, CSV-отчёт). Скрипт НЕ
открывает собственную сессию к кондиционеру (оба слота заняты HA+ESP).
(24 ч, ежечасное изменение с проверкой и возвратом, CSV-отчёт дописывается
по ходу). Скрипт НЕ открывает собственную сессию к кондиционеру (оба слота
заняты HA+ESP). ESPHome-канал (опционально, `--esphome-host`): через native
API отправляются шаги «режим» и «уставка», проверка — по состоянию в HA
(сквозная цепочка ESPHome → модуль → HA); fan/swing — только со стороны HA.
## 8. Этапы
+57 -33
View File
@@ -1,55 +1,79 @@
# Чек-лист релиза HA-интеграции (H5)
## 1. Публикация pyfglair
## 1. Публикация pyfglair (PyPI)
Манифест компонента требует `pyfglair>=1.0.0`; штатный installer HA
резолвит требования только через PyPI.
резолвит требования только через PyPI. PyPI (warehouse) принимает только
`manylinux*`/`musllinux*` платформенные теги — локальный
`py3-none-linux_x86_64` будет отклонён (`HTTP 400 unsupported platform
tag`), поэтому wheel нужно «починить» auditwheel'ом в контейнере со старой
glibc (manylinux):
```sh
# на каждой целевой архитектуре (linux x86_64/aarch64):
.venv/bin/python -m build --wheel # py3-none-linux_<arch>.whl с .so и mbedtls
.venv/bin/python -m build --sdist # sdist с C++-исходниками (MANIFEST.in)
pip install build auditwheel twine
# для каждой архитектуры (linux x86_64/aarch64) в manylinux-контейнере
# (например, quay.io/pypa/manylinux2014_<arch>):
python -m build --wheel # .so без внешнего mbedcrypto
auditwheel repair dist/pyfglair-*.whl \
--plat manylinux2014_x86_64 -w dist/ # или manylinux_2_28 и т.п.
python -m build --sdist # sdist с C++-исходниками (MANIFEST.in)
twine upload dist/*
```
Проверки перед публикацией:
* `scripts/py-ci.sh` — 28 pyfglair + 47 components + 6 acceptance self-test;
* `scripts/py-ci.sh` — pyfglair + acceptance self-test + components;
* `scripts/ci.sh` — ядро (gcc/clang, ASan/UBSan) 11/11;
* `readelf -d pyfglair/libfgl-aircon.so*` — нет внешней `libmbedcrypto`
(mbedtls встроен);
* `auditwheel show dist/pyfglair-*.whl` — платформа совместима с manylinux
(зависимости: libstdc++/libc);
* установка wheel в чистый venv вне репозитория: `import pyfglair.session`.
* `readelf -d build-pyfglair/libfgl-aircon.so*` (или распакованный wheel:
`pyfglair/libfgl-aircon.so*`) — нет внешней `libmbedcrypto` (встроен);
* `auditwheel show` для repaired-wheel — тег manylinux и только
базовые системные библиотеки;
* установка wheel в чистый venv вне репозитория:
`python -c "import pyfglair.session"`;
* aarch64: сборка в соответствующем manylinux-контейнере (QEMU или
нативная), иначе пользователи ARM не смогут поставить `pyfglair`.
При невозможности публикации wheel для какой-то архитектуры в манифесте
можно указать прямую ссылку на wheel, но это лишает HACS-пользователей
других архитектур; предпочтителен PyPI.
Альтернатива — cibuildwheel (`pip install cibuildwheel`) с `auditwheel
repair` внутри, но текущий `bdist_wheel`-хук отдаёт тег
`py3-none-<plat>`, поэтому проверяйте итоговые теги вручную.
## 2. HACS
## 2. GitHub-зеркало и HACS
* Репозиторий содержит `custom_components/fglair/` и `hacs.json` (name).
* Заполнить `codeowners` в `custom_components/fglair/manifest.json`
(GitHub-хендлы владельцев; сейчас пустой список — допустимо для custom
repository, но не для выкладки в HACS по умолчанию).
* Проверить `documentation`/`issue_tracker` в манифесте (актуальные URL).
* Заменить заглушки `custom_components/fglair/screenshots/step-N.png`
реальными скриншотами (описания «что должно быть видно» — в README).
* Добавить brand-ассеты (`custom_components/fglair/brand/icon.png`,
`logo.png`) при выкладке в HACS.
* Создать git-тег (semver) и указать его в HACS-релизе.
HACS устанавливает интеграции только с публичных **GitHub**-репозиториев
(GitLab/Gitea не поддерживаются). Шаги:
* создать GitHub-зеркало (push mirror) и убедиться, что оно содержит
`custom_components/fglair/`, `hacs.json`, тег релиза;
* заполнить `codeowners` в `custom_components/fglair/manifest.json`
(GitHub-хендлы; сейчас пустой список);
* проверить `documentation`/`issue_tracker` в манифесте;
* обновить `version` манифеста под номер тега (сейчас `0.1.0`, pyfglair —
`1.0.0`; синхронизируйте по вкусу — компонент и пакет версионируются
отдельно);
* заменить заглушки `custom_components/fglair/screenshots/step-N.png`
реальными скриншотами (описания «что должно быть видно» — в README);
* заменить заглушки `custom_components/fglair/brand/{icon,logo}.png`
фирменными ассетами;
* создать git-тег (semver) в GitHub-зеркале — HACS покажет версию.
## 3. Приёмка на живом стенде
* `tests/acceptance/test_esphome_ha.py quick` — матрица изменений
(HA; при наличии ESPHome-компонента — обе стороны), с возвратом.
* `--long --hours 24` — суточный прогон с CSV-отчётом.
* Проверить сценарии: 503 (два слота заняты), key_error и Repair,
offline/восстановление, несколько устройств (разные порты прослушивания),
reconfigure без потери конверсий.
* `tests/acceptance/test_esphome_ha.py quick` — матрица изменений (HA;
с `--esphome-host` шаги «режим/уставка» идут через ESPHome, проверка — по
состоянию в HA), возврат к исходному.
* `long --hours 24 --interval 3600 --report acceptance.csv` — суточный
прогон, отчёт дописывается по ходу.
* Сценарии: 503 (два слота заняты), key_error + Repair, offline и
восстановление, два устройства (разные порты прослушивания), options flow
(копирование/смена ключа), reconfigure без потери конверсий.
## 4. Ограничения текущего стенда
* Реального железа/облака в CI нет: протокол проверен mock-модулем
(`tests/ayla/mock_ac.py`), облако — мок-сервером.
* Суточный soak и работа с реальными re-key — только на приборе.
(`tests/ayla/mock_ac.py`), облако — мок-сервером; приёмочный скрипт имеет
self-test на моке HA REST.
* Суточный soak, re-key и облачный вход — только на приборе/аккаунте.
* ESPHome-канал приёмки требует установленного `aioesphomeapi` и
работающего ESPHome-компонента (PLAN_ESPHOME); без них скрипт работает
только со стороны HA.