Ankündigung

Einklappen
Keine Ankündigung bisher.

Schaltuhr - Plugin erweitert um Sonnenauf- und Untergang

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    [WireGate-Plugin] Schaltuhr - Plugin erweitert um Sonnenauf- und Untergang

    Hallo zusammen,

    ich habe das Plugin von Swiss SourceForge.net Repository - [openautomation] Log of /wiregate/plugin/generic/schaltuhr.pl um eine Sonnenaufgangs - Sonnenuntergangs - Funktion erweitert. (Naja ich habe halt keinen Helligkeitssensor )

    Hier der gesamte Code:
    Code:
    # Plugin zum Zeit abhängigem schalten von GA's (Schaltuhr)
    # Version 0.5 BETA 03.07.2011
    # Copyright: swiss (https://knx-user-forum.de/members/swiss.html)
    # License: GPL (v2)
    # Aufbau möglichst so, dass man unterhalb der Einstellungen nichts verändern muss!
    # Erweitert um Sonnenauf / - untergang von ZeitlerW (https://knx-user-forum.de/members/zeitlerw.html)
    # Inspiriert von kleinklausi's Rolladen - Plugin
    
    
    ####################
    ###Einstellungen:###
    ####################
    
    # Die Standortdaten 
    # Die Koordinaten des Hauses. Sehr einfach über http://www.getlatlon.com/ zu ermitteln.
    my ($lat, $lon) = (
        50.27816466477597, # Breitengrad in Grad
        11.64325475692749  # Längengrad in Grad
        );
    
    #Winkel für Beginn der Dämmerung
    # siehe auch: http://search.cpan.org/~rkhill/Astro-Sunrise-0.91/Sunrise.pm#DESCRIPTION 
    my $winkel=-3;
    
    my @Schaltzeiten;
    #Pro Schaltpunkt einfach den unten stehenden Eintrag kopieren und anpassen.
    #Sollen Schaltzeiten astronomisch geschaltet werden, so muß bei Astro 'a' für Sonnenaufgang
    #und 'u' für Sonnenuntergang eingetragen werden. Der Stunden und Minutenwert wird dann ignoriert.
    
    push @Schaltzeiten, { name => "Stern_Wohnzimmer", montag => 1, dienstag => 1, mittwoch => 1, donnerstag => 1, freitag => 1, samstag => 1, sonntag => 1, Stunden => 16, Minuten => 00, Wert => 1, DPT => 1, ga => '0/0/34', KW => '', Monat => '', Astro => 'u' };
    push @Schaltzeiten, { name => "Stern_Wohnzimmer", montag => 1, dienstag => 1, mittwoch => 1, donnerstag => 1, freitag => 1, samstag => 1, sonntag => 1, Stunden => 23, Minuten => 00, Wert => 0, DPT => 1, ga => '0/0/34', KW => '', Monat => '', Astro => '' };
    push @Schaltzeiten, { name => "Stern_Wohnzimmer", montag => 1, dienstag => 1, mittwoch => 1, donnerstag => 1, freitag => 1, samstag => 1, sonntag => 1, Stunden => 06, Minuten => 00, Wert => 1, DPT => 1, ga => '0/0/34', KW => '', Monat => '', Astro => '' };
    push @Schaltzeiten, { name => "Stern_Wohnzimmer", montag => 1, dienstag => 1, mittwoch => 1, donnerstag => 1, freitag => 1, samstag => 1, sonntag => 1, Stunden => 8, Minuten => 30, Wert => 0, DPT => 1, ga => '0/0/34', KW => '', Monat => '', Astro => 'a' };
    push @Schaltzeiten, { name => "Glasvase_Wohnzimmer", montag => 1, dienstag => 1, mittwoch => 1, donnerstag => 1, freitag => 1, samstag => 1, sonntag => 1, Stunden => 16, Minuten => 00, Wert => 1, DPT => 1, ga => '0/0/35', KW => '', Monat => '', Astro => 'u' };
    push @Schaltzeiten, { name => "Glasvase_Wohnzimmer", montag => 1, dienstag => 1, mittwoch => 1, donnerstag => 1, freitag => 1, samstag => 1, sonntag => 1, Stunden => 23, Minuten => 00, Wert => 0, DPT => 1, ga => '0/0/35', KW => '', Monat => '', Astro => '' };
    push @Schaltzeiten, { name => "Glasvase_Wohnzimmer", montag => 1, dienstag => 1, mittwoch => 1, donnerstag => 1, freitag => 1, samstag => 1, sonntag => 1, Stunden => 06, Minuten => 00, Wert => 1, DPT => 1, ga => '0/0/35', KW => '', Monat => '', Astro => '' };
    push @Schaltzeiten, { name => "Glasvase_Wohnzimmer", montag => 1, dienstag => 1, mittwoch => 1, donnerstag => 1, freitag => 1, samstag => 1, sonntag => 1, Stunden => 8, Minuten => 30, Wert => 0, DPT => 1, ga => '0/0/35', KW => '', Monat => '', Astro => 'a' };
    ######################
    ##ENDE Einstellungen##
    ######################
    
    use POSIX;
    use Time::Local;
    # Wir brauchen auch Sonnenstandsberechnung
    use Astro::Sunrise;
    
    
    # Eigenen Aufruf-Zyklus auf 20sek. setzen
    $plugin_info{$plugname.'_cycle'} = 20;
    
    #Hier wird ein Array angelegt, um die Wochentagsnummer von localtime zu übersetzen
    my @Wochentag = ('sonntag', 'montag', 'dienstag', 'mittwoch', 'donnerstag', 'freitag', 'samstag');
    
    my @sunrise=split(/:/,sun_rise($lon,$lat,$winkel));
    my @sunset=split(/:/,sun_set($lon,$lat,$winkel));
    my $sec; #Sekunde
    my $min; # Minute
    my $hour; #Stunde
    my $mday; #Monatstag
    my $mon; #Monatsnummer
    my $year; #Jahr
    my $wday; #Wochentag 0-6
    my $yday; #Tag ab 01.01.xxxx
    my $isdst;
    
    ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
    $year += 1900;
    $mon += 1;
    
    my $kw = getWeekNumber($year, $mon, $mday);
    
    foreach my $element (@Schaltzeiten) {
        if (knx_read($element->{ga},0,$element->{DPT}) ne $element->{Wert}) {
                    if ($element->{Astro} ne '') {
                            if ($element->{Astro} eq 'a') {
                                    if ($isdst) {
                                            $element->{Stunden}=$sunrise[0]+1;
                                    } else {
                                            $element->{Stunden}=$sunrise[0];
                                            }
                                    $element->{Minuten}=$sunrise[1];
                            } elsif ($element->{Astro} eq 'u') {
                                    if ($isdst) {
                                            $element->{Stunden}=$sunset[0]+1;
                                    } else {
                                            $element->{Stunden}=$sunset[0];
                                            }
                                    $element->{Minuten}=$sunset[1];
                            }
                    }
    
      if ($element->{$Wochentag[$wday]} == 1 && $element->{Stunden} == $hour && $element->{Minuten} == $min && $element->{KW} ne '') {
                if ($element->{KW} == $kw) {
                    knx_write($element->{ga},$element->{Wert},$element->{DPT});
                    next;
                } else {
                    next;
                }
            } elsif ($element->{$Wochentag[$wday]} == 1 && $element->{Stunden} == $hour && $element->{Minuten} == $min && $element->{Monat} ne '') {
                if ($element->{Monat} == $mon) {
                    knx_write($element->{ga},$element->{Wert},$element->{DPT});
                    next;
                } else {
                    next;
                }
            } elsif ($element->{$Wochentag[$wday]} == 1 && $element->{Stunden} == $hour && $element->{Minuten} == $min && $element->{KW} eq '' && $element->{Monat} eq '') {
                knx_write($element->{ga},$element->{Wert},$element->{DPT});
                next;
            }
        }    
    next;
    }
    
    sub getWeekNumber {
    my ($year, $month, $day) = @_;
    my $weekNumber = checkWeekNumber($year, $month, $day);
    # wenn Wochennummer gleich 0, dann ist das aktuelle Datum
    # in der Woche vor dem 4. Januar
    # also in der letzten Woche des letzten Jahres
    if ($weekNumber eq 0)
    {
    # Wochennummer des letzten Woche des letzten Jahres suchen
    $weekNumber = checkWeekNumber(($year - 1), 12, 31);
    
    # wenn die Wochennummer größer als 52 ist
    # dann prüfen ob diese Wochennummer korrekt ist oder
    # sie bereits die erste Woche des aktuellen Jahres ist
    if ($weekNumber gt 52)
    {
    $weekNumber = checkWeekNumber($year, 1, 1);
    # wenn der 1. Januar des aktuellen Jahres in der Woche 0 liegt
    # dann ist es die Woche 53
    if ($weekNumber eq 0)
    {
    $weekNumber = 53;
    }
    }
    }
    # wenn die Wochennummer größer als 52 ist
    # dann prüfen ob diese Wochennummer korrekt ist oder
    # sie bereits die erste Woche des nächsten Jahres ist
    elsif ($weekNumber gt 52)
    {
    $weekNumber = checkWeekNumber(($year + 1), 1, 1);
    # wenn der 1. Januar des nächsten Jahres in der Woche 0 liegt
    # dann ist es die Woche 53
    if ($weekNumber eq 0)
    {
    $weekNumber = 53;
    }
    }
    
    return ($weekNumber);
    }
    
    sub checkWeekNumber {
    my ($year, $month, $day) = @_;
    
    # 4. Januar als erste Woche erstellen
    my $firstDateTime = timelocal(0, 0, 12, 4, 0, $year);
    # Wochentag des 4. Januar ermitteln
    my $dayOfWeek = (localtime($firstDateTime))[6];
    $dayOfWeek = abs((($dayOfWeek + 6) % 7));
    # geh zu Wochenanfang (Montag) zurück
    $firstDateTime -= ($dayOfWeek * 3600 * 24);
    
    # aktuelles Datum erstellen
    my $currentDateTime = timelocal(0, 0, 14, $day, ($month - 1),$year);
    
    # Differenz in Tagen berechnen
    my $diffInDay = ($currentDateTime - $firstDateTime) / 3600 / 24;
    # Anzahl der Wochen zwischen aktuellem Datum und 4. Januar berechnen
    my $weekNumber = floor($diffInDay / 7) + 1;
    
    return ($weekNumber);
    }
    ... ich habe auch ein .diff zur aktuellen svn - Version hochgeladen.

    Anwendung
    :
    Soll ein Schaltbefehl zum Sonnenaufgang ausgeführt werden, im Array @Schaltzeiten das Element Astro auf 'a' setzen, für Sonnenuntergang das Element Astro auf 'u' setzen. Für diesen Eintrag werden dann die Stunden und Minuten - Einträge mit den berechneten Zeiten überschrieben.

    Achtung Änderung!
    Dank makki gibts jetzt das libastro-sunrise-perl im wiregate-repro!

    Voraussetzung:
    Damit die Berechnung funktioniert muß das Perl - Modul Astro::Sunrise installiert werden. Das gibts nun als debian-lenny library. Weiterhin braucht man das perl - modul DateTime. Dies gibts als lenny-paket:
    Code:
    apt-get install libdatetime-perl
    apt-get install libastro-sunrise-perl
    @Swiss
    Bei Gefallen kann der Code gerne ins ursprüngliche Plugin aufgenommen werden.

    Vielen Dank auch an kleinklausi für die Inspiration aus dem Rolladen - Plugin!


    Viel Spass beim Testen

    Wolfgang
    Angehängte Dateien

    #2
    Danke für das Script. Es fehlt wohl noch ein DateTime Modul?

    Kommentar


      #3
      Zitat von nipponichi Beitrag anzeigen
      Danke für das Script. Es fehlt wohl noch ein DateTime Modul?
      Hi nipponichi,

      eigentlich war das
      Code:
      use Time::Local;
      schon im Ursprungsplugin von swiss.
      Ich würde die über die debian - lib installieren:
      Code:
      apt-get install libdatetime-perl
      vG
      Wolfgang

      Kommentar


        #4
        Hallo Wolfgang

        Die Erweiterung gefällt mir sehr gut. Werde ich bei mir auch so übernehemen da ich es spätestens nächsten Winter zur Steuerung der Weinachtsbeleuchtung auch mit Astrofunktion brauche. Werde es mal auf Herz und Nieren testen aber sieht auf den ersten Blick wirklich gut aus. Werde ich gerne auch in's Original übernehmen wenn es eine Zeit lang stabil läuft und keine Einwände bestehen
        Gruss Patrik alias swiss

        Kommentar


          #5
          Hallo Patrik,

          die Erweiterung läuft bei mir seit 4 Wochen stabil. Du kannst die gerne ins Plugin übernehmen.
          ... und mein Weihnachtsstern hängt immer noch

          vG
          Wolfgang

          Kommentar


            #6
            Ok ich werde das mal so übernemen. Meine Arbeitsversion hat Teile drin die noch nicht fertig entwikelt sind. Da ich aber noch nicht weit bin und momentan noch gefühlte 100 andere Baustellen habe werde ich einfach mit deiner Verison weiterarbeiten. Macht auch das diff für spätere Erweiterungen einfacher

            LG Patrik
            Gruss Patrik alias swiss

            Kommentar


              #7
              Hallo Wolfgang

              Ich habe ein kleines Problem...

              Ich habe das von dir angefügte Astro.pm in das von dir angegeebne Verzeichnis kopiert. Leider kommt nun mit dem neuen Plugin folgende Fehlermeldung:

              Attempt to reload Astro/Sunrise.pm aborted. Compilation failed in require at (eval 181524) line 41, line 25804992. BEGIN failed--compilation aborted at (eval 181524) line 41, line 25804992.
              Hast du das pm für lenny kompiliert? Muss ich noch etwas machen um es an's laufen zu bekommen?

              LG Patrik
              Gruss Patrik alias swiss

              Kommentar


                #8
                Hallo Patrik,

                sorry, daß ich so spät reagiere ... ich hab den Thread völlig aus den Augen verloren.

                ... es hat sich ein Fehler eingeschlichen: Das Sunrise.pm muß je nach perl - Installation ggf. in
                Code:
                /usr/local/share/perl/5.10.0/Astro/Sunrise.pm
                kopiert werden. (Ich hab das Communitiy Gate auf voyage-linux installiert )

                Am besten ist es das Modul über CPAN nachzuinstallieren mit:
                Code:
                cpan -i Astro::Sunrise
                ... ich werde das in der Orginalankündigung noch nachtragen.

                vG
                Wolfgang

                Kommentar


                  #9
                  Das Plugin berücksichtigt wohl keine Sommerzeit. Zeit des Wiregate hat sich korrekt umgestellt, im Log ist die Aufgangs-/untergangsstunde gleich zu der gestern. Entsprechend zu früh wurde es eben dunkel ...

                  Kommentar


                    #10
                    Hallo nipponichi


                    Zitat von nipponichi Beitrag anzeigen
                    Das Plugin berücksichtigt wohl keine Sommerzeit. Zeit des Wiregate hat sich korrekt umgestellt, im Log ist die Aufgangs-/untergangsstunde gleich zu der gestern. Entsprechend zu früh wurde es eben dunkel ...
                    ... leider warst Du 10 Minuten zu schnell. Hier die Änderung zur Sommerzeit:

                    Bittel die Zeilen 68 ... 76 aus dem SVN wie folgt ändern:

                    Code:
                                    if ($element->{Astro} ne '') {
                                            if ($element->{Astro} eq 'a') {
                                                    if ($isdst) {
                                                            $element->{Stunden}=$sunrise[0]+1;
                                                    } else {
                                                            $element->{Stunden}=$sunrise[0];
                                                            }
                                                    $element->{Minuten}=$sunrise[1];
                                            } elsif ($element->{Astro} eq 'u') {
                                                    if ($isdst) {
                                                            $element->{Stunden}=$sunset[0]+1;
                                                    } else {
                                                            $element->{Stunden}=$sunset[0];
                                                            }
                                                    $element->{Minuten}=$sunset[1];
                                            }
                                    }
                    @Swiss: vielleicht könntest Du das im SVN aktualisieren:

                    ... ich habe es auch in der Originalankündigung nachgetragen

                    vG
                    Wolfgang
                    Angehängte Dateien

                    Kommentar


                      #11
                      Danke!
                      Man muß schon wissen, was sich hinter "isdst" verbirgt ...

                      Kommentar


                        #12
                        Ok hab ich im SVN Commited
                        Gruss Patrik alias swiss

                        Kommentar


                          #13
                          Hallo zusammen,

                          ich muß zugeben, daß ich etwas verwirrt bin.
                          Offensichtlich wird heute (Tag der SZ - Umschaltung + 1) die sunrise / sunset - Zeit korrekt ermittelt, wodurch der Patch aus #8 obsolet wäre!

                          @all: Könnt Ihr das so bestätigen?


                          Zitat von nipponichi Beitrag anzeigen
                          Danke!
                          Man muß schon wissen, was sich hinter "isdst" verbirgt ...
                          .. naja das ist das Standard - localtime Codeschnipsel aus der perl-doc
                          localtime - perldoc.perl.org
                          vG
                          Wolfgang

                          Kommentar


                            #14
                            Keine Ahnung. Warscheinlich wird die Zeitverschiebung für die Astrofunktion nur um Mitternacht berechnet und die Zeitumstellung war um 2 Uhr. Damit verschiebt sich alles um 1 Tag.
                            Gruss Patrik alias swiss

                            Kommentar


                              #15
                              Hallo Swiss,

                              Zitat von swiss Beitrag anzeigen
                              Keine Ahnung. Warscheinlich wird die Zeitverschiebung für die Astrofunktion nur um Mitternacht berechnet und die Zeitumstellung war um 2 Uhr. Damit verschiebt sich alles um 1 Tag.
                              sieht so aus! Auch die Kollegen von enertex haben ihre Freude damit https://knx-user-forum.de/eibpc/1372...ei-sunset.html

                              ... also Kommando zurück mit dem Patch!

                              vG
                              Wolfgang

                              Kommentar

                              Lädt...
                              X