Status und Requests¶
Diese Seite beschreibt, wie die App Requests aufbaut, ausführt und Antworten verarbeitet.
WidgetStatusConfig¶
| Feld | Typ | Default | Bedeutung |
|---|---|---|---|
request |
EndpointRequestConfig? |
null |
direkter Status-Request |
sharedRequestId |
String? |
null |
Referenz auf globalen Sammelrequest |
responseKind |
ResponseKind |
auto |
erwartete Antwortart |
Wichtige Regel:
- genau eines von
requestodersharedRequestIdmuss gesetzt sein - wenn ein Widget gar keinen Status braucht, darf
statusnur beimode = "icon_text"odermode = "shutter"komplett fehlen
EndpointRequestConfig¶
| Feld | Typ | Default | Bedeutung |
|---|---|---|---|
url |
String |
kein Default | Zieladresse |
method |
EndpointRequestMethod? |
null |
optionale HTTP-Methode |
headers |
Map<String, String> |
{} |
Request-Header |
jsonBody |
JsonElement? |
null |
optionaler JSON-Body |
timeoutMs |
Long? |
null |
überschreibt globales Timeout |
Request-Aufbau¶
Zur Laufzeit erzeugt das Repository aus RequestDefaultsConfig und EndpointRequestConfig einen ResolvedRequest.
Merge-Regeln:
- URL kommt immer aus dem konkreten Request
- Header werden aus Defaults und Request zusammengeführt
- widget-spezifische Header überschreiben Default-Header mit gleichem Key
timeoutMsdes Requests überschreibt das Default-Timeout- wenn kein
Acceptgesetzt ist, setzt die Appapplication/json, image/png, image/jpeg
HTTP-Methode¶
Unterstützte Werte für method:
getpostputpatchdelete
Wenn method nicht gesetzt ist, verwendet die App automatisch:
GET, wennjsonBody = nullPOST, wennjsonBodygesetzt ist
Wichtige Regel:
GETwird ohne JSON-Body ausgeführt- für Requests mit
jsonBodysolltest duPOST,PUT,PATCHoderDELETEverwenden
ResponseKind¶
| Wert | Bedeutung |
|---|---|
auto |
Antwort wird automatisch erkannt |
json |
es wird JSON erwartet |
text |
es wird ein einzelner Text-, Zahl- oder Boolean-Wert erwartet |
jpg |
es wird ein JPG/JPEG erwartet |
png |
es wird ein PNG erwartet |
Automatische Erkennung:
image/pngimContent-Typereicht ausimage/jpegoderimage/jpgimContent-Typereichen ebenfalls aus- alternativ prüft die App auch die PNG-Signatur der ersten Bytes
- für JPG prüft die App zusätzlich die JPEG-Signatur
- alles andere wird als JSON oder roher Text interpretiert
Hinweis zu text:
- sinnvoll für Endpoints, die nur
on,off,23.5odertrueliefern - der Wert steht als primitiver Root-Wert zur Verfügung
- für
title.valueodervalue.valuekannst du deshalb beimode = "path"den Pfad$verwenden
Beispiel für einen Text-Endpoint:
{
"content": {
"mode": "icon_text",
"title": {
"mode": "static",
"value": "API-Status"
},
"value": {
"mode": "path",
"value": "$",
"fallback": "unbekannt"
}
},
"status": {
"request": {
"url": "https://example.org/api/healthz"
},
"responseKind": "text"
}
}
Ergebnisobjekt EndpointExecutionResult¶
Zur Laufzeit liefert das Netzwerkmodul:
| Feld | Typ | Bedeutung |
|---|---|---|
statusCode |
Int |
HTTP-Statuscode |
contentType |
String? |
Server-Content-Type |
jsonPayload |
JsonElement? |
JSON- oder Textnutzlast |
imageBytes |
ByteArray? |
Bilddaten, z. B. PNG oder JPG |
Shared-Status-Requests¶
defaults.sharedStatusRequests erlaubt es, mehrere Widgets an dieselbe Statusantwort zu hängen.
Beispiel:
{
"defaults": {
"sharedStatusRequests": [
{
"id": "living-room-light-state",
"request": {
"url": "http://192.168.1.20/api/lights/living-room"
}
}
]
},
"widgets": [
{
"id": "light",
"status": {
"sharedRequestId": "living-room-light-state"
}
},
{
"id": "dimmer",
"status": {
"sharedRequestId": "living-room-light-state"
}
}
]
}
Laufzeitverhalten:
- pro Refresh werden nur benötigte Shared-Requests ausgeführt
- jeder benötigte Shared-Request läuft exakt einmal
- alle Widgets lesen danach unterschiedliche Werte aus derselben JSON-Antwort
Fehlerverhalten¶
Wenn ein Widget nicht aktualisiert werden kann:
- das Widget bleibt sichtbar
hasError = true- die Karte wird visuell ausgegraut
- der bisherige Snapshot bleibt erhalten
URL-Regeln¶
Zulässig:
https://example.org/api/statehttp://192.168.1.20/api/state
Nicht zulässig:
http://example.org/api/statehttp://10.0.0.5/api/statehttp://localhost/api/stateftp://...
Die Logik sitzt in UrlPolicy.isAllowed(...).
Beispiel für einen Request mit Headern und Body¶
{
"request": {
"url": "https://example.org/api/energy/current",
"method": "post",
"headers": {
"X-Api-Key": "demo"
},
"jsonBody": {
"scope": "today"
},
"timeoutMs": 8000
}
}
Empfehlung für Response-Design¶
Wenn du die API selbst kontrollierst, sind diese Muster besonders gut nutzbar:
- flache JSONs für kleine Widgets
- konsistente Namensgebung für gemeinsam genutzte Statuspayloads
- Arrays aus Objekten für Select-Optionen
- separate PNG-Endpunkte für Kamerabilder