mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-01-31 06:39:11 +00:00
HMCCU: Fixed some minor bugs
git-svn-id: https://svn.fhem.de/fhem/trunk@17824 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
a2fdbb2db3
commit
3355be2e9e
@ -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.
|
||||
- bugfix: 88_HMCCU: Some minor bugs fixed
|
||||
- bugfix: 42_XiaomiBTLESens: bugfix humidity reading
|
||||
- feature: 42_AptToDate: add new get command getDistribution to fetch
|
||||
distribution info
|
||||
|
@ -4,7 +4,7 @@
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# Version 4.3.007
|
||||
# Version 4.3.008
|
||||
#
|
||||
# Module for communication between FHEM and Homematic CCU2/3.
|
||||
#
|
||||
@ -108,7 +108,7 @@ my %HMCCU_CUST_CHN_DEFAULTS;
|
||||
my %HMCCU_CUST_DEV_DEFAULTS;
|
||||
|
||||
# HMCCU version
|
||||
my $HMCCU_VERSION = '4.3.007';
|
||||
my $HMCCU_VERSION = '4.3.008';
|
||||
|
||||
# Default RPC port (BidCos-RF)
|
||||
my $HMCCU_RPC_PORT_DEFAULT = 2001;
|
||||
@ -2883,7 +2883,7 @@ sub HMCCU_CreateDevice ($$$$$)
|
||||
if (!defined ($sourceAddr)) {
|
||||
# Search for type in device table
|
||||
return 1 if (!defined ($newType));
|
||||
for my $da (keys %{$hash->{hmccu}{dev}}) {
|
||||
foreach my $da (keys %{$hash->{hmccu}{dev}}) {
|
||||
if ($hash->{hmccu}{dev}{$da}{type} eq $newType) {
|
||||
$sourceAddr = $da;
|
||||
last;
|
||||
@ -4038,7 +4038,7 @@ sub HMCCU_GetDeviceInfo ($$$)
|
||||
|
||||
$ccuget = HMCCU_GetAttribute ($hmccu_hash, $hash, 'ccuget', 'Value') if ($ccuget eq 'Attr');
|
||||
|
||||
for my $dev (@devlist) {
|
||||
foreach my $dev (@devlist) {
|
||||
my ($int, $add, $chn, $dpt, $nam, $flags) = HMCCU_ParseObject ($hmccu_hash, $dev, 0);
|
||||
if ($flags == $HMCCU_FLAG_ADDRESS) {
|
||||
$devname = HMCCU_GetDeviceName ($hmccu_hash, $add, '');
|
||||
@ -5078,12 +5078,12 @@ sub HMCCU_FindClientDevices ($$$$)
|
||||
}
|
||||
|
||||
######################################################################
|
||||
# Get name of assigned client device of type HMCCURPC or HMCCURPCPROC.
|
||||
# Create a RPC device of type HMCCURPC or HMCCURPCPROC if none is
|
||||
# found and parameter create is set to 1.
|
||||
# Get name of assigned client device of type HMCCURPCPROC.
|
||||
# Create a RPC device of type HMCCURPCPROC if none is found and
|
||||
# parameter create is set to 1.
|
||||
# Return (devname, create).
|
||||
# Return empty string for devname if RPC device cannot be identified
|
||||
# or created. Return create = 1 if device has been created and
|
||||
# or created. Return (devname,1) if device has been created and
|
||||
# configuration should be saved.
|
||||
######################################################################
|
||||
|
||||
@ -5170,6 +5170,10 @@ sub HMCCU_GetRPCDevice ($$$)
|
||||
my %rpcdevattr = ('room' => 'copy', 'group' => 'copy', 'icon' => 'copy',
|
||||
'stateFormat' => 'rpcstate/state', 'eventMap' => '/rpcserver on:on/rpcserver off:off/',
|
||||
'verbose' => 2, 'alias' => $alias );
|
||||
if ($ifname eq 'BidCos-RF') {
|
||||
$rpcdevattr{'rpcPingCCU'} = 300;
|
||||
$rpcdevattr{'ccuflags'} = 'reconnect';
|
||||
}
|
||||
foreach my $a (keys %rpcdevattr) {
|
||||
my $v = $rpcdevattr{$a} eq 'copy' ? AttrVal ($name, $a, '') : $rpcdevattr{$a};
|
||||
CommandAttr (undef, "$rpcdevname $a $v") if ($v ne '');
|
||||
@ -6215,7 +6219,7 @@ sub HMCCU_SetDatapoint ($$$)
|
||||
}
|
||||
|
||||
if ($type eq 'HMCCUDEV' && $hash->{ccuif} eq 'fhem' && $hash->{ccutype} ne 'n/a' && exists ($hash->{ccugroup})) {
|
||||
for my $gaddr (split (',', $hash->{ccugroup})) {
|
||||
foreach my $gaddr (split (',', $hash->{ccugroup})) {
|
||||
$cmd .= '(datapoints.Get("'.$int.'.'.$gaddr.':'.$chn.'.'.$dpt.'")).State('.$value.");\n";
|
||||
}
|
||||
}
|
||||
@ -7110,13 +7114,20 @@ sub HMCCU_CalculateReading ($$)
|
||||
elsif ($vt eq 'avg') {
|
||||
# Average value
|
||||
next if ($pc < 1);
|
||||
my $newval = shift @pars;
|
||||
my $cnt = ReadingsVal ($name, $rn."_cnt", 0);
|
||||
my $sum = ReadingsVal ($name, $rn."_sum", 0);
|
||||
$cnt++;
|
||||
$sum += $newval;
|
||||
my $curval = $sum/$cnt;
|
||||
push (@result, $rn."_cnt", $cnt, $rn."_sum", $sum, $rn, $curval);
|
||||
if ($pc == 1) {
|
||||
my $newval = shift @pars;
|
||||
my $cnt = ReadingsVal ($name, $rn."_cnt", 0);
|
||||
my $sum = ReadingsVal ($name, $rn."_sum", 0);
|
||||
$cnt++;
|
||||
$sum += $newval;
|
||||
my $curval = $sum/$cnt;
|
||||
push (@result, $rn."_cnt", $cnt, $rn."_sum", $sum, $rn, $curval);
|
||||
}
|
||||
else {
|
||||
my $sum = 0;
|
||||
foreach my $p (@pars) { $sum += $p; }
|
||||
push (@result, $rn, $sum/scalar(@pars));
|
||||
}
|
||||
}
|
||||
elsif ($vt eq 'sum') {
|
||||
# Sum of values
|
||||
@ -7632,7 +7643,7 @@ sub HMCCU_CCURPC_NewDevicesCB ($$$)
|
||||
my $msg = '';
|
||||
|
||||
Log3 $name, 2, "CCURPC: $cb NewDevice received $devcount device specifications";
|
||||
for my $dev (@$a) {
|
||||
foreach my $dev (@$a) {
|
||||
my $msg = '';
|
||||
if ($dev->{ADDRESS} =~ /:[0-9]{1,2}$/) {
|
||||
$msg = "C|".$dev->{ADDRESS}."|".$dev->{TYPE}."|".$dev->{VERSION}."|null|null";
|
||||
@ -7660,7 +7671,7 @@ sub HMCCU_CCURPC_DeleteDevicesCB ($$$)
|
||||
my $devcount = scalar (@$a);
|
||||
|
||||
Log3 $name, 2, "CCURPC: $cb DeleteDevice received $devcount device addresses";
|
||||
for my $dev (@$a) {
|
||||
foreach my $dev (@$a) {
|
||||
HMCCU_CCURPC_Write ("DD", $dev);
|
||||
}
|
||||
|
||||
@ -7704,7 +7715,7 @@ sub HMCCU_CCURPC_ReaddDevicesCB ($$$)
|
||||
my $devcount = scalar (@$a);
|
||||
|
||||
Log3 $name, 2, "CCURPC: $cb ReaddDevice received $devcount device addresses";
|
||||
for my $dev (@$a) {
|
||||
foreach my $dev (@$a) {
|
||||
HMCCU_CCURPC_Write ("RA", $dev);
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# Version 4.3.003
|
||||
# Version 4.3.004
|
||||
#
|
||||
# (c) 2018 zap (zap01 <at> t-online <dot> de)
|
||||
#
|
||||
@ -788,7 +788,7 @@ sub HMCCUCHN_Get ($@)
|
||||
<i>dp-list</i>. The result is stored in <i>reading</i>. For datapoints in <i>dp-list</i>
|
||||
also variable notation is supported (for more information on variables see documentation of
|
||||
attribute 'peer').<br/>
|
||||
The following <i>values</i> are supported:<br/>
|
||||
The following <i>value-types</i> are supported:<br/>
|
||||
dewpoint = calculate dewpoint, <i>dp-list</i> = <temperature>,<humidity><br/>
|
||||
abshumidity = calculate absolute humidity, <i>dp-list</i> = <temperature>,<humidity><br/>
|
||||
equ = compare datapoint values. Result is "n/a" if values are not equal.<br/>
|
||||
|
@ -4,7 +4,7 @@
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# Version 1.2
|
||||
# Version 1.3
|
||||
#
|
||||
# Subprocess based RPC Server module for HMCCU.
|
||||
#
|
||||
@ -35,7 +35,7 @@ use SetExtensions;
|
||||
######################################################################
|
||||
|
||||
# HMCCURPC version
|
||||
my $HMCCURPCPROC_VERSION = '1.2';
|
||||
my $HMCCURPCPROC_VERSION = '1.3';
|
||||
|
||||
# Maximum number of events processed per call of Read()
|
||||
my $HMCCURPCPROC_MAX_EVENTS = 100;
|
||||
@ -52,16 +52,16 @@ my $HMCCURPCPROC_MAX_QUEUESEND = 70;
|
||||
# Time to wait after data processing loop in microseconds
|
||||
my $HMCCURPCPROC_TIME_WAIT = 100000;
|
||||
|
||||
# Timeout for established CCU connection
|
||||
# Timeout for established CCU connection in seconds
|
||||
my $HMCCURPCPROC_TIMEOUT_CONNECTION = 1;
|
||||
|
||||
# Timeout for TriggerIO()
|
||||
# Timeout for TriggerIO() in seconds
|
||||
my $HMCCURPCPROC_TIMEOUT_WRITE = 0.001;
|
||||
|
||||
# Timeout for accepting incoming connections (0 = default)
|
||||
# Timeout for accepting incoming connections in seconds (0 = default)
|
||||
my $HMCCURPCPROC_TIMEOUT_ACCEPT = 1;
|
||||
|
||||
# Timeout for incoming CCU events
|
||||
# Timeout for incoming CCU events in seconds
|
||||
my $HMCCURPCPROC_TIMEOUT_EVENT = 600;
|
||||
|
||||
# Send statistic information after specified amount of events
|
||||
@ -73,13 +73,13 @@ my $HMCCURPCPROC_RPC_PORT_DEFAULT = 2001;
|
||||
# Default RPC server base port
|
||||
my $HMCCURPCPROC_SERVER_PORT = 5400;
|
||||
|
||||
# Delay for RPC server start after FHEM is initialized
|
||||
# Delay for RPC server start after FHEM is initialized in seconds
|
||||
my $HMCCURPCPROC_INIT_INTERVAL0 = 12;
|
||||
|
||||
# Delay for RPC server cleanup after stop
|
||||
# Delay for RPC server cleanup after stop in seconds
|
||||
my $HMCCURPCPROC_INIT_INTERVAL2 = 30;
|
||||
|
||||
# Delay for RPC server functionality check after start
|
||||
# Delay for RPC server functionality check after start in seconds
|
||||
my $HMCCURPCPROC_INIT_INTERVAL3 = 25;
|
||||
|
||||
# BinRPC data types
|
||||
@ -117,24 +117,25 @@ sub HMCCURPCPROC_SetState ($$);
|
||||
sub HMCCURPCPROC_ProcessEvent ($$);
|
||||
|
||||
# RPC server control functions
|
||||
sub HMCCURPCPROC_GetRPCServerID ($$);
|
||||
sub HMCCURPCPROC_RegisterCallback ($$);
|
||||
sub HMCCURPCPROC_CheckProcessState ($$);
|
||||
sub HMCCURPCPROC_CleanupIO ($);
|
||||
sub HMCCURPCPROC_CleanupProcess ($);
|
||||
sub HMCCURPCPROC_DeRegisterCallback ($$);
|
||||
sub HMCCURPCPROC_GetRPCServerID ($$);
|
||||
sub HMCCURPCPROC_Housekeeping ($);
|
||||
sub HMCCURPCPROC_InitRPCServer ($$$$);
|
||||
sub HMCCURPCPROC_StartRPCServer ($);
|
||||
sub HMCCURPCPROC_IsRPCServerRunning ($);
|
||||
sub HMCCURPCPROC_IsRPCStateBlocking ($);
|
||||
sub HMCCURPCPROC_RegisterCallback ($$);
|
||||
sub HMCCURPCPROC_ResetRPCState ($);
|
||||
sub HMCCURPCPROC_RPCPing ($);
|
||||
sub HMCCURPCPROC_RPCServerStarted ($);
|
||||
sub HMCCURPCPROC_RPCServerStopped ($);
|
||||
sub HMCCURPCPROC_CleanupProcess ($);
|
||||
sub HMCCURPCPROC_CleanupIO ($);
|
||||
sub HMCCURPCPROC_TerminateProcess ($);
|
||||
sub HMCCURPCPROC_CheckProcessState ($$);
|
||||
sub HMCCURPCPROC_IsRPCServerRunning ($);
|
||||
sub HMCCURPCPROC_Housekeeping ($);
|
||||
sub HMCCURPCPROC_StopRPCServer ($);
|
||||
sub HMCCURPCPROC_SendRequest ($@);
|
||||
sub HMCCURPCPROC_SetRPCState ($$$$);
|
||||
sub HMCCURPCPROC_ResetRPCState ($);
|
||||
sub HMCCURPCPROC_IsRPCStateBlocking ($);
|
||||
sub HMCCURPCPROC_StartRPCServer ($);
|
||||
sub HMCCURPCPROC_StopRPCServer ($);
|
||||
sub HMCCURPCPROC_TerminateProcess ($);
|
||||
|
||||
# Helper functions
|
||||
sub HMCCURPCPROC_GetAttribute ($$$$);
|
||||
@ -199,10 +200,10 @@ sub HMCCURPCPROC_Initialize ($)
|
||||
|
||||
$hash->{parseParams} = 1;
|
||||
|
||||
$hash->{AttrList} = "ccuflags:multiple-strict,expert,reconnect,logEvents,ccuInit,queueEvents,noEvents".
|
||||
$hash->{AttrList} = "ccuflags:multiple-strict,expert,reconnect,logEvents,ccuInit,queueEvents,noEvents,logPong".
|
||||
" rpcMaxEvents rpcQueueSend rpcQueueSize rpcMaxIOErrors".
|
||||
" rpcServerAddr rpcServerPort rpcWriteTimeout rpcAcceptTimeout".
|
||||
" rpcConnTimeout rpcStatistics rpcEventTimeout ".
|
||||
" rpcConnTimeout rpcStatistics rpcEventTimeout rpcPingCCU ".
|
||||
$readingFnAttributes;
|
||||
}
|
||||
|
||||
@ -245,7 +246,7 @@ sub HMCCURPCPROC_Define ($$)
|
||||
$rpcip = HMCCU_ResolveName ($hash->{host}, 'N/A');
|
||||
|
||||
# Find IO device
|
||||
for my $d (keys %defs) {
|
||||
foreach my $d (keys %defs) {
|
||||
my $dh = $defs{$d};
|
||||
next if (!exists ($dh->{TYPE}) || !exists ($dh->{NAME}));
|
||||
next if ($dh->{TYPE} ne 'HMCCU');
|
||||
@ -299,7 +300,8 @@ sub HMCCURPCPROC_Define ($$)
|
||||
|
||||
######################################################################
|
||||
# Initialization of FHEM device.
|
||||
# Called during Define() or by HMCCU after CCU ready.
|
||||
# Called during Define() or by HMCCU during delayed initialization
|
||||
# after CCU ready.
|
||||
# Return 0 on successful initialization or >0 on error:
|
||||
# 1 = Invalid port or interface
|
||||
# 2 = Cannot assign IO device
|
||||
@ -319,7 +321,7 @@ sub HMCCURPCPROC_InitDevice ($$) {
|
||||
return 1 if (!defined ($ifname) || !defined ($ifport));
|
||||
|
||||
# Check if RPC device with same interface already exists
|
||||
for my $d (keys %defs) {
|
||||
foreach my $d (keys %defs) {
|
||||
my $dh = $defs{$d};
|
||||
next if (!exists ($dh->{TYPE}) || !exists ($dh->{NAME}));
|
||||
if ($dh->{TYPE} eq 'HMCCURPCPROC' && $dh->{NAME} ne $name && IsDisabled ($dh->{NAME}) != 1) {
|
||||
@ -354,10 +356,11 @@ sub HMCCURPCPROC_InitDevice ($$) {
|
||||
|
||||
Log3 $name, 1, "HMCCURPCPROC: [$name] Initialized version $HMCCURPCPROC_VERSION for interface $ifname with I/O device $ioname";
|
||||
|
||||
# Set some attributes
|
||||
# Set some attributes and start CCU ping
|
||||
if ($init_done) {
|
||||
$attr{$name}{stateFormat} = "rpcstate/state";
|
||||
$attr{$name}{verbose} = 2;
|
||||
$attr{$name}{verbose} = 2;+
|
||||
HMCCURPCPROC_RPCPing ($dev_hash);
|
||||
}
|
||||
|
||||
HMCCURPCPROC_ResetRPCState ($dev_hash);
|
||||
@ -420,11 +423,27 @@ sub HMCCURPCPROC_Attr ($@)
|
||||
elsif ($attrname eq 'rpcServerAddr') {
|
||||
$hash->{hmccu}{localaddr} = $attrval;
|
||||
}
|
||||
elsif ($attrname eq 'rpcPingCCU') {
|
||||
if ($attrval > 0) {
|
||||
if ($hash->{rpcinterface} =~ /^(BidCos-RF|BidCos-Wired|HmIP-RF)$/) {
|
||||
InternalTimer (gettimeofday()+$attrval, "HMCCURPCPROC_RPCPing", $hash, 0);
|
||||
}
|
||||
else {
|
||||
return "HMCCURPCPROC: [$name] RPC Ping not supported by interface ".$hash->{rpcinterface};
|
||||
}
|
||||
}
|
||||
else {
|
||||
RemoveInternalTimer ($hash, "HMCCURPCPROC_RPCPing");
|
||||
}
|
||||
}
|
||||
}
|
||||
elsif ($cmd eq 'del') {
|
||||
if ($attrname eq 'rpcServerAddr') {
|
||||
$hash->{hmccu}{localaddr} = $hash->{hmccu}{defaultaddr};
|
||||
}
|
||||
elsif ($attrname eq 'rpcPingCCU') {
|
||||
RemoveInternalTimer ($hash, "HMCCURPCPROC_RPCPing");
|
||||
}
|
||||
}
|
||||
|
||||
return undef;
|
||||
@ -442,7 +461,8 @@ sub HMCCURPCPROC_Set ($@)
|
||||
my $opt = shift @$a;
|
||||
|
||||
my $ccuflags = AttrVal ($name, 'ccuflags', 'null');
|
||||
my $options = $ccuflags =~ /expert/ ? "cleanup:noArg deregister:noArg register:noArg rpcrequest rpcserver:on,off" : "";
|
||||
my $options = $ccuflags =~ /expert/ ?
|
||||
"cleanup:noArg deregister:noArg register:noArg rpcrequest rpcserver:on,off" : "";
|
||||
my $busyoptions = $ccuflags =~ /expert/ ? "rpcserver:off" : "";
|
||||
|
||||
return "HMCCURPCPROC: CCU busy, choose one of $busyoptions"
|
||||
@ -782,22 +802,18 @@ sub HMCCURPCPROC_ProcessEvent ($$)
|
||||
my $evttimeout = HMCCURPCPROC_GetAttribute ($hash, 'rpcEventTimeout', 'rpcevtimeout',
|
||||
$HMCCURPCPROC_TIMEOUT_EVENT);
|
||||
|
||||
# Parse event
|
||||
return undef if (!defined ($event) || $event eq '');
|
||||
my @t = split (/\|/, $event);
|
||||
my $et = shift @t;
|
||||
my $clkey = shift @t;
|
||||
my $tc = scalar (@t);
|
||||
|
||||
# Log event
|
||||
Log3 $name, 2, "HMCCURPCPROC: [$name] CCUEvent = $event" if ($ccuflags =~ /logEvents/);
|
||||
|
||||
# Check event data
|
||||
if (!defined ($clkey)) {
|
||||
Log3 $name, 2, "HMCCURPCPROC: [$name] Syntax error in RPC event data";
|
||||
# Detect event type and clkey
|
||||
my ($et, $clkey, $evdata) = split (/\|/, $event, 3);
|
||||
if (!defined ($evdata)) {
|
||||
Log3 $name, 2, "HMCCURPCPROC: [$name] Syntax error in RPC event data $event";
|
||||
return undef;
|
||||
}
|
||||
|
||||
|
||||
# Check for valid server
|
||||
if ($clkey ne $rpcname) {
|
||||
Log3 $name, 2, "HMCCURPCPROC: [$name] Received $et event for unknown RPC server $clkey";
|
||||
@ -810,10 +826,14 @@ sub HMCCURPCPROC_ProcessEvent ($$)
|
||||
Log3 $name, 2, "HMCCURPCPROC: [$name] Received unknown event from CCU: ".$et;
|
||||
return undef;
|
||||
}
|
||||
|
||||
# Parse event
|
||||
my @t = split (/\|/, $evdata, $rpceventargs{$et});
|
||||
my $tc = scalar (@t);
|
||||
|
||||
# Check event parameters
|
||||
if ($tc != $rpceventargs{$et}) {
|
||||
Log3 $name, 2, "HMCCURPCPROC: [$name] Wrong number of parameters in event $event. Expected ".
|
||||
Log3 $name, 2, "HMCCURPCPROC: [$name] Wrong number of $tc parameters in event $event. Expected ".
|
||||
$rpceventargs{$et};
|
||||
return undef;
|
||||
}
|
||||
@ -832,7 +852,8 @@ sub HMCCURPCPROC_ProcessEvent ($$)
|
||||
$rh->{sumdelay} += $delay;
|
||||
$rh->{avgdelay} = $rh->{sumdelay}/$rh->{rec}{$et};
|
||||
$hash->{ccustate} = 'active' if ($hash->{ccustate} ne 'active');
|
||||
Log3 $name, 3, "HMCCURPCPROC: [$name] Received CENTRAL event. ".$t[2]."=".$t[3] if ($t[1] eq 'CENTRAL');
|
||||
Log3 $name, 3, "HMCCURPCPROC: [$name] Received CENTRAL event from $clkey. ".$t[2]."=".$t[3]
|
||||
if ($t[1] eq 'CENTRAL' && $t[3] eq $rpcname && $ccuflags =~ /logPong/);
|
||||
my ($add, $chn) = split (/:/, $t[1]);
|
||||
return defined ($chn) ? ($et, $clkey, $add, $chn, $t[2], $t[3]) : undef;
|
||||
}
|
||||
@ -1474,7 +1495,7 @@ sub HMCCURPCPROC_CheckProcessState ($$)
|
||||
|
||||
sub HMCCURPCPROC_IsRPCServerRunning ($)
|
||||
{
|
||||
my ($hash, $cleanup) = @_;
|
||||
my ($hash) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
|
||||
Log3 $name, 2, "HMCCURPCPROC: [$name] Checking if RPC server process is running";
|
||||
@ -1562,6 +1583,7 @@ sub HMCCURPCPROC_SendRequest ($@)
|
||||
my $rc;
|
||||
|
||||
if (HMCCU_IsRPCType ($hmccu_hash, $port, 'A')) {
|
||||
# Use XMLRPC
|
||||
my $clurl = HMCCU_GetRPCServerInfo ($hmccu_hash, $port, 'url');
|
||||
return HMCCU_Log ($hash, 2, "Can't get client URL for port $port", undef)
|
||||
if (!defined ($clurl));
|
||||
@ -1572,6 +1594,7 @@ sub HMCCURPCPROC_SendRequest ($@)
|
||||
Log3 $name, 2, "HMCCURPCPROC: [$name] RPC request error ".$RPC::XML::ERROR if (!defined ($rc));
|
||||
}
|
||||
elsif (HMCCU_IsRPCType ($hmccu_hash, $port, 'B')) {
|
||||
# Use BINRPC
|
||||
my $serveraddr = HMCCU_GetRPCServerInfo ($hmccu_hash, $port, 'host');
|
||||
return HMCCU_Log ($hash, 2, "Can't get server address for port $port", undef)
|
||||
if (!defined ($serveraddr));
|
||||
@ -1618,6 +1641,25 @@ sub HMCCURPCPROC_SendRequest ($@)
|
||||
return $rc;
|
||||
}
|
||||
|
||||
######################################################################
|
||||
# Timer function for RPC Ping
|
||||
######################################################################
|
||||
|
||||
sub HMCCURPCPROC_RPCPing ($)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
|
||||
my $ping = AttrVal ($name, 'rpcPingCCU', 0);
|
||||
if ($ping > 0) {
|
||||
if ($init_done && HMCCURPCPROC_CheckProcessState ($hash, 'running')) {
|
||||
my $clkey = 'CB'.$hash->{rpcport}.$hash->{rpcid};
|
||||
HMCCURPCPROC_SendRequest ($hash, "ping", $clkey);
|
||||
}
|
||||
InternalTimer (gettimeofday()+$ping, "HMCCURPCPROC_RPCPing", $hash, 0);
|
||||
}
|
||||
}
|
||||
|
||||
######################################################################
|
||||
# Process binary RPC request
|
||||
######################################################################
|
||||
@ -2690,6 +2732,7 @@ sub HMCCURPCPROC_DecodeResponse ($)
|
||||
This flag is not supported by interfaces CUxD and HVL.<br/>
|
||||
expert - Activate expert mode<br/>
|
||||
logEvents - Events are written into FHEM logfile if verbose is 4<br/>
|
||||
logPong - Write log message when receiving pong event if verbose level is at least 3.<br/>
|
||||
noEvents - Ignore events from CCU, do not update client device readings.<br/>
|
||||
queueEvents - Always write events into queue and send them asynchronously to FHEM.
|
||||
Frequency of event transmission to FHEM depends on attribute rpcConnTimeout.<br/>
|
||||
@ -2717,6 +2760,11 @@ sub HMCCURPCPROC_DecodeResponse ($)
|
||||
message is written into FHEM log file. Default value is 100. Set this attribute to 0
|
||||
to disable error counting.
|
||||
</li><br/>
|
||||
<li><b>rpcPingCCU <interval></b><br/>
|
||||
Send RPC ping request to CCU every <i>interval</i> seconds. If <i>interval</i> is 0
|
||||
sending ping requests is disabled. If attribut ccuflags is set to logPong a log message
|
||||
with level 3 is created when receiving a pong event.
|
||||
</li><br/>
|
||||
<li><b>rpcQueueSend <events></b><br/>
|
||||
Maximum number of events sent to FHEM per accept loop. Default is 70. If set to 0
|
||||
all events in queue are sent to FHEM. Transmission is stopped when an I/O error occurrs
|
||||
|
@ -4,7 +4,7 @@
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# Version 4.3
|
||||
# Version 4.4
|
||||
#
|
||||
# Configuration parameters for HomeMatic devices.
|
||||
#
|
||||
@ -58,6 +58,20 @@ use vars qw(%HMCCU_SCRIPTS);
|
||||
statedatapoint => "STATE",
|
||||
substitute => "STATE!0:closed,1:tilted,2:open;ERROR!0:no,1:sabotage"
|
||||
},
|
||||
"HmIP-SRH" => {
|
||||
_description => "Fenster Drehgriffkontakt",
|
||||
_channels => "1",
|
||||
ccureadingfilter => "STATE",
|
||||
statedatapoint => "STATE",
|
||||
substitute => "STATE!0:closed,1:tilted,2:open"
|
||||
},
|
||||
"HmIP-SAM" => {
|
||||
_description => "Beschleunigungssensor",
|
||||
_channels => "1",
|
||||
ccureadingfilter => "MOTION",
|
||||
statedatapoint => "MOTION",
|
||||
substitute => "MOTION!(0|false):no,(1|true):yes"
|
||||
},
|
||||
"HM-Sec-Key|HM-Sec-Key-S|HM-Sec-Key-O|HM-Sec-Key-Generic" => {
|
||||
_description => "Funk-Tuerschlossantrieb KeyMatic",
|
||||
_channels => "1",
|
||||
@ -89,7 +103,7 @@ use vars qw(%HMCCU_SCRIPTS);
|
||||
webCmd => "devstate",
|
||||
widgetOverride => "devstate:uzsuToggle,off,on"
|
||||
},
|
||||
"HMIP-PS" => {
|
||||
"HmIP-PS" => {
|
||||
_description => "Steckdose",
|
||||
_channels => "3",
|
||||
ccureadingfilter => "STATE",
|
||||
@ -468,6 +482,18 @@ use vars qw(%HMCCU_SCRIPTS);
|
||||
statedatapoint => "1.STATE",
|
||||
substitute => "STATE!0:closed,1:tilted,2:open;ERROR!0:no,1:sabotage"
|
||||
},
|
||||
"HMIP-SRH" => {
|
||||
_description => "Fenster Drehgriffkontakt",
|
||||
ccureadingfilter => "STATE",
|
||||
statedatapoint => "1.STATE",
|
||||
substitute => "STATE!0:closed,1:tilted,2:open"
|
||||
},
|
||||
"HmIP-SAM" => {
|
||||
_description => "Beschleunigungssensor",
|
||||
ccureadingfilter => "1.MOTION",
|
||||
statedatapoint => "1.MOTION",
|
||||
substitute => "MOTION!(0|false):no,(1|true):yes"
|
||||
},
|
||||
"HM-Sec-Key|HM-Sec-Key-S|HM-Sec-Key-O|HM-Sec-Key-Generic" => {
|
||||
_description => "Funk-Tuerschlossantrieb KeyMatic",
|
||||
ccureadingfilter => "(STATE|INHIBIT)",
|
||||
@ -606,6 +632,14 @@ use vars qw(%HMCCU_SCRIPTS);
|
||||
ccureadingfilter => "PRESS",
|
||||
substitute => "PRESS_SHORT,PRESS_LONG!(1|true):pressed,(0|false):released"
|
||||
},
|
||||
"HmIP-BSL" => {
|
||||
_description => "Schaltaktor mit Signalleuchte",
|
||||
ccureadingfilter => "(LEVEL|STATE|COLOR|PRESS)",
|
||||
ccuscaleval => "LEVEL:0:1:0:100",
|
||||
statedatapoint => "4.STATE",
|
||||
statevals => "on:true,off:false",
|
||||
substitute => "STATE!(0|false):off,(1|true):on;COLOR!0:black,1:blue,2:green,3:turquoise,4:red,5:purple,6:yellow,7:white"
|
||||
},
|
||||
"HM-SwI-3-FM" => {
|
||||
_description => "Funk-Schalterschnittstelle",
|
||||
ccureadingfilter => "PRESS",
|
||||
@ -980,7 +1014,7 @@ if (oPR) {
|
||||
parameters => 4,
|
||||
code => qq(
|
||||
object oSV = dom.GetObject("\$name");
|
||||
if (!oSV){
|
||||
if (!oSV) {
|
||||
object oSysVars = dom.GetObject(ID_SYSTEM_VARIABLES);
|
||||
oSV = dom.CreateObject(OT_VARDP);
|
||||
oSysVars.Add(oSV.ID());
|
||||
@ -1005,7 +1039,7 @@ else {
|
||||
parameters => 6,
|
||||
code => qq(
|
||||
object oSV = dom.GetObject("\$name");
|
||||
if (!oSV){
|
||||
if (!oSV) {
|
||||
object oSysVars = dom.GetObject(ID_SYSTEM_VARIABLES);
|
||||
oSV = dom.CreateObject(OT_VARDP);
|
||||
oSysVars.Add(oSV.ID());
|
||||
@ -1032,7 +1066,7 @@ else {
|
||||
parameters => 6,
|
||||
code => qq(
|
||||
object oSV = dom.GetObject("\$name");
|
||||
if (!oSV){
|
||||
if (!oSV) {
|
||||
object oSysVars = dom.GetObject(ID_SYSTEM_VARIABLES);
|
||||
oSV = dom.CreateObject(OT_VARDP);
|
||||
oSysVars.Add(oSV.ID());
|
||||
@ -1095,10 +1129,48 @@ if (oSV) {
|
||||
code => qq(
|
||||
object osysvar;
|
||||
string ssysvarid;
|
||||
foreach (ssysvarid, dom.GetObject(ID_SYSTEM_VARIABLES).EnumUsedIDs())
|
||||
{
|
||||
foreach (ssysvarid, dom.GetObject(ID_SYSTEM_VARIABLES).EnumUsedIDs()) {
|
||||
osysvar = dom.GetObject(ssysvarid);
|
||||
WriteLine (osysvar.Name() # "=" # osysvar.Variable() # "=" # osysvar.Value());
|
||||
Write(osysvar.Name());
|
||||
if(osysvar.ValueSubType() == 6) {
|
||||
Write ("=" # osysvar.AlType());
|
||||
}
|
||||
else {
|
||||
Write ("=" # osysvar.Variable());
|
||||
}
|
||||
WriteLine ("=" # osysvar.Value());
|
||||
}
|
||||
)
|
||||
},
|
||||
"GetVariablesExt" => {
|
||||
description => "Query system variables",
|
||||
syntax => "",
|
||||
parameters => 0,
|
||||
code => qq(
|
||||
string sSysVarId;
|
||||
foreach (sSysVarId, dom.GetObject(ID_SYSTEM_VARIABLES).EnumUsedIDs()) {
|
||||
object oSysVar = dom.GetObject(sSysVarId);
|
||||
Write(oSysVar.Name());
|
||||
if (oSysVar.ValueSubType() == 6) {
|
||||
Write(";" # oSysVar.AlType());
|
||||
} else {
|
||||
Write(";" # oSysVar.Variable());
|
||||
}
|
||||
Write(";" # oSysVar.Value() # ";");
|
||||
if (oSysVar.ValueType() == 16) {
|
||||
Write(oSysVar.ValueList());
|
||||
}
|
||||
Write(";" # oSysVar.ValueMin() # ";" # oSysVar.ValueMax());
|
||||
Write(";" # oSysVar.ValueUnit() # ";" # oSysVar.ValueType() # ";" # oSysVar.ValueSubType());
|
||||
Write(";" # oSysVar.DPArchive() # ";" # oSysVar.Visible());
|
||||
Write(";" # oSysVar.Timestamp().ToInteger());
|
||||
if (oSysVar.ValueType() == 2) {
|
||||
Write(";" # oSysVar.ValueName0());
|
||||
}
|
||||
if (oSysVar.ValueType() == 2) {
|
||||
Write(";" # oSysVar.ValueName1());
|
||||
}
|
||||
WriteLine("");
|
||||
}
|
||||
)
|
||||
},
|
||||
@ -1382,6 +1454,147 @@ if(lResult == 0) {
|
||||
WriteLine(lGetOut);
|
||||
}
|
||||
)
|
||||
},
|
||||
"GetServiceMessages" => {
|
||||
description => "Read list of CCU service messages",
|
||||
syntax => "",
|
||||
parameters => 0,
|
||||
code => qq(
|
||||
integer c = 0;
|
||||
object oTmpArray = dom.GetObject(ID_SERVICES);
|
||||
if(oTmpArray) {
|
||||
string sTmp;
|
||||
string sdesc;
|
||||
string stest;
|
||||
foreach(sTmp, oTmpArray.EnumIDs()) {
|
||||
object oTmp = dom.GetObject(sTmp);
|
||||
if (oTmp) {
|
||||
if(oTmp.IsTypeOf(OT_ALARMDP) && (oTmp.AlState() == asOncoming)) {
|
||||
boolean collect = true;
|
||||
object trigDP = dom.GetObject(oTmp.AlTriggerDP());
|
||||
object och = dom.GetObject((trigDP.Channel()));
|
||||
object odev = dom.GetObject((och.Device()));
|
||||
var ival = trigDP.Value();
|
||||
time sftime = oTmp.AlOccurrenceTime();
|
||||
time sltime = oTmp.LastTriggerTime();
|
||||
var sdesc = trigDP.HSSID();
|
||||
var sserial = odev.Address();
|
||||
string sAlarmMessage = web.webKeyFromStringTable(sdesc.Name());
|
||||
if(!sAlarmMessage.Length()) {
|
||||
sAlarmMessage = sdesc;
|
||||
}
|
||||
c = c+1;
|
||||
WriteLine(sftime # ";" # sltime # ";" # sAlarmMessage # ";" # sserial);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Write(c);
|
||||
)
|
||||
},
|
||||
"GetAlarms" => {
|
||||
description => "Read list of CCU alarm messages",
|
||||
syntax => "",
|
||||
parameters => 0,
|
||||
code => qq(
|
||||
integer c = 0;
|
||||
object oTmpArray = dom.GetObject( ID_SYSTEM_VARIABLES );
|
||||
if(oTmpArray) {
|
||||
string sTmp;
|
||||
foreach(sTmp,oTmpArray.EnumIDs()) {
|
||||
object oTmp = dom.GetObject(sTmp);
|
||||
if(oTmp) {
|
||||
if(oTmp.IsTypeOf(OT_ALARMDP) && (oTmp.AlState() == asOncoming)) {
|
||||
c = c+1;
|
||||
object oSV = oTmp;
|
||||
Write(oSV.AlOccurrenceTime());
|
||||
Write(";" # oSV.Timestamp());
|
||||
object oDestDP = dom.GetObject( oSV.AlDestMapDP() );
|
||||
string sDestDPName = "";
|
||||
if(oDestDP) {
|
||||
sDestDPName = oDestDP.Name();
|
||||
}
|
||||
else {
|
||||
sDestDPName = "none";
|
||||
}
|
||||
Write(";" # sDestDPName);
|
||||
|
||||
string sAlarmName = oSV.Name();
|
||||
if(!sAlarmName.Length()) {
|
||||
sAlarmName = "none";
|
||||
}
|
||||
Write(";" # sAlarmName);
|
||||
|
||||
string sAlarmDescription = oSV.DPInfo();
|
||||
if(!sAlarmDescription.Length()) {
|
||||
sAlarmDescription = "none";
|
||||
}
|
||||
Write(";" # sAlarmDescription);
|
||||
|
||||
string sRooms = "";
|
||||
string sLastTriggerName = "";
|
||||
string sLastTriggerMessage = "";
|
||||
string sLastTriggerKey = "";
|
||||
integer iTmpTriggerID = oSV.LastTriggerID();
|
||||
if(iTmpTriggerID == ID_ERROR) {
|
||||
iTmpTriggerID = oSV.AlTriggerDP();
|
||||
}
|
||||
|
||||
string sAlarmMessage = "";
|
||||
string sChannelName = "none";
|
||||
object oLastTrigger = dom.GetObject(iTmpTriggerID);
|
||||
if(oLastTrigger) {
|
||||
object oLastTriggerChannel = dom.GetObject(oLastTrigger.Channel());
|
||||
if(oLastTriggerChannel) {
|
||||
sChannelName = oLastTriggerChannel.Name();
|
||||
string sLastTriggerName = sChannelName;
|
||||
string sRID;
|
||||
foreach(sRID, oLastTriggerChannel.ChnRoom()) {
|
||||
object oRoom = dom.GetObject(sRID);
|
||||
if(oRoom) {
|
||||
sRooms = sRooms # "," # oRoom.Name();
|
||||
}
|
||||
}
|
||||
|
||||
if(oLastTrigger.IsTypeOf(OT_HSSDP)) {
|
||||
string sLongKey = oLastTriggerChannel.ChnLabel()#"|"#oLastTrigger.HSSID();
|
||||
string sShortKey = oLastTrigger.HSSID();
|
||||
if((oLastTrigger.ValueType() == ivtInteger) && (oLastTrigger.ValueSubType() == istEnum)) {
|
||||
sLongKey = sLongKey#"="#web.webGetValueFromList( oLastTrigger.ValueList(), oSV.Value() );
|
||||
sShortKey = sShortKey#"="#web.webGetValueFromList( oLastTrigger.ValueList(), oSV.Value() );
|
||||
}
|
||||
sAlarmMessage = web.webKeyFromStringTable(sLongKey);
|
||||
if(!sAlarmMessage.Length()) {
|
||||
sAlarmMessage = web.webKeyFromStringTable(sShortKey);
|
||||
if(!sAlarmMessage.Length()) {
|
||||
sAlarmMessage = sShortKey;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (oSV.IsTypeOf(OT_ALARMDP)) {
|
||||
if ((oSV.Value() == false) || (oSV.Value() == "")) {
|
||||
sAlarmMessage = oSV.ValueName0();
|
||||
}
|
||||
else {
|
||||
sAlarmMessage = oSV.ValueName1();
|
||||
}
|
||||
}
|
||||
}
|
||||
if(sRooms == "") {
|
||||
sRooms = "none";
|
||||
}
|
||||
|
||||
Write(";" # sAlarmMessage # ";" # sRooms # ";" # sChannelName);
|
||||
WriteLine("");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Write(c);
|
||||
)
|
||||
}
|
||||
);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user