Mein SmartHome-Projekt Gasuhr
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.
![]() |
![]() |
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.
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.
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 nocht 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 hochgezählt.
Der ESP8266 ruft zwei PHP-Scripte von einem Raspberry Pi ab. Das erste ist GetUTC.php, ein Einzeiler der dem ESP8266 die UTC-Zeit in Sekunden liefert:
<?php
print time();
?>
Wenn man den Start-Zeitpunkt und die Laufzeit des ESP8266 nicht benötigt oder kein entsprechender Raspberry Pi vorhanden ist, kann man die entsprechenden Code-Zeilen entfernen.
Das zweite PHP-Script GetActualGasMeter.php wird ebenso 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.
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:
![]() |
![]() |
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:
![]() |
![]() |
Die Schaltung sieht dann so aus:
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.
Der oben dargestellte XML-Code des ESP8266 wird in meinem Fall 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 MySQL-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: