v0.13.9-rework_ha_addon

This commit is contained in:
Mateusz Gruszczyński
2026-09-10 08:24:53 +02:00
parent b905a6fcc4
commit 34e62da372
45 changed files with 405 additions and 1597 deletions
+32 -41
View File
@@ -1,55 +1,46 @@
80285335976065f05dd0cc3ad6006f0f5f6c8cc917dbaea9a10ad23f49df09f0 ./.env.example
d67af429e4da9ce08e9d2f2a8472849ffbd70d135b1c5da535a076026794d04c ./.env.example
a4ec3874a2e3ab1bad28fb40bb620f7b01f64d01ad9b699306bf70ada31227db ./.gitignore
36a2cb85329ae82d097a335a6afd81c1ba7bc450eebdac09c600e12befe36ba2 ./Cargo.lock
5f9afa17638997837880ab244301e3921a6444972154b49797a73bc3103fbcad ./Cargo.toml
19b2943504acb8f8de280f873a8dbec4bb6ebbe3870b158f5655d4fb8c298f5f ./LICENSE
d1418eefca2226e2bbd2a6f710f0d94bb3955ef81585b81c9681bb1dda5a7256 ./README.md
491aeceb202b240807d0d3cb72cdae622ee9ae8cbfd89439dc4add0bc648144f ./README.md
bb549919b96b0413152dd905aec8640bb53301f07ec7d0b1be48ccbd37936fef ./build.rs
d590a6df7ec31c274a2437075d76305cfafbe56385c800fbf39b18b54875119e ./docs/API.md
2e1e18fd8167dabfe2469c26e85cce62486c7cb6a502c63c6f6b0cd74d5885e0 ./docs/FLOW.md
3e995a5bb3ec40b26c2676818f90adbd5fa42e760b487d18a16b09a586702484 ./docs/openapi.json
e05c3dbc72aa2e2d5dfab2f9be713ee91ba6e69a6baddf9d44b9cda036d09637 ./ha-addon/.env.example
fef9a676b9ce82d0539d44e456237a814169a17a158557d7b803a455985bc020 ./ha-addon/.env.example
a18d2460340264d34c267fa704ee51a42e59bcc1783ee4c0dbb2a8ef42fa0f16 ./ha-addon/Dockerfile
0d7f1c5e026465b494f749ae7c4c26a0540b7b04288afa6b948ca7ad0134cb33 ./ha-addon/NETWORKING.en.md
3dcbc9ea27cd35425d7155cc3fc4705aee976f888bb157c7e1f88bfe2c8a6047 ./ha-addon/NETWORKING.md
ab7bfcde65d28e76e544ab906693e44b929332f77e10cb79f90262f0956719b4 ./ha-addon/README.md
4d55b7bb6c3aa564b2c9113fadd8878e3a39ecb7b301eadc624f16dd94107831 ./ha-addon/build.sh
62d0e3657432b727dfb993198a68a6cefba3c0f85026e9a3b01cd4e488f4e1f6 ./ha-addon/docs/README.en.md
ff4a5d68d3cd120d81f53f441cd8208af8e99c0986c28ccf7140524a91342d1a ./ha-addon/docs/README.md
79dffc634bacb0008b5d16dc6d490afb6fb80e870d424567e3dcbccf9d1083fb ./ha-addon/docs/README.pl.md
4c2f8c74bcef72883affe782283bea837d6ca7729b9789c9804a6e7b2c124bb1 ./ha-addon/docs/topologia-ha-vlan-gree-pl.png
8ee0343c78279271c0a3f580647c225be470c3679064e77d736566609c753098 ./ha-addon/docs/topology-ha-vlan-gree-en.png
7ffafcc102b997b013ce36228b39474916a87b41ade80274edabb0e6d04afcb0 ./ha-addon/render-repository.sh
7018d71adc77a53d2881672c1e452952e1c1269f5aa7d7dd78fcec0f2977efc1 ./ha-addon/repository/gree-controller/CHANGELOG.md
a9f0b5a9069de8502158f90414713be72b300b784e35c2bde37c3f597e484231 ./ha-addon/repository/gree-controller/DOCS.md
fc9039c440063e48f120f49e5166872d09625da9ef2cf3ca35589496f5a643f8 ./ha-addon/repository/gree-controller/DOCS.pl.md
e4100a2c902c50f51898150340defb84491f359ff8ee3a49fdc9327192173c5f ./ha-addon/repository/gree-controller/README.md
827dfc48c1b2a0dad1c20c9b5c3c5c55d46610901e85455ee7d4cf0c273b7d4e ./ha-addon/repository/gree-controller/config.yaml
4c2f8c74bcef72883affe782283bea837d6ca7729b9789c9804a6e7b2c124bb1 ./ha-addon/repository/gree-controller/topologia-ha-vlan-gree-pl.png
8ee0343c78279271c0a3f580647c225be470c3679064e77d736566609c753098 ./ha-addon/repository/gree-controller/topology-ha-vlan-gree-en.png
9266b7885849007ac7626c0151b401da2fcb8e0a2721a6d196089dee1a67fbf3 ./ha-addon/README.md
cd7fd4b937a1d6138699f7effd184e3c077912b881e9c73c37b90bbafba68477 ./ha-addon/build.sh
fd041032f353ceb0a2b02005f5a78d74a460b12e4e78de13dcb60129859f8c4e ./ha-addon/home-assistant/README.md
f8e8559fe10fe523ac5bc9aac25c6e26e862f679d502e8f3c39f38a0a8e40911 ./ha-addon/home-assistant/custom_components/gree_controller/__init__.py
3f6ef15ef58456376ac53fde7cace1ef359d6a6f7a64c5b575ad77ea6e55ccc4 ./ha-addon/home-assistant/custom_components/gree_controller/api.py
021a235617852c3adc4990936c3daf497309ea9a18574223805ae7496b1366c3 ./ha-addon/home-assistant/custom_components/gree_controller/climate.py
5e4aef2143e81bedb5a15dd4be5c71b64a3ab448ec6d33a20851edd098e5f529 ./ha-addon/home-assistant/custom_components/gree_controller/config_flow.py
b7f0873109c52be9d7f09bea3dffc416103c50085e1f0680d11661a969479898 ./ha-addon/home-assistant/custom_components/gree_controller/const.py
41a8958a6fe6d10e5679c95ac34832583a2a15ecfd67d09b4e094a83d06f5c47 ./ha-addon/home-assistant/custom_components/gree_controller/coordinator.py
5a96fe8f5c035c34f1339370270cd078056202d09e236dec75735be11de92a7d ./ha-addon/home-assistant/custom_components/gree_controller/entity_map.py
c4fb75c246db651087900ebfc2291ff41ac87652cd6194fc0b776b0005c1cbcf ./ha-addon/home-assistant/custom_components/gree_controller/icon.png
500f87cbfac7c933a5c22f974bf15ec8ee25ed1136eac7eeafe6a2918f8cd503 ./ha-addon/home-assistant/custom_components/gree_controller/manifest.json
c52a484b671ce738ecc00228a1db19a5d703f69ab27530c2896a5c2ae3b4a96f ./ha-addon/home-assistant/custom_components/gree_controller/number.py
39c4309001b75abb56234f05662bc06e077054986876f1927937edbce528ec95 ./ha-addon/home-assistant/custom_components/gree_controller/select.py
cca65482e36d48035aca178121a378fe7d578d600acff267ae81a6399c0da653 ./ha-addon/home-assistant/custom_components/gree_controller/sensor.py
338a42662e77f91215150851e55bbd39a5c77f5612cc77f3e037c06a6e6bdadb ./ha-addon/home-assistant/custom_components/gree_controller/switch.py
6bddb7b4620021ecd2099a86a77ef5c7f2c2dcd3d07d5db4e7b4c4ce6d3e8c03 ./ha-addon/home-assistant/custom_components/gree_controller/translations/en.json
13f30e2dcdcedbd1b6c3f99c2335e0487108fd72c8e86922368b84f2fa2038ae ./ha-addon/home-assistant/custom_components/gree_controller/translations/pl.json
c5fc5c87273d82d2834a0a5a365c821a416413ed509613441e24e4dc3507c4d2 ./ha-addon/home-assistant/generated/gree_controller_entities.example.json
fc6cad1fe53f1ad365cdf0a089ce4156460e6b07ba404b65b78aafd1a0a8ba01 ./ha-addon/repository/gree-controller/CHANGELOG.md
3c06bd11671452ea6472afd5543fb91a39aba73a1d2d95c7762c04f94ab64030 ./ha-addon/repository/gree-controller/DOCS.md
c3db302f38d26dc9f8caf37a1a8a07a1334cc07ae301d452f2940a5ec5915719 ./ha-addon/repository/gree-controller/README.md
fdfb371926690e26a3693acd32d899e222ea66e4cb3476f717f55382e303e0d0 ./ha-addon/repository/gree-controller/config.yaml
3aae6cdae4c3aaab7786a9575e7093b7e2c5b69288167075f4b7475611691a6b ./ha-addon/repository/gree-controller/topologia-ha-vlan-gree-pl.png
0d0b42a7639b128946eec379175436fa1f150294f39d2dfd169077bfa87fd14d ./ha-addon/repository/gree-controller/topology-ha-vlan-gree-en.png
d13e4c2b993d209078342c0c86d852b300692089b377aa044f811308dd188a1e ./ha-addon/repository/gree-controller/translations/en.yaml
9cf50879d7ea32cd3ff7ee95a6d50c4f1eab727420bc6610282931a9117e7dde ./ha-addon/repository/gree-controller/translations/pl.yaml
ebcfb7dfb69649aa86196c19025798b3d4661691b04f4487a7c3d9f00976f2ed ./ha-addon/repository/repository.yaml
2153b230357aab4766398577e23a7a9ff83bb135ddc86d1b3f2cbfc852efe0a1 ./ha-addon/repository/repository.yaml
c123b190219556382f0e7f3058056fb233f6261f257a01eceb96a2c0bbfa12f3 ./ha-addon/run.sh
e5642010dd44500d23214ae26dcdcddf1a4d6537b4ce458b13a33bdf95ccebd1 ./ha_addon.md
b11e581dd916676e24402112fe6896bc681abf3c94cafc85c4d3ded3f3a272a3 ./home-assistant/README.md
f8e8559fe10fe523ac5bc9aac25c6e26e862f679d502e8f3c39f38a0a8e40911 ./home-assistant/custom_components/gree_controller/__init__.py
3f6ef15ef58456376ac53fde7cace1ef359d6a6f7a64c5b575ad77ea6e55ccc4 ./home-assistant/custom_components/gree_controller/api.py
021a235617852c3adc4990936c3daf497309ea9a18574223805ae7496b1366c3 ./home-assistant/custom_components/gree_controller/climate.py
5e4aef2143e81bedb5a15dd4be5c71b64a3ab448ec6d33a20851edd098e5f529 ./home-assistant/custom_components/gree_controller/config_flow.py
b7f0873109c52be9d7f09bea3dffc416103c50085e1f0680d11661a969479898 ./home-assistant/custom_components/gree_controller/const.py
41a8958a6fe6d10e5679c95ac34832583a2a15ecfd67d09b4e094a83d06f5c47 ./home-assistant/custom_components/gree_controller/coordinator.py
5a96fe8f5c035c34f1339370270cd078056202d09e236dec75735be11de92a7d ./home-assistant/custom_components/gree_controller/entity_map.py
c4fb75c246db651087900ebfc2291ff41ac87652cd6194fc0b776b0005c1cbcf ./home-assistant/custom_components/gree_controller/icon.png
c4fb75c246db651087900ebfc2291ff41ac87652cd6194fc0b776b0005c1cbcf ./home-assistant/custom_components/gree_controller/logo.png
500f87cbfac7c933a5c22f974bf15ec8ee25ed1136eac7eeafe6a2918f8cd503 ./home-assistant/custom_components/gree_controller/manifest.json
c52a484b671ce738ecc00228a1db19a5d703f69ab27530c2896a5c2ae3b4a96f ./home-assistant/custom_components/gree_controller/number.py
39c4309001b75abb56234f05662bc06e077054986876f1927937edbce528ec95 ./home-assistant/custom_components/gree_controller/select.py
cca65482e36d48035aca178121a378fe7d578d600acff267ae81a6399c0da653 ./home-assistant/custom_components/gree_controller/sensor.py
338a42662e77f91215150851e55bbd39a5c77f5612cc77f3e037c06a6e6bdadb ./home-assistant/custom_components/gree_controller/switch.py
6bddb7b4620021ecd2099a86a77ef5c7f2c2dcd3d07d5db4e7b4c4ce6d3e8c03 ./home-assistant/custom_components/gree_controller/translations/en.json
13f30e2dcdcedbd1b6c3f99c2335e0487108fd72c8e86922368b84f2fa2038ae ./home-assistant/custom_components/gree_controller/translations/pl.json
c5fc5c87273d82d2834a0a5a365c821a416413ed509613441e24e4dc3507c4d2 ./home-assistant/generated/gree_controller_entities.example.json
081e27b6e43070d44f865335c30a42a5a29668eaa6a5ea5ab6967ac4447b8e06 ./ha-addon/sync-repository.sh
f9e31de3d109ead32bf531c074d46a087df398d62488caee0b46b5e0a1c027f7 ./ha_addon.md
253a0bc912786e67ea7fc92a64e4a510ad973bec343a88ccfb1f28fca3e8cf01 ./lang/README.md
a5412c879ac0896ae6f9c2d66dd861789897b8c8610098e3fb9b5462068acd74 ./lang/en.json
615d7297c5fa6228c017a7814aa17898aa990bfbde649d9c7c43b7b49d046ebe ./lang/pl.json
@@ -97,7 +88,7 @@ b48677a5d38684a524c6a1b0275bb6640fa1fb87e05ba29e92470f2d0aa89957 ./scripts/api_
5bc736c7bc76ca80aaa406bb171d2aa91baf4c3aa8695dce0e09b888b6ab3146 ./scripts/common.sh
6403786610ee6d2f628193c25aee0dd058d62e904aa1a31d5f62fdaae0e94b4f ./scripts/configure-gree-network.sh
1d6e14e26e49aa9d3527f30a23668bf8d9c48b67e6628ef686c3155c012155de ./scripts/dev.sh
14076104c042fba1284ebb07531a6c3ff972df1f9f5b18f70da18ab774efed27 ./scripts/generate_ha_migration.py
3fe88e64e43d380c56955f577992ea5b0252c05280f6e9dc3cd0bbcc0bf00896 ./scripts/generate_ha_migration.py
e4849261fd9ed1f01df96c0637c439c0c4eff8fa317b2918026167bba343af79 ./scripts/install-lxc.sh
bb7cd2c5b27c9dceec1d1d2846fbad9600df9c08e0ad07d13fcde97af533091c ./scripts/install.sh
1a84c91a89bf7f60aa4816a7650640f315efadf39bf7b54dc20f1259b2e2d5ce ./scripts/live_realtime_test.js
+3 -3
View File
@@ -249,7 +249,7 @@ Stale/unavailable external data falls back to the GREE sensor when possible. The
Bundled integration directory:
```text
home-assistant/custom_components/gree_controller/
ha-addon/home-assistant/custom_components/gree_controller/
```
Copy `gree_controller` to Home Assistant's `custom_components` directory, restart Home Assistant and add **GREE Controller** from Integrations.
@@ -264,7 +264,7 @@ For entity-ID migration tooling:
python3 scripts/generate_ha_migration.py --help
```
The generated mapping example is under `home-assistant/generated/`.
The generated mapping example is under `ha-addon/home-assistant/generated/`.
## History and InfluxDB
@@ -410,7 +410,7 @@ src/ Rust backend, GREE protocol and thermostat engine
web/ Embedded Web UI / PWA
web/js/ Frontend JS source modules bundled by build.rs
lang/ Runtime language packs
home-assistant/ Home Assistant custom integration and migration output
ha-addon/ Home Assistant add-on, custom integration and release tooling
scripts/ Development, install, update, service and diagnostics
systemd/ Production service unit
docs/API.md Complete API documentation
+14 -10
View File
@@ -1,13 +1,17 @@
# OCI registry. Works with standard OCI registries, including Zot.
REGISTRY=oci.linuxiarz.pl
# OCI image
REGISTRY=repo.example.com
IMAGE_NAME=gree-controller
# Build/runtime base: trixie or alpine.
DISTRO=trixie
# Buildx builder name.
DISTRO=alpine
RUST_VERSION=1.89
BUILD_PLATFORMS=linux/amd64,linux/arm64
BUILDER=gree-controller-multiarch
# Optional BuildKit config for a private registry with custom CA / HTTP.
# Example: /etc/buildkit/buildkitd.toml
BUILDER_CONFIG=
# Home Assistant distribution repository
HA_REPO_URL=https://repo.example.com/gree-controller-ha-addon/
HA_REPO_BRANCH=master
HA_REPO_PATH=../gree-controller-ha-addon
# Repository layout
ADDON_DIR=gree-controller
INTEGRATION_DOMAIN=gree_controller
-32
View File
@@ -1,32 +0,0 @@
# Home Assistant add-on: networking, VLANs, and multiple interfaces
This directory contains the full set of materials related to running GREE Controller as a Home Assistant add-on:
- multi-arch build (`build.sh`)
- Dockerfile targets for `trixie` and `alpine`
- add-on repository (`https://git.linuxiarz.pl/gru/gree-controller-ha-addon/`)
- networking documentation (`https://git.linuxiarz.pl/gru/gree-controller-ha-addon/gree-controller/DOCS.md`, `https://git.linuxiarz.pl/gru/gree-controller-ha-addon/gree-controller/DOCS.pl.md`)
- topology diagrams (`docs/topology-ha-vlan-gree-en.png`, `docs/topologia-ha-vlan-gree-pl.png`)
## Quick conclusion
For a Home Assistant add-on, the recommended model is:
- `host_network: true`
- configure VLANs and interfaces on the HA OS host
- the add-on reuses the host interfaces
- do not use `macvlan` inside the add-on
## Where the diagrams are
- `docs/topology-ha-vlan-gree-en.png` - English version
- `docs/topologia-ha-vlan-gree-pl.png` - Polish version
- `https://git.linuxiarz.pl/gru/gree-controller-ha-addon/gree-controller/topology-ha-vlan-gree-en.png` - repository copy EN
- `https://git.linuxiarz.pl/gru/gree-controller-ha-addon/gree-controller/topologia-ha-vlan-gree-pl.png` - repository copy PL
## Where the docs are
- `docs/README.en.md`
- `docs/README.pl.md`
- `https://git.linuxiarz.pl/gru/gree-controller-ha-addon/gree-controller/DOCS.md`
- `https://git.linuxiarz.pl/gru/gree-controller-ha-addon/gree-controller/DOCS.pl.md`
-32
View File
@@ -1,32 +0,0 @@
# Home Assistant add-on: sieć, VLAN-y i wiele interfejsów
Ten katalog zawiera komplet materiałów związanych z uruchomieniem GREE Controller jako dodatku Home Assistant:
- build multi-arch (`build.sh`)
- Dockerfile z targetami `trixie` i `alpine`
- repozytorium dodatku (`https://git.linuxiarz.pl/gru/gree-controller-ha-addon/`)
- dokumentację sieci (`https://git.linuxiarz.pl/gru/gree-controller-ha-addon/gree-controller/DOCS.pl.md`, `https://git.linuxiarz.pl/gru/gree-controller-ha-addon/gree-controller/DOCS.md`)
- obrazy topologii sieci (`docs/topologia-ha-vlan-gree-pl.png`, `docs/topology-ha-vlan-gree-en.png`)
## Szybki wniosek
Dla Home Assistant Add-on zalecany jest model:
- `host_network: true`
- VLAN-y i interfejsy konfigurujesz na hoście HA OS
- dodatek korzysta z interfejsów hosta
- nie używamy `macvlan` w dodatku
## Gdzie są obrazki
- `docs/topologia-ha-vlan-gree-pl.png` - wersja polska
- `docs/topology-ha-vlan-gree-en.png` - wersja angielska
- `https://git.linuxiarz.pl/gru/gree-controller-ha-addon/gree-controller/topologia-ha-vlan-gree-pl.png` - kopia publikacyjna PL
- `https://git.linuxiarz.pl/gru/gree-controller-ha-addon/gree-controller/topology-ha-vlan-gree-en.png` - kopia publikacyjna EN
## Gdzie jest opis
- `docs/README.pl.md`
- `docs/README.en.md`
- `https://git.linuxiarz.pl/gru/gree-controller-ha-addon/gree-controller/DOCS.pl.md`
- `https://git.linuxiarz.pl/gru/gree-controller-ha-addon/gree-controller/DOCS.md`
+52 -89
View File
@@ -1,37 +1,10 @@
# GREE Controller - Home Assistant add-on
# GREE Controller Home Assistant distribution
Everything related to the Home Assistant add-on lives in this directory: build, OCI publishing, custom repository, VLAN/multi-interface docs and diagrams.
This directory contains the OCI build, Home Assistant add-on repository source, custom integration and repository synchronization tooling.
## Topology / topologia
## Configuration
### PL
![Topologia Home Assistant OS + GREE Controller + VLAN](./docs/topologia-ha-vlan-gree-pl.png)
### EN
![Home Assistant OS + GREE Controller + VLAN topology](./docs/topology-ha-vlan-gree-en.png)
## Minimal versioning
There is only **one manually maintained version**: `package.version` in the project root `Cargo.toml`.
```toml
[package]
version = "X.Y.Z"
```
Do not set a version in `.env` and do not create architecture-specific release tags. `./build.sh` automatically:
1. reads the version from `Cargo.toml`,
2. synchronizes the root package entry in `Cargo.lock`,
3. writes the same version to `https://git.linuxiarz.pl/gru/gree-controller-ha-addon/gree-controller/config.yaml`,
4. builds `linux/amd64` and `linux/arm64`,
5. publishes one multi-arch OCI manifest: `REGISTRY/IMAGE_NAME:<version>`.
So a release version is changed in one place only.
## Configure build
Create the local build/repository configuration once:
```bash
cd ha-addon
@@ -39,78 +12,68 @@ cp .env.example .env
$EDITOR .env
```
Example:
`build.sh` and `sync-repository.sh` read all deployment-specific values from `.env`; `.env` is ignored by Git.
Important variables:
```dotenv
REGISTRY=zot.linuxiarz.pl
REGISTRY=repo.example.com
IMAGE_NAME=gree-controller
DISTRO=trixie
DISTRO=alpine
RUST_VERSION=1.89
BUILD_PLATFORMS=linux/amd64,linux/arm64
BUILDER=gree-controller-multiarch
BUILDER_CONFIG=
HA_REPO_URL=https://repo.example.com/gree-controller-ha-addon/
HA_REPO_BRANCH=master
HA_REPO_PATH=../gree-controller-ha-addon
ADDON_DIR=gree-controller
INTEGRATION_DOMAIN=gree_controller
```
Supported base images:
- `DISTRO=trixie` - Debian Trixie builder + `debian:trixie-slim` runtime
- `DISTRO=alpine` - latest Alpine builder + runtime
Registry authentication, when required:
```bash
docker login zot.linuxiarz.pl
```
## Build and publish
Publish one multi-arch image for Home Assistant:
```bash
./build.sh push
```
Result:
```text
zot.linuxiarz.pl/gree-controller:X.Y.Z
├─ linux/amd64
└─ linux/arm64
```
No `-amd64`, `-aarch64`, `-trixie`, `-alpine` or `latest` release tags are required.
Local single-architecture test:
```bash
./build.sh load amd64
# or
./build.sh load aarch64
```
The local test image is always tagged `REGISTRY/IMAGE_NAME:local`.
Only refresh Home Assistant repository metadata:
## OCI image
```bash
./build.sh render
./build.sh load amd64
./build.sh load aarch64
./build.sh push
```
## Home Assistant network model
The project version comes only from root `Cargo.toml`. `render` synchronizes it to `Cargo.lock`, add-on `config.yaml` and the custom integration `manifest.json`, and sets the OCI image from `.env`.
The add-on uses `host_network: true`. VLANs and physical/logical interfaces are configured on Home Assistant OS, not created as Docker `macvlan` networks inside the add-on.
## Home Assistant repository
Recommended model:
```bash
./sync-repository.sh
```
- configure NICs/VLANs on HA OS,
- let the add-on share host networking,
- set `gree_interface` to a specific host interface/IP for one GREE subnet,
- leave `gree_interface` empty for automatic per-device routing across several directly attached subnets,
- run UDP broadcast discovery separately for each VLAN/subnet.
The command updates/clones `HA_REPO_URL`, mirrors the repository and pushes only when content changed. The resulting repository contains:
Detailed documentation:
```text
repository.yaml
gree-controller/ # Home Assistant add-on
custom_components/gree_controller/ # Home Assistant custom integration
```
- `NETWORKING.md` - PL
- `NETWORKING.en.md` - EN
- `https://git.linuxiarz.pl/gru/gree-controller-ha-addon/gree-controller/DOCS.pl.md` - PL add-on docs
- `https://git.linuxiarz.pl/gru/gree-controller-ha-addon/gree-controller/DOCS.md` - EN add-on docs
The custom integration source is maintained only in:
## Publish the custom repository
```text
ha-addon/home-assistant/custom_components/gree_controller/
```
Publish `ha-addon/repository/` as a Git repository and add its URL in the Home Assistant add-on/app store as a custom repository. The generated `config.yaml` points Home Assistant at the same OCI repository and version taken from `Cargo.toml`.
It is added to the separate HA repository during synchronization, so it is not duplicated in this project.
Adding the repository to the Home Assistant add-on store installs the add-on only. The bundled custom integration can be copied from the same repository to `/config/custom_components/gree_controller/` when required.
## Layout
```text
.env.example local deployment configuration template
Dockerfile multi-architecture image
build.sh metadata + OCI build/push
run.sh add-on entrypoint
sync-repository.sh separate HA repository synchronization
repository/ add-on repository source
home-assistant/ custom integration source and migration output
```
+112 -53
View File
@@ -3,87 +3,146 @@ set -Eeuo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
ENV_FILE="${HA_ADDON_ENV_FILE:-$SCRIPT_DIR/.env}"
if [[ -f "$SCRIPT_DIR/.env" ]]; then
set -a
# shellcheck disable=SC1091
source "$SCRIPT_DIR/.env"
set +a
fi
[[ -f "$ENV_FILE" ]] || {
echo "Missing $ENV_FILE. Copy $SCRIPT_DIR/.env.example to $SCRIPT_DIR/.env and edit it." >&2
exit 1
}
REGISTRY="${REGISTRY:-zot.linuxiarz.pl}"
IMAGE_NAME="${IMAGE_NAME:-gree-controller}"
DISTRO="${DISTRO:-trixie}"
BUILDER="${BUILDER:-gree-controller-multiarch}"
BUILDER_CONFIG="${BUILDER_CONFIG:-}"
ACTION="${1:-push}"
set -a
# shellcheck disable=SC1090
source "$ENV_FILE"
set +a
VERSION="$(awk -F '"' '/^version = "/ {print $2; exit}' "$PROJECT_ROOT/Cargo.toml")"
[[ -n "$VERSION" ]] || { echo "Cannot determine version from Cargo.toml" >&2; exit 1; }
required=(REGISTRY IMAGE_NAME DISTRO RUST_VERSION BUILD_PLATFORMS BUILDER HA_REPO_URL ADDON_DIR INTEGRATION_DOMAIN)
for name in "${required[@]}"; do
[[ -n "${!name:-}" ]] || { echo "Missing $name in $ENV_FILE" >&2; exit 1; }
done
case "$DISTRO" in
trixie|alpine) ;;
*) echo "DISTRO must be one of: trixie, alpine" >&2; exit 2 ;;
esac
ACTION="${1:-push}"
VERSION="$(awk -F '"' '/^version = "/ {print $2; exit}' "$PROJECT_ROOT/Cargo.toml")"
[[ -n "$VERSION" ]] || { echo "Cannot determine version from Cargo.toml" >&2; exit 1; }
IMAGE_REPO="${REGISTRY%/}/${IMAGE_NAME#/}"
IMAGE_TAG="${IMAGE_REPO}:${VERSION}"
CONFIG="$SCRIPT_DIR/repository/$ADDON_DIR/config.yaml"
LOCKFILE="$PROJECT_ROOT/Cargo.lock"
INTEGRATION_MANIFEST="$SCRIPT_DIR/home-assistant/custom_components/$INTEGRATION_DOMAIN/manifest.json"
REPOSITORY_CONFIG="$SCRIPT_DIR/repository/repository.yaml"
"$SCRIPT_DIR/render-repository.sh"
[[ -f "$CONFIG" ]] || { echo "Missing add-on config: $CONFIG" >&2; exit 1; }
[[ -f "$INTEGRATION_MANIFEST" ]] || { echo "Missing integration manifest: $INTEGRATION_MANIFEST" >&2; exit 1; }
[[ -f "$REPOSITORY_CONFIG" ]] || { echo "Missing repository config: $REPOSITORY_CONFIG" >&2; exit 1; }
if [[ "$ACTION" == "render" ]]; then
exit 0
fi
render_metadata() {
command -v python3 >/dev/null 2>&1 || { echo "python3 is required" >&2; exit 1; }
python3 - "$CONFIG" "$LOCKFILE" "$INTEGRATION_MANIFEST" "$REPOSITORY_CONFIG" "$VERSION" "$IMAGE_REPO" "$HA_REPO_URL" <<'PY'
from pathlib import Path
import re
import sys
command -v docker >/dev/null 2>&1 || { echo "docker is required" >&2; exit 1; }
docker buildx version >/dev/null 2>&1 || { echo "docker buildx is required" >&2; exit 1; }
config = Path(sys.argv[1])
lockfile = Path(sys.argv[2])
manifest = Path(sys.argv[3])
repository = Path(sys.argv[4])
version = sys.argv[5]
image = sys.argv[6]
repo_url = sys.argv[7]
lines = config.read_text(encoding="utf-8").splitlines()
out = []
for line in lines:
if line.startswith("version:"):
out.append(f'version: "{version}"')
elif line.startswith("image:"):
out.append(f'image: "{image}"')
elif line.startswith("url:"):
out.append(f'url: "{repo_url}"')
else:
out.append(line)
config.write_text("\n".join(out) + "\n", encoding="utf-8")
lock = lockfile.read_text(encoding="utf-8")
pattern = r'(\[\[package\]\]\nname = "gree-controller"\nversion = ")[^"]+("\n)'
updated, count = re.subn(pattern, rf'\g<1>{version}\g<2>', lock, count=1)
if count != 1:
raise SystemExit("Could not find gree-controller package version in Cargo.lock")
lockfile.write_text(updated, encoding="utf-8")
import json
data = json.loads(manifest.read_text(encoding="utf-8"))
data["version"] = version
manifest.write_text(json.dumps(data, indent=2) + "\n", encoding="utf-8")
repo_lines = repository.read_text(encoding="utf-8").splitlines()
repo_out = [f"url: {repo_url}" if line.startswith("url:") else line for line in repo_lines]
repository.write_text("\n".join(repo_out) + "\n", encoding="utf-8")
PY
printf 'Synced version %s; image %s\n' "$VERSION" "$IMAGE_REPO"
}
ensure_builder() {
command -v docker >/dev/null 2>&1 || { echo "docker is required" >&2; exit 1; }
docker buildx version >/dev/null 2>&1 || { echo "docker buildx is required" >&2; exit 1; }
if docker buildx inspect "$BUILDER" >/dev/null 2>&1; then
docker buildx use "$BUILDER"
else
args=(create --name "$BUILDER" --driver docker-container --use)
if [[ -n "$BUILDER_CONFIG" ]]; then
args+=(--config "$BUILDER_CONFIG")
fi
[[ -z "${BUILDER_CONFIG:-}" ]] || args+=(--config "$BUILDER_CONFIG")
docker buildx "${args[@]}" >/dev/null
fi
docker buildx inspect --bootstrap >/dev/null
}
ensure_builder
build_push() {
ensure_builder
docker buildx build \
--platform "$BUILD_PLATFORMS" \
-f "$SCRIPT_DIR/Dockerfile" \
--target "runtime-${DISTRO}" \
--build-arg "BUILD_VERSION=$VERSION" \
--build-arg "RUST_VERSION=$RUST_VERSION" \
-t "$IMAGE_TAG" \
--push \
"$PROJECT_ROOT"
printf 'Published %s (%s, %s)\n' "$IMAGE_TAG" "$BUILD_PLATFORMS" "$DISTRO"
}
build_load() {
local arch="${2:-amd64}" platform
case "$arch" in
amd64) platform="linux/amd64" ;;
aarch64|arm64) platform="linux/arm64" ;;
*) echo "Usage: $0 load [amd64|aarch64]" >&2; exit 2 ;;
esac
ensure_builder
docker buildx build \
--platform "$platform" \
-f "$SCRIPT_DIR/Dockerfile" \
--target "runtime-${DISTRO}" \
--build-arg "BUILD_VERSION=$VERSION" \
--build-arg "RUST_VERSION=$RUST_VERSION" \
-t "${IMAGE_REPO}:local" \
--load \
"$PROJECT_ROOT"
printf 'Loaded %s:local for %s (%s)\n' "$IMAGE_REPO" "$arch" "$DISTRO"
}
render_metadata
case "$ACTION" in
push)
docker buildx build \
--platform linux/amd64,linux/arm64 \
-f "$SCRIPT_DIR/Dockerfile" \
--target "runtime-${DISTRO}" \
--build-arg "BUILD_VERSION=$VERSION" \
-t "$IMAGE_TAG" \
--push \
"$PROJECT_ROOT"
printf 'Published %s using %s (amd64 + aarch64)\n' "$IMAGE_TAG" "$DISTRO"
;;
load)
arch="${2:-amd64}"
case "$arch" in
amd64) platform="linux/amd64" ;;
aarch64|arm64) platform="linux/arm64" ;;
*) echo "Usage: $0 load [amd64|aarch64]" >&2; exit 2 ;;
esac
docker buildx build \
--platform "$platform" \
-f "$SCRIPT_DIR/Dockerfile" \
--target "runtime-${DISTRO}" \
--build-arg "BUILD_VERSION=$VERSION" \
-t "${IMAGE_REPO}:local" \
--load \
"$PROJECT_ROOT"
printf 'Loaded %s:local for %s using %s\n' "$IMAGE_REPO" "$arch" "$DISTRO"
;;
render) ;;
push) build_push ;;
load) build_load "${2:-amd64}" ;;
*)
echo "Usage: $0 [push|load [amd64|aarch64]|render]" >&2
echo "Usage: $0 [render|push|load [amd64|aarch64]]" >&2
exit 2
;;
esac
-21
View File
@@ -1,21 +0,0 @@
# Home Assistant add-on - networking and VLAN
This directory contains topology materials for Home Assistant OS, VLANs, and multiple network interfaces for GREE Controller.
## EN diagram
![Home Assistant OS + VLAN + GREE topology](./topology-ha-vlan-gree-en.png)
## PL diagram
![Topologia HA OS + VLAN + GREE](./topologia-ha-vlan-gree-pl.png)
## Network model
- VLANs and IP addresses are configured on the Home Assistant OS host.
- The add-on runs with `host_network: true`, so it uses the host interfaces directly.
- There is no need to create `macvlan` inside the add-on.
- For several directly attached subnets you can leave `gree_interface` empty so the controller picks the interface that best matches the device IP.
- UDP broadcast discovery happens per subnet/VLAN; broadcast usually does not cross a router.
Full details: `../NETWORKING.en.md` and `../repository/gree-controller/DOCS.md`.
-16
View File
@@ -1,16 +0,0 @@
# Home Assistant add-on - diagrams and VLAN notes
This directory stores the Home Assistant add-on topology diagrams in both languages.
- [Polish notes](./README.pl.md)
- [English notes](./README.en.md)
## Diagrams
### Polish
![Topologia HA OS + VLAN + GREE](./topologia-ha-vlan-gree-pl.png)
### English
![Home Assistant OS + VLAN + GREE topology](./topology-ha-vlan-gree-en.png)
-21
View File
@@ -1,21 +0,0 @@
# Home Assistant add-on - sieć i VLAN
Ten katalog zawiera materiały dotyczące topologii Home Assistant OS, VLAN-ów i wielu interfejsów sieciowych dla GREE Controller.
## Diagram PL
![Topologia HA OS + VLAN + GREE](./topologia-ha-vlan-gree-pl.png)
## Diagram EN
![Home Assistant OS + VLAN + GREE topology](./topology-ha-vlan-gree-en.png)
## Model sieciowy
- VLAN-y oraz adresy IP są konfigurowane na hoście Home Assistant OS.
- Add-on działa z `host_network: true`, więc korzysta bezpośrednio z interfejsów hosta.
- Nie ma potrzeby tworzenia `macvlan` wewnątrz dodatku.
- Dla kilku bezpośrednio podłączonych podsieci `gree_interface` można pozostawić puste, aby kontroler dobierał interfejs do adresu urządzenia.
- Discovery UDP broadcast wykonuje się per podsieć/VLAN; broadcast zwykle nie przechodzi przez router.
Pełny opis: `../NETWORKING.md` oraz `../repository/gree-controller/DOCS.pl.md`.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

@@ -3,7 +3,7 @@
The project includes a custom Home Assistant integration under:
```text
home-assistant/custom_components/gree_controller/
ha-addon/home-assistant/custom_components/gree_controller/
```
It creates HA entities for physical units, thermostat zones, whole-house controls and climate groups, while sending every command to the standalone Rust controller. Home Assistant therefore remains a client and UDP/AES GREE communication stays outside HA.
@@ -27,6 +27,8 @@ Copy the directory into your HA configuration:
/config/custom_components/gree_controller/
```
`sync-repository.sh` also publishes this integration as `custom_components/gree_controller/` in the same Git repository as the add-on. The add-on itself does not install the integration automatically.
Before adding the integration, open the standalone controller Web UI and go to **More -> Home Assistant / Sensors -> Create new token**. Copy the generated secret; it is shown only once.
Restart Home Assistant, then open **Settings -> Devices & services -> Add integration -> GREE Controller** and enter only:

Before

Width:  |  Height:  |  Size: 9.9 KiB

After

Width:  |  Height:  |  Size: 9.9 KiB

-79
View File
@@ -1,79 +0,0 @@
#!/usr/bin/env bash
set -Eeuo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
if [[ -f "$SCRIPT_DIR/.env" ]]; then
set -a
# shellcheck disable=SC1091
source "$SCRIPT_DIR/.env"
set +a
fi
HA_REPO_PATH="${HA_REPO_PATH:-../gree-controller-ha-addon}"
HA_REPO_BRANCH="${HA_REPO_BRANCH:-master}"
if [[ "$HA_REPO_PATH" != /* ]]; then
HA_REPO_PATH="$PROJECT_ROOT/$HA_REPO_PATH"
fi
HA_REPO_PATH="$(realpath -m "$HA_REPO_PATH")"
VERSION="$(
awk -F '"' '/^version = "/ {print $2; exit}' \
"$PROJECT_ROOT/Cargo.toml"
)"
[[ -n "$VERSION" ]] || {
echo "Cannot determine version from Cargo.toml" >&2
exit 1
}
command -v git >/dev/null 2>&1 || {
echo "git is required" >&2
exit 1
}
command -v rsync >/dev/null 2>&1 || {
echo "rsync is required" >&2
exit 1
}
[[ -d "$HA_REPO_PATH/.git" ]] || {
echo "HA_REPO_PATH is not a Git repository: $HA_REPO_PATH" >&2
exit 1
}
echo "==> Building and pushing OCI image ${VERSION}"
"$SCRIPT_DIR/build.sh" push
echo "==> Syncing Home Assistant repository"
rsync -a --delete \
--exclude='.git/' \
"$SCRIPT_DIR/repository/" \
"$HA_REPO_PATH/"
cd "$HA_REPO_PATH"
echo "==> Updating branch ${HA_REPO_BRANCH}"
git checkout "$HA_REPO_BRANCH"
git add -A
if git diff --cached --quiet; then
echo "No Home Assistant repository changes to publish."
exit 0
fi
echo "==> Committing Home Assistant add-on ${VERSION}"
git commit -m "GREE Controller ${VERSION}"
echo "==> Pushing to Gitea"
git push origin "$HA_REPO_BRANCH"
echo
echo "Published:"
echo " image version: ${VERSION}"
echo " HA repository: ${HA_REPO_PATH}"
echo " branch: ${HA_REPO_BRANCH}"
-48
View File
@@ -1,48 +0,0 @@
#!/usr/bin/env bash
set -Eeuo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
CONFIG="$SCRIPT_DIR/repository/gree-controller/config.yaml"
LOCKFILE="$PROJECT_ROOT/Cargo.lock"
REGISTRY="${REGISTRY:-oci.linuxiarz.pl}"
IMAGE_NAME="${IMAGE_NAME:-gree-controller}"
VERSION="$(awk -F '"' '/^version = "/ {print $2; exit}' "$PROJECT_ROOT/Cargo.toml")"
[[ -n "$VERSION" ]] || { echo "Cannot determine version from Cargo.toml" >&2; exit 1; }
IMAGE_REPO="${REGISTRY%/}/${IMAGE_NAME#/}"
python3 - "$CONFIG" "$LOCKFILE" "$VERSION" "$IMAGE_REPO" <<'PY2'
from pathlib import Path
import re
import sys
config = Path(sys.argv[1])
lockfile = Path(sys.argv[2])
version = sys.argv[3]
image = sys.argv[4]
# Home Assistant metadata is generated from the single version source: Cargo.toml.
lines = config.read_text(encoding="utf-8").splitlines()
out = []
for line in lines:
if line.startswith("version:"):
out.append(f'version: "{version}"')
elif line.startswith("image:"):
out.append(f'image: "{image}"')
else:
out.append(line)
config.write_text("\n".join(out) + "\n", encoding="utf-8")
# Keep Cargo.lock in sync so `cargo build --locked` remains usable after a version bump.
lock = lockfile.read_text(encoding="utf-8")
pattern = r'(\[\[package\]\]\nname = "gree-controller"\nversion = ")[^"]+("\n)'
updated, count = re.subn(pattern, rf'\g<1>{version}\g<2>', lock, count=1)
if count != 1:
raise SystemExit("Could not find gree-controller package version in Cargo.lock")
lockfile.write_text(updated, encoding="utf-8")
PY2
printf 'Synced version %s -> Cargo.lock + Home Assistant metadata; image %s:%s\n' \
"$VERSION" "$IMAGE_REPO" "$VERSION"
@@ -1,12 +1,8 @@
# Changelog
Release version is maintained only in the project root `Cargo.toml`. Home Assistant metadata is generated by `ha-addon/build.sh` / `ha-addon/render-repository.sh`.
## 0.13.9
## Current
- Home Assistant add-on packaging.
- amd64 and aarch64 in one OCI multi-arch manifest.
- Host-network operation for GREE UDP discovery and multi-interface hosts.
- Home Assistant ingress support.
- Polish and English topology diagrams and networking documentation.
- Debian Trixie or latest Alpine build/runtime target.
- Home Assistant add-on with `amd64` + `aarch64` multi-arch OCI image.
- Host networking for GREE UDP discovery and multi-interface/VLAN hosts.
- Home Assistant ingress, watchdog and cold backup support.
- Polish and English documentation consolidated into one `DOCS.md`.
+92 -31
View File
@@ -1,27 +1,90 @@
# GREE Controller - Home Assistant add-on
# GREE Controller Home Assistant add-on
## Installation
Repozytorium: `https://git.linuxiarz.pl/gru/gree-controller-ha-addon/`
Obraz OCI: `zot.linuxiarz.pl/gree-controller:<version>`
Publish the `ha-addon/repository` directory as a Git repository. In Home Assistant open the app/add-on store, add that Git repository URL as a custom repository, refresh the store and install **GREE Controller**.
---
The repository metadata points to a pre-built multi-architecture OCI image. The image tag must be identical to `version` in `config.yaml`.
## PL
## Topology diagrams
### Instalacja
### English
W Home Assistant dodaj jako własne repozytorium:
![Home Assistant OS + GREE Controller + VLAN topology](https://git.linuxiarz.pl/gru/gree-controller-ha-addon/media/branch/master/gree-controller/topology-ha-vlan-gree-en.png)
```text
https://git.linuxiarz.pl/gru/gree-controller-ha-addon/
```
### Polish
Odśwież sklep dodatków/aplikacji i zainstaluj **GREE Controller**. `config.yaml` wskazuje gotowy wieloarchitekturowy obraz OCI; jego tag musi być równy polu `version`.
### Sieć, VLAN i discovery
![Topologia Home Assistant OS + GREE Controller + VLAN](https://git.linuxiarz.pl/gru/gree-controller-ha-addon/raw/branch/master/gree-controller/topologia-ha-vlan-gree-pl.png)
Dodatek celowo używa `host_network: true`, więc korzysta bezpośrednio z interfejsów hosta Home Assistant OS. Nie twórz dla niego Docker `macvlan`.
## Network model
Interfejsy hosta:
The add-on deliberately uses `host_network: true`. Do not attach Docker `macvlan` networks to the add-on. With host networking, the controller shares the Home Assistant host network namespace and sees host ethernet/VLAN interfaces directly.
```bash
ha network info
```
Configure physical NICs and VLANs on Home Assistant OS first. Check the current host interfaces with:
Przykład VLAN 50 na `eth0`, bez dodatkowej bramy domyślnej:
```bash
ha network vlan eth0 50 \
--ipv4-method static \
--ipv4-address 192.168.50.2/24 \
--ipv6-method disabled
```
Dla jednej sieci GREE ustaw `gree_interface` na nazwę interfejsu (np. `eth0.50`) albo jego lokalny IPv4 (np. `192.168.50.2`) oraz `discovery_broadcast` na broadcast tej podsieci, np. `192.168.50.255:7000`.
Dla wielu bezpośrednio podłączonych podsieci pozostaw `gree_interface` puste. Kontroler dobiera lokalny interfejs najlepiej pasujący do IP znanego urządzenia. Discovery nadal wysyła jeden broadcast na skan, więc każdą podsieć/VLAN skanuj osobno, zmieniając `discovery_broadcast`, albo dodaj znane urządzenia ręcznie.
Broadcast zwykle nie przechodzi przez router. Sterowanie unicast może działać przez routing/firewall, jeżeli UDP jest dozwolone. Gdy urządzenia są w routowanym VLAN-ie, zapewnij hostowi HA interfejs w tej sieci, relay broadcast UDP albo wykonuj discovery lokalnie dla każdej podsieci.
### Opcje
| Opcja | Znaczenie |
|---|---|
| `gree_interface` | interfejs lub lokalny IPv4; puste = automatyczny dobór trasy |
| `discovery_broadcast` | cel discovery UDP, np. `192.168.50.255:7000` |
| `simulate` | praca bez fizycznych urządzeń |
| `auto_seed` | przykładowe urządzenie w pustej bazie symulatora |
| `poll_interval_seconds` | interwał odpytywania urządzeń |
| `zone_interval_seconds` | interwał sterowania strefami/termostatem |
| `discovery_timeout_ms` | timeout discovery UDP |
| `app_token` | opcjonalna ochrona bezpośredniego Web UI/API |
| `log_level` | `error`, `warn`, `info`, `debug`, `trace` |
### Dostęp, dane i bezpieczeństwo
Usługa słucha na TCP `8787`; ingress Home Assistant przekazuje Web UI na ten port. Jeżeli `8787` jest osiągalny z niezaufanej sieci, ustaw `app_token` albo zablokuj port firewallem. Baza jest zapisywana w `/data/gree-controller.db`; konfiguracja używa `backup: cold`, więc dane są objęte backupem dodatku.
Watchdog sprawdza `/api/health`. Do diagnostyki sieci najpierw sprawdź `ha network info`, poprawność `gree_interface`, broadcast konkretnej podsieci i reguły UDP/firewalla.
---
## EN
### Installation
Add this custom repository in Home Assistant:
```text
https://git.linuxiarz.pl/gru/gree-controller-ha-addon/
```
Refresh the app/add-on store and install **GREE Controller**. `config.yaml` points to a pre-built multi-architecture OCI image; its tag must match `version`.
### Networking, VLANs and discovery
![Home Assistant OS + GREE Controller + VLAN topology](https://git.linuxiarz.pl/gru/gree-controller-ha-addon/raw/branch/master/gree-controller/topology-ha-vlan-gree-en.png)
The add-on intentionally uses `host_network: true`, so it uses the Home Assistant OS host interfaces directly. Do not attach a Docker `macvlan` network to the add-on.
Inspect host interfaces with:
```bash
ha network info
@@ -36,30 +99,28 @@ ha network vlan eth0 50 \
--ipv6-method disabled
```
Then use one of these add-on configurations:
For one GREE subnet, set `gree_interface` to the host interface name (for example `eth0.50`) or its local IPv4 address (for example `192.168.50.2`), and set `discovery_broadcast` to that subnet broadcast, e.g. `192.168.50.255:7000`.
### One dedicated GREE interface
For multiple directly attached subnets, leave `gree_interface` empty. The controller selects the local interface that best matches a known device IP. Discovery still sends one broadcast per scan, so scan each VLAN/subnet separately by changing `discovery_broadcast`, or add known devices manually.
Set `gree_interface` to the host interface name, for example `eth0.50`, or to its local IPv4 address, for example `192.168.50.2`. Set `discovery_broadcast` to the subnet broadcast, for example `192.168.50.255:7000`.
Broadcast normally does not cross routers. Unicast control may work through routing/firewall rules when UDP is allowed. For routed GREE VLANs, give the HA host an interface in the VLAN, use a suitable UDP broadcast relay, or perform discovery locally per subnet.
### Several host interfaces / several directly attached subnets
### Options
Leave `gree_interface` empty. For already known devices the controller chooses the local IPv4 interface whose subnet best matches the device IP. This allows normal polling and commands to devices on different directly attached networks.
| Option | Meaning |
|---|---|
| `gree_interface` | interface or local IPv4; empty = automatic route selection |
| `discovery_broadcast` | UDP discovery target, e.g. `192.168.50.255:7000` |
| `simulate` | run without physical devices |
| `auto_seed` | create a sample device in an empty simulator database |
| `poll_interval_seconds` | device polling interval |
| `zone_interval_seconds` | thermostat/zone control interval |
| `discovery_timeout_ms` | UDP discovery timeout |
| `app_token` | optional protection for direct Web UI/API access |
| `log_level` | `error`, `warn`, `info`, `debug`, `trace` |
Discovery itself sends one broadcast target per scan. To discover devices on several VLANs, scan each subnet separately by supplying its broadcast address (for example `192.168.50.255:7000`, then `192.168.60.255:7000`) or add known devices manually. After discovery, normal traffic can use automatic per-target interface selection.
### Access, data and security
Do not use `discovery_broadcast=auto` when `gree_interface` is empty; automatic broadcast calculation needs an explicitly selected interface.
The service listens on TCP `8787`; Home Assistant ingress proxies the Web UI to that port. If `8787` is reachable from an untrusted network, configure `app_token` or block the port at the firewall. The database is stored in `/data/gree-controller.db`; `backup: cold` keeps it in the add-on backup.
## Routed VLANs
Unicast UDP commands can traverse routing/firewall rules if permitted. Discovery is broadcast-based and normally does not cross a router. Either give the Home Assistant host an interface in the GREE VLAN, use a suitable UDP broadcast relay, or discover/add devices from each local subnet explicitly.
## Docker limitations
Home Assistant add-on configuration supports host networking, but not arbitrary user-defined Docker networks/macvlan attachments. Giving an add-on Docker API/full host access just to create extra container interfaces is unnecessary here and would substantially weaken isolation. Configure the VLANs/NICs on the HA OS host and let this add-on share them through host networking.
## Direct access and ingress
The service listens on TCP 8787 because the same host network is needed for GREE UDP. Home Assistant ingress proxies the Web UI to that port. If TCP 8787 is reachable from untrusted networks, configure `app_token` or block that port at the network/firewall boundary.
The standalone Home Assistant custom integration can still use the controller API exactly as before; point it at an address that Home Assistant Core can reach and use an integration token generated by GREE Controller.
The watchdog checks `/api/health`. For network troubleshooting, verify `ha network info`, `gree_interface`, the selected subnet broadcast, and UDP/firewall rules first.
@@ -1,65 +0,0 @@
# GREE Controller - dodatek Home Assistant
## Instalacja
Opublikuj katalog `ha-addon/repository` jako repozytorium Git. W Home Assistant otwórz sklep dodatków/aplikacji, dodaj URL tego repozytorium jako repozytorium niestandardowe, odśwież listę i zainstaluj **GREE Controller**.
Metadane repozytorium wskazują na gotowy wieloarchitekturny obraz OCI. Tag obrazu musi być taki sam jak `version` w `config.yaml`.
## Diagramy topologii
### Polski
![Topologia Home Assistant OS + GREE Controller + VLAN](https://git.linuxiarz.pl/gru/gree-controller-ha-addon/raw/branch/master/gree-controller/topologia-ha-vlan-gree-pl.png)
### English
![Home Assistant OS + GREE Controller + VLAN topology](https://git.linuxiarz.pl/gru/gree-controller-ha-addon/media/branch/master/gree-controller/topology-ha-vlan-gree-en.png)
## Model sieciowy
Dodatek celowo używa `host_network: true`. Nie podpinaj do dodatku sieci Docker `macvlan`. Przy host networking kontroler współdzieli przestrzeń sieciową hosta Home Assistanta i widzi bezpośrednio interfejsy ethernet/VLAN hosta.
Najpierw skonfiguruj fizyczne NIC-i i VLAN-y w Home Assistant OS. Aktualne interfejsy hosta sprawdzisz poleceniem:
```bash
ha network info
```
Przykład VLAN 50 na `eth0`, bez dodawania kolejnej domyślnej bramy:
```bash
ha network vlan eth0 50 \
--ipv4-method static \
--ipv4-address 192.168.50.2/24 \
--ipv6-method disabled
```
Następnie użyj jednej z tych konfiguracji dodatku:
### Jeden dedykowany interfejs GREE
Ustaw `gree_interface` na nazwę interfejsu hosta, np. `eth0.50`, albo na jego lokalny adres IPv4, np. `192.168.50.2`. Ustaw `discovery_broadcast` na broadcast tej podsieci, np. `192.168.50.255:7000`.
### Kilka interfejsów hosta / kilka bezpośrednio podłączonych podsieci
Pozostaw `gree_interface` puste. Dla znanych urządzeń kontroler wybiera lokalny interfejs IPv4, którego podsieć najlepiej pasuje do adresu IP urządzenia. Dzięki temu normalne odpytywanie i sterowanie działa dla urządzeń w różnych bezpośrednio podłączonych sieciach.
Samo discovery wysyła jeden broadcast na skan. Aby wykrywać urządzenia w kilku VLAN-ach, skanuj każdą podsieć osobno, podając jej adres broadcast (np. `192.168.50.255:7000`, potem `192.168.60.255:7000`) albo dodaj znane urządzenia ręcznie. Po discovery zwykły ruch może działać z automatycznym doborem interfejsu dla celu.
Nie używaj `discovery_broadcast=auto`, gdy `gree_interface` jest puste; automatyczne wyliczenie broadcastu wymaga jawnie wybranego interfejsu.
## VLAN-y routowane
Polecenia unicast UDP mogą przechodzić przez routing/reguły firewalla, jeśli jest to dozwolone. Discovery jest oparte na broadcast i zwykle nie przechodzi przez router. Albo daj hostowi Home Assistant interfejs w VLAN-ie GREE, albo użyj odpowiedniego relaya UDP broadcast, albo wykrywaj/dodawaj urządzenia osobno z każdej lokalnej podsieci.
## Ograniczenia Dockera
Konfiguracja dodatków Home Assistant wspiera host networking, ale nie dowolne, własne sieci Docker/macvlan przypinane do dodatku. Nadawanie dodatkowi pełnego dostępu do hosta lub API Dockera tylko po to, aby tworzyć dodatkowe interfejsy kontenera, nie jest tu potrzebne i znacząco osłabia izolację. Skonfiguruj VLAN-y/NIC-e na hoście HA OS i pozwól temu dodatkowi współdzielić je przez host networking.
## Bezpośredni dostęp i ingress
Usługa nasłuchuje na TCP 8787, ponieważ ten sam host network jest potrzebny dla GREE UDP. Home Assistant ingress proxy przekazuje Web UI na ten port. Jeżeli TCP 8787 jest osiągalny z niezaufanych sieci, skonfiguruj `app_token` albo zablokuj ten port na granicy sieci/firewalla.
Samodzielna integracja Home Assistant może nadal używać API kontrolera jak wcześniej; wskaż adres osiągalny z Home Assistant Core i użyj tokenu integracji wygenerowanego przez GREE Controller.
+5 -27
View File
@@ -1,35 +1,13 @@
# GREE Controller
Local GREE HVAC controller packaged as a Home Assistant add-on. It uses `host_network: true` so UDP discovery and the host VLAN/ethernet interfaces are directly available to the controller. Persistent data is stored in `/data/gree-controller.db` and is included in Home Assistant backups.
Local GREE HVAC controller packaged as a Home Assistant add-on, with Web UI, local API, UDP discovery/control, `amd64` and `aarch64` support, ingress, and database backup from `/data/gree-controller.db`.
## PL - topologia HA / VLAN / GREE
![Home Assistant OS + GREE + VLAN topology](https://git.linuxiarz.pl/gru/gree-controller-ha-addon/raw/branch/master/gree-controller/topology-ha-vlan-gree-en.png)
![Topologia Home Assistant OS + GREE Controller + VLAN](https://git.linuxiarz.pl/gru/gree-controller-ha-addon/raw/branch/master/gree-controller/topologia-ha-vlan-gree-pl.png)
Najważniejsze:
- VLAN-y konfigurujesz na hoście Home Assistant OS,
- dodatek współdzieli interfejsy hosta przez `host_network`,
- nie trzeba tworzyć Docker `macvlan`,
- przy wielu bezpośrednio podłączonych podsieciach `gree_interface` może pozostać puste,
- discovery UDP broadcast wykonuj osobno dla każdego VLAN-u/podsieci.
Pełna dokumentacja: [DOCS.pl.md](./DOCS.pl.md).
## EN - HA / VLAN / GREE topology
![Home Assistant OS + GREE Controller + VLAN topology](https://git.linuxiarz.pl/gru/gree-controller-ha-addon/media/branch/master/gree-controller/topology-ha-vlan-gree-en.png)
Key points:
- configure VLANs on the Home Assistant OS host,
- the add-on shares host interfaces via `host_network`,
- Docker `macvlan` is not required,
- with multiple directly attached subnets `gree_interface` may be left empty,
- run UDP broadcast discovery separately for each VLAN/subnet.
For VLAN deployments, configure VLAN interfaces on the Home Assistant OS host. The add-on uses `host_network: true`; with multiple directly attached subnets, `gree_interface` may remain empty. Run broadcast discovery separately for each VLAN/subnet.
Full documentation: [DOCS.md](./DOCS.md).
## Versioning
The same Git repository also contains the optional `custom_components/gree_controller` integration. It is distributed with the repository but is not installed automatically with the add-on.
The project version is maintained only in the root `Cargo.toml`. The build script copies it into the Home Assistant `config.yaml` and publishes one `amd64 + aarch64` OCI manifest under that version. No separate architecture release tags are used.
Repository: https://git.linuxiarz.pl/gru/gree-controller-ha-addon/
@@ -2,6 +2,7 @@ name: "GREE Controller"
version: "0.13.9"
slug: "gree_controller"
description: "Local GREE HVAC controller with Web UI and Home Assistant integration"
url: "https://git.linuxiarz.pl/gru/gree-controller-ha-addon/"
arch:
- amd64
- aarch64
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

After

Width:  |  Height:  |  Size: 1.4 MiB

+1
View File
@@ -1,2 +1,3 @@
name: GREE Controller
url: https://git.linuxiarz.pl/gru/gree-controller-ha-addon/
maintainer: linuxiarz.pl
+70
View File
@@ -0,0 +1,70 @@
#!/usr/bin/env bash
set -Eeuo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
ENV_FILE="${HA_ADDON_ENV_FILE:-$SCRIPT_DIR/.env}"
[[ -f "$ENV_FILE" ]] || {
echo "Missing $ENV_FILE. Copy $SCRIPT_DIR/.env.example to $SCRIPT_DIR/.env and edit it." >&2
exit 1
}
set -a
# shellcheck disable=SC1090
source "$ENV_FILE"
set +a
required=(HA_REPO_URL HA_REPO_BRANCH HA_REPO_PATH ADDON_DIR INTEGRATION_DOMAIN)
for name in "${required[@]}"; do
[[ -n "${!name:-}" ]] || { echo "Missing $name in $ENV_FILE" >&2; exit 1; }
done
command -v git >/dev/null 2>&1 || { echo "git is required" >&2; exit 1; }
command -v rsync >/dev/null 2>&1 || { echo "rsync is required" >&2; exit 1; }
if [[ "$HA_REPO_PATH" != /* ]]; then
HA_REPO_PATH="$PROJECT_ROOT/$HA_REPO_PATH"
fi
HA_REPO_PATH="$(realpath -m "$HA_REPO_PATH")"
INTEGRATION_SOURCE="$SCRIPT_DIR/home-assistant/custom_components/$INTEGRATION_DOMAIN"
[[ -d "$SCRIPT_DIR/repository/$ADDON_DIR" ]] || { echo "Missing add-on source" >&2; exit 1; }
[[ -d "$INTEGRATION_SOURCE" ]] || { echo "Missing integration source: $INTEGRATION_SOURCE" >&2; exit 1; }
"$SCRIPT_DIR/build.sh" render
if [[ ! -e "$HA_REPO_PATH" ]]; then
git clone --branch "$HA_REPO_BRANCH" "$HA_REPO_URL" "$HA_REPO_PATH"
elif [[ ! -d "$HA_REPO_PATH/.git" ]]; then
echo "HA_REPO_PATH exists but is not a Git repository: $HA_REPO_PATH" >&2
exit 1
fi
if [[ -n "$(git -C "$HA_REPO_PATH" status --porcelain)" ]]; then
echo "HA repository has uncommitted changes: $HA_REPO_PATH" >&2
exit 1
fi
git -C "$HA_REPO_PATH" checkout "$HA_REPO_BRANCH"
git -C "$HA_REPO_PATH" pull --ff-only origin "$HA_REPO_BRANCH"
STAGE="$(mktemp -d)"
trap 'rm -rf "$STAGE"' EXIT
rsync -a "$SCRIPT_DIR/repository/" "$STAGE/"
mkdir -p "$STAGE/custom_components/$INTEGRATION_DOMAIN"
rsync -a "$INTEGRATION_SOURCE/" "$STAGE/custom_components/$INTEGRATION_DOMAIN/"
rsync -a --delete --exclude='.git/' "$STAGE/" "$HA_REPO_PATH/"
git -C "$HA_REPO_PATH" add -A
if git -C "$HA_REPO_PATH" diff --cached --quiet; then
echo "HA repository is already synchronized."
exit 0
fi
VERSION="$(awk -F '"' '/^version = "/ {print $2; exit}' "$PROJECT_ROOT/Cargo.toml")"
[[ -n "$VERSION" ]] || { echo "Cannot determine version from Cargo.toml" >&2; exit 1; }
git -C "$HA_REPO_PATH" commit -m "GREE Controller ${VERSION}"
git -C "$HA_REPO_PATH" push origin "$HA_REPO_BRANCH"
printf 'Synchronized add-on + custom integration -> %s (%s)\n' "$HA_REPO_URL" "$HA_REPO_BRANCH"
+14 -1018
View File
File diff suppressed because it is too large Load Diff
Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

+1 -1
View File
@@ -79,7 +79,7 @@ def main() -> int:
parser.add_argument("--controller-token", default="", help="GREE Controller Home Assistant access token")
parser.add_argument("--ha-url", help="Optional Home Assistant URL used to validate source entities")
parser.add_argument("--ha-token", default="", help="Optional Home Assistant Long-Lived Access Token")
parser.add_argument("--output", default="home-assistant/generated/gree_controller_entities.json", help="Output mapping file")
parser.add_argument("--output", default="ha-addon/home-assistant/generated/gree_controller_entities.json", help="Output mapping file")
args = parser.parse_args()
mappings: list[tuple[str, str]] = list(args.map)