mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-04-29 05:24:10 +00:00
HMCCU: Support for multiple FHEM instances
git-svn-id: https://svn.fhem.de/fhem/trunk@16629 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
7c4473127b
commit
2ab1967bb3
@ -1,5 +1,6 @@
|
|||||||
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
|
# 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.
|
# Do not insert empty lines here, update check depends on it.
|
||||||
|
- change: 88_HMCCU: minor changes
|
||||||
- feature: 93_DbRep: new function dbValue, DbReadingsVal (blocking)
|
- feature: 93_DbRep: new function dbValue, DbReadingsVal (blocking)
|
||||||
- bugfix: 93_DbLog: 3.10.7, create addLog-event if reading was not found
|
- bugfix: 93_DbLog: 3.10.7, create addLog-event if reading was not found
|
||||||
- bugfix: 73_GardenaSmartBridge: add error trigger for notify sub
|
- bugfix: 73_GardenaSmartBridge: add error trigger for notify sub
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#
|
#
|
||||||
# $Id$
|
# $Id$
|
||||||
#
|
#
|
||||||
# Version 4.2.004
|
# Version 4.2.005
|
||||||
#
|
#
|
||||||
# Module for communication between FHEM and Homematic CCU2.
|
# Module for communication between FHEM and Homematic CCU2.
|
||||||
#
|
#
|
||||||
@ -105,7 +105,7 @@ my %HMCCU_CUST_CHN_DEFAULTS;
|
|||||||
my %HMCCU_CUST_DEV_DEFAULTS;
|
my %HMCCU_CUST_DEV_DEFAULTS;
|
||||||
|
|
||||||
# HMCCU version
|
# HMCCU version
|
||||||
my $HMCCU_VERSION = '4.2.004';
|
my $HMCCU_VERSION = '4.2.005';
|
||||||
|
|
||||||
# Default RPC port (BidCos-RF)
|
# Default RPC port (BidCos-RF)
|
||||||
my $HMCCU_RPC_PORT_DEFAULT = 2001;
|
my $HMCCU_RPC_PORT_DEFAULT = 2001;
|
||||||
@ -267,7 +267,6 @@ sub HMCCU_GetAddress ($$$$);
|
|||||||
sub HMCCU_IsDevAddr ($$);
|
sub HMCCU_IsDevAddr ($$);
|
||||||
sub HMCCU_IsChnAddr ($$);
|
sub HMCCU_IsChnAddr ($$);
|
||||||
sub HMCCU_SplitChnAddr ($);
|
sub HMCCU_SplitChnAddr ($);
|
||||||
sub HMCCU_GetCCUObjectAttribute ($$$);
|
|
||||||
sub HMCCU_FindClientDevices ($$$$);
|
sub HMCCU_FindClientDevices ($$$$);
|
||||||
sub HMCCU_GetRPCDevice ($$$);
|
sub HMCCU_GetRPCDevice ($$$);
|
||||||
sub HMCCU_FindIODevice ($);
|
sub HMCCU_FindIODevice ($);
|
||||||
@ -424,6 +423,7 @@ sub HMCCU_Define ($$)
|
|||||||
$hash->{version} = $HMCCU_VERSION;
|
$hash->{version} = $HMCCU_VERSION;
|
||||||
$hash->{ccutype} = 'CCU2';
|
$hash->{ccutype} = 'CCU2';
|
||||||
$hash->{RPCState} = "inactive";
|
$hash->{RPCState} = "inactive";
|
||||||
|
$hash->{NOTIFYDEV} = "global,TYPE=(HMCCU|HMCCUDEV|HMCCUCHN)";
|
||||||
|
|
||||||
Log3 $name, 1, "HMCCU: Device $name. Initialized version $HMCCU_VERSION";
|
Log3 $name, 1, "HMCCU: Device $name. Initialized version $HMCCU_VERSION";
|
||||||
my ($devcnt, $chncnt, $ifcount) = HMCCU_GetDeviceList ($hash);
|
my ($devcnt, $chncnt, $ifcount) = HMCCU_GetDeviceList ($hash);
|
||||||
@ -497,6 +497,9 @@ sub HMCCU_Attr ($@)
|
|||||||
if (HMCCU_IsRPCServerRunning ($hash, undef, undef));
|
if (HMCCU_IsRPCServerRunning ($hash, undef, undef));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ($attrval =~ /(extrpc|intrpc)/) {
|
||||||
|
HMCCU_Log ($hash, 1, "RPC server mode $1 is deprecated. Please use procrpc instead", 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
elsif ($attrname eq 'rpcdevice') {
|
elsif ($attrname eq 'rpcdevice') {
|
||||||
return "HMCCU: Can't find HMCCURPC device $attrval"
|
return "HMCCU: Can't find HMCCURPC device $attrval"
|
||||||
@ -1211,12 +1214,10 @@ sub HMCCU_Set ($@)
|
|||||||
|
|
||||||
return HMCCU_SetError ($hash, $usage) if (!defined ($program));
|
return HMCCU_SetError ($hash, $usage) if (!defined ($program));
|
||||||
|
|
||||||
my $url = qq(http://$host:8181/do.exe?r1=dom.GetObject("$program").ProgramExecute());
|
my $cmd = qq(dom.GetObject("$program").ProgramExecute());
|
||||||
$response = GetFileFromURL ($url, $ccureqtimeout);
|
my $value = HMCCU_HMCommand ($hash, $cmd, 0);
|
||||||
$response =~ m/<r1>(.*)<\/r1>/;
|
|
||||||
my $value = $1;
|
|
||||||
|
|
||||||
return HMCCU_SetState ($hash, "OK") if (defined ($value) && $value ne '' && $value ne 'null');
|
return HMCCU_SetState ($hash, "OK") if (defined ($value));
|
||||||
return HMCCU_SetError ($hash, "Program execution error");
|
return HMCCU_SetError ($hash, "Program execution error");
|
||||||
}
|
}
|
||||||
elsif ($opt eq 'hmscript') {
|
elsif ($opt eq 'hmscript') {
|
||||||
@ -1674,7 +1675,7 @@ sub HMCCU_Get ($@)
|
|||||||
my $ch = $defs{$dev};
|
my $ch = $defs{$dev};
|
||||||
my $ct = uc($ch->{ccutype});
|
my $ct = uc($ch->{ccutype});
|
||||||
my $fw = defined ($ch->{firmware}) ? $ch->{firmware} : 'N/A';
|
my $fw = defined ($ch->{firmware}) ? $ch->{firmware} : 'N/A';
|
||||||
next if (!exists ($hash->{hmccu}{type}{$ct}));
|
next if (!exists ($hash->{hmccu}{type}{$ct}) || $ct !~ /$dtexp/);
|
||||||
$result .= sprintf "%-25s %-20s %-7s <a href=\"http://www.eq-3.de/%s\">%-9s</a> %-10s\n",
|
$result .= sprintf "%-25s %-20s %-7s <a href=\"http://www.eq-3.de/%s\">%-9s</a> %-10s\n",
|
||||||
$ch->{NAME}, $ct, $fw, $hash->{hmccu}{type}{$ct}{download},
|
$ch->{NAME}, $ct, $fw, $hash->{hmccu}{type}{$ct}{download},
|
||||||
$hash->{hmccu}{type}{$ct}{firmware}, $hash->{hmccu}{type}{$ct}{date};
|
$hash->{hmccu}{type}{$ct}{firmware}, $hash->{hmccu}{type}{$ct}{date};
|
||||||
@ -4429,28 +4430,6 @@ sub HMCCU_SplitChnAddr ($)
|
|||||||
return ($dev, $chn);
|
return ($dev, $chn);
|
||||||
}
|
}
|
||||||
|
|
||||||
######################################################################
|
|
||||||
# Query object attribute from CCU. Attribute must be a valid method
|
|
||||||
# for specified object, i.e. Address()
|
|
||||||
######################################################################
|
|
||||||
|
|
||||||
sub HMCCU_GetCCUObjectAttribute ($$$)
|
|
||||||
{
|
|
||||||
my ($hash, $object, $attr) = @_;
|
|
||||||
my $name = $hash->{NAME};
|
|
||||||
my $ccureqtimeout = AttrVal ($name, "ccuReqTimeout", $HMCCU_TIMEOUT_REQUEST);
|
|
||||||
|
|
||||||
my $url = 'http://'.$hash->{host}.':8181/do.exe?r1=dom.GetObject("'.$object.'").'.$attr;
|
|
||||||
my $response = GetFileFromURL ($url, $ccureqtimeout);
|
|
||||||
if (defined ($response) && $response !~ /<r1>null</) {
|
|
||||||
if ($response =~ /<r1>(.+)<\/r1>/) {
|
|
||||||
return $1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return undef;
|
|
||||||
}
|
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
# Get list of client devices matching the specified criteria.
|
# Get list of client devices matching the specified criteria.
|
||||||
# If no criteria is specified all device names will be returned.
|
# If no criteria is specified all device names will be returned.
|
||||||
@ -5234,6 +5213,11 @@ sub HMCCU_HMScriptExt ($$$)
|
|||||||
my $host = $hash->{host};
|
my $host = $hash->{host};
|
||||||
my $code = $hmscript;
|
my $code = $hmscript;
|
||||||
my $scrname = '';
|
my $scrname = '';
|
||||||
|
|
||||||
|
if (!exists ($hash->{host})) {
|
||||||
|
Log3 $name, 2, "HMCCU: CCU host name not defined. Name=$name Type=".$hash->{TYPE};
|
||||||
|
return "ERROR: CCU host name not defined";
|
||||||
|
}
|
||||||
|
|
||||||
# Check for internal script
|
# Check for internal script
|
||||||
if ($hmscript =~ /^!(.*)$/) {
|
if ($hmscript =~ /^!(.*)$/) {
|
||||||
@ -5317,14 +5301,13 @@ sub HMCCU_GetDatapoint ($@)
|
|||||||
{
|
{
|
||||||
my ($hash, $param) = @_;
|
my ($hash, $param) = @_;
|
||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
my $type = $hash->{TYPE};
|
|
||||||
my $fnc = "GetDatapoint";
|
my $fnc = "GetDatapoint";
|
||||||
my $hmccu_hash;
|
my $hmccu_hash;
|
||||||
my $value = '';
|
my $value = '';
|
||||||
|
|
||||||
$hmccu_hash = HMCCU_GetHash ($hash);
|
$hmccu_hash = HMCCU_GetHash ($hash);
|
||||||
return (-3, $value) if (!defined ($hmccu_hash));
|
return (-3, $value) if (!defined ($hmccu_hash));
|
||||||
return (-4, $value) if ($type ne 'HMCCU' && $hash->{ccudevstate} eq 'deleted');
|
return (-4, $value) if ($hash->{TYPE} ne 'HMCCU' && $hash->{ccudevstate} eq 'deleted');
|
||||||
|
|
||||||
my $readingformat = HMCCU_GetAttrReadingFormat ($hash, $hmccu_hash);
|
my $readingformat = HMCCU_GetAttrReadingFormat ($hash, $hmccu_hash);
|
||||||
my ($statechn, $statedpt, $controlchn, $controldpt) = HMCCU_GetSpecialDatapoints (
|
my ($statechn, $statedpt, $controlchn, $controldpt) = HMCCU_GetSpecialDatapoints (
|
||||||
@ -5332,28 +5315,22 @@ sub HMCCU_GetDatapoint ($@)
|
|||||||
my $ccuget = HMCCU_GetAttribute ($hmccu_hash, $hash, 'ccuget', 'Value');
|
my $ccuget = HMCCU_GetAttribute ($hmccu_hash, $hash, 'ccuget', 'Value');
|
||||||
my $ccureqtimeout = AttrVal ($hmccu_hash->{NAME}, "ccuReqTimeout", $HMCCU_TIMEOUT_REQUEST);
|
my $ccureqtimeout = AttrVal ($hmccu_hash->{NAME}, "ccuReqTimeout", $HMCCU_TIMEOUT_REQUEST);
|
||||||
|
|
||||||
my $url = 'http://'.$hmccu_hash->{host}.':8181/do.exe?r1=dom.GetObject("';
|
my $cmd = '';
|
||||||
my ($int, $add, $chn, $dpt, $nam, $flags) = HMCCU_ParseObject ($hmccu_hash, $param,
|
my ($int, $add, $chn, $dpt, $nam, $flags) = HMCCU_ParseObject ($hmccu_hash, $param,
|
||||||
$HMCCU_FLAG_INTERFACE);
|
$HMCCU_FLAG_INTERFACE);
|
||||||
|
return (-1, $value) if ($flags != $HMCCU_FLAGS_IACD && $flags != $HMCCU_FLAGS_NCD);
|
||||||
|
|
||||||
if ($flags == $HMCCU_FLAGS_IACD) {
|
if ($flags == $HMCCU_FLAGS_IACD) {
|
||||||
$url .= $int.'.'.$add.':'.$chn.'.'.$dpt.'").'.$ccuget.'()';
|
$cmd = '(datapoints.Get("'.$int.'.'.$add.':'.$chn.'.'.$dpt.'")).'.$ccuget.'()';
|
||||||
}
|
}
|
||||||
elsif ($flags == $HMCCU_FLAGS_NCD) {
|
elsif ($flags == $HMCCU_FLAGS_NCD) {
|
||||||
$url .= $nam.'").DPByHssDP("'.$dpt.'").'.$ccuget.'()';
|
$cmd = '(dom.GetObject(ID_CHANNELS)).Get("'.$nam.'").DPByHssDP("'.$dpt.'").'.$ccuget.'()';
|
||||||
($add, $chn) = HMCCU_GetAddress ($hmccu_hash, $nam, '', '');
|
($add, $chn) = HMCCU_GetAddress ($hmccu_hash, $nam, '', '');
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
return (-1, $value);
|
|
||||||
}
|
|
||||||
|
|
||||||
HMCCU_Trace ($hash, 2, $fnc, "URL=$url, param=$param, ccuget=$ccuget");
|
HMCCU_Trace ($hash, 2, $fnc, "CMD=$cmd, param=$param, ccuget=$ccuget");
|
||||||
|
|
||||||
my $rawresponse = GetFileFromURL ($url, $ccureqtimeout);
|
$value = HMCCU_HMCommand ($hmccu_hash, $cmd, 1);
|
||||||
my $response = $rawresponse;
|
|
||||||
$response =~ m/<r1>(.*)<\/r1>/;
|
|
||||||
$value = $1;
|
|
||||||
|
|
||||||
HMCCU_Trace ($hash, 2, $fnc, "Response = ".$rawresponse);
|
|
||||||
|
|
||||||
if (defined ($value) && $value ne '' && $value ne 'null') {
|
if (defined ($value) && $value ne '' && $value ne 'null') {
|
||||||
$value = HMCCU_UpdateSingleDatapoint ($hash, $chn, $dpt, $value);
|
$value = HMCCU_UpdateSingleDatapoint ($hash, $chn, $dpt, $value);
|
||||||
@ -5361,7 +5338,7 @@ sub HMCCU_GetDatapoint ($@)
|
|||||||
return (1, $value);
|
return (1, $value);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Log3 $name, 1, "$type: Error URL = ".$url;
|
HMCCU_Log ($hash, 1, "Error CMD = $cmd", 0);
|
||||||
return (-2, '');
|
return (-2, '');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5407,7 +5384,7 @@ sub HMCCU_SetDatapoint ($$$)
|
|||||||
$param = $1;
|
$param = $1;
|
||||||
}
|
}
|
||||||
|
|
||||||
my $cmd = 'dom.GetObject("';
|
my $cmd = '';
|
||||||
my ($int, $add, $chn, $dpt, $nam, $flags) = HMCCU_ParseObject ($hmccu_hash, $param,
|
my ($int, $add, $chn, $dpt, $nam, $flags) = HMCCU_ParseObject ($hmccu_hash, $param,
|
||||||
$HMCCU_FLAG_INTERFACE);
|
$HMCCU_FLAG_INTERFACE);
|
||||||
return -1 if ($flags != $HMCCU_FLAGS_IACD && $flags != $HMCCU_FLAGS_NCD);
|
return -1 if ($flags != $HMCCU_FLAGS_IACD && $flags != $HMCCU_FLAGS_NCD);
|
||||||
@ -5425,11 +5402,11 @@ sub HMCCU_SetDatapoint ($$$)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($flags == $HMCCU_FLAGS_IACD) {
|
if ($flags == $HMCCU_FLAGS_IACD) {
|
||||||
$cmd .= $int.'.'.$add.':'.$chn.'.'.$dpt.'").State('.$value.')';
|
$cmd = '(datapoints.Get("'.$int.'.'.$add.':'.$chn.'.'.$dpt.'")).State('.$value.')';
|
||||||
$nam = HMCCU_GetChannelName ($hmccu_hash, $add.":".$chn, '');
|
$nam = HMCCU_GetChannelName ($hmccu_hash, $add.":".$chn, '');
|
||||||
}
|
}
|
||||||
elsif ($flags == $HMCCU_FLAGS_NCD) {
|
elsif ($flags == $HMCCU_FLAGS_NCD) {
|
||||||
$cmd .= $nam.'").DPByHssDP("'.$dpt.'").State('.$value.')';
|
$cmd = '(dom.GetObject(ID_CHANNELS)).Get("'.$nam.'").DPByHssDP("'.$dpt.'").State('.$value.')';
|
||||||
($add, $chn) = HMCCU_GetAddress ($hmccu_hash, $nam, '', '');
|
($add, $chn) = HMCCU_GetAddress ($hmccu_hash, $nam, '', '');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5581,12 +5558,9 @@ sub HMCCU_SetVariable ($$$$$)
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (!defined ($vartype)) {
|
if (!defined ($vartype)) {
|
||||||
my $url = 'http://'.$hash->{host}.':8181/do.exe?r1=dom.GetObject("'.$varname.
|
my $cmd = qq(dom.GetObject("$varname").State("$value"));
|
||||||
'").State("'.$value.'")';
|
my $response = HMCCU_HMCommand ($hash, $cmd, 1);
|
||||||
|
return HMCCU_Log ($hash, 1, "CMD=$cmd", -2) if (!defined ($response));
|
||||||
my $response = GetFileFromURL ($url, $ccureqtimeout);
|
|
||||||
return HMCCU_Log ($hash, 1, "URL=$url", -2)
|
|
||||||
if (!defined ($response) || $response =~ /<r1>null</);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return -18 if (!exists ($varfnc{$vartype}));
|
return -18 if (!exists ($varfnc{$vartype}));
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#
|
#
|
||||||
# $Id$
|
# $Id$
|
||||||
#
|
#
|
||||||
# Version 1.0.002
|
# Version 1.0.003
|
||||||
#
|
#
|
||||||
# Subprocess based RPC Server module for HMCCU.
|
# Subprocess based RPC Server module for HMCCU.
|
||||||
#
|
#
|
||||||
@ -35,7 +35,7 @@ use SetExtensions;
|
|||||||
######################################################################
|
######################################################################
|
||||||
|
|
||||||
# HMCCURPC version
|
# HMCCURPC version
|
||||||
my $HMCCURPCPROC_VERSION = '1.0.002';
|
my $HMCCURPCPROC_VERSION = '1.0.003';
|
||||||
|
|
||||||
# Maximum number of events processed per call of Read()
|
# Maximum number of events processed per call of Read()
|
||||||
my $HMCCURPCPROC_MAX_EVENTS = 100;
|
my $HMCCURPCPROC_MAX_EVENTS = 100;
|
||||||
@ -82,7 +82,7 @@ my $HMCCURPCPROC_INIT_INTERVAL2 = 30;
|
|||||||
# Delay for RPC server functionality check after start
|
# Delay for RPC server functionality check after start
|
||||||
my $HMCCURPCPROC_INIT_INTERVAL3 = 25;
|
my $HMCCURPCPROC_INIT_INTERVAL3 = 25;
|
||||||
|
|
||||||
# Data types
|
# BinRPC data types
|
||||||
my $BINRPC_INTEGER = 1;
|
my $BINRPC_INTEGER = 1;
|
||||||
my $BINRPC_BOOL = 2;
|
my $BINRPC_BOOL = 2;
|
||||||
my $BINRPC_STRING = 3;
|
my $BINRPC_STRING = 3;
|
||||||
@ -91,7 +91,7 @@ my $BINRPC_BASE64 = 17;
|
|||||||
my $BINRPC_ARRAY = 256;
|
my $BINRPC_ARRAY = 256;
|
||||||
my $BINRPC_STRUCT = 257;
|
my $BINRPC_STRUCT = 257;
|
||||||
|
|
||||||
# Message types
|
# BinRPC message types
|
||||||
my $BINRPC_REQUEST = 0x42696E00;
|
my $BINRPC_REQUEST = 0x42696E00;
|
||||||
my $BINRPC_RESPONSE = 0x42696E01;
|
my $BINRPC_RESPONSE = 0x42696E01;
|
||||||
my $BINRPC_REQUEST_HEADER = 0x42696E40;
|
my $BINRPC_REQUEST_HEADER = 0x42696E40;
|
||||||
@ -116,6 +116,7 @@ sub HMCCURPCPROC_SetState ($$);
|
|||||||
sub HMCCURPCPROC_ProcessEvent ($$);
|
sub HMCCURPCPROC_ProcessEvent ($$);
|
||||||
|
|
||||||
# RPC server functions
|
# RPC server functions
|
||||||
|
sub HMCCURPCPROC_GetRPCServerID ($$);
|
||||||
sub HMCCURPCPROC_RegisterCallback ($$);
|
sub HMCCURPCPROC_RegisterCallback ($$);
|
||||||
sub HMCCURPCPROC_DeRegisterCallback ($$);
|
sub HMCCURPCPROC_DeRegisterCallback ($$);
|
||||||
sub HMCCURPCPROC_InitRPCServer ($$$$);
|
sub HMCCURPCPROC_InitRPCServer ($$$$);
|
||||||
@ -220,7 +221,7 @@ sub HMCCURPCPROC_Define ($$)
|
|||||||
my $ioname = $h->{iodev};
|
my $ioname = $h->{iodev};
|
||||||
return $usage if (scalar (@$a) < 3);
|
return $usage if (scalar (@$a) < 3);
|
||||||
return "HMCCU I/O device $ioname not found" if (!exists ($defs{$ioname}));
|
return "HMCCU I/O device $ioname not found" if (!exists ($defs{$ioname}));
|
||||||
return "Device $ioname is no HMCCU device" if ($defs{$ioname}->{TYPE} ne 'HMCCU');
|
return "Device $ioname is not a HMCCU device" if ($defs{$ioname}->{TYPE} ne 'HMCCU');
|
||||||
$hmccu_hash = $defs{$ioname};
|
$hmccu_hash = $defs{$ioname};
|
||||||
$hash->{host} = $hmccu_hash->{host};
|
$hash->{host} = $hmccu_hash->{host};
|
||||||
$iface = $$a[2];
|
$iface = $$a[2];
|
||||||
@ -229,19 +230,19 @@ sub HMCCURPCPROC_Define ($$)
|
|||||||
return $usage if (scalar (@$a) < 4);
|
return $usage if (scalar (@$a) < 4);
|
||||||
$hash->{host} = $$a[2];
|
$hash->{host} = $$a[2];
|
||||||
$iface = $$a[3];
|
$iface = $$a[3];
|
||||||
}
|
|
||||||
|
# Find IO device
|
||||||
# Find IO device
|
for my $d (keys %defs) {
|
||||||
for my $d (keys %defs) {
|
my $dh = $defs{$d};
|
||||||
my $dh = $defs{$d};
|
next if (!exists ($dh->{TYPE}) || !exists ($dh->{NAME}));
|
||||||
next if (!exists ($dh->{TYPE}) || !exists ($dh->{NAME}));
|
if ($dh->{TYPE} eq 'HMCCU' && $dh->{host} eq $hash->{host}) {
|
||||||
if ($dh->{TYPE} eq 'HMCCU' && $dh->{host} eq $hash->{host}) {
|
$hmccu_hash = $dh;
|
||||||
$hmccu_hash = $dh;
|
last;
|
||||||
last;
|
}
|
||||||
}
|
}
|
||||||
|
return "Can't find HMCCU I/O device" if (!defined ($hmccu_hash));
|
||||||
}
|
}
|
||||||
return "Can't find HMCCU I/O device" if (!defined ($hmccu_hash));
|
|
||||||
|
|
||||||
# Check if interface is valid
|
# Check if interface is valid
|
||||||
my $ifname = HMCCU_GetRPCServerInfo ($hmccu_hash, $iface, 'name');
|
my $ifname = HMCCU_GetRPCServerInfo ($hmccu_hash, $iface, 'name');
|
||||||
my $ifport = HMCCU_GetRPCServerInfo ($hmccu_hash, $iface, 'port');
|
my $ifport = HMCCU_GetRPCServerInfo ($hmccu_hash, $iface, 'port');
|
||||||
@ -423,7 +424,8 @@ sub HMCCURPCPROC_Get ($@)
|
|||||||
|
|
||||||
if ($opt eq 'rpcevents') {
|
if ($opt eq 'rpcevents') {
|
||||||
my @eventtypes = ("EV", "ND", "DD", "RD", "RA", "UD", "IN", "EX", "SL", "TO");
|
my @eventtypes = ("EV", "ND", "DD", "RD", "RA", "UD", "IN", "EX", "SL", "TO");
|
||||||
my $clkey = 'CB'.$hash->{rpcport};
|
my $clkey = 'CB'.$hash->{rpcport}.$hash->{rpcid};
|
||||||
|
|
||||||
$result = "Event statistics for server $clkey\n";
|
$result = "Event statistics for server $clkey\n";
|
||||||
$result .= "Average event delay = ".$hash->{hmccu}{rpc}{avgdelay}."\n"
|
$result .= "Average event delay = ".$hash->{hmccu}{rpc}{avgdelay}."\n"
|
||||||
if (defined ($hash->{hmccu}{rpc}{avgdelay}));
|
if (defined ($hash->{hmccu}{rpc}{avgdelay}));
|
||||||
@ -440,11 +442,11 @@ sub HMCCURPCPROC_Get ($@)
|
|||||||
return $result eq '' ? "No event statistics found" : $result;
|
return $result eq '' ? "No event statistics found" : $result;
|
||||||
}
|
}
|
||||||
elsif ($opt eq 'rpcstate') {
|
elsif ($opt eq 'rpcstate') {
|
||||||
my $clkey = 'CB'.$hash->{rpcport};
|
my $clkey = 'CB'.$hash->{rpcport}.$hash->{rpcid};
|
||||||
$result = "ID RPC-Process State \n";
|
$result = "PID RPC-Process State \n";
|
||||||
$result .= "-----------------------\n";
|
$result .= "--------------------------\n";
|
||||||
my $sid = defined ($hash->{hmccu}{rpc}{pid}) ? sprintf ("%2d", $hash->{hmccu}{rpc}{pid}) : "N/A";
|
my $sid = defined ($hash->{hmccu}{rpc}{pid}) ? sprintf ("%5d", $hash->{hmccu}{rpc}{pid}) : "N/A ";
|
||||||
my $sname = sprintf ("%-6s", $clkey);
|
my $sname = sprintf ("%-10s", $clkey);
|
||||||
$result .= $sid." ".$sname." ".$hash->{hmccu}{rpc}{state}."\n";
|
$result .= $sid." ".$sname." ".$hash->{hmccu}{rpc}{state}."\n";
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
@ -623,6 +625,7 @@ sub HMCCURPCPROC_ResetRPCState ($)
|
|||||||
|
|
||||||
$hash->{RPCPID} = "0";
|
$hash->{RPCPID} = "0";
|
||||||
$hash->{hmccu}{rpc}{pid} = undef;
|
$hash->{hmccu}{rpc}{pid} = undef;
|
||||||
|
$hash->{hmccu}{rpc}{clkey} = undef;
|
||||||
$hash->{hmccu}{evtime} = 0;
|
$hash->{hmccu}{evtime} = 0;
|
||||||
$hash->{hmccu}{rpcstarttime} = 0;
|
$hash->{hmccu}{rpcstarttime} = 0;
|
||||||
|
|
||||||
@ -648,7 +651,7 @@ sub HMCCURPCPROC_ProcessEvent ($$)
|
|||||||
{
|
{
|
||||||
my ($hash, $event) = @_;
|
my ($hash, $event) = @_;
|
||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
my $rpcname = 'CB'.$hash->{rpcport};
|
my $rpcname = 'CB'.$hash->{rpcport}.$hash->{rpcid};
|
||||||
my $rh = \%{$hash->{hmccu}{rpc}}; # Just for code simplification
|
my $rh = \%{$hash->{hmccu}{rpc}}; # Just for code simplification
|
||||||
my $hmccu_hash = $hash->{IODev};
|
my $hmccu_hash = $hash->{IODev};
|
||||||
|
|
||||||
@ -886,7 +889,7 @@ sub HMCCURPCPROC_RegisterCallback ($$)
|
|||||||
my $port = $hash->{rpcport};
|
my $port = $hash->{rpcport};
|
||||||
my $serveraddr = $hash->{host};
|
my $serveraddr = $hash->{host};
|
||||||
my $localaddr = $hash->{hmccu}{localaddr};
|
my $localaddr = $hash->{hmccu}{localaddr};
|
||||||
my $clkey = 'CB'.$port;
|
my $clkey = 'CB'.$port.$hash->{rpcid};
|
||||||
|
|
||||||
return (0, "RPC server $clkey not in state working")
|
return (0, "RPC server $clkey not in state working")
|
||||||
if ($hash->{hmccu}{rpc}{state} ne 'working' && $force == 0);
|
if ($hash->{hmccu}{rpc}{state} ne 'working' && $force == 0);
|
||||||
@ -932,7 +935,7 @@ sub HMCCURPCPROC_DeRegisterCallback ($$)
|
|||||||
my $hmccu_hash = $hash->{IODev};
|
my $hmccu_hash = $hash->{IODev};
|
||||||
|
|
||||||
my $port = $hash->{rpcport};
|
my $port = $hash->{rpcport};
|
||||||
my $clkey = 'CB'.$port;
|
my $clkey = 'CB'.$port.$hash->{rpcid};
|
||||||
my $localaddr = $hash->{hmccu}{localaddr};
|
my $localaddr = $hash->{hmccu}{localaddr};
|
||||||
my $cburl = '';
|
my $cburl = '';
|
||||||
my $clurl = '';
|
my $clurl = '';
|
||||||
@ -978,8 +981,7 @@ sub HMCCURPCPROC_DeRegisterCallback ($$)
|
|||||||
|
|
||||||
sub HMCCURPCPROC_InitRPCServer ($$$$)
|
sub HMCCURPCPROC_InitRPCServer ($$$$)
|
||||||
{
|
{
|
||||||
my ($name, $serverport, $callbackport, $prot) = @_;
|
my ($name, $clkey, $callbackport, $prot) = @_;
|
||||||
my $clkey = 'CB'.$serverport;
|
|
||||||
my $server;
|
my $server;
|
||||||
|
|
||||||
# Create binary RPC server
|
# Create binary RPC server
|
||||||
@ -1094,7 +1096,23 @@ sub HMCCURPCPROC_StartRPCServer ($)
|
|||||||
my $rpcport = $hash->{rpcport};
|
my $rpcport = $hash->{rpcport};
|
||||||
my $serveraddr = HMCCU_GetRPCServerInfo ($hmccu_hash, $rpcport, 'host');
|
my $serveraddr = HMCCU_GetRPCServerInfo ($hmccu_hash, $rpcport, 'host');
|
||||||
my $interface = HMCCU_GetRPCServerInfo ($hmccu_hash, $rpcport, 'name');
|
my $interface = HMCCU_GetRPCServerInfo ($hmccu_hash, $rpcport, 'name');
|
||||||
|
|
||||||
|
# Detect local IP address
|
||||||
|
if ($localaddr eq '') {
|
||||||
|
my $socket = IO::Socket::INET->new (PeerAddr => $serveraddr, PeerPort => $rpcport);
|
||||||
|
return (0, "Can't connect to CCU port $rpcport") if (!$socket);
|
||||||
|
$localaddr = $socket->sockhost ();
|
||||||
|
close ($socket);
|
||||||
|
}
|
||||||
|
$hash->{hmccu}{localaddr} = $localaddr;
|
||||||
|
|
||||||
|
# Get unique ID for RPC server: last segment of local IP address followed by 2 random digits
|
||||||
|
my @ipseg = split (/\./, $localaddr);
|
||||||
|
return (0, "Invalid local IP address $localaddr") if (scalar (@ipseg) != 4);
|
||||||
|
my $base = (time() % 10)+1;
|
||||||
|
$hash->{rpcid} = sprintf ("%03d", $ipseg[3]) . join '', map int rand ($base), 1..2;
|
||||||
|
my $clkey = 'CB'.$rpcport.$hash->{rpcid};
|
||||||
|
|
||||||
# Store parameters for child process
|
# Store parameters for child process
|
||||||
$procpar{socktimeout} = AttrVal ($name, 'rpcWriteTimeout', $HMCCURPCPROC_TIMEOUT_WRITE);
|
$procpar{socktimeout} = AttrVal ($name, 'rpcWriteTimeout', $HMCCURPCPROC_TIMEOUT_WRITE);
|
||||||
$procpar{conntimeout} = AttrVal ($name, 'rpcConnTimeout', $HMCCURPCPROC_TIMEOUT_CONNECTION);
|
$procpar{conntimeout} = AttrVal ($name, 'rpcConnTimeout', $HMCCURPCPROC_TIMEOUT_CONNECTION);
|
||||||
@ -1110,18 +1128,10 @@ sub HMCCURPCPROC_StartRPCServer ($)
|
|||||||
$procpar{flags} = HMCCU_GetRPCServerInfo ($hmccu_hash, $rpcport, 'flags');
|
$procpar{flags} = HMCCU_GetRPCServerInfo ($hmccu_hash, $rpcport, 'flags');
|
||||||
$procpar{type} = HMCCU_GetRPCServerInfo ($hmccu_hash, $rpcport, 'type');
|
$procpar{type} = HMCCU_GetRPCServerInfo ($hmccu_hash, $rpcport, 'type');
|
||||||
$procpar{name} = $name;
|
$procpar{name} = $name;
|
||||||
|
$procpar{clkey} = $clkey;
|
||||||
|
|
||||||
my @eventtypes = ("EV", "ND", "DD", "RD", "RA", "UD", "IN", "EX", "SL", "TO");
|
my @eventtypes = ("EV", "ND", "DD", "RD", "RA", "UD", "IN", "EX", "SL", "TO");
|
||||||
|
|
||||||
# Detect local IP address
|
|
||||||
if ($localaddr eq '') {
|
|
||||||
my $socket = IO::Socket::INET->new (PeerAddr => $serveraddr, PeerPort => $rpcport);
|
|
||||||
return (0, "Can't connect to CCU port $rpcport") if (!$socket);
|
|
||||||
$localaddr = $socket->sockhost ();
|
|
||||||
close ($socket);
|
|
||||||
}
|
|
||||||
$hash->{hmccu}{localaddr} = $localaddr;
|
|
||||||
|
|
||||||
# Reset state of server processes
|
# Reset state of server processes
|
||||||
$hash->{hmccu}{rpc}{state} = 'inactive';
|
$hash->{hmccu}{rpc}{state} = 'inactive';
|
||||||
|
|
||||||
@ -1142,7 +1152,6 @@ sub HMCCURPCPROC_StartRPCServer ($)
|
|||||||
# Initialize RPC server
|
# Initialize RPC server
|
||||||
my $err = '';
|
my $err = '';
|
||||||
my %srvprocpar;
|
my %srvprocpar;
|
||||||
my $clkey = 'CB'.$rpcport;
|
|
||||||
my $callbackport = $rpcserverport+$rpcport+($ccunum*10);
|
my $callbackport = $rpcserverport+$rpcport+($ccunum*10);
|
||||||
|
|
||||||
# Start RPC server process
|
# Start RPC server process
|
||||||
@ -1166,6 +1175,7 @@ sub HMCCURPCPROC_StartRPCServer ($)
|
|||||||
Log3 $name, 2, "HMCCURPCPROC: [$name] RPC server process started for interface $interface with PID=$rpcpid";
|
Log3 $name, 2, "HMCCURPCPROC: [$name] RPC server process started for interface $interface with PID=$rpcpid";
|
||||||
|
|
||||||
# Store process parameters
|
# Store process parameters
|
||||||
|
$hash->{hmccu}{rpc}{clkey} = $clkey;
|
||||||
$hash->{hmccu}{rpc}{cbport} = $callbackport;
|
$hash->{hmccu}{rpc}{cbport} = $callbackport;
|
||||||
$hash->{hmccu}{rpc}{pid} = $rpcpid;
|
$hash->{hmccu}{rpc}{pid} = $rpcpid;
|
||||||
$hash->{hmccu}{rpc}{state} = 'initialized';
|
$hash->{hmccu}{rpc}{state} = 'initialized';
|
||||||
@ -1180,12 +1190,11 @@ sub HMCCURPCPROC_StartRPCServer ($)
|
|||||||
$hash->{RPCPID} = $rpcpid;
|
$hash->{RPCPID} = $rpcpid;
|
||||||
|
|
||||||
# Trigger Timer function for checking successful RPC start
|
# Trigger Timer function for checking successful RPC start
|
||||||
# Timer will be removed if event 'IN' is reveived
|
# Timer will be removed before execution if event 'IN' is reveived
|
||||||
InternalTimer (gettimeofday()+$HMCCURPCPROC_INIT_INTERVAL3, "HMCCURPCPROC_IsRPCServerRunning",
|
InternalTimer (gettimeofday()+$HMCCURPCPROC_INIT_INTERVAL3, "HMCCURPCPROC_IsRPCServerRunning",
|
||||||
$hash, 0);
|
$hash, 0);
|
||||||
|
|
||||||
HMCCURPCPROC_SetRPCState ($hash, "starting", "RPC server starting", 1);
|
HMCCURPCPROC_SetRPCState ($hash, "starting", "RPC server starting", 1);
|
||||||
|
|
||||||
DoTrigger ($name, "RPC server starting");
|
DoTrigger ($name, "RPC server starting");
|
||||||
|
|
||||||
return (1, undef);
|
return (1, undef);
|
||||||
@ -1202,7 +1211,7 @@ sub HMCCURPCPROC_RPCServerStarted ($)
|
|||||||
my ($hash) = @_;
|
my ($hash) = @_;
|
||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
my $hmccu_hash = $hash->{IODev};
|
my $hmccu_hash = $hash->{IODev};
|
||||||
my $clkey = 'CB'.$hash->{rpcport};
|
my $clkey = 'CB'.$hash->{rpcport}.$hash->{rpcid};
|
||||||
my $ifname = $hash->{rpcinterface};
|
my $ifname = $hash->{rpcinterface};
|
||||||
|
|
||||||
# Check if RPC servers are running. Set overall status
|
# Check if RPC servers are running. Set overall status
|
||||||
@ -1231,7 +1240,7 @@ sub HMCCURPCPROC_RPCServerStopped ($)
|
|||||||
{
|
{
|
||||||
my ($hash) = @_;
|
my ($hash) = @_;
|
||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
my $clkey = 'CB'.$hash->{rpcport};
|
my $clkey = 'CB'.$hash->{rpcport}.$hash->{rpcid};
|
||||||
|
|
||||||
HMCCURPCPROC_CleanupProcess ($hash);
|
HMCCURPCPROC_CleanupProcess ($hash);
|
||||||
HMCCURPCPROC_CleanupIO ($hash);
|
HMCCURPCPROC_CleanupIO ($hash);
|
||||||
@ -1279,7 +1288,7 @@ sub HMCCURPCPROC_TerminateProcess ($)
|
|||||||
{
|
{
|
||||||
my ($hash) = @_;
|
my ($hash) = @_;
|
||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
my $clkey = 'CB'.$hash->{rpcport};
|
my $clkey = 'CB'.$hash->{rpcport}.$hash->{rpcid};
|
||||||
|
|
||||||
# return 0 if ($hash->{hmccu}{rpc}{state} eq 'inactive');
|
# return 0 if ($hash->{hmccu}{rpc}{state} eq 'inactive');
|
||||||
|
|
||||||
@ -1304,7 +1313,7 @@ sub HMCCURPCPROC_CleanupProcess ($)
|
|||||||
{
|
{
|
||||||
my ($hash) = @_;
|
my ($hash) = @_;
|
||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
my $clkey = 'CB'.$hash->{rpcport};
|
my $clkey = 'CB'.$hash->{rpcport}.$hash->{rpcid};
|
||||||
|
|
||||||
# return 1 if ($hash->{hmccu}{rpc}{state} eq 'inactive');
|
# return 1 if ($hash->{hmccu}{rpc}{state} eq 'inactive');
|
||||||
|
|
||||||
@ -1342,7 +1351,7 @@ sub HMCCURPCPROC_CleanupProcess ($)
|
|||||||
sub HMCCURPCPROC_CheckProcessState ($$)
|
sub HMCCURPCPROC_CheckProcessState ($$)
|
||||||
{
|
{
|
||||||
my ($hash, $state) = @_;
|
my ($hash, $state) = @_;
|
||||||
my $prcname = 'CB'.$hash->{rpcport};
|
my $prcname = 'CB'.$hash->{rpcport}.$hash->{rpcid};
|
||||||
|
|
||||||
my $pstate = $hash->{hmccu}{rpc}{state};
|
my $pstate = $hash->{hmccu}{rpc}{state};
|
||||||
if ($state eq 'running' || $state eq '.*') {
|
if ($state eq 'running' || $state eq '.*') {
|
||||||
@ -1404,7 +1413,7 @@ sub HMCCURPCPROC_StopRPCServer ($)
|
|||||||
{
|
{
|
||||||
my ($hash) = @_;
|
my ($hash) = @_;
|
||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
my $clkey = 'CB'.$hash->{rpcport};
|
my $clkey = 'CB'.$hash->{rpcport}.$hash->{rpcid};
|
||||||
|
|
||||||
if (HMCCURPCPROC_CheckProcessState ($hash, 'running')) {
|
if (HMCCURPCPROC_CheckProcessState ($hash, 'running')) {
|
||||||
Log3 $name, 1, "HMCCURPCPROC: [$name] Stopping RPC server $clkey";
|
Log3 $name, 1, "HMCCURPCPROC: [$name] Stopping RPC server $clkey";
|
||||||
@ -1435,6 +1444,7 @@ sub HMCCURPCPROC_StopRPCServer ($)
|
|||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
# Send RPC request to CCU.
|
# Send RPC request to CCU.
|
||||||
|
# Supports XML and BINRPC requests.
|
||||||
# Return response or undef on error.
|
# Return response or undef on error.
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|
||||||
@ -1572,18 +1582,18 @@ sub HMCCURPCPROC_HandleConnection ($$$$)
|
|||||||
my $socktimeout = $procpar->{socktimeout};
|
my $socktimeout = $procpar->{socktimeout};
|
||||||
my $maxsnd = $procpar->{queuesend};
|
my $maxsnd = $procpar->{queuesend};
|
||||||
my $maxioerrors = $procpar->{maxioerrors};
|
my $maxioerrors = $procpar->{maxioerrors};
|
||||||
|
my $clkey = $procpar->{clkey};
|
||||||
|
|
||||||
my $ioerrors = 0;
|
my $ioerrors = 0;
|
||||||
my $sioerrors = 0;
|
my $sioerrors = 0;
|
||||||
my $run = 1;
|
my $run = 1;
|
||||||
my $pid = $$;
|
my $pid = $$;
|
||||||
my $clkey = 'CB'.$port;
|
|
||||||
|
|
||||||
my @eventtypes = ("EV", "ND", "DD", "RD", "RA", "UD", "IN", "EX", "SL", "TO");
|
my @eventtypes = ("EV", "ND", "DD", "RD", "RA", "UD", "IN", "EX", "SL", "TO");
|
||||||
|
|
||||||
# Initialize RPC server
|
# Initialize RPC server
|
||||||
Log3 $name, 2, "CCURPC: [$name] Initializing RPC server $clkey for interface $iface";
|
Log3 $name, 2, "CCURPC: [$name] Initializing RPC server $clkey for interface $iface";
|
||||||
my $rpcsrv = HMCCURPCPROC_InitRPCServer ($name, $port, $callbackport, $prot);
|
my $rpcsrv = HMCCURPCPROC_InitRPCServer ($name, $clkey, $callbackport, $prot);
|
||||||
if (!defined ($rpcsrv)) {
|
if (!defined ($rpcsrv)) {
|
||||||
Log3 $name, 1, "CCURPC: [$name] Can't initialize RPC server $clkey for interface $iface";
|
Log3 $name, 1, "CCURPC: [$name] Can't initialize RPC server $clkey for interface $iface";
|
||||||
return;
|
return;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user