diff --git a/fhem/FHEM/98_DOIF.pm b/fhem/FHEM/98_DOIF.pm
index 6458ce33e..a74ecb3e2 100644
--- a/fhem/FHEM/98_DOIF.pm
+++ b/fhem/FHEM/98_DOIF.pm
@@ -34,6 +34,9 @@ sub DOIF_delTimer($)
foreach my $key (keys %{$hash->{triggertime}}) {
RemoveInternalTimer (\$hash->{triggertime}{$key});
}
+ foreach my $key (keys %{$hash->{ptimer}}) {
+ RemoveInternalTimer ($key);
+ }
}
sub DOIF_delAll($)
@@ -55,12 +58,16 @@ sub DOIF_delAll($)
delete ($hash->{internals});
delete ($hash->{trigger});
delete ($hash->{triggertime});
+ delete ($hash->{ptimer});
delete ($hash->{interval});
+ delete ($hash->{perlblock});
+ delete ($hash->{var});
+
foreach my $key (keys %{$hash->{Regex}}) {
delete $hash->{Regex}{$key} if ($key !~ "STATE|DOIF_Readings|uiTable");
}
foreach my $key (keys %{$defs{$hash->{NAME}}{READINGS}}) {
- delete $defs{$hash->{NAME}}{READINGS}{$key} if ($key =~ "^(Device|state|error|warning|cmd|e_|timer_|wait_|matched_|last_cmd|mode)");
+ delete $defs{$hash->{NAME}}{READINGS}{$key} if ($key =~ "^(Device|state|error|warning|cmd|e_|timer_|wait_|matched_|last_cmd|mode|block_)");
}
}
@@ -1749,7 +1756,7 @@ DOIF_SetState($$$$$)
if ($cmd =~ /^"(.*)"$/) {
$cmd=$1;
}
- readingsBeginUpdate ($hash);
+ readingsBeginUpdate($hash);
if ($event) {
push (@{$hash->{helper}{DOIF_eventas}},"cmd_nr: $cmdNr");
readingsBulkUpdate($hash,"cmd_nr",$cmdNr);
@@ -2105,6 +2112,63 @@ sub CheckRegexpDoIf
return undef;
}
+sub DOIF_Perl_Trigger
+{
+ my ($hash,$device)= @_;
+ my $timerNr=-1;
+ my $ret;
+ my $err;
+ my $event="$device";
+ my $pn=$hash->{NAME};
+ my $max_cond=keys %{$hash->{condition}};
+ my $j;
+ my @triggerEvents;
+ for (my $i=0; $i<$max_cond;$i++) {
+ if ($device eq "") {# timer
+ my $found=0;
+ if (defined ($hash->{timers}{$i})) {
+ foreach $j (split(" ",$hash->{timers}{$i})){
+ if ($hash->{timer}{$j} == 1) {
+ $found=1;
+ $timerNr=$j;
+ last;
+ }
+ }
+ }
+ next if (!$found);
+ $event="timer_".($timerNr+1);
+ @triggerEvents=($event);
+ $hash->{helper}{triggerEvents}=\@triggerEvents;
+ $hash->{helper}{triggerDev}="";
+ $hash->{helper}{event}=$event;
+ } else { #event
+ if (!defined CheckRegexpDoIf($hash,"cond", $device,$i,$hash->{helper}{triggerEvents},1)) {
+ next if (!defined ($hash->{devices}{$i}));
+ next if ($hash->{devices}{$i} !~ / $device /);
+ next if (AttrVal($pn, "checkReadingEvent", 0) and !CheckReadingDoIf ($hash->{readings}{$i},$hash->{helper}{triggerEventsState}) and (defined $hash->{internals}{$i} ? $hash->{internals}{$i} !~ / $device:.+ /:1))
+ }
+ $event="$device";
+ }
+ if (($ret,$err)=DOIF_CheckCond($hash,$i)) {
+ if ($err) {
+ Log3 $hash->{Name},4,"$hash->{NAME}: $err in perl block ".($i+1) if ($ret != -1);
+ if ($hash->{perlblock}{$i}) {
+ readingsSingleUpdate ($hash, "block_$hash->{perlblock}{$i}", $err,0);
+ } else {
+ readingsSingleUpdate ($hash, sprintf("block_%02d",($i+1)), $err,0);
+ }
+ } else {
+ if ($hash->{perlblock}{$i}) {
+ readingsSingleUpdate ($hash, "block_$hash->{perlblock}{$i}", "executed",0);
+ } else {
+ readingsSingleUpdate ($hash, sprintf("block_%02d",($i+1)), "executed",0);
+ }
+ }
+ }
+ }
+ return undef;
+}
+
sub DOIF_Trigger
{
my ($hash,$device,$checkall)= @_;
@@ -2206,7 +2270,7 @@ DOIF_Notify($$)
my $err;
my $eventa;
my $eventas;
-
+
$eventa = deviceEvents($dev, AttrVal($pn, "addStateEvent", 0));
$eventas = deviceEvents($dev, 1);
@@ -2232,6 +2296,17 @@ DOIF_Notify($$)
readingsEndUpdate($hash, 0);
}
+ if (defined $hash->{perlblock}{init}) {
+ if (($ret,$err)=DOIF_CheckCond($hash,$hash->{perlblock}{init})) {
+ if ($err) {
+ Log3 $hash->{Name},4,"$hash->{NAME}: $err in perl block init" if ($ret != -1);
+ readingsSingleUpdate ($hash, "block_init", $err,0);
+ } else {
+ readingsSingleUpdate ($hash, "block_init", "executed",0);
+ }
+ }
+ }
+
my $startup=AttrVal($pn, "startup", 0);
if ($startup and !AttrVal($pn,"disable",0)) {
$startup =~ s/\$SELF/$pn/g;
@@ -2268,7 +2343,7 @@ DOIF_Notify($$)
$ret=0;
$hash->{helper}{DOIF_eventas} = ();
-
+
if ((($hash->{devices}{all}) and $hash->{devices}{all} =~ / $dev->{NAME} /) or defined CheckRegexpDoIf($hash,"cond",$dev->{NAME},"",$eventa,0)){
$hash->{helper}{cur_cmd_nr}="Trigger $dev->{NAME}" if (AttrVal($hash->{NAME},"selftrigger","") ne "all");
$hash->{helper}{triggerEvents}=$eventa;
@@ -2297,9 +2372,8 @@ DOIF_Notify($$)
readingsSingleUpdate ($hash, "e_".$dev->{NAME}."_events",join(",",@{$eventa}),0);
}
}
-
readingsSingleUpdate ($hash, "Device",$dev->{NAME},0);
- $ret=DOIF_Trigger($hash,$dev->{NAME});
+ $ret=$hash->{MODEL} eq "Perl" ? DOIF_Perl_Trigger($hash,$dev->{NAME}) : DOIF_Trigger($hash,$dev->{NAME});
}
if ((defined CheckRegexpDoIf($hash,"STATE",$dev->{NAME},"STATE",$eventa,1)) and !$ret) {
@@ -2391,7 +2465,7 @@ DOIF_TimerTrigger ($)
}
}
}
- $ret=DOIF_Trigger ($hash,"") if (ReadingsVal($pn,"mode","") ne "disabled");
+ $ret=($hash->{MODEL} eq "Perl" ? DOIF_Perl_Trigger($hash,"") : DOIF_Trigger($hash,"")) if (ReadingsVal($pn,"mode","") ne "disabled");
for (my $j=0; $j<$hash->{helper}{last_timer};$j++) {
$hash->{timer}{$j}=0;
if (defined $hash->{localtime}{$j} and $hash->{localtime}{$j} == $localtime) {
@@ -2719,11 +2793,133 @@ DOIF_SleepTrigger ($)
if (ReadingsVal($pn,"mode","") ne "disabled") {
DOIF_cmd ($hash,$sleeptimer,$sleepsubtimer,$hash->{helper}{sleepdevice});
}
-
delete $hash->{helper}{cur_cmd_nr};
return undef;
}
+sub DOIF_set_Timer
+{
+ my ($hash,$event,$seconds)=@_;
+ my $name=$hash->{NAME};
+ my $timername="$name:$event";
+ my $current = gettimeofday();
+ my $next_time = $current+$seconds;
+ RemoveInternalTimer($timername);
+ $hash->{ptimer}{$timername}=$next_time;
+ if ($seconds > 0) {
+ $event =~ s/\W/_/g;
+ readingsSingleUpdate ($hash,"timer_$event",strftime("%d.%m.%Y %H:%M:%S",localtime($next_time)),0);
+ }
+ InternalTimer($next_time, "DOIF_PerlTimer", $timername, 0);
+}
+
+sub DOIF_get_Timer
+{
+ my ($hash,$event)=@_;
+ my $name=$hash->{NAME};
+ my $timername="$name:$event";
+ my $current = gettimeofday();
+ if (defined $hash->{ptimer}{$timername}) {
+ my $sec=$hash->{ptimer}{$timername}-$current;
+ if ($sec > 0) {
+ return ($sec);
+ } else {
+ delete ($hash->{ptimer}{$timername});
+ return (0);
+ }
+ } else {
+ return (0);
+ }
+}
+
+sub DOIF_PerlTimer
+{
+ my ($timername)=@_;
+ my ($name,$event)=split(":",$timername);
+ DoTrigger($name, $event);
+ $event =~ s/\W/_/g;
+ delete ($defs{$name}{READINGS}{"timer_$event"});
+}
+
+sub DOIF_del_Timer
+{
+ my ($hash,$event)=@_;
+ my $name=$hash->{NAME};
+ my $timername="$name:$event";
+ delete $hash->{ptimer}{$timername};
+ $event =~ s/\W/_/g;
+ delete ($defs{$hash->{NAME}}{READINGS}{"timer_$event"});
+ RemoveInternalTimer($timername);
+}
+
+sub DOIF_set_Event
+{
+ my ($hash,$event)=@_;
+ DOIF_set_Timer($hash,$event,0);
+}
+
+sub
+CmdDoIfPerl($$)
+{
+ my ($hash, $tail) = @_;
+ my $perlblock="";
+ my $beginning;
+ my $ret;
+ my $err="";
+ my $i=0;
+
+#def modify
+ if ($init_done)
+ {
+ DOIF_delTimer($hash);
+ DOIF_delAll ($hash);
+ readingsBeginUpdate($hash);
+ readingsBulkUpdate($hash,"state","initialized");
+ readingsBulkUpdate ($hash,"mode","enabled");
+ readingsEndUpdate($hash, 1);
+ $hash->{helper}{globalinit}=1;
+ }
+
+ $hash->{helper}{last_timer}=0;
+ $hash->{helper}{sleeptimer}=-1;
+
+ return("","") if ($tail =~ /^ *$/);
+
+ $tail =~ s/set_Timer[ \t]*\(/DOIF_set_Timer\(\$hash,/g;
+ $tail =~ s/get_Timer[ \t]*\(/DOIF_get_Timer\(\$hash,/g;
+ $tail =~ s/del_Timer[ \t]*\(/DOIF_del_Timer\(\$hash,/g;
+ $tail =~ s/set_Event[ \t]*\(/DOIF_set_Event\(\$hash,/g;
+ $tail =~ s/set_Reading[ \t]*\(/readingsSingleUpdate\(\$hash,/g;
+ $tail =~ s/\$_(\w+)/\$hash->\{var\}\{$1\}/g;
+
+ while ($tail ne "") {
+ ($beginning,$perlblock,$err,$tail)=GetBlockDoIf($tail,'[\{\}]');
+ return ($perlblock,$err) if ($err);
+ ($perlblock,$err)=ReplaceAllReadingsDoIf($hash,$perlblock,$i,0);
+ return ($perlblock,$err) if ($err);
+ $hash->{condition}{$i}=$perlblock;
+ if ($beginning =~ /(\w*)[\s]*$/) {
+ $hash->{perlblock}{$i}=$1;
+ if ($1 eq "init") {
+ $hash->{perlblock}{init}=$i;
+ if ($init_done) {
+ if (($ret,$err)=DOIF_CheckCond($hash,$hash->{perlblock}{init})) {
+ if ($err) {
+ Log3 $hash->{Name},4,"$hash->{NAME}: $err in perl block init" if ($ret != -1);
+ readingsSingleUpdate ($hash, "block_init", $err,0);
+ } else {
+ readingsSingleUpdate ($hash, "block_init", "executed",0);
+ }
+ }
+ }
+ }
+ }
+ $i++;
+ }
+ return("","")
+}
+
+
#############################
sub
CmdDoIf($$)
@@ -2742,13 +2938,6 @@ CmdDoIf($$)
my $j=0;
my $last_do;
- if (!$tail) {
- $tail="";
- } else {
- $tail =~ s/(##.*\n)|(##.*$)|\n/ /g;
- $tail =~ s/\$SELF/$hash->{NAME}/g;
- }
-
#def modify
if ($init_done)
{
@@ -2766,7 +2955,9 @@ CmdDoIf($$)
$hash->{helper}{sleeptimer}=-1;
return("","") if ($tail =~ /^ *$/);
-
+
+ $tail =~ s/\n/ /g;
+
while ($tail ne "") {
return($tail, "no left bracket of condition") if ($tail !~ /^ *\(/);
#condition
@@ -2837,7 +3028,27 @@ DOIF_Define($$$)
my ($hash, $def) = @_;
my ($name, $type, $cmd) = split(/[\s]+/, $def, 3);
return undef if (AttrVal($hash->{NAME},"disable",""));
- my ($msg,$err)=CmdDoIf($hash,$cmd);
+ my $err;
+ my $msg;
+
+ if (!$cmd) {
+ $cmd="";
+ } else {
+ $cmd =~ s/(##.*\n)|(##.*$)/ /g;
+ $cmd =~ s/\$SELF/$hash->{NAME}/g;
+ }
+
+ if ($cmd eq "" or $cmd =~ /^ *\(/) {
+ $hash->{MODEL}="FHEM";
+ ($msg,$err)=CmdDoIf($hash,$cmd);
+ #delete $defs{$hash->{NAME}}{".AttrList"};
+ setDevAttrList($hash->{NAME});
+ } else {
+ $hash->{MODEL}="Perl";
+ #$defs{$hash->{NAME}}{".AttrList"} = "disable:0,1 loglevel:0,1,2,3,4,5,6 startup state initialize notexist checkReadingEvent:1,0 addStateEvent:1,0 weekdays setList:textField-long readingList DOIF_Readings:textField-long uiTable:textField-long ".$readingFnAttributes;
+ setDevAttrList($hash->{NAME},"disable:0,1 loglevel:0,1,2,3,4,5,6 startup state initialize notexist checkReadingEvent:1,0 addStateEvent:1,0 weekdays setList:textField-long readingList DOIF_Readings:textField-long uiTable:textField-long ".$readingFnAttributes);
+ ($msg,$err)=CmdDoIfPerl($hash,$cmd);
+ }
if ($err ne "") {
$msg=$cmd if (!$msg);
my $errmsg="$name $type: $err: $msg";
@@ -2858,7 +3069,24 @@ DOIF_Attr(@)
if (($a[0] eq "set" and $a[2] eq "disable" and ($a[3] eq "0")) or (($a[0] eq "del" and $a[2] eq "disable")))
{
my $cmd = $defs{$hash->{NAME}}{DEF};
- my ($msg,$err)=CmdDoIf($hash,$cmd);
+ my $msg;
+ my $err;
+
+ if (!$cmd) {
+ $cmd="";
+ } else {
+ $cmd =~ s/(##.*\n)|(##.*$)/ /g;
+ $cmd =~ s/\$SELF/$hash->{NAME}/g;
+ }
+
+ if ($cmd eq "" or $cmd =~ /^ *\(/) {
+ $hash->{MODEL}="FHEM";
+ ($msg,$err)=CmdDoIf($hash,$cmd);
+ } else {
+ $hash->{MODEL}="Perl";
+ ($msg,$err)=CmdDoIfPerl($hash,$cmd);
+ }
+
if ($err ne "") {
$msg=$cmd if (!$msg);
return ("$err: $msg");
@@ -2878,7 +3106,6 @@ DOIF_Attr(@)
delete $hash->{Regex}{"STATE"};
} elsif($a[0] eq "set" && $a[2] eq "wait") {
RemoveInternalTimer($hash);
- #delete ($defs{$hash->{NAME}}{READINGS}{wait_timer});
readingsSingleUpdate ($hash, "wait_timer", "no timer",1);
$hash->{helper}{sleeptimer}=-1;
} elsif($a[0] eq "del" && $a[2] eq "repeatsame") {
@@ -2898,10 +3125,8 @@ DOIF_Attr(@)
my $err=DOIF_uiTable_def($hash,$a[3],$a[2]);
return $err if ($err);
DOIF_reloadFW;
- # InternalTimer(gettimeofday()+2,"DOIF_reloadFW",$hash) if($a[3]=~/\$ATTRIBUTESFIRST *= *2/);
}
} elsif($a[0] eq "del" && ($a[2] eq "uiTable" || $a[2] eq "uiState")) {
- #my $table=$a[2];
delete ($hash->{Regex}{$a[2]});
delete ($hash->{$a[2]});
} elsif($a[0] eq "set" && $a[2] eq "startup") {
@@ -2970,16 +3195,16 @@ DOIF_Set($@)
my $setList = AttrVal($pn, "setList", " ");
$setList =~ s/\n/ /g;
my $cmdList="";
- #my @cmdState=SplitDoIf('|',AttrVal($hash->{NAME},"cmdState",""));
- #my @cmdSubState;
- my $max_cond=keys %{$hash->{condition}};
- $max_cond++ if (defined ($hash->{do}{$max_cond}{0}) or ($max_cond == 1 and !(AttrVal($pn,"do","") or AttrVal($pn,"repeatsame",""))));
- for (my $i=0; $i <$max_cond;$i++) {
- #@cmdSubState=SplitDoIf(',',$cmdState[$i]);
- $cmdList.="cmd_".($i+1).":noArg ";
- #$cmdList.=EvalCmdStateDoIf($hash,$cmdSubState[0]).":noArg " if defined ($cmdState[$i]);
- }
- return "unknown argument ? for $pn, choose one of disable:noArg initialize:noArg enable:noArg checkall:noArg $cmdList $setList";
+ my $checkall="";
+ if ($hash->{MODEL} ne "Perl") {
+ $checkall="checkall:noArg";
+ my $max_cond=keys %{$hash->{condition}};
+ $max_cond++ if (defined ($hash->{do}{$max_cond}{0}) or ($max_cond == 1 and !(AttrVal($pn,"do","") or AttrVal($pn,"repeatsame",""))));
+ for (my $i=0; $i <$max_cond;$i++) {
+ $cmdList.="cmd_".($i+1).":noArg ";
+ }
+ }
+ return "unknown argument ? for $pn, choose one of disable:noArg initialize:noArg enable:noArg $checkall $cmdList $setList";
} else {
my @rl = split(" ", AttrVal($pn, "readingList", ""));
my $doRet;
@@ -3051,9 +3276,13 @@ Arbitrary Perl functions can also be specified that are defined in FHEM.
The module is triggered by time or by events information through the Devices specified in the condition.
If a condition is true, the associated FHEM- or Perl commands are executed.
-Syntax:
+Syntax FHEM-Mode:
-define <name> DOIF (<condition>) (<commands>) DOELSEIF (<condition>) (<commands>) DOELSEIF ... DOELSE (<commands>)
+
define <name> DOIF (<condition>) (<commands>) DOELSEIF (<condition>) (<commands>) DOELSEIF ... DOELSE (<commands>)define <name> DOIF <Blockname> {<Perl with DOIF-Syntax>} <Blockname> {<Perl with DOIF-Syntax>} ...define <name> DOIF (<Bedingung>) (<Befehle>) DOELSEIF (<Bedingung>) (<Befehle>) DOELSEIF ... DOELSE (<Befehle>)stateinitializeattr di_garage do alwaysset shutters_<postfix> 10 gestellt.
In diesem Beispiel wird die Möglichkeit genutzt bei FHEM-Befehlen Perlcode innerhalb der Klammern {(...)} einzufügen. Siehe Berechnungen im Ausführungsteildefine di_window_open DOIF ["^window_:open|tilted"])
- (defmod at_$DEVICE at +00:05 set send window $DEVICE open)
-DOELSEIF (["^window_:closed"])
- (delete at_$DEVICE)
-
-attr di_window_open do alwaysdefine di_window_open DOIF ["^window_:open|tilted"])
- (sleep 300 $DEVICE quiet;set send window $DEVICE open)
-DOELSEIF (["^window_:closed"])
- (cancel $DEVICE quiet)
-
-attr di_window_open do alwayswait und waitdel lassen sich für verschiedene Kommandos kombinieren. Falls das Attribut für ein Kommando nicht gesetzt werden soll, kann die entsprechende Sekundenzahl ausgelassen oder eine Null angegeben werden.define <name> DOIF <Blockname> {<Perl mit DOIF-Syntax in eckigen Klammern>} <Blockname> {<Perl mit DOIF-Syntax in eckigen Klammern>} ...fhem"..." ausgeführt. Im Gegensatz zum FHEM-Modus können im Perl-Modus mehrere Blöcke unabhängig voneinander, ausgelöst durch einen Ereignis- oder Zeit-Trigger, ausgeführt werden. So kann die Funktionalität mehrer DOIF-Module im FHEM-Modus innerhalb eines DOIF-Moduls im Perl-Moduls realisiert werden.define di_rc_tv DOIF {if ([remotecontol:"on"]) {fhem"set tv on"} else {fhem"set tv off"}}define di_clock_radio DOIF {if ([06:30|Mo Di Mi] or [08:30|Do Fr Sa So]) {fhem"set radio on"} elsif ([08:00|Mo Di Mi] or [09:30|Do Fr Sa So]) {fhem"set radio off"}}define di_lamp DOIF {if ([06:00-09:00] and [sensor:brightness] < 40) {fhem"set lamp:FILTER=STATE!=on on"} else {fhem"set lamp:FILTER=STATE!=off off"}}set_Timer(<TimerEvent>, <seconds>), mit <TimerEvent>: beliebige Angabe, sie spezifiziert eindeutig einen Timer und ist gleichzeitig ein Ereignis,
+welches nach Ablauf des Timers in FHEM erzeugt wird. Auf dieses Ereignis kann wie üblich mit der DOIF-Syntax durch die Angabe [$SELF:"^<TimerEvent>$"] reagiert werden.
+Wird set_Timer mit dem gleichen <TimerEvent> vor seinem Ablauf erneut aufgerufen, so wird der laufender Timer gelöscht und neugesetzt.get_Timer(<TimerEvent>), Returnwert: 0, wenn Timer abgelaufen oder nicht gesetzt ist, sonst Anzahl der Sekunden bis zum Ablauf des Timersdel_Timer(<TimerEvent>)set_Event(<Event>)set_Reading(<readingName>,<content>,<trigger>), mit <trigger>: 0 ohne Trigger, 1 mit Triggerif (defined $_...) ...init {$_status=ReadingsVal("$SELF","state",0)}init {$_status=[?$SELF:state]}my $i=0;
+$_betrag{$i}=100;$_betrag{heute}=100;
+define di_shutter DOIF { #Perlblock zur Auswertung des Tastendruckes
+ if (["FS:^on$"] and get_Timer("Timer_shutter")==0){ #wenn Taste betätigt wird und kein Timer läuft
+ set_Timer("Timer_shutter",2) #Timer für zwei Sekunden setzen
+ } else { #wenn Timer läuft, d.h. ein weitere Tastendruck innerhalb von zwei Sekunden
+ del_Timer("Timer_shutter") #Timer löschen
+ fhem"set shutter up"; #Rollladen hoch
+ }
+}
+{ #Perlblock für die Bearbeitung des Timerevents
+ if ([$SELF:"Timer_shutter"]){ #Wenn nach zwei Sekunden Timer abläuft, d.h. nur ein Tastendruck
+ fhem"set shutter down" #Rollladen runter
+ }
+}
+
+
+define di_count DOIF { #Perlblock zur Auswertung des Ereignisses
+ if (["FS:on"] and get_Timer("Timer_counter")==0){ #wenn Ereignis (hier "FS:on") eintritt und kein Timer läuft
+ $_count=1; #setze count-Variable auf 1
+ set_Timer("Timer_counter",3600) #setze Timer auf eine Stunde
+ } else {
+ $_count++ #wenn Timer bereits läuft zähle Ereignis
+ }
+}
+{ #Perlblock für die Auswertung nach Ablauf des Timers
+ if ([$SELF:"Timer_counter"]) { #wenn Timer nach einer Stunde abläuft
+ if ($_count > 10) {Log 3,"count: $_count action"}} #protokolliere im Log die Anzahl der Ereignisse, wenn sie über 10 ist
+}
+
+define di_light DOIF bewegung { #Perlblock namens "bewegung" reagiert auf Bewegung von FS
+ if (["FS:motion"]) {
+ if ([?lamp:state] ne "on") { #wenn Lampe aus ist
+ fhem"set lamp on"; #Lampe einschalten
+ set_Reading ("state","on",1); #setze Status des DOIF-Moduls auf "on"
+ }
+ set_Timer("lamp_off",30); #Timer wird gesetzt bzw. verlängert
+ }
+}
+ausschalten { #Perlblock namens "ausschalten" reagiert auf Trigger vom des Timers "lamp_off"
+ if ([$SELF:"lamp_off"]) { #Wenn Timer lamp_off abläuft
+ fhem"set lamp off"; #schalte Lampe aus
+ set_Reading ("state","off",1); #setze Status des DOIF-Modus auf "off"
+ }
+}
+define di_window DOIF {
+ if (["_window$:open"]) { #wenn ein Fensterdevice endend mit "_window" geöffnet wird
+ set_Timer ("WINDOW_$DEVICE",600) #setze einen Timer auf 10 Minuten
+ }
+}
+{ #Timer löschen, wenn Fenster geschlossen wird
+ if (["_window$:closed"]) {
+ del_Timer ("WINDOW_$DEVICE")
+ }
+}
+{ #Auswertung eines Timers
+ if (["^$SELF:^WINDOW_"]) { #wenn ein Timerevent kommt
+ my ($window,$device)=split("_","$EVENT"); #bestimme das Device aus dem Timerevent "WINDOW_$DEVICE"
+ Log 3,"Fenster offen, bitte schließen: $device"; #Meldung wird protokolliert
+ set_Timer ("WINDOW_$device",1800) #setze einen neuen Timer für das Fenster für eine erneute Meldung in 30 Minuten
+ }
+}
+
=end html_DE
=cut