98_WeekdayTimer: fix timer removals in some cases

git-svn-id: https://svn.fhem.de/fhem/trunk/fhem@24521 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
Beta-User 2021-05-27 17:54:53 +00:00
parent 91aa651a9e
commit 462cfdde07

View File

@ -100,7 +100,7 @@ sub Initialize {
$hash->{DeleteFn} = \&Delete; $hash->{DeleteFn} = \&Delete;
$hash->{GetFn} = \&Get; $hash->{GetFn} = \&Get;
$hash->{AttrFn} = \&Attr; $hash->{AttrFn} = \&Attr;
$hash->{UpdFn} = \&WeekdayTimer_Update; $hash->{UpdFn} = \&WDT_Update;
$hash->{AttrList} = "disable:0,1 delayedExecutionCond WDT_delayedExecutionDevices WDT_Group switchInThePast:0,1 commandTemplate WDT_eventMap:textField-long WDT_sendDelay:slider,0,1,300,1 $readingFnAttributes"; $hash->{AttrList} = "disable:0,1 delayedExecutionCond WDT_delayedExecutionDevices WDT_Group switchInThePast:0,1 commandTemplate WDT_eventMap:textField-long WDT_sendDelay:slider,0,1,300,1 $readingFnAttributes";
return; return;
} }
@ -159,7 +159,7 @@ sub Undef {
my $arg = shift // return; my $arg = shift // return;
deleteAllRegIntTimer($hash); deleteAllRegIntTimer($hash);
deleteSingleRegIntTimer($hash->{VERZOEGRUNG_IDX},$hash) if defined $hash->{VERZOEGRUNG_IDX}; deleteSingleRegIntTimer($hash->{DELAYED_IDX},$hash) if defined $hash->{DELAYED_IDX};
#delete $modules{$hash->{TYPE}}{defptr}{$hash->{NAME}}; #delete $modules{$hash->{TYPE}}{defptr}{$hash->{NAME}};
return deleteSingleRegIntTimer('SetTimerOfDay', $hash); return deleteSingleRegIntTimer('SetTimerOfDay', $hash);
@ -170,7 +170,7 @@ sub WDT_Start {
my $hash = shift // return; my $hash = shift // return;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my $def = $hash->{DEF}; my $def = $hash->{DEF};
deleteSingleRegIntTimer($hash->{VERZOEGRUNG_IDX},$hash) if defined ($hash->{VERZOEGRUNG_IDX}); deleteSingleRegIntTimer($hash->{DELAYED_IDX},$hash) if defined ($hash->{DELAYED_IDX});
my @arr = split m{\s+}xms, $def; my @arr = split m{\s+}xms, $def;
my $device = shift @arr; my $device = shift @arr;
@ -211,13 +211,13 @@ sub WDT_Start {
} }
_Profile ($hash); _Profile ($hash);
delete $hash->{VERZOEGRUNG}; delete $hash->{DELAYED};
delete $hash->{VERZOEGRUNG_IDX}; delete $hash->{DELAYED_IDX};
$attr{$name}{commandTemplate} = $attr{$name}{commandTemplate} =
'set $NAME '. checkIfDeviceIsHeatingType($hash) .' $EVENT' if !defined $attr{$name}{commandTemplate}; 'set $NAME '. checkIfDeviceIsHeatingType($hash) .' $EVENT' if !defined $attr{$name}{commandTemplate};
WeekdayTimer_SetTimerOfDay({ HASH => $hash}); WDT_SetTimerOfDay({ HASH => $hash});
return if !$init_done; return if !$init_done;
return join('\n', @errors) if (@errors); return join('\n', @errors) if (@errors);
@ -229,7 +229,7 @@ sub Delete {
deleteAllRegIntTimer($hash); deleteAllRegIntTimer($hash);
RemoveInternalTimer($hash); RemoveInternalTimer($hash);
deleteSingleRegIntTimer($hash->{VERZOEGRUNG_IDX},$hash) if defined $hash->{VERZOEGRUNG_IDX}; #deleteSingleRegIntTimer($hash->{DELAYED_IDX},$hash) if defined $hash->{DELAYED_IDX};
return; return;
} }
@ -245,10 +245,10 @@ sub Set {
if ($v eq 'enable') { if ($v eq 'enable') {
Log3( $hash, 3, "[$name] set $name $v" ); Log3( $hash, 3, "[$name] set $name $v" );
if (AttrVal($name, "disable", 0)) { if (AttrVal($name, 'disable', 0)) {
CommandAttr(undef, "$name disable 0"); CommandAttr(undef, "$name disable 0");
} else { } else {
WeekdayTimer_SetTimerOfDay({ HASH => $hash}); WDT_SetTimerOfDay({ HASH => $hash});
} }
return; return;
} }
@ -718,15 +718,15 @@ sub _SetTimerForMidnightUpdate {
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($now); my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($now);
my $midnightPlus5Seconds = getSwitchtimeEpoch ($now, 0, 0, 5, 1); my $midnightPlus5Seconds = getSwitchtimeEpoch ($now, 0, 0, 5, 1);
deleteSingleRegIntTimer('midnight', $hash,\&WeekdayTimer_SetTimerOfDay); deleteSingleRegIntTimer('midnight', $hash);
$fnHash = setRegIntTimer('midnight', $midnightPlus5Seconds, \&WeekdayTimer_SetTimerOfDay, $hash, 0) if !AttrVal($hash->{NAME},'disable',0); $fnHash = setRegIntTimer('midnight', $midnightPlus5Seconds, \&WDT_SetTimerOfDay, $hash, 0) if !AttrVal($hash->{NAME},'disable',0);
$fnHash->{SETTIMERATMIDNIGHT} = 1; $fnHash->{SETTIMERATMIDNIGHT} = 1;
return; return;
} }
################################################################################ ################################################################################
sub WeekdayTimer_SetTimerOfDay { sub WDT_SetTimerOfDay {
my $fnHash = shift // return; my $fnHash = shift // return;
my $hash = $fnHash->{HASH} // $fnHash; my $hash = $fnHash->{HASH} // $fnHash;
return if !defined $hash; return if !defined $hash;
@ -812,7 +812,7 @@ sub _SetTimer {
if ( $timToSwitch - $now > -5 || defined $hash->{SETTIMERATMIDNIGHT} ) { if ( $timToSwitch - $now > -5 || defined $hash->{SETTIMERATMIDNIGHT} ) {
if($isActiveTimer) { if($isActiveTimer) {
Log3( $hash, 4, "[$name] setTimer - timer seems to be active today: ".join( q{},@{$tage})."|$time|$para" ); Log3( $hash, 4, "[$name] setTimer - timer seems to be active today: ".join( q{},@{$tage})."|$time|$para" );
resetRegIntTimer("$idx", $timToSwitch + AttrVal($name,'WDT_sendDelay',0), \&WeekdayTimer_Update, $hash, 0); resetRegIntTimer($idx, $timToSwitch + AttrVal($name,'WDT_sendDelay',0), \&WDT_Update, $hash, 0);
} else { } else {
Log3( $hash, 4, "[$name] setTimer - timer seems to be NOT active today: ".join(q{},@{$tage})."|$time|$para ". $hash->{CONDITION} ); Log3( $hash, 4, "[$name] setTimer - timer seems to be NOT active today: ".join(q{},@{$tage})."|$time|$para ". $hash->{CONDITION} );
deleteSingleRegIntTimer("$idx", $hash); deleteSingleRegIntTimer("$idx", $hash);
@ -835,7 +835,7 @@ sub _SetTimer {
return if !$switchInThePast || !defined $aktTime || checkDelayedExecution($hash, $aktParameter, $aktIdx ); return if !$switchInThePast || !defined $aktTime || checkDelayedExecution($hash, $aktParameter, $aktIdx );
# alle in der Vergangenheit liegenden Schaltungen sammeln und # alle in der Vergangenheit liegenden Schaltungen sammeln und
# nach 5 Sekunden in der Reihenfolge der Schaltzeiten # nach 5 Sekunden in der Reihenfolge der Schaltzeiten
# durch WeekdayTimer_delayedTimerInPast() als Timer einstellen # durch WDT_delayedTimerInPast() als Timer einstellen
# die Parameter merken wir uns kurzzeitig im hash # die Parameter merken wir uns kurzzeitig im hash
# modules{WeekdayTimer}{timerInThePast} # modules{WeekdayTimer}{timerInThePast}
my $device = $hash->{DEVICE}; my $device = $hash->{DEVICE};
@ -843,7 +843,7 @@ sub _SetTimer {
#my $parameter = $modules{WeekdayTimer}{timerInThePast}{$device}{$aktTime} // []; #my $parameter = $modules{WeekdayTimer}{timerInThePast}{$device}{$aktTime} // [];
my $parameter = $hash->{helper}{timerInThePast}{$aktTime} // []; my $parameter = $hash->{helper}{timerInThePast}{$aktTime} // [];
push @{$parameter},["$aktIdx", $aktTime, \&WeekdayTimer_Update, $hash, 0]; push @{$parameter},[$aktIdx, $aktTime, \&WDT_Update, $hash, 0];
$hash->{helper}{timerInThePast}{$device}{$aktTime} = $parameter; $hash->{helper}{timerInThePast}{$device}{$aktTime} = $parameter;
#$modules{WeekdayTimer}{timerInThePast}{$device}{$aktTime} = $parameter; #$modules{WeekdayTimer}{timerInThePast}{$device}{$aktTime} = $parameter;
@ -854,13 +854,13 @@ sub _SetTimer {
#$tipHash = $hash->{helper}{timerInThePastHash} = $tipHash; #$tipHash = $hash->{helper}{timerInThePastHash} = $tipHash;
$hash->{helper}{timerInThePastHash} = $tipHash; $hash->{helper}{timerInThePastHash} = $tipHash;
resetRegIntTimer('delayed', time + 5 + AttrVal($name,'WDT_sendDelay',0), \&WeekdayTimer_delayedTimerInPast, $tipHash, 0); resetRegIntTimer('delayed', time + 5 + AttrVal($name,'WDT_sendDelay',0), \&WDT_delayedTimerInPast, $tipHash, 0);
return; return;
} }
################################################################################ ################################################################################
sub WeekdayTimer_delayedTimerInPast { sub WDT_delayedTimerInPast {
my $fnHash = shift // return; my $fnHash = shift // return;
my ($hash, $modifier) = ($fnHash->{HASH}, $fnHash->{MODIFIER}); my ($hash, $modifier) = ($fnHash->{HASH}, $fnHash->{MODIFIER});
@ -897,7 +897,7 @@ sub _checkTimerReset {
return if return if
!isAnActiveTimer ($hash, $hash->{profil}{$idx}{TAGE}, $hash->{profil}{$idx}{PARA}, $hash->{profil}{$idx}{WE_Override}) !isAnActiveTimer ($hash, $hash->{profil}{$idx}{TAGE}, $hash->{profil}{$idx}{PARA}, $hash->{profil}{$idx}{WE_Override})
&& !isAnActiveTimer ($hash, $hash->{helper}{WEDAYS}{0} ? [7]:[8], $hash->{profil}{$idx}{PARA}, $hash->{profil}{$idx}{WE_Override}); && !isAnActiveTimer ($hash, $hash->{helper}{WEDAYS}{0} ? [7]:[8], $hash->{profil}{$idx}{PARA}, $hash->{profil}{$idx}{WE_Override});
resetRegIntTimer($idx, $hash->{profil}{$idx}{EPOCH}, \&WeekdayTimer_Update, $hash, 0); resetRegIntTimer($idx, $hash->{profil}{$idx}{EPOCH}, \&WDT_Update, $hash, 0);
return; return;
} }
@ -962,7 +962,7 @@ sub _DeleteTimer {
} }
################################################################################ ################################################################################
sub WeekdayTimer_Update { sub WDT_Update {
my $fnHash = shift // return; my $fnHash = shift // return;
my $hash = $fnHash->{HASH} // $fnHash; my $hash = $fnHash->{HASH} // $fnHash;
return if (!defined($hash)); return if (!defined($hash));
@ -994,8 +994,8 @@ sub WeekdayTimer_Update {
$activeTimer = isAnActiveTimer ($hash, $dieGanzeWoche, $newParam, $overrulewday); $activeTimer = isAnActiveTimer ($hash, $dieGanzeWoche, $newParam, $overrulewday);
$activeTimerState = isAnActiveTimer ($hash, $tage, $newParam, $overrulewday); $activeTimerState = isAnActiveTimer ($hash, $tage, $newParam, $overrulewday);
Log3( $hash, 4, "[$name] Update - past timer activated" ); Log3( $hash, 4, "[$name] Update - past timer activated" );
deleteSingleRegIntTimer($idx, $hash, 1); deleteSingleRegIntTimer($idx, $hash);#, 1);
setRegIntTimer($idx, $timToSwitch, \&WeekdayTimer_Update, $hash, 0) if $timToSwitch > $now && ($activeTimerState || $activeTimer ); setRegIntTimer($idx, $timToSwitch, \&WDT_Update, $hash, 0) if $timToSwitch > $now && ($activeTimerState || $activeTimer );
} else { } else {
$activeTimer = isAnActiveTimer ($hash, $tage, $newParam, $overrulewday); $activeTimer = isAnActiveTimer ($hash, $tage, $newParam, $overrulewday);
$activeTimerState = $activeTimer; $activeTimerState = $activeTimer;
@ -1117,19 +1117,19 @@ sub checkDelayedExecution {
Log3( $hash, 4, "[$name] result of delayedExecutionCond: $logtext" ); Log3( $hash, 4, "[$name] result of delayedExecutionCond: $logtext" );
if ($verzoegerteAusfuehrung) { if ($verzoegerteAusfuehrung) {
if ( !defined $hash->{VERZOEGRUNG} ) { if ( !defined $hash->{DELAYED} ) {
Log3( $hash, 3, "[$name] switch of $hash->{DEVICE} delayed - delayedExecutionCond: '$verzoegerteAusfuehrungCond' is TRUE" ); Log3( $hash, 3, "[$name] switch of $hash->{DEVICE} delayed - delayedExecutionCond: '$verzoegerteAusfuehrungCond' is TRUE" );
} }
if ( defined $hash->{VERZOEGRUNG_IDX} && $hash->{VERZOEGRUNG_IDX}!=$idx) { if ( defined $hash->{DELAYED_IDX} && $hash->{DELAYED_IDX}!=$idx) {
#Prüfen, ob der nächste Timer überhaupt für den aktuellen Tag relevant ist! #Prüfen, ob der nächste Timer überhaupt für den aktuellen Tag relevant ist!
Log3( $hash, 3, "[$name] timer at $hash->{profil}{$hash->{VERZOEGRUNG_IDX}}{TIME} skipped by new timer at $hash->{profil}{$idx}{TIME}, delayedExecutionCond returned $verzoegerteAusfuehrung" ); Log3( $hash, 3, "[$name] timer at $hash->{profil}{$hash->{DELAYED_IDX}}{TIME} skipped by new timer at $hash->{profil}{$idx}{TIME}, delayedExecutionCond returned $verzoegerteAusfuehrung" );
deleteSingleRegIntTimer($hash->{VERZOEGRUNG_IDX},$hash); deleteSingleRegIntTimer($hash->{DELAYED_IDX},$hash);
_checkTimerReset($hash, $idx); _checkTimerReset($hash, $idx);
} }
$hash->{VERZOEGRUNG_IDX} = $idx; $hash->{DELAYED_IDX} = $idx;
resetRegIntTimer($idx, $nextRetry, \&WeekdayTimer_Update, $hash, 0); resetRegIntTimer($idx, $nextRetry, \&WDT_Update, $hash, 0);
$hash->{VERZOEGRUNG} = 1; $hash->{DELAYED} = 1;
return $verzoegerteAusfuehrung; return $verzoegerteAusfuehrung;
} }
@ -1176,26 +1176,26 @@ sub checkDelayedExecution {
Log3( $hash, 5, "[$name] sensor '$fk' Reading/Attribute '$reading' is '$windowStatus'" ); Log3( $hash, 5, "[$name] sensor '$fk' Reading/Attribute '$reading' is '$windowStatus'" );
if ( $windowStatus =~ m{\A$statusReg\z}xms ) { if ( $windowStatus =~ m{\A$statusReg\z}xms ) {
if ( !defined $hash->{VERZOEGRUNG} ) { if ( !defined $hash->{DELAYED} ) {
Log3( $hash, 3, "[$name] switch of $hash->{DEVICE} delayed - sensor '$fk' Reading/Attribute '$reading' is '$windowStatus'" ); Log3( $hash, 3, "[$name] switch of $hash->{DEVICE} delayed - sensor '$fk' Reading/Attribute '$reading' is '$windowStatus'" );
} }
if ( defined $hash->{VERZOEGRUNG_IDX} && $hash->{VERZOEGRUNG_IDX} != $idx ) { if ( defined $hash->{DELAYED_IDX} && $hash->{DELAYED_IDX} != $idx ) {
Log3( $hash, 3, "[$name] timer at $hash->{profil}{$hash->{VERZOEGRUNG_IDX}}{TIME} skipped by new timer at $hash->{profil}{$idx}{TIME} while window contact returned open state"); Log3( $hash, 3, "[$name] timer at $hash->{profil}{$hash->{DELAYED_IDX}}{TIME} skipped by new timer at $hash->{profil}{$idx}{TIME} while window contact returned open state");
deleteSingleRegIntTimer($hash->{VERZOEGRUNG_IDX},$hash); deleteSingleRegIntTimer($hash->{DELAYED_IDX},$hash);
#xxxxx add logic for last timer of day #xxxxx add logic for last timer of day
_checkTimerReset($hash, $idx); _checkTimerReset($hash, $idx);
} }
$hash->{VERZOEGRUNG_IDX} = $idx; $hash->{DELAYED_IDX} = $idx;
resetRegIntTimer($idx, $nextRetry, \&WeekdayTimer_Update, $hash, 0); resetRegIntTimer($idx, $nextRetry, \&WDT_Update, $hash, 0);
$hash->{VERZOEGRUNG} = 1; $hash->{DELAYED} = 1;
return 1 return 1
} }
} }
if ( $hash->{VERZOEGRUNG} ) { if ( $hash->{DELAYED} ) {
Log3( $hash, 3, "[$name] delay of switching $hash->{DEVICE} stopped." ); Log3( $hash, 3, "[$name] delay of switching $hash->{DEVICE} stopped." );
delete $hash->{DELAYED};
} }
delete $hash->{VERZOEGRUNG}; delete $hash->{DELAYED_IDX} if defined $hash->{DELAYED_IDX};
delete $hash->{VERZOEGRUNG_IDX} if defined $hash->{VERZOEGRUNG_IDX};
_checkTimerReset($hash, $idx); _checkTimerReset($hash, $idx);
return 0; return 0;
} }
@ -1327,9 +1327,9 @@ sub Attr {
###RemoveInternalTimer($fnHash); ###RemoveInternalTimer($fnHash);
readingsSingleUpdate ($hash, 'disabled', $attrVal, 1); readingsSingleUpdate ($hash, 'disabled', $attrVal, 1);
$attr{$name}{$attrName} = $attrVal; $attr{$name}{$attrName} = $attrVal;
return RemoveInternalTimer($hash,\&WeekdayTimer_SetTimerOfDay) if $attrVal; return RemoveInternalTimer($hash,\&WDT_SetTimerOfDay) if $attrVal;
return WDT_Start($hash); return WDT_Start($hash);
#return WeekdayTimer_SetTimerOfDay( { HASH => $hash} ) if !$attrVal; #return WDT_SetTimerOfDay( { HASH => $hash} ) if !$attrVal;
} }
if ( $attrName eq 'weekprofile' ) { if ( $attrName eq 'weekprofile' ) {
$attr{$name}{$attrName} = $attrVal; $attr{$name}{$attrName} = $attrVal;