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:

Wie man unschwer erkennt habe ich private Daten anonymisiert. Lacht nicht! :-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:

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 ;-) ) 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. :-)

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. :-)

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

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.

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:

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

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. :-D