This commit is contained in:
Mateusz Gruszczyński
2026-09-16 16:56:13 +02:00
parent 143ff0d272
commit 1862fed87f
27 changed files with 1368 additions and 178 deletions
+16 -3
View File
@@ -38,7 +38,7 @@ There are three access levels.
### Public
No token is required for:
No administrator token is required for the static UI shell/assets and the generated chart share surface listed below. In Supervisor mode, `/api/health` is anonymous only to the Supervisor watchdog; a direct network request needs the application token.
```text
GET /api/health
@@ -55,11 +55,13 @@ GET /sw.js
GET /favicon.svg
GET /lang/index.json
GET /lang/{file}
GET /charts/custom/{share-token}
GET /api/public/charts/custom/{share-token}
```
### Administrator API
All normal `/api/*` routes are administrator routes. If `GREE_CONTROLLER_APP_TOKEN` is empty, the controller intentionally operates in trusted-LAN mode and these routes do not require authentication.
All normal `/api/*` routes are administrator routes. In standalone installations, an empty `GREE_CONTROLLER_APP_TOKEN` keeps trusted-LAN mode. When Home Assistant Supervisor authentication is active, direct requests to the administrator API require `GREE_CONTROLLER_APP_TOKEN`; if it is empty, direct administrator access is disabled. Requests proxied by the trusted Home Assistant ingress are accepted without the application token.
When an app token is configured, send either:
@@ -119,6 +121,9 @@ Common statuses:
| Method | Endpoint | Description |
| --- | --- | --- |
| GET | `/api/health` | Lightweight process/control-engine health. |
| POST | `/api/charts/custom/share` | Create a persisted Custom Chart share; administrator/ingress authentication required. |
| GET | `/api/public/charts/custom/{token}` | Read-only data for one generated Custom Chart share. |
| GET | `/charts/custom/{token}` | Standalone chart-only HTML view. |
| GET | `/api/bootstrap` | Complete initial application snapshot. |
| GET | `/api/system/info` | Runtime/system diagnostic information. |
| GET | `/ws` | Live WebSocket event stream. |
@@ -226,7 +231,7 @@ Common statuses:
### `GET /api/health`
Public lightweight health check.
Lightweight health check. It is public in standalone mode. When Supervisor authentication is active, a request without the application token is accepted only from the Supervisor peer so the add-on watchdog continues to work.
Response:
@@ -316,6 +321,14 @@ Returns the initial Web UI snapshot:
`settings` is a single startup snapshot composed from the same response models as the eight `/api/settings/*` GET endpoints. Secret values are never included; only `*_configured` flags are exposed for stored credentials. The split settings endpoints remain the canonical resources for independent reads and updates.
### Custom Chart share links
`POST /api/charts/custom/share` is an administrator endpoint that persists a selected Custom Chart definition and returns a random path such as `/charts/custom/chart_<token>`. Only a hash of the share token is stored. The URL does not contain device names or metric selectors.
`GET /charts/custom/:token` renders only the shared chart, without the dashboard. `GET /api/public/charts/custom/:token` returns only the series configured for that share and is intentionally unauthenticated. Possession of the unguessable share URL is the authorization for this narrow read-only endpoint.
In Home Assistant add-on ingress, the Web UI builds the copied URL against the direct add-on host and bound HTTP port (normally `8787`) instead of the `/api/hassio_ingress/...` prefix. Standalone installations use their current origin and configured base path.
### `GET /api/system/info`
Returns the `system` diagnostic object independently of the full bootstrap. Useful for monitoring and **Settings → System status**.
+174 -1
View File
@@ -104,7 +104,7 @@
"System"
],
"summary": "Health check",
"description": "Public lightweight process and control-engine health check. `control_ready=false` means the process is alive but initial physical device synchronization has not completed.",
"description": "Lightweight process and control-engine health check. In standalone mode it is public. When Home Assistant Supervisor authentication is active, anonymous health requests are accepted only from the Supervisor peer for the add-on watchdog; direct network requests require the administrator app token. `control_ready=false` means the process is alive but initial physical device synchronization has not completed.",
"operationId": "health",
"security": [],
"responses": {
@@ -5591,6 +5591,179 @@
}
}
}
},
"/api/charts/custom/share": {
"post": {
"tags": [
"History"
],
"summary": "Create Custom Chart share",
"description": "Persists a validated Custom Chart definition and returns an opaque random chart-only path. The share token is returned only in the URL; SQLite stores its SHA-256 hash.",
"operationId": "createPublicCustomChart",
"security": [
{
"BearerToken": []
},
{
"ApiTokenHeader": []
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"series"
],
"properties": {
"title": {
"type": [
"string",
"null"
],
"maxLength": 120
},
"series": {
"type": "array",
"minItems": 1,
"maxItems": 16,
"items": {
"type": "string",
"maxLength": 256
}
},
"hours": {
"type": [
"integer",
"null"
],
"minimum": 1,
"maximum": 87600,
"default": 24
},
"lang": {
"type": [
"string",
"null"
],
"enum": [
"en",
"pl",
null
]
}
}
}
}
}
},
"responses": {
"200": {
"description": "Generated chart-only share path",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"path"
],
"properties": {
"path": {
"type": "string",
"example": "/charts/custom/chart_example"
}
}
}
}
}
},
"400": {
"$ref": "#/components/responses/BadRequest"
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"500": {
"$ref": "#/components/responses/InternalError"
}
}
}
},
"/api/public/charts/custom/{token}": {
"get": {
"tags": [
"History"
],
"summary": "Read shared Custom Chart data",
"description": "Read-only public data endpoint for exactly one persisted Custom Chart share. Possession of the unguessable share URL is the authorization; arbitrary metric selectors are not accepted.",
"operationId": "publicCustomChart",
"security": [],
"parameters": [
{
"name": "token",
"in": "path",
"required": true,
"schema": {
"type": "string",
"pattern": "^chart_"
}
}
],
"responses": {
"200": {
"description": "Chart definition and selected time-series points",
"content": {
"application/json": {
"schema": {
"type": "object"
}
}
}
},
"404": {
"$ref": "#/components/responses/NotFound"
},
"500": {
"$ref": "#/components/responses/InternalError"
}
}
}
},
"/charts/custom/{token}": {
"get": {
"tags": [
"History"
],
"summary": "Open standalone shared Custom Chart",
"description": "Returns a chart-only HTML page without the application dashboard. The page loads data only through the matching opaque share token.",
"operationId": "publicCustomChartPage",
"security": [],
"parameters": [
{
"name": "token",
"in": "path",
"required": true,
"schema": {
"type": "string",
"pattern": "^chart_"
}
}
],
"responses": {
"200": {
"description": "Standalone Custom Chart HTML page",
"content": {
"text/html": {
"schema": {
"type": "string"
}
}
}
}
}
}
}
},
"components": {