Wieso man den Haus-Akku gescriptet ausschalten können will
Meiner Lösung für das Laden eines E-Autos mit PV-Überschuss go-e-pvsd kann man mittlerweile zur Laufzeit mitteilen, dass man eine andere Ladeschwelle als die eigentliche haben will. Das nutze ich dafür, dass ich das Auto auch dann lade, wenn der Überschuss nicht allein dafür ausreicht. Z. B. kann man die Schwelle auf 1 W einstellen. Dann wird geladen, sobald es überhaupt irgendwelchen Überschuss gibt, und zwar mit dem minimalen Ladestrom. Was fehlt, kommt vom Netz, aber sollte der Überschuss reichen, dann wird der Ladestrom, genau wie beim „normalen“ Überschussladen, so angepasst, dass alles für das Laden benutzt wird, was da ist.
Wenn man aber nur teilweise mit eigenem Strom laden kann, dann ist es wenig sinnvoll, dass man den fehlenden Anteil aus dem Haus-Akku holt. Weil dann lädt man einen Akku mit einem anderen. Da ist der Strom aus dem Haus-Akku später bei den Verbrauchern im Haus deutlich besser aufgehoben. Und abgesehen davon wäre der Akku auch schnell leer, weil der Auto-Akku i. d. R. ja eine vielfach höhere Kapazität hat.
Also wäre es sinnvoll, das Entladen des Akkus automatisiert zu verhindern, wenn das Auto geladen wird – oder das zumindest so einfach wie möglich zu gestalten. Das geht ohne weitere Maßnamhen über ein zeitgesteuertes Energieprofil, was man im Webinterface des Wechselrichters anlegen kann. Das muss dann von Montag bis Sonntag von 0.00 bis 23.59 Uhr gelten und die maximale Entladung auf 0 W festlegen. Wenn man das dann aktiviert, dann wird aller zusätzlich benötigter Strom aus dem Netz geholt. Dazu muss man aber im lokalen Netzwerk sein, sich am Webinterface des Wechselrichters anmelden, und dann via „Energiemanagement“ → „Batteriemanagement“ das jeweilige Profil aktivieren. Nervt.
Akku steuern via Modbus
Tatsächlich kann man den Akku auch mittels Modbus „ausschalten“, also die Entladung verhindern. Dazu gibt es von Fronius allerlei Dokumentation (wenn man sich mit seiner E-Mail-Adresse registriert, dann kann man die Dokumente einfach herunterladen). Das ist aber alles auf den ersten Blick ziemlich kryptisch, insbesondere dann, wenn man (wie ich) noch nie mit Modbus zu tun hatte.
Alles, was man findet, wenn man nach „Fronius Akku per Modbus steuern“ oder auch „Fronius control battery using modbus“ sucht, ist Stand heute ziemlich dürftig. Ein paar Forums-Posts, ein paar Youtube-Videos. Scheinbar wissen auch manche nicht so recht, was sie da eigentlich machen … und alle benutzen „Home Assistant“, „Node Red“ oder sonstwas.
Das muss doch auch einfacher gehen.
Geht es auch, und zwar mit pymodbus, einer vollständigen Implementierung des Modbus-Protokolls für Python. Damit kann man das mit einer Handvoll Zeilen Code bewerkstelligen.
Steuerung mit einem Python-Script und pymodbus
Modbus TCP am Wechselrichter aktivieren
Was man zuerst machen muss: Dem Wechselrichter mitteilen, dass er als Modbus-Server (in der Modbus-Welt „Slave“ genannt) agieren soll. Das geht folgendermaßen:
Zunächst muss man sich als „Technician“ anmelden [Update 08.11.2024: Mit der aktuellen Firmware geht das jetzt auch als „Customer“]:
Dann über das Menü zu den Modbus-Einstellungen navigieren:
Und schließlich den Modbus-Server aktivieren:
Die Einstellungen waren hier schon alle so vorausgewählt. Ich habe auch „SunSpec Model Type“ auf „int + SF“ (also Integer-Werte mit einem Skalierungsfaktor) gelassen. Für die andere Option „float“ müsste man dann andere Adressen und Werte benutzen.
Benötigte Register
Zum Steuern der maximalen Ladung bzw. Entladung braucht man nur zwei Register. Für „int + SF“ als „SunSpec Model Type“ sind diese (vgl. die Fronius-Dokumentation):
StorCtl_Mod (Register 40349)
Hier kann festgelegt werden, ob die maximale Ladung, Entladung oder beide Werte festgelegt werden sollen. Der Wert besteht aus zwei Bits. Das erste Bit steht für Ladung, das zweite für Entladung. Wir können also entweder 0x01 (≙ 1), 0x10 (≙ 2) oder 0x11 (≙ 3) setzen, was dann entsprechend für die maximale Ladung, Entladung oder für beide Werte steht.
OutWRte (Register 40356)
Dieser Wert legt die prozentuale maximale Ladung bzw. Entladung fest. Er kann zwischen 0 und 10 000 liegen und hat einen Skalierungsfaktor von -2. Dieser steht für eine Zehnerpotenz, mit der der Wert multipliziert werden muss, in diesem Fall also 10-2. Folgerichtig steht 0 für 0 % und 10 000 für 100 %.
Ansteuerung mit Python und pymodbus
Ich habe pymodbus 3.6.9 benutzt. Das gibt es oder gibt es nicht „einfach so“, je nach Distribution. Bei Gentoo gibt ein Ebuild in verschiedenen Overlays, auf Artix kann man sich ein Paket mittels dem AUR bauen, und Devuan hat es von Haus aus dabei (wobei ich für Stable einen Backport benutzen musste). Egal wie: Man bekommt das Paket installiert.
Wir brauchen nur die Klasse ModbusTcpClient, die wir aus pymodbus.client importieren:
from pymodbus.client import ModbusTcpClient
Dann instanziieren wir einen Client und verbinden uns mit dem Server. Der Host muss der Hostnname bzw. die IP-Adresse des Wechselrichters sein. Der Port ist standardmäßig auf 502 eingestellt, sicherheitshalber habe ich ihn aber explizit angegeben:
client = ModbusTcpClient(host = "192.168.1.3", port = 502) # Adjust as needed
client.connect()
Und schon kann es losgehen. Wir brauchen nur die Funktion write_register. Version 3.6.9 von pymodbus legt als Standardwert für slave 0 fest. Die „unit id“ des Wechselrichters ist fix 0x01, weswegen wir den Parameter explizit angeben müssen. Laut Dokumentation sind „die ausgesendete[n] Registeradresse[n] […] immer um 1 geringer als die eigentliche Registernummer“ – also benutzen wir für StorCtl_Mod Register 40348 und für OutWRte Register 40355.
Dann stellen wir sicher, dass wir den maximalen Entladewert setzen:
client.write_register(40348, 2, slave = 1)
Und hinterher setzen wir den Wert (0 für „ausschalten“, 10000 für „einschalten“):
client.write_register(40355, 0, slave = 1) # off
#client.write_register(40355, 10000, slave = 1) # on
Und das war’s auch schon. Zum Schluss schließen wir noch die Verbindung und sind fertig!
client.close()
Der Effekt ist nach ein paar Sekunden im Wechselrichter-Webinterface oder Solarweb zu sehen.
Sinnvollerweise setzt man natürlich die Host-Adresse und ggf. den Port in einer Konfigurationsdatei, macht ein bisschen Fehlerbehandlung (konnte die Verbindung hergestellt werden? Waren die Abfragen erfolgreich?), aber im Prinzip sind es erfreulicherweise nur die paar Zeilen Python-Code, die man braucht, um den Akku zu steuern.
Ich hoffe, ich kann damit vielleicht dem Einen oder Anderen ein bisschen Kopfzerbrechen und Dokumentation wälzen ersparen!
Wir haben eine Dunstabzugshaube von Berbel. Die funktioniert spitze, war aber nicht gerade billig. Für die Zu- und Abluft wurde ein Mauerkasten verbaut, der sich, gesteuert von der Haube, öffnet und schließt. Und jetzt war, unschönerweise schon nach knapp acht Jahren, einer der Mauerkästen kaputt. Genauer gesagt der Antrieb darin.
Der Antrieb „BMK ferngesteuert“ (Berbel-Artikelnummer 6000519) besteht aus einem Elektromotor, einem Getriebe und ein bisschen Elektronik. Er hat einen Anschluss für ein 12-V-Netzteil und noch zwei Adern für eine Steuerleitung. Für bereits 108 € bietet der Hersteller das Ersatzteil an – ein echtes Schnäppchen.
Dummerweise gibt es genau diesen Motor nicht mehr, sondern nur seinen Nachfolger mit der Nummer 6005345. Der augenscheinlich einzige Unterschied ist, dass der kein Kabel mit zwei Adern als Steuerleitung hat, sondern eines mit einem Klinkenstecker. Auf Nachfrage beim Kundendienst wurde mir versichert, dass der einzige Unterschied eben jener Klinkenstecker ist, es aber einen Adapter für ältere Dunstabzugshauben gäbe.
Okay. Das Ding hat nach wie vor zwei Adern für die Steuerung. Und der Adapter, auf der einen Seite eine Klinkenbuchse, und auf der anderen besagte zwei Adern, soll 24 € kosten. Sonst geht’s aber schon noch, oder?! Eine 3,5-mm-Klinkenbuchse gibt es so ca. für 50 ¢, und ein paar cm Kabel sind erst recht nicht der Rede wert. Auf meine Frage hin, ob man denn nicht auch einfach den Stecker abzwicken könnte, wurde mir gesagt, dazu könne man keine Auskunft erteilen. Völlig unerwartet. Technische Unterlagen gibt es natürlich auch nicht. Und sinnvollerweise wird auch als Verbinder für zwei Pole ein Klinkenstecker mit vier Kontakten verbaut. Was auch sonst?!
Das können die vergessen. Ich habe ja den alten Motor und kann reinschauen, was wo angelötet ist. Und in den neuen kann ich auch reinschauen.
Langer Rede kurzer Sinn: Hier ist die Belegung der Steuerleitung:
Das rote Kabel liegt am Masseanschluss (Sleeve) des Klinkensteckers an und ist Anschluss Nummer 1
Das schwarze Kabel liegt am 1. Ring des Klinkensteckers an und ist Anschluss Nummer 2
Entweder zwickt man also wirklich einfach den Klinkenstecker ab und schließt die Adern direkt an (natürlich nach Montage einer Aderendhülse), oder man macht es so wie ich und vermeidet, dass es im Garantiefall heißen könnte, man hätte ja daran herummanipuliert – indem man sich seinen Adapter einfach selber lötet. Eine normale 3,5-mm-Stereo-Klinkenbuchse reicht dazu ja schon. Mich hätte es aber auch nicht gewundert, wenn die eine Leitung an den 2. Ring gelötet hätten, damit man eine vierpolige Buchse braucht.
Jedenfalls viel Spaß beim Nicht-Kaufen eines Centartikels für 24 € :-P
Alles „im Internet bestellen“ ist manchmal weder billiger, noch besser. Das habe ich heute (mal wieder) an einem guten Beispiel gesehen: Ich hatte zwei Muckturnier.org-T-Shirts in der Hand. Von verschiedenen Quellen. Ich habe vor einigen Jahren schonmal welche drucken lassen, aber da ein paar von denen im Schrank geschrumpft sein müssen, waren neue fällig :-) Und da habe ich ein bisschen rumprobiert.
Die letzten Muckturnier.org-T-Shirts hat mir die Firma Maisel (Word of Textiles) aus Konradsreuth bedruckt. Mit einem Digital-Direktdruck wegen einer geringen Auflage. 10 Stück musste ich mindestens abnehmen. Die T-Shirts waren Hakro No. 292, erfreulich gute Qualität. Aber jetzt mussten neue her.
Auf jeden Fall habe ich wieder einen 10er-Satz T-Shirts vom Maisel bestellt, wieder Hakro No. 292, nur eine andere Farbe (weil es die vom letzten Mal nicht mehr gab). Und testweise auch noch eines von Flyeralarm und eines von Spreadshirt. Spreadshirt war ziemlich einfach: Vektorgraphik hochladen und gut. Die von Flyeralarm wollten druckfertige Daten. Das ist ja auch kein Problem, aber man musste das Logo selbst in einem definierten beduckbaren Bereich positionieren, und der musste eine definierte Größe haben. Was letztendlich dazu geführt hat, dass das Logo nicht ganz da gelandet ist, wo ich mir es vorgestellt hatte. Aber darum soll es jetzt gar nicht gehen.
Die T-Shirts haben pro Stück ziemlich genau gleich viel gekostet. „Das Internet“ war vielleicht ein bisschen günstiger, aber nicht tatsächlich relevant günstiger. Und heute hatte ich eben zwei von den T-Shirts gleichzeitig in der Hand. Und so sehen sie aus, nach ein paar Wäschen:
Oben das von Word of Textiles, unten das von Spreadshirt. Das von Flyeralarm sieht vergleichbar aus. Wenn man sich den Druck ein bisschen näher anschaut, dann muss man das eigentlich gar nicht weiter kommentieren.
Hier World of Textiles:
und hier Spreadshirt:
Von der erheblich besseren Stoffqualität des Hakro-T-Shirts ganz zu schweigen.
Manchmal ist es halt doch gar keine schlechte Idee, die regionale Wirtschaft zu unterstützen.
I recently purchased a Sunmi Blink 2D barcode scanner, for more stylish booking code registration with Muckturnier.org ;-)
Indeed, this thingy looks way cooler than a “normal” handheld barcode scanner. I think it’s intended to be used in retail as a POS termial for QR code based payments (like Alipay). However, here in Germany (or Europe?!) this way to pay isn’t too common (we use NFC for that). Thus, the choice for such scanners is not too manifold. However, for a muckturnier, this thing should be the very right device for QR booking code scanning.
The scanner has a configuration manual with special barcodes to e.g. set the keyboard layout, which codes to search for and so on – just like a “normal” barcode scanner (after all, it is one). However, whilst testing it out, I noticed one problem: The scanner did not type encoded spaces. All space characters were simply skipped and omitted.
E.g. the following QR code contains QR Code with a bunch of spaces:
Yet, the Sunmi Blink would type QRCodewithabunchofspaces when scanning it. I also tried Data Matrix, Aztec and PDF 417 – always with the same result: Spaces encoded in the barcode would be ignored when scanning them.
So I decided to file a request at Sunmi’s customer support asking what’s going on here – and I actually got an answer. After writing a few emails and describing the problem, sending some example barcodes and so on the employee finally asked me to try out the following configuration code:
… and it actually did the trick! After having scanned it, the Sunmi Blink typed spaces encoded in a barcode as-is.
This code is actually not printed in the configuration manual. So you have no chance to find it. The Chinese ideographs below are translated to “Output Function Keys” by Google Translator. I would suppose that there’s also a reverse code to turn the spaces typing off again that should read 3030AD1 (like e.g. the two barcodes turning Aztec Code support on and off, which encode 1003281 and 1003280 respectively).
Anyway this seems to be some non-standard barcode format. I can read it using my phone’s barcode scanner Binary Eye and it does decode to 3030AD0, identified as a Code 128 barcode. But when I create a Code 128 barcode containing 3030AD0, the result looks different. Most probably, there’s some special sequence that ensures that the scanner’s configuration is not changed if a real/normal Code 128 barcode containing some configuration sequence is scanned. I thus could not test if one can switch this off again other than resetting the scanner to factory defaults.
However, I hope this helps somebody at some point, as my searches for “Sunmi Blink doesn’t enter spaces” or such didn’t yield any result, and this code seems to be not (yet?) documented officially, at least not for the Sunmi Blink. But after all, my Sunmi Blink now types spaces :-)