Ankündigung

Einklappen
Keine Ankündigung bisher.

Sommer-/Winterumschaltung via 3-Tagesmittel

Einklappen
Dieses Thema ist geschlossen.
X
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    [wiregate] Sommer-/Winterumschaltung via 3-Tagesmittel

    Moin zusammen,

    da ich o.g. Funktion im SVN nicht finden konnte habe ich mir da kurzerhand selbst beholfen und ein Plugin dafür erstellt.
    Vielleicht gibt es ja da draußen noch weitere Leute, die ein solches Plugin gebrauchen können.

    Kurze Erläuterung:
    Das Plugin loggt die Temperaturen der letzten drei Tage mit (heute, gestern und vorgestern). Als Berechnungsgrundlage dient die Tagesmittel-Berechnung nach DIN: (T 07:00 Uhr + T 14:00 Uhr + 2x T 22:00 Uhr)/4. Jeden Tag um 22:00 Uhr wird das neue 3-Tagesmittel aus dem arithmetischen Mittelwert der DIN-Tagesmittel der letzten 3 Tage gebildet: (Tagesmittel_Heute + Tagesmittel_Gestern + Tagesmittel_Vorgestern)/3. Ist das 3-Tagesmittel nun größer als die parametrierte Umschalttemperatur zwischen Sommer-/Winterbetrieb, so wird auf eine parametrierte GA eine "1" für Sommerbetrieb gesendet. Umgekehrt eine "0" für Winterbetrieb.
    Die Umschalttemperatur könnte man natürlich auch via GA abholen, um sie so beispielsweise von der CometVisu vorzugeben.

    Als Grundlage für die Zeitschaltung habe ich die entsprechenden Codestellen des "Schaltuhr.pl"-Plugins des Users emax zweckentfremdet.

    Ich bin jetzt kein geborener Perl-Programmierer, meine Kenntnisse liegen eher im SPS- bzw. C/C++ Bereich.
    Sofern der Code also optimierungsfähig / schlecht programmiert ist bitte ich um Rückmeldung.

    Ach ja noch zur Anwendung: Ich nutze das um meine Heizung via Schaltaktor und Koppelrelais über einen potentialfreien Kontakt (der auf einen parametrierbaren Eingang meiner Wärmepumpe geschaltet ist) zwischen Heizbetrieb und Nicht-Heizbetrieb umzuschalten. Zudem schaltet ich mit der Sommer-/Winter-GA meine Heizungsaktoren zwischen Sommer-/Winterbetrieb um. Somit habe ich eine zeitgleiche Umschaltung der Heizung selbst und der Heizungsaktoren kreiert.

    Ansonsten viel Spaß mit dem Plugin und bei Fragen -> fragen.

    Code:
    # Sommer-/Winter-Umschaltung
    # V1.00 2015-09-23
    # by mitchdsa
    
    use POSIX;
    use Time::Zone;
    
    ## Definitionen
    ### Hier werden die Werte/Gruppenadressen definiert
    
    ### Konfigurierbare Werte
    my $LokaleZeitZone = "CET"; # lokale Zeitzone
    my $LokaleSommerZeitZone = "CEST"; # lokale Zeitzone im Sommer
    my $slotEnd = 3;
    my $temp_ga = '7/0/26'; # GA der Außentemperatur
    my $sommer_ga = '7/1/0'; # GA für Sommer-/Winter-Umschaltung
    my $umschalttemperatur = 14; # 3-Tagesmittel > Umschalttemperatur = Sommer, 3-Tagesmittel < Umschalttemperatur = Winter
    my $debug = 0; # Aktivierung detaillierter Logeinträge = 1, Deaktivierung detaillierter Logeinträge = 0;
    
    ### Nicht konfigurierbare Werte
    my $tagesmittel;    # Tagesmittel (Mittelwert von Temp 07:00 + Temp 14:00 + 2x Temp 22:00)
    my $tagesmittel_gestern;    # Tagesmittel von Gestern
    my $tagesmittel_vorgestern;    # Tagesmittel von Vorgestern
    my $dreitagesmittel;    # Dreitagesmittel
    my $WTag;    # Wochentag-Merker, Werte 0-6. 0=Sonntag ... 6=Samstag
    
    ## Aufruf-Zyklus setzen
    ### Anmerkung: Sekunden werden nicht verarbeitet -> kleinste Einheit =60 (1 Minute)
    my $cycleTime = 60;
    
    ## Versionsnummer vergeben
    ### Anmerkung: Die Versionsnummer ist Teil des plugin_info hashes und dient dazu, dass das Script definierte Anfangskonditionen  
    ### findet - auch ohne den wiregated neu starten zu müssen. Die Nummer wird nach einer Änderung des Scriptes um eins erhöht.
    my $version = 10;
    
    
    ## Unterprogramme
    ### Zykluszeit berechnen und neu setzen
    sub setCycle
    {
        my ($seconds,$uSec) = gettimeofday();
        my $curSec = $seconds%60;
        if ($curSec >= $slotEnd)
        {
        $plugin_info{$plugname.'_cycle'} = $cycleTime - $curSec - $uSec/1000000 + 0.1; # avoid rounding underruns
        plugin_log($plugname, "cycle time set to $plugin_info{$plugname.'_cycle'} second");
        }
        else
        {
        $plugin_info{$plugname.'_cycle'} = $cycleTime;
        }
    } # Ende setCycle
    
    
    ## Hauptprogramm
    my $tStamp = time;
    my ($curSec,$curMin,$curStu,$curMTag,$curMon,$curJahr,$curWTag,$curJTag,$isdst) = localtime($tStamp);
    $curJahr += 1900;
    
    ### Setzen der konfigurierten Zeitzone
    my $curZone = ($isdst) ? $LokaleSommerZeitZone : $LokaleZeitZone;
    my $lclOffset = tz_offset("$curZone");
    
    ### Setzen definierter Startkonditionen
    if (!defined $plugin_info{"$plugname.$version.firstRun"})
    {
        plugin_log($plugname, "Starting plugin version $version, will execute with first time-slot.");
        ### Obsolete Versionen von $plugin_info bereinigen
        foreach (keys %plugin_info)
        {
        if (/^$plugname\./)
        {
            delete $plugin_info{$_};
            plugin_log($plugname, "deleted plugin_info[$_]");
        }
        }    
        $plugin_info{"$plugname.$version.firstRun"} = 1;
        &setCycle();
    }
    
    ### Beim ersten Mal nur ausführen, wenn innerhalb des Slots
    ($curSec >= $slotEnd && $plugin_info{"$plugname.$version.firstRun"} == 1) and return;
    
    ### Prüfen, ob das Script in dieser Minute bereits ausgeführt wurde
    if (defined $plugin_info{"$plugname.$version.lastMinute"} && $plugin_info{"$plugname.$version.lastMinute"} == $curMin)
    {
        &setCycle();
        return;
    }
    
    ### "Basetime" als Berechnungsgrundlage generieren
    my ($basSec,$basMin,$basStu,$basMTag,$basMon,$basJahr,$basWTag,$basJTag) =
        ($curSec,$curMin,$curStu,$curMTag,$curMon,$curJahr,$curWTag,$curJTag);
    
    if(!defined $plugin_info{$plugname.'_WTag_alt'}) {
        $plugin_info{$plugname.'_WTag_alt'} = $basWTag;
    }    
    
    ### Tageswechsel?
    $WTag = $basWTag;
    if($WTag != $plugin_info{$plugname.'_WTag_alt'} && $basStu == 0 && $basMin == 0) {
        $plugin_info{$plugname.'_Tag3_T1'} = $plugin_info{$plugname.'_Tag2_T1'};
        $plugin_info{$plugname.'_Tag3_T2'} = $plugin_info{$plugname.'_Tag2_T2'};
        $plugin_info{$plugname.'_Tag3_T3'} = $plugin_info{$plugname.'_Tag2_T3'};
        $plugin_info{$plugname.'_Tag2_T1'} = $plugin_info{$plugname.'_Tag1_T1'};
        $plugin_info{$plugname.'_Tag2_T2'} = $plugin_info{$plugname.'_Tag1_T2'};
        $plugin_info{$plugname.'_Tag2_T3'} = $plugin_info{$plugname.'_Tag1_T3'};
        
        ### Aktuellen Tag merken, um Tageswechsel herauszufinden
        $plugin_info{$plugname.'_WTag_alt'} = $WTag;
            
        if($debug>=1){plugin_log($plugname,'Tageswechsel. Temperaturwerte kopiert');}
    }
    
    ### 07:00 Uhr Temperatur aktualisieren
    if ($basStu == 7 && $basMin == 0) {
        $plugin_info{$plugname.'_Tag1_T1'}  = knx_read($temp_ga,0,9.001);
        if($debug>=1){plugin_log($plugname,'7:00 Uhr Temperatur aktualisiert. Wert: ' .$plugin_info{$plugname.'_Tag1_T1'});}
    }
    ### 14:00 Uhr Temperatur aktualisieren    
    if ($basStu == 14 && $basMin == 0) {
        $plugin_info{$plugname.'_Tag1_T2'}  = knx_read($temp_ga,0,9.001);
        if($debug>=1){plugin_log($plugname,'14:00 Uhr Temperatur aktualisiert. Wert: ' .$plugin_info{$plugname.'_Tag1_T2'});}
    }
    ### 22:00 Uhr Temperatur aktualisieren und Berechnungen durchführen
    if ($basStu == 22 && $basMin == 0) {
        $plugin_info{$plugname.'_Tag1_T3'}  = knx_read($temp_ga,0,9.001);
        if($debug>=1){plugin_log($plugname,'22:00 Uhr Temperatur aktualisiert. Wert: ' .$plugin_info{$plugname.'_Tag1_T3'});}
        
        ### Berechnung Tagesmittel aktueller Tag
        $tagesmittel = ($plugin_info{$plugname.'_Tag1_T1'} + $plugin_info{$plugname.'_Tag1_T2'} + 2*$plugin_info{$plugname.'_Tag1_T3'})/4;
        $plugin_info{$plugname.'_Tagesmittel'} = $tagesmittel;
        if($debug>=1){plugin_log($plugname,'Tagesmittel heute: ' .$plugin_info{$plugname.'_Tagesmittel'});}
        
        ### Berechnung 3-Tagesmittel
        $tagesmittel_gestern = ($plugin_info{$plugname.'_Tag2_T1'} + $plugin_info{$plugname.'_Tag2_T2'} + 2*$plugin_info{$plugname.'_Tag2_T3'})/4;
        $tagesmittel_vorgestern = ($plugin_info{$plugname.'_Tag3_T1'} + $plugin_info{$plugname.'_Tag3_T2'} + 2*$plugin_info{$plugname.'_Tag3_T3'})/4;
        $dreitagesmittel = ($tagesmittel + $tagesmittel_gestern + $tagesmittel_vorgestern)/3;
        $plugin_info{$plugname.'_3-Tagesmittel'} = $dreitagesmittel;
        if($debug>=1){plugin_log($plugname,'Aktualisiertes 3-Tagesmittel: ' .$plugin_info{$plugname.'_3-Tagesmittel'});}
        
        ### Sommer-/Winter-Umschaltung
        if ($dreitagesmittel > $umschalttemperatur) {
            $plugin_info{$plugname.'_Sommer'} = 1;
            knx_write($sommer_ga, 1, 1.001);
            plugin_log($plugname,'Sommerbetrieb aktiv.');
        } else {
            $plugin_info{$plugname.'_Sommer'} = 0;
            knx_write($sommer_ga, 0, 1.001);
            plugin_log($plugname,'Winterbetrieb aktiv.');
        }
    }
    
    $plugin_info{"$plugname.$version.lastMinute"} = $curMin;
    
    ### Ggf. Zykluszeit korrigieren
    &setCycle();
    $plugin_info{"$plugname.$version.firstRun"} = 0;
    Gruß,
    Martin

    #2
    Hallo Martin, vielen Dank dass Du Dein Plugin mit der Allgemeinheit teilst. Sehr schön dokumentiert!

    lg

    Stefan

    Kommentar

    Lädt...
    X