Hardware:
- Zählertyp: Sagemcom Smarty BZ plus von Digimeto / Sachsennetze
- Hichi IR Lesekopf TTL-Variante (Bezug über diverse Kanäle möglich z.b. hier)
- ESP D1 Mini
Software:
- aktuelles Tasmota Image kompiliert mit Tasmocompiler auf Gitpod
- Tasmota SML Treiber
Wichtige Referenzen:
Grundlagen – https://tasmota.github.io/docs/Smart-Meter-Interface/
Anleitung Zähler – DIGImeto_Sagemcom_smarty_Bedienungsanleitung_Web.pdf
Wissenswertes zum SML-Protokoll – http://www.stefan-weigert.de/php_loader/sml.php
SML-Decoder zur Script-Erzeugung – https://tasmota-sml-parser.dicp.net/
Die Geschichte:
Im www gab es leider keine Anleitung bzw. Tasmota Script, das auf meinen Zähler passt.
Der Zähler bietet Auslesemöglichkeiten über D0 und SML an. SML wird in 2 Varianten unterstützt (einfacher und erweiterter Datensatz). Ich entschied mich für die SML Variante mit erweiterten Datensatz. Ich fand es im sinnvollsten, einfach die periodisch gesendeten Telegramme abzugreifen, ohne irgendetwas senden zu müssen.
Und so ging ich auch vor. Vorab hatte ich bei Digimeto den Freischaltcode angefordert um die so genannte INFO-Schnittstelle im Einstellungsmenü des Zählers zu aktivieren. Weiterhin habe ich die PIN-Abfrage deaktiviert, um mir daraus eventuell resuliteriende Probleme zu ersparen. Das alles ist sehr gut in der Anleitung des Zählers beschrieben, weshalb ich darauf nicht weiter eingehen möchte. Nun versprach ich mir eine problemlose Inbetriebnahme des ganzen. Die Tasmota Auslesescripts für diese Methode sind ja sehr überschaubar und verständlich.
Ein Tasmota Image habe ich mit Hilfe des Tasmo-Compilers (GUI) selbst gebaut. Geflasht auf den ESP mit esptool auf einem Linux System. Alles ziemlich straight forward. Dafür gibt es Anleitungen en masse, deshalb hier keine Details.
Das erste Script mit einem dump des Zähleroutputs und dem WEB-SML-Parser erstellt, und zumindest hatte ich auf Anhieb einen Teilerfolg. Die aktuelle Wirkleistung konnte ich zuverlässig auslesen. Aber das wars dann auch. Ich kam einfach nicht an die Zählerstände ran und so ging ich in die Grundlagenforschung…
Auf dem Weg zum funktionierenden Script ist folgende Zerlegung des SML-Telegramms meines Zählers entstanden:
1b 1b 1b 1b #Escape Sequenz 01 01 01 01 #Start Version 1.0 76 #Liste mit 6 Einträgen (1. SML Nachricht in diesem Telegramm) 05 00 00 00 00 #transactionId: "0" 62 00 #groupNo: 62 00 #abortOnError: 72 #messageBody: Liste mit 2 Einträgen 65 00 00 01 01 #getOpenResponse: 76 #Liste mit 6 Einträgen 01 #codepage: ohne Wert 01 #clientId: ohne Wert 05 00 00 00 00 #reqFileId: 0b xx xx xx xx xx xx xx xx xx xx #serverID: (0b(HEX)=11Bytes Länge) 72 #refTime: ohne Wert 62 01 #choice: secIndex 65 02 cf 33 69 #Liste mit 9 Einträgen 01 #smlVersion: ohne Wert 63 be c4 #CRC Prüfsumme der zweiten Nachricht 00 #Ende der ersten SML Nachricht 76 #Liste mit 6 Einträgen (2. SML Nachricht in diesem Telegramm) 05 00 00 00 01 #transactionId: "1" 62 00 #groupNo: 62 00 #abortOnError: 72 #messageBody: Liste mit 2 Einträgen 65 00 00 07 01 #getListResponse: 77 #Liste mit 7 Einträgen 01 #clientId: ohne Wert 0b xx xx xx xx xx xx xx xx xx xx #serverID: 07 01 00 62 0a ff ff #ListName: 72 #Liste mit 2 Einträgen 62 01 #choice: secIndex 65 02 cf 33 69 #secIndex: (Uptime) 79 #Liste mit 9 Einträgen 77 #Liste mit 7 Einträgen 07 01 00 60 32 01 01 #Herstellerkennung vid 01 #status: - 01 #valTime: - 01 #Einheit: - 01 #scaler: - 04 53 41 47 #Ascii-UTF8-Wert: 0x534147 "SAG" 01 #valueSignature: ohne Wert 77 07 01 00 60 01 00 ff #Geräte-Indentifikation 01 #status: - 01 #valTime: - 01 #Einheit: - 01 #scaler: - 0b xx xx xx xx xx xx xx xx xx xx #Nicht weiter zerlegen s. Aufdruck Zähler 01 #valueSignature: ohne Wert 77 #Liste mit 7 Einträgen 07 01 00 01 08 00 ff #Totalregister Wirkenergie (Bezug) - name: WEBT 65 00 1c 01 04 #status: wert = "1835268" (Type zu status Unsigned32) 72 #valTime: 62 01 #type: Wert = "01" => SML_Time = "0x01" => secIndex 65 02 cf 33 69 #minOccurs: Wert = "47133545" => 4713545 s 62 1e #Einheit: 1e = "Wh" 52 ff #scaler: ff(integer)=-1(dezimal) -> 10^-1 = 0.1 69 00 00 00 00 05 5d 47 a7 #unsigned-Wert: 89999271 => 8999,9271 kWh, Type zu value Unsigned64 01 #valueSignature: ohne Wert 77 #Liste mit 7 Einträgen 07 01 00 01 08 01 ff #Tarifregister 1 Wirkenergie (Bezug) - name: WEB1 01 #status: - 72 #valTime: - 62 01 #Wert = "1" 65 02 cf 33 69 #Wert = "47133545" 62 1e #Einheit: 1e = "Wh" 52 ff #scaler: ff(integer)=-1(dezimal) -> 10^-1 = 0.1 69 00 00 00 00 03 07 f0 59 #Unsigned-Wert: 50851929 => 5085,1929 kWh 01 #valueSignature: ohne Wert 77 #Liste mit 7 Einträgen 07 01 00 01 08 02 ff #Tarifregister 2 Wirkenergie (Bezug) - name: WEB2 01 #status: - 72 #valTime: - 62 01 #Wert = "1" 65 02 cf 33 69 #Wert = "47133545" 62 1e #Einheit: 1e = "Wh" 52 ff #scaler: ff(integer)=-1(dezimal) -> 10^-1 = 0.1 69 00 00 00 00 02 55 57 4f #Unsigned-Wert: 39147343 => 3914,7343 kWh 01 #valueSignature: ohne Wert 77 #Liste mit 7 Einträgen 07 01 00 02 08 00 ff #Totalregister Wirkenergie (Lieferung) - name: WELT 01 #status: - 72 #valTime: - 62 01 #Wert = "1" 65 02 cf 33 69 #Wert = "47133545" 62 1e #Einheit: 1e = "Wh" 52 ff #scaler: ff(integer)=-1(dezimal) -> 10^-1 = 0.1 69 00 00 00 00 00 07 1c 7e #Unsigned-Wert: 466046 => 46,6046 kWh 01 #valueSignature: ohne Wert 77 #Liste mit 7 Einträgen 07 01 00 02 08 01 ff #Tarifregister 1 Wirkenergie (Lieferung) - name: WEL1 01 #status: - 72 #valTime: - 62 01 #Wert = "1" 65 02 cf 33 69 #Wert = "47133545" 62 1e #Einheit: 1e = "Wh" 52 ff #scaler: ff(integer)=-1(dezimal) -> 10^-1 = 0.1 69 00 00 00 00 00 05 de b0 #Unsigned-Wert: 384688 => 38,4688 kWh 01 #valueSignature: ohne Wert 77 #Liste mit 7 Einträgen 07 01 00 02 08 02 ff #Tarifregister 2 Wirkenergie (Lieferung) - name: WEL1 01 #status: - 72 #valTime: - 62 01 #Wert = "1" 65 02 cf 33 69 #Wert = "47133545" 62 1e #Einheit: 1e = "Wh" 52 ff #scaler: ff(integer)=-1(dezimal) -> 10^-1 = 0.1 69 00 00 00 00 00 01 3d ce #Unsigned-Wert: 81358 => 8,1358 kWh 01 #valueSignature: ohne Wert 77 #Liste mit 7 Einträgen 07 01 00 10 07 00 ff #Momentane Wirkleistung - name: MWL 01 #status: - 01 #valTime: - 62 1b #Einheit: 1b = "W" 52 00 #scaler: 0(integer)=0(dezimal) -> 10^0 = 1 59 00 00 00 00 00 00 02 0c #integer-Wert: 524 01 #valueSignature: ohne Wert 01 #listSignature: ohne Wert 01 #actGatewayTime: ohne Wert 63 47 ec #CRC Prüfsumme der zweiten Nachricht 00 #Ende der zweiten SML Nachricht 76 #Liste mit 6 Einträgen (3. SML Nachricht in diesem Telegramm) 05 00 00 00 02 #transactionId: "0" 62 00 #groupNo: 62 00 #abortOnError: 72 #messageBody: Liste mit 2 Einträgen 65 00 00 02 01 #getCloseResponse: 71 #Liste mit einem Eintrag 01 #? ohne Wert 63 2f 35 #CRC Prüfsumme der dritten Nachricht 00 #Ende der zweiten SML Nachricht 1b 1b 1b 1b #Escape Sequenz 1a 00 a9 b5 #1a + Füllbyte + CRC (2Bytes) des gesamten Telegrammes
Das dekodierte Telegramm deckt sich inhaltlich mit dem Handbuch des Zählers. Mehr gibts nicht.- Weitere oft nachgefragte Messwerte wie zum Beispiel „Leistung je Phase“ werden nicht ausgegeben. Da es sich um einen 2-Tarifzähler handelt gibt es die Zählerstände für die Tarife einzeln.
Ich hatte nun vor, die Smart Meter Seite mit den Erkenntnissen nochmal gezielt durchzuarbeiten. Und landete schließlich bei den special options. Bei special option 3 angekommen, durchfuhr mich eine Ahnung. Mit Hilfe dieser Option lässt sich die maximale Länge eines einzulesenden SML-Telegramms anpassen. Und das passte auch ins Bild. Ich hatte schone längere Zeit das Gefühl, dass der dump die Zahlen zwar enthält, aber der Tasmota Parser gar nicht alles einliest. Es kam gelegentlich dazu, dass Werte zwischen Decoder Zeilen hin und her zu springen schienen. Nun, ums kurz zu machen, die Zeile „1,=so3.512“ löste die Probleme. Es ist nun alles auslesbar, was angeboten wird.
Hier das Script:
>D >B =>sensor53 r >M 1 +1,3,s,0,9600,SAGBZ+ 1,=so3.512 1,77070100010800ff@1000,Wirkenergie Bezug (tot),kWh,webt_kwh,3 1,77070100010801ff@1000,Wirkenergie Bezug (T1),kWh,web1_kwh,3 1,77070100010802ff@1000,Wirkenergie Bezug (T2),kWh,web2_kwh,3 1,77070100020800ff@1000,Wirkenergie Lief. (tot),kWh,welt_kwh,3 1,77070100020801ff@1000,Wirkenergie Lief. (T1),kWh,wel1_kwh,3 1,77070100020802ff@1000,Wirkenergie Lief. (T2),kWh,wel2_kwh,3 1,77070100100700ff@1,Momentane Wirkleistung,W,mwl_W,0 ;1,77070100600100ff@#,Geräte ID,,did,0 ;1,7707010060320101@#1x,Herstellerkennung,,vid,0 #
Geräte-ID und Herstellerkennung lese ich nicht aus. Dabei gab es auch noch manchmal Wertesprünge, deshalb auskommentiert.
Und hier das Ergebnis:
Viel Spaß beim Nachbasteln!