diff --git a/fhem/CHANGED b/fhem/CHANGED index b0d044ae9..773b4d350 100644 --- a/fhem/CHANGED +++ b/fhem/CHANGED @@ -1,5 +1,7 @@ # 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: 98_ping: Add attribute for minimum fails before reporting + (minFailCount) - bugfix: PRESENCE: fix log warning "use of uninitialized value ..." when using power set command without any argument. - added: 60_allergy: Allergy forecast data for Germany diff --git a/fhem/FHEM/98_ping.pm b/fhem/FHEM/98_ping.pm index 43801eddd..0c55c02cc 100644 --- a/fhem/FHEM/98_ping.pm +++ b/fhem/FHEM/98_ping.pm @@ -41,7 +41,7 @@ sub ping_Initialize($) $hash->{DefFn} = "ping_Define"; $hash->{UndefFn} = "ping_Undefine"; $hash->{AttrFn} = "ping_Attr"; - $hash->{AttrList} = "disable:0,1 checkInterval ".$readingFnAttributes; + $hash->{AttrList} = "disable:1 checkInterval minFailCount ".$readingFnAttributes; return undef; } @@ -61,11 +61,14 @@ sub ping_Define($$) $hash->{HOST} = $host; $hash->{MODE} = lc($mode); $hash->{TIMEOUT} = $timeout; + $hash->{FAILCOUNT} = 0; + readingsSingleUpdate($hash, "state", "Initialized", 1); return "ERROR: mode must be one of tcp,udp,icmp" if ($hash->{MODE} !~ "tcp|udp|icmp"); return "ERROR: timeout must be 0 or higher." if (($hash->{TIMEOUT} !~ /^\d*$/) || ($hash->{TIMEOUT} < 0)); $attr{$name}{"checkInterval"} = 10 if (!defined($attr{$name}{"checkInterval"})); + $attr{$name}{"event-on-change-reading"} = "state" if (!defined($attr{$name}{"event-on-change-reading"})); ping_State($hash); @@ -90,25 +93,28 @@ sub ping_Attr($$$$) { Log3 ($hash, 5, "$hash->{NAME}_Attr: Attr $attribute; Value $value"); - if ($attribute eq "checkInterval") - { - if (($value !~ /^\d*$/) || ($value < 5)) + if ($command eq "set") { + + if ($attribute eq "checkInterval") { - $attr{$name}{"checkInterval"} = 10; - return "checkInterval is required in s (default: 10, min: 5)"; + if (($value !~ /^\d*$/) || ($value < 5)) + { + $attr{$name}{"checkInterval"} = 10; + return "checkInterval is required in s (default: 10, min: 5)"; + } } - } - # Handle "disable" attribute by opening/closing connection to device - elsif ($attribute eq "disable") - { - # Disable on 1, enable on anything else. - if ($value eq "1") + # Handle "disable" attribute by opening/closing connection to device + elsif ($attribute eq "disable") { - readingsSingleUpdate($hash, "state", "disabled", 1); - } - else - { - readingsSingleUpdate($hash, "state", "Initialized", 1); + # Disable on 1, enable on anything else. + if ($value eq "1") + { + readingsSingleUpdate($hash, "state", "disabled", 1); + } + else + { + readingsSingleUpdate($hash, "state", "Initialized", 1); + } } } @@ -121,24 +127,32 @@ sub ping_State(@) { # Update Bridge state my ($hash) = @_; - + return undef if (IsDisabled($hash->{NAME})); Log3 ( $hash, 5, "$hash->{NAME}_State: Executing ping"); # check via ping - my $pingstatus = "unreachable"; my $p; $p = Net::Ping->new($hash->{MODE}); my $alive = $p->ping($hash->{HOST}, $hash->{TIMEOUT}); $p->close(); - $pingstatus = "ok" if $alive; - # And update state - readingsSingleUpdate($hash, "state", $pingstatus, 1); + if ($alive) { + # State is ok + $hash->{FAILCOUNT} = 0; + readingsSingleUpdate($hash, "state", "ok", 1); + } else { + # Increment failcount and report unreachable if over limit + $hash->{FAILCOUNT} += 1; + if ($hash->{FAILCOUNT} >= AttrVal($hash->{NAME}, "minFailCount", 1)) { + readingsSingleUpdate($hash, "state", "unreachable", 1); + } + } # Check state every X seconds + RemoveInternalTimer($hash); InternalTimer(gettimeofday() + AttrVal($hash->{NAME}, "checkInterval", "10"), "ping_State", $hash, 0); return undef; @@ -181,6 +195,10 @@ sub ping_State(@) checkInterval
Default: 10s. Time after the bridge connection is re-checked. +
  • + minFailCount
    + Default: 1. Number of failures before reporting "unreachable". +