FHEM Forum

FHEM => Codeschnipsel => Thema gestartet von: klausw am 15 November 2016, 17:02:14

Titel: Weihnachstbeleuchtung automatisch schalten
Beitrag von: klausw am 15 November 2016, 17:02:14
Bald ist es wieder soweit.
Mancher wird es übertrieben finden ... aber was solls  8)

Zwischen dem Donnerstag vor dem 1. Advent und dem 2. Februar werden alle Geräte mit dem Attribut "weihnachtsbel = 1"
In einem Zeitraum von 0-6min (per Zufallsgenerator bestimmt) nach ausführen von advent() auf "on" gesetzt.
Und 0:00 (Fr.-So. 1:00, 24.12. 10:00, Silvester 8:00) wieder abgeschaltet.
Kann natürlich alles angepasst werden.


Globales Userattribut hinzufügen:
{defined AttrVal('global', 'userattr', undef) ? (AttrVal('global', 'userattr', undef) =~ /weihnachtsbel/ ? return "Schon vorhanden" : fhem"attr global userattr " . AttrVal('global', 'userattr', undef) . " weihnachtsbel:0,1") : return "Fehler"}
Jedes device bei dem das attribut weihnachtsbel auf 1 gesetzt ist wird geschaltet

at anlegen (dieses führt 10min vor Sonnenuntergang die Routine advent() aus)
define Weihnachtsbeleuchtung at *{sunset(-600)} { advent() }

in die 99_myUtils.pm einfügen:

# Weihnachtsbeleuchtung
sub advent {
my $lichtquellen = "a:weihnachtsbel=1";
# Heute aufgeschlüsselt
#my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);   # $year ist jahr ab 1900
# Heute
my $heute = DateTime->now;
# Lichtmess
my $lichtmess = DateTime->new(year => $heute->year(), month =>  2, day =>  2);
# Heilig Abend
my $date =      DateTime->new(year => $heute->year(), month => 12, day => 24);
# 4. Advent (Sonntag vor Heilig Abend)
my $wochentag = 0;            # Sonntag
$date->subtract(days => ($date->day_of_week - $wochentag) % 7);
# Donnersttag vor 1. Advent (4. Advent - 24 Tage)
$date->subtract(days => 24);
# Prüfen ob heute innerhalb der Weihnachszeit liegt
if ($heute >= $date || $heute < $lichtmess) {
my $endezeit = ($heute->wday() < 5 ? "0:00" : "1:00");
if ($heute->month() == 12 && $heute->day() == 24) {
#Heiligabend
$endezeit = "10:00";
} elsif ($heute->month() == 12 && $heute->day() == 31) {
#Sylvester
$endezeit = "8:00";
}
my @dlist = split "\n", (fhem "list $lichtquellen");
foreach (@dlist) {
# Startzeit per Zufall bis zu 6min verschieben
my $beginn = sprintf "%02d:%02d:%02d", 0, int(rand(5)), int(rand(59));
# Endzeit per Zufall bis zu 5min verschieben
my ($estunde, $eminute) = split(/:/,$endezeit);
$date->set(hour => $estunde, minute => $eminute);
$date->add(seconds => int(rand(60*5)));
$endezeit = sprintf "%02d:%02d:%02d", $date->hour, $date->minute, $date->second;
my $anbis = "on-till-overnight";
#$anbis = "on-till" if ($heute->hour < $date->hour || ($heute->hour == $date->hour && $heute->minute < $date->minute) ) ;
#Log3 undef, 1, "schalte $_ ein in $beginn $anbis $endezeit";
fhem"define on$_ at +$beginn {fhem(\"set $_ on-till-overnight $endezeit\")}";
}
}
}
Titel: Antw:Weihnachstbeleuchtung automatisch schalten
Beitrag von: h-man-kl am 17 November 2016, 09:46:01
TOP!
Kleine Frage, habe mit der 99_myUtils noch nie was gemacht, wo finde ich denn das mit "Donnerstag vor dem 1. Advent"  würde das gerne ändern
Danke & Gruß
H-Man
Titel: Antw:Weihnachstbeleuchtung automatisch schalten
Beitrag von: klausw am 17 November 2016, 12:15:35
Ich habe noch nen Fahler drin.
Es funktioniert nur, wenn mehr als 1 device mit dem attribut weihnachtsbel existiert.

Wenn es auch mit einem laufen soll:
Erste Zeile ersetzen:
my $lichtquellen = "a:weihnachtsbel=wt_1 NAME";

In foreach ändern:

foreach (@dlist) {
my @dname = split " ", $_;
# Startzeit per Zufall bis zu 6min verschieben
my $beginn = sprintf "%02d:%02d:%02d", 0, int(rand(5)), int(rand(59));
...
#Log3 undef, 1, "schalte $dname[0] ein in $beginn $anbis $endezeit";
fhem"define on$dname[0] at +$beginn {fhem(\"set $dname[0] on-till-overnight $endezeit\")}";
}



Zitat von: h-man-kl am 17 November 2016, 09:46:01
Kleine Frage, habe mit der 99_myUtils noch nie was gemacht, wo finde ich denn das mit "Donnerstag vor dem 1. Advent"  würde das gerne ändern
woran hakt es denn?
Ich nutzeDateTime (http://search.cpan.org/~drolsky/DateTime-1.41/lib/DateTime.pm) dafür.
In den Variablen ist das komplette Datum und Uhrzeit gespeichert (die Uhrzeit brauchen wir natürlich nicht)

Speichere aktuelle Zeit in Variable
my $heute = DateTime->now;

Speichere Datum Heilig Abend im aktuellen Jahr in Variable $date
my $date = DateTime->new(year => $heute->year(), month => 12, day => 24);

Subtrahiere x Wochentage von $date. Wenn man den aktuellen Wochentag abzieht bekommt man das Datum des vorangegangenen Sonntags. Wochentag - 1 -> Montag usw.
my $wochentag = 0;            # Sonntag
$date->subtract(days => ($date->day_of_week - $wochentag) % 7);


Subtrahiere x Tage von $date
In date ist jetzt das Datum des 4. Advents. Der Donnerstag vor dem ersten Advent ist 24 Tage davor.
$date->subtract(days => 24);
Titel: Antw:Weihnachstbeleuchtung automatisch schalten
Beitrag von: h-man-kl am 17 November 2016, 12:41:38
Danke für die Erlklärung. hatte die Zeilen irgendwie mißverstanden!

Gruß
H-Man
Titel: Antw:Weihnachstbeleuchtung automatisch schalten
Beitrag von: blueberry63 am 17 November 2016, 17:04:34
Es geht auch etwas einfacher:
1. ein Structure anlegen mit allen Geräten, die geschaltet werden sollen
2. einige ATs für das Ein-und Ausschalten anlegen (bei mir sind es 4) und diese nach der Weihnachtszeit auf "DISABLE" setzen

Gruß
Blueberry63
Titel: Antw:Weihnachstbeleuchtung automatisch schalten
Beitrag von: h-man-kl am 21 November 2016, 09:43:06
@klausw:
Ich hätte da noch eine Anregung, allerdings weiß ich überhaupt nicht wie das gehenkann :-)

Ich lasse meine Rollladen per at als structure runterfahren. Das hat natürlich de Nachteil, dass der Blick auf die Weihnachtsbeleuchtung frühzeitig verdeckt wird.
Wenn deine Weihnchtsbeleuchtung also "irgendwie" auf die Rollläden einfluss nehmen könnte, die nicht runterfahren sollen.... Das wäre TOP!

Gruß
H-Man
Titel: Antw:Weihnachstbeleuchtung automatisch schalten
Beitrag von: klausw am 22 November 2016, 16:06:46
wenn du die Rollläden nach dem einschalten der Weihnachtsbeleuchtung runter fährst könntest du in dem at prüfen, ob eine der Beleuchtungen schon eingeschaltet ist.
Oder du löst es mit einem Dummy, den du unter "if ($heute >= $date || $heute < $lichtmess) {" setzt und in einem nachfolgenden "else" auf aus setzt. Diesen fragst du dann auch wieder im at ab.