DDF-Handbuch / Teil A – Protokoll-DDF

REST-API

Konzept

Der REST-Treiber ist ein HTTP(S)-Client mit JSON-, XML/SOAP-, Text- und JPEG-Unterstützung. Zusätzlich kann er als Listener (HTTP-Server für Push-Ereignisse) und als SSE-Client (Server-Sent Events) arbeiten. PROTOCOL beginnt mit REST (z. B. REST-API (DDF)).

Jede Funktion ist ein Request: Methode + URL + Argumente. Die Antwort wird anhand ihres Content-Type geparst und ist in der Formel über Pfadzugriffe lesbar.

Parameter (*GENERAL)

Key Beschreibung
CONNECTION meist DOMAIN
DOMAIN Basis-URL, z. B. http://<DEVICE_IP> oder https://api.example.com. Bei Multi-Instanzen als Liste bzw. Bereich.
AUTHENTIFICATION NONE, PASSWORD, TOKEN, OAUTH_DEVICE_FLOW, OAUTH_GRANT_FLOW, BASIC_AUTH
USER / PASSWORD für BASIC_AUTH (HTTP Basic) bzw. PASSWORD. Werte setzt der Benutzer.
LISTENER_PORT Port für METHOD=LISTEN
SOAPACTION, SOAPNS für DATATYPE=SOAP
JPEGFILE Ablage für JPEG-Antworten
TIMEOUT Hinweis: Der Client verwendet intern Timeouts von 4 s.

TLS

Die Zertifikatsprüfung ist im Client abgeschaltet. HTTPS verschlüsselt also, authentifiziert den Server aber nicht.

Spalten der Funktionen

Spalte Beschreibung
ALIAS Name
METHOD GET, POST, PUT, PATCH, DELETE, URL (nur URL bauen), SSE (Event-Stream), GETSTREAM, LISTEN (Listener)
URL Pfad relativ zu DOMAIN (oder eine absolute URL)
DATATYPE JSON, TEXT, XML, SOAP, X-WWW-FORM-URLENCODED (bestimmt Body-Format und Content-Type)
POLLING ms
FORMULA Auswertung der Antwort

Argumente

;*ARGS;METHOD;ALIAS;TYPE;NAME;VALUE;ITEM;FORMAT;
;ARGS;<FunktionsALIAS>;;<TYPE>;<NAME>;<VALUE>;<ITEM>;<FORMAT>;

Die Spalte direkt nach ARGS ist der Funktions-Alias (im Kopf METHOD). Die Spalte ALIAS bleibt in den Originaldateien leer.

Spalte Beschreibung
METHOD (Spalte nach ARGS) Funktions-Alias oder *ALL
ALIAS leer (Bedeutung zu klären)
TYPE url = Pfadteil anhängen · arg = Query-Parameter (?/&, URL-kodiert) · header = HTTP-Header · data = Body-Feld
NAME Name des Parameters/Headers/JSON-Schlüssels
VALUE fester Wert
ITEM Quelle des Werts: Variablen-/Itemname, oder $KEY für params[KEY] (z. B. $TOKEN)
FORMAT Formatierung (siehe unten)

Zur Laufzeit lassen sich Argumente per <ALIAS>.ARG.<name> := wert; setzen.

FORMAT-Werte

FORMAT Wirkung
(leer) / STRING als String
DEZIMAL Ganzzahl
FLOAT Gleitkomma
ISO8601 Zeitstempel → ISO-8601
DAY Datum
T_YYYYMMDDHHMM Zeitformat YYYYMMDDHHMM
ENUM:0=a,1=b Zahl → Text
BLOCK, BLOCK_START, BLOCK_END verschachtelte JSON-Objekte öffnen/schließen
ARRAY_START, ARRAY_END JSON-Array öffnen/schließen
%s, %lld, %g … printf-Format

Ein JSON-Body wird automatisch in { … } eingeschlossen. Bei SOAP erzeugt der Treiber den Envelope mit SOAPNS/SOAPACTION.

Zugriff auf die Antwort

Ausdruck Bedeutung
<A>.HTTP_CODE HTTP-Statuscode
<A>.HTTP_DATA Rohantwort (String)
<A>.HTTP_DATA_TYPE erkannter Content-Type
<A>.VALUE.<pfad> Wert an JSON/XML-Pfad, z. B. R.VALUE.data.power, Arrays mit name[n]
<A>.EXIST.<pfad> 1, wenn der Pfad existiert
<A>.FIND.<str>.<pfad> Suche nach str
<A>.FINDVALUE.<key>.<str>.<pfad> Element finden, dessen key = str ist, und pfad darin lesen
<A>.ASLIST.<arr[-1]…> Array als Liste
<A>.ARRAY.MEDIA|MIN|MAX|LEN.<pfad> Mittelwert, Minimum, Maximum, Länge eines Zahlenarrays
<A>.ARG.<name> Argumentwert
.Q, .F, .URL, … allgemeine Suffixe

Ergänzend gibt es die Formelfunktionen JSONGETVALUE(json,pfad) und JSONGETVALUEFROMARRAY(…) (siehe Formelreferenz).

Listener (Push)

SSE

METHOD=SSE öffnet einen Event-Stream. Jedes Ereignis wird in JSON gewandelt ({"event":…}) und steht der Formel wie eine normale Antwort zur Verfügung.

Schritt für Schritt

  1. Die API-Doku auswerten: Basis-URL, Authentifizierung, Endpunkte, Antwortformat.
  2. *GENERAL: PROTOCOL;REST-API (DDF), CONNECTION;DOMAIN, DOMAIN als Vorgabe (oder leer lassen, dann setzt sie der Benutzer), AUTHENTIFICATION.
  3. Je Endpunkt eine *READ-Funktion (GET, POLLING).
  4. Header und Query als ARGS. Geheimnisse nie fest eintragen, sondern über ITEM=$KEY aus den Parametern nehmen.
  5. In der Formel IF R.Q && R.HTTP_CODE == 200 THEN … ENDIF; prüfen und R.VALUE.<pfad> auslesen.
  6. Schreibende Endpunkte als *WRITE mit POLLING 0 anlegen. Das Item setzt in der WFORMULA <A>.ARG.<name> und <A>.F:=1;.

Realer Auszug: Shelly DUO RGBW Bulb

Datei Shelly.Lamp.REST-API (DDF).DUO RGBW Bulb.1(0x0D00002D00010100).csv (gekürzt, Geräte-IP geschwärzt):

*GENERAL;
;DEVICE;DUO RGBW Bulb;
;MANUFACTURER;Shelly;
;TYPE;Lamp;
;PROTOCOL;REST-API (DDF);
;MODEL_NR;1;
;VERSION_NR;1;
;ID;0x0D00002D00010100;
*GENERAL;
;CONNECTION;DOMAIN;
;AUTHENTIFICATION;NONE;
;DOMAIN;http://<DEVICE_IP>;
;SLAVESMAX;20;
*READ;ALIAS;METHOD;URL;DATATYPE;FORMULA;POLLING;
;STATE;GET;;JSON;"""IF STATE.HTTP_CODE == 200 THEN
X.100 := STATE.VALUE.ison;
X.101 := STATE.VALUE.mode;
X.102 := STATE.VALUE.brightness * 32767 / 100;
X.103 := STATE.VALUE.red * 32767 / 255;
X.108 := (STATE.VALUE.temp - 3000) * 4681 / 495;
X.200 := 1;
ELSE
X.200 := 0;
ENDIF;
STATE.F := 0;""";5000;
;*ARGS;METHOD;ALIAS;TYPE;NAME;VALUE;ITEM;FORMAT;
;ARGS;STATE;;url;/light/0;
*WRITE;ALIAS;METHOD;URL;DATATYPE;FORMULA;
;TURN;GET;;JSON;"""IF TURN.HTTP_CODE == 200 THEN
X.200 := 1;
ELSE
X.200 := 0;
ENDIF;
TURN.F := 0;""";
;*ARGS;METHOD;ALIAS;TYPE;NAME;VALUE;ITEM;FORMAT;
;ARGS;TURN;;url;/light/0;
;ARGS;TURN;;arg;turn;;turn_val;STRING;
;ARGS;TURN;;arg;transition;;X.7;DEZIMAL;
;RGB;GET;;JSON;"""IF RGB.HTTP_CODE == 200 THEN
X.200 := 1;
ELSE
X.200 := 0;
ENDIF;
RGB.F := 0;""";
;*ARGS;METHOD;ALIAS;TYPE;NAME;VALUE;ITEM;FORMAT;
;ARGS;RGB;;url;/light/0;
;ARGS;RGB;;arg;red;;red_val;DEZIMAL;
;ARGS;RGB;;arg;gain;100;;DEZIMAL;
;ARGS;RGB;;arg;mode;color;;STRING;
*GROUP;ID;ALIAS;NAME;
;0;BULB;BULB;
*ITEM;GROUP;ALIAS;NAME;ID;VISIBILITY;UNIT;TYPE;DEFAULT;WFORMULA;RFORMULA;POLLING;
;0;TURN_SET;Turn SET;0;;0=Off, 1=On;;;"""IF X.0 THEN
 turn_val := 'on';
ELSE
 turn_val := 'off';
ENDIF;
TURN.F := 1;""";
;0;RED_SET;Red SET;3;;%;;;"""red_val :=X.3 *255 / 32767; RGB.F:=1;""";
;0;TRANSITION_SET;Transition SET;7;;[0,5000] ms;
;0;ISON_FB;Ison FB;100;;0=Off, 1=On;
;0;NEXT_REQUEST;Next Request;199;;s;;;;"""IF STATE.HTTP_CODE == 200 THEN
 X.199 := 5 - ($.SYS.TIME - STATE.T);
ENDIF;""";250;
;0;QUALITY;Quality;200;;0=Error, 1=Ok;

Was der Auszug zeigt:

Fallstricke

Checkliste