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

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ärlastige 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.

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

Parsen

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 XX Gemessener Wert (1= Summe Wirkleistung+, 2= Wirkleistung-, 3 = Blindleistung+ etc.
  • 01 Max, Aktuell
  • xx 62 Tarifstufe
  • xx 52 Vorwertzählerstand


Quelle: BDEV http://www.edi-energy.de/files2/OBIS-Kennzahlen-System_2_2d_20151001.pdf  Seite 3 

Der Zähler hat natürlich noch einige weitere Daten geliefert. Ich habe mich mal daran versucht die Daten zu decodieren, was mit aber noch nicht komplett gelungen ist.

Diese Beschreibung ist noch nicht komplett.

Bytes 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.

Ich wollte sowieso auf dem Aufnahmegerät nur eine minimale Logik implementieren.

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/