Aktuellen Stromverbrauch mithilfe von Volkszähler in ioBroker speichern

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.

12 Kommentare

    1. 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

  1. 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?

    1. 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

    1. 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

  2. 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 ?

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.