Shelly Plug S in Volkszähler einbinden

Seit Jahren schon zeichne ich den Gesamtstromverbrauch des Hauses direkt von unserem Stromzähler mit Hilfe eines Optokopfes auf. Die niedrigsten Verbrauchswerte sind um die 150 Watt, darunter liegt der Stromverbrauch niemals. Ich wollte nun herausfinden, wo der ganze Strom verbraucht wird.

Von Weihnachten hatte ich noch ein paar Shelly Plug S-Zwischenstecker rumliegen. Diese kann man nicht nur per HTTP-Befehlen an- und ausschalten, sondern sie messen auch die verbrauchte Energie und bieten eine HTTP-basierte API zum Abruf des Verbrauchs: /meter/0.

Zur Datenaufzeichnung und Visualisierung nutze ich den Volkszähler. Der vzlogger wird alle 10 Minuten per cron gestartet, liest die Daten vom Stromzähler aus und schreibt sie dann in die "Middleware", die die Daten in die Datenbank wirft. Die Ausgabe erfolgt per volkszähler-Webinterface im Browser:

Volkszähler-Webinterface im Browser

Kanal anlegen

Bevor man den Logger konfigurieren kann, muss im Webinterface ein neuer Kanal angelegt werden. Also Kanal hinzufügen und dann Kanal erstellen und folgende Einstellungen vornehmen:

Typ
El. Energie (Zählerstände)
Auflösung
60000 (der normale Stromzähler hat kWh-Auflösung, und der Shelly Plug S misst aber Wattminuten. 60.000 Wattminuten sind eine kWh.)
Stil
steps (die richtige Einstellung für Zähler)

Der Rest ist nach Belieben wählbar.

Hat man den Kanal angelegt bekommt man eine UUID, die man sich merken bzw. in eine Textdatei kopieren sollte - man braucht sie für die Loggerkonfiguration.

Shelly Plug S: Daten abrufen

Der vzlogger muss die Daten vom Shelly abrufen. Dazu habe ich im "meters"-Abschnitt der vzlogger.conf-Datei ein neues Gerät angelegt:

{
    "enabled": true,
    "allowskip": true,
    "interval": -1,
    "aggtime": -1,
    "aggfixedinterval": false,
    "protocol": "exec",
    "command": "curl -s http://shellyplug1/meter/0 | jq -r '[\"total\", .total] | join(\" \")'",
    "format": "$i $v",
    "channels": [
        {
            "uuid": "9af09190-b000-11ec-96e0-bb006c288051",
            "middleware": "http://strom.home.cweiske.de/middleware.php",
            "identifier": "total",
            "aggmode": "max"
        }
    ]
}

Das Protokoll ist "exec", weil ein Befehl ausgeführt werden soll. Hier ist ganz wichtig, daß der vzlogger nicht als root laufen darf, weil das exec dann (absichtlich) nicht funktioniert.

Der Befehl command holt sich die aktuellen Verbrauchsdaten mit curl vom Shelly ab und formatiert sie mit jq so um, daß die Zeile "total 2342" rauskommt (wenn der Zählerstand 2342 ist).

Das format sagt, daß zuerst der Identifier ("total"), dann ein Leerzeichen und dann der Zählerstand ("2342") kommt. Ich hatte es ohne Identifier probiert und das format nur auf "$v" gesetzt, aber dann hat der vzlogger nicht mitbekommen, daß Daten vorhanden waren:

[Mar 26 13:00:02][exec] MeterExec::read: Closing process 'curl -s http://shellyplug1/meter/0 | jq -r .total''
[Mar 26 13:00:02][mtr3] Stopped reading.
[Mar 26 13:00:02][chn4] ==> number of tuples: 0
[Mar 26 13:00:02][chn4] JSON request body is null. Nothing to send now.

Mit diesen Einstellungen schreibt der Logger jetzt brav aller 10 Minuten die Verbrauchswerte für die fünf ShellyPlugS in die Datenbank.

Restmenge

Die Daten wurden nun mitgeloggt und auch im Browser hübsch angezeigt. Was mir fehlte war noch eine Anzeige, wieviel des verbrauchten Stroms nicht gemessen wird.

Dazu legte ich einen "Verbrauchssensor (virt.)" an. In die Felder für die Eingänge schreibt man die UUIDs der Kanäle, und bei "Regel" die Berechnung:

val(in1)-val(in2)-val(in3)

Hier wird der Wert on Eingang 1 als Basis genutzt und dann die Werte von Eingang 2 und 3 abgezogen. So sehe ich, wieviel "unbekannten" Strom noch im Haus verbraucht wird.

Ich habe 2 weitere virtuelle Sensoren definiert, in denen ich jeweils 4 Messwerte zusammengerechnet habe (weil das Webinterface nur Felder für 4 Eingänge anzeigt). Diese habe ich dann im 3. virtuellen Sensor final vom Gesamtstrom abgezogen.

Restmengenanzeige (lila)

Written by Christian Weiske.

Comments? Please send an e-mail.