Inhaltsverzeichnis

SunSpec kompatible Wechselrichter

Hier wird ein Weg beschrieben, wie man mit vzlogger an die Daten von SunSpec kompatiblen Wechselrichtern kommt.

Viele Hersteller verwenden in ihren Wechselrichtern den SunSpec Standard, so etwa ABB, Fronius, LG, SMA, Schneider Electric etc. Dadurch können sie alle auf die gleiche Weise ausgelesen werden.

In dieser Anleitung wurde mit einem SolarEdge Gerät gearbeitet. Das Vorgehen sollte ebenso gültig sein für alle Geräte auf der Liste von SunSpec-zertifizierten Produkten.

Zusammenfassung

Der beschriebene Weg in Kürze:

  1. vzlogger kann nicht direkt Modbus TCP, es braucht weitere Komponenten.
  2. Der Modbus Metering Deamon mbmd springt in diese Lücke.
    Er kennt nicht nur generell Modbus, sondern insbesondere auch das SunSpec Format.
  3. Um mit vzlogger an die Daten von mbmd zu kommen, ist der kürzeste Weg
    (im Sinne von „braucht wenig weitere Software…“) der,
    via exec Protokoll ein Python Script aufzurufen, das die Daten aus der Rest-API von mbmd liest und für vzlogger aufbereitet.
Alternativen:
mbmd kann die ausgelesenen Daten auch auf andere Arten zur Verfügung stellen. Wer schon MQTT, nodeRED & co. kennt, ist damit vielleicht schneller. ingress ist explizit ein Tool, das unter Anderem mbmd und die Volkszähler Middleware verbinden soll. Jedoch steht es irgendwo zwischen work in progress und abandoned. Unabhängig vom Status, es braucht zusätzlich auch noch MQTT, also unter Umständen noch mehr Lernaufwand.

Die hier gezeigte Lösung verlangt von jemandem der den Volkszähler und vzlogger schon kennt, als Lernaufwand „nur“ mbmd und ein minimales Stück Python.

mbmd

mbmd gehört zwar zum volkszaehler.org Projekt, ist aber als universelles Tool ausgelegt und nicht so eng mit VZ verzahnt wie man vielleicht erwarten würde. Etwa verwenden beide per Default den selben Port für den Webserver.

mbmd kennt verschiedene gut dokumentierte Kommandos, mit denen man mit dem Wechselrichter kommunizieren kann.

Bevor man mbmd als Dienst beim Systemstart starten kann, braucht man einige Angaben, die man erst mal zusammensuchen muss. Dazu genügt es, wie in der Installationsanleitung beschrieben die ausführbare Datei mbmd auf den Rechner zu holen.

Verbindung testen

scan

In der mbmd Dokumentation steht, wie man mit scan nach Geräten scannen kann. Als Beispiel ist dort ein Serial-Port wie wie /dev/ttyUSB0 angegeben. Dies muss für Modbus-TCP durch die IP des Wechselrichters, gefolgt vom immer gleich bleibenden Port 502 ersetzt werden. Das Kommando und der Output sehen dann z.B. so aus:

pi@raspberrypi:~ $ mbmd scan -a 192.168.1.101:502
2021/11/19 17:43:50 config: creating TCP connection for 192.168.1.101:502
2021/11/19 17:43:50 starting bus scan on 192.168.1.101:502
2021/11/19 17:43:51 device 1: SolarEdge type device found, Current: 234.40
2021/11/19 17:43:54 device 2: n/a

…jetzt dauert's ewig, bis nach dem Scannen aller Adressen ein Paar weitere Details ausgespuckt werden:

2021/11/19 20:01:47 device 246: n/a
2021/11/19 20:01:50 device 247: n/a
2021/11/19 20:01:50 found 1 active devices:
2021/11/19 20:01:50 * #1 type SolarEdge (Model: SE9K Version: 0003.225 Serial: 9A166F9D)
2021/11/19 20:01:50 WARNING: This lists only the devices that responded to a known probe request. Devices with different function code definitions might not be detected.

Der Scan kann auch vorzeitig unterbrochen werden um sich das Warten zu sparen. Dies wenn man weiss, dass man nicht mehr als die schon gefundenen Geräte hat.

Wichtig aus der Ausgabe ist nur, dass mbmd den Wechselrichter findet, und die device Nummer, im Beispiel oben die 1. Man braucht die type Angabe nicht, denn SunSpec ist ohnehin der einzige Device- Typ für TCP. Entsprechend der Dokumentation funktioniert -d SUNS:1 als device- Parameter. Auch der im Output von scan gefundene String SolarEdge funktioniert: -d SolarEdge:1.

inspect

Zum testen der so gefundenen Daten für die device- und adapter- parameter kann man mit dem inspect Befehl erstmals Daten vom gefundenen Device abfragen:

pi@raspberrypi:~ $ mbmd inspect -a 192.168.1.101:502 -d SUNS:1
2021/11/19 20:15:05 config: creating TCP connection for 192.168.1.101:502
--------- Model 1 common ---------
Mn         SolarEdge     string
Md               SE9K    string
Opt                      string
Vr           0003.225    string
SN           9A166F9D    string
DA               1.00    uint16
Pad            0x0067    pad
--------- Model 103 inverter ---------
A                    0.00    uint16
AphA                 0.00    uint16
AphB                 0.00    uint16
AphC                 0.00    uint16
...
run

Als letzten Test kann man mit run den deamon starten.

Dabei ist zu beachten, dass der Webserver standardmässig auf dem selben Port laufen will wie der vom Volkszähler standard- Frontend, Port 8080. Deshalb muss man, wenn man auf dem selben Server ist, im zusätzlichen –api Parameter einen anderen Port angeben mbmd run -a 192.168.1.101:502 -d SUNS:1 –api 0.0.0.0:8888

Jetzt kann man im Webbrowser unter der IP des Servers und angegebenem Port das Frontend mit live- Daten sehen: [raspi-ip]:8888

Von hier kann man gleich die Geräte- Adresse, SUNS1.1 notieren. Diese braucht man später im python script.

mbmd als Dienst installieren

Jetzt da mbmd läuft, kann er wie in der Dokumentation beschrieben als Dienst gestartet werden. Dabei ist natürlich die Kommandozeile mit den bis hier ermittelten Parametern anzupassen. ExecStart=/usr/local/bin/mbmd run -a 192.168.1.101:502 -d SUNS:1 –api 0.0.0.0:8888

das Python Script

Da vzlogger nicht direkt auf die Daten von mbmd zugreifen kann, braucht es ein Script, das sie aufbereitet. Stefan Schoof hat das mit einem Python Script erledigt. Die URL von der mbmd API ist natürlich wieder anzupassen, mit der IP, Port und Meter-ID (letzteres aus dem mbmd Web Frontend)

/usr/local/bin/mbmd.py
#!/usr/bin/env python3
import requests
import json
 
response = requests.get("http://localhost:8888/api/last/SUNS1.1")
if (not response.ok):
    exit(1)
data = json.loads(response.content)
print(f'{data["Unix"]}: Export = {data["Export"]}')
print(f'{data["Unix"]}: Power = {data["Power"]}')
print(f'{data["Unix"]}: DCPower = {data["DCPower"]}')

nach dem die Datei mit chmod +x mbmd.py ausführbar gemacht ist, kann sie ausgeführt werden und sollte den letzten Messwert liefern:

pi@raspberrypi:~ $ /usr/local/bin/mbmd.py
1636450880: Export = 34981.956
1636450880: Power = 5173.0
1636450880: DCPower = 5251.0

Wer andere oder mehr Messwerte braucht, kann natürlich das Script anpassen.

Diese Ausgabe ist nun das, was vzlogger beim exec- Protokoll erwartet.

vzlogger

In vzlogger geht man nun prinzipiell vor wie bei jedem Anlegen von neuen Kanälen:

Typischerweise über's Web Frontend legt man die neuen Kanäle an und trägt dann ihre UUID's in der vzlogger.conf ein. Siehe auch die Dokumentation zum exec- Protokoll

/etc/vzlogger.conf
{
  "retry": 0,
  "verbosity": 10, // 0 for production, 10 or 15 for testing
  "log": "/var/log/vzlogger/vzlogger.log",
  "local": {
    "enabled": false,
    "port": 8081,
    "index": false,
    "timeout": 0,
    "buffer": 0
  },
  "meters": [
    {
       // pv inverter via mbmd
       "enabled": true,
       "allowskip": true,
       "protocol": "exec",
       "command": "mbmd.py",
       "format": "$t: $i = $v",
       "channels": [
          {
             "uuid": "3b500000-0000-11ec-9104-53d1c7275a14",
             "identifier": "Export",
             "api": "volkszaehler",
             "middleware": "http://localhost/middleware.php",
             "aggmode": "none",
             "duplicates": 3600
          },
          {
             "uuid": "86359ba0-0000-11ec-95e3-2d00008b8e87",
             "identifier": "Power",
             "api": "volkszaehler",
             "middleware": "http://localhost/middleware.php",
             "aggmode": "none"
          }
       ]
    },

Insbesondere wichtig sind bei den channels die identifier wie „identifier“: „Export“, die mit den Angaben im python Script übereinstimmen müssen und allenfalls der Pfad zum Script, falls es nicht am gleichen Ort liegt wie vzlogger.

Jetzt sollte man beim Start von vzlogger sehen können, dass alles läuft:

pi@raspberrypi:~ $ vzlogger
[Nov 09 10:22:48][main] vzlogger v0.8.0 based on heads/master-0-g033de9dc7d from Wed, 10 Feb 2021 14:44:17 +0100 started.
[Nov 09 10:22:48][mtr0] Creating new meter with protocol exec.
[Nov 09 10:22:48][exec] MeterExec::MeterExec: Parsed format string "$t: $i = $v" => "%3$lf: %2$ms = %1$lf"
[Nov 09 10:22:48][mtr0] Meter configured, enabled.
[Nov 09 10:22:48]       New meter initialized (protocol=exec)
[Nov 09 10:22:48]       Configure channel.
[Nov 09 10:22:48][chn0] New channel initialized (uuid=...275a14 api=volkszaehler id=Export)
[Nov 09 10:22:48]       Configure channel.
[Nov 09 10:22:48][chn1] New channel initialized (uuid=...8b8e87 api=volkszaehler id=Power)
[Nov 09 10:22:48][mtr1] Creating new meter with protocol d0.
[Nov 09 10:22:48][d0]   pullseq len:5 found
[Nov 09 10:22:48][d0]   using autoack
[Nov 09 10:22:48][mtr1] Meter configured, enabled.
[Nov 09 10:22:48]       New meter initialized (protocol=d0)
[Nov 09 10:22:48]       Configure channel.
[Nov 09 10:22:48][chn2] New channel initialized (uuid=...f5cde2 api=volkszaehler id=1.8.0)
[Nov 09 10:22:48]       Configure channel.
[Nov 09 10:22:48][chn3] New channel initialized (uuid=...27cd37 api=volkszaehler id=2.8.0)
[Nov 09 10:22:48]       Have 2 meters.
[Nov 09 10:22:48][main] log level is 10
[Nov 09 10:22:48][main] daemon=1, local=0
[Nov 09 10:22:48]       Daemonize process...

Und im Log sollte, je nach eingestelltem Log Level, auch etwas zu sehen sein:

pi@raspberrypi:~ $ cat /var/log/vzlogger/vzlogger.log
[Nov 09 10:44:14][exec] MeterExec::read: Calling 'mbmd.py'
[Nov 09 10:44:14][chn0] ==> number of tuples: 0
[Nov 09 10:44:14][chn0] JSON request body is null. Nothing to send now.
[Nov 09 10:44:14][chn1] ==> number of tuples: 0
[Nov 09 10:44:14][chn1] JSON request body is null. Nothing to send now.
[Nov 09 10:44:14][exec] MeterExec::read: Closing process 'mbmd.py'

Oops, es gibt keine Fehlermeldung und trotzdem keinen Output vom python script? Ah, mit log level 15 sehe ich mehr:

pi@raspberrypi:~ $ cat /var/log/vzlogger/vzlogger.log
[Nov 10 06:28:27][]     ===> Start meters
[Nov 10 06:28:27][exec] MeterExec::open: Testing command line 'mbmd.py': Permission denied

Da ist scheinbar die Ursache, Falsche Rechte…

Ja das kann sein. Man muss aufpassen wenn man mit dem User pi arbeitet und teils auch 'root', da schnell mal der User vzlogger, unter dem vzlogger normalerweise läuft, nicht mehr die richtigen Rechte hat auf den bearbeiteten Dateien.
Aber in meinem Fall lag's an einem falschen/fehlenden Pfad zur Datei mbmd.py, so dass die richtige Fehlermeldung eher etwas wie File not found hätte sein müssen. Dies lag an einem Bug, der aktuell behoben wird.