Hallo,
nachdem ich erfolgreich KNXD mit einem fremden Bussystem ans Laufen gebracht habe, stelle ich meine Plugins auf den Wiregate Syntax um.
Hier ist jetzt eine Abwandlung des Schaltuhr-Plugins, welches aber ohne eine Cycle-Zeit von 20 Sekunden auskommt.
Das Plugin wird immer nur zu den Schaltzeiten aufgerufen und behandelt einen Feiertag als Sonntag. Sonnenauf- und Untergangszeiten sind ebenfalls möglich.
Nach dem gleichen Prinzip habe ich auch andere Plugins mit täglich festgelegten Aktionszeiten angepasst. Ich denke dass dadurch weniger Ressourcen verbraucht werden, was z.B. bei ARM-Systemen von Vorteil ist.
Gruß
Carsten
nachdem ich erfolgreich KNXD mit einem fremden Bussystem ans Laufen gebracht habe, stelle ich meine Plugins auf den Wiregate Syntax um.
Hier ist jetzt eine Abwandlung des Schaltuhr-Plugins, welches aber ohne eine Cycle-Zeit von 20 Sekunden auskommt.
Das Plugin wird immer nur zu den Schaltzeiten aufgerufen und behandelt einen Feiertag als Sonntag. Sonnenauf- und Untergangszeiten sind ebenfalls möglich.
Nach dem gleichen Prinzip habe ich auch andere Plugins mit täglich festgelegten Aktionszeiten angepasst. Ich denke dass dadurch weniger Ressourcen verbraucht werden, was z.B. bei ARM-Systemen von Vorteil ist.
Code:
# Wochenzeitschaltuhr zum Senden von GA's # - Berücksichtigung von Sonnenaufgang und Sonnenuntergang # - Feiertag wird als Sonntag behandelt (Feiertage je # nach Bundesland im Unterprogramm anpassen) # - Berücksichtigung von Wechsel auf Sommer- oder Winterzeit # # Version 0.1 21.05.2013 # Copyright: derwolff2010 (https://knx-user-forum.de/members/derwolff2010.html) # License: GPL (v2) # Inspiriert durch die Plugins von swiss, zeitlerw, Fry my @Schaltzeiten; #Einstellungen--------------------------------------------------------------------------- # Die Standortdaten # Die Koordinaten des Hauses. Sehr einfach über http://www.getlatlon.com/ zu ermitteln. my ($lat, $lon, $elev) = ( 0.0, # Breitengrad in Grad 0.0 );# 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=-6; # Bürgerliche Dämmerung #Pro Schaltpunkt den unten stehenden Eintrag kopieren und anpassen. #Sollen Schaltzeiten astronomisch geschaltet werden, so muss bei astro 'a' für Sonnenaufgang #oder 'u' für Sonnenuntergang eingetragen werden. Die Uhrzeit wird dann ignoriert. #Feiertage werden wie Sonntage behandelt. push @Schaltzeiten, { name => "Schaltzeit", mo => 1, di => 1, mi => 1, do => 1, fr => 1, sa => 0, so => 0, zeit => '08:00', astro => '', ga => '0/0/0', wert => 1, dpt => 1 }; # Ende Einstellungen----------------------------------------------------------------------- use POSIX; use Time::Local; use Astro::Sunrise; # Aufrufgrund ermitteln my $event=undef; if (!$plugin_initflag) { $event='restart'; } # Restart des daemons / Reboot elsif ($plugin_info{$plugname.'_lastsaved'} > $plugin_info{$plugname.'_last'}) { $event='modified'; } # Plugin modifiziert elsif (%msg) { $event='bus'; } # Bustraffic elsif ($fh) { $event='socket'; } # Netzwerktraffic else { $event='cycle'; } # Zyklus # Plugin-Code fuer die verschiedenen Aufrufvarianten if($event=~/restart|modified/) { # Erster Aufruf nach Reboot, Daemon-Restart oder Plugin-Modifikation # Cleanup aller Variablen for my $k (grep /^$plugname\_/, keys %plugin_info) { delete $plugin_info{$k}; } plugin_log($plugname,"initialisiert"); } #Hier wird ein Array angelegt, um die Wochentagsnummer von localtime zu übersetzen my @Wochentag = ('so', 'mo', 'di', 'mi', 'do', 'fr', 'sa'); # Sonnenaufgang und Untergang berechnen my $sonnenaufgang = sec(sun_rise($lon,$lat,$winkel)); my $sonnenuntergang = sec(sun_set($lon,$lat,$winkel)); my $schaltzeit = 0; my $schaltzeit_min = 86400; # 1 Tag my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday) = localtime(time); $yday = $yday+1; my $time = $hour*3600+$min*60+$sec; # Feiertag als Sonntag behandeln if (is_holiday()) { $wday = 0;} # nächste Schaltzeit bestimmen foreach my $element (@Schaltzeiten) { #Überspringe Schaltpunkt wenn heute schon ausgeführt oder Wochentag nicht aktiv ist if ($plugin_info{$plugname.'_'.$element->{name}}==$yday || $element->{$Wochentag[$wday]} != 1 ) {next;} if ($element->{astro} ne '') { if ($element->{astro} eq 'a') {$schaltzeit = $sonnenaufgang;} else {$schaltzeit = $sonnenuntergang;} } else {$schaltzeit = sec($element->{zeit});} if ($time >= $schaltzeit && $time < ($schaltzeit+60)) { $plugin_info{$plugname.'_'.$element->{name}}=$yday; knx_write($element->{ga},$element->{wert},$element->{dpt}); plugin_log($plugname,'Schaltpunkt: '.$element->{name}.' ausgeführt. Wert: '.$element->{wert}.' an Gruppenadresse '.$element->{ga}.' gesendet'); } elsif ($schaltzeit > $time && $schaltzeit < $schaltzeit_min) {$schaltzeit_min = $schaltzeit;} } # Nächste Aufrufzeit setzen, spätestens wieder um 0 Uhr if ($schaltzeit_min == 86400) {$schaltzeit_min=sek_bis_schaltzeit(sec('00:00'));} else {$schaltzeit_min=sek_bis_schaltzeit($schaltzeit_min);} $plugin_info{$plugname.'_cycle'}=$schaltzeit_min; ($sec,$min,$hour) = localtime(time + $schaltzeit_min); $hour = sprintf "%02d",$hour; $min = sprintf "%02d",$min; plugin_log($plugname,"Nächster Aufruf in $schaltzeit_min Sek., $hour:$min Uhr"); return; # Unterprogramme --------------------------------------------------------------- sub sek_bis_schaltzeit { # Eingangsparam.: Zeit in Sek., Ausgabeparam.: Zeit in Sek. # Berechnet die Zeit von aktueller Zeit bis zur Schaltzeit in Sek. my $schalt_zeit_sek = $_[0]; my $stunde = int($schalt_zeit_sek/3600); # Aktuelle Zeit lesen my ($sec,$min,$hour) = localtime(time); my $time = $hour*3600+$min*60+$sec; # Wenn akt. Zeit schon später als Schaltzeit, nächsten Tag einplanen? if ($schalt_zeit_sek < $time) {$schalt_zeit_sek+=86400; } my $wartezeit = $schalt_zeit_sek - $time; ($sec,$min,$hour) = localtime(time+$wartezeit); # Überprüfung auf Wechsel von Sommer- u. Winterzeit if ($hour<$stunde) {$wartezeit+=3600;} elsif ($hour>$stunde) {$wartezeit-=3600;} return ($wartezeit); } sub is_holiday { #Aufruf: is_holiday() my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday) = localtime(time); $year = $year + 1900; $yday = $yday + 1; # Schaltjahr? my $leapyear = ($year % 4)==0 && ($year % 100!=0 || $year % 400==0); # Osterdatum berechnen (Algorithmus von Ron Mallen, Codefragment von Randy McLeary, beruht auf der Formel von Gauss/Lichtenberg) my $C = int($year/100); my $G = $year%19; my $K = int(($C - 17)/25); my $I = ($C - int($C/4) - int(($C - $K)/3) + 19 * $G + 15)%30; $I = $I - int($I/28) * (1 - int($I/28) * int(29/($I + 1)) * int((21 - $G)/11)); my $L = $I - ($year + int($year/4) + $I + 2 - $C + int($C/4))%7; my $M = 3 + int(($L + 40)/44); my $D = $L + 28 - 31 * int($M/4); # diesjaehriger Ostersonntag ist $year-$M-$D # julianisches Osterdatum (Tag im Jahr) berechnen $year-$J my @days_before_month=(0,0,31,59+$leapyear,90+$leapyear,120+$leapyear,151+$leapyear,181+$leapyear,212+$leapyear,243+$leapyear, 273+$leapyear,304+$leapyear,334+$leapyear); my $J = $days_before_month[$M]+$D; # Feiertagstabelle für NRW als Tageszahl im Jahr (1=1.Januar, 32=1.Februar usw.): 1.1., 1.5., 3.10., 1.11., 25./26.12. # und die auf Ostern bezogenen Kirchenfeiertage: Karfreitag, Ostern (2x), Christi Himmelfahrt, Pfingsten (2x), Fronleichnam my @holidays=(1,121+$leapyear,276+$leapyear,304+$leapyear,359+$leapyear,360+$leapyear,$J-2,$J,$J+39,$J+49,$J+50,$J+60); return (grep { $_==$yday } @holidays) ? 1 : 0; } sub sunpos { # Module laden use Astro::Coord::ECI; use Astro::Coord::ECI::Sun; use Astro::Coord::ECI::TLE; use Astro::Coord::ECI::Utils qw{rad2deg deg2rad}; # Aktuelle Zeit my $time = time (); # Die eigenen Koordinaten my $loc = Astro::Coord::ECI->geodetic(deg2rad(shift), deg2rad(shift), shift); # Sonne instanzieren my $sun = Astro::Coord::ECI::Sun->universal($time); # Sonnenstand berechnen my ($azimut, $elevation, $range) = $loc->azel($sun); return (rad2deg($azimut), rad2deg($elevation)); } sub sec { # Konvertiert HH:MM in Sekunden my $time = $_[0]; $time =~ /(\d+):(\d+)/; return ($1*60*60+$2*60); }
Carsten
Kommentar