Neue Version Plugin
Hallo zusammen,
ich habe ja geschrieben, dass nach dem Aus- und wieder Einschalten des Kessels der Tagesverbrauch abnorm hohe Werte liefert.
Das Problem liegt in den vom Kessel gelieferten Daten für den Gesamtverbrauch. Der Gesamtverbrauch ist nach dem Einschalten geringfügig niedriger als vor dem letzten Ausschalten. Mit dieser dann negativen Differenz kommt das RRD nicht klar.
Ich habe dies nun im Plugin abgefangen, damit auch in diesem Fall realistische Werte geschrieben werden.
Es wäre gut, wenn das jemand in SVN laden könnte. Mir ist das bisher nie gelungen.
Viele Grüße
Sascha
Hallo zusammen,
ich habe ja geschrieben, dass nach dem Aus- und wieder Einschalten des Kessels der Tagesverbrauch abnorm hohe Werte liefert.
Das Problem liegt in den vom Kessel gelieferten Daten für den Gesamtverbrauch. Der Gesamtverbrauch ist nach dem Einschalten geringfügig niedriger als vor dem letzten Ausschalten. Mit dieser dann negativen Differenz kommt das RRD nicht klar.
Ich habe dies nun im Plugin abgefangen, damit auch in diesem Fall realistische Werte geschrieben werden.
Es wäre gut, wenn das jemand in SVN laden könnte. Mir ist das bisher nie gelungen.
Viele Grüße
Sascha
Code:
# Plugin: Schnittstelle zum Pelletskessel ETA-PU
# Version 1.3
# License: GPL (v3)
# Dieses Plugin dient als Schnittstelle zwischen KNX und dem ETA Heizkessel PU (Pellets Unit).
# Verwendet wird hierbei die ETAtouch RESTful Webservices Schnittstelle, die mit der Anbindung
# des Kessels an www.meineta.at zur Verfügung steht.
#
# Eine Beschreibung der Schnittstelle ist unter diesem Link verfügbar:
# https://www.meineta.at/user/download.action?contentType=application%2Fpdf&file=ETA-RESTful-v1.pdf
# CAN-BUS-URI können in der XML-Datei für die Menüstruktur entnommen werden:
# http://ip:port/user/menu
# Aktuell werden folgende Features unterstützt:
# 1. Lesen von festgelegten Kesseldaten in einem festgelegten Intervall (aktuell 1 Minute):
# - Schreiben der Kesselwerte auf KNX-Gruppenadressen
# > DPT wird über ein Mapping der Einheiten bestimmt)
# - Schreiben von Statustexten auf KNX-Gruppenadressen
# > DPT wird über Import der Gruppenadressen ins Wiregate bestimmt
# - Aufzeichnen der Kesselwerte in RRD für Messwerte (GAUGE)
# > RRD wird mit Standardparametern automatisch angelegt
# - Aufzeichnen von Tageswerten auf Basis von Zählerständen des Kessel in RRD für Zähler (COUNTER)
# > RRD wird mit den entsprechenden Parametern automatisch angelegt, falls noch vorhanden
# - Aufzeichnen der Statusänderungen je Tag (z. B. Anzahl Ladevorgänge)
# auf Basis von durch das Plugin erzeugten Zählerständen in RRD für Zähler (COUNTER)
# > RRD wird mit den entsprechenden Parametern automatisch angelegt, falls noch vorhanden
# > Die Beschreibung des Statuswerts lässt sich über die gespeicherten Plugin_Info ablesen
# z. B. ETA_PU2KNX_Connector.pl_112/10021/0/0/12000_Status_6 = Heizen
# 2. Lesen der Meldungen der Kesselsteuerung in einem festgelegten Intervall (aktuell 1 Minute)
# - Schreiben einer Status Grupenadresse: Meldung Ja/Nein
# - Schreiben der Anzahl der Meldungen auf eine Gruppenadresse
# 3. Empfangen von KNX-Schreibtelegrammen von festgelegten KNX-Gruppenadressen
# und Schreiben in die Steuerung des Kessels.
# Achtung: Es dürfen nicht die selben Gruppenadressen wie beim Lesen der Kesseldaten verwendet werden!!!
# Folgende Features werden aktuell durch das Plugin noch nicht unterstützt:
# - Lesen und Schreiben auf Werte der Schaltuhren
# - Empfangen von KNX-Lesetelegrammen von festgelegten KNX-Gruppenadressen,
# Lesen der entsprechenden Kesseldaten und Schreiben der Kesselwerte auf KNX-Gruppenadressen
# - Schreiben der Fehlermeldungen in einen RSS-Feed
#
# Folgende Features werden aktuell durch die ETAtouch RESTful Webservices Schnittstelle noch nicht unterstützt:
# - Lesen der aktuellen Pumpenleistung in %
# - Lesen und Schreiben auf Werte die mit der Service Anmeldung in der Kesselsteuerung zur Verfügung stehen
# - Ein-/Ausschalten der Schaltuhren
# Die Fachliche Diskussion zu dem Plugin findet im knx-user-forum.de statt:
# https://knx-user-forum.de/knx-eib-forum/16767-plugin-pelletskessel-eta-pu-new-post.html
#
# Mitwirkende bei der Entwicklung des Plugins:
# Matthias Lemke greentux
# Sascha Bank haegar80
# Kontaktaufnahme bitte über das knx-user-forum.de
## Beginn Definitionen ##
my $IP_PU = "192.168.10.11:8080";
my $TimeoutSek = 5;
my $ResVariables = "/user/vars";
my $ResSingleVariable = "/user/var";
my $ResErrors = "/user/errors";
my $set = "basic";
my $DirRrd = "/var/www/rrd/";
my $GA_Fehler = "10/0/3";
my $DPT_GA_Fehler = "1.001";
my $GA_AnzahlFehler = "10/0/4";
my $DPT_GA_AnzahlFehler = "5.010";
# Mapping ETA can-bus-uri zu Gruppenadressen für Werte aus string Rückgaben
my %string_GA_URI_mapping = (
'10/0/0' => '112/10021/0/0/12000', # Kessel - Kesselstatus (Text)
'10/0/42' => '112/10021/0/0/12078', # Kessel - VL1-Regler
'10/0/52' => '112/10021/0/0/12203', # Kessel - VL2-Regler
'10/0/48' => '112/10021/0/11128/0', # Kessel - UV-Speicher (Text)
'10/0/80' => '112/10021/0/0/12050', # Kessel - Entaschung Status (Text)
'10/0/90' => '112/10021/0/0/12248', # Kessel - Beginn Ruhezeit
'10/0/95' => '112/10021/0/0/12249', # Kessel - Dauer Ruhezeit
'10/0/185' => '112/10021/0/0/12152', # Kessel - Pellets Saugzeitpunkt
'10/0/200' => '112/10021/0/0/12153', # Kessel - Betriebsstunden (Text)
'10/2/0' => '112/10101/0/0/12090', # HK - Status (Text)
'10/2/2' => '112/10101/0/0/12092', # HK - Betrieb (Text)
'10/2/20' => '112/10101/0/0/12232', # HK - Urlaub Beginn
'10/2/25' => '112/10101/0/0/12239', # HK - Urlaub Ende
'10/3/0' => '112/10102/0/0/12090', # FBH - Status (Text)
'10/3/2' => '112/10102/0/0/12092', # FBH - Betrieb (Text)
'10/3/20' => '112/10102/0/0/12232', # FBH - Urlaub Beginn
'10/3/25' => '112/10102/0/0/12239', # FBH - Urlaub Ende
'10/5/0' => '112/10111/0/0/12129', # WW - Schaltzustand (Text)
);
# Mapping ETA can-bus-uri zu Gruppenadressen für Werte aus Value Rückgaben
my %value_GA_URI_mapping = (
'10/0/1' => '112/10021/0/0/12000', # Kessel - Kesselstatus (Code)
'10/0/2' => '112/10241/0/11149/2001', # Kessel - Störmeldung
'10/0/6' => '112/10021/0/0/12080', # Kessel - I/O Taste
'10/0/8' => '112/10021/0/0/12115', # Kessel - Emissionsmessung
'10/0/9' => '112/10241/0/0/12197', # Kessel - Außentemperatur
'10/0/10' => '112/10021/0/0/12001', # Kessel - Kessel Solltemperatur
'10/0/11' => '112/10021/0/0/12161', # Kessel - Isttemperatur
'10/0/12' => '112/10021/0/0/12300', # Kessel - Isttemperatur unten
'10/0/20' => '112/10021/0/0/12180', # Kessel - Druck
'10/0/21' => '112/10021/0/0/12162', # Kessel - Abgastemperatur
'10/0/22' => '112/10021/0/0/12165', # Kessel - Drehzahl Abgasgebläse
'10/0/23' => '112/10021/0/0/12164', # Kessel - Restsauerstoff
'10/0/40' => '112/10021/0/11121/2120', # Kessel - VL1-Solltemperatur
'10/0/41' => '112/10021/0/11121/2121', # Kessel - VL1-Isttemperatur
'10/0/43' => '112/10021/0/0/12078', # Kessel - VL1-Regler
'10/0/45' => '112/10021/0/11123/2001', # Kessel - Kesselpumpe 1 / Status
'10/0/46' => '112/10021/0/11123/0', # Kessel - Kesselpumpe 1 / Leistung
'10/0/49' => '112/10021/0/11128/0', # Kessel - UV-Speicher (Code)
'10/0/50' => '112/10021/0/11152/2120', # Kessel - VL2-Solltemperatur
'10/0/51' => '112/10021/0/11152/2121', # Kessel - VL2-Isttemperatur
'10/0/53' => '112/10021/0/0/12203', # Kessel - VL2-Regler
'10/0/55' => '112/10021/0/11138/2001', # Kessel - Kesselpumpe 2 / Status
'10/0/56' => '112/10021/0/11138/0', # Kessel - Kesselpumpe 2 / Leistung
'10/0/81' => '112/10021/0/0/12050', # Kessel - Entaschung Status (Code)
'10/0/86' => '112/10021/0/0/12112', # Kessel - Entaschentaste
'10/0/100' => '112/10021/0/0/12073', # Kessel - Entaschen nach kg frühestens
'10/0/103' => '112/10021/0/0/12074', # Kessel - Entaschen nach kg spätestens
'10/0/111' => '112/10021/0/0/12120', # Kessel - Kübel leeren nach
'10/0/170' => '112/10201/0/0/12015', # Silo - Vorrat
'10/0/175' => '112/10021/0/0/12011', # Kessel - Pellets Behälterinhalt
'10/0/181' => '112/10021/0/0/12071', # Kessel - Pellets Füllen
'10/0/201' => '112/10021/0/0/12153', # Kessel - Betriebsstunden (Sekunden)
'10/0/205' => '112/10021/0/0/12016', # Kessel - Gesamtverbrauch
'10/0/210' => '112/10021/0/0/12014', # Kessel - kg seit Wartung
'10/0/211' => '112/10021/0/0/12012', # Kessel - kg seit Entaschung
'10/0/212' => '112/10021/0/0/12013', # Kessel - kg seit Kübel entleeren
'10/2/1' => '112/10101/0/0/12090', # HK - Status (Code)
'10/2/3' => '112/10101/0/0/12092', # HK - Betrieb (Code)
'10/2/6' => '112/10101/0/0/12080', # HK - I/O Taste
'10/2/11' => '112/10101/0/0/12126', # HK - Auto Taste
'10/2/13' => '112/10101/0/0/12125', # HK - Tag Taste
'10/2/15' => '112/10101/0/0/12230', # HK - Nacht Taste
'10/2/17' => '112/10101/0/0/12218', # HK - Kommen Taste
'10/2/19' => '112/10101/0/0/12231', # HK - Gehen Taste
'10/2/30' => '112/10101/0/0/12111', # HK - Solltemperatur
'10/2/36' => '112/10101/0/0/12240', # HK - Schieber Position
'10/2/41' => '112/10101/0/0/12104', # HK - Vorlauf bei -10°C
'10/2/43' => '112/10101/0/0/12103', # HK - Vorlauf bei +10°C
'10/2/45' => '112/10101/0/0/12107', # HK - Vorlauf Absenkung
'10/2/47' => '112/10101/0/0/12096', # HK - Heizgrenze Tag
'10/2/49' => '112/10101/0/0/12097', # HK - Heizgrenze Nacht
'10/2/50' => '112/10101/12095/0/1071', # HK - Außen verzögert (Lag x)
'10/2/51' => '112/10101/12095/0/1072', # HK - Außen verzögert (Lag Tf)
'10/2/53' => '112/10101/12095/0/1073', # HK - Außen verzögert (Lag y)
'10/3/1' => '112/10102/0/0/12090', # FBH - Status (Code)
'10/3/3' => '112/10102/0/0/12092', # FBH - Betrieb (Code)
'10/3/6' => '112/10102/0/0/12080', # FBH - I/O Taste
'10/3/11' => '112/10102/0/0/12126', # FBH - Auto Taste
'10/3/13' => '112/10102/0/0/12125', # FBH - Tag Taste
'10/3/15' => '112/10102/0/0/12230', # FBH - Nacht Taste
'10/3/17' => '112/10102/0/0/12218', # FBH - Kommen Taste
'10/3/19' => '112/10102/0/0/12231', # FBH - Gehen Taste
'10/3/30' => '112/10102/0/0/12111', # FBH - Solltemperatur
'10/3/36' => '112/10102/0/0/12240', # FBH - Schieber Position
'10/3/41' => '112/10102/0/0/12104', # FBH - Vorlauf bei -10°C
'10/3/43' => '112/10102/0/0/12103', # FBH - Vorlauf bei +10°C
'10/3/45' => '112/10102/0/0/12107', # FBH - Vorlauf Absenkung
'10/3/47' => '112/10102/0/0/12096', # FBH - Heizgrenze Tag
'10/3/49' => '112/10102/0/0/12097', # FBH - Heizgrenze Nacht
'10/3/50' => '112/10102/12095/0/1071', # FBH - Außen verzögert (Lag x)
'10/3/51' => '112/10102/12095/0/1072', # FBH - Außen verzögert (Lag Tf)
'10/3/53' => '112/10102/12095/0/1073', # FBH - Außen verzögert (Lag y)
'10/3/60' => '112/10102/12113/0/1109', # FBH - Zeitautomatik Schaltzustand
'10/2/60' => '112/10101/12113/0/1109', # HK - Zeitautomatik Schaltzustand
'10/5/1' => '112/10111/0/0/12129', # WW - Schaltzustand (Code)
'10/5/6' => '112/10111/0/0/12134', # WW - Laden Taste
'10/5/10' => '112/10111/0/0/12132', # WW - Solltemperatur
'10/5/16' => '112/10111/0/0/12133', # WW - Einschaltdifferenz
'10/5/17' => '112/10111/0/0/12135', # WW - Temperatur Speicher unten Aus
'10/5/20' => '112/10111/0/0/12271', # WW - Temperatur Speicher oben
'10/5/21' => '112/10111/0/0/12272', # WW - Temperatur Speicher unten
'10/5/60' => '112/10111/12130/0/1109', # WW - Zeitautomatik Schaltzustand
'10/5/61' => '112/10111/12130/0/1110', # WW - Zeitautomatik Temperatur
);
# Mapping ETA can-bus-uri zu Gruppenadressen für Schreibaktionen
my %write_GA_URI_mapping = (
'10/0/5' => '112/10021/0/0/12080', # Kessel - I/O Taste
'10/0/7' => '112/10021/0/0/12115', # Kessel - Emissionsmessung
'10/0/85' => '112/10021/0/0/12112', # Kessel - Entaschentaste
'10/0/101' => '112/10021/0/0/12073', # Kessel - Entaschen nach kg frühestens
'10/0/102' => '112/10021/0/0/12074', # Kessel - Entaschen nach kg spätestens
'10/0/110' => '112/10021/0/0/12120', # Kessel - Kübel leeren nach
'10/0/180' => '112/10021/0/0/12071', # Kessel - Pellets Füllen
'10/2/5' => '112/10101/0/0/12080', # HK - I/O Taste
'10/2/10' => '112/10101/0/0/12126', # HK - Auto Taste
'10/2/12' => '112/10101/0/0/12125', # HK - Tag Taste
'10/2/14' => '112/10101/0/0/12230', # HK - Nacht Taste
'10/2/16' => '112/10101/0/0/12218', # HK - Kommen Taste
'10/2/18' => '112/10101/0/0/12231', # HK - Gehen Taste
'10/2/35' => '112/10101/0/0/12240', # HK - Schieber Position
'10/2/40' => '112/10101/0/0/12104', # HK - Vorlauf bei -10°C
'10/2/42' => '112/10101/0/0/12103', # HK - Vorlauf bei +10°C
'10/2/44' => '112/10101/0/0/12107', # HK - Vorlauf Absenkung
'10/2/46' => '112/10101/0/0/12096', # HK - Heizgrenze Tag
'10/2/48' => '112/10101/0/0/12097', # HK - Heizgrenze Nacht
'10/2/52' => '112/10101/12095/0/1072', # HK - Außen verzögert (Lag Tf)
'10/3/5' => '112/10102/0/0/12080', # FBH - I/O Taste
'10/3/10' => '112/10102/0/0/12126', # FBH - Auto Taste
'10/3/12' => '112/10102/0/0/12125', # FBH - Tag Taste
'10/3/14' => '112/10102/0/0/12230', # FBH - Nacht Taste
'10/3/16' => '112/10102/0/0/12218', # FBH - Kommen Taste
'10/3/18' => '112/10102/0/0/12231', # FBH - Gehen Taste
'10/3/35' => '112/10102/0/0/12240', # FBH - Schieber Position
'10/3/40' => '112/10102/0/0/12104', # FBH - Vorlauf bei -10°C
'10/3/42' => '112/10102/0/0/12103', # FBH - Vorlauf bei +10°C
'10/3/44' => '112/10102/0/0/12107', # FBH - Vorlauf Absenkung
'10/3/46' => '112/10102/0/0/12096', # FBH - Heizgrenze Tag
'10/3/48' => '112/10102/0/0/12097', # FBH - Heizgrenze Nacht
'10/3/52' => '112/10102/12095/0/1072', # FBH - Außen verzögert (Lag Tf)
'10/5/5' => '112/10111/0/0/12134', # WW - Laden Taste
'10/5/15' => '112/10111/0/0/12133', # WW - Einschaltdifferenz
'10/5/18' => '112/10111/0/0/12135', # WW - Temperatur Speicher unten Aus
);
# Mapping ETA can-bus-uri zu RRD Graphen (Gauge = Messerte) aus Value Rückgaben
my %value_URI_RRD_mapping = (
'112/10021/0/0/12001' => 'Heizung_KesselSolltemperatur',
'112/10021/0/0/12161' => 'Heizung_Kesseltemperatur',
'112/10021/0/0/12300' => 'Heizung_KesseltemperaturUnten',
'112/10021/0/0/12180' => 'Heizung_Kesseldruck',
'112/10021/0/0/12162' => 'Heizung_Abgastemperatur',
'112/10021/0/0/12165' => 'Heizung_DrehzahlAbgasgebläse',
'112/10021/0/0/12164' => 'Heizung_Restsauerstoff',
'112/10241/0/0/12197' => 'Heizung_Aussentemperatur',
'112/10021/0/11121/2120' => 'Heizung_VL1_Solltemperatur',
'112/10021/0/11121/2121' => 'Heizung_VL1_Isttemperatur',
'112/10021/0/11152/2120' => 'Heizung_VL2_Solltemperatur',
'112/10021/0/11152/2121' => 'Heizung_VL2_Isttemperatur',
'112/10101/0/0/12111' => 'Heizung_HK_Solltemperatur',
'112/10101/0/0/12240' => 'Heizung_HK_Schieber',
'112/10102/0/0/12111' => 'Heizung_FBH_Solltemperatur',
'112/10102/0/0/12240' => 'Heizung_FBH_Schieber',
'112/10111/0/0/12132' => 'Heizung_WW_Solltemperatur',
'112/10111/0/0/12271' => 'Heizung_WW_TemperaturSpeicherOben',
'112/10111/0/0/12272' => 'Heizung_WW_TemperaturSpeicherUnten',
);
# Mapping ETA can-bus-uri zu RRD Graphen für Tageszähler von Statuswechseln aus Value Rückgaben
my %value_URI_RRDdaycountStatus_mapping = (
'112/10021/0/0/12000' => 'Heizung_KesselStatus',
'112/10021/0/11128/0' => 'Heizung_UVstatus',
'112/10021/0/0/12050' => 'Heizung_EntaschungStatus',
'112/10101/0/0/12090' => 'Heizung_HKstatus',
'112/10101/0/0/12092' => 'Heizung_HKbetrieb',
'112/10102/0/0/12090' => 'Heizung_FBHstatus',
'112/10102/0/0/12092' => 'Heizung_FBHbetrieb',
'112/10111/0/0/12129' => 'Heizung_WWstatus',
);
# Mapping ETA can-bus-uri zu RRD Graphen für Tageszähler (aus Zählerstand) aus Value Rückgaben
my %value_URI_RRDdaycount_mapping = (
'112/10021/0/0/12016' => 'Heizung_PelletsverbrauchTag',
'112/10021/0/0/12153' => 'Heizung_Betriebssekunden',
);
# Mapping der ETA Einheiten zu KNX Datenpunkttypen
my %unit_DPT_mapping = (
"%" => '5.001',
"U/min" => '7.001',
"\N{U+00b0}C" => '9.001',
"Sek" => '9.010',
"bar" => '9.000',
'kg' => '14.051',
);
my $DPT_StatusText = "16.000";
## Ende Definitionen ##
#Module laden
use warnings;
use LWP::UserAgent;
use XML::Parser;
# Plugin alle 2 Minuten aufrufen
$plugin_info{$plugname.'_cycle'} = 60*2;
#Letzte Laufzeit protokollieren
update_rrd("LaufzeitPlugin_".$plugname,"",$plugin_info{$plugname.'_runtime'});
# Variablen definieren
my %value_GA_URI;
my %write_GA_URI;
my %string_GA_URI;
# ETA Variablenset anlegen, wenn Plugin durch Speichern aufgerufen
my $SetVar;
# Code vor PL30
#if ((stat('/etc/wiregate/plugin/generic/' . $plugname))[9] > time()-10) {
# Code nach PL30
if ($plugin_info{$plugname.'_lastsaved'} > $plugin_info{$plugname.'_last'} or $plugin_info{$plugname.'_lastSetVariable'} == 0) {
$SetVar = 1;
}
# ETA Variablenset anlegen, wenn Variablenset fehlt
if ($plugin_info{$plugname.'_lastSetVariable'} == 0) {
$SetVar = 1;
}
# ETA Variablenset anlegen
if ($SetVar) {
delete_set("http://".$IP_PU.$ResVariables, $set);
create_set("http://".$IP_PU.$ResVariables, $set);
plugin_log($plugname,"Variablenset anlegen: ".$set);
$plugin_info{$plugname.'_lastSetVariable'} = time();
}
for my $ga (%string_GA_URI_mapping) {
if (exists $string_GA_URI_mapping{$ga}) {
#$plugin_subscribe{$ga}{$plugname} = 1; #An Gruppenadresse anmelden
$string_GA_URI{$string_GA_URI_mapping{$ga}} = $ga; # Hash URI -> GA aus Hash GA->URI bilden
if ($SetVar) {
# ETA Uri zu Variablenset hinzufügen
add_to_set("http://".$IP_PU.$ResVariables, $set, $string_GA_URI_mapping{$ga});
plugin_log($plugname, "Variablenset erweitern: ".$set.
" - String URI".$string_GA_URI_mapping{$ga});
}
}
}
for my $ga (%value_GA_URI_mapping) {
if (exists $value_GA_URI_mapping{$ga}) {
#$plugin_subscribe{$ga}{$plugname} = 1; #An Gruppenadresse anmelden
$value_GA_URI{$value_GA_URI_mapping{$ga}} = $ga; # Hash URI -> GA aus Hash GA->URI bilden
if ($SetVar) {
# ETA Uri zu Variablenset hinzufügen
add_to_set("http://".$IP_PU.$ResVariables, $set, $value_GA_URI_mapping{$ga});
plugin_log($plugname, "Variablenset erweitern: ".$set.
" - Value URI".$value_GA_URI_mapping{$ga});
}
}
}
for my $ga (%write_GA_URI_mapping) {
if (exists $write_GA_URI_mapping{$ga}) {
$plugin_subscribe{$ga}{$plugname} = 1; #An Gruppenadresse anmelden
$write_GA_URI{$write_GA_URI_mapping{$ga}} = $ga; # Hash URI -> GA aus Hash GA->URI bilden
if ($SetVar) {
# ETA Uri zu Variablenset hinzufügen
add_to_set("http://".$IP_PU.$ResVariables, $set, $write_GA_URI_mapping{$ga});
plugin_log($plugname, "Variablenset erweitern: ".$set.
" - Write URI".$write_GA_URI_mapping{$ga});
}
}
}
# Bei Schreibtelegramm Wert mit Faktor und Offset in Kesselsteuerung schreiben
if ($msg{'apci'} eq "A_GroupValue_Write" and exists $write_GA_URI_mapping{$msg{'dst'}}) {
set_value( "http://".$IP_PU.$ResSingleVariable,$write_GA_URI_mapping{$msg{'dst'}},
$msg{'value'}
* $plugin_info{$plugname.'_'.$write_GA_URI_mapping{$msg{'dst'}}.'_scaleFactor'}
+ $plugin_info{$plugname.'_'.$write_GA_URI_mapping{$msg{'dst'}}.'_advTextOffset'});
plugin_log( $plugname, $write_GA_URI_mapping{$msg{'dst'}}." - GA ".$msg{'dst'}.
" - Wert schreiben: ". $msg{'value'}.
" / scaleFactor ". $plugin_info{$plugname.'_'.$write_GA_URI_mapping{$msg{'dst'}}.'_scaleFactor'}.
" advTextOffset ". $plugin_info{$plugname.'_'.$write_GA_URI_mapping{$msg{'dst'}}.'_advTextOffset'});
}
# Im Intervall oder nach Schreibtelegramm Werte aus der Kesselsteuerung lesen
if (! %msg or ($msg{'apci'} eq "A_GroupValue_Write" and exists $write_GA_URI_mapping{$msg{'dst'}})) {
my @values = query_user_set_variables("http://".$IP_PU.$ResVariables, $set);
for my $value (@values) {
# Werte für String auf GA schreiben
if (exists $string_GA_URI{$value->{uri}}) {
my $dpt = $DPT_StatusText || $eibgaconf{$string_GA_URI{$value->{uri}}}{'DPTSubId'};
knx_write($string_GA_URI{$value->{uri}},$value->{strValue},$dpt);
plugin_log($plugname, $value->{uri}." - GA ".$string_GA_URI{$value->{uri}}." DPT ".$dpt.
" - String lesen: ".$value->{strValue});
}
# Werte für Value auf GA schreiben
if (exists $value_GA_URI{$value->{uri}}) {
my $dpt = $unit_DPT_mapping{$value->{unit}} || $eibgaconf{$value_GA_URI{$value->{uri}}}{'DPTSubId'};
knx_write($value_GA_URI{$value->{uri}},($value->{RAW}/$value->{scaleFactor}-$value->{advTextOffset}),$dpt);
plugin_log($plugname, $value->{uri}." - GA ".$value_GA_URI{$value->{uri}}." DPT ".$dpt.
" - Wert lesen: ".($value->{RAW}/$value->{scaleFactor}-$value->{advTextOffset}));
}
#Faktor und Offset für Write URI merken
if (exists $write_GA_URI{$value->{uri}} and $SetVar) {
$plugin_info{$plugname.'_'.$value->{uri}.'_scaleFactor'} = $value->{scaleFactor};
$plugin_info{$plugname.'_'.$value->{uri}.'_advTextOffset'} = $value->{advTextOffset};
}
# Werte für Value auf RRD schreiben
if (exists $value_URI_RRD_mapping{$value->{uri}}) {
update_rrd($value_URI_RRD_mapping{$value->{uri}},"",($value->{RAW}/$value->{scaleFactor}-$value->{advTextOffset}));
plugin_log($plugname, $value->{uri}." - RRD ".$value_URI_RRD_mapping{$value->{uri}}.
" - Wert: ".($value->{RAW}/$value->{scaleFactor}-$value->{advTextOffset}));
}
# Werte für Value auf RRD für Statuswechsel schreiben
if (exists $value_URI_RRDdaycountStatus_mapping{$value->{uri}} and $plugin_info{$plugname.'_'.$value->{uri}.'_lastStatus'} ne ($value->{RAW}/$value->{scaleFactor}-$value->{advTextOffset}) ) {
$plugin_info{$plugname.'_'.$value->{uri}.'_lastStatus'} = ($value->{RAW}/$value->{scaleFactor}-$value->{advTextOffset});
$plugin_info{$plugname.'_'.$value->{uri}.'_Status_'.($value->{RAW}/$value->{scaleFactor}-$value->{advTextOffset})."_COUNTER"}++;
$plugin_info{$plugname.'_'.$value->{uri}.'_Status_'.($value->{RAW}/$value->{scaleFactor}-$value->{advTextOffset})} = $value->{strValue};
# Falls RRD noch nicht existiert, so soll er angelegt werden
if (! -e $DirRrd.$value_URI_RRDdaycountStatus_mapping{$value->{uri}}."_".($value->{RAW}/$value->{scaleFactor}-$value->{advTextOffset}).".rrd" ) {
RRDs::create( $DirRrd.$value_URI_RRDdaycountStatus_mapping{$value->{uri}}."_".($value->{RAW}/$value->{scaleFactor}-$value->{advTextOffset}).".rrd",
'--step' => 86400,
'DS:value:COUNTER:86500:0:10000000000',
'RRA:AVERAGE:0.5:1:365', 'RRA:AVERAGE:0.5:7:300');
plugin_log($plugname,$value->{uri}." - Status COUNTER-RRD ".$value_URI_RRDdaycountStatus_mapping{$value->{uri}}."_".($value->{RAW}/$value->{scaleFactor}-$value->{advTextOffset})." neu angelegt");
}
update_rrd( $value_URI_RRDdaycountStatus_mapping{$value->{uri}}."_".($value->{RAW}/$value->{scaleFactor}-$value->{advTextOffset}),"",
(86400*$plugin_info{$plugname.'_'.$value->{uri}.'_Status_'.($value->{RAW}/$value->{scaleFactor}-$value->{advTextOffset})."_COUNTER"}),"COUNTER");
plugin_log($plugname, $value->{uri}." - Status COUNTER-RRD ".
$value_URI_RRDdaycountStatus_mapping{$value->{uri}}."_".($value->{RAW}/$value->{scaleFactor}-$value->{advTextOffset}).
" - Wert: ".($value->{RAW}/$value->{scaleFactor}-$value->{advTextOffset}));
}
# Werte für Value auf RRD Tagesverbrauch schreiben
if (exists $value_URI_RRDdaycount_mapping{$value->{uri}} and ($value->{RAW}/$value->{scaleFactor}-$value->{advTextOffset}) > $plugin_info{$plugname.'_'.$value->{uri}.'_lastValue'}) {
# Falls RRD noch nicht existiert, so soll er angelegt werden
if (! -e $DirRrd.$value_URI_RRDdaycount_mapping{$value->{uri}}.".rrd" ) {
RRDs::create( $DirRrd.$value_URI_RRDdaycount_mapping{$value->{uri}}.".rrd",
'--step' => 86400,
'DS:value:COUNTER:86500:0:10000000000',
'RRA:AVERAGE:0.5:1:365', 'RRA:AVERAGE:0.5:7:300');
plugin_log($plugname,$value->{uri}." - COUNTER-RRD ".$value_URI_RRDdaycount_mapping{$value->{uri}}." neu angelegt");
}
update_rrd( $value_URI_RRDdaycount_mapping{$value->{uri}},"",
(86400*$value->{RAW}/$value->{scaleFactor}-$value->{advTextOffset}),"COUNTER");
$plugin_info{$plugname.'_'.$value->{uri}.'_lastValue'} = ($value->{RAW}/$value->{scaleFactor}-$value->{advTextOffset});
plugin_log($plugname, $value->{uri}." - COUNTER-RRD ".
$value_URI_RRDdaycount_mapping{$value->{uri}}.
" - Wert: ".($value->{RAW}/$value->{scaleFactor}-$value->{advTextOffset}));
}
}
# Wenn keine Werte zurückgeben werden, beim nächsten Durchlauf Variablenset neu anlegen
if (@values eq 0) {
$plugin_info{$plugname.'_lastSetVariable'} = 0;
}
# Fehlerprotokoll auslesen
my @values = query_errors("http://".$IP_PU.$ResErrors);
knx_write($GA_AnzahlFehler,1,$eibgaconf{$GA_AnzahlFehler}{'DPTSubId'} || $DPT_GA_AnzahlFehler);
plugin_log($plugname,"Anzahl Fehlermeldungen: ".@values);
if (@values > 0) {
knx_write($GA_Fehler,1,$eibgaconf{$GA_Fehler}{'DPTSubId'} || $DPT_GA_Fehler);
for my $value (@values) {
# TODO: RSS-Feed schreiben
plugin_log($plugname, "Meldung (".$value->{time}."): ".$value->{priority}." - ".
$value->{msg}." (".$value->{RAW}.")");
}
}
else {
knx_write($GA_Fehler,0,$eibgaconf{$GA_Fehler}{'DPTSubId'} || $DPT_GA_Fehler);
}
$plugin_info{$plugname.'_lastDataUpdate'} = time();
}
sub query_user_set_variables {
my ($base_url, $set) = @_;
my $url = "$base_url/$set";
my $response = do_request(GET => $url);
return parse_response($response, 'variable');
}
sub do_request {
my ($type, $url) = @_;
my $request = HTTP::Request->new($type => $url);
my $ua = LWP::UserAgent->new;
$ua->timeout($TimeoutSek);
my $response = $ua->request($request);
if ($response->content eq undef) {
return 'Abfrage '.$type.' - '.$url.' fehlgeschlagen' ;
}
return $response->content;
}
sub query_errors {
my ($url) = @_;
my $response = do_request(GET => $url);
return parse_response($response, 'error');
}
sub parse_response {
my ($response, $want_element) = @_;
my @result;
my $raw_value = '';
my $get_characters;
my $current_attributes;
my $start_handler = sub {
my ($expat, $element, %attr) = @_;
return if ($element ne $want_element);
$current_attributes = \%attr;
$get_characters = 1;
};
my $end_handler = sub {
my ($expat, $element) = @_;
return if ($element ne $want_element);
$get_characters = 0;
$current_attributes->{RAW} = $raw_value;
push @result, $current_attributes;
$raw_value = '';
};
my $char_handler = sub {
my ($expat, $value) = @_;
if ($get_characters) {
$raw_value .= $value;
}
};
my $parser = XML::Parser->new(Handlers => {Start => $start_handler,Char => $char_handler,End => $end_handler });
$parser->parse($response);
return @result;
}
sub set_value {
my ($base_url, $uri, $value) = @_;
my $url = "$base_url/$uri";
return post_request($url, value => $value);
}
sub post_request {
my ($url, %form) = @_;
my $ua = LWP::UserAgent->new;
$ua->timeout($TimeoutSek);
my $response = $ua->post($url, \%form);
if ($response->content eq undef) {
return 'HTTP POST '.\%form.' - '.$url.' fehlgeschlagen' ;
}
return $response->content;
}
sub create_set {
my ($base_url, $set) = @_;
my $url = "$base_url/$set";
# Ignore errors here, set might already be existing
eval {
do_request(PUT => $url);
};
}
sub delete_set {
my ($base_url, $set) = @_;
my $url = "$base_url/$set";
do_request(DELETE => $url);
}
sub add_to_set {
my ($base_url, $set, $uri) = @_;
my $url = "$base_url/$set/$uri";
do_request(PUT => $url);
}
sub delete_from_set {
my ($base_url, $set, $uri) = @_;
my $url = "$base_url/$set/$uri";
do_request(DELETE => $url);
}


Kommentar