|
 |
|

20.04.2012, 10:20
|
|
Benutzer
|
|
Registriert seit: 14.01.2010
Ort: NRW
Beiträge: 38
|
|
So kurz vor dem Sommer habe ich mal eine Frage. Wie habt ihr denn die Sommerabschaltung der Heizung realisiert?
Das Steuergerät meiner Heizung schaltet in den Sommermonaten automatisch den Heizbetrieb aus (nur noch Warmwasseraufbereitung), wenn die maximale Temperatur an zwei Tagen höher als 18 Grad war.
Ich überlege ob man diese Logik direkt ins Plugin integriert oder dafür ein eigenes Plugin erstellen sollte, welches die Temperaturreglung deaktiviert.
|

21.04.2012, 01:59
|
 |
Erfahrener Benutzer
|
|
Registriert seit: 07.07.2007
Beiträge: 11.779
|
|
Im Kern halte ich die "Logik" der üblichen Heizungsregelung (verschleppte Messwerte, Maximalwert aus 48h uvm) für bullsh**, das schaltet dann im März auf Sommer und mitten im Juli auch mal auf Winter
Was einzig&wirklich funktioniert ist die DIN-Methode (ich glaube, nicht sicher, 12831, dabei schon wieder ein schönes PDF gefunden - da steht aber das nicht direkt drin, ist jedoch im Kontext trotzdem informativ IMHO)
Der HS-Baustein (19830 von MatthiasS) tut das hier seither zuverlässig, ich nehme mir mal vor, daraus ein WG-Plugin zu machen
Im Kern ist es (wenn ich es richtig überflogen habe):
T1@7 Uhr
T2@14 Uhr
T3+4@ 22 Uhr
T1-4 / 4 ergibt sinnvollen Durchschnitt, so bei 15°C hier, lässt sich Sommer und Winter ohne Ausreisser ganz sicher unterscheiden..
Makki
__________________
EIB/KNX & HS3(+Lüfter+picoPSU80), Multiroom-AV mit Russound,mpd,vdr,DM8000, Profilux II+, N141 DALI, DMX, dez. Lüfter (RS485), Wärmepumpe (RS422), 30+ 1-Wire Temp,Luft&Bodenfeuchte,IRTrans
WireGate - Supportforum - bitte keine PN's!
|

21.04.2012, 13:45
|
 |
Erfahrener Benutzer
|
|
Registriert seit: 14.12.2008
Beiträge: 4.859
|
|
Zitat von derwolff2010
Wie habt ihr denn die Sommerabschaltung der Heizung realisiert?
[...]
Ich überlege ob man diese Logik direkt ins Plugin integriert oder dafür ein eigenes Plugin erstellen sollte, welches die Temperaturreglung deaktiviert.
|
Einer Temperatur-Regelung ist es vollkommen egal ob Sommer oder Winter ist. Das ist dort genau so relevant wie die Jahreszeiten auf dem Mars!
Die Regelung möchte mehr Energie in den Raum bringen wenn Soll > Ist und bei Ist > Soll entsprechend weniger.
=> Das Wissen ob Sommer oder Winter ist, gehört nicht in dieses Plugin.
Aber das Thema ist komplexer:
Die Regelung geht immer davon aus, dass aus der Leitung ein unerschöpflicher Energie-Vorrat kommt.
Wenn diese Annahme nicht mehr stimmt, z.B. weil im Sommer im Vorlauf kein warmes Medium mehr ist, sondern zum Kühlen ein kaltes zirkuliert, dann ist dringend die Regelung aus diesem Plugin zu deaktivieren. Dafür (und für den dann notwendigen Taupunkt-Schutz) würde ich aber ein anderes Plugin verwenden.
__________________
TS2, B.IQ, DALI, WireGate für 1wire so wie Server für Logik und auf HomeCockpit Minor. - Bitte keine PNs, Fragen gehören in das Forum, damit jeder was von den Antworten hat!
|

22.04.2012, 10:41
|
|
Benutzer
|
|
Registriert seit: 14.01.2010
Ort: NRW
Beiträge: 38
|
|
Zitat von Chris M.
Die Regelung geht immer davon aus, dass aus der Leitung ein unerschöpflicher Energie-Vorrat kommt.
|
Ich hatte ja oben geschrieben dass sich meine Heizung abschaltet, also keine unerschöpfliche Energiequelle ist. Das Plugin steuert also unnötigerweise die Stellantriebe im Sommerbetrieb an.
Da ich keinen großen Einfluß auf die Abschaltungslogik der Heizung habe, werde ich mir genau diese Logik nachbauen um dem Plugin zu melden dass keine Heizenergie zur Verfügung steht.
Die Erkennung des Sommerbetriebs lager ich dann wohl in ein eingenständiges Plugin aus.
Ich will das RTR-Plugin aber ungern während dieser Zeit komplett abschalten, da ich es um eine Ventilschutzfunktion (mindestens einmaliges Ansteuern der thermischen Stellantriebe pro Woche) erweitert hatte.
|

22.04.2012, 18:39
|
 |
Erfahrener Benutzer
|
|
Registriert seit: 14.12.2008
Beiträge: 4.859
|
|
Zitat von derwolff2010
Ich hatte ja oben geschrieben dass sich meine Heizung abschaltet, also keine unerschöpfliche Energiequelle ist.
|
Da kann man dann tatsächlich das Plugin für diese Zeit deaktivieren.
Evtl. musst Du dazu auch gar nichts nachbauen, evtl. reicht es schon die Vorlauftemperatur anzusehen...
Zitat von derwolff2010
Ich will das RTR-Plugin aber ungern während dieser Zeit komplett abschalten, da ich es um eine Ventilschutzfunktion (mindestens einmaliges Ansteuern der thermischen Stellantriebe pro Woche) erweitert hatte.
|
OK, das machen meine Heizungs-Aktoren von sich aus...
__________________
TS2, B.IQ, DALI, WireGate für 1wire so wie Server für Logik und auf HomeCockpit Minor. - Bitte keine PNs, Fragen gehören in das Forum, damit jeder was von den Antworten hat!
|

09.01.2013, 21:13
|
 |
Benutzer
|
|
Registriert seit: 02.06.2007
Ort: Mönchengladbach
Beiträge: 163
|
|
Hallo zusammen,
wusste gar nicht, dass es besser ist die Ventile ab und an mal fahren zu lassen. Damit sich dort nichts "festsetzt" ?!
Andere Frage: auch nach kurzer Recherche habe ich nichts bzgl. des Multi RTR's Plugin's und geöffneten / gekippten Fenstern gefunden. Gibt es hierzu auch schon einen Workaround, welchen man adaptieren könnte ?
Ich möchte das ja Heizkreisweise machen und nicht global ...
Danke und Gruß
Daniel
P.S.: wie macht Ihr das mit der Solltemperatur und Abwesenheit ? Wenn abwesend => dann Soll auf 17 Grad ?
__________________
Endlich kann Ich Bei Euch mitreden ...
:smilie_gladbach:
Geändert von harryhirsch3 (09.01.2013 um 22:19 Uhr)
|

09.01.2013, 22:13
|
|
Benutzer
|
|
Registriert seit: 13.12.2008
Ort: Lörrach
Beiträge: 22
|
|
Hallo,
[Achtung, der Post wird etwas länger...]
ich hab da was, was ich mal posten wollte...
Ist aber noch nicht komplett fertig und bestimmt auch nicht schön geschrieben, da ich kaum Perl verstehe. Und auch viel debugging drinnen.
Da du aber nun fragst, stelle ich das mal als "Erweiterung" des bestehenden Plugins vor. Vielleicht kann man ja Teile davon verwenden und ins SVN werfen?
Ich hatte Probleme, das manchmal die Ist-Temperatur nicht gelesen werden konnte, daher habe ich geändert, das in diesem Fall der Controller ignoriert wird (Bei mir passierte das so oft, das der Integralanteil so hoch wurde und der Raum war immer viel zu heiß).
Seither läuft das bei mir richtig gut.
Was leider noch fehlt sind die Fenster. Ich wollte mal noch einbauen, dass Heizung aus (oder Frostschutz), wenn Fenster länger als 10 Minuten auf.
Dafür hab ich ein anderes Plugin - ganz unten im Post. (Achtung, wieder seltsam programmiert, mit viel debugging ausgaben)
Das gibt mir den Status aus, auch wie lange ein Fenster schon auf oder zu ist. Kann aber auch nach x Minuten eine Sperr_GA senden, welche im Multi- RTR integriert werden könnte.
Nur wusste ich noch nicht genau wie...
Code:
#############################################################################
# Plugin: Multi RTR
# V0.7 2011-11-20
# Copyright: Christian Mayer (mail at ChristianMayer.de)
#
# V0.8 2012-01-13
# Copyright: Tobias Buss
#
# License: GPL (v3)
#
# Plugin for multiple RTR (room temperature controllers) by using a PI
# controller
#
# Suggested settings:
# ===================
# floor heating: ProportionalGain = 5 K, IntegralTime = 240 min (*)
# hot water heating: ProportionalGain = 5 K, IntegralTime = 150 min (*)
#
# Uebersetzungshilfe:
# ===================
# ProportionalGain = Proportionalbereich in Kelvin
# IntegralTime = Nachstellzeit in Minuten
#
# ---------
# (*): GIRA manual for TS2+ with RTR 1052-00 / 1055-00, 01/06, page 71
#############################################################################
#return;
#############################################################################
# Configuration:
# --> change values in the conf.d directory!
my %controllers = ();
my %default = ();
my $TempDropNightGA = '';
my $TempDropStandbyGA = '';
my $TempFixFrostGA = '';
my $TempDPT = '9.001';
my $GlobalDisableGA = '14/5/50';
my $reset = 0; # set to 1 to reset the states, run script and change to 0 again
my $show_debug = 0; # switches debug information that will be shown in the log
#############################################################################
# Do NOT change anything below!
#############################################################################
my $confFile = '/etc/wiregate/plugin/generic/conf.d/'.basename($plugname,'.pl').'.conf';
if (! -f $confFile)
{
plugin_log($plugname, " no conf file [$confFile] found.");
}
else
{
plugin_log($plugname, " reading conf file [$confFile].") if( $show_debug > 1);
open(CONF, $confFile);
my @lines = <CONF>;
close($confFile);
my $result = eval("@lines");
if( $show_debug > 1 )
{
($result) and plugin_log($plugname, "conf file [$confFile] returned result[$result]");
}
if ($@)
{
plugin_log($plugname, "conf file [$confFile] returned:") if( $show_debug > 1 );
my @parts = split(/\n/, $@);
if( $show_debug > 1 )
{
plugin_log($plugname, "--> $_") foreach (@parts);
}
}
}
#############################################################################
# main()
#############################################################################
my $busActive = !(!keys %msg); # true if script was called due to bus traffic
my $ret_val = '';
#############################################################################
# Initialisation
if( !$busActive ) # unnecesary during bus traffic
{
for my $this_controller_name ( keys %controllers )
{
my %this_controller = (%{$controllers{ $this_controller_name }}, %default);
# Initialise controller state variables
if( $reset or not exists $plugin_info{ $plugname . '_' . $this_controller_name . '_Actuator' } )
{
$plugin_info{ $plugname . '_' . $this_controller_name . '_SetPoint' } = $this_controller{ 'SetPointInit' };
$plugin_info{ $plugname . '_' . $this_controller_name . '_Integral' } = 0;
$plugin_info{ $plugname . '_' . $this_controller_name . '_Actuator' } = 0; # Reset
if( defined $this_controller{ 'SetPointGA' } and defined $this_controller{ 'SetPointDPT' } )
{
knx_write( $this_controller{ 'SetPointGA' }, $this_controller{ 'SetPointInit' }, $this_controller{ 'SetPointDPT' } ); # send initial value
}
# The ActuatorGA doesn't need to be sent here as !$busActive will also
# cause the first round of controller calculations
}
# subscribe SetPointGA
if( defined $this_controller{ 'SetPointGA' } )
{
$plugin_subscribe{ $this_controller{ 'SetPointGA' } }{ $plugname } = 1;
}
# subscribe SensorGA
if( defined $this_controller{ 'SensorGA' } )
{
$plugin_subscribe{ $this_controller{ 'SensorGA' } }{ $plugname } = 1;
}
# subscribe ActuatorGA
if( defined $this_controller{ 'ActuatorGA' } )
{
$plugin_subscribe{ $this_controller{ 'ActuatorGA' } }{ $plugname } = 1;
}
# subscribe DisableGA
if( defined $this_controller{ 'DisableGA' } )
{
$plugin_subscribe{ $this_controller{ 'DisableGA' } }{ $plugname } = 1;
$ret_val .= $this_controller_name . ' disabled?';
my $active = knx_read( $this_controller{ 'DisableGA' } ) || 1; # active if unreadable
if ( !int($active) and defined $this_controller{ 'ActuatorGA' } ) {
if (knx_read( $this_controller{ 'ActuatorGA' } ) ne 0) { # only if not already 0
knx_write( $this_controller{ 'ActuatorGA' }, 0, $this_controller{ 'ActuatorDPT' } );
}
$plugin_info{ $plugname . '_' . $this_controller_name . '_Integral' } = 0;
$plugin_info{ $plugname . '_' . $this_controller_name . '_Actuator' } = 0; # Reset
$ret_val .= ' yes';
} else {
$ret_val .= ' no';
}
}
# subscribe ModeGA
if( defined $this_controller{ 'ModeGA' } )
{
$plugin_subscribe{ $this_controller{ 'ModeGA' } }{ $plugname } = 1;
}
# subscribe SetPointComfortGA
if( defined $this_controller{ 'SetPointComfortGA' } )
{
$plugin_subscribe{ $this_controller{ 'SetPointComfortGA' } }{ $plugname } = 1;
}
# subscribe TempDropStandbyGA
if( defined $TempDropStandbyGA )
{
$plugin_subscribe{ $TempDropStandbyGA }{ $plugname } = 1;
}
# subscribe TempDropNightGA
if( defined $TempDropNightGA )
{
$plugin_subscribe{ $TempDropNightGA }{ $plugname } = 1;
}
# subscribe TempFixFrostGA
if( defined $TempFixFrostGA )
{
$plugin_subscribe{ $TempFixFrostGA }{ $plugname } = 1;
}
}
}
# Set the update cycle to one minute
$plugin_info{$plugname.'_cycle'} = 60;
#############################################################################
# Handle the bus traffic
my $SetPointChange = 0;
my $ModeChange = 0;
if( $busActive )
{
# Early exit during a response messeage - it's usually from us...
if( $msg{'apci'} eq 'A_GroupValue_Response' )
{
return;
}
# Global update of the Temperature Drop or Temperature Fix (for all Controllers)
if($msg{'apci'} eq 'A_GroupValue_Write')
{
if( $msg{'dst'} eq $TempDropStandbyGA )
{
#update $TempDropStandby
my $value = knx_read( $msg{'dst'}, 0, $TempDPT );
$plugin_info{ $plugname . '_' . '_TempDropStandby' } = $value;
plugin_log($plugname,"New TempDropStandby: ".$value);
}
if( $msg{'dst'} eq $TempDropNightGA )
{
#update $TempDropNight
my $value = knx_read( $msg{'dst'}, 0, $TempDPT );
$plugin_info{ $plugname . '_' . '_TempDropNight' } = $value;
plugin_log($plugname,"New TempDropNight: ".$value);
}
if( $msg{'dst'} eq $TempFixFrostGA )
{
#update $TempFixFrost
my $value = knx_read( $msg{'dst'}, 0, $TempDPT );
$plugin_info{ $plugname . '_' . '_TempFixFrost' } = $value;
plugin_log($plugname,"New TempFixFrost: ".$value);
}
}
elsif( $msg{'apci'} eq 'A_GroupValue_Read' )
{
if($msg{'dst'} eq $TempDropNightGA)
{
# A read request for this GA was sent on the bus and the L-flag is set
my $value = $plugin_info{ $plugname . '_' . '_TempDropNight'};
knx_write( $msg{'dst'}, $value, $TempDPT, 1 ); # send response
$ret_val .= 'read(' . $msg{'dst'} . ') TempDropNight -> ' . $value;
}elsif ($msg{'dst'} eq $TempDropStandbyGA)
{
# A read request for this GA was sent on the bus and the L-flag is set
my $value = $plugin_info{ $plugname . '_' . '_TempDropStandby' };
knx_write( $msg{'dst'}, $value, $TempDPT, 1 ); # send response
$ret_val .= 'read(' . $msg{'dst'} . ') TempDropStandby -> ' . $value;
}elsif ($msg{'dst'} eq $TempFixFrostGA)
{
# A read request for this GA was sent on the bus and the L-flag is set
my $value = $plugin_info{ $plugname . '_' . '_TempFixFrost' };
knx_write( $msg{'dst'}, $value, $TempDPT, 1 ); # send response
$ret_val .= 'read(' . $msg{'dst'} . ') TempFixFrost-> ' . $value;
}
}
# a linear search isn't smart but OK for only a few states:
for my $this_controller_name ( keys %controllers )
{
my %this_controller = (%{$controllers{ $this_controller_name }}, %default);
if( $msg{'apci'} eq 'A_GroupValue_Read' )
{
if( $msg{'dst'} eq $this_controller{ 'SetPointGA' } and $this_controller{ 'SetPointLFlag' })
{
# A read request for this GA was sent on the bus and the L-flag is set
my $value = $plugin_info{ $plugname . '_' . $this_controller_name . '_SetPoint' };
my $DPT = $this_controller{ 'SetPointDPT' };
knx_write( $msg{'dst'}, $value, $DPT, 1 ); # send response
$ret_val .= 'read(' . $msg{'dst'} . '=' . $this_controller_name . ') SetPoint -> ' . $value;
} elsif( $msg{'dst'} eq $this_controller{ 'ActuatorGA' } and $this_controller{ 'ActuatorLFlag' })
{
# A read request for this GA was sent on the bus and the L-flag is set
my $value = $plugin_info{ $plugname . '_' . $this_controller_name . '_Actuator' };
my $DPT = $this_controller{ 'ActuatorDPT' };
knx_write( $msg{'dst'}, $value, $DPT, 1 ); # send response
$ret_val .= 'read(' . $msg{'dst'} . '=' . $this_controller_name . ') Actuator -> ' . $value;
}
#read SetPointComfort
elsif( $msg{'dst'} eq $this_controller{ 'SetPointComfortGA' } and $this_controller{ 'SetPointComfortLFlag' })
{
# A read request for this GA was sent on the bus and the L-flag is set
my $value = $plugin_info{ $plugname . '_' . $this_controller_name . '_SetPointComfort' };
my $DPT = $this_controller{ 'SetPointDPT' };
knx_write( $msg{'dst'}, $value, $DPT, 1 ); # send response
$ret_val .= 'read(' . $msg{'dst'} . '=' . $this_controller_name . ') SetPointComfort -> ' . $value;
}
#read Mode
elsif( $msg{'dst'} eq $this_controller{ 'ModeGA' } and $this_controller{ 'ModeLFlag' })
{
# A read request for this GA was sent on the bus and the L-flag is set
my $value = $plugin_info{ $plugname . '_' . $this_controller_name . '_Mode' };
my $DPT = "20.102";
knx_write( $msg{'dst'}, $value, $DPT, 1 ); # send response
$ret_val .= 'read(' . $msg{'dst'} . '=' . $this_controller_name . ') Mode -> ' . $value;
}
}
elsif($msg{'apci'} eq 'A_GroupValue_Write')
{
if( $msg{'dst'} eq $this_controller{ 'SetPointGA' } )
{
# A new(?) setpoint was sent on the bus => update internal state
# read from eibd cache, so we'll get the cast for free:
my $value = knx_read( $msg{'dst'}, 0, $this_controller{ 'SetPointDPT' } );
$plugin_info{ $plugname . '_' . $this_controller_name . '_SetPoint' } = $value;
$SetPointChange = 1;
$ret_val .= 'write(' . $msg{'dst'} . '=' . $this_controller_name . ') ' . $value . ' -> SetPoint';
}
if( $msg{'dst'} eq $this_controller{ 'ModeGA' } )
{
#A new mode was sent to use for this controller.
my $mode = knx_read( $msg{'dst'}, 0, "20.102" );
$plugin_info{ $plugname . '_' . $this_controller_name . '_Mode' } = $mode;
$ModeChange = 1;
plugin_log($plugname,"New Mode: ".$this_controller_name." - value: ".$mode);
}
if( $msg{'dst'} eq $this_controller{ 'SetPointComfortGA' } )
{
# A new(?) comfortTemperature was sent on the bus => update internal state
# read from eibd cache, so we'll get the cast for free:
my $value = knx_read( $msg{'dst'}, 0, $this_controller{ 'SetPointDPT' } );
$plugin_info{ $plugname . '_' . $this_controller_name . '_SetPointComfort' } = $value;
$ModeChange = 1;
plugin_log($plugname,"New ComfortTemperature: ".$this_controller_name." - value: ".$value);
}
}
}
} # if( $busActive )
#############################################################################
# Update the setpoint because of the mode / or comfortTemperature change
# TOBI!
if ($ModeChange)
{
my $standby = $plugin_info{ $plugname . '_' . '_TempDropStandby' };
my $night = $plugin_info{ $plugname . '_' . '_TempDropNight' };
my $frost = $plugin_info{ $plugname . '_' . '_TempFixFrost' };
for my $this_controller_name ( keys %controllers )
{
my %this_controller = (%{$controllers{ $this_controller_name }}, %default);
my $prefix = $plugname . '_' . $this_controller_name;
my $mode = $plugin_info{ $prefix . '_Mode' };
my $SetPointComfort = $plugin_info{ $prefix . '_SetPointComfort' };
my $SetPoint = $plugin_info{ $prefix . '_SetPoint' };
#if there is no temperature, set it to initial temperature
if ($SetPointComfort == 0){
$SetPointComfort = $this_controller{ 'SetPointInit' };
$plugin_info{ $plugname . '_' . $this_controller_name . '_SetPointComfort' } = $SetPointComfort;
plugin_log($plugname,"Keine Comforttemperatur: ".$this_controller_name." - New: ".$SetPointComfort);
}
#if invalid mode, set it to comfort (1)
if ($mode < 1 or $mode > 4){
$mode = 1;
$plugin_info{ $plugname . '_' . $this_controller_name . '_Mode' } = $mode;
plugin_log($plugname,"Ungültiger Modus: ".$this_controller_name." - New: ".$mode);
}
#The DPT 20.102 is not supported, so we use the following:
#
# MODE VALUE
# comfort 1
# standby 2
# night 3
# frost 4
#
my $newValue = $SetPointComfort;
my $modetext = 'none';
if ($mode eq 1){ #comfort
$modetext = 'Comfort';
$newValue = $SetPointComfort;
#plugin_log($plugname,"New Mode: ".$this_controller_name." - Mode: Comfort"." - SetPoint: ".$newValue);
}
if ($mode eq 2){ #standby
$modetext = 'Standby';
$newValue = $SetPointComfort-$standby;
#plugin_log($plugname,"New Mode: ".$this_controller_name." - Mode: Standby"." - SetPoint: ".$newValue);
}
if ($mode eq 3){ #night
$modetext = 'Night';
$newValue = $SetPointComfort-$night;
#plugin_log($plugname,"New Mode: ".$this_controller_name." - Mode: Night"." - SetPoint: ".$newValue);
}
if ($mode eq 4){ #frost
$modetext = 'Frost';
$newValue = $frost;
#plugin_log($plugname,"New Mode: ".$this_controller_name." - Mode: Frost"." - SetPoint: ".$newValue);
}
#check, if update neccessary for this controller
if ($newValue ne $SetPoint){
plugin_log($plugname,"New Mode: ".$this_controller_name." - Mode: ".$modetext." - SetPoint: ".$newValue);
knx_write( $this_controller{ 'SetPointGA' }, $newValue, $this_controller{ 'SetPointDPT' }, 1); # send new SetPoint
$plugin_info{ $plugname . '_' . $this_controller_name . '_SetPoint' } = $newValue;
$SetPointChange = 1;
}
}
}
#############################################################################
# Update the controllers
if( !$busActive or $SetPointChange ) # only at init, cycle or set point change
{
my $dt = time() - $plugin_info{ $plugname . '_tlast' };
$plugin_info{ $plugname . '_tlast' } = time();
$ret_val .= sprintf( ' dt: %.3f; ', $dt );
for my $this_controller_name ( keys %controllers )
{
my %this_controller = (%{$controllers{ $this_controller_name }}, %default);
my $prefix = $plugname . '_' . $this_controller_name;
my $Sensor = knx_read( $this_controller{ 'SensorGA' }, 0, $this_controller{ 'SensorDPT' } );
#my $Sensor = knx_read( $this_controller{ 'SensorGA' }, 60, $this_controller{ 'SensorDPT' } );
#01.02.2012 (v0.8)
# Changed: Sometimes I get no Temperature - script takes "0" - then the actuator is set to 100. Room gets too warm.
# New: Skip this controller and print a warning.
# Note: Tried 60s timeout - it doesn't work better.
if ($Sensor == 0){
plugin_log($plugname,"Temperature error: ".$this_controller_name);
next;
}
my $SetPoint = $plugin_info{ $prefix . '_SetPoint' };
my $old = $plugin_info{ $prefix . '_Actuator' };
my $kp = 1.0 / $this_controller{ 'ProportionalGain' };
my $error = $SetPoint - $Sensor;
# caclulate the I part of the PI controller:
$plugin_info{ $prefix . '_Integral' } = $plugin_info{ $prefix . '_Integral' } + $error * $dt;
my $integral = $plugin_info{ $prefix . '_Integral' } / (60.0 * $this_controller{ 'IntegralTime' });
# put together the PI controller:
$plugin_info{ $prefix . '_Actuator' } = 100.0 * $kp * ($error + $integral);
# clip at maximum to avoid windup:
if( $plugin_info{ $prefix . '_Actuator' } > 100 )
{
$ret_val .= '[>]';
$plugin_info{ $prefix . '_Actuator' } = 100;
$plugin_info{ $prefix . '_Integral' } = (1.0 / $kp) * 60.0 * $this_controller{ 'IntegralTime' };
}
# clip at minimum
if( $plugin_info{ $prefix . '_Actuator' } < 0 or $plugin_info{ $prefix . '_Integral' } < 0 )
{
$ret_val .= '[<]';
$plugin_info{ $prefix . '_Actuator' } = 0 if $plugin_info{ $prefix . '_Actuator' } < 0;
$plugin_info{ $prefix . '_Integral' } = 0;
}
#$plugin_info{ $prefix . '_Actuator' } = round( $plugin_info{ $prefix . '_Actuator' } );
# If a GA is defined, send the new actuator value
if( defined $this_controller{ 'ActuatorGA' } and (
($old ne $plugin_info{ $prefix . '_Actuator' }) or (time() - $plugin_info{ $prefix . '_lastSent' } > $this_controller{'MinUpdateRate'} )) )
{
knx_write( $this_controller{ 'ActuatorGA' }, $plugin_info{ $prefix . '_Actuator' }, $this_controller{ 'ActuatorDPT' } );
$plugin_info{ $prefix . '_lastSent' } = time();
}
if( defined $this_controller{ 'SetPointRRD' } )
{
update_rrd( $this_controller{ 'SetPointRRD' }, '', $SetPoint );
}
if( defined $this_controller{ 'ActuatorRRD' } )
{
update_rrd( $this_controller{ 'ActuatorRRD' }, '', $plugin_info{ $prefix . '_Actuator' } );
}
$ret_val .= $this_controller_name . ': ' . $SetPoint . '<>' . $Sensor . '=>' . $plugin_info{ $prefix . '_Actuator' } . ' [' . ($error*$kp) . '/' . $integral*$kp . ']; ';
}
}
if( $show_debug ) { return $ret_val; }
return;
#############################################################################
# Version history:
# ================
# 0.8:
# * Bug fix: If there occurs a timeout reading the current temperature (returns 0),
# then skip controller until the next cycle.
# * Added ModeGA, TempDropStandby, TempDropNight, TempFixFrost to work with the standard modes.
# 0.7:
# * change to external config (-> conf.d)
# 0.6:
# * Bug fix for setups where the WireGate didn't know the ActuatorGA
# * Force sending of actuator after x seconds/minutes so that the watchdog in
# the actuator doesn't time out
# 0.5:
# * initial release
#
#############################################################################
# ToDo:
# =====
# * Limit bus traffic by sending actuator values after a change that is bigger
# than x%
# * Add GA for sending delta values for the setpoint [DONE]
# * External Config [DONE]
# * Actuator overwrite ("Zwangsstellung")
# * Hard temperature limit (min, max)
#############################################################################
Das config-file könnte so aussehen:
Code:
#-----------------------------------------------------------------------------
# ACHTUNG: Variablen duerfen nur im Plugin mit 'my' definiert werden,
# 'my' hier nicht verwenden!
#-----------------------------------------------------------------------------
#############################################################################
# Configuration:
%controllers = (
#Erdgeschoss
'1-20_Büro_FBH' => {
'SetPointGA' => '3/1/20', 'SetPointRRD' => '1-20_Büro_FBH_Sollwert',
'SensorGA' => '3/1/21',
'ActuatorGA' => '3/1/22', 'ActuatorRRD' => '1-20_Büro_FBH_Regelung',
'ProportionalGain' => 5, 'IntegralTime' => 240,
'ModeGA' => '3/1/24', 'SetPointComfortGA' => '3/1/25'
},
#Obergeschoss
'2-20_Bad_FBH' => {
'SetPointGA' => '3/2/20', 'SetPointRRD' => '2-20_Bad_FBH_Sollwert',
'SensorGA' => '3/2/21',
'ActuatorGA' => '3/2/22', 'ActuatorRRD' => '2-20_Bad_FBH_Regelung',
'ProportionalGain' => 5, 'IntegralTime' => 240,
'ModeGA' => '3/2/24', 'SetPointComfortGA' => '3/2/25'
},
# '140_Hobby2_HK' => {
# 'SetPointGA' => '3/3/140', 'SetPointRRD' => '140_Hobby2_HK_Sollwert',
# 'SensorGA' => '4/0/140',
# 'ActuatorGA' => '3/0/140', 'ActuatorRRD' => '140_Hobby2_HK_Regelung',
# 'ProportionalGain' => 5, 'IntegralTime' => 240
# },
);
%default = (
'SetPointDPT' => 9.001,
'SensorDPT' => 9.001,
'ActuatorDPT' => 5,
'DisableDPT' => 0,
'SetPointInit' => 21.0,
'SetPointLFlag' => 1, # true
'ActuatorLFlag' => 1, # true
'ModeLFlag' => 1, # true
'SetPointComfortLFlag' => 1, # true
'MinUpdateRate' => 5 * 60, # 5 minutes
);
$TempDropNightGA = '3/6/30';
$TempDropStandbyGA = '3/6/31';
$TempFixFrostGA = '3/6/32';
$TempDPT = '9.001';
$GlobalDisableGA = '14/5/50';
$reset = 0; # set to 1 to reset the states, run script and change to 0 again
$show_debug = 1; # switches debug information that will be shown in the log
#############################################################################
1;
# emacs setting
# ;;; Local Variables: ***
# ;;; mode:perl ***
# ;;; End: ***
# vim: set filetype=perl expandtab tabstop=8 shiftwidth=2 autoindent smartindent:
Ich sende je nach Uhrzeit oder Anwesenheit den Modus
# comfort 1
# standby 2
# night 3
# frost 4
and die $ModeGA. Die Temperaturen/absenkungen werden auch via GA
Code:
$TempDropNightGA = '3/6/30';
$TempDropStandbyGA = '3/6/31';
$TempFixFrostGA = '3/6/32';
gesetzt und im Plugin gespeichert.
Fenster-Plugin:
Code:
$plugin_info{$plugname.'_cycle'} = 300; #alle 300 Sekunden
my @Fenster;
# name: Name des Fensters
# GA_offen: GA des Kontaktes für OFFEN
# GA_kipp: GA des Kontaktes für GEKIPPT
# GA_status: Der Status wird in diese GA geschrieben (zu=0; kipp=1; offen=2 oder 3)
# status_zeit: Die Zeit, seitdem der status geändert wurde
# timeout_heizung_sperren: Zeit, nachder die Heizung ausgeht in Sekunden
# GA_heizung_sperren: 1 Heizung gesperrt, 0 Heizung freigegeben
#1st Floor
push @Fenster, { name => "Büro",
GA_offen=> "4/1/20",
GA_kipp => "4/1/21",
GA_status => "4/1/22",
timeout_heizung_sperren => 600,
GA_heizung_sperren => "3/4/10"
};
push @Fenster, { name => "WC",
GA_offen=> "4/1/30",
GA_kipp => "4/1/31",
GA_status => "4/1/32",
timeout_heizung_sperren => 600,
GA_heizung_sperren => "3/4/11"
};
#2nd floor
push @Fenster, { name => "Schlafzimmer",
GA_offen=> "4/2/10",
GA_kipp => "4/2/11",
GA_status => "4/2/12",
timeout_heizung_sperren => 600,
GA_heizung_sperren => "3/6/20"
};
#keller - keine Heizung
push @Fenster, { name => "KG_HWR",
GA_offen=> "4/0/10",
GA_kipp => "4/0/11",
GA_status => "4/0/12"
#,
#timeout_heizung_sperren => 600,
#GA_heizung_sperren => "3/6/24"
};
push @Fenster, { name => "KG_Hobby",
GA_offen=> "4/0/30",
GA_kipp => "4/0/31",
GA_status => "4/0/32"
#,
#timeout_heizung_sperren => 600,
#GA_heizung_sperren => "3/6/24"
};
#subscribe an jeder GA
foreach my $element(@Fenster) {
# anmelden für jede statusänderung
$plugin_subscribe{ $element->{GA_offen}} {$plugname} = 1;
$plugin_subscribe{ $element->{GA_kipp} } {$plugname} = 1;
}
#status change
foreach my $element(@Fenster) {
if($msg{'apci'} eq 'A_GroupValue_Write'){
if( $msg{'dst'} eq $element->{GA_offen} ){
my $value = knx_read( $msg{'dst'}, 0, 1);
$plugin_info{$plugname.'_'.$element->{name}.'_offen'} = $value;
plugin_log($plugname,"Name: " . $element->{name} . "; Status: offen/".$value);
}
}
if($msg{'apci'} eq 'A_GroupValue_Write'){
if( $msg{'dst'} eq $element->{GA_kipp} ){
my $value = knx_read( $msg{'dst'}, 0, 1);
$plugin_info{$plugname.'_'.$element->{name}.'_kipp'} = $value;
plugin_log($plugname,"Name: " . $element->{name} . "; Status: kipp/".$value);
}
}
}
#$plugin_info{$plugname.'_cycle'} = 600;
# Aktuelle Zeit
my $time = time ();
# Los gehts. Jedes Fenster abarbeiten.
foreach my $element(@Fenster) {
#my $status_old = knx_read($element->{GA_status},0,1);
my $status_old = $plugin_info{$plugname.'_'.$element->{name}.'_status'};
#my $status_new = knx_read($element->{GA_offen},0,1)*2 + knx_read($element->{GA_kipp},0,1)*1;
my $status_new = $plugin_info{$plugname.'_'.$element->{name}.'_offen'} *2 + $plugin_info{$plugname.'_'.$element->{name}.'_kipp'}*1;
#Bei Statusänderung
if ($status_old != $status_new){
$plugin_info{$plugname.'_'.$element->{name}.'_status'} = $status_new;
knx_write($element->{GA_status}, $status_new, 5.010);
#$element->{status_zeit} = $time;
$plugin_info{$plugname.'_'.$element->{name}.'_status_zeit'} = $time;
plugin_log($plugname,"Name: " . $element->{name} . "; Changed: $status_old --> $status_new");
#return "changed: $status_old --> $status_new >> ".$time;
}
my $status_zeit = $plugin_info{$plugname.'_'.$element->{name}.'_status_zeit'};
#Zeit überprüfen
#Optimieren...
my $diff = $time - $status_zeit;
my $diff_d = floor($diff/60/60/24);
$diff_d = '0' if $diff_d<0; #murks vertuschen :-)
my $diff_h = ($diff/60/60) %24;
$diff_h = '0'.$diff_h if $diff_h<10; #murks vertuschen :-)
my $diff_m = ($diff/60) %60;
$diff_m = '0'.$diff_m if $diff_m<10; #murks vertuschen :-)
my $diff_s = ($diff) %60;
$diff_s = '0'.$diff_s if $diff_s<10; #murks vertuschen :-)
my $gesperrt = $plugin_info{$plugname.'_'.$element->{name}.'_heizung_gesperrt'};
if ($status_new > 0){
#Fenster offen
plugin_log($plugname,"Name: " . $element->{name} . "; Fenster schon $diff_d Tagen $diff_h:$diff_m:$diff_s geöffnet!");
if( defined $element->{GA_heizung_sperren} ){
if ( ($diff) >= $element->{timeout_heizung_sperren} ) {
#Heizung sperren...
if ($gesperrt != 1){
$gesperrt = 1;
$plugin_info{$plugname.'_'.$element->{name}.'_heizung_gesperrt'} = $gesperrt;
plugin_log($plugname,"Name: " . $element->{name} . "; Heizung sperren...");
knx_write($element->{GA_heizung_sperren}, $gesperrt, 1);
}else{
plugin_log($plugname,"Name: " . $element->{name} . "; Heizung ist schon gesperrt.");
}
}
}
}
if ($status_new == 0){
#Fenster geschlossen
plugin_log($plugname,"Name: " . $element->{name} . "; Fenster seit $diff_d Tagen $diff_h:$diff_m:$diff_s geschlossen!");
if( defined $element->{GA_heizung_sperren} ){
#Heizung entsperren
if ($gesperrt != 0){
$gesperrt = 0;
$plugin_info{$plugname.'_'.$element->{name}.'_heizung_gesperrt'} = $gesperrt;
plugin_log($plugname,"Name: " . $element->{name} . "; Heizung entsperren...");
knx_write($element->{GA_heizung_sperren}, $gesperrt, 1);
}else{
plugin_log($plugname,"Name: " . $element->{name} . "; Heizung ist schon entsperrt.");
}
}
}
}
|
| Themen-Optionen |
|
|
| Ansicht |
Linear-Darstellung
|
Forumregeln
|
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.
HTML-Code ist aus.
|
|
|
Alle Zeitangaben in WEZ +2. Es ist jetzt 06:59 Uhr.
|