# $Id$ ############################################## # # 98_ping.pm # FHEM module to check remote network device using ping. # # Author: Matthew Wire (mattwire) # # This file is part of fhem. # # Fhem is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # Fhem is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with fhem. If not, see . # ############################################################################## package main; use strict; use warnings; #use IO::Handle; #use IO::Socket; #use IO::Select; #use Time::HiRes; use Net::Ping; sub ping_Initialize($) { my ($hash) = @_; $hash->{DefFn} = "ping_Define"; $hash->{UndefFn} = "ping_Undefine"; $hash->{AttrFn} = "ping_Attr"; $hash->{AttrList} = "disable:1 checkInterval minFailCount ".$readingFnAttributes; return undef; } ##################################### # Define ping device sub ping_Define($$) { my ($hash, $def) = @_; my @args = split("[ \t][ \t]*", $def); return "Usage: define ping " if(@args < 5); my ($name, $type, $host, $mode, $timeout) = @args; # Parameters $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); return undef; } ##################################### # Undefine ping device sub ping_Undefine($$) { my ($hash,$arg) = @_; RemoveInternalTimer($hash); return undef; } ##################################### # Manage attribute changes sub ping_Attr($$$$) { my ($command,$name,$attribute,$value) = @_; my $hash = $defs{$name}; Log3 ($hash, 5, "$hash->{NAME}_Attr: Attr $attribute; Value $value"); if ($command eq "set") { if ($attribute eq "checkInterval") { 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") { readingsSingleUpdate($hash, "state", "disabled", 1); } else { readingsSingleUpdate($hash, "state", "Initialized", 1); } } } return undef; } ##################################### # Perform a ping and set state to result 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 $p; $p = Net::Ping->new($hash->{MODE}); my $alive = $p->ping($hash->{HOST}, $hash->{TIMEOUT}); $p->close(); 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; } 1; =pod =begin html

ping

    This module provides a simple "ping" function for testing the state of a remote network device.

    It allows for alerts to be triggered when devices cannot be reached using a notify function.

    Define

      define <name> ping <host/ip> <mode> <timeout>

      Specifies the ping device.
      <host/ip> is the hostname or IP address of the Bridge.

      Specifies ping mode.
      <mode> One of: tcp|udp|icmp. Read the perl docs for more detail: http://perldoc.perl.org/Net/Ping.html

      Timeout.
      <timeout> is the maximum time to wait for each ping.

    Readings

    • state
      [Initialized|ok|unreachable]: Shows reachable status check every 10 (checkInterval) seconds.

    Attributes

    • checkInterval
      Default: 10s. Time after the bridge connection is re-checked.
    • minFailCount
      Default: 1. Number of failures before reporting "unreachable".
=end html =cut