This commit is contained in:
Mateusz Gruszczyński
2026-09-18 12:26:48 +02:00
parent 8d96ad2d38
commit 00cbe975bb
21 changed files with 231 additions and 106 deletions
+8 -6
View File
@@ -1,6 +1,6 @@
# GREE Controller API reference
HTTP and WebSocket API for GREE Controller **0.15.6**.
HTTP and WebSocket API for GREE Controller **0.15.7**.
[← Main documentation](../README.md)
@@ -241,7 +241,7 @@ Response:
{
"status": "ok",
"name": "gree-controller",
"version": "0.15.6",
"version": "0.15.7",
"uptime_seconds": 1234,
"control_ready": true,
"time": "2026-08-30T06:54:00Z"
@@ -304,7 +304,7 @@ Returns the initial Web UI snapshot:
"control_plan": {"generated_at": "2026-09-04T08:00:00Z", "zones": [], "rules": []},
"control_plan_revision": 42,
"system": {
"version": "0.15.6",
"version": "0.15.7",
"uptime_seconds": 1234,
"auth_required": false,
"control_ready": true,
@@ -388,9 +388,9 @@ Scans without adding or binding anything. Request body fields are optional:
}
```
`protocol_version` accepts `0` (auto/both), `1` (AES-ECB only) or `2` (AES-GCM only). Explicit V1/V2 selection rejects replies from the other protocol generation before decryption. The UDP scan packet itself is common to both generations.
`protocol_version` accepts `0` (auto/both), `1` (AES-ECB only) or `2` (AES-GCM only). The UDP scan packet is common to both generations, and newer V2-capable modules may advertise through a legacy/plain discovery envelope. Discovery therefore decodes the reply first and uses the inner `ver` metadata as the protocol hint (`V1.*` -> V1, `V2.*` and newer -> V2). Auto keeps unresolved replies as protocol `0`; explicit V1/V2 scans return only candidates whose hint matches the selected generation.
The response contains candidates with MAC, IP, detected protocol and an `already_added` flag:
The response contains candidates with MAC, IP, protocol hint, a `protocol_locked` flag and an `already_added` flag:
```json
{
@@ -402,6 +402,7 @@ The response contains candidates with MAC, IP, detected protocol and an `already
"ip": "192.168.50.30",
"port": 7000,
"protocol_version": 1,
"protocol_locked": false,
"model": "GREE",
"firmware": "",
"already_added": false
@@ -423,6 +424,7 @@ Add only selected candidates returned by `/api/discovery/scan`:
"ip": "192.168.50.30",
"port": 7000,
"protocol_version": 1,
"protocol_locked": false,
"model": "GREE",
"firmware": "",
"already_added": false
@@ -431,7 +433,7 @@ Add only selected candidates returned by `/api/discovery/scan`:
}
```
Each selected candidate is bound strictly with its detected `protocol_version`. Existing MAC addresses are skipped.
For Auto discovery (`protocol_locked=false`), `protocol_version` is only the preferred bind order. The controller falls back to the other generation if needed and stores the protocol that actually binds successfully. Explicit V1/V2 discovery returns `protocol_locked=true` and binds strictly with the selected protocol. Existing MAC addresses are skipped.
### `GET /api/devices`
+14 -7
View File
@@ -2,7 +2,7 @@
"openapi": "3.1.0",
"info": {
"title": "GREE Controller API",
"version": "0.15.6",
"version": "0.15.7",
"summary": "Local HTTP/WebSocket API for GREE Controller",
"description": "Local API used by the GREE Controller Web UI and Home Assistant integration.",
"license": {
@@ -204,7 +204,7 @@
"Devices"
],
"summary": "Scan for local GREE devices",
"description": "Broadcasts GREE discovery and returns local device candidates without persisting or binding them. protocol_version=1 or 2 strictly accepts only that protocol; protocol_version=0 accepts both.",
"description": "Broadcasts GREE discovery and returns local device candidates without persisting or binding them. The scan envelope is not treated as the device protocol: Auto decodes replies, uses inner ver metadata as a V1/V2 hint and keeps unresolved candidates as protocol 0. Explicit protocol_version=1 or 2 returns only candidates whose resolved hint matches the selected generation.",
"operationId": "scanDiscoveredDevices",
"requestBody": {
"required": true,
@@ -262,7 +262,7 @@
"Devices"
],
"summary": "Add selected discovered devices",
"description": "Persists and binds only the local discovery candidates selected by the caller. Each selected unit is bound strictly with the protocol version detected during the scan.",
"description": "Persists and binds only the local discovery candidates selected by the caller. Auto-discovered candidates use their protocol hint as the preferred bind order, fall back to the other generation, and persist the protocol that actually succeeds. Candidates from explicit V1/V2 discovery are bound strictly.",
"operationId": "addDiscoveredDevices",
"requestBody": {
"required": true,
@@ -281,7 +281,8 @@
"protocol_version": 1,
"model": "GREE",
"firmware": "",
"already_added": false
"already_added": false,
"protocol_locked": false
}
]
}
@@ -5966,7 +5967,7 @@
},
"version": {
"type": "string",
"example": "0.15.6"
"example": "0.15.7"
},
"uptime_seconds": {
"type": "integer",
@@ -6685,7 +6686,7 @@
},
"protocol_version": {
"type": "integer",
"description": "0=auto/both, 1=AES-ECB, 2=AES-GCM",
"description": "0=auto/both with protocol hint + bind verification, 1=AES-ECB only, 2=AES-GCM only",
"minimum": 0,
"maximum": 2,
"example": 0
@@ -9663,10 +9664,16 @@
"protocol_version": {
"type": "integer",
"enum": [
0,
1,
2
],
"description": "Detected protocol generation"
"description": "Discovery protocol hint: 0=unknown/auto, 1=legacy AES-ECB, 2=AES-GCM"
},
"protocol_locked": {
"type": "boolean",
"default": false,
"description": "True when discovery explicitly selected V1 or V2; false for Auto so binding may verify/fallback"
},
"model": {
"type": "string",