diff --git a/fhem/FHEM/98_DOIF.pm b/fhem/FHEM/98_DOIF.pm
index f1707cac9..a7d471612 100644
--- a/fhem/FHEM/98_DOIF.pm
+++ b/fhem/FHEM/98_DOIF.pm
@@ -68,7 +68,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 waitsame waitdel cmdpause timerWithWait ".$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 ".$readingFnAttributes;
}
@@ -523,7 +523,7 @@ DOIF_time($$$$$$)
if ($hms ge $begin) {
$ret=1;
} elsif ($hms lt $end) {
- $wday=1 if ($wday-- == -1);
+ $wday=6 if ($wday-- == 0);
$we=DOIF_we($wday);
$ret=1;
}
@@ -678,6 +678,7 @@ DOIF_cmd ($$$$)
my @repeatsame=split(/:/,AttrVal($pn,"repeatsame",""));
my @cmdpause=split(/:/,AttrVal($pn,"cmdpause",""));
my @waitsame=split(/:/,AttrVal($pn,"waitsame",""));
+ my @sleeptimer=split(/:/,AttrVal($pn,"repeatcmd",""));
my ($seconds, $microseconds) = gettimeofday();
if ($cmdpause[$nr] and $subnr==0) {
return undef if ($seconds - time_str2num(ReadingsTimestamp($pn, "state", "1970-01-01 01:00:00")) < $cmdpause[$nr]);
@@ -690,6 +691,7 @@ DOIF_cmd ($$$$)
if ($repeatnr < $repeatsame[$nr]) {
$repeatnr++;
} else {
+ delete ($defs{$hash->{NAME}}{READINGS}{cmd_count}) if (defined ($sleeptimer[$nr]) and (AttrVal($pn,"do","") eq "always" or AttrVal($pn,"do","") eq "resetwait"));
return undef;
}
} else {
@@ -727,9 +729,16 @@ DOIF_cmd ($$$$)
delete $hash->{helper}{cur_cmd_nr};
if (defined $hash->{do}{$nr}{++$subnr}) {
my $last_cond=ReadingsVal($pn,"cmd_nr",0)-1;
- if (DOIF_SetSleepTimer($hash,$last_cond,$nr,$subnr,$event,-1)) {
+ if (DOIF_SetSleepTimer($hash,$last_cond,$nr,$subnr,$event,-1,undef)) {
DOIF_cmd ($hash,$nr,$subnr,$event);
}
+ } else {
+ if (defined ($sleeptimer[$nr])) {
+ my $last_cond=ReadingsVal($pn,"cmd_nr",0)-1;
+ if (DOIF_SetSleepTimer($hash,$last_cond,$nr,0,$event,-1,$sleeptimer[$nr])) {
+ DOIF_cmd ($hash,$nr,$subnr,$event);
+ }
+ }
}
return undef;
}
@@ -763,7 +772,7 @@ DOIF_Trigger ($$$)
return undef;
}
if ($ret) {
- if (DOIF_SetSleepTimer($hash,$last_cond,$i,0,$device,$timerNr)) {
+ if (DOIF_SetSleepTimer($hash,$last_cond,$i,0,$device,$timerNr,undef)) {
DOIF_cmd ($hash,$i,0,$event);
return 1;
} else {
@@ -776,7 +785,7 @@ DOIF_Trigger ($$$)
}
if ($doelse) { #DOELSE
if (defined ($hash->{do}{$max_cond}{0}) or ($max_cond == 1 and !(AttrVal($pn,"do","") or AttrVal($pn,"repeatsame","")))) { #DOELSE
- if (DOIF_SetSleepTimer($hash,$last_cond,$max_cond,0,$device,$timerNr)) {
+ if (DOIF_SetSleepTimer($hash,$last_cond,$max_cond,0,$device,$timerNr,undef)) {
DOIF_cmd ($hash,$max_cond,0,$event) ;
return 1;
}
@@ -1070,9 +1079,9 @@ DOIF_SetTimer($$)
}
sub
-DOIF_SetSleepTimer($$$$$$)
+DOIF_SetSleepTimer($$$$$$$)
{
- my ($hash,$last_cond,$nr,$subnr,$device,$timerNr)=@_;
+ my ($hash,$last_cond,$nr,$subnr,$device,$timerNr,$repeatcmd)=@_;
my $pn = $hash->{NAME};
if (defined $hash->{helper}{cur_cmd_nr}) {
return 0;
@@ -1098,16 +1107,23 @@ DOIF_SetSleepTimer($$$$$$)
return 0;
}
}
-
- if ($hash->{helper}{sleeptimer} == -1 and ($last_cond != $nr or $subnr > 0 or AttrVal($pn,"do","") eq "always" or AttrVal($pn,"do","") eq "resetwait" or AttrVal($pn,"repeatsame",""))) {
- my @sleeptimer=split(/:/,AttrVal($pn,"wait",""));
+ if ($hash->{helper}{sleeptimer} == -1 and ($last_cond != $nr or $subnr > 0
+ or AttrVal($pn,"do","") eq "always"
+ or AttrVal($pn,"do","") eq "resetwait"
+ or AttrVal($pn,"repeatsame","")
+ or defined($repeatcmd))) {
my $sleeptime=0;
- if ($waitdelsubnr[$subnr]) {
- $sleeptime = $waitdelsubnr[$subnr];
+ if (defined ($repeatcmd)) {
+ $sleeptime=$repeatcmd;
} else {
- my @sleepsubtimer=split(/,/,defined $sleeptimer[$nr]? $sleeptimer[$nr]: "");
- if ($sleepsubtimer[$subnr]) {
- $sleeptime=$sleepsubtimer[$subnr];
+ my @sleeptimer=split(/:/,AttrVal($pn,"wait",""));
+ if ($waitdelsubnr[$subnr]) {
+ $sleeptime = $waitdelsubnr[$subnr];
+ } else {
+ my @sleepsubtimer=split(/,/,defined $sleeptimer[$nr]? $sleeptimer[$nr]: "");
+ if ($sleepsubtimer[$subnr]) {
+ $sleeptime=$sleepsubtimer[$subnr];
+ }
}
}
($sleeptime,$err)=ReplaceAllReadingsDoIf($hash,$sleeptime,-1,1);
@@ -1139,8 +1155,10 @@ DOIF_SetSleepTimer($$$$$$)
}
InternalTimer($next_time, "DOIF_SleepTrigger",$hash, 0);
return 0;
+ } elsif (defined($repeatcmd)){
+ return 0;
} else {
- return 1;
+ return 1;
}
} else {
return 0;
@@ -1158,7 +1176,7 @@ DOIF_SleepTrigger ($)
my $pn = $hash->{NAME};
readingsSingleUpdate ($hash, "wait_timer", "no timer",1);
# if (!AttrVal($hash->{NAME},"disable","")) {
- if (ReadingsVal($pn,"mode","") ne "disable") {
+ if (ReadingsVal($pn,"mode","") ne "disabled") {
DOIF_cmd ($hash,$sleeptimer,$sleepsubtimer,$hash->{helper}{sleepdevice});
}
@@ -1840,7 +1858,7 @@ Verzögerungen können mit Hilfe des Attributs timerWithWait
auf Ti
Anwendungsbeispiel: Lampe soll zufällig nach Sonnenuntergang verzögert werden.
-define di_rand_sunset([{sunset()}])(set lamp on)
+define di_rand_sunset DOIF ([{sunset()}])(set lamp on)
attr di_rand_sunset wait rand(1200)
attr di_rand_sunset timerWithWait
attr di_rand_sunset do always
@@ -1890,6 +1908,41 @@ Das Attribut do resetwait
impliziert eine beliebige Wiederholung wi
attr di_push wait 1800
attr di_push do resetwait
+Wiederholung von Befehlsausführung
+
+Wiederholungen der Ausführung von Kommandos werden pro Befehlsfolge über das Attribut "repeatcmd" definiert. Syntax:
+
+attr <DOIF-modul> repeatcmd <Sekunden für Befehlsfolge des ersten DO-Falls>:<Sekunden für Befehlsfolge des zweiten DO-Falls>:...
+
+Statt Sekundenangaben können ebenfalls Stati in eckigen Klammen oder Perlbefehle angegeben werden.
+
+Die Wiederholung findet so lange statt, bis der Zustand des Moduls durch einen anderen DO-Fall wechselt.
+
+Anwendungsbeispiel: Nach dem Eintreffen des Ereignisses wird die push-Meldung stündlich wiederholt, bis Frost ungleich "on" ist.
+
+define di_push DOIF ([frost] eq "on")(set pushmsg "danger of frost")
+attr di_push repeatcmd 3600
+
+Eine Begrenzung der Wiederholungen kann mit dem Attribut repeatsame vorgenommen werden
+attr di_push repeatsame 3
+
+Ebenso lässt sich das repeatcmd-Attribut mit Zeitangaben kombinieren.
+
+Anwendungsbeispiel: Wiederholung ab einem Zeitpunkt
+
+define di_alarm_clock DOIF ([08:00])(set alarm_clock on)
+attr di_alarm_clock repeatcmd 300
+attr di_alarm_clock repeatsame 10
+attr di_alarm_clock do always
+
+Ab 8:00 Uhr wird 10 mal Weckton alle 5 Minuten wiederholt.
+
+Anwendungsbeispiel: Anwesenheitssimulation
+
+define di_presence_simulation DOIF ([19:00-00:00])(set lamp on-for-timer {(int(rand(1800)+300))}) DOELSE
+attr di_presence_simulation repeatcmd rand(3600)+2100
+attr di_presence_simulation do always
+
Zwangspause für das Ausführen eines Kommandos seit der letzten Zustandsänderung
Mit dem Attribut cmdpause <Sekunden für cmd_1>:<Sekunden für cmd_2>:...
wird die Zeitspanne in Sekunden angegeben für eine Zwangspause seit der letzten Zustandsänderung.