Licht bei Bedingungen einschalten
Aufgabe
Es soll unter bestimmten Bedingungen beim Öffnen einer Tür das Licht eingeschaltet werden. An der Haustür ist dazu ein Tür-Kontakt angebracht.
Wenn die Tür geöffnet wird (doorContact = on) soll das Licht in der Wohnung angeschaltet werden, allerdings nur, wenn folgende Bedingungen zutreffen:
- es ist 30 Minuten nach Sonnenuntergang (es ist dunkel)
- innerhalb der letzten 20 Minuten wurde der Lampenstatus nicht auf "off" gesetzt
Die zweite Bedingung soll erreichen, dass das Licht nicht eingeschaltet wird, wenn jemand es manuell vor kurzem ausgeschaltet hat. Es soll insbesondere verhindert werden, dass beim Verlassen des Gebäudes das Licht wieder eingeschaltet wird, weil z.B. beim Verschließen die Tür noch mal kurz geöffnet wird.
Script
define storeLastOff notify .*:off { $data{lastOffTime} = time() } define sunSetOn notify doorContact:on { \ if($data{lastOffTime}+20*60 < time() &&\ sunset_abs(1800) lt sprintf("%%02d:%%02d", $hour, $min)) {\ fhem "set light on";;\ }\ }
Erläuterungen
Die Zeitangaben sind in Sekunden, sunset_abs(1800)
entspricht also den geforderten 30 Minuten.
sprintf
ist ein PERL Befehl, der aus den Variablenwerten aktuelle Stunde ("hour") und aktuelle Minute ("min") einen formatierten String erzeugt.
Konkret würde der Befehl:
sprintf("%02d:%02d",$hour,$min)
die Werte von "hour" und "min" auslesen und daraus einen Uhrzeitstring wie 20:31 bauen.
%02d erzeugt dabei eine ganzzahlige Nummer, die auch 2 führende Nullen haben kann (z.b. für Mitternacht),
wobei
- %d = ganzzahlige Nummer (im Gegensatz z.b. zu %f = dezimale Ziffer mit Nachkommastellen)
- 02 = zwei führende Nullen (im Gegensatz z.b. zu .3= drei Nachkommastellen)
definiert.
Diese genaue Formatierung ist wichtig, weil ansonsten z.B. 09:02 Uhr beim blossen Zusammenfügen der "hour" und "min" Variablen zu 9:2 Uhr führen würde und der Vergleich mit der Uhrzeit die sunset_abs ausgibt scheitern würde, da 09:02 ungleich 9:2 ist.
Für weitere Details siehe z.b. hier: PERL Dokumentation http://perldoc.perl.org/functions/sprintf.html
Problemastisch ist aber, dass FHEM das %-Zeichen als Platzhalter für empfangene Events auffasst und im Moment der Ausführung ersetzt.
So würde z.b.
define b3lampV1 notify btn3 set lamp %
bewirken, dass die Lampe "lamp" ein- oder ausgeschaltet wird, je nachdem welchen Wert btn3 enthält, da zum Zeitpunkt der Ausführung der Ausdruck "set lamp %" in z.b. "set lamp off" umgewandelt wird.
Würde man in einem Script nun den an sich richtigen Ausdruck:
printf("%02d:%02d",$hour,$min)
verwenden, würden die %-Zeichen ersetzt.
Will man in einem Script also tatsächlich das %-Zeichen als Text verwenden, muss das % verdoppelt werden:
sprintf("%%02d:%%02d", $hour, $min)
Mehr Details hier:
Notify -Section in FHEM commandref http://fhem.de/commandref.html#notify