Smartmeter D0, SML

Leider hat mein Energieversorger den Zähler schon wieder gegen ein anderes Modell (MT681) getauscht.
Auch den sollte man aber auslesen können. Siehe https://wiki.volkszaehler.org/hardware/channels/meters/power/edl-ehz/iskraemeco_mt681

Ich bin nicht sicher, ob ich mein Projekt noch weiter entwickle, denn seit meinen Anfängen im Jahr 2014 hat sich viel getan und vor allem habe Projekte wie Tasmota und andere Maker mittlerweile Lösungen fertig. Links finden sie in der Seite.

Ein "Stromzähler" der per "Blinkimpulse" anzeigt wie viel Energie gerade verbraucht wird, ist relativ einfach auszulesen. Eine passende Seite dazu habe ich auf Arduino und S0 schon veröffentlicht. Interessant wird es nun natürlich in Verbindung mit den "neuen" Zählern, die neben einer "blinkenden" LED auch noch einen Datenausgang haben.

Übersicht

Durch den Einzug in ein neues Haus mit Zweirichtungszähler (Solarzellen) und zudem einem Zweitarifzähler (Wärmepumpenstrom) habe ich nun zwei Zähler, die nicht mehr "sichtbar" Blinken (IR-LEDs) sondern auch noch die erweiterte "D0-Schnittstelle" haben. Diese Seite beschreibt meine Schritte diese Schnittstelle per Ethernet erreichbar zu machen bzw. zur Weiterverarbeitung zu geben. Ich würde einfach gerne nicht nur einmal am Jahresende den Gesamtverbrauch ablesen sondern genauer über Verbrauch und Einspeisung Buch führen zu können. Und letztlich macht Basteln auch Spaß. So könnte die Umgebung aussehen.

Ein IR-Lesekopf nimmt die periodisch gesendeten SML-Daten auf dem Zähle ab und sendet diese nach einer Verarbeitung weiter. Zuerst denke ich an einen PRTG-Push-Sensor, da ich den Server schon betreibe. Denkbar wäre auch ein MQTT-Backend um die Daten anderweitig abzugreifen. Sie können gerne meine Ideen, Informationen und Codeteile für eigene Projekte verwenden. Ich würde mich freuen, wenn Sie ihrerseits dann die Informationen ebenfalls veröffentlichen und mit den Link dahin mitteilen.

Moderne Zähler und D0

Die modernen Zähler sind mittlerweile kleine Computer, wie ein Blick in die Beschreibungen der Hersteller zeigen. Mein Zähler ist wohl von ein "EHZ-K" oder EHZ-P von EMH (http://www.emh-metering.com/de/produkte/ehz-i/)


Quelle: Produkthandbuch http://www.nzr.de/download.php?id=612

Da ich nicht genau weiß, wie die Zähler noch kommunizieren können oder vielleicht aus der Ferne beeinflussbar sind, habe ich die Seriennummern, Server-ID, Public-Key etc. Unkenntlich gemacht. Interessant sind auf dem Zähler oben die grüne Öffnung, hinter der sich wohl eine IR-LED verbirgt, die bei diesem Zähler 10.000 Impulse pro kWh liefert, zumindest steht dies so auf dem Zähler. Auf dem LCD kann man sehr einfach unterschiedliche Werte ablesen. Links oben steht dazu ein Zahlencode, der die Bedeutung festlegt. Ich habe in meinem Haus allerdings zwei diese Zähler. Einer für den normalen "Gebrauchsstrom" für Licht, über den aber auch die Solaranlage (Siehe PRTG Kostal) angeschlossen ist und Strom einspeist (abzüglich dem Eigenverbrauch). Der zweite Zähler bedient die Wärmepumpe mit aktuell noch "günstigerem" Wärmepumpenstrom.

Code  Zwei Richtungszähler Zweittarifzähler

1.8.0

Strombezug Haupttarif

nicht vorhanden

1.8.1

nicht vorhanden

Strombezug Tarif 1 (Haupttarif)

1.8.2

nicht vorhanden

Strombezug Tarif 2 (Niedertarif)

2.8.0

Eingespeister Strom

0

Beim Zweirichtungszähler gibt es noch eine "A+"-Anzeige, wenn man Strom bezieht und "A-", wenn man Strom einspeist.

Interessanter sind rechts die beiden Öffnungen mit der Metallplatte. So können über einen Magnet als Halter sehr einfach eine IR-LED und ein IR-Fototransistor montiert werden, die mit dem Zähler kommunizieren. Ich will dabei gar nichts an den Zähler senden. Aber der Zähler soll laut Beschreibung alle 1-4 Sekunden eigenständig ein Datenprotokoll ausgeben. Das ist durchaus interessanter als nur "Impulse zählen.

Man kann aber auch mit einer einfachen Taschenlampe den Zähler "anblinken" und so folgende Funktionen abrufen:

Realer Irrsinn: Neue digitale Stromzähler | extra 3 | NDR
https://www.youtube.com/watch?v=aqHauk3bNFA

Anzahl der Blinken  Ausgabe im Display Beschreibung

1

 

Displaytest für beide Zeilen

2

PIN

Eingabe der PIN 

3

P

Aktuelle Leistung

4

E

Stromverbrauch seit der letzten Null-Stellung

5

1d

Stromverbrauch des letzten Tages

6

7d

Stromverbrauch der letzten 7 Tages

7

30d

Stromverbrauch der letzten 30 Tage

8

365d

Stromverbrauch der letzten 365 Tage 

9

0.2.2

Aktivierung der PIN-Eingabe

Einige der Werte können Sie durch ein langes Anleuchten (>5 Sek) auf 0 setzen.

Köpfe für D0

Und so ist es auch kein Wunder, wenn es verschiedene fertige Zählerköpfe und Selbstbaulösungen gibt. Die Zähler senden ihre Datentelegramme nämlich relativ überschaubar mit 9600,8,n.1 als Bytes. Die fertigen Köpfe kosten aber meist deutlich mehr, als der geübte Elektronikbastler ausgeben will. 100-300€ sind einfach zu viel für eine IR-LED mit eventuell einen Schnittstellenwandler, insbesondere wenn man nur Lesen will. Hier dennoch ein paar Links zu verschiedenen Ansätzen:

D0 am meinem Stromzähler?

Mechanisch wird so ein Fototransistor am besten per Ring-Magnet befestigt. Das Verfahren nutzen kommerzielle Zählerköpfe und die Metallplatte am Zähler legt auch genau das Verfahren nahe. Die Fläche ist bei meinem Energiezähler ca. 28mm breit und die beiden LEDs haben einen Abstand von etwas über 6mm.

 

Da ich allerdings gar nicht schreiben oder steuern möchte, sondern einfach nur "passiv" lesen, recht mir eine LED, die halbwegs passend über die Sende-LED gesetzt wird. Relevant für das Datenprotokoll ist die rechte LED. Die mittlere LED ist zum Steuern und die ganz Links mit "IR" bezeichnete LED sendet 10.000 Impulse/kWh. Insofern bin ich sehr flexibel was die Anordnung betrifft. Es dürfte ein einfacher Ringmagnet reichen, in den der Empfänger eingebaut wird. Um sichtbares Licht auszusperren, würde ich eine kleine schwarze Filzschicht dazwischen setzen. Zwei Magnete habe ich dazu verwendet.

Alle 1-4 Sek sendet der Zähler hier mit 9600 Baud ein Telegramm nach SML-Standard. Ein Telegramm ist maximal 400ms lang. Allerdings steht im Produkthandbuch auch, dass diese Schnittstelle per Konfiguration freigegeben werden kann. Eventuell hat ihr Netzbetreiber die Schnittstelle deaktiviert. Einen ersten Test können Sie mit einer normalen Digitalkamera machen. Die meisten nehmen auch IR-Licht auf, welches vom Auge nicht gesehen wird.

 

So können Sie aber gut kontrollieren, ob die LED sendet. Interessanterweise sehe ich aber an der linken LED keine Impulse. Damit sind aber die Grundlagen vorhanden die Daten abzufragen.

Signalaufbereitung

Ich habe noch nicht das basteln angefangen, aber vielleicht starte ich mit einer BPW40, die an einen analogen Eingang beim Lichteinfall auf "Masse" zieht und dann die Daten eingelesen werden. Aber mit 9600Bit/Sek, also ca. 10000/Sek ist ein Bit ca. 100μs lang. Der Aufnehmer sollte also deutlich flotter sein. Ich bin aber noch nicht sicher, ob ich die Daten dann wirklich über einen Schmitt-Trigger auf den RxD-Anschluss des Arduino leite oder die Daten am Analogport einfach direkt selbst einlese. Wenn ein ESP8266 unter 5€ kostet, dann möchte ich nicht wirklich noch mal 50+€ allein für einen Lesekopf ausgeben. Das muss einfacher gehen. Also habe ich etwas rumgestöbert und diverse Schaltungen gefunden, bei denen ein Fototransistor direkt einen Pin eines Mikroprozessors auf Masse zieht. Vielleicht reicht das ja schon aus:

Wenn der Mikroprozessor sogar über einen internen Pullup-Widerstand verfügt, könnte es noch einfacher gehen. Allerdings muss man sich immer bewusst sein, dass man sich hier ein Stück weit in der Analogtechnik bewegt und man nicht mit TTL-Pegeln zwischen 1 und 0 unterscheiden kann. Lange Leitungen mit Kapazitäten, Fremdlicht etc. sind nicht zu unterschätzen.

Nach etwas Recherche in diversen Foren und um das Wissen der Wellenlänge habe ich einfach mal ein paar Foto-Transistoren vom Typ SP201 bestellt. Fototransistoren sollten es schon sein, da sie in der Regel schnell der Fotodioden und viel schneller als LDRs sind. Die SP201 haben folgende relevante Daten:

Parameter  Daten Bemerkung

Bauform

NPN-Fototransistor in LED-Bauform 

LED-Form mit 3mm Durchmesser passen gut in Rundmagnete und Gehäuse und sind einfacher zu Handhaben als SMD-Bauteile.

Wellenlänge für max. Empfindlichkeit

780nm

Ideal für IR-Signale und hoffentlich gut genug unempfindlich gegen normales Licht.

Kollektor-Emitter-Spannung 

max. 32 V

Das ist unkritisch, da wir uns im 3,3 Volt oder 5Volt-Bereich bewegen

Gesamtverlustleistung

max. 50 mW

Das hilft für die Ermittlung des minimalen Vorwiderstandes. Bei 5V ergibt sich nach (U*I=P oder U/P=I) mit 0.05W/5V = 0,01A. Der strombegrenzende Widerstand bei 5V muss nach U/I=R mindestens 500Ohm betragen.

Anstiegszeit / Abfallzeit

je 5 Mikrosekunden

Die Daten kommen mit 9600 Baud, aufgerundet also 10.000Hz oder 0,1ms/Bit. 100Microsekunden ist ein Bit lang. Da sollten 5 Mikrosekunden an den Flanken genug Reserven bieten.

Preis 

0,25 Euro

(z.B. Pollin  https://www.pollin.de/shop/dt/Mjk5ODc4OTk-/Bauelemente_Bauteile/Aktive_Bauelemente/Optoelektronik/Fototransistor_SP201.html
Datenblatt: https://www.pollin.de/shop/downloads/D121007D.PDF

Den ersten Test habe ich mit der SP201 und einem RS232/USB-Adapter erfolgreich gemacht. Allerdings hat, warum auch immer, dieser Fototransistor nicht mit einem WeMos-Modul funktioniert. Dort habe ich eine BPW40 erfolgreich verwendet.

Herr Rüttgers hat eine eigene Firmware "SMLReader" auf https://github.com/mruettgers/SMLReader veröffentlicht, die zum Anschluss die gleiche Diode und Beschaltung verwendet.

Im Datenblatt ist sichtbar, dass die Anschlussleitung des Emitter etwas kürzer ist also des Kollektors. Das was bei mir nicht der Fall. Eine Abflachung einer Seite des Gehäuse konnte ich auch nicht erkennen. Aber anhand der einen und zwei Nasen am Anschlussdraht konnte ich Kollektor und Emitter ermitteln:

Für einen ersten Test habe ich einfach mal einen USB/RS232-Adapter mit TTL-Pegel genutzt. Diese "billigst"-Adapter haben vier Anschlusskabel für Vcc, GND, RxD und RxD und gibt es bei E-Bay für unter 2€. Senden möchte ich nichts, also könnte es sogar reichen, wenn ein passender Fototransistor oder eine Fotodiode wie oben im Bild die RxD-Leitung bei Licht auf Masse zieht. Der "Ruhezustand" von RxD ist -12V (RS232) oder +5V (TTL). Das ist so gewählt, dass im Ruhezustand schon erkannt werden kann, ob die Leitung "passt" und sehr sparsame Gerät können sich so sogar parasitär mit Strom versorgen.

Als Vorwiderstand habe ich einen 10kOhm Potentiometer genutzt. So ausgestattet bin ich mit einem Terminal-Programm und dem Kabel zum Stromzähler gelaufen und habe die LED einfach mal "drangehalten". Ich war selbst verwundert, das es auf Abhieb geklappt hat.

Anscheinend hat der 10kOhm Vorwiederstand mit dem Serial/USB-Chip und dem Fototransistor genau ausgereicht, Daten zu bekommen. Aus den ersten Blick mögen die Daten "komisch" aussehen, aber das mehrfache Auftauchen des String "EMH", welches der Hersteller des Smartmeter ist, deute ich als gutes Zeichen. Er sendet 396 Zeichen. Das ist problemlos in einem UDP-Paket intern versendbar.

Ebenfalls geeignet sein sollte:

Wer doch auch in die Gegenrichtung arbeiten will, muss sich entsprechende IR-Sendedioden beschaffen, die auf der fraglichen Wellenlänge schnell genug senden können. Denkbar sind hier

Hier ist dann natürlich etwas "experimentieren" angesagt, wenn der Empfänger nicht genau bekannt ist. Sowohl die Wellenlänge als auch die Intensität sind hier variabel. Mittlerweile habe ich schon Angebote auf Amazon und Co gesehen, die noch billiger sind. Aber verwechseln Sie bitte nicht IR-LEDs zum senden von Daten mit IR-LEDs als Beleuchtung für Nachtaufnahmen mit Kameras. Diese sind wohl heller aber sowohl Wellenlänge als auch die Schaltzeit dürften hier nicht ausreichend sein.

SML Protokoll

Die Analyse und Interpretation des SML-Protokolls habe ich auf die Seite SML-Protokoll ausgelagert, da es doch etwas "länger" geworden ist. Für diese reicht es zu wissen, dass das SML-Protokoll sehr viele Fälle und Konstellationen abbilden kann. Allerdings ist es auch nicht einfach zu parsen. Das ist aber auch gar nicht notwendig, wenn Sie einmal den gewünschten Wert gefunden haben. Die meisten Werte haben eine immer gleiche HEX-Werte als Vorlauf und können mit ziemlicher Sicherheit einfach so versucht und gefunden werden. Hier ein Beispiel:

Dies ist nur ein Ausschnitt aber die rot umrandeten Felder kennzeichnen meine beiden Zähler 1.8.1 und 2.8.1. Die HEX-Folge ist ziemlich lang und so sollte es sehr sehr unwahrscheinlich sein, dass diese Zeichenfolge noch mal kommt. Gelb unterlegt ist dann der Zählerstand. Die "56" kennzeichnet dabei die Variabel als Integer mit 6 Stellen (inklusive der Definition). Also sind es nur 5 Bytes, die von High nach Low aufaddiert werden müssen. Da mein Zähler dann auch noch eine Auflösung von 10.000 Impulsen pr kWh hat, muss ich die Zahl entsprechend teilen. Sie müssen mit ihrem eigenen Zähler als "Einfachversion" nur diese Nummern finden. So spare ich mir einen kompletten SML-Parser auf Basis des WeMOS.

SML auf Ethernet (UDP)

Zuerst hatte ich vor, per Arduino Ethernet-Schnittstelle ein Bindeglied zwischen dem Zähler und meinem LAN und der zur Visualisierung genutzten PRTG-Installation zu nutzen. Aber zum einen muss ich dann "Kabel legen" und einen Port freischalten oder per PowerLAN erst Ethernet in den Schaltschrank legen. Zum anderen habe ich mit dem ESP8266 eine viel interessantere Option gefunden, um einfache Aufgaben per WiFi direkt in ein Haus-WLAN oder eigenes "Mess-WLAN" abzuliefern.

Technisch hätte ich natürlich auch einfach die serielle Schnittstelle dieser USB-Wandler-Schaltung an einen RaspberryPi oder gleich an den PC anschließen können. Aber wollen Sie deswegen permanent einen PC laufen zu lassen? Und in meinem RaspberryPI ist die erste SD-Karte auch schon kaputt gewesen. Seitdem ich mal mit dem ESP8266 SoC und NodeMCU gebastelt habe, ist der für solche Aufgaben einfach genial. Meine Überlegung war folgende.

  • ESP8266 als Basis
    Versorgung mit Batterie oder 5V Netzadapter, IR-Fototransistor an RxD.
  • System bucht sich ins WiFi ein, liest die Messwerte und sendet diese per UDP ins LAN oder per HTTPS an einen hinterlegten Server. Ich erspare mir so einen permanent aktiven Client auf dem ein Server läuft.
  • Erfassung
    Mein eh vorhandenes Monitoring-System (Siehe PRTG) startet regelmäßig ein Skript, welches genau diese UDP-Pakete empfängt und an PRTG übergibt

Zuerst musste ich natürlich die Hardware entsprechend vorbereiten. Ich habe mich für ein "fertiges" Board entschiede, welches schon einen USB-Anschluss inkl. Programmierung hat, von der Arduino-IDE unterstützt wird und sehr klein ist. Meine Wahl fiel auf das WeMos D1 und eine BPW40, die ich einfach direkt angeschlossen habe:

Der Emitter ist auf "G" = (GND) verbunden und der Kollektor an "RxD" angeschlossen. Zum "Programmieren" muss ich den Fototransistor allerdings "dunkel" abdecken oder abziehen. Ich habe vorher mit einem Amperemeter den Kurzschlussstrom gemessen (5 mA). Selbst bei 5 Volt wären das also maximal 25mW. Laut Datenblatt soll die BPW40 aber bis zu 150mW bzw. einen Kollektorstrom von bis zu 100mA aushalten. Das ist im grünen Bereich. Später wird die Schaltung natürlich in ein Gehäuse eingebaut und die LED mit einem Ringmagnet und schwarzen Abdeckungen montiert. Aber auch so ist die Funktion schon sehr zuverlässig.

Der nächste Schritt ist die Software, die folgende Schritte durchläuft. Knifflig war etwas, dass die serielle Kommunikation nur einen Puffer von 64bytes hat, während ein Datagramm knapp 400Bytes sind. Also darf ich beim Lesen nicht trödeln. Insbesondere Ausgaben zur Fehlersuche bremsen bei 9600 Baud den Ablauf. Da der Stromzähler aber immer wieder sendet, macht es hier mal nichts aus, ein Paket zu verlieren. Ich habe meinen Code dann einfach den Buffer leert, bis ca. keine Daten mehr kommen. Dann kann ich davon ausgehen, dass es bald "losgeht" und dann stumpf lesen, bis wieder eine Pause kommt. Um den Code einfach zu halten, findet im Code keine umfangreiche Validierung, Normalisierung oder Konvertierung statt. Das überlasse ich dem empfangenden Programm. So ist der Code mit der Hardware quasi universell mit vielen Systemen einsetzbar, die spontan Daten senden.

Die eingebaute LED nutze ich als Statusanzeige.

Blink (Anzahl, Einschaltzeit, Ausschaltzeit, Pause am Ende) Phase Beschreibung

blink(1,5000,500,1000)

INIT Startet

 

blink(4,100,500,2000)

Serial ist initialisiert

 

blink(5,50,100,2000)

WiFi Verbindung wird hergestellt

 

blink(6,100,500,2000)

WiFi Connected

 

blink(7,100,500,2000)

INIT abgeschlossen

 

blink(2,400,100,2000)

LOOP Startet

 

Sek Aus, 0,5 Sek an 

Warte auf Serial Bytes

 

blink(5,100,100,0)

Sende UDP Paket 

 

blink(10,100,100,2000)

Fehler beim Einlesen

 

blink(100,30,70,0)

10 Sek "warten"

 

Zum Testen konnte ich das System erst mal direkt am PC seriell ansteuern. Jede Information, die ich an den ESP8266 gesendet habe, wurde dann per UDP wieder zurück gesendet. Ich habe dann natürlich den RxD-Eingang mit einem Fototransistor gegen Masse ziehen lassen und diesen vor den Zähler gehängt.

 

Die Ausgabe ist im Wireshark gut zu sehen.

PRTG Probe

Nun fehlt nur noch die PRTG-Probe, die ab uns an mal gestartet wird und die eingehenden Daten einfängt, verarbeitet und zur Auswertung weiter gibt. Auch hier ist natürlich wieder PowerShell meine erste Wahl. Es ist damit viel einfacher einen UDP-Port zum "Lesen" zu starten als in VBScript o.ä. und eine EXE wollte ich nun doch mal nicht schreiben.

Hinweis
Achten Sie darauf, dass Sie den UDP-Port auch in der Firewall freischalten, sonst wartet ihre Probe vergeblich auf eingehende Pakete

Auf der Seite PS UDP habe ich schon entsprechende Vorarbeiten geleistet. Allerdings muss ich hier natürlich noch die Daten auflösen und konvertieren um sie dann z.B. an PRTG zu übergeben.

# Smartmeter2prtg

param (
   [string]$localip = "0.0.0.0",
   [string]$udplistenport="12345"
)

$udpClient = New-Object system.Net.Sockets.Udpclient($udplistenport)
$RemoteIpEndPoint = New-Object System.Net.IPEndPoint([system.net.IPAddress]::Parse($localip)  , $udplistenport);

Write-host "Receive-UDP:Wait für Data on Port: $udplistenport"
$data=$udpclient.receive([ref]$RemoteIpEndPoint)
write-host "Received packet from IP " $RemoteIpEndPoint.address ":" $RemoteIpEndPoint.Port

# Parse Content
write-host "Content" ([string]::join("",([System.Text.Encoding]::ASCII.GetChars($data))))


# Generate PRTG Output

Das Skript ist noch nicht fertig

Mittelfristig wäre es natürlich auch eine Idee, einen Dienst zu schreiben, der von mehreren Sensoren die Daten annimmt und dann an PRTG z.B. als HTTPPush-Sensor an PRTG zu senden. Noch direkter wäre, wenn die Aufbereitung der SML-Daten in dem WeMos selbst passiert und dieser dann gleich als HTTPPushSensor die Daten an PRTG übermittelt. Das macht aber erst Sinn, wenn ich mal mehrere SML-Zähler als Beispiele ausgelesen habe. Schon mein Zähler konnte ich nur eingeschränkt decodieren..Ich vermute ja nicht, dass PRTG selbst irgendwann selbst SML-Datenstöme direkt lesen kann.

Firmware (Tasmota und Co)

Für die Bausteine der ESP8266 Serie gibt es mittlerweile unterschiedliche freie Firmware-Lösungen.

Hinsichtlich SML/D0 ist die Tasmota-Firmware etwas besonders, da es ein Modul für eine direkte D0-Auswertung gibt. Ich habe es noch nicht selbst eingesetzt, aber wurde von einem Leser der MSXFAQ darauf aufmerksam gemacht. Da aber jeder Zähler sich irgendwie unterscheidet, kommt man um ein selbst zusammenbauen nicht umhin.

IR-Lesekopf für Stromzähler am ESP8266 mit Tasmota (Wemos D1 Mini / NodeMcu)
https://www.youtube.com/watch?v=s6qQs4FN9B0

Selbst einsetzen?

Sie wollen selbst auf der gleichen Basis ihre ersten Schritte tun? Nichts leichter als das, denn die Hardware ist ja "Super Simpel". Einen WeMos bekommen Sie bei AlIExpress, eBay und anderen Quellen, einen BPW40 Fototransistor bei jedem gut sortierten Elektronik-Versender (Reichelt, Conrad und Co). Die Software stelle ich hier einfach kostenfrei zum Download.

Smartmeter D0 - Code

Sie brauchen dann nur noch die Arduino IDE mit dem ESP8266 Libraries und im Code müssen Sie natürlich die IP-Adresse des Zielsystems, die WiFi-SSID und das Kennwort anpassen und dann auf den WeMos herunter laden.

Weitere Links