265 lines
13 KiB
Markdown
265 lines
13 KiB
Markdown
# API examples
|
|
|
|
`TOKEN` is optional when `GREE_CONTROLLER_APP_TOKEN` is empty.
|
|
|
|
```bash
|
|
AUTH='Authorization: Bearer TOKEN'
|
|
BASE='http://127.0.0.1:8787'
|
|
```
|
|
|
|
|
|
## Home Assistant access tokens
|
|
|
|
Create and revoke integration tokens from the controller Web UI under **More -> Home Assistant / Sensors**. The clear-text secret is returned only once and the SQLite database stores only its SHA-256 hash.
|
|
|
|
Administrator endpoints:
|
|
|
|
```text
|
|
GET /api/access-tokens
|
|
POST /api/access-tokens
|
|
DELETE /api/access-tokens/{id}
|
|
```
|
|
|
|
The Home Assistant custom integration uses a restricted API surface:
|
|
|
|
```text
|
|
GET /api/integrations/home-assistant/devices
|
|
POST /api/integrations/home-assistant/devices/{id}/command
|
|
GET /api/integrations/home-assistant/control-plan
|
|
POST /api/integrations/home-assistant/house/control
|
|
POST /api/integrations/home-assistant/house/preset
|
|
POST /api/integrations/home-assistant/house/power
|
|
POST /api/integrations/home-assistant/zones/{id}/control
|
|
```
|
|
|
|
These endpoints always require `Authorization: Bearer <generated-token>` (or the administrator `GREE_CONTROLLER_APP_TOKEN`). A generated HA token cannot update settings, run discovery, delete devices, manage tokens, or use the controller WebSocket.
|
|
|
|
## Discovery
|
|
|
|
```bash
|
|
curl -X POST "$BASE/api/discovery" -H "$AUTH" -H 'Content-Type: application/json' \
|
|
-d '{"timeout_ms":6000,"broadcast":"255.255.255.255:7000","protocol_version":0,"passes":3}'
|
|
```
|
|
|
|
`protocol_version` is `0` for auto/both, `1` for AES-ECB only, and `2` for AES-GCM only. `passes` is `1..10`. Auto is recommended when different GREE Wi-Fi module generations share the network.
|
|
|
|
## Device command
|
|
|
|
```json
|
|
{
|
|
"power": true,
|
|
"mode": "cool",
|
|
"target_temperature": 22.0,
|
|
"fan_speed": 3,
|
|
"swing_vertical": true,
|
|
"quiet": false,
|
|
"turbo": false,
|
|
"light": true,
|
|
"xfan": false,
|
|
"air": false,
|
|
"health": false,
|
|
"sleep": false
|
|
}
|
|
```
|
|
|
|
Supported modes: `auto`, `cool`, `dry`, `fan`, `heat`. Fan speed: `0..5`. Optional properties map to GREE `Blo` (X-FAN), `Air`, `Health` and `SwhSlp` (Sleep) and should only be used when the device reports the matching `supports_*` capability. Physical GREE Celsius setpoints are normalized to whole degrees in the `8..30°C` range.
|
|
|
|
## Smart thermostat / house control
|
|
|
|
The controller separates the seasonal house mode from per-zone profiles. Normal operation uses setpoint modulation: units remain powered while the controller moves the device target between an active and satisfied setpoint. House mode `off` means **do not control** inherited zones: it does not power a manually operated unit down. A zone explicitly switched to `cool` or `heat` remains independent and can continue to run.
|
|
|
|
```bash
|
|
curl -X POST "$BASE/api/house/control" -H "$AUTH" -H 'Content-Type: application/json' \
|
|
-d '{"mode":"cool"}'
|
|
|
|
curl -X POST "$BASE/api/house/power" -H "$AUTH" -H 'Content-Type: application/json' \
|
|
-d '{"power":false}'
|
|
|
|
curl -X POST "$BASE/api/house/preset" -H "$AUTH" -H 'Content-Type: application/json' \
|
|
-d '{"preset":"sleep"}'
|
|
```
|
|
|
|
House modes: `cool`, `heat`, `off` (`off` = no house-level thermostat control). House presets: `auto`, `comfort`, `sleep`, `away`. A non-`auto` house preset creates temporary per-zone overrides that expire at each zone's next schedule boundary. `POST /api/house/power` controls a separate whole-house master power state. With master power off, zones and controller automations cannot restart units; the selected house thermostat mode is preserved. This is independent from house mode `off`, which only means no house-level thermostat control and allows direct/manual device operation. Choosing whole-house `cool`/`heat` or any whole-house preset is treated as an explicit whole-house activation: master power is set back to on and all enabled units are powered on. Choosing house mode `off` does not change master power.
|
|
|
|
A zone stores separate profile temperatures for both seasons:
|
|
|
|
```json
|
|
{
|
|
"name": "Paweł",
|
|
"device_id": "gree-aabbccddeeff",
|
|
"enabled": true,
|
|
"mode": "cool",
|
|
"inherit_house_mode": true,
|
|
"setpoint": 23.0,
|
|
"cool_comfort_setpoint": 23.0,
|
|
"cool_sleep_setpoint": 24.5,
|
|
"cool_away_setpoint": 27.0,
|
|
"heat_comfort_setpoint": 21.0,
|
|
"heat_sleep_setpoint": 19.0,
|
|
"heat_away_setpoint": 17.0,
|
|
"hysteresis": 0.6,
|
|
"min_adjust_seconds": 120,
|
|
"standby_offset_c": 2.0,
|
|
"smart_fan": true,
|
|
"sensor_source": "combined",
|
|
"ha_entity_id": "sensor.pawel_temperature",
|
|
"external_sensor_weight": 0.4,
|
|
"max_sensor_difference": 3.0
|
|
}
|
|
```
|
|
|
|
Quick control does not directly fight the schedule engine:
|
|
|
|
```bash
|
|
# Sleep now until the next schedule boundary
|
|
curl -X POST "$BASE/api/zones/ZONE_ID/control" -H "$AUTH" -H 'Content-Type: application/json' \
|
|
-d '{"preset":"sleep"}'
|
|
|
|
# Return to automatic schedule
|
|
curl -X POST "$BASE/api/zones/ZONE_ID/control" -H "$AUTH" -H 'Content-Type: application/json' \
|
|
-d '{"preset":"auto"}'
|
|
|
|
# Temporary custom room target
|
|
curl -X POST "$BASE/api/zones/ZONE_ID/control" -H "$AUTH" -H 'Content-Type: application/json' \
|
|
-d '{"setpoint":22.5}'
|
|
```
|
|
|
|
`mode` on the quick zone endpoint accepts `house`, `cool`, or `heat`. Global `off` always wins over local zone mode overrides.
|
|
|
|
### Climate groups
|
|
|
|
Groups persist a set of thermostat zone IDs and an independent group power gate. Group control reuses the normal zone engine, so profiles, schedules, hysteresis and sensor selection remain unchanged.
|
|
|
|
```bash
|
|
curl -X POST "$BASE/api/groups" -H "$AUTH" -H 'Content-Type: application/json' \
|
|
-d '{"name":"Upstairs","zone_ids":["ZONE_A","ZONE_B"]}'
|
|
|
|
curl -X POST "$BASE/api/groups/GROUP_ID/control" -H "$AUTH" -H 'Content-Type: application/json' \
|
|
-d '{"mode":"cool","preset":"sleep","power":true}'
|
|
```
|
|
|
|
Group `mode` accepts `house`/`auto` (follow whole-house Heating/Cooling), `cool`, or `heat`. Group `preset` accepts `auto`, `comfort`, `sleep`, or `away`. Automations may set `action_group_id` and optional `action_preset`; direct-device `action_device_id` remains backward compatible.
|
|
|
|
### Ready-made schedule templates
|
|
|
|
Templates generate normal schedule records and replace the current schedules for the selected zone. Every generated entry remains editable.
|
|
|
|
```bash
|
|
curl -X POST "$BASE/api/zones/ZONE_ID/schedule-template" -H "$AUTH" -H 'Content-Type: application/json' \
|
|
-d '{"template":"child"}'
|
|
```
|
|
|
|
Templates: `family`, `child`, `bedroom`, `workday`, `always`.
|
|
|
|
Schedules use a profile (`comfort`, `sleep`, `away`) or a custom temperature:
|
|
|
|
```json
|
|
{
|
|
"zone_id": "UUID",
|
|
"name": "Sleep",
|
|
"enabled": true,
|
|
"weekdays": [1,2,3,4,5,6,7],
|
|
"start_time": "20:30",
|
|
"end_time": "06:30",
|
|
"preset": "sleep",
|
|
"setpoint": 24.0
|
|
}
|
|
```
|
|
|
|
For non-`custom` schedules, `setpoint` is only a compatibility value; the actual target comes from the zone's seasonal profile.
|
|
|
|
### Home Assistant outdoor assist and local HTTPS
|
|
|
|
Runtime settings can specify `home_assistant.outdoor_entity_id` and `outdoor_assist_enabled`. Outdoor temperature never replaces the zone room temperature. It is only used to make active setpoints/fan speed slightly more assertive in extreme weather.
|
|
|
|
For trusted local Home Assistant servers with self-signed/invalid HTTPS certificates, set:
|
|
|
|
```json
|
|
{
|
|
"home_assistant": {
|
|
"url": "https://10.87.65.2",
|
|
"allow_invalid_tls": true
|
|
}
|
|
}
|
|
```
|
|
|
|
This setting is opt-in and applies only to the controller's outbound Home Assistant sensor client.
|
|
|
|
## Current control plan
|
|
|
|
`GET /api/control-plan` returns a machine-readable view of what the controller is doing now and what is expected next. It includes the house mode, uniform house preset (or `null` for mixed zone profiles), whole-house master-power state, strategy, each zone's effective `mode`, `configured_mode`, `inherit_house_mode`, preset/current and target temperatures, current schedule, manual override expiry, upcoming schedule transitions, enabled automation rules and predictable time-triggered automation events.
|
|
|
|
```bash
|
|
curl "$BASE/api/control-plan" -H "$AUTH"
|
|
```
|
|
|
|
The restricted Home Assistant equivalent is `GET /api/integrations/home-assistant/control-plan`. HA may also change house mode, house preset and whole-house master power through the dedicated `/api/integrations/home-assistant/house/*` endpoints. HA may change a zone target/preset/mode/enabled state through:
|
|
|
|
```bash
|
|
curl -X POST "$BASE/api/integrations/home-assistant/zones/ZONE_ID/control" \
|
|
-H 'Authorization: Bearer HA_TOKEN' -H 'Content-Type: application/json' \
|
|
-d '{"setpoint":22.5}'
|
|
```
|
|
|
|
## Settings backup and debug
|
|
|
|
`GET /api/settings/export` downloads configuration JSON (settings, devices, zones, groups, schedules and automations). It intentionally excludes metric history, event logs and generated API-token records. The export includes GREE device binding keys plus configured Home Assistant and InfluxDB credentials, so treat it as a secret.
|
|
|
|
`POST /api/settings/import` accepts that JSON format and replaces application configuration while preserving metric history, events and generated API tokens.
|
|
|
|
Debug overlay state can be read or changed independently of the full settings document:
|
|
|
|
```text
|
|
GET /api/debug
|
|
PUT /api/debug
|
|
```
|
|
|
|
Example body: `{"overlay_enabled":true,"gree_frames":true}`. With the overlay enabled, live `api.request` WebSocket events contain only HTTP method, path, status and duration. When GREE frame debug is enabled, sanitized `gree.frame` events are also emitted; the bound encryption key is not exposed.
|
|
|
|
## WebSocket
|
|
|
|
Connect to `ws://HOST:8787/ws?token=TOKEN`. The first message uses event type `bootstrap`; later events include `device.updated`, `zone.updated`, `settings.updated`, `debug.settings`, `api.request`, `gree.frame` and `log.created`.
|
|
|
|
## Localization assets
|
|
|
|
Localization endpoints are public because the login dialog also needs translations. Language packs are embedded in the Rust binary at build time.
|
|
|
|
```bash
|
|
curl "$BASE/lang/index.json"
|
|
curl "$BASE/lang/en.json"
|
|
```
|
|
|
|
`GET /lang/index.json` returns the automatically generated language catalog. `GET /lang/<code>.json` returns the corresponding language pack. Add a valid `lang/<code>.json` file and rebuild to expose a new language.
|
|
|
|
### `GET /api/history`
|
|
|
|
The history API exposes three independent data families and a combined overview. `hours` may cover up to 10 years and `limit` is capped at 20,000 rows. Query buckets become progressively wider: 30 s (<=6 h), 2 min (<=24 h), 10 min (<=7 d), 30 min (<=30 d), 2 h (<=90 d), 6 h (<=1 y), then 24 h.
|
|
|
|
```text
|
|
GET /api/history?scope=overview&hours=24
|
|
GET /api/history?scope=devices&device_id=DEVICE_ID&hours=2160
|
|
GET /api/history?scope=zones&zone_id=ZONE_ID&hours=8760
|
|
GET /api/history?scope=sensors&entity_id=sensor.room_temperature&hours=24
|
|
```
|
|
|
|
Local SQLite is the hot store. When compaction is enabled, full-resolution samples are kept for 24 h, then one sample per 10-minute bucket through day 7 and one per 30-minute bucket afterwards. `history_retention_days` controls final local pruning.
|
|
|
|
When InfluxDB is enabled, samples are written in parallel. Maintenance also backfills compacted legacy SQLite samples older than `influxdb.history_threshold_days`; those local rows are deleted only after the archive batch is accepted. Requests that cross the threshold read the older portion from InfluxDB 1.x or 2.x and merge it with recent SQLite data. If the Influx query fails, the endpoint falls back to the available SQLite history and returns `storage_warning`.
|
|
|
|
`scope=overview` returns `zones`, `devices`, `sensors`, row `counts`, `bucket_seconds`, plus `storage`/optional `storage_warning`. Device rows contain indoor/outdoor/target/power; zone rows contain GREE/external/control/target/device-setpoint/outdoor/power/mode/fan/demand/source/preset; HA rows contain entity, optional zone, kind and temperature.
|
|
|
|
## InfluxDB long-term storage
|
|
|
|
Runtime settings support either InfluxDB 1.x (`version=1`, URL, database and optional username/password) or InfluxDB 2.x (`version=2`, URL, org, bucket and token). The same values can be supplied with `GREE_CONTROLLER_INFLUX_*` environment variables; see `.env.example`. An explicitly configured environment value overrides the persisted setting at startup.
|
|
|
|
|
|
## Event log retention
|
|
|
|
`GET /api/events/retention` returns the current event/debug log retention window. `PUT /api/events/retention` accepts `{"days":30}` (1-3650), persists it and immediately prunes older event rows. The same value is part of runtime settings as `event_log_retention_days` and can be set at startup with `GREE_CONTROLLER_EVENT_LOG_RETENTION_DAYS`.
|
|
|
|
## Night mode and sensor aliases
|
|
|
|
Runtime settings include `night_mode` with `enabled`, `start_time`, `end_time`, `max_fan_speed` (1-5), `force_quiet` and `use_native_sleep`. Overnight windows crossing midnight are supported. During the window thermostat-generated fan commands are limited to the configured maximum; Auto is converted to a bounded low speed, while `Quiet` and native `Sleep` are requested only when the unit supports them.
|
|
|
|
`home_assistant.sensor_aliases` is a map of Home Assistant `entity_id` to a friendly UI name, for example `{"sensor.gabinet_temperature":"Gabinet"}`. Aliases affect labels in the controller UI/history only. The backend canonicalizes aliases back to their original keys before Home Assistant requests and metric storage; an alias accidentally saved in a sensor field is also resolved defensively.
|