Gaszähler mit Reed-Kontakt auslesen

Zum Auslesen meines Gaszählers elster BK-G4M verwende ich seit 6.01.2016 einen Reedkontakt vom Elektronikladen um die Ecke (Kosten unter 1 €). Mit doppelseitigem Klebeband habe ich diesen Reed-Kontakt in die Mulde unter dem Zählwerk geklebt.

Gasuhr mit Reed-Sensor Reed-Sensor

 

Erst habe ich den Gaszähler mit einem Raspberry Pi ausgelesen, inzwischen verwende ich aber einen ESP8266 ESP-01. Beide Projekte sind im folgenden beschrieben.

 

Option 1 - Gaszähler mit Raspberry Pi auslesen

Anfangs verwendete ich einen Raspberry Pi A+ und ein Pyton-Skript, das bei jedem Impuls den Zählerstand hochzählt (0,01 m^3 beim BK-G4M). Dazu verwende ich folgendes Python-Skript GetImpulse.py, das mit sudo ./GetImpulse.py & gestartet werden kann. Sinnvoller ist der automatische Start des Python-Scripts nach dem Booten. Auf diese Weise wird sichergestellt, dass im Falle eines Raspberry Pi-Reboots das Script auch tatsächlich läuft.

Der aktuelle Wert des Gaszählers wird bei jedem Impuls aus der Datei GasMeter.dat ausgelesen, und der neue Wert dort abgespeichert. Vor dem Start des Python-Scripts muss diese Text-Datei manuell angelegt werden, und der aktuelle Zählerstand ist dort einzutragen (mit Dezimalpunkt!). Das Script erstellt weiterhin eine XML-Datei /var/www/html/gas.xml. Diese XML-Datei beinhaltet den aktuellen Zeitstempel und den aktuellen Zählerstand. Über diese XML-Datei kann jederzeit über eine HTTP-Anfrage von einem beliebigen Computer im Netzwerk der aktuelle Zählerstand abgefragt werden.

In vielen Foren wird berichtet, dass mit dieser kostengünstien Bastelei nicht jeder Impuls zuverlässig abgefragt wird. Bei mir funktioniert die Abfrage des Zählerstands seit vielen Jahren (seit dem 6.01.2016) absolut fehlerfrei.

 

Option 2 - Gaszähler mit einem ESP8266 auslesen

Da ein Raspberry Pi mit dem simplen Hochzählen eines Impulses eingentlich total unterfordert ist, habe ich seit März 2017 einen ESP8266 ESP-01 dafür im Einsatz. Dessen zwei GPIOs reichen für diese Anwendung völlig aus. Der verwendete Code ist ESP8266_GasMeter.ino:

 

Der Reedkontakt ist am GPIO2 angeschlossen, und eine LED am GPIO0. Die LED blink jede Sekunde kurz auf, und zeigt damit an, dass der ESP8266 läuft. Bei einem eintreffenden Impuls des Reed-Kontakts der Gasuhr leuchtet die LED für die Dauer des Impulses.

Klar könnte man die Impulse auch mit einem Interrupt zählen. Wie das funktioniert wusste ich bei der Erstellung des Codes aber noch nicht. Einen Interrupt verwende ich beim Windsensor-Projekt, da hier die Impulse mit einer viel höheren Frequenz gezählt werden müssen als bei einer Gasuhr. Übrigens werden Fehler bei Zählen durch Prellen des Reed-Kontakts durch die lange Wartezeit von fast einer Sekunde wirkungsvoll vermieden.

Der Zählerstand ist nach dem Start des ESP8266 bei 0. Um dem ESP8266 den aktuellen Zählerstand mitzuteilen erfolgt einmalig folgender Aufruf:
192.168.XXX.YYY/SetValue?Value=1234.5
Nach diesem einmaligen Aufruf wird der aktuelle Zählerstand vom ESP8266 zurückgemeldet und mit jedem erfassten Impuls weiter hochgezählt.

Der Aufruf eines PHP-Script GetActualGasMeter.php wird von dem Raspberry Pi abgerufen, auf den die ganzen Werte in einer MariaDB-Datenbank abgelegt werden. Im Falle eines Neustarts des ESP8266 bezieht dieser den letzten Wert des Gaszählers durch Aufruf dieses PHP-Scripts aus der Datenbank. Wenn man das nicht benötigt startet der Zählerstand im Falle eines Neustarts eben bei Null.

Der aktuelle Zählerstand wird via MQTT übertragen und kann so von jedem beliebigen Gerät im selben Netzwerk ermittelt werden. Mehr dazu hier. Via MQTT kann der Gaszählerstand auch einfach in Home Assistant eingebunden werden.

Nach dem Aufruf via 192.168.XXX.YYY erhält man vom ESP8266 zum Beispiel folgende Antwort:
<ESP8266_ESP01_GasMeter>
 <data name="Device" value="ESP8266_ESP01_GasMeter" valueunit="text"/>
 <data name="Version" value="V2.05 from 2020-02-23" valueunit="text"/>
 <data name="MAC" value="dc:XX:YY:ZZ:ÖÖ:b4" valueunit="AA:BB:CC:DD:EE:FF"/>
 <data name="SSID" value="YourSSID" valueunit="text"/>
 <data name="IP" value="192.168.X.Y" valueunit="xxx.xxx.xxx.xxx"/>
 <data name="StartTime" value="2020-02-23 14:26:31" valueunit="YYYY-MM-DD hh:mm:ss"/>
 <data name="RunTime" value="294.5" valueunit="hours"/>
 <data name="WIFIConnectCounter" value="1" valueunit=""/>
 <data name="help" value="use /SetValue?Value=xx to set new value" valueunit="text"/>
 <data name="GasMeter" value="9380.64" valueunit="m^3"/>
</ESP8266_ESP01_GasMeter>

Bei meiner Gasuhr liegt ein Impuls bei maximalem Gasverbrauch für ca. 4 Sekunden an. Mit einer "Abtastrate" von einer Sekunde wird seit März 2017 tatsächlich jeder Impuls zuverlässig erfasst.

Ich habe den ESP8266 ESP-01 auf einer kleinen Platine zusammen mit einem Spannungswandler AM1117-3.3 untergebracht. Damit kann die Schaltung mit einer variablen Spannung bis 12 VDC versorgt werden. Das Ganze sieht von innen dann so aus:

ESP8266 ESP-01 Gaszähler von innen vorne ESP8266 ESP-01 Gaszähler von innen hinten

 

Die Spannungsversorgung erfolgt über eine Hohlbuchse (5,5/2,1) mit Lötanschluss mit bis zu 12 VDC. Die LED zeigt den Status an (siehe oben). Der Reed-Kontakt wird über die zweipolige Leiterplattenklemme angeschlossen. Von außen sieht das kleine Gerät dann so aus:

ESP8266 ESP-01 Gaszähler Gehäuse ESP8266 ESP-01 Gaszähler Gehäuse innen

 

Die Schaltung sieht dann so aus:

Schaltung Gaszähler

Beim ESP8266 ESP-01 ist darauf zu achten, dass beim Start beide GPIOs auf Plus gezogen werden (sonst startet der ESP im Flash-Modus); daher die beiden Pull-Up-Widerstände (15k). Wenn nun zufällig beim Start der Gaszähler im Nulldurchgang ist, der Reed-Kontakt also geschlossen ist, liegt GPIO2 auf Masse. Dann startet der ESP nicht. Sollte das der Fall sein, muss man den Reed-Kontakt zum Start kurz abklemmen und erst nach dem Start wieder anklemmen.

Die (rote) LED blinkt während dem WLAN-Verbindungsaufbau schnell. Mit einer ca. 1 sec langen Leuchtdauer wird der erfolgreiche Verbindungsaufbau angezeigt. Im Betrieb signalisiert die blinkende LED, dass der ESP8266 richtig funktioniert. Wärhend einem Zählimpuls (Nulldurchgang Gasuhr) leuchtet die LED dauerhaft.

 

Beispiel einer Auswertung

Der aktuelle Zählerstand der Gasuhr wird via MQTT für andere Geräte bereitgestellt. Damit kann z.B. auch Home Assistant auf diesen Sensor-Wert direkt zugreifen. Das ist alles viel, viel einfacher als der hier beschriebene alte Weg zur Auswertung.

Vor der Verwendung von MQTT wurde der oben dargestellte XML-Code des ESP8266 von einem Raspberry Pi in festen Zeitabständen abgefragt. Diese Abfrage erfolgt über ein Python-Script, das die relevanten Parameter aus dem XML-Code extrahiert und in eine MariaDB-Tabellle einträgt.
# --- get value with ID from xmldata
def GetxmlValue(root, ID_Name, ID):
  value = '0'
  for hit in root.findall('.//*[@' + ID_Name + '="' + ID + '"]'):
    value = hit.get('value')
  return value
# --- def GetxmlValue

Mit folgendem Aufruf kann dann zum Beispiel der aktuelle Wert des Gaszählers ausgelesen werden:
GasMeter = float(GetxmlValue(xmlroot, 'name', 'GasMeter'))
In der Variable xmlroot steht in diesem Fall der Inhalt des oben dargestellten XML-Codes, der über einen URL-Request vom ESP8266 abgeholt wird.

In Kombination mit einem Außentemperaturfühler können dann Digramme erstellt werden, die den zeitlichen Verlauf von Außentemperatur und Gasverbrauch zum Beispiel wie folgt darstellen:

Gasverbrauch

Inzwischen verwendet ich an Stelle von amCharts Grafana und Home Assistant.