From 2f475ca063aaec1fcca9037290e0a1945159ba1d Mon Sep 17 00:00:00 2001 From: markusbloch <> Date: Tue, 23 Jan 2018 13:28:21 +0000 Subject: [PATCH] PRESENCE: new set command overrideInterval and clearOverride to change check interval (Forum: #70538) git-svn-id: https://svn.fhem.de/fhem/trunk@15969 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/CHANGED | 3 + fhem/FHEM/73_PRESENCE.pm | 133 ++++++++++++++++++++++++++------------- 2 files changed, 93 insertions(+), 43 deletions(-) diff --git a/fhem/CHANGED b/fhem/CHANGED index 2726257cb..d9b68ac76 100644 --- a/fhem/CHANGED +++ b/fhem/CHANGED @@ -1,5 +1,8 @@ # 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. + - feature: 73_PRESENCE: new set commands overrideInterval and clearOverride + to temporary override the check interval. + new attributes retryCount and retryInterval - feature: 89_FULLY: Added support for attribute disable - change: 93_DbLog: V3.7.0, log verbose 5 enhanced, configuration read check added to configCheck diff --git a/fhem/FHEM/73_PRESENCE.pm b/fhem/FHEM/73_PRESENCE.pm index 06f76a1f4..7d56f192e 100755 --- a/fhem/FHEM/73_PRESENCE.pm +++ b/fhem/FHEM/73_PRESENCE.pm @@ -85,8 +85,8 @@ PRESENCE_Define($$) $hash->{MODE} = "local-bluetooth"; $hash->{ADDRESS} = $a[3]; - $hash->{TIMEOUT_NORMAL} = (defined($a[4]) ? $a[4] : 30); - $hash->{TIMEOUT_PRESENT} = (defined($a[5]) ? $a[5] : $hash->{TIMEOUT_NORMAL}); + $hash->{INTERVAL_NORMAL} = (defined($a[4]) ? $a[4] : 30); + $hash->{INTERVAL_PRESENT} = (defined($a[5]) ? $a[5] : $hash->{INTERVAL_NORMAL}); } elsif($a[2] eq "fritzbox") { @@ -106,8 +106,8 @@ PRESENCE_Define($$) $hash->{MODE} = "fritzbox"; $hash->{ADDRESS} = $a[3]; - $hash->{TIMEOUT_NORMAL} = (defined($a[4]) ? $a[4] : 30); - $hash->{TIMEOUT_PRESENT} = (defined($a[5]) ? $a[5] : $hash->{TIMEOUT_NORMAL}); + $hash->{INTERVAL_NORMAL} = (defined($a[4]) ? $a[4] : 30); + $hash->{INTERVAL_PRESENT} = (defined($a[5]) ? $a[5] : $hash->{INTERVAL_NORMAL}); } elsif($a[2] eq "lan-ping") { @@ -120,8 +120,8 @@ PRESENCE_Define($$) $hash->{MODE} = "lan-ping"; $hash->{ADDRESS} = $a[3]; - $hash->{TIMEOUT_NORMAL} = (defined($a[4]) ? $a[4] : 30); - $hash->{TIMEOUT_PRESENT} = (defined($a[5]) ? $a[5] : $hash->{TIMEOUT_NORMAL}); + $hash->{INTERVAL_NORMAL} = (defined($a[4]) ? $a[4] : 30); + $hash->{INTERVAL_PRESENT} = (defined($a[5]) ? $a[5] : $hash->{INTERVAL_NORMAL}); } elsif($a[2] =~ /(shellscript|function)/) { @@ -129,8 +129,8 @@ PRESENCE_Define($$) { $hash->{MODE} = $2; $hash->{helper}{call} = $3; - $hash->{TIMEOUT_NORMAL} = ($4 ne "" ? $4 : 30); - $hash->{TIMEOUT_PRESENT} = ($5 ne "" ? $5 : $hash->{TIMEOUT_NORMAL}); + $hash->{INTERVAL_NORMAL} = ($4 ne "" ? $4 : 30); + $hash->{INTERVAL_PRESENT} = ($5 ne "" ? $5 : $hash->{INTERVAL_NORMAL}); delete($hash->{helper}{ADDRESS}); @@ -162,8 +162,8 @@ PRESENCE_Define($$) $hash->{MODE} = "lan-bluetooth"; $hash->{ADDRESS} = $a[3]; - $hash->{TIMEOUT_NORMAL} = (defined($a[5]) ? $a[5] : 30); - $hash->{TIMEOUT_PRESENT} = (defined($a[6]) ? $a[6] : $hash->{TIMEOUT_NORMAL}); + $hash->{INTERVAL_NORMAL} = (defined($a[5]) ? $a[5] : 30); + $hash->{INTERVAL_PRESENT} = (defined($a[6]) ? $a[6] : $hash->{INTERVAL_NORMAL}); $dev = $a[4]; $dev .= ":5222" if($dev !~ m/:/ && $dev ne "none" && $dev !~ m/\@/); @@ -201,8 +201,8 @@ PRESENCE_Define($$) return $msg; } - my $timeout = $hash->{TIMEOUT_NORMAL}; - my $presence_timeout = $hash->{TIMEOUT_PRESENT}; + my $timeout = $hash->{INTERVAL_NORMAL}; + my $presence_timeout = $hash->{INTERVAL_PRESENT}; if(defined($timeout) and not $timeout =~ /^\d+$/) { @@ -334,6 +334,9 @@ PRESENCE_Set($@) my $powerCmd = AttrVal($name, "powerCmd", undef); $usage .= " power" if(defined($powerCmd)); + $usage .= " overrideInterval" if($hash->{MODE} !~ /^event|lan-bluetooth$/); + $usage .= " clearOverride:noArg" if($hash->{INTERVAL_OVERRIDED}); + if($a[1] eq "statusRequest") { if($hash->{MODE} ne "lan-bluetooth") @@ -377,13 +380,30 @@ PRESENCE_Set($@) { readingsSingleUpdate($hash, "powerCmd", "executed",1); } - - return undef; + } + elsif($a[1] eq "overrideInterval") + { + if($a[2] and $a[2] =~ /^\d+$/) + { + Log3 $name, 3, "PRESENCE ($name) - overriding regular check intervals to ".$a[2]." seconds"; + $hash->{INTERVAL_OVERRIDED} = $a[2]; + } + else + { + Log3 $name, 3, "PRESENCE ($name) - interval override cleared. regular interval will be used for next check."; + return "invalid override interval given (must be a positive integer)" + } + } + elsif($a[1] eq "clearOverride") + { + delete($hash->{INTERVAL_OVERRIDED}); } else { return $usage; } + + return undef; } @@ -522,11 +542,11 @@ PRESENCE_Read($) if($line =~ /^absence|absent/) { - if(!$hash->{helper}{DISABLED} and $hash->{helper}{CURRENT_TIMEOUT} eq "present" and $hash->{TIMEOUT_NORMAL} != $hash->{TIMEOUT_PRESENT}) + if(!$hash->{helper}{DISABLED} and $hash->{helper}{CURRENT_TIMEOUT} eq "present" and $hash->{INTERVAL_NORMAL} != $hash->{INTERVAL_PRESENT}) { $hash->{helper}{CURRENT_TIMEOUT} = "normal"; - Log3 $name, 4 , "PRESENCE ($name) - changing to normal timeout every ".$hash->{TIMEOUT_NORMAL}." seconds"; - DevIo_SimpleWrite($hash, $hash->{ADDRESS}."|".$hash->{TIMEOUT_NORMAL}."\n", 2); + Log3 $name, 4 , "PRESENCE ($name) - changing to normal timeout every ".$hash->{INTERVAL_NORMAL}." seconds"; + DevIo_SimpleWrite($hash, $hash->{ADDRESS}."|".$hash->{INTERVAL_NORMAL}."\n", 2); } unless($hash->{helper}{DISABLED}) @@ -541,11 +561,11 @@ PRESENCE_Read($) } elsif($line =~ /present;(.+?)$/) { - if(!$hash->{helper}{DISABLED} and $hash->{helper}{CURRENT_TIMEOUT} eq "normal" and $hash->{TIMEOUT_NORMAL} != $hash->{TIMEOUT_PRESENT}) + if(!$hash->{helper}{DISABLED} and $hash->{helper}{CURRENT_TIMEOUT} eq "normal" and $hash->{INTERVAL_NORMAL} != $hash->{INTERVAL_PRESENT}) { $hash->{helper}{CURRENT_TIMEOUT} = "present"; - Log3 $name, 4 , "PRESENCE ($name) - changing to present timeout every ".$hash->{TIMEOUT_PRESENT}." seconds"; - DevIo_SimpleWrite($hash, $hash->{ADDRESS}."|".$hash->{TIMEOUT_PRESENT}."\n", 2); + Log3 $name, 4 , "PRESENCE ($name) - changing to present timeout every ".$hash->{INTERVAL_PRESENT}." seconds"; + DevIo_SimpleWrite($hash, $hash->{ADDRESS}."|".$hash->{INTERVAL_PRESENT}."\n", 2); } unless($hash->{helper}{DISABLED}) @@ -670,7 +690,7 @@ sub PRESENCE_StartLocalScan($;$) { delete($hash->{helper}{RUNNING_PID}); - my $seconds = (ReadingsVal($name, "state", "absent") eq "present" ? $hash->{TIMEOUT_PRESENT} : $hash->{TIMEOUT_NORMAL}); + my $seconds = (ReadingsVal($name, "state", "absent") eq "present" ? $hash->{INTERVAL_PRESENT} : $hash->{INTERVAL_NORMAL}); Log3 $hash->{NAME}, 4, "PRESENCE ($name) - fork failed, rescheduling next check in $seconds seconds"; @@ -686,7 +706,7 @@ sub PRESENCE_StartLocalScan($;$) if($local == 0) { - my $seconds = (ReadingsVal($name, "state", "absent") eq "present" ? $hash->{TIMEOUT_PRESENT} : $hash->{TIMEOUT_NORMAL}); + my $seconds = (ReadingsVal($name, "state", "absent") eq "present" ? $hash->{INTERVAL_PRESENT} : $hash->{INTERVAL_NORMAL}); Log3 $hash->{NAME}, 4, "PRESENCE ($name) - rescheduling next check in $seconds seconds"; @@ -1124,10 +1144,12 @@ sub PRESENCE_ProcessLocalScan($) readingsEndUpdate($hash, 1); - #Schedule the next check withing $timeout if it is a regular run + #Schedule the next check within $timeout if it is a regular run if($local eq "0") { - my $seconds = ($a[2] eq "present" ? $hash->{TIMEOUT_PRESENT} : $hash->{TIMEOUT_NORMAL}); + my $seconds = ($a[2] eq "present" ? $hash->{INTERVAL_PRESENT} : $hash->{INTERVAL_NORMAL}); + + $seconds = $hash->{INTERVAL_OVERRIDED} if($hash->{INTERVAL_OVERRIDED}); Log3 $hash->{NAME}, 4, "PRESENCE ($name) - rescheduling next check in $seconds seconds"; @@ -1139,32 +1161,33 @@ sub PRESENCE_ProcessLocalScan($) ##################################### sub PRESENCE_ProcessAbortedScan($) { - my ($hash, $msg) = @_; my $name = $hash->{NAME}; delete($hash->{helper}{RUNNING_PID}); RemoveInternalTimer($hash); + my $retry_interval = AttrVal($name,"retryInterval",10); + if(defined($hash->{helper}{RETRY_COUNT})) { - if($hash->{helper}{RETRY_COUNT} >= 3) + if($hash->{helper}{RETRY_COUNT} >= AttrVal($name, "retryCount", 3)) { Log3 $hash->{NAME}, 2, "PRESENCE ($name) - device could not be checked after ".$hash->{helper}{RETRY_COUNT}." ".($hash->{helper}{RETRY_COUNT} > 1 ? "retries" : "retry"). " (resuming normal operation): $msg" if($hash->{helper}{RETRY_COUNT} == 3); - InternalTimer(gettimeofday()+10, "PRESENCE_StartLocalScan", $hash, 0) unless($hash->{helper}{DISABLED}); + InternalTimer(gettimeofday()+$hash->{INTERVAL_NORMAL}, "PRESENCE_StartLocalScan", $hash, 0) unless($hash->{helper}{DISABLED}); $hash->{helper}{RETRY_COUNT}++; } else { - Log3 $hash->{NAME}, 2, "PRESENCE ($name) - device could not be checked after ".$hash->{helper}{RETRY_COUNT}." ".($hash->{helper}{RETRY_COUNT} > 1 ? "retries" : "retry")." (retrying in 10 seconds): $msg"; - InternalTimer(gettimeofday()+10, "PRESENCE_StartLocalScan", $hash, 0) unless($hash->{helper}{DISABLED}); + Log3 $hash->{NAME}, 2, "PRESENCE ($name) - device could not be checked after ".$hash->{helper}{RETRY_COUNT}." ".($hash->{helper}{RETRY_COUNT} > 1 ? "retries" : "retry")." (retrying in $retry_interval seconds): $msg"; + InternalTimer(gettimeofday()+$retry_interval, "PRESENCE_StartLocalScan", $hash, 0) unless($hash->{helper}{DISABLED}); $hash->{helper}{RETRY_COUNT}++; } } else { $hash->{helper}{RETRY_COUNT} = 1; - InternalTimer(gettimeofday()+10, "PRESENCE_StartLocalScan", $hash, 0) unless($hash->{helper}{DISABLED}); - Log3 $hash->{NAME}, 2, "PRESENCE ($name) - device could not be checked (retrying in 10 seconds): $msg" + InternalTimer(gettimeofday()+$retry_interval, "PRESENCE_StartLocalScan", $hash, 0) unless($hash->{helper}{DISABLED}); + Log3 $hash->{NAME}, 2, "PRESENCE ($name) - device could not be checked (retrying in $retry_interval seconds): $msg" } readingsSingleUpdate($hash, "state", "timeout",1); @@ -1186,7 +1209,7 @@ sub PRESENCE_DoInit($) { readingsSingleUpdate($hash, "state", "active",0); $hash->{helper}{CURRENT_TIMEOUT} = "normal"; - DevIo_SimpleWrite($hash, $hash->{ADDRESS}."|".$hash->{TIMEOUT_NORMAL}."\n", 2); + DevIo_SimpleWrite($hash, $hash->{ADDRESS}."|".$hash->{INTERVAL_NORMAL}."\n", 2); } else { @@ -1525,8 +1548,8 @@ valid log levels: LOG_CRIT, LOG_ERR, LOG_WARNING, LOG_NOTICE, LOG_INFO, LOG_DEBUG. Default: LOG_INFO Examples: - lepresenced --bluetoothdevice hci0 --listenaddress 127.0.0.1 --listenport 5333 --daemon - lepresenced --loglevel LOG_DEBUG --daemon + lepresenced --bluetoothdevice hci0 --listenaddress 127.0.0.1 --listenport 5333 --daemon + lepresenced --loglevel LOG_DEBUG --daemon To detect the presence of a device, it uses the command hcitool lescan (package: @@ -1605,6 +1628,8 @@ Options: