v0.13.9-ha_addon

This commit is contained in:
Mateusz Gruszczyński
2026-09-09 15:19:10 +02:00
parent 4196fbe0ef
commit fa0d4d0754
32 changed files with 1941 additions and 30 deletions
+13
View File
@@ -0,0 +1,13 @@
# OCI registry. Works with standard OCI registries, including Zot.
REGISTRY=oci.linuxiarz.pl
IMAGE_NAME=gree-controller
# Build/runtime base: trixie or alpine.
DISTRO=trixie
# Buildx builder name.
BUILDER=gree-controller-multiarch
# Optional BuildKit config for a private registry with custom CA / HTTP.
# Example: /etc/buildkit/buildkitd.toml
BUILDER_CONFIG=
+64
View File
@@ -0,0 +1,64 @@
# syntax=docker/dockerfile:1.7
ARG RUST_VERSION=1.89
FROM --platform=$TARGETPLATFORM rust:${RUST_VERSION}-trixie AS builder-trixie
WORKDIR /src
RUN apt-get update \
&& apt-get install -y --no-install-recommends build-essential pkg-config \
&& rm -rf /var/lib/apt/lists/*
COPY Cargo.toml Cargo.lock build.rs ./
COPY src ./src
COPY web ./web
COPY lang ./lang
COPY presets ./presets
COPY docs ./docs
RUN cargo build --locked --release
FROM --platform=$TARGETPLATFORM rust:${RUST_VERSION}-alpine AS builder-alpine
WORKDIR /src
RUN apk add --no-cache build-base pkgconfig musl-dev
COPY Cargo.toml Cargo.lock build.rs ./
COPY src ./src
COPY web ./web
COPY lang ./lang
COPY presets ./presets
COPY docs ./docs
RUN cargo build --locked --release
FROM --platform=$TARGETPLATFORM debian:trixie-slim AS runtime-trixie
ARG BUILD_VERSION=dev
ARG TARGETARCH
LABEL io.hass.version="${BUILD_VERSION}" \
io.hass.type="app" \
org.opencontainers.image.base.name="debian:trixie-slim" \
org.opencontainers.image.description="GREE Controller Home Assistant add-on" \
org.opencontainers.image.vendor="MateuszG" \
org.opencontainers.image.title="GREE Controller" \
org.opencontainers.image.version="${BUILD_VERSION}" \
org.opencontainers.image.architecture="${TARGETARCH}"
RUN apt-get update \
&& apt-get install -y --no-install-recommends ca-certificates tzdata jq iproute2 \
&& rm -rf /var/lib/apt/lists/*
COPY --from=builder-trixie /src/target/release/gree-controller /usr/local/bin/gree-controller
COPY ha-addon/run.sh /usr/local/bin/run.sh
RUN chmod 0755 /usr/local/bin/run.sh /usr/local/bin/gree-controller
EXPOSE 8787/tcp
ENTRYPOINT ["/usr/local/bin/run.sh"]
FROM --platform=$TARGETPLATFORM alpine:latest AS runtime-alpine
ARG BUILD_VERSION=dev
ARG TARGETARCH
LABEL io.hass.version="${BUILD_VERSION}" \
io.hass.type="app" \
org.opencontainers.image.base.name="alpine:latest" \
org.opencontainers.image.description="GREE Controller Home Assistant add-on" \
org.opencontainers.image.vendor="MateuszG" \
org.opencontainers.image.title="GREE Controller" \
org.opencontainers.image.version="${BUILD_VERSION}" \
org.opencontainers.image.architecture="${TARGETARCH}"
RUN apk add --no-cache ca-certificates tzdata jq iproute2
COPY --from=builder-alpine /src/target/release/gree-controller /usr/local/bin/gree-controller
COPY ha-addon/run.sh /usr/local/bin/run.sh
RUN chmod 0755 /usr/local/bin/run.sh /usr/local/bin/gree-controller
EXPOSE 8787/tcp
ENTRYPOINT ["/usr/local/bin/run.sh"]
+32
View File
@@ -0,0 +1,32 @@
# 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
@@ -0,0 +1,32 @@
# 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`
+116
View File
@@ -0,0 +1,116 @@
# GREE Controller - Home Assistant add-on
Everything related to the Home Assistant add-on lives in this directory: build, OCI publishing, custom repository, VLAN/multi-interface docs and diagrams.
## Topology / topologia
### 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
```bash
cd ha-addon
cp .env.example .env
$EDITOR .env
```
Example:
```dotenv
REGISTRY=zot.linuxiarz.pl
IMAGE_NAME=gree-controller
DISTRO=trixie
```
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:
```bash
./build.sh render
```
## Home Assistant network model
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.
Recommended model:
- 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.
Detailed documentation:
- `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
## Publish the custom repository
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`.
+89
View File
@@ -0,0 +1,89 @@
#!/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
REGISTRY="${REGISTRY:-oci.linuxiarz.pl}"
IMAGE_NAME="${IMAGE_NAME:-gree-controller}"
DISTRO="${DISTRO:-trixie}"
BUILDER="${BUILDER:-gree-controller-multiarch}"
BUILDER_CONFIG="${BUILDER_CONFIG:-}"
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; }
case "$DISTRO" in
trixie|alpine) ;;
*) echo "DISTRO must be one of: trixie, alpine" >&2; exit 2 ;;
esac
IMAGE_REPO="${REGISTRY%/}/${IMAGE_NAME#/}"
IMAGE_TAG="${IMAGE_REPO}:${VERSION}"
"$SCRIPT_DIR/render-repository.sh"
if [[ "$ACTION" == "render" ]]; then
exit 0
fi
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; }
ensure_builder() {
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
docker buildx "${args[@]}" >/dev/null
fi
docker buildx inspect --bootstrap >/dev/null
}
ensure_builder
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"
;;
*)
echo "Usage: $0 [push|load [amd64|aarch64]|render]" >&2
exit 2
;;
esac
+21
View File
@@ -0,0 +1,21 @@
# 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
@@ -0,0 +1,16 @@
# 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
@@ -0,0 +1,21 @@
# 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.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

+79
View File
@@ -0,0 +1,79 @@
#!/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
@@ -0,0 +1,48 @@
#!/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"
@@ -0,0 +1,12 @@
# 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`.
## 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.
@@ -0,0 +1,65 @@
# GREE Controller - Home Assistant add-on
## Installation
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`.
## Topology diagrams
### 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)
### Polish
![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)
## Network model
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.
Configure physical NICs and VLANs on Home Assistant OS first. Check the current host interfaces with:
```bash
ha network info
```
Example VLAN 50 on `eth0`, without adding another default gateway:
```bash
ha network vlan eth0 50 \
--ipv4-method static \
--ipv4-address 192.168.50.2/24 \
--ipv6-method disabled
```
Then use one of these add-on configurations:
### One dedicated GREE interface
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`.
### Several host interfaces / several directly attached subnets
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.
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.
Do not use `discovery_broadcast=auto` when `gree_interface` is empty; automatic broadcast calculation needs an explicitly selected interface.
## 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.
@@ -0,0 +1,65 @@
# 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.
@@ -0,0 +1,35 @@
# 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.
## PL - topologia HA / VLAN / GREE
![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.
Full documentation: [DOCS.md](./DOCS.md).
## Versioning
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.
@@ -0,0 +1,40 @@
name: "GREE Controller"
version: "0.13.9"
slug: "gree_controller"
description: "Local GREE HVAC controller with Web UI and Home Assistant integration"
arch:
- amd64
- aarch64
image: "zot.linuxiarz.pl/gree-controller"
startup: application
boot: auto
init: false
host_network: true
ingress: true
ingress_port: 8787
ingress_stream: true
panel_icon: mdi:air-conditioner
panel_title: GREE Controller
panel_admin: true
watchdog: "http://[HOST]:8787/api/health"
backup: cold
options:
gree_interface: ""
discovery_broadcast: "255.255.255.255:7000"
simulate: false
auto_seed: false
poll_interval_seconds: 15
zone_interval_seconds: 5
discovery_timeout_ms: 3000
app_token: ""
log_level: info
schema:
gree_interface: str
discovery_broadcast: str
simulate: bool
auto_seed: bool
poll_interval_seconds: "int(2,3600)"
zone_interval_seconds: "int(2,3600)"
discovery_timeout_ms: "int(500,30000)"
app_token: password
log_level: "list(error|warn|info|debug|trace)"
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

@@ -0,0 +1,28 @@
configuration:
gree_interface:
name: GREE network interface
description: Interface name or local IPv4 address. Leave empty for automatic routing.
discovery_broadcast:
name: Discovery broadcast
description: Broadcast target, for example 192.168.50.255:7000. Use an explicit subnet broadcast for VLANs.
simulate:
name: Simulation mode
description: Run without physical GREE units.
auto_seed:
name: Seed simulator
description: Create a sample simulated unit when the database is empty.
poll_interval_seconds:
name: Poll interval
description: Device polling interval in seconds.
zone_interval_seconds:
name: Zone interval
description: Thermostat control interval in seconds.
discovery_timeout_ms:
name: Discovery timeout
description: UDP discovery timeout in milliseconds.
app_token:
name: Application token
description: Optional token protecting direct Web UI/API access outside Home Assistant ingress.
log_level:
name: Log level
description: Controller log verbosity.
@@ -0,0 +1,28 @@
configuration:
gree_interface:
name: Interfejs sieci GREE
description: Nazwa interfejsu lub lokalny adres IPv4. Puste pole oznacza automatyczny wybór trasy.
discovery_broadcast:
name: Broadcast discovery
description: Adres broadcast, np. 192.168.50.255:7000. Dla VLAN użyj broadcastu konkretnej podsieci.
simulate:
name: Tryb symulacji
description: Uruchomienie bez fizycznych urządzeń GREE.
auto_seed:
name: Dane testowe symulatora
description: Dodaj przykładowe urządzenie, gdy baza jest pusta.
poll_interval_seconds:
name: Interwał odpytywania
description: Odpytywanie urządzeń w sekundach.
zone_interval_seconds:
name: Interwał stref
description: Interwał sterowania termostatem w sekundach.
discovery_timeout_ms:
name: Timeout discovery
description: Timeout wykrywania UDP w milisekundach.
app_token:
name: Token aplikacji
description: Opcjonalna ochrona bezpośredniego dostępu do Web UI/API poza ingressem Home Assistanta.
log_level:
name: Poziom logowania
description: Szczegółowość logów kontrolera.
+2
View File
@@ -0,0 +1,2 @@
name: GREE Controller
maintainer: linuxiarz.pl
+40
View File
@@ -0,0 +1,40 @@
#!/usr/bin/env bash
set -Eeuo pipefail
CONFIG=/data/options.json
read_option() {
local key="$1" default_value="${2-}"
if [[ -f "$CONFIG" ]]; then
jq -r --arg key "$key" --arg default "$default_value" \
'if has($key) and .[$key] != null then .[$key] else $default end' "$CONFIG"
else
printf '%s\n' "$default_value"
fi
}
GREE_INTERFACE="$(read_option gree_interface '')"
DISCOVERY_BROADCAST="$(read_option discovery_broadcast '255.255.255.255:7000')"
SIMULATE="$(read_option simulate 'false')"
AUTO_SEED="$(read_option auto_seed 'false')"
POLL_INTERVAL="$(read_option poll_interval_seconds '15')"
ZONE_INTERVAL="$(read_option zone_interval_seconds '5')"
DISCOVERY_TIMEOUT="$(read_option discovery_timeout_ms '3000')"
APP_TOKEN="$(read_option app_token '')"
LOG_LEVEL="$(read_option log_level 'info')"
export GREE_CONTROLLER_BIND="0.0.0.0:8787"
export GREE_CONTROLLER_DATABASE="/data/gree-controller.db"
export GREE_CONTROLLER_GREE_INTERFACE="$GREE_INTERFACE"
export GREE_CONTROLLER_DISCOVERY_BROADCAST="$DISCOVERY_BROADCAST"
export GREE_CONTROLLER_SIMULATE="$SIMULATE"
export GREE_CONTROLLER_AUTO_SEED="$AUTO_SEED"
export GREE_CONTROLLER_POLL_INTERVAL_SECONDS="$POLL_INTERVAL"
export GREE_CONTROLLER_ZONE_INTERVAL_SECONDS="$ZONE_INTERVAL"
export GREE_CONTROLLER_DISCOVERY_TIMEOUT_MS="$DISCOVERY_TIMEOUT"
export GREE_CONTROLLER_APP_TOKEN="$APP_TOKEN"
export RUST_LOG="gree_controller=${LOG_LEVEL},tower_http=${LOG_LEVEL}"
printf 'GREE Controller: interface=%s discovery=%s database=%s\n' \
"${GREE_INTERFACE:-auto}" "$DISCOVERY_BROADCAST" "$GREE_CONTROLLER_DATABASE"
exec /usr/local/bin/gree-controller