Smart Meter-Datenkabel selbst gemacht: libehz


Hinweis 13.06.2011: Die in diesem Artikel beschriebene Schaltung funktioniert sehr gut mit Zählern von Hager. Andere Zähler (z.B. der Fa. Easymeter) liefern jedoch nur ein sehr schwaches Signal, sodass die Schaltung hier versagt. Dominik Keller, einer meiner Studenten, arbeitet an einer verbesserten Schaltung. Seinen aktuellen Zwischenstand hat er hier dokumentiert: Optoreader im mySmartGrid Developer Wiki. Wir werden — sobald die Schaltung fertig gestellt ist — einen Bausatz anbieten.

Mit Smart Metern sollen Stromkunden Ihren Stromverbrauch genauer kontrollieren können. Aber: Wer geht schon regelmäßig in den Keller, um seinen Stromzähler abzulesen? Der elektronische Haushaltszähler (eHZ), in Deutschland durch den VDE definiert und bei diversen Herstellern zu beziehen, schreibt eine Infrarotschnittstelle für den Stromkunden vor. Dort sollen beliebige Geräte den Momentanverbrauch, den Zählerstand und andere Informationen auslesen können.

Das Problem dabei: Die optischen Ausleseköpfe (z.B. von PE Technik) sind ziemlich teuer, die Preise für einzelne Geräte schwanken zwischen 100 und 300 Euro. Für eine simple serielle Schnittstelle ein stolzer Preis!

Also: Selbst ist der Mann. Meine ersten Experimente mit einem TSOP-1738 scheiterten. Dieser Standardbaustein empfängt Infrarotsignale im Bereich 880nm und wird normalerweise in Infrarotfernbedienungen eingesetzt. Dafür ist er auch optimiert: Ein integrierter Bandpass filtert eingehende Signale. Dazu erwartet der Baustein alle Signale aufmoduliert auf einen Träger von 38kHz — normalerweise um Sonnenstrahlen von "echten" Fernbedienungssignalen zu unterscheiden. Ich konnte damit zwar Signale im Oszilloskop sehen, aber diese waren im Wesentlichen Binärabfall. Also: 880nm scheint zu funktionieren, der TSOP-1738 kann allerdings nur bis zu 2400 Baud übertragen. Der von mir verwendete eHZ von Hager sendet laut Datenblatt aber mit 9600 Baud. Der Binärabfall kommt also durch eine zu geringe Samplingrate zustande.

DIY-Empfänger

Mit einer Infrarotdiode vom Typ BPW82 funktioniert der Empfang allerdings prima. Im Oszilloskop erkennt man, das die Diode in Kombination mit einem Spannungsteiler ein Signal mit ca. 0.7V zwischen logisch LOW und HIGH ausgibt. Das Signal ist die obere, gelbe Linie in folgendem Screenshot:

Das reicht leider noch nicht aus, um via TTL-USB-Konverter ausgelesen zu werden. In einer nächtlichen Hackaktion mit eBrnd und ‘ (vielen Dank an die Beiden!) entstand die folgende Transistorschaltung:

Damit wird der Pegel auf ein akzeptables Niveau gebracht und zudem noch das Signal geschärft. Im Oszilloskop-Screenshot oben ist die untere, grüne Linie das aufbereitete Signal. Auf Lochraster aufgebaut sieht die Schaltung (ohne TTL-USB-Adapter) so aus:

Rechts erkennt man die Infrarotdiode, eingebettet in ein Stück Schaumstoff und professionell festgeklebt™. Der Schaumstoff hält die Diode an der richtigen Stelle direkt über der Sendediode des eHZ. Gleichzeitig wird Infrarotlicht aus der Umgebung abgeschirmt. Ich hatte bis jetzt keine Probleme mit Umgebungslicht.

Die Daten

Mit einem USB-TTL-Adapter kann man sich nun den Klartext in einer Terminal anschauen. Ich verwende dafür einen Kermit mit folgenden Einstellungen (in der .kermrc, 9600 7N1):

 SET LINE /dev/cu.SLAB_USBtoUART
 SET SPEED 9600
 SET COMMAND BYTESIZE 7
 SET PARITY NONE
 SET STOP 1
 SET CARRIER-WATCH OFF

Der eHZ gibt die folgenden Werte alle 1-4 Sekunden (abhängig von der Last am Zähler) aus:

 /HAG5eHZ010C_EHZ1vA02
 
 1-0:0.0.0*255(1095100000067865)
 1-0:1.8.0*255(000001.2963)
 1-0:96.5.5*255(82)
 0-0:96.1.255*255(0000067865)
 1-0:52.7.0*255(228.38*V)
 1-0:51.7.0*255(000.16*A)
 1-0:41.7.0*255(+00026*W)
 1-0:96.50.0*0(45)
 1-0:96.50.0*1(07D0)
 1-0:96.50.0*2(16)
 1-0:96.50.0*3(11)
 1-0:96.50.0*4(1F)
 1-0:96.50.0*5(18)
 1-0:96.50.0*6(003D381B070AF6B0CF05140900009F80)
 1-0:96.50.0*7(00)
 !

Die Daten sind jeweils mit einer OBIS-Kennzahl versehen. Die Wirkleistung auf L2 hat z.B. die Kennzahl „1-0:41.7.0” und den Wert 26W. Nun fehlt noch eine kleine C++-Applikation, welche die Datagramme auswertet und sauber zugänglich macht.

C++-Client für den eHZ

Einen minimalen Client in C++ gibt es nun schon einmal im Repository auf Github.. Im Moment funktioniert der Client auf meinem Mac, allerdings sollte er auf jeder Plattform mit termios-Support laufen (also auch Linux). Mit einem einfachen

 ehzread /dev/cu.SLAB_USBtoUART

gibt der Client die Datagramme des eHZ auf der Konsole aus. Der Sourcecode ist recht simpel. Im Wesentlichen wird ein Filedesktriptor (tty_fd) an das Terminal-Device gebunden:

 // 7n1, see termios.h for more information
 memset(&tio,0,sizeof(tio));
 tio.c_iflag=0;
 tio.c_oflag=0;
 tio.c_cflag=CS7|CREAD|CLOCAL;           
 tio.c_lflag=0;
 tio.c_cc[VMIN]=1;
 tio.c_cc[VTIME]=5;
 
 tty_fd=open(argv[1], O_RDWR | O_NONBLOCK);      
 cfsetospeed(&tio,B9600);            // 9600 baud
 cfsetispeed(&tio,B9600);            // 9600 baud

In einer Endlosschleife liest der Client dann von tty_fd und gibt die Zeichen auf der Konsole aus. Hier kann dann ein Parser ansetzen.

Hilfreiche Ressourcen

Comments


Mathias Dalheimer

Yours truly.

likes distributed & embedded systems

GPG key: B6501625
fingerprint: E7BA B68E A2D3 9B6A ECEF 4DE4 823E 0DBE B650 1625
github | twitter | flickr