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.
Der beschriebene Weg in Kürze:
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 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.
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
.
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 ...
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.
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
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/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.
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
{ "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…
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.
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.