Stromzähler (SmartMeter) mit Raspberry Pi auslesen

Das Auslesen meines Stromzählers EasyMeter Q3B war leider eine etwas zähe Geschichte. Eigentlich sollte dieses SmartMeter über die D0-Schnittstelle alle relevanten Daten bereitstellen. Als ersten Versuch habe ich nach Anleitung von Sven Jordan einen Optokoppler nachgebaut. Leider hat das so nicht funktioniert. Ich habe zwar über die serielle Schnittstelle Daten einlesen können, allerdings ohne erkennbare Struktur, schon gar nicht wie in dieser Anleitung dargestellt. Da ich nun nicht wusste, ob es an meinem selbst gebastelten Optokoppler lag, habe ich mir den von EasyMeter empfohlenen optischen Tastkopf OD400 TTL (D0) der Firma Propertools für ca. 50 € gekauft. Leider ist dieser nicht mehr verfügbar. Es gibt aber von EasyMeter neue Empfehlungen. Diese Investition lohnt sich aus meiner Sicht schon deshalb, weil diese OptoKoppler sich mit dem Magneten ganz einfach am EasyMeter in Position bringen lassen:

SmartMeter


Mein zweiter Versuch mit dem OD400 TTL war leider auch nicht auf Anhieb erfolgreich. Ich habe die serielle Schnittstelle über ein Pyton-Script ausgelesen und dabei die Schnittstellen-Parameter wie oben angegeben verwendet (9600/7/even/1). Damit konnte ich jetzt immerhin ASCII-Daten einlesen, die zumindest hin und wieder sinnvolle Informationen zu enthalten schienen. Zum einen kam in unregelmäßigen Abständen ein ESY, an einer Stelle sogar ESY Q3B, und die Zählernummer wurde als Klartext übertragen. Die restlichen Zeichen waren mir aber erst einmal Rätsel.

Laut Betriebanleitung des Q3B wird für die Übertragung über die optischen Datenschnittstelle das SML-Protokoll verwendet wird. Der Datenstrom in hexadezimaler Darstellung ist durch Escape-Merkmale 0x1b1b1b1b gekennzeichnet. Der Beginn der Nachricht wird durch ein solches Escape-Markmal gefolgt von einem Beginn-der-Nachricht-Merkmal 0x01010101 definiert. Am Ende einer Nachricht folgt 0x1a auf ein Escape-Merkmal, also 0x1b1b1b1b1a. Laut Hersteller ist die Einstellung der seriellen Kommunikation 9600/7/even/1 für die Geräte der xxD und xxS-Reihe. Die SML-Zähler (xxB und xxC) senden mit 9600/8/none/1. Also habe ich für meinen Q3B die serielle Schrittstelle entsprechend konfiguriert, und jetzt klappt die Abfrage!

Die Spannungsversorgung des Raspberry Pi im Schaltschrank erfolgt bei mir über ein Hutschienennetzteil DR-1 5-5, 5V MEAN WELL. Dieses liefert direkt die für den Raspberry Pi benötigten 5 VDC und kostet ca. 14 €.


Python-Script

Den Datenstrom der seriellen Schnittstelle interpretiere ich mit einem Python-Script nach folgendem Programmablauf:

  • Serielle Schnittstelle initialisieren
  • Zeichen in einer Schleife einlesen und zu einer hexadezimalen Zeichenfolge zusammensetzen
  • Sobald Beginn-der-Nachricht-Merkmal 1b1b1b1b01010101 einging, alle vorhergehenden Zeichen abschneiden und auf Ende-der-Nachricht-Merkmal 1b1b1b1b1a warten. Damit ist dannn eine Nachricht komplett.
  • Die vollständige erhaltene Nachricht nach OBIS-Kennungen durchsuchen und auswerten.

Im Beispiel meines EasyMeter Q3B kommen über die D0-Schnittstelle fogende Daten nach der jeweiligen Kennzahl:

  • Herstellerkennung (Kennzahl 0x81 81 c7 82 03 ff): 0x45 53 59 = ESY
  • Eigentumsnummer (0x01 00 00 00 00 ff): 0x33 31 33 34 31 32 36 31 33 = 313 412 613 (steht auf dem Zähler, aber nicht auf meinem!)
  • Summenregister Bezug (0x01 00 01 08 00 ff): 0x00 00 00 00 67 54 6f 34 = 1733586740 * 10^-4 Wh = 173358,6740 Wh = 173,3586740 kWh
  • Momentanleistung über alle Phasen (0x01 00 01 07 00 ff): 0x00 00 28 2e = 10286 * 10^-2 W = 102.86 W

Zum Auslesen der D0-Schnittstelle mit einem Raspberry Pi A+ verwende ich folgendes Python-Skript MyHomePower.py, das beim Booten des Raspberry Pi automatisch gestartet wird sudo ./MyHomePower.py &):

Das Python-Skript liest jeden Datensatz des SmartMeters aus. Im Falle des EasyMeter Q3B bekomme ich damit alle zwei Sekunden die aktuellen Werte für Bezug (Wh) und Momentanleistung (W). Zusammen mit dem aktuellen Zeitstempel werden diese beiden aktuellen Werte einerseits in eine XML-Datei /var/www/html/SmartMeter.xml geschrieben (um via HTTP-Anfrage von einem beliebigen Computer im Netzwerk ausgelesen werden zu können). Andererseits werden alle 2-Sekunden-Werte in die Datei output.csv geschrieben, um daraus eine 15-Minuten-Statistik zu berechnen. Das macht aus meiner Sicht Sinn, da der tatsächliche Leistungsbezug auf Basis der 2-Sekunden-Werte sehr stark schwankt und damit wenig aussagekräftig ist.

Über Crontab wird daher alle 15 Minuten das bash-Script analyze.sh aufgerufen, das die Datei output.csv bis auf die letzten 450 Werte (entspricht hier 15 Minuten) abschneidet:

Dann wird das Python-Script analyze.py ausführt, um den minimalen, maximalen und Mittwelwert sowie die Standardabweichung zu erstellen:


Datenübertragung und Visualisierung

Dieses Python-Script ermittelt über den Zeitraum der letzten 15 Minuten den minimalen, mittleren und maximalen Leistungswert sowie die Standardabweichung. Zusammen mit dem aktuellen Zeitstempel werden diese Werte in die XML-Datei /var/www/html/SmartMeter_15minutes.xml geschrieben. Mein zentraler Raspberry Pi fragt diese Werte vom SmartMeter regelmäßig ab und trägt die Werte in eine MySQL-Datenbank ein.

Mit diesen Daten lassen sich dann schöne Diagramme erstellen, zu. Beispiel mit amCharts. Hier als Beispiel der Leistungsverlauf von August bis Dezember: