Hallo Zusammen,
nachdem ich im Mikrocontroller-Forum auf meine nicht so ganz professionelle, aber funktionierende Lösung zur Integration von einem Junkers Heizgerät mit HT3-Schnittstelle angesprochen wurde will ich hier kurz beschreiben, wie ich das gelöst habe.
Hier in Kurzform die Vorgehensweise, um Daten einer Junkers-Heizung mit Heattronic 3 in Fhem zu integrieren.
Folgende Dinge sollten gelesen und beachtet werden:
- Hardware: Es wird ein Adapter für den HT3-Bus benötigt, siehe hierzu
http://www.mikrocontroller.net/topic/317004#3585250- Software: Auf dem Raspberry Pi (o.ä.) wird eine Auswertung des Protokolls benötig, siehe hierzu auch
http://www.mikrocontroller.net/topic/324673#3588841Für obiges ein großes Dankeschön an Norbert, er hat hier zur Installation der Hard- und Software im Mikrocontroller-Forum bereits einiges geschrieben, eine ausführliche Anleitung ist auch schon erstellt, die befindet sich mit im Software-Paket.
Nun zur Anbindung in FHEM.
Ich bin hier einen recht einfachen Weg gegangen, da mir die Anpassung eines Perl-Moduls zu schwierig war und auch das Datenaufkommen deutlich zu groß ist. Daher habe ich zu der obigen Installation zusätzlich einen Webserver mit Apache und PHP auf dem raspberry Pi installiert. Anleitungen hierzu gibt es reichlich im Internet, z.B. unter:
http://www.forum-raspberrypi.de/Thread-tutorial-raspberry-pi-als-webserver-php-5-installation.
PHP ist wichtig, damit werden die Textdateien im Browser auch korrekt angezeigt und können mit HTTPMOD ausgelesen werden.
Dann rufe ich mittels Cronjob ein kleines Script auf, welches mir die Daten in eine einfache TXT-Datei schreibt.
Diese Textdatei frage ich mittel dem HTTPMOD-Modul in Fhem regelmäßig ab und fülle hierüber die einzelnen Variablen, die auch in meiner FHEM-SQL-Datenbank gespeichert werden.
Als Hinweis noch vorab, nicht alle Daten werden bei mir übertragen, da ich auch nicht alle Messpunkte wie Norbert S. oder Frank im Mikrocontroller-Forum. Daher bitte die Punkte selber anpassen, das sollte recht einfach möglich sein.
Zuerst das Script für die Dateierstellung im Raspberry mit der HT-Schnittstelle. Hier frage ich einfach periodisch die letzten geschriebenen Werte in der SQLITE-Datenbank ab und schreibe diese in die Datei hzg.txt im Verzeichnis /var/www/
Das Script "date_sql_extract.pl" liegt mit im Verzeichnis /usr/local/bin/ und ist unter Benutzer pi ausführbar.
Damit die sqllite-Datenbank angesprochen werden kann muß man das Perl-modul DBI installieren mit "sudo apt-get install libdbd-mysql-perl" und ggf. "sudo apt-get install libdbi-perl". Sollte auf dem Raspberry bereits FHEM installiert sein, dann sollte das DBI-Paket bereits installiert sein.
Bitte den Pfad zur SQL-Lite-Datei prüfen und ggf. anpassen (Zeile 6). Hier auch nochmals der Hinweis, ich habe nicht alle Daten abgefragt da ich auch nicht alle Datenpunkte verwende bzw. auch nicht physikalisch zur Verfügung habe oder technisch richtige Werte ausgegeben werden!
date_sql_extract.pl: (ist im Anhang zum Beitrag)
#!/usr/bin/perl
use strict;
use DBI;
my $dbargs = {AutoCommit => 0, PrintError => 1};
my $dbh = DBI->connect("dbi:SQLite:dbname=/home/pi/HT3/software/var/databases/HT3_db.sqlite", "", "", $dbargs); ##PFAD zur SQLITE anpassen
open (DATEI, ">/var/www/hzg.txt") or die $!; ## Datei mit den Heizungsdaten öffnen
## Zeilen ausgeben, Solar
my ($time, $t_kollektor, $t_speicher, $sp_laufzeit, $V_ertrag) = "";
my $res = $dbh->selectall_arrayref("SELECT Local_date_time, T_kollektor, T_speicher_unten, V_ertrag_stunde, C_laufzeit FROM solar ORDER BY rowid DESC LIMIT 1 ;");
foreach my $row (@$res) {
($time, $t_kollektor, $t_speicher, $V_ertrag, $sp_laufzeit) = @$row;
print DATEI "SO-Time: $time - Temp_Koll: $t_kollektor, T-Speicher $t_speicher ,Ertrag: $V_ertrag ,Laufzeit SP $sp_laufzeit\n";
## print("Time: $time - Temp_Koll: $t_kollektor, T-Speicher $t_speicher ,Ertrag: $V_ertrag ,Laufzeit SP $sp_laufzeit\n");
}
## Zeilen ausgeben, Heizgerät
my ($time, $t_vorlauf_soll, $t_vorlauf_ist, $brenner_lstg, $hg_betr_modus, $hp_an, $zp_an, $wwp_an) = "";
my $res = $dbh->selectall_arrayref("SELECT Local_date_time, T_vorlauf_soll, T_vorlauf_ist, V_modus, V_leistung, V_heizungs_pumpe, V_zirkula_pumpe, V_speicher_pumpe FROM heizgeraet ORDER BY rowid DESC LIMIT 1 ;");
foreach my $row (@$res) {
($time, $t_vorlauf_soll, $t_vorlauf_ist, $hg_betr_modus, $brenner_lstg,$hp_an, $zp_an, $wwp_an) = @$row;
print DATEI "HG-Time: $time vorlauf_soll $t_vorlauf_soll, vorlauf_ist $t_vorlauf_ist, hg_modus $hg_betr_modus, brenner_lstg $brenner_lstg, hp_an $hp_an, zp_an $zp_an, wwp_an $wwp_an\n";
## print("Time: $time vorlauf_soll $t_vorlauf_soll, vorlauf_ist $t_vorlauf_ist, hg_modus $hg_betr_modus brenner_lstg $brenner_lstg, hp_an $hp_an, zp_an $zp_an, wwp_an $wwp_an\n");
}
## Zeilen ausgeben, Warmwasser
my ($time, $t_soll, $t_ist, $t_speicher, $C_betriebs_zeit) = "";
my $res = $dbh->selectall_arrayref("SELECT Local_date_time, T_soll, T_ist, T_speicher, C_betriebs_zeit FROM warmwasser ORDER BY rowid DESC LIMIT 1 ;");
foreach my $row (@$res) {
($time, $t_soll, $t_ist, $t_speicher, $C_betriebs_zeit) = @$row;
print DATEI "WW-Time: $time t_soll $t_soll, t_ist $t_ist, t_speicher $t_speicher, betriebs_zeit $C_betriebs_zeit\n";
# print("Time: $time t_aussen $t_aussen, hk_soll $t_soll_HK1, hk ist $t_ist_HK1, betrieb_gesamt $C_betrieb_gesamt, betrieb_heizung $C_betrieb_heizung, brenner_ges_ein $C_brenner_gesamt, brenner_hzg_ein $C_brenner_heizung, betriebsart $V_betriebs_art\n");
}
## Zeilen ausgeben, Heizkreis
my ($time, $t_aussen, $t_soll_HK1, $t_ist_HK1, $C_betrieb_gesamt, $C_betrieb_heizung, $C_brenner_gesamt, $C_brenner_heizung, $V_betriebs_art) = "";
my $res = $dbh->selectall_arrayref("SELECT Local_date_time, T_aussen, T_soll_HK1, T_ist_HK1, C_betrieb_gesamt, C_betrieb_heizung, C_brenner_gesamt, C_brenner_heizung, V_betriebs_art FROM heizkreis ORDER BY rowid DESC LIMIT 1 ;");
foreach my $row (@$res) {
($time, $t_aussen, $t_soll_HK1, $t_ist_HK1, $C_betrieb_gesamt, $C_betrieb_heizung, $C_brenner_gesamt, $C_brenner_heizung, $V_betriebs_art) = @$row;
print DATEI "HK-Time: $time t_aussen $t_aussen, hk_soll $t_soll_HK1, hk_ist $t_ist_HK1, betrieb_gesamt $C_betrieb_gesamt, betrieb_heizung $C_betrieb_heizung, brenner_ges_ein $C_brenner_gesamt, brenner_hzg_ein $C_brenner_heizung, betriebsart $V_betriebs_art\n";
# print("Time: $time t_aussen $t_aussen, hk_soll $t_soll_HK1, hk ist $t_ist_HK1, betrieb_gesamt $C_betrieb_gesamt, betrieb_heizung $C_betrieb_heizung, brenner_ges_ein $C_brenner_gesamt, brenner_hzg_ein $C_brenner_heizung, betriebsart $V_betriebs_art\n");
}
## Datenbank und Datei schließen
if ($dbh->err()) { die "$DBI::errstr\n"; }
$dbh->disconnect();
close (DATEI);
Im Crontab bitte die folgende Zeile ergänzen:
*/05 * * * * pi /usr/bin/perl -S date_sql_extract.pl
(siehe auch Anleitung von Norbert)
Damit wird alle 5 Minuten die Ausgabe der Daten in der Datei "hzg.txt" angestoßen
In FHEM wird nun über das Modul HTTPMOD die Variablen in einer selbst definierbaren Zeit gefüllt. Hierzu habe frage ich die Datei hzg.txt immer ab.
Inhalt der hzg.txt:
SO-Time: 2014.04.08 16:54:35 - Temp_Koll: 23, T-Speicher 43 ,Ertrag: 36 ,Laufzeit SP 6104
HG-Time: 2014.04.08 16:54:56 vorlauf_soll 51, vorlauf_ist 42.6, hg_modus 0, brenner_lstg 0, hp_an 1, zp_an 0, wwp_an 0
WW-Time: 2014.04.08 16:54:57 t_soll 50, t_ist 48.7, t_speicher 48.7, betriebs_zeit 12157
HK-Time: 2014.04.08 16:54:37 t_aussen 7.7, hk_soll 23, hk_ist 32.1, betrieb_gesamt 177094, betrieb_heizung 164936, brenner_ges_ein 73681, brenner_hzg_ein 73296, betriebsart 3
Definieren der Variablen über Modul HTTPMOD in FHEM:
ACHTUNG: Auch hier die IP-Adresse des Raspberrys richtig angeben, bei mir ist es 192.168.3.115 Der Wert hinter dem Link gibt die Abfrage der Werte in Sekunden ab, 600= alle 10 Minuten. Denk bitte daran, es macht nicht sinn, hier das Intervall kürzer einzustellen als im Cronjob, mit dessen die Datei hzg.txt erzeugt wird.
define hzg_solar HTTPMOD http://192.168.3.115/hzg.txt 600
attr hzg_solar readingsName.1 temp_kollektor
attr hzg_solar readingsName.2 temp_ww_u
attr hzg_solar readingsName.3 solar_ertrag_h
attr hzg_solar readingsName.4 hzg_laufzeit_sp
attr hzg_solar readingsRegex.1 Temp_Koll: ([\d\.]+)
attr hzg_solar readingsRegex.1Temp_Koll: (-?[\d\.]+)
attr hzg_solar readingsRegex.2 T-Speicher ([\d\.]+)
attr hzg_solar readingsRegex.3 Ertrag: ([\d\.]+)
attr hzg_solar readingsRegex.4 Laufzeit SP ([\d\.]+)
attr hzg_solar room Junkers
attr hzg_solar stateFormat {sprintf("Temperatur Kollektor %.1fC, Temperatur WW-Speicher unten %.1fC , Temperatur Solarertrag letze Stunde %.0fW, Laufzeit Solarpumpe %.0fmin", ReadingsVal($name,"temp_kollektor",0), ReadingsVal($name,"temp_ww_u",0), ReadingsVal($name,"solar_ertrag_h",0), ReadingsVal($name,"hzg_laufzeit_sp",0))}
define hzg_kessel HTTPMOD http://192.168.3.115/hzg.txt 300
attr hzg_kessel readingsName.1 hzg_kessel_soll
attr hzg_kessel readingsName.2 hzg_kessel_ist
attr hzg_kessel readingsName.3 hzg_brenner_lstg
attr hzg_kessel readingsName.4 hzg_hp_an
attr hzg_kessel readingsName.5 hzg_zp_an
attr hzg_kessel readingsName.6 hzg_wwp_an
attr hzg_kessel readingsRegex.1 vorlauf_soll ([\d\.]+)
attr hzg_kessel readingsRegex.2 vorlauf_ist ([\d\.]+)
attr hzg_kessel readingsRegex.3 brenner_lstg ([\d\.]+)
attr hzg_kessel readingsRegex.4 hp_an ([\d\.]+)
attr hzg_kessel readingsRegex.5 zp_an ([\d\.]+)
attr hzg_kessel readingsRegex.6 wwp_an ([\d\.]+)
attr hzg_kessel room Junkers
attr hzg_kessel stateFormat {sprintf("Kessel_soll %.1fC, Kessel_ist %.1fC , Brennerlstg %.0fpct, Heiz.Pumpe %.0f, Zirk-Pump %.0f, WW-Pump %.0f", ReadingsVal($name,"hzg_kessel_soll",0), ReadingsVal($name,"hzg_kessel_ist",0), ReadingsVal($name,"hzg_brenner_lstg",0), ReadingsVal($name,"hzg_hp_an",0),ReadingsVal($name,"hzg_zp_an",0),ReadingsVal($name,"hzg_wwp_an",0))}
define hzg_heizkreis HTTPMOD http://192.168.3.115/hzg.txt 300
attr hzg_heizkreis readingsName.1 hzg_t_aussen
attr hzg_heizkreis readingsName.2 hzg_hk_soll
attr hzg_heizkreis readingsName.3 hzg_hk_ist
attr hzg_heizkreis readingsName.4 hzg_betrieb_ges
attr hzg_heizkreis readingsName.5 hzg_betrieb_hzg
attr hzg_heizkreis readingsName.6 brenner_ges_ein
attr hzg_heizkreis readingsName.7 hzg_hk_betriebsart
attr hzg_heizkreis readingsRegex.1 t_aussen (-?[\d\.]+)
attr hzg_heizkreis readingsRegex.2 hk_soll ([\d\.]+)
attr hzg_heizkreis readingsRegex.3 hk_ist ([\d\.]+)
attr hzg_heizkreis readingsRegex.4 betrieb_gesamt ([\d\.]+)
attr hzg_heizkreis readingsRegex.5 betrieb_heizung ([\d\.]+)
attr hzg_heizkreis readingsRegex.6 brenner_ges_ein ([\d\.]+)
attr hzg_heizkreis readingsRegex.7 betriebsart ([\d\.]+)
attr hzg_heizkreis room Junkers
attr hzg_heizkreis stateFormat {sprintf("Aussentmp %.1f C, HK_soll %.1fC , HK_ist %.1fC, Heiz.Betr.ges %.0fmin, Hzg.Betrieb.Hzg %.0fmin, Brenner_ges_ein %.0fx, Betriebsart %.0f", ReadingsVal($name,"hzg_t_aussen",0), ReadingsVal($name,"hzg_hk_soll",0), ReadingsVal($name,"hzg_hk_ist",0), ReadingsVal($name,"hzg_betrieb_ges",0),ReadingsVal($name,"hzg_betrieb_hzg",0),ReadingsVal($name,"brenner_ges_ein",0),ReadingsVal($name,"hzg_hk_betriebsart",0))}
define hzg_ww HTTPMOD http://192.168.3.115/hzg.txt 300
attr hzg_ww readingsName.1 hzg_ww_tspeicher_soll
attr hzg_ww readingsName.2 hzg_ww_tspeicher_ist
attr hzg_ww readingsName.3 hzg_ww_betrieb_ges
attr hzg_ww readingsRegex.1 t_soll ([\d\.]+)
attr hzg_ww readingsRegex.2 t_ist ([\d\.]+)
attr hzg_ww readingsRegex.3 betriebs_zeit ([\d\.]+)
attr hzg_ww room Junkers
attr hzg_ww stateFormat {sprintf("Speicher_soll %.1fC, Speicher_ist %.1fC , WW.Betrz.ges %.0fmin", ReadingsVal($name,"hzg_ww_tspeicher_soll",0), ReadingsVal($name,"hzg_ww_tspeicher_ist",0), ReadingsVal($name,"hzg_ww_betrieb_ges",0))}
Damit kann man alle Daten auch in den SVG-Grafiken darstellen, z.B. den Solarertrag:
define PL_SOLARZAEHLER SVG logdb:hzg:HISTORY
attr PL_SOLARZAEHLER label my $zeit_akt = 0+(($hour+0)+($min/60));;;; my $sol_ertrag_tag=$zeit_akt*$data{avg1};;;;my $sol_ert_ges=Value("solarertrag_gesamt");; sprintf("Solarertrag: Aktuell %.0f W/ Avg: %.2fW/ Max: %.0fW /Stunden %.1f / Tagesertrag: %.0fW, %.0fkW", $data{currval1}, $data{avg1}, $data{max1}, $zeit_akt, $sol_ertrag_tag,$sol_ert_ges)
attr PL_SOLARZAEHLER room Junkers
Die zugehörige Datei zur Grafikdarstellung ist mit im Anhang (hzg.gplot)
Wie bereits Eingangs geschrieben, es ist der erste Ansatz zur Erzeugung von Daten der Junkers-Therme in FHEM. Wenn jemand ein perl-FHEM-Modul schreiben möchte, ich würde es gerne auch nutzen.
Die auszugebenden Daten können einfach angepasst werden. Ich habe auch den Solarertrag in Summe und für den jeweiligen Tag über diese Werte erzeugt, hier reicht es, eine kleine Progrämmchen in myUtils.pm einzutragen, welches bei einer Änderung der Solarwerte aufgerufen wird, dann hat man auch diese Werte passend.
Dieses ist jedoch alles (einschl. der obige Code und Weg) noch in der Erprobung und Fehler sind definitiv nicht auszuschließen. So wird z.B. die Aussentemperatur und auch die Temperatur des Solarkollektors falsch ausgewertet (negative Werte werden als 0 Grad interpretiert). Auch ist die Benennung der "Variablen" sicherlich verbesserungswürdig, aber, es geht zum Testen vorerst.
Wenn ich mehr Zeit bekomme, dann geht es auch noch weiter. Auf Wunsch kann ich auch noch meien myUtils.pm hier anhängen bzw. die Schritte für die Anzeige des Solarertrags erklären, jedoch ist gerade dieses noch in der Erprobung und hat zwischendurch auch einmal einen falschen Wert erzeugt.
Sollte ich einen Schritt vergessen haben oder sollte die Kurzanleitung nicht ausreichen, so bitte kurze Antwort hier im Forum für alle oder auch per PM.
Viel Spaß.
Gruß
Kai