Files
gree-controller/README.md
T
2026-09-01 11:36:11 +02:00

16 KiB

GREE Controller

Self-hosted controller for GREE-compatible air conditioners with a local Web UI, thermostat zones, schedules, Home Assistant integration, history, notifications and a documented HTTP/WebSocket API.

Current release: 0.8.22

Full API reference — authentication, every endpoint, request bodies, response models, WebSocket events and examples.

What it does

  • Discovers and binds GREE Wi-Fi units on the LAN, including mixed protocol generations.
  • Provides direct technical device control and a separate thermostat layer built around zones.
  • Supports cooling/heating profiles: Comfort, Sleep, Away and custom quick targets.
  • Coordinates house, group and per-zone control without silently fighting physical/manual overrides.
  • Supports schedules, automations, night mode and temporary Quick Thermostat sessions.
  • Can use GREE sensors, Home Assistant room sensors or a weighted combination.
  • Stores recent history in SQLite and can archive/query long-term history in InfluxDB 1.x or 2.x.
  • Exposes native Home Assistant entities through the bundled custom integration.
  • Includes PWA-capable responsive UI, Polish/English localization and live diagnostics.
  • Can run in Simulation mode without physical air conditioners. A large warning is shown whenever simulation is enabled.

UI overview

The interface is intentionally split by responsibility:

Area Purpose
Dashboard Whole-house summary and Quick Thermostat controls.
Devices Discovery, binding and direct/technical GREE device control.
Zones Thermostat configuration, profiles, sensors and control ownership.
Groups Climate group membership and group power/mode/preset/custom-temperature control.
Schedules Weekly thermostat schedules and ready-made templates.
Automations Time/temperature triggered device or group actions.
History Overview, zones, devices and HA sensors with precise chart tooltips and zoom.
Simulation Simulated units for safe testing.
Night mode Quiet/Sleep/fan limits during an overnight window.
Home Assistant Sensor connection, aliases and restricted integration tokens.
Settings → Application Simulation, notifications, metrics/logs, InfluxDB, debug and backup.
Settings → GREE Controller identity, polling/discovery, GREE commands and live GREE traffic.
Events Operational event log and diagnostics.

The top bar uses the same compact language and theme controls on desktop and mobile. The live debug overlay can be filtered to All, Requests or GREE frames.

Quick start for development

Requirements are installed automatically on supported Debian/Ubuntu environments unless --no-install is used.

cp .env.example .env
./scripts/dev.sh

Useful development commands:

./scripts/dev.sh --check       # format, tests, build and HTTP smoke test
./scripts/dev.sh --release     # optimized local build
./scripts/dev.sh --reset       # recreate the local SQLite database
./scripts/smoke.sh             # API smoke test against an isolated simulated instance

The default panel is available at http://127.0.0.1:8787 when the process is bound locally.

LXC / systemd installation

The production scripts target Debian/Ubuntu systemd hosts and LXC containers.

First installation

sudo ./scripts/install.sh

Optional flags:

sudo ./scripts/install.sh --skip-tests
sudo ./scripts/install.sh --no-start

Installed layout:

Path Purpose
/opt/gree-controller/gree-controller Release binary.
/etc/gree-controller.env Environment configuration; mode 0600.
/var/lib/gree-controller/gree-controller.db SQLite database.
/etc/systemd/system/gree-controller.service systemd unit.
/var/backups/gree-controller/ Update backups used for rollback.

Update

Run from the extracted source tree of the new release:

sudo ./scripts/update.sh

The updater builds/tests first, stops the old service, backs up the binary/unit/environment/database, installs the release, checks /api/health and rolls back automatically if startup fails.

Service helper

./scripts/service.sh status
./scripts/service.sh health
./scripts/service.sh logs
sudo ./scripts/service.sh restart

./scripts/install-lxc.sh remains as a compatibility alias to install.sh.

Configuration

Copy .env.example for the full supported example. Command-line arguments exist for the core Config options, while most day-to-day runtime settings are also editable in the Web UI and persisted in SQLite.

Environment values explicitly supplied for supported runtime overrides win over the persisted value after restart.

Core variables

Variable Default Description
GREE_CONTROLLER_BIND 0.0.0.0:8787 HTTP/WebSocket listen address.
GREE_CONTROLLER_DATABASE ./data/gree-controller.db SQLite database path.
GREE_CONTROLLER_APP_TOKEN empty Optional administrator API/Web UI token. Empty means trusted-LAN mode.
GREE_CONTROLLER_BASE_PATH empty Optional reverse-proxy prefix such as /gree.
GREE_CONTROLLER_ID gree-controller GREE client/controller identifier.
GREE_CONTROLLER_SIMULATE false Initial Simulation mode.
GREE_CONTROLLER_AUTO_SEED false Seed simulated sample data when applicable.
GREE_CONTROLLER_POLL_INTERVAL_SECONDS 15 Device polling interval.
GREE_CONTROLLER_ZONE_INTERVAL_SECONDS 5 Thermostat control interval.
GREE_CONTROLLER_DISCOVERY_TIMEOUT_MS 3000 Discovery timeout.
GREE_CONTROLLER_DISCOVERY_BROADCAST 255.255.255.255:7000 GREE discovery target.
GREE_CONTROLLER_GREE_INTERFACE auto Optional interface name or local IP used for GREE UDP traffic.

Additional environment variables cover history retention, debug, night mode, Home Assistant and InfluxDB. See .env.example.

Connecting physical GREE units

  1. Place the controller host on a network that can reach the air-conditioner Wi-Fi modules by UDP.
  2. Open Devices and start discovery.
  3. Auto protocol mode is recommended; the controller accepts both supported GREE encryption generations.
  4. Newly discovered devices are bound automatically when possible. Manual bind is also available.
  5. Create a thermostat zone for each unit you want the thermostat engine to own.

Discovery uses UDP broadcast, so routed/VLAN networks must explicitly permit or relay the required traffic.

Multi-NIC / dedicated GREE interface

For a host with separate management and GREE networks, set for example:

GREE_CONTROLLER_GREE_INTERFACE=eth1

or a local address:

GREE_CONTROLLER_GREE_INTERFACE=192.168.50.2

The controller will use that interface for GREE UDP traffic while keeping the HTTP UI on GREE_CONTROLLER_BIND.

Diagnostics:

sudo ./scripts/configure-gree-network.sh
./scripts/network-debug.sh

The hardened systemd unit allows AF_NETLINK, which is required for interface discovery on multi-NIC Linux/LXC systems.

Thermostat model

Devices vs zones

A Device is the physical GREE unit. Device commands are direct/technical commands.

A Zone is the thermostat owner for a device. It decides demand from room temperature, setpoint, hysteresis, schedules, group/house gates, manual ownership and safety lockouts.

This distinction is important: direct device control intentionally behaves differently from thermostat control.

Control ownership

The zone state exposes who currently owns control (control_owner, control_source, timestamps and reason). Physical remote/direct device actions can create a manual-device takeover so normal schedules do not immediately overwrite the user. Explicit zone thermostat control hands ownership back to the thermostat engine when appropriate.

Whole-house master OFF remains authoritative and powers managed devices down.

Profiles and schedules

Each zone stores separate cooling and heating temperatures for:

  • Comfort
  • Sleep
  • Away
  • Custom/manual target

Schedules select profiles or a custom target for selected ISO weekdays (1=Monday, 7=Sunday). Overnight windows are supported. Overlapping enabled schedules for the same zone are rejected.

Quick preset/setpoint overrides normally hand control back at the next schedule boundary. Temporary Quick Thermostat adds explicit start/finish rules such as duration, exact time, temperature reached/stable or next schedule boundary.

Home Assistant

There are two independent Home Assistant directions.

1. Home Assistant as a temperature source

Configure Home Assistant / Sensors in the Web UI or use:

HA_URL=
HA_TOKEN=
HA_ENTITY_ID=
HA_OUTDOOR_ENTITY_ID=
HA_SENSOR_STALE_AFTER_SECONDS=300
HA_ALLOW_INVALID_TLS=false

Per zone, sensor_source can be:

  • device — GREE indoor sensor,
  • home_assistant — configured HA room sensor,
  • combined — weighted GREE + HA value.

Stale/unavailable external data falls back to the GREE sensor when possible. The optional outdoor sensor is only an assist signal; it never replaces room temperature.

2. GREE Controller entities inside Home Assistant

Bundled integration directory:

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.

Create a restricted token in Home Assistant / Sensors → Access tokens. The token secret is displayed only once and the database stores only its SHA-256 hash. The integration uses a restricted /api/integrations/home-assistant/* surface rather than administrator endpoints.

The integration exposes physical device climate controls, thermostat zone climate entities, whole-house controls, groups and optional unit capabilities. Prefer zone thermostat entities for normal comfort control; physical device entities are direct/manual controls.

For entity-ID migration tooling:

python3 scripts/generate_ha_migration.py --help

The generated mapping example is under home-assistant/generated/.

History and InfluxDB

SQLite is the local hot store. History compaction reduces older local sample density while preserving the resolutions needed by charts. Retention is configurable from the UI or environment.

Optional InfluxDB writes samples in parallel and can serve the older part of long history queries:

  • InfluxDB 1.x: URL, database, optional username/password.
  • InfluxDB 2.x: URL, organization, bucket and token.

If an Influx query fails, the API returns available SQLite data and can include a storage_warning rather than discarding the whole history response.

See GET /api/history for scopes and bucket behavior.

Notifications

Optional notifications support:

  • Pushover
  • Slack webhook
  • Discord webhook

Modes can report problems only or problems plus important state changes. Individual categories include sensor freshness/errors, communication failures, target timeout, automation/control errors and other warnings. Cooldown and failure thresholds are configurable.

Debugging

Enable Settings → Application → On-screen debug.

The overlay has three filters:

  • All — request diagnostics, application events and GREE frames,
  • Requests — HTTP method/path/status/duration,
  • GREE — sanitized protocol frames when GREE frame logging is enabled.

Binding/encryption keys are not intentionally exposed in GREE debug frames.

For Linux/network issues also use:

./scripts/network-debug.sh
./scripts/service.sh logs

Backup and restore

Settings → Application → Configuration backup exports settings, devices, zones, groups, schedules and automations.

The export intentionally does not contain metric history, event history or generated API-token records. It does contain GREE binding keys and configured integration secrets, so store it like a credential file.

Import replaces application configuration while preserving local metric/event history and generated access-token records. Runtime ownership/timers are sanitized and live device state is re-polled before automatic control resumes.

Reverse proxy and sub-path deployment

For a root deployment, proxy HTTP and WebSocket traffic to the controller normally.

For a sub-path, configure:

GREE_CONTROLLER_BASE_PATH=/gree

Then serve the application under /gree/. The proxy must preserve WebSocket upgrade headers. A typical nginx location is:

location /gree/ {
    proxy_pass http://127.0.0.1:8787/gree/;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
}

If your proxy strips the prefix, keep its upstream/base-path handling consistent. Do not publish the controller directly to an untrusted network without authentication and TLS at the proxy/VPN layer.

Security

The default empty GREE_CONTROLLER_APP_TOKEN is intended for a trusted LAN only. Set a long random token when the interface is reachable by other networks.

Implemented safeguards include:

  • optional bearer administrator authentication,
  • separate restricted generated tokens for Home Assistant,
  • hashed generated-token storage,
  • secrets omitted from normal settings responses,
  • restrictive security headers and no permissive CORS,
  • API responses marked no-store,
  • hardened systemd service,
  • safe device power-off behavior when thermostat ownership is removed,
  • startup synchronization before the thermostat engine begins issuing commands.

For remote access, prefer a VPN or authenticated TLS reverse proxy. Treat configuration exports and /etc/gree-controller.env as secrets.

Localization

Language packs are JSON files under lang/. The build validates/embeds them and generates the public language catalog.

To add a language:

  1. Copy lang/en.json to lang/<code>.json.
  2. Update meta.code, names and locale.
  3. Keep the same translation keys as the reference pack.
  4. Rebuild the Rust binary.

Runtime assets are available at /lang/index.json and /lang/<code>.json.

API

The HTTP API is the same backend used by the Web UI. It includes devices, zones, groups, house control, schedules, automations, history, control plan, events, settings, backup/restore, debug, tokens and integration tests.

Start here:

docs/API.md — complete API reference

Public health check:

curl http://127.0.0.1:8787/api/health

Authenticated example when an app token is configured:

curl -H 'Authorization: Bearer YOUR_TOKEN' \
  http://127.0.0.1:8787/api/system/info

Project layout

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
scripts/                     Development, install, update, service and diagnostics
systemd/                     Production service unit
docs/API.md                  Complete API documentation
.env.example                 Environment reference

The application is intentionally self-contained: static assets and language packs are embedded into the binary at build time; SQLite is the default data store; no external frontend build chain is required. build.rs concatenates the ordered files from web/js/ into one generated application bundle and exposes it under a content-hashed URL.

Validation before release

Recommended full check on a host with Rust installed:

./scripts/dev.sh --check

This runs formatting checks, Rust tests, a build and an isolated simulated API smoke test.

License

See LICENSE.