2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-01-31 12:49:34 +00:00

98_WeekdayTimer: renew delayed timer when window is closed

git-svn-id: https://svn.fhem.de/fhem/trunk@24513 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
Beta-User 2021-05-26 03:53:53 +00:00
parent f8b4cc54c7
commit ed3e21a268
2 changed files with 42 additions and 29 deletions

View File

@ -33,7 +33,6 @@ use warnings;
use Time::Local qw( timelocal_nocheck );
use Data::Dumper;
$Data::Dumper::Sortkeys = 1;
use Scalar::Util qw( weaken );
use FHEM::Core::Timer::Register qw(:ALL);
use GPUtils qw(GP_Import);
@ -854,10 +853,8 @@ sub _SetTimer {
#$modules{WeekdayTimer}{timerInThePastHash} = $tipHash;
#$tipHash = $hash->{helper}{timerInThePastHash} = $tipHash;
$hash->{helper}{timerInThePastHash} = $tipHash;
resetRegIntTimer('delayed', time + 5 + AttrVal($name,'WDT_sendDelay',0), \&WeekdayTimer_delayedTimerInPast, $tipHash, 0);
return;
}
@ -892,6 +889,18 @@ sub WeekdayTimer_delayedTimerInPast {
return;
}
sub _checkTimerReset {
my $hash = shift // return;
my $idx = shift // return;
return if $hash->{profil}{$idx}{EPOCH} <= time;
return if
!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});
resetRegIntTimer($idx, $hash->{profil}{$idx}{EPOCH}, \&WeekdayTimer_Update, $hash, 0);
return;
}
################################################################################
sub _searchAktNext {
my ($hash, $now) = @_;
@ -985,7 +994,8 @@ sub WeekdayTimer_Update {
$activeTimer = isAnActiveTimer ($hash, $dieGanzeWoche, $newParam, $overrulewday);
$activeTimerState = isAnActiveTimer ($hash, $tage, $newParam, $overrulewday);
Log3( $hash, 4, "[$name] Update - past timer activated" );
resetRegIntTimer("$idx", $timToSwitch, \&WeekdayTimer_Update, $hash, 0) if $timToSwitch > $now && ($activeTimerState || $activeTimer );
deleteSingleRegIntTimer($idx, $hash, 1);
setRegIntTimer($idx, $timToSwitch, \&WeekdayTimer_Update, $hash, 0) if $timToSwitch > $now && ($activeTimerState || $activeTimer );
} else {
$activeTimer = isAnActiveTimer ($hash, $tage, $newParam, $overrulewday);
$activeTimerState = $activeTimer;
@ -1065,34 +1075,34 @@ sub checkIfDeviceIsHeatingType {
################################################################################
sub checkDelayedExecution {
my ($hash, $event, $time) = @_;
my ($hash, $event, $idx) = @_;
my $name = $hash->{NAME};
my %specials = (
'%WEEKDAYTIMER' => $hash->{NAME},
'%NAME' => $hash->{DEVICE},
'%EVENT' => $event,
'%TIME' => $hash->{profil}{$time}{TIME},
'%TIME' => $hash->{profil}{$idx}{TIME},
'$WEEKDAYTIMER' => $hash->{NAME},
'$NAME' => $hash->{DEVICE},
'$EVENT' => $event,
'$TIME' => $hash->{profil}{$time}{TIME},
'$TIME' => $hash->{profil}{$idx}{TIME},
);
my $verzoegerteAusfuehrungCond = AttrVal($hash->{NAME}, 'delayedExecutionCond', 0);
my $nextRetry = time + 55 + int(rand(10));
my $epoch = $hash->{profil}{$time}{EPOCH};
my $epoch = $hash->{profil}{$idx}{EPOCH};
if (!$epoch) { #prevent FHEM crashing when profile is somehow damaged or incomlete, forum #109164
my $actual_wp_reading = ReadingsVal($name,'weekprofiles','none');
Log3( $hash, 0, "[$name] profile $actual_wp_reading, item $time seems to be somehow damaged or incomplete!" );
Log3( $hash, 0, "[$name] profile $actual_wp_reading, item $idx seems to be somehow damaged or incomplete!" );
$epoch = int(time) - 10*MINUTESECONDS;
readingsSingleUpdate( $hash, 'corrupt_wp_count', ReadingsNum($name,'corrupt_wp_count', 0) + 1, 1 );
}
my $delay = int(time) - $epoch;
my $nextDelay = int($delay/60.+1.5)*60; # round to multiple of 60sec
$nextRetry = $epoch + $nextDelay + AttrVal($name,'WDT_sendDelay',0);
Log3( $hash, 4, "[$name] time=".$hash->{profil}{$time}{TIME}."/$epoch delay=$delay, nextDelay=$nextDelay, nextRetry=$nextRetry" );
Log3( $hash, 4, "[$name] time=".$hash->{profil}{$idx}{TIME}."/$epoch delay=$delay, nextDelay=$nextDelay, nextRetry=$nextRetry" );
for my $key (keys %specials) {
my $val = $specials{$key};
@ -1110,19 +1120,15 @@ sub checkDelayedExecution {
if ( !defined $hash->{VERZOEGRUNG} ) {
Log3( $hash, 3, "[$name] switch of $hash->{DEVICE} delayed - delayedExecutionCond: '$verzoegerteAusfuehrungCond' is TRUE" );
}
if ( defined $hash->{VERZOEGRUNG_IDX} && $hash->{VERZOEGRUNG_IDX}!=$time) {
if ( defined $hash->{VERZOEGRUNG_IDX} && $hash->{VERZOEGRUNG_IDX}!=$idx) {
#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}{$time}{TIME}, delayedExecutionCond returned $verzoegerteAusfuehrung" );
Log3( $hash, 3, "[$name] timer at $hash->{profil}{$hash->{VERZOEGRUNG_IDX}}{TIME} skipped by new timer at $hash->{profil}{$idx}{TIME}, delayedExecutionCond returned $verzoegerteAusfuehrung" );
deleteSingleRegIntTimer($hash->{VERZOEGRUNG_IDX},$hash);
#xxxxx add logic for last timer of day
resetRegIntTimer($time, $hash->{profil}{$time}{EPOCH}, \&WeekdayTimer_Update, $hash, 0)
if $hash->{profil}{$time}{EPOCH} > time
&& (isAnActiveTimer ($hash, $hash->{profil}{$time}{TAGE}, $hash->{profil}{$time}{PARA}, $hash->{profil}{$time}{WE_Override})
|| isAnActiveTimer ($hash, $hash->{helper}{WEDAYS}{0} ? [7]:[8], $hash->{profil}{$time}{PARA}, $hash->{profil}{$time}{WE_Override}) );
_checkTimerReset($hash, $idx);
}
$hash->{VERZOEGRUNG_IDX} = $time;
resetRegIntTimer("$time", $nextRetry, \&WeekdayTimer_Update, $hash, 0);
$hash->{VERZOEGRUNG_IDX} = $idx;
resetRegIntTimer($idx, $nextRetry, \&WeekdayTimer_Update, $hash, 0);
$hash->{VERZOEGRUNG} = 1;
return $verzoegerteAusfuehrung;
}
@ -1173,17 +1179,14 @@ sub checkDelayedExecution {
if ( !defined $hash->{VERZOEGRUNG} ) {
Log3( $hash, 3, "[$name] switch of $hash->{DEVICE} delayed - sensor '$fk' Reading/Attribute '$reading' is '$windowStatus'" );
}
if ( defined $hash->{VERZOEGRUNG_IDX} && $hash->{VERZOEGRUNG_IDX} != $time ) {
Log3( $hash, 3, "[$name] timer at $hash->{profil}{$hash->{VERZOEGRUNG_IDX}}{TIME} skipped by new timer at $hash->{profil}{$time}{TIME} while window contact returned open state");
if ( defined $hash->{VERZOEGRUNG_IDX} && $hash->{VERZOEGRUNG_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");
deleteSingleRegIntTimer($hash->{VERZOEGRUNG_IDX},$hash);
#xxxxx add logic for last timer of day
resetRegIntTimer($time, $hash->{profil}{$time}{EPOCH}, \&WeekdayTimer_Update, $hash, 0)
if $hash->{profil}{$time}{EPOCH} > time
&& (isAnActiveTimer ($hash, $hash->{profil}{$time}{TAGE}, $hash->{profil}{$time}{PARA}, $hash->{profil}{$time}{WE_Override})
|| isAnActiveTimer ($hash, $hash->{helper}{WEDAYS}{0} ? [7]:[8], $hash->{profil}{$time}{PARA}, $hash->{profil}{$time}{WE_Override}) );
_checkTimerReset($hash, $idx);
}
$hash->{VERZOEGRUNG_IDX} = $time;
resetRegIntTimer("$time", $nextRetry, \&WeekdayTimer_Update, $hash, 0);
$hash->{VERZOEGRUNG_IDX} = $idx;
resetRegIntTimer($idx, $nextRetry, \&WeekdayTimer_Update, $hash, 0);
$hash->{VERZOEGRUNG} = 1;
return 1
}
@ -1193,6 +1196,7 @@ sub checkDelayedExecution {
}
delete $hash->{VERZOEGRUNG};
delete $hash->{VERZOEGRUNG_IDX} if defined $hash->{VERZOEGRUNG_IDX};
_checkTimerReset($hash, $idx);
return 0;
}

View File

@ -5,7 +5,7 @@ use warnings;
use Carp qw( carp );
use Scalar::Util qw( weaken );
use version; our $VERSION = qv('1.0.0');
use version; our $VERSION = qv('1.0.1');
use Exporter ('import');use GPUtils qw(GP_Import);
@ -70,7 +70,16 @@ sub resetRegIntTimer {
my $hash = shift // carp q[No hash reference specified] && return;
my $initFlag = shift // 0;
deleteSingleRegIntTimer( $modifier, $hash );
my $timerName = "$hash->{NAME}_$modifier";
my $fnHash = $hash->{TIMER}{$timerName};
if ( defined $fnHash ) {
::Log3( $hash, '5', "[$hash->{NAME}] resetting Timer: $timerName" );
::RemoveInternalTimer($fnHash);
::InternalTimer( $time, $callback, $fnHash, $initFlag );
return $fnHash;
}
return setRegIntTimer ( $modifier, $time, $callback, $hash, $initFlag );
}