ioBroker beschreibt sich als „Integrationsplattform für das Internet der Dinge“ und ist eine Software, die Heimautomatisierung deutlich vereinfacht. Da ich zusätzlich das Volkszähler-Projekt zur Stromerfassung benutze, kam recht schnell die Idee auf, die beiden Dienste direkt miteinander zu verknüpfen. Deshalb habe ich ein einfaches Skript für den ioBroker geschrieben, welches ich im Folgenden erkläre.
Das vollständige Skript befindet sich am Ende der Seite!
Idee
Der Volkszähler bietet über die sogenannte „middleware“ eine einfache API, die es erlaubt, die letzten Werte des jeweiligen Kanals abzurufen. Diese werden als JSON zurückgegeben. Für unseren Anwendungsfall muss folgende URL auf dem Volkszähler-Server aufgerufen werden („KANAL_UUID“ wird durch die UUID des Kanals ersetzt, die im frontend zu finden ist):
/middleware.php/data.json?from=now&uuid[]=KANAL_UUID
Um diesen aktuellen Wert nun in ioBroker verarbeiten zu können, habe ich ein besagtes Skript geschrieben, welches obige URL regelmäßig abruft und den Wert speichert.
Umsetzung
Die einfachste Art, in ioBroker Daten zu speichern, ist mittels Objekten. Diese erzeugt man (einmalig) mithilfe der createState
Funktion. Der erste Parameter der Funktion ist die ID, über die man den Wert später im ioBroker auslesen kann, in meinem Beispiel „Volkszaehler.AKTUELLER_VERBRAUCH“.
createState("Volkszaehler.AKTUELLER_VERBRAUCH", 0, { name: 'Aktueller Verbrauch', desc: 'Aktueller Verbrauch', type: 'number', role: 'value', unit: 'W' });
Für das Laden des JSONs habe ich eine simple Funktion (readJson
) benutzt, welcher man die URL des Volkszaehlers übergibt und die dann entweder das JSON oder einen Fehler zurückgibt. Das Aufrufen dieser sieht wie folgt aus:
readJson(url, function(err,json) { if(!err) { // Durchs JSON "navigieren", siehe unten var wert = json.data[0].tuples[0][1]; // Setzen der Werte in ioBroker setState("Volkszaehler.AKTUELLER_VERBRAUCH", wert); } else { log("Fehler beim Auslesen des JSON fuer Volkszaehler", "warn"); } });
Interessant ist hier die Zeile var wert = json.data[0].tuples[0][1]
. Um diese besser zu verstehen, empfehle ich die Volkszähler-API-URL einfach in Firefox aufzurufen, da dieser das JSON automatisch formatiert darstellt.
Trotzdem eine kurze Erklärung: Mit data[0]
greift man auf den ersten (und einzigen) zurückgegebenen Channel zu. tuples
sind die einzelnen Werte mit Zeitstempel, hier interessiert nur der Zahlenwert des neuesten „Tuples“, also tuples[0][1]
.
Aktualisieren der Werte
Wenn das Skript jetzt ausgeführt wird, sollte ein ioBroker-Objekt erstellt und der aktuelle Wert übernommen werden. Dies passiert allerdings nur einmalig bei jedem Start des Skriptes. Deshalb gibt es die schedule-Funktion, die eine Funktion regelmäßig wiederholt. Die „Wiederholrate“ wird mithilfe einer Variante des crontab-Syntax angegeben. Um den Wert z.B. alle zwei Sekunden zu aktualisieren, sieht der Code so aus:
schedule("*/2 * * * * *", function () { // Hier den auszuführenden Code, in unserem Beispiel der obige Codeblock });
Optional: Mehrere Messwerte gleichzeitig abrufen
Um mehrere Messwerte bzw. Kanäle gleichzeitig abzurufen, hängt man die neue UUID an obige URL wie folgt an:
/middleware.php/data.json?from=now&uuid[]=KANAL1_UUID&uuid[]=KANAL2_UUID
Für den jeden neuen Wert muss wieder nach obigem Prinzip ein neues Objekt im ioBroker erzeugt werden. Interessant ist hauptsächlich nur das Auslesen aus dem JSON. Hierfür ist die Reihenfolge der UUIDs in der obigen URL relevant.
var kanal1_wert = json.data[0].tuples[0][1]; var kanal2_wert = json.data[1].tuples[0][1];
Das fertige Skript
Das war’s dann auch schon. Wenn wir alle Elemente zusammenfügen, sieht der Code wie folgt aus. Fragen oder Anmerkungen dazu gerne in die Kommentare.
Hallo,
leider finde ich das ganze Skript nicht bzw. keinen Download darauf,
Gruß
Thomas
Hallo Thomas,
entschuldige die späte Antwort. Hier ist ein seperater Link zu dem Skript, funktioniert das? https://gist.github.com/digitmind-net/d61a89ef1b92ce9273bc0887b2181c04#file-volkszaehler-js
Gruß
Thomas
Hi,
durch das Script habe ich nun die Zählerstände (mehr gibt mein VZ-Logger nicht aus) auch in ioBroker und in der Datenbank.
Zur Weiterverarbeitung wäre es jetzt schön, wenn man den smartmeter-Adapter nutzen könnte.
Gibt es eine Möglichkeit, den Zählerstand dort einzubinden?
Hallo,
soweit ich das auf die Schnelle gefunden hatte, ist es nicht so einfach möglich, Volkszähler direkt in den smartmeter einzubinden, weshalb ich auch das Skript geschrieben hatte.
Da ich mich deshalb mit dem smartmeter Adapter nie intensiver auseinander gesetzt habe, würde mich interessieren, was für Vorteile dieser überhaupt bezüglich Weiterverarbeitung bietet?
Gruß Thomas
Hallo Thomas,
vielen Dank für das Script, funktioniert, soweit ich es bis jetzt getestet habe, super!
Viele Grüße
Peter
Hallo Peter,
danke für deinen Kommentar, das freut mich!
Grüße
Thomas
MEGA!
Funktioniert auf Anhieb!
Richtig gute Arbeit!
Vielen vielen Dank
Danke für deinen Kommentar. Freut mich, dass alles funktioniert!
Hallo Zusammen,
können auch die historischen Daten,
wie täglicher und monatlicher Verbrauch ausgelesen werden?
Hallo David, mit der API vom Volkszähler ist das möglich, die Daten auszulesen: https://wiki.volkszaehler.org/development/api/reference
Unter „Messwerte abfragen“ ist dort ein Beispiel, welche URL du dafür aufrufen müsstest.
Man müsste dazu allerdings einige Dinge im Skript verändern und ich hatte bisher keinen Bedarf dazu. Deshalb kann ich dir da leider nicht weiterhelfen.
Lg Thomas
Hallo, ich bekomme immer diese Meldung im IOBroker:
javascript.0 2020-08-25 19:29:38.021 error (21706) Error in request callback: TypeError: Cannot read property ‚0‘ of undefined
Was bedeutet das ?
Fehler gefunden. 🙂
Hallo Michael,
hab die gleiche Fehlermeldung und finde den Fehler nicht ..
Ein Tipp?
Hallo Dieter, vielleicht findest du im ioBroker-Forum ja einen Hinweis, dort hatten mehrere Leuten einen ähnlichen Fehler: https://forum.iobroker.net/topic/18697/gel%C3%B6st-skript-volksz%C3%A4hler-zickt (bisschen runterscrollen).
Grundsätzlich ist der erste Schritt zum Finden eines Fehler immer, die URL ganz oben im Script im Browser einzugeben und zu schauen, was dabei so rauskommt. Du kannst den Output dann auch einfach gerne mal im Forum postet und dann versuche ich dir dort weiterzuhelfen
Bekomme leider folgenden Error:
(32) Error in request callback: TypeError: Cannot read property ‚tuples‘ of undefined
Hallo Markus, siehe meinen Kommentar an Dieter, dort findest du einen Link zum Forum. Dort können die bestimmt andere oder ich weiterhelfen!
Hallo Thomas
finde es super das jemand sich mit der Datenübergabe von volkszähler zu iobroker beschäftigt hat.
Habe dein Script im iobroker eingefügt und zum testen meine uuid für den aktuellen Verbrauch aus vzlogger gesetzt.
Das script läuft aber ich bekomme keinen Wert. Woran könnte das liegen?
das ist die ausgabe:
17:19:55.805 info javascript.0 (24181) Stop script script.js.Volkszaehler
17:19:55.868 info javascript.0 (24181) Start javascript script.js.Volkszaehler
17:19:55.882 info javascript.0 (24181) script.js.Volkszaehler: registered 0 subscriptions and 1 schedule
Danke schon mal im voraus
Gruß Stephan
Hallo Stephan, siehe meinen Kommentar an Dieter, dort findest du einen Link zum Forum. Dort können die bestimmt andere oder ich weiterhelfen!