in Kurzform: Gibt es einen einfachen "Smart Message Language"-Parser (sml) in Pascal für Lazarus? Wenn ja, wo?
https://de.wikipedia.org/wiki/Smart_Message_Language
In Langform:
Ich beschäftige mich gerade mit meinem Stromzähler.
Hintergrund ist der Betrieb eines Balkonkraftwerkes, dessen Strom ich nicht verschenken, sondern möglichst vollständig selbst verbrauchen möchte. Dazu muss ich wissen, wieviel Strom im Augenblick verbraucht (=bezogen), bzw erzeugt (=ins Stromnetz abgegeben) wird, um entsprechend die Abgabe aus dem PV-System (Zendure, sehr einfache Kommunikation über TCP und WLAN) zu steuern.
Der verbaute Zähler, ein DZG DWSB20.2H, besitzt eine Infrarot-Schnittstelle, auf der etwa einmal pro Sekunde ein Datenpaket die aktellen Daten des Zählers seriell ausgegeben werden. Um das zu lesen habe ich mir eine kleine Hardware gebastelt, die ich an den seriellen Input-Pin eines Raspberry Pi angeschlossen habe und mittels eines kleinen Lazarus Programms einlesen kann.
Jetzt kommt endlich die Software ins Spiel.
Die Daten kommen in einem etwas seltsamen Binärformat. Hier eine schöne Seite, wo das erklärt wird: https://www.schatenseite.de/2016/05/30/ ... -auslesen/.
Das ist nicht schwer zur parsen, aber ich dachte, wenn das schon jemand mal gemacht hat muss ich das Rad ja nicht neu erfinden.
Andersherum, wenn ich sowas mache, dann könnte es ja auch für andere interessant sein.
Interessant auch deshalb, weil der Stromzähler die Daten liefert, für die man sonst extra Messtechnik kaufen müsste. Und so kann man mit einem billigen Raspberry einige Fliegen mit einer Klatsche fangen, weil das Teil dafür alles hat (serielle Schnittstelle, WLAN, Ausgabepins und vor allem die Lazarus-IDE
(Ja, es gibt fertige Leseköpfe mit WLAN, die man mit einem Magneten auf den Zähler "klebt", aber der Zählerschrank ist aus Metall und dann brauche ich einen extra Router. Außerdem kann der Lesekopf nicht mit dem PV-Modul reden, dass könnte nur wieder ein anderes Modul. Und am Ende gibt es immer noch, gerade Nachmittags überschüssigen Strom, den ich dann gerne für die Warmwassererwärmung verwenden würde. Da muss ich mit einigen Relais die drei Heizstäbe so schalten, dass ich die Zustände Aus, 330W, 500W, 660W und 1000W erzeugen kann. Alles läuft deshalb auf diesen Raspberry mit Lazarus hinaus)
Liebe Grüße aus Hildesheim
Hier noch ein kurzer kommentierter Ausriss aus den zu parsenden Daten, näheres im o.a. Link. Es fehlen insbesondere die Einleitungssequenz und der Schluss mit der Prüfsumme, hier geht es aber nur um einen kurzen Eindruck.
Code: Alles auswählen
xx00: xx xx xx xx 77 07 01 00 01 08 00 ff 64 1c 01 04 ....w␇␁␀ ␁␈␀.d␜␁␄
xx10: 72 62 01 64 da d0 f5 62 1e 52 ff 54 71 f4 5c 01 rb␁d...b ␞R.Tq.\␁
xx20: 77 07 01 00 02 08 00 ff 01 72 62 01 64 da d0 f5 w␇␁␀␂␈␀. ␁rb␁d...
xx30: 62 1e 52 ff 54 0e fd 93 01 77 07 01 00 10 07 00 b␞R.T␎.. ␁w␇␁␀␐␇␀
xx40: ff 01 01 62 1b 52 fe 53 52 81 01 xx xx xx xx xx .␁␁b␛R.S R.␁.....
77 // 7x = Liste, x7 = 7 Einträge folgen: Liste mit 7 Einträgen
07 01 00 01 08 00 ff // 0x = Bytestring, x7 = 7 Bytes inklusive diesem: objName "1.8.0" akkumulierter Verbrauch = Zählerstand
64 1c 01 04 // 6x=Unsigned Int, x4 = Länge inkl diesem, also 3 Bytes folgen: Status
72 // valTime
62 01
64 da d0 f5
62 1e // 6x=Unsigned Int, x2 = Länge inkl diesem, also ein Byte folgt: Unit 1E, sehr wahrscheinlich Wh
52 ff // 5x=Signed Int: Scaler FF = -1
54 71 f4 5c // Value 0x71F45C = 7468124 => eine Stelle nach rechts 746812,4 => 746,8 kWh
01 // Ein leerer Bytestring: ValueSignature (OPTIONAL)
77 // Liste mit 7 Einträgen
07 01 00 02 08 00 ff // ObjName "1.8.2" akkumulierte Einspeisung = Zählerstand
01 // Status (OPTIONAL)
72 // valTime
62 01
64 da d0 f5
62 1e // Unit 1E, sehr wahrscheinlich Wh
52 ff // Scaler FF = -1
54 0e fd 93 // Value 0x0EFD93 = 982419 => eine Stelle nach rechts 98241,9 => 98,2 kWh
01 // ValueSignature (OPTIONAL)
77 // Liste mit 7 Einträgen
07 01 00 10 07 00 ff // objName "1.16.7" Wirkleistung = aktueller Verbrauch
01 // Status (OPTIONAL)
01 // valTime (OPTIONAL)
62 1b // Unit 1B, sehr wahrschinlich W
52 fe // Scaler FE = -2
53 52 81 // Value 0x5281 = 21121 => zwei Stellen nach rechts 211,21W
01 // ValueSignature (OPTIONAL)