Elster Gaszähler auswerten

Begonnen von DerJens, 06 Dezember 2014, 23:51:46

Vorheriges Thema - Nächstes Thema

DerJens

Hallo,

ich habe ein weiteres FHEM-Projekt erfolgreich abgeschlossen und möchte kurz meine Lösung zurückspielen:

Worum geht es?
Im Haus ist eine zentrale Gasheizung für Heizung und Warmwasser verbaut. An dieser kann man diverse Einstellungen wie z.B. Vorlauftemperatur, Leistung usw. vornehmen, auch habe ich das Service-Menü auf der 2. Ebene entdeckt. Die Anlage ist rein Außentemperaturgesteuert. Leider lassen sich Änderungen dort nur bedingt nachverfolgen, letztendlich ändern sich auf der einen Seite die Raumtemperatur und auf der anderen Seite die Kosten. Raum- und Außentemperatur kann ich messen (via JeeLink und zahlreichen 10€ Sensoren), für die Kosten muss ich regelmäßig zum Gaszähler rennen, Werte notieren und rechnen.

Ziele
Ich würde gerne Daten wie z.B. aktuelle Leistung, Verbrauch und Kosten aus meiner Zentralheizung in FHEM abbilden. Diese Daten können dann direkt Innen- und Außentemperaturen gegenübergestellt werden, auch sind die Auswirkungen der Änderungen an Einstellungen der Heizung schneller ersichtlich. So kann ich kostenbewusster Einstellungen vornehmen.

Hardware
Ich habe einen Elster Impulsnehmer IN-Z65 für meinen Elster-Balgengaszähler angeschafft. Dieser ist mit ca. 30€ recht teuer im Vergleich zu einem Reedkontakt Marke Eigenbau, hat aber zwei große Vorteile: Erstens ist dieser Impulsnehmer als Originalteil für den Gaszähler zugelassen, zweitens ist er passgenau in 3 Minuten mit einer Schraube montiert und muss nicht justiert werden. Diesen habe ich an die GPIO-Ports von einem Raspberry Pi gehängt, auf dem FHEM läuft.

Raspberry Pi GPIO in FHEM
Mit einem aktuellen (Oktober 2014) Debian in der Standardinstallation musste ich keine Anpassungen vornehmen und konnte direkt mit der Konfiguration von FHEM beginnen:
define GPIO3 RPI_GPIO 3
attr GPIO3 debounce_in_ms 250
attr GPIO3 direction input
attr GPIO3 interrupt falling
attr GPIO3 room Zentralheizung
attr GPIO3 stateFormat Counter

Hier wird zunächst Port 3 der GPIO-Leiste über das FHEM-Modul RPI_GPIO als GPIO3 eingebunden und anschließend als Eingang definiert. Der Impulszähler schließt beim Erreichen der "9" und öffnet wieder beim Erreichen der "0", also kann die fallende Flanke als Zähler verwendet werden. Schön ist hier die Lösung via Interrupt, so wird FHEM informiert, wenn dieses Ereignis auftritt ohne aktiv darauf warten zu müssen. Wenn man jetzt als stateFormat das Reading Counter nimmt, hat man schon einen Zähler, der die Umdrehungen der letzten Stelle des Gaszählers zählt. Achja, debounce_in_ms entprellt den Impulszähler, denn der hat das auch nötig.

Zentralheizung
Ich habe mir nun einen Dummy erstellt, der meine Zentralheizung abbilden soll. Dieser wird via at alle 5 Minuten mit dem Wert des Gaszählers versorgt und kann damit Leistung und Verbrauch berechnen:
define Zentralheizung dummy
attr Zentralheizung comment Leistung in kW, *Verbrauch in kWh
attr Zentralheizung room Zentralheizung
attr Zentralheizung stateFormat { sprintf("%.2f kW", ReadingsVal("Zentralheizung","Leistung",0));; }
attr Zentralheizung userReadings Verbrauch difference { ReadingsVal("Zentralheizung","state",0)*0.01*0.9384*10.056;; }, Leistung differential { ReadingsVal("Zentralheizung","state",0)*0.01*0.9384*10.056*3600;; }


Mit Hilfe von UserReadings lege ich zwei zusätzliche Readings an. Der Verbrauch in kWh der letzten 5 Minuten ist die Differenz des Zählers vom GPIO, multipliziert mit 0,01 um auf cbm zu kommen und multipliziert mit den Werten für Zustandszahl und Brennwert aus der letzten Gasrechnung. Die Leistung in kW berechnet sich aus dem Verbrauch pro Zeit. Mit stateFormat habe ich die Anzeige etwas aufgehübscht.

define UpdateZentralheizung at +*00:05:00 {my $b = ReadingsVal("GPIO3", "Counter", "");; fhem("set Zentralheizung $b");; }
attr UpdateZentralheizung alignTime 00:05:00
attr UpdateZentralheizung room Zentralheizung


Tagsverbrauch
Um den Tagesverbrauch ermitteln zu können, habe ich zunächst die Werte der Heizung in ein Log geschrieben:
define FileLog_Gasverbrauch FileLog ./log/Gasverbrauch-%Y.log Gasverbrauch
attr FileLog_Gasverbrauch logtype text

Dann habe ich einen Dummy angelegt, der mir den Tagesverbauch repräsentieren wird:
define Tagesverbrauch dummy
attr Tagesverbrauch room Zentralheizung
attr Tagesverbrauch stateFormat kWh, Euro
attr Tagesverbrauch userReadings kWh { sprintf("%.2f kWh", ReadingsVal("Tagesverbrauch","state",0));; }, Euro { sprintf("%.2f €", ReadingsVal("Tagesverbrauch","state",0)*0.054502);; }


Via Notify auf Aktualisierung des Verbrauchs addiere ich diesen zum Tagesverbrauch:
define UpdateTagesverbrauch notify Zentralheizung:Verbrauch:.* {\
my $x = ReadingsVal("Zentralheizung", "Verbrauch", "");;\
my $y = ReadingsVal("Tagesverbrauch", "state", "");;\
my $z = $x+$y;;\
fhem("set Tagesverbrauch $z");;\
}
attr UpdateTagesverbrauch room Zentralheizung


Nachts wird der Tagesverbrauch zurückgesetzt:
define ResetTagesverbrauch at *00:00:01 set Tagesverbrauch 0
attr ResetTagesverbrauch room Zentralheizung


Visualisierung
Mit ein wenig Kosmetik habe ich mir für mein Wandtablet ein Floorplan für die Zentralheizung gebaut, ein Bild hängt an. Tagesverläufe via Plots gehen natürlich auch.

Ich hoffe, ich habe nichts vergessen.

Liebe Grüße
DerJens


Prof. Dr. Peter Henning

Tipp: Mal einen Blick auf den Code des OWCOUNT-Moduls werfen, ist ganz ähnlich auch in EMX umgesetzt.

LG

pah

kvo1

Hallo ,

nicht schlecht, danke für den Ansatz.
Ich habe ähnliches vor, hab mir gerade für meinen Gaszähler so
einen Impulsnehmer besorgt.


gruss kvo1
RPi1: mit CUL: HM-CC-RT-DN,HM-ES-PMSw1-Pl,HM-LC-BL1-FM,HM-LC-Bl1PBU-FM,HM-LC-SW1-PL2,HM-SCI-3-FM,HM-SEC-SC-2,KFM-Sensor
RPi2: Viessmann(optolink) mit 99_VCONTROL.pm,
Cubietruck: Wheezy / Apache / Owncloud
Cubietruck: Armbian(Jessie) / fhem 5.7 / LMS 7.9
RPi3: (Test) mit 7" Touch  &  HM-MOD-RPI-PCB

karenz

Hallo,

gute Beschreibung, auch für "Nichtprofis"!

Habe heute mittels FS20TFK und dem HourCouter dein Modul angepasst und testweise ein Readkontakt angehängt. Läuft prima. Ich bin mal gespannt ob der praktische Einsatz dann auch funktioniert wenn ich den IN-Z65 an den Zähler bringe oder die Impulse (Funkverkehr)  zuviel werden über den Tag.

Gibt es auch noch eine Erweiterung die den Gesamtverbrauch und die Gesamtkosten berechnet? Würde zum Jahreswechsel gut passen da man dann die Jahreskosten im Überblick hat. Bin leider nicht fit mit den Perl Funktionen!

Gruss

karenz


BerndHST

Hallo,

vielen Dank für die Codeschnipsel. Hatte für meine Zähler erst eine Lösung über hourcounter gefunden, jedoch werde ich da das Problem mit doppelten und dreifachen Logeinträgen nicht los. Deine Lösung scheint mir eleganter.
Allerdings verstehe ich (v.a.) eine Zeile noch nicht:
define FileLog_Gasverbrauch FileLog ./log/Gasverbrauch-%Y.log Gasverbrauch
Müsste es nicht "define FileLog_Gasverbrauch FileLog ./log/Gasverbrauch-%Y.log Zentralheizung" heißen?
Es sind doch die Werte des dummy "Zentralheizung", die ins Logfile sollen, oder?
Jedenfalls bleibt bei mir  mit "....Gasverbrauch" das Logfile leer.
Und wie sieht das mit "Tagesverbrauch" aus? Wird der Wert auch ins log geschrieben, oder nur einmal am Tagesende?

Bernd

DerJens

Hallo Bernd,

du hast recht, da ist mir wohl ein Copy&Paste-Fehler unterlaufen.

Ich hab dir ein Bildschirmfoto meiner aktuellen Konfiguration angehängt. Schau mal, ob dir das weiterhilft. Läuft bei mir jetzt seit über einem Jahr problemlos. Die erfassten Werte visualisiere ich auf meinem Display an der Wand.

Tagesverbrauch schreibt bei jeder Aktualisierung ins Log. Um eine Jahresauswertung habe ich mich bislang noch nicht gekümmert. Das geht sicher in FHEM oder notfalls in Excel ;)

Bei Fragen meld dich einfach noch mal.

FunkOdyssey

Ich habe mir auch den IN-Z65 besorgt und erst einmal direkt an GND und GPIO21 am RasPi 2 B angeschlossen. Mich wundert es, dass hier im Thread das Entprellen nur mittels debounce gemacht werden soll. Dann habe ich bei einer Umdrehung ca. 45 Counts.

Ist wirklich kein Widerstand oder Tiefpass oder ähnliches eingesetzt?
Auch kein "pud_resistor = up"?

Kann mir jemand einen Tipp geben, wie ich am besten enptrelle?

Ich habe nur eine 1 Meter lange Leitung zum RasPi.

Danke.

BerndHST

Hallo,

doch - ein "pud_resistor=up" ist bei mir gesetzt. Anonsten dürfte das auch nicht funktionieren. Die Leitung zum Raspi ist bei mir einige Meter lang, das sollte kein Problem sein. Entprellt habe ich nur mit "debounce_in_ms=250", das funktioniert bei mir sehr zuverlässig.
Bernd

FunkOdyssey

#8
Ich kann euch ja mal mein Log zeigen:


2016-09-30_11:18:26 GPIOGaszaehler Pinlevel: low
2016-09-30_11:18:26 GPIOGaszaehler off
2016-09-30_11:18:26 GPIOGaszaehler Toggle: off
2016-09-30_11:18:26 GPIOGaszaehler Counter: 91
2016-09-30_11:18:44 GPIOGaszaehler Pinlevel: low
2016-09-30_11:18:44 GPIOGaszaehler off
2016-09-30_11:18:44 GPIOGaszaehler Toggle: on
2016-09-30_11:18:44 GPIOGaszaehler Counter: 92
2016-09-30_11:19:01 GPIOGaszaehler Pinlevel: low
2016-09-30_11:19:01 GPIOGaszaehler off
2016-09-30_11:19:01 GPIOGaszaehler Toggle: off
2016-09-30_11:19:01 GPIOGaszaehler Counter: 93
2016-09-30_11:19:22 GPIOGaszaehler Pinlevel: low
2016-09-30_11:19:22 GPIOGaszaehler off
2016-09-30_11:19:22 GPIOGaszaehler Toggle: on
2016-09-30_11:19:22 GPIOGaszaehler Counter: 94
2016-09-30_11:19:45 GPIOGaszaehler Pinlevel: low
2016-09-30_11:19:45 GPIOGaszaehler off
2016-09-30_11:19:45 GPIOGaszaehler Toggle: off
2016-09-30_11:19:45 GPIOGaszaehler Counter: 95
2016-09-30_11:20:13 GPIOGaszaehler Pinlevel: low
2016-09-30_11:20:13 GPIOGaszaehler off
2016-09-30_11:20:13 GPIOGaszaehler Toggle: on
2016-09-30_11:20:13 GPIOGaszaehler Counter: 96
2016-09-30_11:20:45 GPIOGaszaehler Pinlevel: low
2016-09-30_11:20:45 GPIOGaszaehler off
2016-09-30_11:20:45 GPIOGaszaehler Toggle: on
2016-09-30_11:20:45 GPIOGaszaehler Counter: 97
2016-09-30_11:21:21 GPIOGaszaehler Pinlevel: low
2016-09-30_11:21:21 GPIOGaszaehler off
2016-09-30_11:21:21 GPIOGaszaehler Toggle: off
2016-09-30_11:21:21 GPIOGaszaehler Counter: 98
2016-09-30_11:22:03 GPIOGaszaehler Pinlevel: low
2016-09-30_11:22:03 GPIOGaszaehler off
2016-09-30_11:22:03 GPIOGaszaehler Toggle: on
2016-09-30_11:22:03 GPIOGaszaehler Counter: 99
2016-09-30_11:22:48 GPIOGaszaehler Pinlevel: low
2016-09-30_11:22:48 GPIOGaszaehler off
2016-09-30_11:22:48 GPIOGaszaehler Toggle: off
2016-09-30_11:22:48 GPIOGaszaehler Counter: 100
2016-09-30_11:23:37 GPIOGaszaehler Pinlevel: low
2016-09-30_11:23:37 GPIOGaszaehler off
2016-09-30_11:23:37 GPIOGaszaehler Toggle: on
2016-09-30_11:23:37 GPIOGaszaehler Counter: 101
2016-09-30_11:24:30 GPIOGaszaehler Pinlevel: low
2016-09-30_11:24:30 GPIOGaszaehler off
2016-09-30_11:24:30 GPIOGaszaehler Toggle: off
2016-09-30_11:24:30 GPIOGaszaehler Counter: 102


Die Abstände zwischen on und off sind recht groß.

Update: Hat sich erledigt. Ich habe ein Pullup-Widerstand eingesetzt und es funktioniert nun.