From bd0800f2856eae3d3c8f035b1258b0634cbdd15c Mon Sep 17 00:00:00 2001 From: Damian <> Date: Wed, 22 Mar 2017 15:48:02 +0000 Subject: [PATCH] 98_DOIF.pm: new attribute weekdays, Modul will be defined now in spite of an incorrect timer specification; Error message will be stored in timer reading git-svn-id: https://svn.fhem.de/fhem/trunk@13770 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/FHEM/98_DOIF.pm | 151 +++++++++++++++++++++++++++---------------- 1 file changed, 97 insertions(+), 54 deletions(-) diff --git a/fhem/FHEM/98_DOIF.pm b/fhem/FHEM/98_DOIF.pm index 207f4649f..987a66ffc 100644 --- a/fhem/FHEM/98_DOIF.pm +++ b/fhem/FHEM/98_DOIF.pm @@ -74,7 +74,7 @@ DOIF_Initialize($) $hash->{UndefFn} = "DOIF_Undef"; $hash->{AttrFn} = "DOIF_Attr"; $hash->{NotifyFn} = "DOIF_Notify"; - $hash->{AttrList} = "disable:0,1 loglevel:0,1,2,3,4,5,6 wait do:always,resetwait cmdState state initialize repeatsame repeatcmd waitsame waitdel cmdpause timerWithWait:1,0 notexist selftrigger:wait,all timerevent:1,0 checkReadingEvent:1,0 addStateEvent:1,0 checkall:event,timer,all setList:textField-long readingList ".$readingFnAttributes; + $hash->{AttrList} = "disable:0,1 loglevel:0,1,2,3,4,5,6 wait do:always,resetwait cmdState state initialize repeatsame repeatcmd waitsame waitdel cmdpause timerWithWait:1,0 notexist selftrigger:wait,all timerevent:1,0 checkReadingEvent:1,0 addStateEvent:1,0 checkall:event,timer,all weekdays setList:textField-long readingList ".$readingFnAttributes; } @@ -762,6 +762,18 @@ ParseCommandsDoIf($$$) return("",$last_error); } +sub DOIF_weekdays($$) +{ + my ($hash,$weekdays)=@_; + my @days=SplitDoIf(',',AttrVal($hash->{NAME},"weekdays","So,Mo,Di,Mi,Do,Fr,Sa,WE,AT")); + for (my $i=0;$i<@days;$i++) + { + $weekdays =~ s/$days[$i]/$i/; + } + return($weekdays); +} + + sub DOIF_CheckTimers($$$$) { @@ -842,8 +854,9 @@ DOIF_CheckTimers($$$$) $hash->{timeCond}{$nr}=$condition; $hash->{days}{$nr}=$days if ($days ne ""); if ($init_done) { - $err=(DOIF_SetTimer($hash,"DOIF_TimerTrigger",$nr)); - return($hash->{time}{$nr},$err) if ($err); + DOIF_SetTimer($hash,"DOIF_TimerTrigger",$nr); + #$err=(DOIF_SetTimer($hash,"DOIF_TimerTrigger",$nr)); + #return($hash->{time}{$nr},$err) if ($err); } $hash->{timers}{$condition}.=" $nr " if ($trigger); } @@ -871,6 +884,8 @@ DOIF_time my $ret=0; my ($hash,$b,$e,$wday,$hms,$days)=@_; $days="" if (!defined ($days)); + return 0 if (!defined $hash->{realtime}{$b}); + return 0 if (!defined $hash->{realtime}{$e}); my $begin=$hash->{realtime}{$b}; my $end=$hash->{realtime}{$e}; my $err; @@ -882,6 +897,7 @@ DOIF_time readingsSingleUpdate ($hash, "error", $errmsg,0); return 0; } + $days=DOIF_weekdays($hash,$days); my $we=DOIF_we($wday); if ($end gt $begin) { if ($hms ge $begin and $hms lt $end) { @@ -916,6 +932,7 @@ DOIF_time_once readingsSingleUpdate ($hash, "error", $errmsg,0); return 0; } + $days=DOIF_weekdays($hash,$days); my $we=DOIF_we($wday); if ($flag) { return 1 if ($days eq "" or $days =~ /$wday/ or ($days =~ /7/ and $we) or ($days =~ /8/ and !$we)); @@ -1414,20 +1431,21 @@ DOIF_Notify($$) } } + + return "" if (!$hash->{helper}{globalinit}); + return "" if (defined $hash->{helper}{cur_cmd_nr}); + return "" if (!$hash->{itimer}{all} and !$hash->{devices}{all} and !$hash->{state}{device} and !$hash->{regexp}{all}); + if (($hash->{itimer}{all}) and $hash->{itimer}{all} =~ / $dev->{NAME} /) { - for (my $j=0; $j<$hash->{helper}{last_timer};$j++) { + for (my $j=0; $j<$hash->{helper}{last_timer};$j++) { if (CheckiTimerDoIf ($dev->{NAME},$hash->{time}{$j},$eventas)) { - # { if (AttrVal($pn, "checkReadingEvent", 0) and CheckiTimerDoIf ($dev->{NAME},$hash->{time}{$j},$eventas) - # or !AttrVal($pn, "checkReadingEvent", 0) and $hash->{time}{$j} =~ /\[$dev->{NAME}(\]|:.+\]|,.+\])/) { DOIF_SetTimer($hash,"DOIF_TimerTrigger",$j); } } } + return "" if (ReadingsVal($pn,"mode","") eq "disabled"); - return "" if (!$hash->{helper}{globalinit}); - return "" if (defined $hash->{helper}{cur_cmd_nr}); - return "" if (!$hash->{devices}{all} and !$hash->{state}{device} and !$hash->{regexp}{all}); - + if ((($hash->{devices}{all}) and $hash->{devices}{all} =~ / $dev->{NAME} /) or CheckRegexpDoIf($hash,$dev->{NAME},$eventa,-1)){ $hash->{helper}{cur_cmd_nr}="Trigger $dev->{NAME}" if (AttrVal($hash->{NAME},"selftrigger","") ne "all"); readingsSingleUpdate ($hash, "Device",$dev->{NAME},0); @@ -1480,16 +1498,17 @@ DOIF_TimerTrigger ($) my $pn = $hash->{NAME}; my $localtime=${$timer}->{localtime}; delete $hash->{triggertime}{$localtime}; + my $ret; my ($now, $microseconds) = gettimeofday(); my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($now); $hash->{helper}{cur_cmd_nr}="timer $localtime" if (AttrVal($hash->{NAME},"selftrigger","") ne "all"); #$hash->{helper}{cur_cmd_nr}="timer $localtime"; for (my $j=0; $j<$hash->{helper}{last_timer};$j++) { - if ($hash->{localtime}{$j} == $localtime) { + if (defined $hash->{localtime}{$j} and $hash->{localtime}{$j} == $localtime) { if (defined ($hash->{interval}{$j})) { if ($hash->{interval}{$j} != -1) { - if ($hash->{realtime}{$j} eq $hash->{realtime}{$hash->{interval}{$j}}) { + if (defined $hash->{realtime}{$j} eq $hash->{realtime}{$hash->{interval}{$j}}) { $hash->{timer}{$hash->{interval}{$j}}=0; next; } @@ -1504,7 +1523,7 @@ DOIF_TimerTrigger ($) $ret=DOIF_Trigger ($hash,"") if (ReadingsVal($pn,"mode","") ne "disabled"); for (my $j=0; $j<$hash->{helper}{last_timer};$j++) { $hash->{timer}{$j}=0; - if ($hash->{localtime}{$j} == $localtime) { + if (defined $hash->{localtime}{$j} and $hash->{localtime}{$j} == $localtime) { if (!AttrVal($hash->{NAME},"disable","")) { if (defined ($hash->{interval}{$j})) { if ($hash->{interval}{$j} != -1) { @@ -1665,7 +1684,22 @@ DOIF_SetTimer($$$) my $timeStr=$hash->{time}{$nr}; my $cond=$hash->{timeCond}{$nr}; my $next_time; - + if (defined ($hash->{localtime}{$nr})) { + my $old_lt=$hash->{localtime}{$nr}; + my $found=0; + delete ($hash->{localtime}{$nr}); + delete ($hash->{realtime}{$nr}); + foreach my $lt (keys %{$hash->{localtime}}) { + if ($hash->{localtime}{$lt} == $old_lt) { + $found=1; + last; + } + } + if (!$found) { + RemoveInternalTimer(\$hash->{triggertime}{$old_lt}); + delete ($hash->{triggertime}{$old_lt}); + } + } my ($second,$err, $rel)=DOIF_CalcTime($hash,$timeStr); my $timernr=sprintf("timer_%02d_c%02d",($nr+1),($cond+1)); if ($err) @@ -1673,7 +1707,7 @@ DOIF_SetTimer($$$) readingsSingleUpdate ($hash,$timernr,"error: ".$err,AttrVal($hash->{NAME},"timerevent","")?1:0); Log3 $hash->{NAME},4 , "$hash->{NAME} ".$timernr." error: ".$err; #RemoveInternalTimer($timer); - $hash->{realtime}{$nr}="00:00:00"; + #$hash->{realtime}{$nr} = "00:00:00" if (!defined $hash->{realtime}{$nr}); return $err; } @@ -1705,35 +1739,16 @@ DOIF_SetTimer($$$) } } } - #if ($next_time < $now and $isdst_now == $isdst) { - # readingsSingleUpdate ($hash,"timer_".($nr+1)."_c".($cond+1),"back to the past is not allowed",AttrVal($hash->{NAME},"timerevent","")?1:0); - # return("timer_".($nr+1)."_c".($cond+1),"back to the past is not allowed"); - #} else { my $next_time_str=strftime("%d.%m.%Y %H:%M:%S",localtime($next_time)); $next_time_str.="\|".$hash->{days}{$nr} if (defined ($hash->{days}{$nr})); readingsSingleUpdate ($hash,$timernr,$next_time_str,AttrVal($hash->{NAME},"timerevent","")?1:0); $hash->{realtime}{$nr}=strftime("%H:%M:%S",localtime($next_time)); - if (defined ($hash->{localtime}{$nr})) { - my $old_lt=$hash->{localtime}{$nr}; - my $found=0; - delete ($hash->{localtime}{$nr}); - foreach my $lt (keys %{$hash->{localtime}}) { - if ($hash->{localtime}{$lt} == $old_lt) { - $found=1; - last; - } - } - if (!$found) { - RemoveInternalTimer(\$hash->{triggertime}{$old_lt}); - delete ($hash->{triggertime}{$old_lt}); - } - } $hash->{localtime}{$nr}=$next_time; if (!defined ($hash->{triggertime}{$next_time})) { $hash->{triggertime}{$next_time}{hash}=$hash; $hash->{triggertime}{$next_time}{localtime}=$next_time; - InternalTimer($next_time, $func, \$hash->{triggertime}{$next_time}, 0); + InternalTimer($next_time, $func, \$hash->{triggertime}{$next_time}, 0); } return undef; } @@ -2026,6 +2041,8 @@ DOIF_Set($@) } elsif ($arg eq "initialize" ) { delete ($defs{$hash->{NAME}}{READINGS}{mode}); delete ($defs{$hash->{NAME}}{READINGS}{cmd_nr}); + delete ($defs{$hash->{NAME}}{READINGS}{cmd}); + delete ($defs{$hash->{NAME}}{READINGS}{cmd_seqnr}); delete ($defs{$hash->{NAME}}{READINGS}{cmd_event}); readingsSingleUpdate($hash, "state","initialize",1); } elsif ($arg eq "enable" ) { @@ -2180,12 +2197,21 @@ Dieses Verhalten ist sinnvoll, um zu verhindern, dass zyklisch sendende Sensoren
Einfache Anwendungsbeispiele:

    -Fernbedienung (Ereignissteuerung): define di_rc_tv DOIF ([remotecontol:"on"]) (set tv on) DOELSE (set tv off)
    +Fernbedienung (Ereignissteuerung)

    -Zeitschaltuhr (Zeitsteuerung): define di_clock_radio DOIF ([06:30|8] or [08:30|7]) (set radio on) DOELSEIF ([08:00|8] or [09:30|7]) (set radio off)
    +define di_rc_tv DOIF ([remotecontol:"on"]) (set tv on) DOELSE (set tv off)

    -Kombinierte Ereignis- und Zeitsteuerung: define di_lamp DOIF ([06:00-09:00] and [sensor:brightness] < 40) (set lamp on) DOELSE (set lamp off)
    +Zeitschaltuhr (Zeitsteuerung)
    +
    +define di_clock_radio DOIF ([06:30|Mo Di Mi] or [08:30|Do Fr Sa So]) (set radio on) DOELSEIF ([08:00|Mo Di Mi] or [09:30|Do Fr Sa So]) (set radio off)
    +
    +Kombinierte Ereignis- und Zeitsteuerung
    +
    +define di_lamp DOIF ([06:00-09:00] and [sensor:brightness] < 40) (set lamp on) DOELSE (set lamp off)

+Eine ausführliche Erläuterung der obigen Anwendungsbeispiele kann hier nachgelesen werden: +Erste Schritte mit DOIF

+
Inhaltsübersicht