Lokale REST API auf S-Serie Geräten: Intro und Möglichkeiten
|
|
||
|
Einrichten der lokalen REST API Ihr stellt euch vor eure WP WP [Wärmepumpe] und klickt euch zu Menüpunkt 7.5.15
Ein Wort zum Thema (IT-)Sicherheit Die REST API ist zwar über https erreichbar und dementsprechend sicher 😉 (da ja das 's' in https für sicher steht) allerdings ist das Zertifikat der WP WP [Wärmepumpe] selbstsigniert und jeder anständig konfigurierte Browser wird meckern, sobald Ihr euch verbinden wollt. Es gibt keine Möglichkeit die Daten aus dem Zertifikat an der WP WP [Wärmepumpe] abzugleichen, d.h. falls Ihr fiese Hacker bei euch im Heimnetz habt, können die sich unbemerkt zwischen euch und die Wärmepumpe klemmen und dann mehr Brauchwasser bestellen. Ich persönlich hab bei mir die ganze Internet of Things Sauce vom Rest des Heimnetzes abgetrennt, und da hier ja nicht IT Sicherheit im Vordergrund stehen soll, mach ich mal weiter. Erster Zugriff auf die REST API Für die folgenden Beispiele hier arbeite ich mit der Variablen $IP, welche die IP Adresse eurer WP WP [Wärmepumpe] darstellen soll.
Hier ein Screenshots wie die REST API aussieht: Später schreibe ich noch ein bisschen was zur Datenauswertung und ein paar Beispiel-curl-Aufrufe, die Inspiration zur Automatisierung geben sollen. |
||
|
||
|
Zugriff via curl/Automatisierung DISCLAIMER: Ich sitz fast immer vor einem Linux, weshalb sich die Anleitung vermutlich nicht 1:1 auf Windows-User übertragen lässt Auch wenn das über den Webbrowser zum Durchschauen ganz ok ist, will man zum Monitoren der Werte und deren Speicherung kann man bspw. was curl-basiertes machen. Die API Dokumentation sagt, dass wir immer einen basicHash brauchen. Dieser ist letztlch Benutzername und Passwort in base64 kodiert. Damit man später keinen Ärger mit Passwörtern in der Bash History hat schlage ich hier folgendes vor: $ set +o history # turn of command history $ export NIBEAUTH=`echo -n myusername:mypassword | base64` $ export IP='192.168.178.123' # IP of your heatpump $ set -o history # turn it back on Anschließend könnt Ihr curlen. Folgende Header würd ich hier immer setzen:
Zudem müsst Ihr vermutlich aufgrund des selbstsignierten Zertifikats noch die -k Option nutzen, damit curl den Dienst nicht verweigert. Beispiele für Lesezugriffe $ curl -k -H "Authorization: Basic $NIBEAUTH" -H 'Content-Type: application/json' https://$IP:8443/api/v1/devices/0/points/4 {"title":"Current outdoor temperature (BT1)","description":"","metadata":{"type":"metadata","variableId":4,"variableType":"integer","variableSize":"s16","unit":"°C","modbusRegisterType":"MODBUS_INPUT_REGISTER","shortUnit":"°","isWritable":false,"divisor":10,"decimal":1,"modbusRegisterID":1,"minValue":0,"maxValue":0,"intDefaultValue":0,"change":5,"stringDefaultValue":""},"value":{"type":"datavalue","isOk":true,"variableId":4,"integerValue":9,"stringValue":""}}% $ curl -k -H "Authorization: Basic $NIBEAUTH" -H 'Content-Type: application/json' https://$IP:8443/api/v1/devices/0 {"product":{"serialNumber":"1234567890","name":"","manufacturer":"NIBE","firmwareId":"nibe-n"},"deviceIndex":0,"aidMode":"off","smartMode":"normal"} $ curl -k -H "Authorization: Basic $NIBEAUTH" -H 'Content-Type: application/json' -H 'Accept-Language: de' https://$IP:8443/api/v1/devices/0/points/4564 {"title":"Mehr Brauchwasser","description":"","metadata":{"type":"metadata","variableId":4564,"variableType":"integer","variableSize":"s8","unit":"","modbusRegisterType":"MODBUS_HOLDING_REGISTER","shortUnit":"","isWritable":true,"divisor":1,"decimal":0,"modbusRegisterID":697,"minValue":0,"maxValue":0,"intDefaultValue":0,"change":1,"stringDefaultValue":""},"value":{"type":"datavalue","isOk":true,"variableId":4564,"integerValue":0,"stringValue":""}} Beispiel für einen Schreibzugriff Hinweis: Hierzu müsst Ihr die Einstellung bzgl. REST Lesezugriff an der WP WP [Wärmepumpe] entsprechend ändern, dass ihr schreiben dürft. $ curl -k -H "Authorization: Basic $NIBEAUTH" -H 'Content-Type: application/json' https://$IP:8443/api/v1/devices/0/points -d '[{"type":"datavalue","isOk":true,"variableId":4564,"integerValue":4,"stringValue":""}]' {"4564":{"title":"More hot water","description":"","metadata":{"type":"metadata","variableId":4564,"variableType":"integer","variableSize":"s8","unit":"","modbusRegisterType":"MODBUS_HOLDING_REGISTER","shortUnit":"","isWritable":true,"divisor":1,"decimal":0,"modbusRegisterID":697,"minValue":0,"maxValue":0,"intDefaultValue":0,"change":1,"stringDefaultValue":""},"value":{"type":"datavalue","isOk":true,"variableId":4564,"integerValue":4,"stringValue":""}}} Die Infos, was hier alles in den Datenteil muss, findet Ihr in der API Doku. Letzen Endes sind die Stellschrauben variableId und integerValue, der Rest (höhö) ist immer gleich. Hinweis zum Output Im JSON Output macht die REST-API reichlich gebrauch von Soft Hyphens (SHY) [1], je nach Umgebung in der die Ausgabe gesichtet wird ergeben sich dadurch unschöne Leerzeichen. Die bekommt man aber mit sed ganz gut weg (sed 's/COPY PASTE EINES SHY//g') [1] https://en.wikipedia.org/wiki/Soft_hyphen |
||
|
||
|
Auswertung der Daten Neben den Klassikern wie regelmäßiges Pollen der Daten und Weiterleitung dieser in z.B. eine InfluxDB oder Anbindung der WP WP [Wärmepumpe] über Home Assistant via REST statt Modbus wäre natürlich auch ein teilweiser Nachbau des WP WP [Wärmepumpe] Menüs als Webapplikation vorstellbar. Da offenbar jetzt auch wirklich alle abrufbaren Daten mit einem Request abholbar sind, geht da bestimmt einiges. Zudem gibt es ja abgesehen von den getPoint/getPoints API Calls auch noch getNotifications, was sicherlich für Leute interessant ist, die Ihre WP WP [Wärmepumpe] nicht an myUplink haben, aber dennoch regelmäßig nach Alerts schauen wollen. Bei mir ist der Output dieser methode zwar bisher zum Glück immer leer, aber falls eine WP WP [Wärmepumpe] in unregelmäßigen Abständen Fehler wirft, kann man damit schauen wann die entstehen, da auch den Verlauf protokollieren und je nachdem auch gleich löschen. Ich hab bisher erstmal nur etwas mit Ruby rumgespielt um mir einen Überblick über die vorhandenen Daten zu verschaffen und deren Schlüssigkeit zu prüfen: require 'json' require 'colorize' filename = "/tmp/newpoints1" def printcurrent(point) title = point['title'].to_s md = point['metadata'] registerid = md['modbusRegisterID'] unit = md['unit'] divisor = md['divisor'] value = point['value']['integerValue'] modbusregister = md['modbusRegisterID'] puts "#{modbusregister} - #{title}: #{(value.to_f/divisor).to_s.green.bold}#{unit.green} (#{md['variableSize']})" end jsondata = JSON.parse(File.read(filename)) jsondata.each{|k,v| printcurrent v} Der Output (gekürzt auf 20 Zeilen) sieht dann in etwa so aus: Falls Bedarf ist, kann ich auch den ganzen Output mal als Anhang hochladen. |
||
|
|
Beitrag schreiben oder Werbung ausblenden?
Einloggen
Kostenlos registrieren [Mehr Infos]



