Zurück   KNX-User-Forum > Öffentlicher Bereich > KNX EIB Forum > Code-Schnipsel
knx-user-forum - International KNX Award Winner 2010


Links
Kalender
Spende

Antwort
 
Themen-Optionen Ansicht
  #61  
Alt 20.04.2012, 10:20
Benutzer
 
Registriert seit: 14.01.2010
Ort: NRW
Beiträge: 38
derwolff2010 ist zur Zeit noch ein unbeschriebenes Blatt
Standard

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.
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
  #62  
Alt 21.04.2012, 01:59
Benutzerbild von makki
Erfahrener Benutzer
 
Registriert seit: 07.07.2007
Beiträge: 11.779
makki sorgt für eine eindrucksvolle Atmosphäremakki sorgt für eine eindrucksvolle Atmosphäremakki sorgt für eine eindrucksvolle Atmosphäremakki sorgt für eine eindrucksvolle Atmosphäremakki sorgt für eine eindrucksvolle Atmosphäremakki sorgt für eine eindrucksvolle Atmosphäre
Standard

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!
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
  #63  
Alt 21.04.2012, 13:45
Benutzerbild von Chris M.
Erfahrener Benutzer
 
Registriert seit: 14.12.2008
Beiträge: 4.859
Chris M. sorgt für eine eindrucksvolle AtmosphäreChris M. sorgt für eine eindrucksvolle AtmosphäreChris M. sorgt für eine eindrucksvolle AtmosphäreChris M. sorgt für eine eindrucksvolle Atmosphäre
Standard

Zitat von derwolff2010 Beitrag anzeigen
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!
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
  #64  
Alt 22.04.2012, 10:41
Benutzer
 
Registriert seit: 14.01.2010
Ort: NRW
Beiträge: 38
derwolff2010 ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Zitat von Chris M. Beitrag anzeigen
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.
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
  #65  
Alt 22.04.2012, 18:39
Benutzerbild von Chris M.
Erfahrener Benutzer
 
Registriert seit: 14.12.2008
Beiträge: 4.859
Chris M. sorgt für eine eindrucksvolle AtmosphäreChris M. sorgt für eine eindrucksvolle AtmosphäreChris M. sorgt für eine eindrucksvolle AtmosphäreChris M. sorgt für eine eindrucksvolle Atmosphäre
Standard

Zitat von derwolff2010 Beitrag anzeigen
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 Beitrag anzeigen
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!
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
  #66  
Alt 09.01.2013, 21:13
Benutzerbild von harryhirsch3
Benutzer
 
Registriert seit: 02.06.2007
Ort: Mönchengladbach
Beiträge: 163
harryhirsch3 ist zur Zeit noch ein unbeschriebenes Blatt
Standard

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)
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
  #67  
Alt 09.01.2013, 22:13
Benutzer
 
Registriert seit: 13.12.2008
Ort: Lörrach
Beiträge: 22
tobiB ist zur Zeit noch ein unbeschriebenes Blatt
Standard

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.");
            }
        }
    }
}
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
Antwort

Stichworte
heizung, multi, multifunktionsgateway, pi-regler, plugin, regelung, rtr, steuerung, wiregate

Themen-Optionen
Ansicht

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.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are aus
Pingbacks are aus
Refbacks are aus


Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
welche Parameter für PI Regler Reason555 KNX EIB Forum 38 09.03.2012 12:43
[Codebeispiel] PI Regler enertegus eibPC 2 19.11.2009 19:51
[HS/FS] Logik Programmieren für RTR be1001 KNX EIB Forum 10 29.10.2009 19:07
[HS/FS] Logikersatz für RTR mit schaltender PI Regelung ? Martin KNX EIB Forum 4 04.10.2008 19:55
[KNX/EIB] Welche Heizkreise durch welche RTR steuern bzw. zusammenfassen? pio KNX EIB Forum 6 12.09.2008 17:29


Alle Zeitangaben in WEZ +2. Es ist jetzt 06:59 Uhr.



SEO by vBSEO