Quantcast
Viewing all articles
Browse latest Browse all 87

Smart Message Language — Stromzähler auslesen

Image may be NSFW.
Clik here to view.
Die Augen des Stromzählers

Die Augen des Stromzählers

Gestern habe ich mich mal intensiv mit meinem Stromzähler auseinander gesetzt. Das ist ein ziemlich neumodisches Gerät, ein Iskra MT175. Dieses Modell verfügt über eine Infrarotschnittstelle (nach DIN EN 62056-21) mit der die Zählerstände ausgelesen werden, und das muss natürlich ausprobiert werden.

Zu dem Zweck habe ich mir eine Hardware gebastelt die die Daten auslesen kann. Dazu später mehr, in einem anderen Beitrag. Mein Zähler überträgt etwa alle zwei Sekunden einen Datensatz. Automatisch, ohne dass ich ihn darum bitten müsste. Wenn ich den auslese erhalte ich einen formschönen Haufen Hex-Code, ähnlich diesem:

1B 1B 1B 1B 01 01 01 01 76 05 01 D3 D7 BA 62 00 62 00 72 63 01 01 76 01 01 05
00 9B F2 94 0B xx xx xx xx xx xx xx xx xx xx 01 01 63 B3 78 00 76 05 01 D3 D7
BB 62 00 62 00 72 63 07 01 77 01 0B xx xx xx xx xx xx xx xx xx xx 07 01 00 62
0A FF FF 72 62 01 65 01 8A 4D 15 77 77 07 81 81 C7 82 03 FF 01 01 01 01 04 49
53 4B 01 77 07 01 00 00 00 09 FF 01 01 01 01 0B xx xx xx xx xx xx xx xx xx xx
01 77 07 01 00 01 08 00 FF 65 00 00 01 82 01 62 1E 52 FF 59 xx xx xx xx xx xx
xx xx 01 77 07 01 00 01 08 01 FF 01 01 62 1E 52 FF 59 xx xx xx xx xx xx xx xx
01 77 07 01 00 01 08 02 FF 01 01 62 1E 52 FF 59 xx xx xx xx xx xx xx xx 01 77
07 01 00 10 07 00 FF 01 01 62 1B 52 00 55 xx xx xx xx 01 77 07 81 81 C7 82 05
FF 01 01 01 01 83 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx
xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx
xx xx xx 01 01 01 63 C6 12 00 76 05 01 D3 D7 BC 62 00 62 00 72 63 02 01 71 01
63 EE 1A 00 1B 1B 1B 1B 1A 00 F3 C7

Wie man unschwer erkennt habe ich private Daten anonymisiert. Lacht nicht! Image may be NSFW.
Clik here to view.
:-D

Nachdem ich da längere Zeit mit verbracht habe weiß ich mittlerweile ziemlich genau was da steht. Und damit andere einen besseren Einstieg finden schreibe ich das mal hier auf.

Die Sprache nennt sich Smart Message Language (SML). Es gibt auch Zähler die die Daten in anderen Formaten, oder direkt im ASCII-Format ausgeben. SML ist aber ein Standard, und wird von vielen Herstellern genutzt. Wie das funktioniert kann man zum Beispiel in der Technischen Richtlinie BSI TR-03109-1 beim Bundesamt für Sicherheit in der Informationstechnik nachlesen. Wenn man das tut kann man den Datensatz da oben tatsächlich lesbar machen:

1B 1B 1B 1B                                     -- Start Escape
01 01 01 01                                     -- Start Übertragung Version 1

Die ersten vier Bytes sind einfach eine Markierung für den Anfang der Übertragung, in der zweiten Zeile steht dass wir Version 1 des Protokolls lesen.

Als nächstes müssen wir ein wichtiges Konzept verstehen. Das erste Byte der folgenden Nachricht lautet ’76’. Man muss das als Nibbles sehen, und bei Hex-Zahlen bedeutet das Ziffer für Ziffer. Das erste Nibble ‘7’ können wir auf Seite 42 (natürlich Image may be NSFW.
Clik here to view.
;-)
) des oben verlinkten Dokumentes nachschlagen. Da steht eine Tabelle mit einer Zeile ‘X111LLLL’. Jetzt matcht das binäre ‘X111’ auf das erste Nibble, also haben wir es hier mit einer Liste zu tun. Das zweite Nibble gibt die Länge an, wir erwarten also eine Liste mit 6 Elementen.

Das erste Byte der folgenden Zeilen ist jeweils nach dem gleichen Schema aufgebaut. In der Regel steht das erste Nibble für den Datentypen, das zweite für die Länge — merkwürdigerweise bei einfachen Datentypen die Länge inclusive dieses Längen-Bytes. Datentyp 0 in Zeile 4 ist laut Seite 42 ein Octet String. Die 5 sagt dass dieser Teil einschliesslich der Längenangabe 5 Bytes umfasst, wir erwarten nach der Länge also noch vier Bytes. Auf Seite 17 des Dokumentes steht dass hier eine Transaktions-ID kommen muss.

Nachdem das Prinzip klar sein sollte werde ich nicht mehr alles haarklein entschlüsseln. Das heisst: ich habe schon. Aber an dieser Stelle überlasse ich das mal dem geneigten Leser. Image may be NSFW.
Clik here to view.
:-)

76                                              -- SML Message mit 6 Elementen
   05 01 D3 D7 BA                               -- transactionId
   62 00                                        -- groupNo
   62 00                                        -- abortOnError
   72                                           -- messageBody
      63 01 01                                  -- getOpenResponse
      76                                        -- Liste mit 6 Elementen
         01                                     -- codepage / optional
         01                                     -- client id / optional
         05 00 9B F2 94                         -- reqFileId
         0B xx xx xx xx xx xx xx xx xx xx       -- server Id
         01                                     -- refTime / optional
         01                                     -- smlVersion / optional
   63 B3 78                                     -- CRC
   00                                           -- End of SML message

Man sieht durch die Einrückung ziemlich deutlich dass man sich den Datensatz gut als Liste von Listen vorstellen kann. Außen wird eine Liste mit sechs Elementen angekündigt (76), darin stehen ein Octet String (beginnt mit 0, Zeile 4), zwei Unsigned Integer (6, Zeilen 5 und 6), eine weitere Liste mit zwei Elementen (72, Zeile 7), ein weiterer Unsigned Integer (6, Zeile 16) mit der Prüfsumme und eine Markierung für das Ende der Nachricht (00, Zeile 17). Die Liste mit den zwei Elementen enthält wiederum einen Unsigned Integer (6, Zeile 8 ) und eine Liste mit sechs Elementen (76, Zeile 9). Die meisten dieser sechs Elemente sind Octet Strings die samt des Längen-Bytes eine Länge von 1 haben (01), also leere Strings. Ein String (Zeile 12) enthält eine File-ID, einer (Zeile 13) die Server-ID. Letztere kann man auch direkt auf dem Gerät lesen, die ist aufgedruckt. Beruhigend. Image may be NSFW.
Clik here to view.
:-)

Jetzt wird es ernst: eine weitere Liste mit sechs Elementen (76), die ersten Zeilen entsprechen dem Block oben:

76
   05 01 D3 D7 BB
   62 00
   62 00
   72
      63 07 01                                  -- getListResponse
      77
         01                                     -- clientId / optional
         0B xx xx xx xx xx xx xx xx xx xx       -- serverId
         07 01 00 62 0A FF FF                   -- listName / optional
         72                                     -- actSensorTime / optional
            62 01                               -- choice: secIndex
            65 01 8A 4D 15                      -- secIndex (uptime)

Enthalten ist eine Liste mit zwei Elementen (72, Zeile 22). Der erste Octet String (Zeile 23) gibt den Typ der Nachricht an, es ist ein getListResponse. Der wiederum besteht auf sieben Elementen (77, Zeile 24). Interessant ist hier vielleicht das vierte Element (72, Zeile 28. An dieser Stelle soll die aktuelle Zeit stehen, und die kann auf verschiedene Weise angegeben werden. Erklärt ist das auf Seite 22 des BSI-Dokumentes, dementsprechend haben wir es hier durch die 01 in Zeile 29 mit einem secIndex zu tun. In Zeile 30 folgt dann der Wert. Die Zahl 0x018A4D15 entspricht in etwa der Zeit die das Gerät hier eingebaut ist, das wird also eine Art Betriebsstundenzähler sein.

Die Liste die in Zeile 31 startet ist das fünfte Element der Liste aus Zeile 24. Und hier kommt der wirklich spannende Teil: die Messdaten. Naja, und ein paar Meta-Daten. Erst das Kürzel des Herstellers Iskra (ASCII-Codes in Zeile 38), dann nochmal die bereits bekannte Server ID. Die nächsten drei Elemente enthalten die verbrauchte Energie (die Kilowattstunden), sowohl als Summe als auch aufgesplittet in zwei Tarife — wenn man denn zwei Tarife hat.

Hier kommen wir übrigens zu einem Teil den ich noch nicht verstanden habe: in Zeile 50 wird ein Status angegeben. Wenn mir jemand sagen kann was der bedeutet: immer her damit! 0x0182 ist dezimal 386, darauf kann ich mir keinen Reim machen.

Die Energiewerte muss man übrigens durch 10.000 teilen um auf die kWh zu kommen die am Gerät angezeigt werden.

In Zeile 78 steht die aktuelle Leistung, also wie viel Watt tatsächlich in diesem Moment verbraucht werden. In Zeile 86 folgt ein ‘public key’. Der steht auch auf dem Gerät, ich nehme an der ist relevant wenn der Zähler wirklich ‘nach Hause telefoniert’. Die SML-Kommunikation funktioniert nämlich nicht nur über die Infrarot-Schnittstelle, sondern bei Bedarf auch über die Stromleitung. So kann der Anbieter Verbrauchswerte ablesen ohne dass dafür jemand zu Besuch kommen muss.

Die beiden Werte in Zeile 88 und 89 sind optional und vervollständigen so die Liste die in Zeile 24 begonnen wurde.

77                                     -- valList
            77                                  -- SML_ListEntry
               07 81 81 C7 82 03 FF             -- objName
               01                               -- status / optional
               01                               -- valTime / optional
               01                               -- unit / optional
               01                               -- scaler / optional
               04 49 53 4B                      -- value -- Herstelleridentifikation (ISK)
               01                               -- valueSignature / optional
            77
               07 01 00 00 00 09 FF
               01
               01
               01
               01
               0B xx xx xx xx xx xx xx xx xx xx -- Server ID
               01
            77
               07 01 00 01 08 00 FF
               65 00 00 01 82
               01
               62 1E
               52 FF
               59 xx xx xx xx xx xx xx xx       -- Gesamtverbrauch
               01
            77
               07 01 00 01 08 01 FF
               01
               01
               62 1E
               52 FF
               59 xx xx xx xx xx xx xx xx       -- Verbrauch Tarif 1
               01
            77
               07 01 00 01 08 02 FF
               01
               01
               62 1E
               52 FF
               59 xx xx xx xx xx xx xx xx       -- Verbrauch Tarif 2
               01
            77
               07 01 00 10 07 00 FF
               01
               01
               62 1B
               52 00
               55 xx xx xx xx                   -- Wirkleistung total
               01
            77
               07 81 81 C7 82 05 FF
               01
               01
               01
               01
               83 02 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx -- public key
               01
         01                                     -- listSignature / optional
         01                                     -- actGatewayTime / optional

Oh, noch ein interessanter Punkt zu Zeile 86: das Nibble ‘8’ ist eigenlich eine 0, also wieder ein Octet String. Da aber das Most Significant Bit gesetzt ist wird daraus eine 8, und das bedeutet dass die Länge der folgenden Daten nicht nur durch das zweite Nibble — die 3 — angegeben wird, sondern zusätzlich durch das folgende Byte. Nützlich, denn mit nur einem Nibble könnte man maximal 15 Bytes ankündigen (nachdem eines für die Länge draufgegangen ist). So kommen wir auf 0x32 == 50 Bytes. Ausreichend also für 48 Bytes Public Key und zwei Bytes Längenangabe.

Es folgen noch eine Prüfsumme und das förmliche Ende der zweiten Nachricht:

63 C6 12                                  -- crc
      00                                        -- end of message

Die dritte Nachricht ist einfach nur da um das Ende der Übertragung anzukündigen.

76
   05 01 D3 D7 BC
   62 00
   62 00
   72
      63 02 01                                  -- getCloseResponse
      71
         01
   63 EE 1A                                     -- crc
   00                                           -- end of message
1B 1B 1B 1B                                     -- end escape
1A 00 F3 C7

Zu guter Letzt folgt in Zeile 102 nochmal die vom Anfang bekannte Escape-Sequenz, dann 1A um wirklich die Nachricht abzuschließen und nochmal drei Bytes für eine Prüfsumme.

Jetzt noch was in eigener Sache: viele Blogs schließen ihre Artikel grundsätzlich mit einer Frage an die Leser, um Kommentare zu fischen. Ich finde das penetrant, und mache das in der Regel nicht. Aber nach diesem furztrockenen (!) Artikel erlaube ich mir das ausnahmsweise mal: bitte ein Handzeichen von allen die bis hier durchgehalten haben! Muss kein Lob sein, ein Hallo Welt genügt. Image may be NSFW.
Clik here to view.
:-D


Viewing all articles
Browse latest Browse all 87