Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a32e2f0bfc | ||
|
|
34cdb7fef8 |
@@ -0,0 +1,95 @@
|
|||||||
|
# Сборка и публикация pyfglair в PyPI-реестр пакетов Gitea.
|
||||||
|
# Запуск: Actions → Publish pyfglair → Run workflow (ручной, workflow_dispatch).
|
||||||
|
#
|
||||||
|
# Секреты репозитория (Settings → Actions → Secrets):
|
||||||
|
# GITEA_PYPI_TOKEN — personal access token со scope write:package
|
||||||
|
# GITEA_PYPI_USER — (опционально) имя пользователя Gitea для upload;
|
||||||
|
# по умолчанию — актор запуска.
|
||||||
|
#
|
||||||
|
# Примечания Gitea Actions:
|
||||||
|
# * встроенный GITEA_TOKEN не может публиковать пакеты — нужен PAT;
|
||||||
|
# * actions/checkout и actions/setup-python тянутся с github.com
|
||||||
|
# (если инстанс изолирован — замените на абсолютные URL своих зеркал);
|
||||||
|
# * сборка wheel с bundled mbedtls требует доступ к github.com
|
||||||
|
# (FetchContent); при BUNDLED=0 ставится системный libmbedtls-dev.
|
||||||
|
name: Publish pyfglair
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
bundled_mbedtls:
|
||||||
|
description: "1 — встроить mbedtls, 0 — использовать системный"
|
||||||
|
required: false
|
||||||
|
default: "1"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
publish:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Python
|
||||||
|
uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: "3.12"
|
||||||
|
|
||||||
|
- name: Toolchain
|
||||||
|
run: |
|
||||||
|
if ! command -v cmake >/dev/null || ! command -v ninja >/dev/null \
|
||||||
|
|| ! command -v g++ >/dev/null; then
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y --no-install-recommends cmake ninja-build g++
|
||||||
|
fi
|
||||||
|
if [ "${{ inputs.bundled_mbedtls }}" = "0" ]; then
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y --no-install-recommends libmbedtls-dev
|
||||||
|
fi
|
||||||
|
cmake --version | head -1
|
||||||
|
g++ --version | head -1
|
||||||
|
|
||||||
|
- name: Build wheel + sdist
|
||||||
|
env:
|
||||||
|
BUNDLED: ${{ inputs.bundled_mbedtls }}
|
||||||
|
run: |
|
||||||
|
if [ "$BUNDLED" = "0" ]; then
|
||||||
|
export FGL_BUNDLED_MBEDTLS=0
|
||||||
|
else
|
||||||
|
export FGL_BUNDLED_MBEDTLS=1
|
||||||
|
fi
|
||||||
|
pip install --upgrade build
|
||||||
|
python -m build
|
||||||
|
ls -l dist
|
||||||
|
|
||||||
|
- name: Smoke test wheel
|
||||||
|
run: |
|
||||||
|
python -m venv /tmp/wheeltest
|
||||||
|
/tmp/wheeltest/bin/pip install --quiet dist/*.whl
|
||||||
|
/tmp/wheeltest/bin/python -c "import pyfglair.session as s; print('pyfglair:', s.__file__)"
|
||||||
|
/tmp/wheeltest/bin/python -c "from pyfglair import Template, Prop, convert_to_display; assert convert_to_display(Template.A, Prop.DISPLAY_TEMPERATURE, 7000) == 200"
|
||||||
|
|
||||||
|
- name: Publish to Gitea package registry (PyPI)
|
||||||
|
env:
|
||||||
|
TOKEN: ${{ secrets.GITEA_PYPI_TOKEN }}
|
||||||
|
SECRET_USER: ${{ secrets.GITEA_PYPI_USER }}
|
||||||
|
run: |
|
||||||
|
if [ -z "$TOKEN" ]; then
|
||||||
|
echo "::error::Задайте секрет GITEA_PYPI_TOKEN (PAT со scope write:package)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
SERVER="${GITHUB_SERVER_URL:-}"
|
||||||
|
if [ -z "$SERVER" ]; then
|
||||||
|
SERVER="$(git remote get-url origin | sed -E 's#^git@([^:]+):.*#https://\1#; s#^(https?://[^/]+)/.*#\1#')"
|
||||||
|
fi
|
||||||
|
REPO="${GITHUB_REPOSITORY:-$(git remote get-url origin | sed -E 's#.*[:/]([^/]+/[^/]+?)(\.git)?$#\1#')}"
|
||||||
|
OWNER="${REPO%%/*}"
|
||||||
|
GITEA_USER="${SECRET_USER:-${GITHUB_ACTOR:-git}}"
|
||||||
|
pip install --upgrade twine
|
||||||
|
python -m twine upload \
|
||||||
|
--repository-url "$SERVER/api/packages/$OWNER/pypi" \
|
||||||
|
--username "$GITEA_USER" \
|
||||||
|
--password "$TOKEN" \
|
||||||
|
--skip-existing \
|
||||||
|
--non-interactive \
|
||||||
|
dist/*
|
||||||
|
echo "Опубликовано: $SERVER/api/packages/$OWNER/pypi/simple/pyfglair/"
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
name: Validate (hassfest)
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
pull_request:
|
||||||
|
schedule:
|
||||||
|
- cron: "0 0 * * *"
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions: {}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
validate-hassfest:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: hassfest
|
||||||
|
uses: home-assistant/actions/hassfest@master
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
name: Validate (HACS)
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
pull_request:
|
||||||
|
schedule:
|
||||||
|
- cron: "0 0 * * *"
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions: {}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
validate-hacs:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: HACS validation
|
||||||
|
uses: hacs/action@main
|
||||||
|
with:
|
||||||
|
category: integration
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2026 Petr Polezhaev
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Вендоренный парсер JSON `third_party/jsmn` распространяется под лицензией
|
||||||
|
MIT (см. `third_party/jsmn/LICENSE`).
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
include CMakeLists.txt README.md pyproject.toml setup.py
|
include CMakeLists.txt LICENSE README.md pyproject.toml setup.py
|
||||||
recursive-include include *.h *.hpp
|
recursive-include include *.h *.hpp
|
||||||
recursive-include src *.cpp *.hpp
|
recursive-include src *.cpp *.hpp
|
||||||
recursive-include third_party *
|
recursive-include third_party *
|
||||||
|
|||||||
@@ -126,5 +126,6 @@ converted from the module's 0.01 °C+5000 format.
|
|||||||
|
|
||||||
## License / provenance
|
## License / provenance
|
||||||
|
|
||||||
Protocol documentation and code reconstructed from the FGLair 3.4.3 APK for
|
MIT — see [`LICENSE`](LICENSE). Protocol documentation and code reconstructed
|
||||||
interoperability; `third_party/jsmn` is MIT.
|
from the FGLair 3.4.3 APK for interoperability; vendored `third_party/jsmn`
|
||||||
|
is MIT.
|
||||||
|
|||||||
@@ -11,9 +11,11 @@
|
|||||||
## Требования
|
## Требования
|
||||||
|
|
||||||
* Home Assistant ≥ 2025.1 (Linux x86_64/aarch64).
|
* Home Assistant ≥ 2025.1 (Linux x86_64/aarch64).
|
||||||
* Пакет `pyfglair` (манифест ставит его автоматически из PyPI).
|
* Пакет `pyfglair`. Манифест ставит его из PyPI; при внутренней установке
|
||||||
До публикации на PyPI установите wheel вручную в python-окружение HA:
|
(Gitea, без публичного PyPI) поставьте вручную из PyPI-реестра пакетов
|
||||||
`pip install pyfglair-*.whl` (см. [`docs/RELEASE_HA.md`](../../docs/RELEASE_HA.md)).
|
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-сессии**:
|
* Модуль кондиционера в той же LAN. Модуль поддерживает **2 LAN-сессии**:
|
||||||
телефон с FGLair и HA уживаются; третья (например, ESPHome) получит 503.
|
телефон с FGLair и HA уживаются; третья (например, ESPHome) получит 503.
|
||||||
|
|
||||||
|
|||||||
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 607 B After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 832 B After Width: | Height: | Size: 1.5 KiB |
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"domain": "fglair",
|
"domain": "fglair",
|
||||||
"name": "FGLair (Fujitsu General)",
|
"name": "FGLair (Fujitsu General)",
|
||||||
"codeowners": [],
|
"codeowners": ["@petr.polezhaev"],
|
||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"documentation": "https://git.ratigorsk-12.ru/esphome/fgl-aircon",
|
"documentation": "https://git.ratigorsk-12.ru/esphome/fgl-aircon",
|
||||||
"integration_type": "device",
|
"integration_type": "device",
|
||||||
|
|||||||
@@ -1,80 +1,120 @@
|
|||||||
# Чек-лист релиза HA-интеграции (H5)
|
# Релиз и установка HA-интеграции
|
||||||
|
|
||||||
## 1. Публикация pyfglair (PyPI)
|
## 1. Внутренняя сборка и установка (Gitea, текущий режим)
|
||||||
|
|
||||||
Манифест компонента требует `pyfglair>=1.0.0`; штатный installer HA
|
Внутренний репозиторий — Gitea (`git.ratigorsk-12.ru`), поэтому:
|
||||||
резолвит требования только через PyPI. PyPI (warehouse) принимает только
|
|
||||||
`manylinux*`/`musllinux*` платформенные теги — локальный
|
* HACS к Gitea **не подключается** (только публичный GitHub) — для
|
||||||
`py3-none-linux_x86_64` будет отклонён (`HTTP 400 unsupported platform
|
внутреннего использования интеграция ставится копированием
|
||||||
tag`), поэтому wheel нужно «починить» auditwheel'ом в контейнере со старой
|
`custom_components/fglair/` в `<config>/custom_components/`;
|
||||||
glibc (manylinux):
|
* зависимость `pyfglair` публикуется в **PyPI-реестр пакетов Gitea** и
|
||||||
|
ставится оттуда.
|
||||||
|
|
||||||
|
### 1.1. Сборка и публикация wheel (Gitea Actions, ручной запуск)
|
||||||
|
|
||||||
|
Workflow: `.gitea/workflows/publish-pyfglair.yaml`.
|
||||||
|
|
||||||
|
1. Создайте personal access token Gitea со scope `write:package`
|
||||||
|
(Settings → Applications → Generate token).
|
||||||
|
2. Settings репозитория → Actions → Secrets:
|
||||||
|
* `GITEA_PYPI_TOKEN` — этот токен (обязательно);
|
||||||
|
* `GITEA_PYPI_USER` — имя пользователя Gitea (опционально; иначе актор
|
||||||
|
запуска).
|
||||||
|
3. Actions → **Publish pyfglair** → Run workflow (вход `bundled_mbedtls`:
|
||||||
|
`1` — встроить mbedtls, `0` — системный `libmbedtls-dev`).
|
||||||
|
4. Артефакт появится в: `https://git.ratigorsk-12.ru/api/packages/<owner>/pypi/simple/pyfglair/`
|
||||||
|
(`<owner>` — владелец репозитория, напр. `esphome`).
|
||||||
|
|
||||||
|
Workflow собирает `wheel` + `sdist`, прогоняет smoke-тест установки и
|
||||||
|
публикует через `twine upload --skip-existing`. Повторная публикация той же
|
||||||
|
версии пропускается; для новой версии поднимите `version` в
|
||||||
|
`pyproject.toml`.
|
||||||
|
|
||||||
|
### 1.2. Установка pyfglair в Home Assistant
|
||||||
|
|
||||||
|
Пакет обязателен (cffi-биндинги). Варианты:
|
||||||
|
|
||||||
|
* **Вручную в окружение HA** (проще всего для теста; HA увидит
|
||||||
|
установленный дистрибутив и не будет вызывать pip для `pyfglair>=1.0.0`):
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# в контейнере/venv Home Assistant (Advanced SSH & Web Terminal, docker exec и т.п.)
|
||||||
|
pip install --index-url https://<user>:<token>@git.ratigorsk-12.ru/api/packages/<owner>/pypi/simple \
|
||||||
|
--no-deps pyfglair
|
||||||
|
```
|
||||||
|
|
||||||
|
* **Через индекс pip в окружении HA** (`pip.conf`/`PIP_EXTRA_INDEX_URL`):
|
||||||
|
тогда HA сам поставит `pyfglair` из манифеста. Учтите риск dependency
|
||||||
|
confusion при `--extra-index-url` — для внутреннего стенда допустимо.
|
||||||
|
|
||||||
|
* **Публичный PyPI** — см. §2 (для распространения вне сети).
|
||||||
|
|
||||||
|
### 1.3. Обновление интеграции
|
||||||
|
|
||||||
|
`custom_components/fglair/` обновляется из Gitea (git pull / копирование),
|
||||||
|
затем перезапуск HA. `pyfglair` — переустановкой из пакетов Gitea.
|
||||||
|
|
||||||
|
## 2. Публикация pyfglair на PyPI (если понадобится публично)
|
||||||
|
|
||||||
|
PyPI (warehouse) принимает только `manylinux*`/`musllinux*` теги, поэтому
|
||||||
|
локальный `py3-none-linux_x86_64` нужно чинить auditwheel'ом в контейнере
|
||||||
|
со старой glibc:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
pip install build auditwheel twine
|
pip install build auditwheel twine
|
||||||
|
|
||||||
# для каждой архитектуры (linux x86_64/aarch64) в manylinux-контейнере
|
# для каждой архитектуры (linux x86_64/aarch64) в manylinux-контейнере:
|
||||||
# (например, quay.io/pypa/manylinux2014_<arch>):
|
python -m build --wheel
|
||||||
python -m build --wheel # .so без внешнего mbedcrypto
|
auditwheel repair dist/pyfglair-*.whl --plat manylinux2014_x86_64 -w dist/manylinux/
|
||||||
auditwheel repair dist/pyfglair-*.whl \
|
rm -f dist/pyfglair-*-linux_*.whl
|
||||||
--plat manylinux2014_x86_64 -w dist/manylinux/ # или manylinux_2_28
|
python -m build --sdist
|
||||||
rm -f dist/pyfglair-*-linux_*.whl # linux-тег PyPI отклонит
|
|
||||||
python -m build --sdist # sdist с C++-исходниками (MANIFEST.in)
|
|
||||||
twine upload dist/manylinux/* dist/*.tar.gz
|
twine upload dist/manylinux/* dist/*.tar.gz
|
||||||
```
|
```
|
||||||
|
|
||||||
Проверки перед публикацией:
|
Проверки: `scripts/py-ci.sh`, `scripts/ci.sh`, `readelf -d` по `.so`
|
||||||
|
(нет внешней `libmbedcrypto`), установка wheel в чистый venv.
|
||||||
|
|
||||||
* `scripts/py-ci.sh` — pyfglair + acceptance self-test + components;
|
## 3. GitHub-зеркало и Custom Repositories (HACS)
|
||||||
* `scripts/ci.sh` — ядро (gcc/clang, ASan/UBSan) 11/11;
|
|
||||||
* `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`.
|
|
||||||
|
|
||||||
Альтернатива — cibuildwheel (`pip install cibuildwheel`) с `auditwheel
|
|
||||||
repair` внутри, но текущий `bdist_wheel`-хук отдаёт тег
|
|
||||||
`py3-none-<plat>`, поэтому проверяйте итоговые теги вручную.
|
|
||||||
|
|
||||||
## 2. GitHub-зеркало и HACS
|
|
||||||
|
|
||||||
HACS устанавливает интеграции только с публичных **GitHub**-репозиториев
|
HACS устанавливает интеграции только с публичных **GitHub**-репозиториев
|
||||||
(GitLab/Gitea не поддерживаются). Шаги:
|
(GitLab/Gitea не поддерживаются:
|
||||||
|
https://hacs.xyz/docs/faq/other_git_providers/). Публикация в
|
||||||
|
default-репозиторий HACS не требуется — достаточно Custom Repositories, но
|
||||||
|
хостинг обязан быть GitHub.
|
||||||
|
|
||||||
* создать GitHub-зеркало (push mirror) и убедиться, что оно содержит
|
```sh
|
||||||
`custom_components/fglair/`, `hacs.json`, тег релиза;
|
git remote add github git@github.com:<owner>/fgl-aircon.git
|
||||||
* заполнить `codeowners` в `custom_components/fglair/manifest.json`
|
git push --mirror github
|
||||||
(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. Приёмка на живом стенде
|
После зеркала:
|
||||||
|
|
||||||
|
* заполнить на GitHub Description, Topics (`home-assistant`, `hacs`,
|
||||||
|
`fujitsu`, `air-conditioner`), включить Issues (проверяет HACS Action);
|
||||||
|
* проверить `codeowners` в manifest (`@petr.polezhaev`; для GitHub нужен
|
||||||
|
реальный GitHub-логин);
|
||||||
|
* обновить `version` манифеста под тег; заменить заглушки
|
||||||
|
`screenshots/step-N.png` и `brand/*.png` реальными ассетами;
|
||||||
|
* создать тег (semver) — HACS покажет версию.
|
||||||
|
|
||||||
|
Готовые файлы HACS: `hacs.json`, `info.md`, `LICENSE` (MIT),
|
||||||
|
`custom_components/fglair/brand/` (icon/icon@2x/logo + dark-варианты),
|
||||||
|
workflows `.github/workflows/{validate-hacs,hassfest}.yaml`.
|
||||||
|
|
||||||
|
## 4. Приёмка на живом стенде
|
||||||
|
|
||||||
* `tests/acceptance/test_esphome_ha.py quick` — матрица изменений (HA;
|
* `tests/acceptance/test_esphome_ha.py quick` — матрица изменений (HA;
|
||||||
с `--esphome-host` шаги «режим/уставка» идут через ESPHome, проверка — по
|
с `--esphome-host` шаги «режим/уставка» идут через ESPHome, проверка — по
|
||||||
состоянию в HA), возврат к исходному.
|
состоянию в HA), возврат к исходному.
|
||||||
* `long --hours 24 --interval 3600 --report acceptance.csv` — суточный
|
* `long --hours 24 --interval 3600 --report acceptance.csv`.
|
||||||
прогон, отчёт дописывается по ходу.
|
* Сценарии: 503 (два слота), key_error + Repair, offline/восстановление,
|
||||||
* Сценарии: 503 (два слота заняты), key_error + Repair, offline и
|
два устройства, options flow (копирование/смена ключа), reconfigure.
|
||||||
восстановление, два устройства (разные порты прослушивания), options flow
|
|
||||||
(копирование/смена ключа), reconfigure без потери конверсий.
|
|
||||||
|
|
||||||
## 4. Ограничения текущего стенда
|
## 5. Ограничения стенда
|
||||||
|
|
||||||
* Реального железа/облака в CI нет: протокол проверен mock-модулем
|
* Реального железа/облака в CI нет: протокол проверен mock-модулем,
|
||||||
(`tests/ayla/mock_ac.py`), облако — мок-сервером; приёмочный скрипт имеет
|
облако — мок-сервером; приёмочный скрипт имеет self-test на моке HA REST.
|
||||||
self-test на моке HA REST.
|
|
||||||
* Суточный soak, re-key и облачный вход — только на приборе/аккаунте.
|
* Суточный soak, re-key и облачный вход — только на приборе/аккаунте.
|
||||||
* ESPHome-канал приёмки требует установленного `aioesphomeapi` и
|
* Gitea Actions: встроенный `GITEA_TOKEN` не публикует пакеты (нужен PAT);
|
||||||
работающего ESPHome-компонента (PLAN_ESPHOME); без них скрипт работает
|
`actions/checkout`/`setup-python` тянутся с github.com (для изолированного
|
||||||
только со стороны HA.
|
инстанса используйте абсолютные URL зеркал).
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
# FGLair — локальное управление кондиционерами Fujitsu General
|
||||||
|
|
||||||
|
Интеграция Home Assistant для кондиционеров Fujitsu General (FGLair / Ayla)
|
||||||
|
**по локальной сети, без облака в рантайме**. Протокол и ядро — C++
|
||||||
|
(`fgl-aircon`), доступ из HA — через python-пакет `pyfglair` (cffi).
|
||||||
|
|
||||||
|
## Возможности
|
||||||
|
|
||||||
|
* `climate`: режим (off/cool/dry/fan/heat/auto), скорость вентилятора,
|
||||||
|
swing (вертикальный и горизонтальный), preset ECO/BOOST, уставка 16–30 °C,
|
||||||
|
текущая температура;
|
||||||
|
* `switch`: economy, powerful, coil dry, min heat, outdoor low noise,
|
||||||
|
human det auto save, Wi-Fi LED, indoor fan control;
|
||||||
|
* `select`: положение заслонок, `sensor`: температура/код ошибки/состояние
|
||||||
|
связи, `binary_sensor`: connectivity и флаги op_status;
|
||||||
|
* настройка через облако FGLair (однократно), вручную или импортом
|
||||||
|
`config_*.json`; превью шаблона с ручными конверсиями;
|
||||||
|
* Repair при несовпадении LAN-ключа, диагностика и переводы en/ru.
|
||||||
|
|
||||||
|
## Установка
|
||||||
|
|
||||||
|
HACS работает только с публичными **GitHub**-репозиториями — используйте
|
||||||
|
GitHub-зеркало этого репозитория:
|
||||||
|
|
||||||
|
1. HACS → ⋮ → **Custom repositories** → URL GitHub-зеркала, категория
|
||||||
|
**Integration** → Add → Download → перезапуск HA.
|
||||||
|
2. Либо вручную скопируйте `custom_components/fglair/` в
|
||||||
|
`<config>/custom_components/`.
|
||||||
|
|
||||||
|
Требуется пакет `pyfglair` (манифест ставит его из PyPI) и HA ≥ 2025.1 на
|
||||||
|
Linux x86_64/aarch64.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Подробная инструкция — в
|
||||||
|
[`custom_components/fglair/README.md`](custom_components/fglair/README.md).
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
[build-system]
|
[build-system]
|
||||||
requires = ["setuptools>=68", "wheel"]
|
requires = ["setuptools>=77", "wheel"]
|
||||||
build-backend = "setuptools.build_meta"
|
build-backend = "setuptools.build_meta"
|
||||||
|
|
||||||
[project]
|
[project]
|
||||||
@@ -7,6 +7,8 @@ name = "pyfglair"
|
|||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
description = "Local control of Fujitsu General (FGLair/Ayla) air conditioners: cffi bindings to the fgl-aircon C++ core"
|
description = "Local control of Fujitsu General (FGLair/Ayla) air conditioners: cffi bindings to the fgl-aircon C++ core"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
license = "MIT"
|
||||||
|
license-files = ["LICENSE"]
|
||||||
requires-python = ">=3.10"
|
requires-python = ">=3.10"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cffi>=1.15",
|
"cffi>=1.15",
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
"""Сборка wheel pyfglair: вместе с python-пакетом собирается libfgl-aircon.so
|
"""Сборка wheel pyfglair: вместе с python-пакетом собирается libfgl-aircon.so
|
||||||
из корня монорепо (cmake). Метаданные — в pyproject.toml; здесь только хуки
|
из корня монорепо (cmake). Метаданные — в pyproject.toml; здесь только хуки
|
||||||
setuptools для сборки нативного ядра."""
|
setuptools для сборки нативного ядра."""
|
||||||
|
import os
|
||||||
from importlib.util import module_from_spec, spec_from_file_location
|
from importlib.util import module_from_spec, spec_from_file_location
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
@@ -32,7 +33,8 @@ class build_py(_build_py):
|
|||||||
dest.mkdir(parents=True, exist_ok=True)
|
dest.mkdir(parents=True, exist_ok=True)
|
||||||
for stale in dest.glob("libfgl-aircon.*"):
|
for stale in dest.glob("libfgl-aircon.*"):
|
||||||
stale.unlink()
|
stale.unlink()
|
||||||
_load_corebuild().build_core(dest=dest, bundled_mbedtls=True)
|
bundled = os.environ.get("FGL_BUNDLED_MBEDTLS", "1") != "0"
|
||||||
|
_load_corebuild().build_core(dest=dest, bundled_mbedtls=bundled)
|
||||||
super().run()
|
super().run()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||