Geräte mit REST API steuern

HTTP JSON lesen

Hat ein Gerät kein Binding und kann somit nicht einfach als Thing importiert werden muss man eine andere Lösung finden. Falls das Gerät eine HTTP Schnittstelle aufweist, kann man das mit einem HTTP URL Thing lösen.

Dazu unter Einstellungen-Things auf das Pluszeichen klicken und das HTTP Binding wählen. Anschliessend Name wählen, URL des Gerätes eintragen und die Refresh Time definieren.

Anschliessend braucht es Channels die man hinzufügen muss. In der Registerkarte Channels auf Add Channel kreiert genau dies.

Hier mein Beispiel welches die Wassertemperatur von meinem Warmwasserboiler liest. Wichtig ist einerseits die State URL extension, welche der IP-Adresse vom Gerät angefügt wird. Dies dient dazu, dass der HTTP-Aufruf das gewünschte Resultat zurück liefert.

Bei mir ist das also http://192.168.178.113/getval.json welches dieses Resultat liefert (vereinfacht):

{	
	"DATETIME": "Sun, 2021-11-28 12:37:07",
	"MODBUS_VAL_OPERATING_TIME": "313 days 17 hours 40 min.",
	"MODBUS_VAL_STATUS": "0",
	"MODBUS_VAL_HEATER_LOAD": "0",
	"MODBUS_VAL_TEMPERATURE_SENSOR0": "42"
}


Nun muss aus der Antwort nur noch der gewünschte Wert gelesen werden. Bei mir ist die Antwort ein JSON-String. Um einen Wert aus vielen zu extrahieren, verwendet man die State Transformation. Da wird mit JSONPATH:$.PFAD_ZUM_WERT automatisch der Wert aus dem JSON geholt.

HTTP PUT mit Wert in URL

Um einen Wert an das Gerät zurückzusenden muss man erst einmal den Read/Write Mode auf Read/Write stellen oder, falls nur schreiben erwünscht ist natürlich auf Write Only.

Je nach Gerät, das man steuern will, muss man nun die korrekte Art Informationen zu senden wählen. Wenn das zu steuernde Gerät HTTP PUT mit Wert in der URL erfordert, dann geht man so vor: In der Command URL Extension die URL definieren, nur dass man für den eigentlichen Wert einen Platzhalter einfügt.

Z.B. licht?status=%2$s

So wird dann der Wert, den man mit dem Item verbindet, in die URL übernommen. Dabei gibt es 2 verschiedene Platzhalter.

%1$Aktuelles Datum mit Zeit
%2$Der gesetzte Wert des Items. Dieser ist je nach Item-Typ anders . Details dazu findet man hier.

HTTP PUT mit JSON Payload

Es gibt jedoch Geräte, die man nicht wie oben beschrieben mit der URL steuert. Man muss den Wert im Payload senden, also im eigentlichen Body der Request. Nehmen wir also mal an ein Gerät braucht ein HTTP PUT Request mit einem JSON als Inhalt. Folgendes Beispiel würde eine Lampe einschalten:

{
  LICHT=1
}

Nun gibt es keine Transformation, die man analog wie oben mit Platzhaltern einsetzen kann. Man kann sich hier mit einem Trick behelfen indem man eine Map ablegt. Man erstellt also eine Datei im /etc/openhab/transformations Verzeichnis. Z.B. licht.map mit diesem Inhalt:

ON: { LICHT=1 }
OFF: { LICHT=0 }

Dann fügt man bei Command Transformation folgendes ein: MAP:licht.map

Rule mit HTTP PUT

Um periodisch eine HTTP PUT Request mit Payload zum Gerät zu senden, habe ich eine Rule erstellt. Mein Gerät muss diesen Befehl immer wieder erhalten, sonst wird die Steuerung wieder deaktiviert. Daher ist ein einmaliges Schreiben über den Channel nicht wirksam.

Der Soll-Wert den ich schreiben will, wird durch ein neues Item vom Typ Number dargestellt. Diesen kann ich auf einer Page mit einem Stepper oder Slider einfach verändern.

Alle 5 Sekunden, führt die Rule dieses DSL-Script aus:

var stepWrite = HeaterStepSetter.state;
var json = '{ MODBUS_CMD_SET_HEATER_STEP:'+stepWrite+' }';
HTTP.sendHttpPutRequest('http://192.168.178.113', 'application/json', json, 1000);

Der Wert wird im Script in ein JSON verpackt und anschliessend als Payload zum Gerät gesendet. So wird das Gerät entsprechend gesteuert und der gewünschte Wert verändert.