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:
... 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:
@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
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);
}
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-[URL="http://redaktion.knx-user-forum.de/lexikon/perl/"]perl[/URL]
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


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
Kommentar