mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-03-10 03:06:37 +00:00
98_WeekdayTimer: prevent double actions, CONDITION now is changed at each switching time, (#124101)
git-svn-id: https://svn.fhem.de/fhem/trunk@25243 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
5d02f03a1f
commit
6b94464c4e
@ -1,5 +1,6 @@
|
|||||||
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
|
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
|
||||||
# Do not insert empty lines here, update check depends on it.
|
# Do not insert empty lines here, update check depends on it.
|
||||||
|
- change: 98_WeekdayTimer: CONDITION now is checked at each switching time
|
||||||
- bugfix: 10_KNX: fix for dpt3, dpt10 and dpt19 (working days)
|
- bugfix: 10_KNX: fix for dpt3, dpt10 and dpt19 (working days)
|
||||||
- bugfix: 88_HMCCU: Fixed some bugs
|
- bugfix: 88_HMCCU: Fixed some bugs
|
||||||
- bugfix: 73_AutoShuttersControl: Fix uninitialized value within %charHash
|
- bugfix: 73_AutoShuttersControl: Fix uninitialized value within %charHash
|
||||||
|
@ -32,8 +32,7 @@ use warnings;
|
|||||||
|
|
||||||
use Time::Local qw( timelocal_nocheck );
|
use Time::Local qw( timelocal_nocheck );
|
||||||
use Scalar::Util qw(looks_like_number);
|
use Scalar::Util qw(looks_like_number);
|
||||||
use Data::Dumper;
|
use Carp qw(carp);
|
||||||
$Data::Dumper::Sortkeys = 1;
|
|
||||||
use FHEM::Core::Timer::Register qw(:ALL);
|
use FHEM::Core::Timer::Register qw(:ALL);
|
||||||
use JSON qw(decode_json);
|
use JSON qw(decode_json);
|
||||||
use GPUtils qw(GP_Import);
|
use GPUtils qw(GP_Import);
|
||||||
@ -368,7 +367,7 @@ sub _Profile {
|
|||||||
$hash->{profil}{$idx}{TIME} = $time;
|
$hash->{profil}{$idx}{TIME} = $time;
|
||||||
$hash->{profil}{$idx}{PARA} = $parameter;
|
$hash->{profil}{$idx}{PARA} = $parameter;
|
||||||
$hash->{profil}{$idx}{EPOCH} = getSwitchtimeEpoch ($now, $stunde, $minute, $sekunde, 0);
|
$hash->{profil}{$idx}{EPOCH} = getSwitchtimeEpoch ($now, $stunde, $minute, $sekunde, 0);
|
||||||
$hash->{profil}{$idx}{TAGE} = $tage;
|
$hash->{profil}{$idx}{DAYS} = $tage;
|
||||||
$hash->{profil}{$idx}{WE_Override} = $overrulewday;
|
$hash->{profil}{$idx}{WE_Override} = $overrulewday;
|
||||||
}
|
}
|
||||||
# ---- Texte Readings aufbauen -----------------------------------------
|
# ---- Texte Readings aufbauen -----------------------------------------
|
||||||
@ -438,16 +437,12 @@ sub _SwitchingTime {
|
|||||||
}
|
}
|
||||||
|
|
||||||
my @tage = @{_daylistAsArray($hash, $daylist)};
|
my @tage = @{_daylistAsArray($hash, $daylist)};
|
||||||
#my $tage=@tage;
|
|
||||||
Log3( $hash, 1, "[$name] invalid daylist in $name <$daylist> use one of 012345678 or $hash->{helper}{daysRegExpMessage}" ) if !(@tage);
|
Log3( $hash, 1, "[$name] invalid daylist in $name <$daylist> use one of 012345678 or $hash->{helper}{daysRegExpMessage}" ) if !(@tage);
|
||||||
|
|
||||||
my %hdays=();
|
my %hdays=();
|
||||||
@hdays{@tageGlobal} = undef;
|
@hdays{@tageGlobal} = undef;
|
||||||
@hdays{@tage} = undef;
|
@hdays{@tage} = undef;
|
||||||
#@tage = sort keys %hdays;
|
|
||||||
|
|
||||||
#Log3 $hash, 3, "Tage: " . Dumper \@tage;
|
|
||||||
#return (\@tage,$time,$para,$overrulewday);
|
|
||||||
return ([sort keys %hdays], $time, $para, $overrulewday);
|
return ([sort keys %hdays], $time, $para, $overrulewday);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -794,17 +789,17 @@ sub _SetTimer {
|
|||||||
return Log3( $hash, 3, "[$name] no switches to send, due to possible errors." ) if !@switches;
|
return Log3( $hash, 3, "[$name] no switches to send, due to possible errors." ) if !@switches;
|
||||||
|
|
||||||
readingsSingleUpdate ($hash, 'state', 'inactive', 1) if !defined $hash->{SETTIMERATMIDNIGHT};
|
readingsSingleUpdate ($hash, 'state', 'inactive', 1) if !defined $hash->{SETTIMERATMIDNIGHT};
|
||||||
for(my $i=0; $i<=$#switches; $i++) {
|
for my $i (0..$#switches) {
|
||||||
|
|
||||||
my $idx = $switches[$i];
|
my $idx = $switches[$i];
|
||||||
|
|
||||||
my $time = $hash->{profil}{$idx}{TIME};
|
my $time = $hash->{profil}{$idx}{TIME};
|
||||||
my $timToSwitch = $hash->{profil}{$idx}{EPOCH};
|
my $timToSwitch = $hash->{profil}{$idx}{EPOCH};
|
||||||
my $tage = $hash->{profil}{$idx}{TAGE};
|
my $tage = $hash->{profil}{$idx}{DAYS};
|
||||||
my $para = $hash->{profil}{$idx}{PARA};
|
my $para = $hash->{profil}{$idx}{PARA};
|
||||||
my $overrulewday = $hash->{profil}{$idx}{WE_Override};
|
my $overrulewday = $hash->{profil}{$idx}{WE_Override};
|
||||||
|
|
||||||
my $isActiveTimer = isAnActiveTimer ($hash, $tage, $para, $overrulewday);
|
my $isActiveTimer = checkDaysCondition($hash, $tage, $overrulewday); #isAnActiveTimer ($hash, $tage, $para, $overrulewday);
|
||||||
readingsSingleUpdate ($hash, 'state', 'active', 1)
|
readingsSingleUpdate ($hash, 'state', 'active', 1)
|
||||||
if !defined $hash->{SETTIMERATMIDNIGHT} && $isActiveTimer;
|
if !defined $hash->{SETTIMERATMIDNIGHT} && $isActiveTimer;
|
||||||
|
|
||||||
@ -813,7 +808,7 @@ sub _SetTimer {
|
|||||||
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), \&WDT_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" );
|
||||||
deleteSingleRegIntTimer("$idx", $hash);
|
deleteSingleRegIntTimer("$idx", $hash);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -892,10 +887,8 @@ sub _checkTimerReset {
|
|||||||
my $hash = shift // return;
|
my $hash = shift // return;
|
||||||
my $idx = shift // return;
|
my $idx = shift // return;
|
||||||
|
|
||||||
return if $hash->{profil}{$idx}{EPOCH} <= time;
|
return if $hash->{profil}{$idx}{EPOCH} <= int(time) + 1; #for int/+1 see https://forum.fhem.de/index.php/topic,124101.0.html
|
||||||
return if
|
return if !checkWDTCondition($hash, $hash->{profil}{$idx}{PARA});
|
||||||
!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}, \&WDT_Update, $hash, 0);
|
resetRegIntTimer($idx, $hash->{profil}{$idx}{EPOCH}, \&WDT_Update, $hash, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -937,7 +930,7 @@ sub _searchAktNext {
|
|||||||
#Log3 $hash, 3, $shortDays{$language}[$nextTag]." ".FmtDateTime($nextTime)." ".$nextPara." ".$nextIdx;
|
#Log3 $hash, 3, $shortDays{$language}[$nextTag]." ".FmtDateTime($nextTime)." ".$nextPara." ".$nextIdx;
|
||||||
my $ignore = 0;
|
my $ignore = 0;
|
||||||
my $wend = 0;
|
my $wend = 0;
|
||||||
my $tage = $hash->{profil}{$nextIdx}{TAGE}[0];
|
my $tage = $hash->{profil}{$nextIdx}{DAYS}[0];
|
||||||
if ($wday==$relWday) {
|
if ($wday==$relWday) {
|
||||||
$wend = $hash->{helper}{WEDAYS}{0};
|
$wend = $hash->{helper}{WEDAYS}{0};
|
||||||
$ignore = (($tage == 7 && !$wend ) || ($tage == 8 && $wend ));
|
$ignore = (($tage == 7 && !$wend ) || ($tage == 8 && $wend ));
|
||||||
@ -971,7 +964,7 @@ sub WDT_Update {
|
|||||||
my $now = time;
|
my $now = time;
|
||||||
|
|
||||||
# Schaltparameter ermitteln
|
# Schaltparameter ermitteln
|
||||||
my $tage = $hash->{profil}{$idx}{TAGE};
|
my $tage = $hash->{profil}{$idx}{DAYS};
|
||||||
my $time = $hash->{profil}{$idx}{TIME};
|
my $time = $hash->{profil}{$idx}{TIME};
|
||||||
my $newParam = $hash->{profil}{$idx}{PARA};
|
my $newParam = $hash->{profil}{$idx}{PARA};
|
||||||
my $timToSwitch = $hash->{profil}{$idx}{EPOCH};
|
my $timToSwitch = $hash->{profil}{$idx}{EPOCH};
|
||||||
@ -990,13 +983,13 @@ sub WDT_Update {
|
|||||||
|
|
||||||
my ($activeTimer, $activeTimerState);
|
my ($activeTimer, $activeTimerState);
|
||||||
if (defined $fnHash->{forceSwitch}) { #timer is delayed
|
if (defined $fnHash->{forceSwitch}) { #timer is delayed
|
||||||
$activeTimer = isAnActiveTimer ($hash, $dieGanzeWoche, $newParam, $overrulewday);
|
$activeTimer = checkDaysCondition($hash, $dieGanzeWoche, $overrulewday); #isAnActiveTimer ($hash, $dieGanzeWoche, $newParam, $overrulewday);
|
||||||
$activeTimerState = isAnActiveTimer ($hash, $tage, $newParam, $overrulewday);
|
$activeTimerState = checkWDTCondition($hash, $newParam); #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, \&WDT_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 = checkWDTCondition($hash, $newParam); #isAnActiveTimer ($hash, $tage, $newParam, $overrulewday);
|
||||||
$activeTimerState = $activeTimer;
|
$activeTimerState = $activeTimer;
|
||||||
Log3( $hash, 4, "[$name] Update - timer seems to be active today: ".join(q{},@{$tage})."|$time|$newParam" ) if ( $activeTimer && (@{$tage}) );
|
Log3( $hash, 4, "[$name] Update - timer seems to be active today: ".join(q{},@{$tage})."|$time|$newParam" ) if ( $activeTimer && (@{$tage}) );
|
||||||
Log3( $hash, 2, "[$name] Daylist is missing!") if !(@{$tage});
|
Log3( $hash, 2, "[$name] Daylist is missing!") if !(@{$tage});
|
||||||
@ -1011,8 +1004,7 @@ sub WDT_Update {
|
|||||||
my $disabled = AttrVal($hash->{NAME}, 'disable', 0);
|
my $disabled = AttrVal($hash->{NAME}, 'disable', 0);
|
||||||
|
|
||||||
# ggf. Device schalten
|
# ggf. Device schalten
|
||||||
Switch_Device($hash, $newParam, $tage) if $activeTimer;
|
Switch_Device($hash, $newParam) if $activeTimer;
|
||||||
|
|
||||||
readingsBeginUpdate($hash);
|
readingsBeginUpdate($hash);
|
||||||
readingsBulkUpdate ($hash, 'nextUpdate', FmtDateTime($nextTime));
|
readingsBulkUpdate ($hash, 'nextUpdate', FmtDateTime($nextTime));
|
||||||
readingsBulkUpdate ($hash, 'nextValue', $nextParameter);
|
readingsBulkUpdate ($hash, 'nextValue', $nextParameter);
|
||||||
@ -1078,17 +1070,17 @@ sub checkDelayedExecution {
|
|||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
|
|
||||||
my %specials = (
|
my %specials = (
|
||||||
'%WEEKDAYTIMER' => $hash->{NAME},
|
'%WEEKDAYTIMER' => $name,
|
||||||
'%NAME' => $hash->{DEVICE},
|
'%NAME' => $hash->{DEVICE},
|
||||||
'%EVENT' => $event,
|
'%EVENT' => $event,
|
||||||
'%TIME' => $hash->{profil}{$idx}{TIME},
|
'%TIME' => $hash->{profil}{$idx}{TIME},
|
||||||
'$WEEKDAYTIMER' => $hash->{NAME},
|
'$WEEKDAYTIMER' => $name,
|
||||||
'$NAME' => $hash->{DEVICE},
|
'$NAME' => $hash->{DEVICE},
|
||||||
'$EVENT' => $event,
|
'$EVENT' => $event,
|
||||||
'$TIME' => $hash->{profil}{$idx}{TIME},
|
'$TIME' => $hash->{profil}{$idx}{TIME},
|
||||||
);
|
);
|
||||||
|
|
||||||
my $verzoegerteAusfuehrungCond = AttrVal($hash->{NAME}, 'delayedExecutionCond', 0);
|
my $verzoegerteAusfuehrungCond = AttrVal($name, 'delayedExecutionCond', 0);
|
||||||
|
|
||||||
my $nextRetry = time + 55 + int(rand(10));
|
my $nextRetry = time + 55 + int(rand(10));
|
||||||
my $epoch = $hash->{profil}{$idx}{EPOCH};
|
my $epoch = $hash->{profil}{$idx}{EPOCH};
|
||||||
@ -1103,17 +1095,20 @@ sub checkDelayedExecution {
|
|||||||
$nextRetry = $epoch + $nextDelay + AttrVal($name,'WDT_sendDelay',0);
|
$nextRetry = $epoch + $nextDelay + AttrVal($name,'WDT_sendDelay',0);
|
||||||
Log3( $hash, 4, "[$name] time=".$hash->{profil}{$idx}{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 $verzoegerteAusfuehrung = 0;
|
||||||
my $val = $specials{$key};
|
if ($verzoegerteAusfuehrungCond) {
|
||||||
$key =~ s{\$}{\\\$}gxms;
|
for my $key (keys %specials) {
|
||||||
$verzoegerteAusfuehrungCond =~ s{$key}{$val}gxms
|
my $val = $specials{$key};
|
||||||
|
$key =~ s{\$}{\\\$}gxms;
|
||||||
|
$verzoegerteAusfuehrungCond =~ s{$key}{$val}gxms
|
||||||
|
}
|
||||||
|
Log3( $hash, 4, "[$name] delayedExecutionCond: $verzoegerteAusfuehrungCond" );
|
||||||
|
|
||||||
|
$verzoegerteAusfuehrung = AnalyzePerlCommand( $hash, $verzoegerteAusfuehrungCond );
|
||||||
|
|
||||||
|
my $logtext = $verzoegerteAusfuehrung // 'no condition attribute set';
|
||||||
|
Log3( $hash, 4, "[$name] result of delayedExecutionCond: $logtext" );
|
||||||
}
|
}
|
||||||
Log3( $hash, 4, "[$name] delayedExecutionCond:$verzoegerteAusfuehrungCond" );
|
|
||||||
|
|
||||||
my $verzoegerteAusfuehrung = AnalyzePerlCommand( $hash, $verzoegerteAusfuehrungCond );
|
|
||||||
|
|
||||||
my $logtext = $verzoegerteAusfuehrung // 'no condition attribute set';
|
|
||||||
Log3( $hash, 4, "[$name] result of delayedExecutionCond: $logtext" );
|
|
||||||
|
|
||||||
if ($verzoegerteAusfuehrung) {
|
if ($verzoegerteAusfuehrung) {
|
||||||
if ( !defined $hash->{DELAYED} ) {
|
if ( !defined $hash->{DELAYED} ) {
|
||||||
@ -1201,82 +1196,99 @@ sub checkDelayedExecution {
|
|||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
sub Switch_Device {
|
sub Switch_Device {
|
||||||
my ($hash, $newParam, $tage) = @_;
|
my $hash = shift // return;
|
||||||
|
my $newParam = shift // carp q[No new parameter provided!] && return;
|
||||||
|
|
||||||
my ($command, $condition, $tageAsHash) = q{};
|
|
||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
|
return if AttrVal($name, 'disable', 0);
|
||||||
|
|
||||||
my $now = time;
|
my $command = AttrVal($name, 'commandTemplate', undef);
|
||||||
#modifier des Zieldevices auswaehlen
|
|
||||||
my $setModifier = checkIfDeviceIsHeatingType($hash);
|
my $setModifier = checkIfDeviceIsHeatingType($hash);
|
||||||
$setModifier .= ' ' if length $setModifier;
|
|
||||||
|
|
||||||
$attr{$name}{commandTemplate} =
|
if (!defined $command) {
|
||||||
'set $NAME ' . $setModifier . '$EVENT' if !defined $attr{$name}{commandTemplate};
|
#modifier des Zieldevices auswaehlen
|
||||||
|
$setModifier .= ' ' if length $setModifier;
|
||||||
|
|
||||||
|
$attr{$name}{commandTemplate} =
|
||||||
|
'set $NAME ' . $setModifier . '$EVENT';
|
||||||
|
$command = AttrVal($name, 'commandTemplate', 'commandTemplate not found');
|
||||||
|
}
|
||||||
|
|
||||||
$command = AttrVal($name, 'commandTemplate', 'commandTemplate not found');
|
|
||||||
$command = 'set $NAME $EVENT' if defined $hash->{WDT_EVENTMAP} && defined $hash->{WDT_EVENTMAP}{$newParam};
|
$command = 'set $NAME $EVENT' if defined $hash->{WDT_EVENTMAP} && defined $hash->{WDT_EVENTMAP}{$newParam};
|
||||||
$command = $hash->{COMMAND} if defined $hash->{COMMAND} && $hash->{COMMAND} ne '';
|
$command = $hash->{COMMAND} if defined $hash->{COMMAND} && $hash->{COMMAND} ne '';
|
||||||
|
|
||||||
|
|
||||||
my $activeTimer = 1;
|
|
||||||
|
|
||||||
my $isHeating = $setModifier ? 1 : 0;
|
my $isHeating = $setModifier ? 1 : 0;
|
||||||
my $aktParam = ReadingsVal($hash->{DEVICE}, $setModifier, '');
|
my $aktParam = ReadingsVal($hash->{DEVICE}, $setModifier, '');
|
||||||
$aktParam = sprintf("%.1f", $aktParam) if $isHeating && $aktParam =~ m{\A[0-9]{1,3}\z}ixms;
|
$aktParam = sprintf("%.1f", $aktParam) if $isHeating && $aktParam =~ m{\A[0-9]{1,3}\z}ixms;
|
||||||
|
|
||||||
my $disabled = AttrVal($hash->{NAME}, 'disable', 0);
|
Log3( $hash, 4, "[$name] aktParam:$aktParam newParam:$newParam - is not disabled" );
|
||||||
my $disabled_txt = $disabled ? '' : ' not';
|
|
||||||
Log3( $hash, 4, "[$name] aktParam:$aktParam newParam:$newParam - is$disabled_txt disabled" );
|
|
||||||
|
|
||||||
#Kommando ausführen
|
#Kommando ausführen
|
||||||
if ($command && !$disabled && $activeTimer
|
return if !$command || $aktParam eq $newParam;
|
||||||
&& $aktParam ne $newParam
|
if ( defined $hash->{WDT_EVENTMAP} && defined $hash->{WDT_EVENTMAP}{$newParam} ) {
|
||||||
) {
|
$newParam = $hash->{WDT_EVENTMAP}{$newParam};
|
||||||
if ( defined $hash->{WDT_EVENTMAP} && defined $hash->{WDT_EVENTMAP}{$newParam} ) {
|
} else {
|
||||||
$newParam = $hash->{WDT_EVENTMAP}{$newParam};
|
$newParam =~ s{\\:}{|}gxms;
|
||||||
} else {
|
$newParam =~ s{:}{ }gxms;
|
||||||
$newParam =~ s{\\:}{|}gxms;
|
$newParam =~ s{\|}{:}gxms;
|
||||||
$newParam =~ s{:}{ }gxms;
|
|
||||||
$newParam =~ s{\|}{:}gxms;
|
|
||||||
}
|
|
||||||
|
|
||||||
my %specials = ( "%NAME" => $hash->{DEVICE}, "%EVENT" => $newParam );
|
|
||||||
$command = EvalSpecials($command, %specials);
|
|
||||||
|
|
||||||
Log3( $hash, 4, "[$name] command: '$command' executed with ".join(",", map { "$_=>$specials{$_}" } keys %specials) );
|
|
||||||
my $ret = AnalyzeCommandChain(undef, $command);
|
|
||||||
Log3( $hash, 3, $ret ) if $ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
my %specials = ( "%NAME" => $hash->{DEVICE}, "%EVENT" => $newParam );
|
||||||
|
$command = EvalSpecials($command, %specials);
|
||||||
|
my $ret = AnalyzeCommandChain(undef, $command);
|
||||||
|
Log3( $hash, 4, "[$name] command: '$command' executed with ".join(",", map { "$_=>$specials{$_}" } keys %specials) );
|
||||||
|
return Log3( $hash, 2, $ret ) if $ret;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
sub checkWDTCondition {
|
||||||
|
my $hash = shift // return 0;
|
||||||
|
my $para = shift // carp q[No new parameter provided!] && return;
|
||||||
|
return 1 if !defined $hash->{CONDITION} || !$hash->{CONDITION};
|
||||||
|
|
||||||
|
my $name = $hash->{NAME};
|
||||||
|
my $condition = $hash->{CONDITION};
|
||||||
|
|
||||||
|
Log3( $hash, 4, "[$name] checking condition: $condition");
|
||||||
|
|
||||||
|
my %specials = ( "%NAME" => $hash->{DEVICE}, "%EVENT" => $para );
|
||||||
|
my $xPression = qq( { $condition } );
|
||||||
|
$xPression = EvalSpecials($xPression, %specials);
|
||||||
|
Log3( $hash, 5, "[$name] evaluated condition: $xPression" );
|
||||||
|
|
||||||
|
my $ret = AnalyzeCommandChain(undef, $xPression);
|
||||||
|
Log3( $hash, 5, "[$name] condition evaluation returned: $ret" );
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
sub checkDaysCondition {
|
||||||
|
my $hash = shift // return 0;
|
||||||
|
my $tage = shift // return 0;
|
||||||
|
my $overrulewday = shift;
|
||||||
|
|
||||||
|
my $name = $hash->{NAME};
|
||||||
|
Log3( $hash, 4, "[$name] check days:" . join q{,}, @{$tage} );
|
||||||
|
my $condition = getDaysAsCondition($tage, $overrulewday);
|
||||||
|
my $tageAsHash = getDaysAsHash($hash, $tage);
|
||||||
|
my $xPression = qq( $tageAsHash ; $condition );
|
||||||
|
Log3( $hash, 5, "[$name] check days: $xPression" );
|
||||||
|
|
||||||
|
my $ret = AnalyzePerlCommand(undef, $xPression);
|
||||||
|
Log3( $hash, 5, "[$name] result of check days: $ret" );
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
sub getDaysAsHash {
|
sub getDaysAsHash {
|
||||||
my $hash = shift;
|
my $hash = shift;
|
||||||
my $tage = shift //return {};
|
my $tage = shift //return {};
|
||||||
|
|
||||||
my %days = map {$_ => 1} @{$tage};
|
my %days = map {$_ => 1} @{$tage};
|
||||||
delete @days{7,8};
|
delete @days{7,8};
|
||||||
|
|
||||||
return 'my $days={};map{$days->{$_}=1}('. join (q{,}, sort keys %days ) .')';
|
return 'my $days = {} ; map{ $days->{$_} = 1 }('. join (q{,}, sort keys %days ) .')';
|
||||||
}
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
sub checkWDTCondition {
|
|
||||||
my $hash = shift;
|
|
||||||
my $tage = shift // return 0;
|
|
||||||
my $overrulewday = shift;
|
|
||||||
|
|
||||||
my $name = $hash->{NAME};
|
|
||||||
Log3( $hash, 4, "[$name] condition:$hash->{CONDITION} - Tage:" . join q{,}, @{$tage} );
|
|
||||||
|
|
||||||
my $condition = q{( };
|
|
||||||
$condition .= (defined $hash->{CONDITION} && $hash->{CONDITION} ne '') ? $hash->{CONDITION} : 1 ;
|
|
||||||
$condition .= ' && ' . getDaysAsCondition($tage, $overrulewday);
|
|
||||||
$condition .= ')';
|
|
||||||
|
|
||||||
return $condition;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
@ -1289,12 +1301,10 @@ sub getDaysAsCondition {
|
|||||||
my $we = $days{7}; delete $days{7}; # $we
|
my $we = $days{7}; delete $days{7}; # $we
|
||||||
my $notWe = $days{8}; delete $days{8}; #!$we
|
my $notWe = $days{8}; delete $days{8}; #!$we
|
||||||
|
|
||||||
my $tageExp = '(defined $days->{$wday}';
|
my $tageExp = 'defined $days->{$wday}';
|
||||||
$tageExp .= ' && !$we' if $overrulewday;
|
$tageExp .= ' && !$we' if $overrulewday;
|
||||||
$tageExp .= ' || $we' if defined $we;
|
$tageExp .= ' || $we' if defined $we;
|
||||||
$tageExp .= ' || !$we' if defined $notWe;
|
$tageExp .= ' || !$we' if defined $notWe;
|
||||||
$tageExp .= ')';
|
|
||||||
|
|
||||||
return $tageExp;
|
return $tageExp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1510,23 +1520,22 @@ __END__
|
|||||||
<code>set <device> weekprofile <weekprofile-device:topic:profile></code><br>
|
<code>set <device> weekprofile <weekprofile-device:topic:profile></code><br>
|
||||||
</ul>
|
</ul>
|
||||||
<ul><b>command</b><br>
|
<ul><b>command</b><br>
|
||||||
If no <i>condition</i> is set, all the rest is interpreted as a <i>command</i>. Perl-code is setting upby the well-known Block with {}.<br>
|
If no <i>condition</i> is set, all the rest is interpreted as a <i>command</i>. Perl-code is setting up by the well-known Block with {}.<br>
|
||||||
Note: if a <i>command</i> is defined only this command is executed. In case of executing
|
Note: if a <i>command</i> is defined only this command is executed. In case of executing
|
||||||
a "set desired-temp" command, you must define the hole commandpart explicitly by yourself.<br>
|
a "set desired-temp" command, you must define the hole command part explicitly by yourself.<br>
|
||||||
If no explicit <i>command</i> is provided, <i>commandTemplate</i> attribute will indicate the command; this may be a simple <code>set $NAME $EVENT</code> or some variation wrt. to the device beeing recognized as heating type (see <i>WDT_eventMap</i> for even more options!).
|
If no explicit <i>command</i> is provided, <i>commandTemplate</i> attribute will indicate the command; this may be a simple <code>set $NAME $EVENT</code> or some variation wrt. to the device beeing recognized as heating type (see <i>WDT_eventMap</i> for even more options!).
|
||||||
<!----------------------------------------------------------------------------- -->
|
The following parameters are replaced:<br>
|
||||||
<!-- -------------------------------------------------------------------------- -->
|
|
||||||
The following parameter are replaced:<br>
|
|
||||||
<ol>
|
<ol>
|
||||||
<li>$NAME => the device to switch</li>
|
<li>$NAME => the device to switch</li>
|
||||||
<li>$EVENT => the new temperature</li>
|
<li>$EVENT => the new parameter (e.g. a temperature)</li>
|
||||||
</ol>
|
</ol>
|
||||||
</ul>
|
</ul>
|
||||||
<p>
|
<p>
|
||||||
<ul><b>condition</b><br>
|
<ul><b>condition</b><br>
|
||||||
if a condition is defined you must declare this with () and a valid perl-code.<br>
|
if a condition is defined you must declare this with () and a valid perl-code.<br>
|
||||||
The return value must be boolean.<br>
|
The return value must be boolean.<br>
|
||||||
The parameters $NAME and $EVENT will be interpreted.
|
The parameters $NAME and $EVENT will also be interpreted.
|
||||||
|
If condition is provided and evaluation (at switchingtime) returns "0", the parameter will not be set, next check will be done as soon as next switchingtime is reached.
|
||||||
</ul>
|
</ul>
|
||||||
<p>
|
<p>
|
||||||
<b>Examples:</b>
|
<b>Examples:</b>
|
||||||
@ -1699,7 +1708,6 @@ __END__
|
|||||||
"prereqs" : {
|
"prereqs" : {
|
||||||
"runtime" : {
|
"runtime" : {
|
||||||
"requires" : {
|
"requires" : {
|
||||||
"Data::Dumper" : "0",
|
|
||||||
"Time::Local" : "0",
|
"Time::Local" : "0",
|
||||||
"strict" : "0",
|
"strict" : "0",
|
||||||
"warnings" : "0"
|
"warnings" : "0"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user