« Heizung, Lüftung, Klima  |

Lokale REST API auf S-Serie Geräten: Intro und Möglichkeiten

   
Teilen: facebook    whatsapp    email
  •  bastin
18.11. - 19.11.2025
4 Antworten | 2 Autoren 4
3
7
Hi,

nachdem Nibe in den Release Notes für Firmware 4.4.7 eine lokale REST[1] API angekündigt hat und diese spätestens ab Version 4.6.4 auch tatsächlich funktioniert, habe ich mir mal angeschaut, was damit machbar ist.

Wie man das ganze an der Wärmepumpe einrichtet und wie man mit dem REST Server sprechen kann erläutere ich in den folgenden Posts.

Was kann man damit machen?
  • einen oder alle Datenpunkte der Wärmepumpe mit einer HTTP Anfrage einsammeln
  • vor allem das Feature "alle Datenpunkte" hat ggü. Modbus TCP den Vorteil, dass man nicht auf eine Maximale Abfragemenge von Registern angewiesen ist
  • zu diesen Datenpunkten bekommt man nicht nur den Wert sondern auch dessen Bedeutung und weitere Metadaten, wie physikalische Einheit oder ob der Wert schreibbar ist
  • die Rückgabewerte müssen nicht wie bei Modbus erst durch das Lesen von mehreren Registern und der Konversion der gelesen Bytes umgewandelt werden, lediglich der angegebene Divisor muss angewendet werden, und der steht in den Metadaten*
  • schreibbare Werte über HTTP Anfragen ändern

Dadurch, dass man alle Datenpunkte auf einen Schlag bekommt und zum Zugriff nur einen Webbrowser benötigt, sehe ich hier auch die Möglichkeit, relativ einfach Konfigurationen untereinander auszutauschen, so dass man bei Hilfe-Themen zu Problemen direkt einen Großteil des Ist-Zustands der Wärmepumpe anzuhängen, so dass sich Fragen wie "Was ist bei dir als Norm-Außentemperatur festgelegt?" oder "Wieviele Verdichterstarts hattest du bisher?" direkt daraus ablesen können.

Auch sonstige Konfiguration wie Start/Stop-Temperaturen für WW WW [Warmwasser] oder Heiz/Kühl-Modi kommen da einfach mit.

Hierzu ist im Gegensatz zu Modbus TCP keine zusätzliche Software nötig, das einzige was zusätzlich zum Browser noch hilfreich ist, ist ein Tool, welches die resultierenden Daten im JSON Format schön formattiert.

Schauen wir uns mal einen Datenpunkt als schön formatiertes JSON an:

{
  "title": "Current outdoor temper­ature (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": 58,
    "stringValue": ""
  }
}
Wir haben also einmal den Titel des Wertes leider eine immerzu leere Beschreibung, dann unter Metadata u.a. folgendes:
  • unit: Also die physikalische Einheit, hier Grad Celsius
  • modbusRegisterType: Was für eine Modbus Registerart diesem Wert zugrunde liegt; falls man ein Holding Register vor sich hat, ist der Wert auch isWritable, also beschreibbar
  • divisor beschreibt, wie man arithmetisch mit dem Wert umgehen muss, also z.B. ist hier der später folgene integerValue durch 10 zu teilen
  • min und maxValues, die insbesondere dann spannend sind, wenn man selber Werte via REST ändern will
  • modbusRegisterID gibt an, aus welchem Modbus-Register man diesen Wert bekommen kann

Unter Value bekommen wir dann das eigentlich interessante zu sehen, nämlich die Messwerte in Form von integerValue. Im Beispiel hier haben wir es also mit der Außentemperatur in Höhe von 5.8 (58:10) Grad Celsius zu tun.

Durch die vielen Modbus-Referenzen im REST JSON Output halte ich es für möglich, dass der REST Server auf der WP WP [Wärmepumpe] seine Antworten via lokalem Modbus abholt, was unter dem Gesichtspunkt schlecht ist, dass der REST Server vom Modbus-Dienst abhängt. Allerdings lassen sich die ganzen Daten via REST imho einfacher einsammeln und auswerten.

Dazu später mehr.

* Für einige Werte bekomme ich -32768 zurück, was der kleinste s16 Wert ist, soweit ich sehen konnte taucht der aber nur bei "Features" auf, die meine WP WP [Wärmepumpe] gar nicht hat.

[1] https://en.wikipedia.org/wiki/REST

  •  bastin
18.11.2025 18:35  (#1)
Einrichten der lokalen REST API

Ihr stellt euch vor eure WP WP [Wärmepumpe] und klickt euch zu Menüpunkt 7.5.15

  • Schieberegler oben auf An stellen
  • Benutzername: den braucht Ihr dann für die Anmeldung am REST-Server
  • Passwort: siehe Benutzername
  • IP-Adressenbeschränkung: Vielleicht dem ein oder andern schon von den Modbus TCP Settings bekannt, es kann durchaus sinnvoll sein hier den Zugriff auf die IP einzuschränken, von der Ihr dann auch auf REST zugreift
  • Vertrauensw. IP: Die IP Adresse des Gerätes, von dem Ihr auf die REST API zugreifen wollt, falls ihr die Adressenbeschränkung aktiviert habt
  • Nur Lesen von REST API: Sollte man für initiale Tests erstmal anschalten, falls man später bestimmte Werte auch schreiben will muss man den Teil deaktivieren

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.


_aktuell/20251118101601.png


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.

  • Ihr öffnet einen Browser und geht auf https://$IP:8443/ lest euch aufmerksam die Zertifikatswarnung durch und sucht dann den "Ich will trotzdem weiter machen" Knopf und klickt den. 
  • Dann gebt Ihr Benutzername und Passwort wie an der WP WP [Wärmepumpe] hinterlegt ein und werdet von der Hilfeseite begrüßt
  • Um zu sehen wieviele Geräte ihr habt, geht ihr auf https://$IP:8443/api/v1/devices/
  • Falls Ihr wie ich nur eine WP WP [Wärmepumpe] habt, gerne auch gleich auf https://$IP:8443/api/v1/devices/0
  • Dann könnt ihr schauen wie warm es bei euch am Außenfühler ist: https://$IP:8443/api/v1/devices/0/points/4
  • Und um einmal alle Daten zu holen geht ihr auf https://$IP:8443/api/v1/devices/0/points


Hier ein Screenshots wie die REST API aussieht:


_aktuell/20251118873447.png

Später schreibe ich noch ein bisschen was zur Datenauswertung und ein paar Beispiel-curl-Aufrufe, die Inspiration zur Automatisierung geben sollen. 

1
  •  bastin
18.11.2025 19:08  (#2)
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:
  • Authorization: Basic $NIBEAUTH
  • Content-Type: application/json
Falls euch die Sprache der REST Antworten nicht passt, könnt Ihr das über den
  • Accept-Language
Header steuern und den bspw. auf de oder en 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 temper­ature (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 Brauch­wasser","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

1
  •  bastin
18.11.2025 20:05  (#3)
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:


_aktuell/20251118465841.png

Falls Bedarf ist, kann ich auch den ganzen Output mal als Anhang hochladen.

1


  •  querty
  •   Gold-Award
19.11.2025 9:30  (#4)
Sehr interessant und wäre sicher cool, paar Daten der WP WP [Wärmepumpe] auf meinem Smart Mirror anzuzeigen...leider hab ich "nur" eine F1155-12 EM 😢

1


Beitrag schreiben oder Werbung ausblenden?
Einloggen

 Kostenlos registrieren [Mehr Infos]