diff --git a/fhem/CHANGED b/fhem/CHANGED index 9317c6d2d..3ed6aebfe 100644 --- a/fhem/CHANGED +++ b/fhem/CHANGED @@ -1,5 +1,6 @@ # 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: 88_HMCCU: Added parameter waitforccu to define command - bugfix: 42_SYSMON: PERL WARNING: Use of uninitialized value - bugfix: 59_WUup.pm: fix state and missing attributes (#695364, #696275) - change: 93_DbLog: V2.22.10, adapted to use extended abortArg diff --git a/fhem/FHEM/88_HMCCU.pm b/fhem/FHEM/88_HMCCU.pm index 48f4b3a9c..44c153443 100755 --- a/fhem/FHEM/88_HMCCU.pm +++ b/fhem/FHEM/88_HMCCU.pm @@ -4,7 +4,7 @@ # # $Id$ # -# Version 4.1.001 +# Version 4.1.002 # # Module for communication between FHEM and Homematic CCU2. # @@ -15,7 +15,7 @@ # ############################################################################## # -# define HMCCU [ccunumber] +# define HMCCU [ccunumber] [waitforccu=] # # set cleardefaults # set defaults @@ -105,7 +105,7 @@ my %HMCCU_CUST_CHN_DEFAULTS; my %HMCCU_CUST_DEV_DEFAULTS; # HMCCU version -my $HMCCU_VERSION = '4.1.001'; +my $HMCCU_VERSION = '4.1.002'; # Default RPC port (BidCos-RF) my $HMCCU_RPC_PORT_DEFAULT = 2001; @@ -304,6 +304,8 @@ sub HMCCU_RefToString ($); sub HMCCU_ExprMatch ($$$); sub HMCCU_ExprNotMatch ($$$); sub HMCCU_GetDutyCycle ($); +sub HMCCU_TCPPing ($$$); +sub HMCCU_TCPConnect ($$); sub HMCCU_CorrectName ($); # Subprocess functions @@ -363,6 +365,16 @@ sub HMCCU_Define ($$) $hash->{host} = $$a[2]; $hash->{Clients} = ':HMCCUDEV:HMCCUCHN:HMCCURPC:'; + + # Check if TCL-Rega process is running on CCU + my $timeout = exists ($h->{waitforccu}) ? $h->{waitforccu} : 0; + if (HMCCU_TCPPing ($hash->{host}, 8181, $timeout)) { + $hash->{ccustate} = 'active'; + } + else { + $hash->{ccustate} = 'unreachable'; + Log3 $name, 1, "HMCCU: CCU2 is not reachable"; + } if (scalar (@$a) >= 4) { return "CCU number must be in range 1-9" if ($$a[3] < 1 || $$a[3] > 9); @@ -4380,9 +4392,13 @@ sub HMCCU_ReadRPCQueue ($) if ($hash->{hmccu}{evtime} > 0 && time()-$hash->{hmccu}{evtime} > $rpctimeout && $hash->{hmccu}{evtimeout} == 0) { $hash->{hmccu}{evtimeout} = 1; + $hash->{ccustate} = HMCCU_TCPConnect ($hash->{host}, 8181) ? 'timeout' : 'unreachable'; Log3 $name, 2, "HMCCU: Received no events from CCU since $rpctimeout seconds"; DoTrigger ($name, "No events from CCU since $rpctimeout seconds"); } + else { + $hash->{ccustate} = 'active' if ($hash->{ccustate} ne 'active'); + } my @hm_pids; my @hm_tids; @@ -5681,6 +5697,47 @@ sub HMCCU_GetDutyCycle ($) return $dc; } +###################################################################### +# Check if TCP port is reachable. +# Parameter timeout should be a multiple of 20 plus 5. +###################################################################### + +sub HMCCU_TCPPing ($$$) +{ + my ($addr, $port, $timeout) = @_; + + if ($timeout > 0) { + my $t = time (); + + while (time () < $t+$timeout) { + return 1 if (HMCCU_TCPConnect ($addr, $port)); + sleep (20); + } + + return 0; + } + else { + return HMCCU_TCPConnect ($addr, $port); + } +} + +###################################################################### +# Check if TCP connection to specified host and port is possible. +###################################################################### + +sub HMCCU_TCPConnect ($$) +{ + my ($addr, $port) = @_; + + my $socket = IO::Socket::INET->new (PeerAddr => $addr, PeerPort => $port); + if ($socket) { + close ($socket); + return 1; + } + + return 0; +} + ###################################################################### # Substitute invalid characters in reading name. # Substitution rules: ':' => '.', any other illegal character => '_' @@ -6016,13 +6073,16 @@ sub HMCCU_CCURPC_ListDevicesCB ($$) Define

    - define <name> HMCCU <HostOrIP> [<ccu-number>] + define <name> HMCCU <HostOrIP> [<ccu-number>] [waitforccu=<timeout>]

    Example:
    define myccu HMCCU 192.168.1.10

    The parameter HostOrIP is the hostname or IP address of a Homematic CCU2. If you have - more than one CCU you can specifiy a unique CCU number with parameter ccu-number. + more than one CCU you can specifiy a unique CCU number with parameter ccu-number. With + option waitforccu HMCCU will wait for the specified time if CCU is not reachable. + Parameter timeout should be a multiple of 20 in seconds. Warning: This option could + block the start of FHEM for timeout seconds.
    For automatic update of Homematic device datapoints and FHEM readings one have to:

    diff --git a/fhem/FHEM/88_HMCCURPC.pm b/fhem/FHEM/88_HMCCURPC.pm index 171d87853..adbe06d45 100644 --- a/fhem/FHEM/88_HMCCURPC.pm +++ b/fhem/FHEM/88_HMCCURPC.pm @@ -4,7 +4,7 @@ # # $Id$ # -# Version 0.96.001 beta +# Version 0.96.002 beta # # Thread based RPC Server module for HMCCU. # @@ -40,7 +40,7 @@ use SetExtensions; ###################################################################### # HMCCURPC version -my $HMCCURPC_VERSION = '0.96 beta'; +my $HMCCURPC_VERSION = '0.96.002 beta'; # Maximum number of events processed per call of Read() my $HMCCURPC_MAX_EVENTS = 50; @@ -869,6 +869,9 @@ sub HMCCURPC_ProcessEvent ($$) my $delay = $rh->{$clkey}{evtime}-$t[0]; $rh->{$clkey}{sumdelay} += $delay; $rh->{$clkey}{avgdelay} = $rh->{$clkey}{sumdelay}/$rh->{$clkey}{rec}{$et}; + if (defined ($hmccu_hash) && $hmccu_hash->{ccustate} ne 'active') { + $hmccu_hash->{ccustate} = 'active'; + } Log3 $name, 2, "HMCCURPC: Received CENTRAL event. ".$t[2]."=".$t[3] if ($t[1] eq 'CENTRAL'); my ($add, $chn) = split (/:/, $t[1]); return defined ($chn) ? ($et, $clkey, $add, $chn, $t[2], $t[3]) : undef; @@ -1024,6 +1027,9 @@ sub HMCCURPC_ProcessEvent ($$) # Input: TO|clkey|Time # Output: TO, clkey, Port, Time # + if (defined ($hmccu_hash)) { + $hmccu_hash->{ccustate} = HMCCU_TCPConnect ($hash->{host}, 8181) ? 'timeout' : 'unreachable'; + } Log3 $name, 2, "HMCCU: Received no events from interface $clkey for ".$t[0]." seconds"; DoTrigger ($name, "No events from interface $clkey for ".$t[0]." seconds"); return ($et, $clkey, $hash->{hmccu}{rpc}{$clkey}{port}, $t[0]);