SML - Protokoll

Auf der Seite Smartmeter D0, SML beschreibe ich, wie ich per Fototransistor und Minimalbeschaltung die D0-Daten eines Stromzählers in mein LAN poste, damit ich diese Daten weiter verarbeiten kann. Auf diese Seite habe ich die Links, Analysen und Ergebnisse zur Auswertung de D0-Protokolls zusammen gefasst.

Übersicht

Das SML-Protokoll ist schon etwas besonderes für einen Windows, Exchange, Consultant. Es ist auf geringe Datenmenge und flexible Inhalte ausgelegt und überträgt Daten binär. Es ist also kein "lesbares" Textformat oder XML oder gar JSON-Datei. Allerdings gibt es eine ausführliche Beschreibung. Das Protokoll wird nämlich nicht nur für Stromzähler genutzt. Damit können auch Werte für Wärmemengen, Gasmengen und andere Stoffe übertragen werden. Insofern dürfte es ganz viele entsprechende Geräte und Auswertungsprogramme geben.

Die Bedeutung der Bits bzw. Bytes ist natürlich einheitlich festgelegt. Allerdings gibt es so viele Besonderheiten, dass ein generischer Parser zu viel verlangt wäre. Ich werde also wohl nur "meinen" Zähler entsprechend aufbereiten". Nach der Startsequenz werden alle weiteren Gruppen mit einem "01 01 01 01" eingeleitet.

Technischen Richtlinie BSI TR-03109-1
https://www.bsi.bund.de/SharedDocs/Downloads/DE/BSI/Publikationen/TechnischeRichtlinien/TR03109/TR-03109-1_Anlage_Feinspezifikation_Drahtgebundene_LMN-Schnittstelle_Teilb.pdf?__blob=publicationFile

Codeliste der OBIS-Kennzahlen und Medien
https://www.bundesnetzagentur.de/DE/Beschlusskammern/BK06/BK6_83_Zug_Mess/835_mitteilungen_datenformate/Mitteilung_30/Anlagen/Codeliste_OBIS.pdf?__blob=publicationFile&v=1

Das Dokument ist sehr umfangreich aber erst mit mehrmaligem Lesen finden Sie die Ergebnisse zusammen. So gibt es eine "TransactionID" from Typ "OctetString". Erst weiter hinten findet sich dann die Beschreibung, dass die niederwertigen 4 Bits des ersten Byte die Länge angeben. Eventuell variiert ihr Zähler die Ausgabe. Daher ist es immer sinnvoll auch nach Unterlagen des Zählerherstellers zu suchen:

Das D0-Protokoll ist angeblich explizit drauf ausgelegt, auch auf kleinen Prozessoren und schwachen Geräten genutzt zu werden. Damit kann ich mir zumindest die Übertragung mit 9600,7,n,1 erklären, die wirklich keinen Empfänger überlasten sollte. Weniger Verständnis habe ich für die sehr binär-lastige Codierung um noch mehr Bandbreite zu sparen. ein "Sprechender Text" wäre einfacher gewesen, wenn man nicht gleich XML nutzen würde. SML über XML ist sogar spezifiziert.

Aber die meisten Stromzähler senden wohl eine "SML-Datei", die eine Gruppe mehrerer SML-Nachrichten beinhaltet. Die erste Nachricht ist dabei eine "Start"-Meldung zu der am Ende die passende "Endemeldung" gehört. Die SML-Datei wird mit einer Zeichenkette eingeleitet und abgeschlossen. Da SML bidirektional ist, gibt es den Typ "Auftrag", "Antwort" und "Komi". Ich stelle mir das so vor:

Der Anfang einer "SML-Datei" der Version 1.0 ist durch "1B 1B 1B 1B 01 01 01 01" gekennzeichnet. Das Ende ist dann "1B 1B 1B 1B 1A XX XX XX". Die anderen Stationen sind dann etwas kniffliger. Ich beschränke mich hier auf das passive Lesen von Stromzählern. Wenn Sie "81 81 C7 C7 xx xx" finden, dann sind das globale Fehlernummern oder Hinweise. An anderer Stelle finden Sie auch oft die Erläuterung anhand von Listen, deren Einträge wiederrum eine Liste ist.

TL-Feld

Eine Besonderheit ist noch die Definition der Feldinhalte. Diese können ja unterschiedlichen Typs (IN8, INT16, UINT8 , UINT16, ByteArray etc.) sein. SML nutzt dazu ein "TL - Type-Length-Value", bei dem das erste Bytes den Typ und die Länge angibt. Ein Auszug dazu:


Auszug aus : TR-03109-1_Anlage_Feinspezifikation_Drahtgebundene_LMN-Schnittstelle_Teilb.pdf Seite 42

Damit finden sich in der Rückgabe meist Werte wie:

  • 52,53,55,59 = Integer 8/16/32/64
    56 Integer
  • 62,63,65,69 = Unsigned Int 8/16/32/64
  • 42 = Boolean
  • 00-0E = Octet mit 0-14 Stellen
    Das Byte selbst zählt mit zur Länge.
  • 7x  List of

Durch diese Besonderheit können Sie sich einfach von Feld zu Feld durchhangeln, da jedes Feld auch immer den TL-Header hat.

OBIS Werte

Ein SML-Datensatz kann auf einen Rutsch gleich mehrere Werte liefert. Für die elektrische Energie gilt der folgende Aufbau

 


Quelle: BDEV http://www.edi-energy.de/files2/OBIS-Kennzahlen-System_2_2d_20151001.pdf  Seite 3 
https://www.bundesnetzagentur.de/DE/Beschlusskammern/BK06/BK6_83_Zug_Mess/835_mitteilungen_datenformate/Mitteilung_30/Anlagen/Codeliste_OBIS.pdf?__blob=publicationFile&v=1  Seite 6

Das ist aber nur der Einstieg. Abgesehen von Trenn-Bytes, Längenbytes Prüfsummern etc. könnte ein einfacher Parser sich erst mal an den Feldern orientieren, die mit "77 01" beginnen. Dies steht im SML-Protokoll für "SML_GetList_Response - ClientID (not set)". Diese werden direkt gefolgt von einer Nummer aus dem "OBIS Kennzahlen System", die ebenfalls aus einer Tabelle des BDEW (Bundesverband der Energie und Wasserwirtschaft e.V." entnommen werden kann. Ich habe daher die ganzen Werte hier aufgetrennt.

So steht die Zeichenkette 77 07 01 00 01 08 01 FF 01 01 62 1E 52 für "Wirk Energie Tarif 1 Bezug  1.8.1" und ergibt sich aus

  • 77 07 SML_GetList_Response - ClientID (not set)".
  • 01 XX Elektrizität
  • 01 XX Kanal 1
  • 01 08 01 FF  Entspricht der OBIS Kennzahl 1.8.0
  • etc.

Einige OBIS-Kennzahlen wie 1.8.0, 1.8.1, 1.8.1, 2.8.0 haben die ein oder andere Zählerableser schon mal gesehen. Definiert sind aber viel mehr.


Quelle: https://www.bundesnetzagentur.de/DE/Beschlusskammern/BK06/BK6_83_Zug_Mess/835_mitteilungen_datenformate/Mitteilung_30/Anlagen/Codeliste_OBIS.pdf?__blob=publicationFile&v=1 Seite 8

Hier können Sie gut ablesen:

1.8.0  = Wirkleistung+ (Bezug)       im Zeitintegral1 und Tarif 0  (Klassischer Strombezug für Licht)
1.8.1  = Wirkleistung+ (Bezug)       im Zeitintegral1 und Tarif 1  (in der Regel Hochtarif bei Wärmepumpen
1.8.2  = Wirkleistung+ (Bezug)       im Zeitintegral1 und Tarif 1  (in der Regel Niedertarif bei Wärmepumpen
2.8.0  = Wirkleistung- (Einspeisung) im Zeitintegral1 und Tarif 0  (Klassischer Strombezug für Licht)

Es gibt aber noch jede Menge andere Werte, die ein System liefern kann aber nicht muss. bei Gaszählern machen solche Werte schon Sinn, Sie sind aber definiert, z.B.

99.41.16 Temperatur [C]
99.42.16 Absolutdruck [bar]

Für elektrische Energie sind natürlich all die Zahlen interessant, die ein Smartmeter erfasst und ihnen auf dem Display anzeigt. Sie müssen dazu nur dien Zähler mit einer Taschenlampe entsprechend "anleuchtet" und mit Blinkimpulsen eine PIN eingeben. Dann liefert der Zähler auch Daten wie aktuelle Energiemenge, Menge der letzten 24h, 7Tage, 1 Monat, 365Tage etc.

 0.0.1 Identifikationsnummer 1.0 ServerId  Seriennummer
 2.6.0  Wirk-Leistungsmaximum Total Lieferung
15.7.0  Wirk-Leistung Total
17.7.0  Blind-Leistung Total Momentanleistung
25.7.0  Strom Total
32.7.0  Spannung Phase 1
52.7.0  Spannung Phase 2
72.7.0  Spannung Phase 3
72.7.0  Netzfrequenz

Zusammenstellung OBIS Kennzahlen
http://www.itrona.ch/stuff/F2-2_PJM_5_Zusammenstellung%20OBIS%20Kennzahlen%20V1.1_30.03.2012.pdf

Nur weil es die Definition gibt, bedeutet das nicht dass alle Zähler alle Daten liefern. Einige liefern im Standard nur die Zählerstände und können in einen "Informationsmode" mittels Taschenlampe umgeschaltet werden

Decodierung

Ich habe versucht eine SML-Meldung meines Zählers manuell zu decodieren. Ganz bin ich noch nicht fertig, aber einen Teil kann man schon sehen. 

Bytes/th> Bedeutung

1B 1B 1B 1B

Escape Sequenz zum Start

01 01 01 01

SML Start

76
07 00 07 06 15 FC E7 62
00
62
00 72 63 01 01

StartSMLMessage un 6 Gruppen kommen
TransactionID mit 7 Stellen
GroupNo 00
abortOnError 

76
01
01 07 00 07 02 E0 
53 CE 0B 09 01
45 4D 48
00 00 48 95 F7 01 01 63 33 AA 00

StartSMLMessage
Länge
TransactionID

"EMH"

76
07 00 07 06 15 FC E8 62
00
62 00
72 63 07 01
77 01
0B 09 01 45 4D 48 00 00
48 95 F7 07 01 00 62 0A FF FF 72 62 01 65 02 E0 0F 29
7A 77 07
81 81
C7 82 03 FF

StartSMLMessage mit 6 Gruppen
TransactionID Länge
GroupNo
abortOnError 
MessageBody
SMLGetList+ClietnID
Seriennummer "EMH" 

SensorTime ?
HerstellerID ?
ServerID ?

01 01 01 01

SML Start 

04
45 4D 48
01
77 07 01 00 00 00 09-FF  


"EMH" 

01 01 01 01  

SML Start 

0B 09 01
45 4D 48
00 00 48 95 F7 01


"EMH" 

77 07 01 00 01 08 00 FF 64 01 02 82
01 62 1E 52 FF 56 00 04 1E D3 E9 01

Wirkenergie Total Bezug
1.8.0*255 

77 07 01 00 02 08 00 FF 64 01 02 82 01
62 1E 52 FF 56 00 00 00 07 28 01 

Wirkenergie Total Lieferung
2.8.0*255

77 07 01 00 01 08 01 FF 01 01 62 1E 52
FF 56 00 02 BE DD 30 01 

Wirk Energie Tarif 1 Bezug 
1.8.1*255

77 07 01 00 02 08 01 FF 01 01 62 1E 52
FF 56 00 00 00 07 28 01

Wirk Energie Tarif 1 Lieferung
2.8.1*255

77 07 01 00 01 08 02 FF 01 01 62 1E 52
FF 56 00 01 5F F6 BA 01

Wirk Energie Tarif 2 Bezug 
1.8.2*255 

77 07 01 00 02 08 02 FF FF 56 00 01 5F
F6 BA 01

Wirk Energie Tarif 2 Lieferung
2.8.1*255 

77 07 01 00 02 08 02 FF 01 01 62 1E 52
FF 56 00 00 00 00 00 01

Wirk Energie Tarif 2 Lieferung
2.8.2*255  

77 07 01 00 10 07 00 FF 01 01 62 1B 52 FF 55 00 00 7F 4D 01  

 

77 07 81 81 C7 82 05 FF 01 72 62 01 65 02 E0 0F 29 01 01 83 

 

02 E2 24 E1 43 E5 3C B3 3F DB 27 51 B7 E1 5C BE EA 2A 2C
E2 A3 28 D3 C5 D8 7C 9D 19 C7 E2 D4 45 45 59 C3 49 62 57

76 AC 88 10 4B 3F

76 61 97 FA 39 01 01 01 63 48 C2 00

76 07 00 07 06 15 FC E9
62 00
62 00
72 63 02 01 71 01 63 E8 35

00
00

Start der Füllbytes um durch 4 teilbare Bytes zu bekommen.
Füllbyte

1B 1B 1B 1B

Escape Sequenz zum Ende

1A 01 AF 56 FC

Prüfsumme

Es dürfte also ganz schön knifflig sein, einen richtigen SML-Parser mal eben schnell zu schreiben. Das ist aber auch gar nicht mein Ziel. Ich möchte ja "nur" Die Zählerstände und ggfls. andere Werte ermitteln, die über ein OBIS-Feld aber klar definiert sind. Eine OBIS-Kennzahl ist aber immer wieder gleich und bei den Zählerständen des EMH immer mit "77 07 01 xx" eingeleitet. Ich denke eine Such nach diesen drei Bytes ist mit 2^24 Wahrscheinlichkeit für mich zielführend genug, um die Werte auszulesen.

Minimal-Parser

Nicht alle Programme sind darauf aus, das komplette SML-Datagramm zu decodieren, die Prüfsumme zu errechnen etc. Wenn Sie nur ein oder zwei Werte auslesen wollen, können Sie sich auf diese Werte stürzen und damit den Code deutlich vereinfachen. Sie starten immer mit einer "77 07" SML_GetList_Response.

+--------------------- 77 07 SML_GetList_Response - ClientID (not set)".
!     +--------------- 01 XX Elektrizität
!     !     +--------- 01 08 Kanal 1.8     02 08= Kanal 2.8
!     !     !        +--- 01 = Wirkleistung
!     !     !        !
77 07 01 00 01 08 00 FF
77 07 01 00 02 08 01 

77 07 81 81 c7 82 03 ff 01 01 01 01 LL x1 x2 x3      OBIS Kennzahl für Hersteller LL = ist Länge, z.B. 4 und x1,x2,x3 dann der Herstellercode
77 07 01 00 00 00 09 ff 01 01 01 01 LL x1 x2 x3      OBIS Kennzahl für Geräte nummer
77 07 01 00 01 08 00 ff xx xx xx xx xx xx xx xx      OBIS Kennzahl für Wirkenergie Bezug gesamt tariflos   1.8.0
77 07 01 00 01 08 01 ff xx xx xx xx xx xx xx xx      OBIS Kennzahl für Wirkenergie Bezug gesamt tariflos   1.8.1
...

Soweit ich gesehen habe, nutzt auch Tasmota den Ansatz. In der Konfiguration wird die Byte-Folge definiert, auf die der Code schauen muss und dann nur noch den Werte zu ermiteln.

>D
>B
=>sensor53 r 
>M 1
+1,14,s,0,9600,Z1
1,770701000F0700FF@1,Aktuell,W,Power_curr,0
1,77070100010801FF@1000,Bezug,kWh,Total_In,2
1,77070100020800FF@1000,Einspeisung,kWh,Total_Out,2
#

Schauen Sie sich mal diese Zeichenkette meines Zählers an:

77 07 01 00 01 08 00 ff 65 00 00 02 80 01 62 1e 52 03 69 00 00 00 00 00 00 0f c3 01

Decodiert ergibt das:

77 07                         GetList response mi 7 Einträgen
01 00                         Elektrizität Kanal
01 08 00 FF                   Kanal (1.8.0. Verbrauch)
65 00 00 02 80                Status des Herstellers
01                            Zeitangabe ohne Wert
62 1E                         Einheit Wh
52 03                         Multiplikator 3=1000, 2=100, 1=10, 0=1, FF = -1
69 00 00 00 00 00 00 0f c3    0FC3hex = 4035dez
01                            Signatur ohne Bedeutung

Und genau die 4035 gibt der SML-Decoder auf (https://tasmota-sml-parser.dicp.net/) auch aus 

0x0100010800ff 1.8.0 Zählerstand Total 4035 Wh 4035000Wh (Zählerstand Total)

Wer mag kann sich ja mal die Decodierung seines kompletten Dumps machen.

Momentanwerte

Auf der Seite Smartmeter D0, SML und PRTG habe ich die Grenzen einer Überwachung von Zählern beschrieben, die nur kWh statt Wh liefern. Die Zahlen sind zu grob, um daraus die aktuelle Energiemenge zu ermitteln. Selbst ein Fön oder Heizlüfter müsste schon 30-60 Minuten bei voller Leistung laufen, ehe der Zähler sich auch nur um eine Stelle erhöht. Wenn ihr Smartmeter ebenfalls solche Daten liefert, dann haben Sie verschiedene Optionen:

  • Smartmeter Umkonfiguration/Tausch
    Das können Sie aber nicht selbst sondern der Netzbetreiber als Inhaber. Die meisten Smartmeter haben auf der Rückseite nämlich noch eine D0-Schnittstelle, die auch Schreiben kann
  • Smartmeter im Information-Mode
    Mittlerweile sollten Sie vom Netzbetreiber problemlos die Pin und eine Anleitung bekommen, um den Smartmeter in einen erweiterten Betrieb zu bringen. Hier zeigt er dann z.B. im Display deutlich mehr, z.B.: den Momentan-Verbrauch, an. Vielleicht liefert der Smartmeter diese dann auch an die D0-Schnittstelle
  • Eigener Zwischenzähler
    Das ist in vielen Fällen sogar der Regelfall, wen Sie einen Batteriespeicher mit der Solaranlage koppeln. Damit sind sie unabhängig vom Smartmeter, welcher ja auch immer mal wieder getauscht wird.
  • Blink-LED anzapfen
    Die meisten Zähler haben auch immer noch die klassische LED, die einmal pro Wh oder 0,1Wh blinkt. Die könnte man auch einfach Auslesen und die Impulse pro Zeiteinheit oder die Abstände zwischen den Impulsen zählen um so den Momentanverbrauch zu ermitteln. Das hilft aber nicht viel bei Zweirichtungszählern.

Mein Smartmeter zeigt im Information-Mode viele Details an uns meldet noch mehr per SML. Leider kann aber Tasmota dann damit den Daten erst einmal nichts anfangen. Das ist also etwas für die nächste Ferienzeit.

Weitere Links

Über zwei Datenschnittstellen (Kunden- und MSB-Schnittstelle) werden mittels SML-Protokoll (Smart Message Language) Zählerdaten übertragen.
Quelle: http://www.emh-metering.com/de/produkte/ehz-i/