mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-03-09 20:57:11 +00:00
HMCCU: New features and bug fixes
git-svn-id: https://svn.fhem.de/fhem/trunk@20016 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
feb9116452
commit
44f26f7800
@ -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.
|
||||
- change: 88_HMCCU: New features and bug fixes
|
||||
- feature: 36_WMBUS: initial support for mode 7 encryption (mostly untested)
|
||||
Digest::CMAC must be installed
|
||||
- feature: 72_XiaomiDevice: added S1 vacuum states
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -4,7 +4,7 @@
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# Version 4.3.006
|
||||
# Version 4.3.007
|
||||
#
|
||||
# (c) 2019 zap (zap01 <at> t-online <dot> de)
|
||||
#
|
||||
@ -205,7 +205,10 @@ sub HMCCUCHN_Set ($@)
|
||||
my $name = shift @$a;
|
||||
my $opt = shift @$a;
|
||||
|
||||
my $rocmds = "clear config defaults:noArg";
|
||||
return "No set command specified" if (!defined ($opt));
|
||||
|
||||
my $rocmds = "clear defaults:noArg";
|
||||
my $rwcmds = "clear config control datapoint defaults:noArg devstate rpcParameter";
|
||||
|
||||
# Get I/O device, check device state
|
||||
return undef if (!defined ($hash->{ccudevstate}) || $hash->{ccudevstate} eq 'pending' ||
|
||||
@ -415,7 +418,20 @@ sub HMCCUCHN_Set ($@)
|
||||
if (defined ($par) && $par eq 'device') {
|
||||
($ccuobj, undef) = HMCCU_SplitChnAddr ($ccuaddr);
|
||||
}
|
||||
my $rc = HMCCU_RPCSetConfig ($hash, $ccuobj, $h);
|
||||
my ($rc, $res) = HMCCU_RPCRequest ($hash, "putParamset", $ccuobj, "MASTER", $h);
|
||||
# my $rc = HMCCU_RPCSetConfig ($hash, $ccuobj, $h);
|
||||
return HMCCU_SetError ($hash, $rc) if ($rc < 0);
|
||||
return HMCCU_SetState ($hash, "OK");
|
||||
}
|
||||
elsif ($opt eq 'rpcParameter') {
|
||||
return HMCCU_SetError ($hash, "Usage: set $name rpcParameter [MASTER|VALUES] {parameter}={value} [...]")
|
||||
if ((scalar keys %{$h}) < 1);
|
||||
my $key = shift @$a;
|
||||
$key = 'VALUES' if (!defined ($key));
|
||||
return HMCCU_SetError ($hash, "Key must be MASTER or VALUES")
|
||||
if ($key ne 'MASTER' && $key ne 'VALUES');
|
||||
|
||||
my ($rc, $res) = HMCCU_RPCRequest ($hash, "putParamset", $ccuaddr, $key, $h);
|
||||
return HMCCU_SetError ($hash, $rc) if ($rc < 0);
|
||||
return HMCCU_SetState ($hash, "OK");
|
||||
}
|
||||
@ -425,14 +441,13 @@ sub HMCCUCHN_Set ($@)
|
||||
return HMCCU_SetState ($hash, "OK");
|
||||
}
|
||||
else {
|
||||
return "HMCCUCHN: Unknown argument $opt, choose one of ".$rocmds
|
||||
return "HMCCUCHN: Unknown argument $opt, choose one of $rocmds"
|
||||
if ($hash->{statevals} eq 'readonly');
|
||||
|
||||
my $retmsg = "HMCCUCHN: Unknown argument $opt, choose one of clear config control datapoint defaults:noArg devstate";
|
||||
my $retmsg = "HMCCUCHN: Unknown argument $opt, choose one of $rwcmds";
|
||||
if ($hash->{statevals} ne '') {
|
||||
my @cmdlist = split /\|/,$hash->{statevals};
|
||||
shift @cmdlist;
|
||||
$retmsg .= ':'.join(',',@cmdlist) if (@cmdlist > 0);
|
||||
$retmsg .= ':'.join(',',@cmdlist) if (scalar(@cmdlist) > 0);
|
||||
foreach my $sv (@cmdlist) {
|
||||
$retmsg .= ' '.$sv.':noArg';
|
||||
}
|
||||
@ -457,6 +472,8 @@ sub HMCCUCHN_Get ($@)
|
||||
my $name = shift @$a;
|
||||
my $opt = shift @$a;
|
||||
|
||||
return "No get command specified" if (!defined ($opt));
|
||||
|
||||
return undef if (!defined ($hash->{ccudevstate}) || $hash->{ccudevstate} eq 'pending' ||
|
||||
!defined ($hash->{IODev}));
|
||||
|
||||
@ -533,7 +550,8 @@ sub HMCCUCHN_Get ($@)
|
||||
}
|
||||
$par = '.*' if (!defined ($par));
|
||||
|
||||
my ($rc, $res) = HMCCU_RPCGetConfig ($hash, $ccuobj, "getParamset", $par);
|
||||
my ($rc, $res) = HMCCU_RPCRequest ($hash, "getParamset", $ccuobj, "MASTER", undef, $par);
|
||||
# my ($rc, $res) = HMCCU_RPCGetConfig ($hash, $ccuobj, "getParamset", $par);
|
||||
return HMCCU_SetError ($hash, $rc, $res) if ($rc < 0);
|
||||
return $ccureadings ? undef : $res;
|
||||
}
|
||||
@ -548,7 +566,8 @@ sub HMCCUCHN_Get ($@)
|
||||
}
|
||||
$par = '.*' if (!defined ($par));
|
||||
|
||||
my ($rc, $res) = HMCCU_RPCGetConfig ($hash, $ccuobj, "listParamset", $par);
|
||||
my ($rc, $res) = HMCCU_RPCRequest ($hash, "listParamset", $ccuobj, "MASTER", undef, $par);
|
||||
# my ($rc, $res) = HMCCU_RPCGetConfig ($hash, $ccuobj, "listParamset", $par);
|
||||
return HMCCU_SetError ($hash, $rc, $res) if ($rc < 0);
|
||||
return $res;
|
||||
}
|
||||
@ -559,7 +578,8 @@ sub HMCCUCHN_Get ($@)
|
||||
($ccuobj, undef) = HMCCU_SplitChnAddr ($ccuaddr);
|
||||
}
|
||||
|
||||
my ($rc, $res) = HMCCU_RPCGetConfig ($hash, $ccuobj, "getParamsetDescription", undef);
|
||||
my ($rc, $res) = HMCCU_RPCRequest ($hash, "getParamsetDescription", $ccuobj, "MASTER", undef);
|
||||
# my ($rc, $res) = HMCCU_RPCGetConfig ($hash, $ccuobj, "getParamsetDescription", undef);
|
||||
return HMCCU_SetError ($hash, $rc, $res) if ($rc < 0);
|
||||
return $res;
|
||||
}
|
||||
@ -827,7 +847,7 @@ sub HMCCUCHN_Get ($@)
|
||||
channel-name.datapoint. If set to 'datapoint' format is channel-number.datapoint. With
|
||||
suffix 'lc' reading names are converted to lowercase.
|
||||
</li><br/>
|
||||
<li><b>ccureadingname <old-readingname-expr>:[+]<new-readingname>[;...]</b><br/>
|
||||
<li><b>ccureadingname <old-readingname-expr>:[+]<new-readingname>[,...];[;...]</b><br/>
|
||||
Set alternative or additional reading names or group readings. Only part of old reading
|
||||
name matching <i>old-readingname-exptr</i> is substituted by <i>new-readingname</i>.
|
||||
If <i>new-readingname</i> is preceded by '+' an additional reading is created. If
|
||||
|
@ -4,7 +4,7 @@
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# Version 4.3.008
|
||||
# Version 4.3.009
|
||||
#
|
||||
# (c) 2019 zap (zap01 <at> t-online <dot> de)
|
||||
#
|
||||
@ -340,6 +340,8 @@ sub HMCCUDEV_Set ($@)
|
||||
my $name = shift @$a;
|
||||
my $opt = shift @$a;
|
||||
|
||||
return "No set command specified" if (!defined ($opt));
|
||||
|
||||
# Valid commands for read only devices
|
||||
my $rocmds = "clear config defaults:noArg";
|
||||
|
||||
@ -593,11 +595,36 @@ sub HMCCUDEV_Set ($@)
|
||||
$objname .= ':'.$1;
|
||||
}
|
||||
|
||||
my $rc = HMCCU_RPCSetConfig ($hash, $objname, $h);
|
||||
my ($rc, $res) = HMCCU_RPCRequest ($hash, "putParamset", $objname, "MASTER", $h);
|
||||
# my $rc = HMCCU_RPCSetConfig ($hash, $objname, $h);
|
||||
return HMCCU_SetError ($hash, $rc) if ($rc < 0);
|
||||
|
||||
return HMCCU_SetState ($hash, "OK");
|
||||
}
|
||||
elsif ($opt eq 'rpcParameter') {
|
||||
return HMCCU_SetError ($hash, "Usage: set $name rpcParameter [channel] [MASTER|VALUES] {parameter}={value} [...]")
|
||||
if ((scalar keys %{$h}) < 1);
|
||||
|
||||
my $key;
|
||||
my $addr;
|
||||
|
||||
while (my $p = shift @$a) {
|
||||
if ($p =~ /^(MASTER|VALUES)$/ && !defined ($key)) {
|
||||
$key = $p;
|
||||
}
|
||||
elsif ($p =~ /^([0-9]+)$/ && !defined ($addr)) {
|
||||
HMCCU_SetError ($hash, -7) if ($p >= $hash->{channels});
|
||||
$addr = $p;
|
||||
}
|
||||
}
|
||||
|
||||
$key = 'VALUES' if (!defined ($key));
|
||||
$addr = defined ($addr) ? "$ccuaddr:$addr" : $ccuaddr;
|
||||
|
||||
my ($rc, $res) = HMCCU_RPCRequest ($hash, "putParamset", $addr, $key, $h);
|
||||
return HMCCU_SetError ($hash, $rc) if ($rc < 0);
|
||||
return HMCCU_SetState ($hash, "OK");
|
||||
}
|
||||
elsif ($opt eq 'defaults') {
|
||||
my $rc = HMCCU_SetDefaults ($hash);
|
||||
return HMCCU_SetError ($hash, "HMCCU: No default attributes found") if ($rc == 0);
|
||||
@ -640,6 +667,8 @@ sub HMCCUDEV_Get ($@)
|
||||
my $name = shift @$a;
|
||||
my $opt = shift @$a;
|
||||
|
||||
return "No get command specified" if (!defined ($opt));
|
||||
|
||||
# Get I/O device
|
||||
return undef if (!defined ($hash->{ccudevstate}) || $hash->{ccudevstate} eq 'pending' ||
|
||||
!defined ($hash->{IODev}));
|
||||
@ -739,7 +768,6 @@ sub HMCCUDEV_Get ($@)
|
||||
return HMCCU_FormatDeviceInfo ($result);
|
||||
}
|
||||
elsif ($opt eq 'config') {
|
||||
my $channel = undef;
|
||||
my $ccuobj = $ccuaddr;
|
||||
my $par = shift @$a;
|
||||
if (defined ($par)) {
|
||||
@ -751,13 +779,13 @@ sub HMCCUDEV_Get ($@)
|
||||
}
|
||||
$par = '.*' if (!defined ($par));
|
||||
|
||||
my ($rc, $res) = HMCCU_RPCGetConfig ($hash, $ccuobj, "getParamset", $par);
|
||||
my ($rc, $res) = HMCCU_RPCRequest ($hash, "getParamset", $ccuobj, "MASTER", undef, $par);
|
||||
# my ($rc, $res) = HMCCU_RPCGetConfig ($hash, $ccuobj, "getParamset", $par);
|
||||
return HMCCU_SetError ($hash, $rc, $res) if ($rc < 0);
|
||||
HMCCU_SetState ($hash, "OK") if (exists ($hash->{STATE}) && $hash->{STATE} eq "Error");
|
||||
return $ccureadings ? undef : $res;
|
||||
}
|
||||
elsif ($opt eq 'configlist') {
|
||||
my $channel = undef;
|
||||
my $ccuobj = $ccuaddr;
|
||||
my $par = shift @$a;
|
||||
if (defined ($par)) {
|
||||
@ -769,13 +797,13 @@ sub HMCCUDEV_Get ($@)
|
||||
}
|
||||
$par = '.*' if (!defined ($par));
|
||||
|
||||
my ($rc, $res) = HMCCU_RPCGetConfig ($hash, $ccuobj, "listParamset", $par);
|
||||
my ($rc, $res) = HMCCU_RPCRequest ($hash, "listParamset", $ccuobj, "MASTER", undef, $par);
|
||||
# my ($rc, $res) = HMCCU_RPCGetConfig ($hash, $ccuobj, "listParamset", $par);
|
||||
return HMCCU_SetError ($hash, $rc, $res) if ($rc < 0);
|
||||
HMCCU_SetState ($hash, "OK") if (exists ($hash->{STATE}) && $hash->{STATE} eq "Error");
|
||||
return $res;
|
||||
}
|
||||
elsif ($opt eq 'configdesc') {
|
||||
my $channel = undef;
|
||||
my $ccuobj = $ccuaddr;
|
||||
my $par = shift @$a;
|
||||
if (defined ($par)) {
|
||||
@ -788,7 +816,8 @@ sub HMCCUDEV_Get ($@)
|
||||
}
|
||||
}
|
||||
|
||||
my ($rc, $res) = HMCCU_RPCGetConfig ($hash, $ccuobj, "getParamsetDescription", undef);
|
||||
my ($rc, $res) = HMCCU_RPCRequest ($hash, "getParamsetDescription", $ccuobj, "MASTER", undef);
|
||||
# my ($rc, $res) = HMCCU_RPCGetConfig ($hash, $ccuobj, "getParamsetDescription", undef);
|
||||
return HMCCU_SetError ($hash, $rc, $res) if ($rc < 0);
|
||||
HMCCU_SetState ($hash, "OK") if (exists ($hash->{STATE}) && $hash->{STATE} eq "Error");
|
||||
return $res;
|
||||
|
@ -4,7 +4,7 @@
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# Version 1.7.002
|
||||
# Version 1.8
|
||||
#
|
||||
# Subprocess based RPC Server module for HMCCU.
|
||||
#
|
||||
@ -35,7 +35,7 @@ use SetExtensions;
|
||||
######################################################################
|
||||
|
||||
# HMCCURPC version
|
||||
my $HMCCURPCPROC_VERSION = '1.7.001';
|
||||
my $HMCCURPCPROC_VERSION = '1.8';
|
||||
|
||||
# Maximum number of events processed per call of Read()
|
||||
my $HMCCURPCPROC_MAX_EVENTS = 100;
|
||||
@ -97,6 +97,26 @@ my $BINRPC_RESPONSE = 0x42696E01;
|
||||
my $BINRPC_REQUEST_HEADER = 0x42696E40;
|
||||
my $BINRPC_ERROR = 0x42696EFF;
|
||||
|
||||
# BinRPC datatype mapping
|
||||
my %BINRPC_TYPE_MAPPING = (
|
||||
"BOOL" => $BINRPC_BOOL,
|
||||
"INTEGER" => $BINRPC_INTEGER,
|
||||
"STRING" => $BINRPC_STRING,
|
||||
"FLOAT" => $BINRPC_DOUBLE,
|
||||
"DOUBLE" => $BINRPC_DOUBLE,
|
||||
"BASE64" => $BINRPC_BASE64,
|
||||
"ARRAY" => $BINRPC_ARRAY,
|
||||
"STRUCT" => $BINRPC_STRUCT
|
||||
);
|
||||
|
||||
# Read/Write flags for RPC methods (0=Read, 1=Write)
|
||||
my %RPC_METHODS = (
|
||||
'putParamset' => 1,
|
||||
'getParamset' => 0,
|
||||
'getParamsetDescription' => 0,
|
||||
'setValue' => 1,
|
||||
'getValue' => 0
|
||||
);
|
||||
|
||||
######################################################################
|
||||
# Functions
|
||||
@ -157,8 +177,8 @@ sub HMCCURPCPROC_ReaddDevicesCB ($$$);
|
||||
sub HMCCURPCPROC_EventCB ($$$$$);
|
||||
sub HMCCURPCPROC_ListDevicesCB ($$);
|
||||
|
||||
# Binary RPC encoding functions
|
||||
sub HMCCURPCPROC_RPCNewValue ($$);
|
||||
# RPC encoding functions
|
||||
sub HMCCURPCPROC_EncValue ($$);
|
||||
sub HMCCURPCPROC_EncInteger ($);
|
||||
sub HMCCURPCPROC_EncBool ($);
|
||||
sub HMCCURPCPROC_EncString ($);
|
||||
@ -497,6 +517,8 @@ sub HMCCURPCPROC_Set ($@)
|
||||
my $name = shift @$a;
|
||||
my $opt = shift @$a;
|
||||
|
||||
return "No set command specified" if (!defined ($opt));
|
||||
|
||||
my $ccuflags = AttrVal ($name, 'ccuflags', 'null');
|
||||
my $options = $ccuflags =~ /expert/ ?
|
||||
"cleanup:noArg deregister:noArg register:noArg rpcrequest rpcserver:on,off" : "";
|
||||
@ -576,6 +598,8 @@ sub HMCCURPCPROC_Get ($@)
|
||||
my $name = shift @$a;
|
||||
my $opt = shift @$a;
|
||||
|
||||
return "No get command specified" if (!defined ($opt));
|
||||
|
||||
my $ccuflags = AttrVal ($name, 'ccuflags', 'null');
|
||||
my $options = "rpcevents:noArg rpcstate:noArg";
|
||||
|
||||
@ -1080,13 +1104,7 @@ sub HMCCURPCPROC_RegisterCallback ($$)
|
||||
$hash->{hmccu}{rpc}{cburl} = $cburl;
|
||||
|
||||
Log3 $name, 2, "HMCCURPCPROC: [$name] Registering callback $cburl of type $rpctype with ID $clkey at $clurl";
|
||||
my $rc;
|
||||
if ($rpctype eq 'A') {
|
||||
$rc = HMCCURPCPROC_SendRequest ($hash, "init", $cburl, $clkey);
|
||||
}
|
||||
else {
|
||||
$rc = HMCCURPCPROC_SendRequest ($hash, "init", $BINRPC_STRING, $cburl, $BINRPC_STRING, $clkey);
|
||||
}
|
||||
my $rc = HMCCURPCPROC_SendRequest ($hash, "init", "$cburl:STRING", "$clkey:STRING");
|
||||
|
||||
if (defined ($rc)) {
|
||||
return (1, $ccuflags !~ /ccuInit/ ? 'running' : 'registered');
|
||||
@ -1126,13 +1144,7 @@ sub HMCCURPCPROC_DeRegisterCallback ($$)
|
||||
|
||||
# Deregister up to 2 times
|
||||
for (my $i=0; $i<2; $i++) {
|
||||
my $rc;
|
||||
if (HMCCU_IsRPCType ($hmccu_hash, $port, 'A')) {
|
||||
$rc = HMCCURPCPROC_SendRequest ($hash, "init", $cburl);
|
||||
}
|
||||
else {
|
||||
$rc = HMCCURPCPROC_SendRequest ($hash, "init", $BINRPC_STRING, $cburl);
|
||||
}
|
||||
my $rc = HMCCURPCPROC_SendRequest ($hash, "init", "$cburl:STRING");
|
||||
|
||||
if (defined ($rc)) {
|
||||
HMCCURPCPROC_SetRPCState ($hash, $force == 0 ? 'deregistered' : $rpchash->{state},
|
||||
@ -1389,8 +1401,8 @@ sub HMCCURPCPROC_RPCServerStarted ($)
|
||||
# Update client devices if interface is managed by HMCCURPCPROC device.
|
||||
# Normally interfaces are managed by HMCCU device.
|
||||
if ($hmccu_hash->{hmccu}{interfaces}{$ifname}{manager} eq 'HMCCURPCPROC') {
|
||||
my ($c_ok, $c_err) = HMCCU_UpdateClients ($hmccu_hash, '.*', 'Attr', 0, $ifname);
|
||||
Log3 $name, 2, "HMCCURPCPROC: [$name] Updated devices. Success=$c_ok Failed=$c_err";
|
||||
HMCCU_UpdateClients ($hmccu_hash, '.*', 'Attr', 0, $ifname, 1);
|
||||
# Log3 $name, 2, "HMCCURPCPROC: [$name] Updated devices. Success=$c_ok Failed=$c_err";
|
||||
}
|
||||
|
||||
RemoveInternalTimer ($hash, "HMCCURPCPROC_IsRPCServerRunning");
|
||||
@ -1633,6 +1645,25 @@ sub HMCCURPCPROC_StopRPCServer ($$)
|
||||
######################################################################
|
||||
# Send RPC request to CCU.
|
||||
# Supports XML and BINRPC requests.
|
||||
# Parameter $request contains the RPC command (i.e. "init" or
|
||||
# "putParamset"). If RPC command is a parameter set command, two
|
||||
# additional parameters address and key (MASTER or VALUE) must be
|
||||
# specified.
|
||||
# If RPC command is putParamset or setValue, the remaining elements
|
||||
# in array @param contains the request parameters in format:
|
||||
# ParameterName=Value[:ParameterType]
|
||||
# For other RPC command the array @param contains the parameters in
|
||||
# format:
|
||||
# Value[:ParameterType]
|
||||
# For BINRPC interfaces ParameterType is mapped as follows:
|
||||
# "INTEGER" = $BINRPC_INTEGER
|
||||
# "BOOL" = $BINRPC_BOOL
|
||||
# "STRING" = $BINRPC_STRING
|
||||
# "FLOAT" = $BINRPC_DOUBLE
|
||||
# "DOUBLE" = $BINRPC_DOUBLE
|
||||
# "BASE64" = $BINRPC_BASE64
|
||||
# "ARRAY" = $BINRPC_ARRAY
|
||||
# "STRUCT" = $BINRPC_STRUCT
|
||||
# Return response or undef on error.
|
||||
######################################################################
|
||||
|
||||
@ -1640,35 +1671,89 @@ sub HMCCURPCPROC_SendRequest ($@)
|
||||
{
|
||||
my ($hash, $request, @param) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
my $hmccu_hash = $hash->{IODev};
|
||||
my $ioHash = $hash->{IODev};
|
||||
my $port = $hash->{rpcport};
|
||||
|
||||
my $rc;
|
||||
|
||||
return HMCCU_Log ($hash, 2, "I/O device not found", undef) if (!defined ($hmccu_hash));
|
||||
return HMCCU_Log ($hash, 2, "I/O device not found", undef) if (!defined ($ioHash));
|
||||
|
||||
if (HMCCU_IsRPCType ($hmccu_hash, $port, 'A')) {
|
||||
my $re = ':('.join('|', keys(%BINRPC_TYPE_MAPPING)).')';
|
||||
|
||||
if (HMCCU_IsRPCType ($ioHash, $port, 'A')) {
|
||||
# Use XMLRPC
|
||||
my $clurl = HMCCU_BuildURL ($hmccu_hash, $port);
|
||||
my $clurl = HMCCU_BuildURL ($ioHash, $port);
|
||||
return HMCCU_Log ($hash, 2, "Can't get client URL for port $port", undef)
|
||||
if (!defined ($clurl));
|
||||
|
||||
Log3 $name, 4, "HMCCURPCPROC: [$name] Send ASCII RPC request $request to $clurl";
|
||||
HMCCU_Log ($hash, 4, "Send ASCII RPC request $request to $clurl", undef);
|
||||
my $rpcclient = RPC::XML::Client->new ($clurl, useragent => [
|
||||
ssl_opts => { verify_hostname => 0, SSL_verify_mode => 0 } ]);
|
||||
$rc = $rpcclient->simple_request ($request, @param);
|
||||
Log3 $name, 2, "HMCCURPCPROC: [$name] RPC request error ".$RPC::XML::ERROR if (!defined ($rc));
|
||||
|
||||
if (exists ($RPC_METHODS{$request})) {
|
||||
# Read or write parameter sets
|
||||
my $address = shift @param;
|
||||
my $key = shift @param;
|
||||
return HMCCU_Log ($hash, 2, "Missing address or key in RPC request $request", undef)
|
||||
if (!defined ($key));
|
||||
|
||||
my %hparam;
|
||||
|
||||
# Write requests have at least one parameters
|
||||
if ($RPC_METHODS{$request} == 1) {
|
||||
# Build a parameter hash
|
||||
while (my $p = shift @param) {
|
||||
my $pt = "STRING";
|
||||
if ($p =~ /${re}/) {
|
||||
$pt = $1;
|
||||
$p =~ s/${re}//;
|
||||
}
|
||||
my ($pn, $pv) = split ('=', $p, 2);
|
||||
next if (!defined ($pv));
|
||||
$hparam{$pn} = HMCCURPCPROC_EncValue ($pv, $pt);
|
||||
}
|
||||
|
||||
return HMCCU_Log ($hash, 2, "Missing parameter in RPC request $request", undef)
|
||||
if (!keys %hparam);
|
||||
|
||||
# Submit write paramset request
|
||||
$rc = $rpcclient->simple_request ($request, $address, $key, \%hparam);
|
||||
}
|
||||
else {
|
||||
# Submit read paramset request
|
||||
$rc = $rpcclient->simple_request ($request, $address, $key);
|
||||
}
|
||||
}
|
||||
else {
|
||||
# RPC commands
|
||||
my @aparam = ();
|
||||
|
||||
# Build a parameter array
|
||||
while (my $p = shift @param) {
|
||||
my $pt = "STRING";
|
||||
if ($p =~ /${re}/) {
|
||||
$pt = $1;
|
||||
$p =~ s/${re}//;
|
||||
}
|
||||
push (@aparam, HMCCURPCPROC_EncValue ($p, $pt));
|
||||
}
|
||||
|
||||
# Submit RPC command
|
||||
$rc = $rpcclient->simple_request ($request, @aparam);
|
||||
}
|
||||
|
||||
HMCCU_Log ($hash, 2, "RPC request error ".$RPC::XML::ERROR, undef) if (!defined ($rc));
|
||||
}
|
||||
elsif (HMCCU_IsRPCType ($hmccu_hash, $port, 'B')) {
|
||||
elsif (HMCCU_IsRPCType ($ioHash, $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)
|
||||
my ($serveraddr) = HMCCU_GetRPCServerInfo ($ioHash, $port, 'host');
|
||||
return HMCCU_Log ($ioHash, 2, "Can't get server address for port $port", undef)
|
||||
if (!defined ($serveraddr));
|
||||
|
||||
my $ccuflags = AttrVal ($name, 'ccuflags', 'null');
|
||||
my $verbose = GetVerbose ($name);
|
||||
|
||||
Log3 $name, 4, "HMCCURPCPROC: [$name] Send binary RPC request $request to $serveraddr:$port";
|
||||
HMCCU_Log ($hash, 4, "Send binary RPC request $request to $serveraddr:$port", undef);
|
||||
my $encreq = HMCCURPCPROC_EncodeRequest ($request, \@param);
|
||||
return HMCCU_Log ($hash, 2, "Error encoding binary request", undef) if ($encreq eq '');
|
||||
|
||||
@ -1687,7 +1772,7 @@ sub HMCCURPCPROC_SendRequest ($@)
|
||||
|
||||
if (defined ($encresp)) {
|
||||
if ($ccuflags =~ /logEvents/ && $verbose >= 4) {
|
||||
Log3 $name, 4, "HMCCURPCPROC: [$name] Response";
|
||||
HMCCU_Log ($hash, 4, "Response", undef);
|
||||
HMCCURPCPROC_HexDump ($name, $encresp);
|
||||
}
|
||||
my ($response, $err) = HMCCURPCPROC_DecodeResponse ($encresp);
|
||||
@ -1701,7 +1786,7 @@ sub HMCCURPCPROC_SendRequest ($@)
|
||||
$socket->close ();
|
||||
}
|
||||
else {
|
||||
Log3 $name, 2, "HMCCURPCPROC: [$name] Unknown RPC server type";
|
||||
HMCCU_Log ($hash, 2, "Unknown RPC server type", undef);
|
||||
}
|
||||
|
||||
return $rc;
|
||||
@ -1723,7 +1808,7 @@ sub HMCCURPCPROC_RPCPing ($)
|
||||
if ($ping > 0) {
|
||||
if ($init_done && HMCCURPCPROC_CheckProcessState ($hash, 'running')) {
|
||||
my $clkey = 'CB'.$hash->{rpcport}.$hash->{rpcid};
|
||||
HMCCURPCPROC_SendRequest ($hash, "ping", $clkey);
|
||||
HMCCURPCPROC_SendRequest ($hash, "ping", "$clkey:STRING");
|
||||
}
|
||||
InternalTimer (gettimeofday()+$ping, "HMCCURPCPROC_RPCPing", $hash, 0);
|
||||
}
|
||||
@ -2253,6 +2338,10 @@ sub HMCCURPCPROC_ListDevicesCB ($$)
|
||||
return RPC::XML::array->new ();
|
||||
}
|
||||
|
||||
######################################################################
|
||||
# RPC encoding functions
|
||||
######################################################################
|
||||
|
||||
######################################################################
|
||||
# Convert value to RPC data type
|
||||
# Valid types are bool, boolean, int, integer, float, double, string.
|
||||
@ -2260,7 +2349,7 @@ sub HMCCURPCPROC_ListDevicesCB ($$)
|
||||
# value is returned as is.
|
||||
######################################################################
|
||||
|
||||
sub HMCCURPCPROC_RPCNewValue ($$)
|
||||
sub HMCCURPCPROC_EncValue ($$)
|
||||
{
|
||||
my ($value, $type) = @_;
|
||||
|
||||
@ -2300,10 +2389,6 @@ sub HMCCURPCPROC_RPCNewValue ($$)
|
||||
return $value;
|
||||
}
|
||||
|
||||
######################################################################
|
||||
# Binary RPC encoding functions
|
||||
######################################################################
|
||||
|
||||
######################################################################
|
||||
# Encode integer (type = 1)
|
||||
######################################################################
|
||||
@ -2448,6 +2533,8 @@ sub HMCCURPCPROC_EncType ($$)
|
||||
{
|
||||
my ($t, $v) = @_;
|
||||
|
||||
return '' if (!defined ($t));
|
||||
|
||||
if ($t == $BINRPC_INTEGER) {
|
||||
return HMCCURPCPROC_EncInteger ($v);
|
||||
}
|
||||
@ -2478,7 +2565,8 @@ sub HMCCURPCPROC_EncType ($$)
|
||||
# Encode RPC request with method and optional parameters.
|
||||
# Headers are not supported.
|
||||
# Input is method name and reference to parameter array.
|
||||
# Array must contain (type, value) pairs
|
||||
# Array must contain parameters in format value[:type]. Default for
|
||||
# type is STRING.
|
||||
# Return encoded data or empty string on error
|
||||
######################################################################
|
||||
|
||||
@ -2490,14 +2578,19 @@ sub HMCCURPCPROC_EncodeRequest ($$)
|
||||
my $m = HMCCURPCPROC_EncName ($method);
|
||||
|
||||
# Encode parameters
|
||||
my $re = ':('.join('|', keys(%BINRPC_TYPE_MAPPING)).')';
|
||||
my $r = '';
|
||||
my $s = 0;
|
||||
|
||||
|
||||
if (defined ($args)) {
|
||||
while (my $t = shift @$args) {
|
||||
my $e = shift @$args;
|
||||
last if (!defined ($e));
|
||||
$r .= HMCCURPCPROC_EncType ($t, $e);
|
||||
while (my $p = shift @$args) {
|
||||
my $pt = "STRING";
|
||||
if ($p =~ /${re}/) {
|
||||
$pt = $1;
|
||||
$p =~ s/${re}//;
|
||||
}
|
||||
my ($e, $t) = split (':', $p);
|
||||
$r .= HMCCURPCPROC_EncType ($BINRPC_TYPE_MAPPING{uc($pt)}, $p);
|
||||
$s++;
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# Version 4.6
|
||||
# Version 4.6.002
|
||||
#
|
||||
# Configuration parameters for HomeMatic devices.
|
||||
#
|
||||
@ -168,6 +168,17 @@ use vars qw(%HMCCU_SCRIPTS);
|
||||
webCmd => "control:on:off",
|
||||
widgetOverride => "control:slider,0,10,100"
|
||||
},
|
||||
"HmIP-FCI6" => {
|
||||
_description => "IP Kontaktschnittstelle Unterputz 6-fach",
|
||||
_channels => "1,2,3,4,5,6",
|
||||
ccureadingfilter => "STATE",
|
||||
controldatapoint => "STATE",
|
||||
statedatapoint => "STATE",
|
||||
statevals => "on:true,off:false",
|
||||
substitute => "STATE!(0|false):off,(1|true):on",
|
||||
webCmd => "devstate",
|
||||
widgetOverride => "devstate:uzsuToggle,off,on"
|
||||
},
|
||||
"HM-PB-2-FM" => {
|
||||
_description => "Funk-Wandtaster 2-fach",
|
||||
_channels => "1,2",
|
||||
@ -297,7 +308,7 @@ use vars qw(%HMCCU_SCRIPTS);
|
||||
webCmd => "control:up:stop:down",
|
||||
widgetOverride => "control:slider,0,10,100"
|
||||
},
|
||||
"HmIP-BROLL" => {
|
||||
"HmIP-BROLL|HmIP-FROLL" => {
|
||||
_description => "Rollladenaktor",
|
||||
_channels => "4",
|
||||
ccureadingfilter => "(ERROR_CODE|ERROR_OVERHEAT|ACTUAL_TEMPERATURE|LEVEL|ACTIVITY_STATE)",
|
||||
@ -336,7 +347,7 @@ use vars qw(%HMCCU_SCRIPTS);
|
||||
stripnumber => 1,
|
||||
substitute => "RAINING,RAIN_COUNTER_OVERFLOW,SUNSHINEDURATION_OVERFLOW,SUNSHINE_THRESHOLD_OVERRUN,WIND_THRESHOLD_OVERRUN!(0|false):no,(1|true):yes"
|
||||
},
|
||||
"HM-Sec-MD|HM-Sec-MDIR|HM-Sec-MDIR-2|HM-Sec-MDIR-3" => {
|
||||
"HM-Sec-MD|HM-Sec-MDIR|HM-Sec-MDIR-2|HM-Sec-MDIR-3|Hm-Sen-MDIR-O-3" => {
|
||||
_description => "Bewegungsmelder",
|
||||
_channels => "1",
|
||||
ccureadingfilter => "(BRIGHTNESS|MOTION)",
|
||||
@ -348,9 +359,13 @@ use vars qw(%HMCCU_SCRIPTS);
|
||||
_description => "Bewegungsmelder",
|
||||
_channels => "1",
|
||||
ccureadingfilter => "(ILLUMINATION|MOTION)",
|
||||
eventMap => "/datapoint MOTION_DETECTION_ACTIVE 1:detection-on/datapoint MOTION_DETECTION_ACTIVE 0:detection-off/",
|
||||
controldatapoint => "MOTION_DETECTION_ACTIVE",
|
||||
eventMap => "/datapoint RESET_MOTION 1:reset/datapoint MOTION_DETECTION_ACTIVE 1:detection-on/datapoint MOTION_DETECTION_ACTIVE 0:detection-off/",
|
||||
hmstatevals => "SABOTAGE!(1|true):sabotage",
|
||||
statedatapoint => "MOTION",
|
||||
substitute => "MOTION!(0|false):no,(1|true):yes"
|
||||
substitute => "MOTION!(0|false):no,(1|true):yes;MOTION_DETECTION_ACTIVE!(0|false):off,(1|true):on",
|
||||
webCmd => "control",
|
||||
widgetOverride => "control:uzsuToggle,off,on"
|
||||
},
|
||||
"HmIP-SPI" => {
|
||||
_description => "Anwesenheitssensor",
|
||||
@ -712,16 +727,16 @@ use vars qw(%HMCCU_SCRIPTS);
|
||||
webCmd => "control:up:stop:down",
|
||||
widgetOverride => "control:slider,0,10,100"
|
||||
},
|
||||
"HmIP-BROLL" => {
|
||||
"HmIP-BROLL|HmIP-FROLL" => {
|
||||
_description => "Rollladenaktor",
|
||||
ccureadingfilter => "(ERROR_CODE|ERROR_OVERHEAT|ACTUAL_TEMPERATURE|LEVEL|ACTIVITY_STATE|SELF_CALIBRATION_RESULT)",
|
||||
ccureadingname => "LEVEL:+pct",
|
||||
ccureadingfilter => "3.LEVEL;(ERROR_CODE|ERROR_OVERHEAT|ACTUAL_TEMPERATURE|ACTIVITY_STATE|SELF_CALIBRATION_RESULT)",
|
||||
ccureadingname => "3.LEVEL$:+control,+pct",
|
||||
ccuscaleval => "LEVEL:0:1:0:100",
|
||||
cmdIcon => "up:fts_shutter_up stop:fts_shutter_manual down:fts_shutter_down",
|
||||
controldatapoint => "4.LEVEL",
|
||||
hmstatevals => "ACTUAL_TEMPERATURE_STATUS!2:tempOverflow,3:tempUnderflow;ERROR_OVERHEAT!(1|true):overheat",
|
||||
eventMap => "/datapoint 4.STOP true:stop/datapoint 4.LEVEL 0:down/datapoint 4.LEVEL 100:up/datapoint 3.SELF_CALIBRATION 0:stopCalibration/datapoint 3.SELF_CALIBRATION 1:startCalibration/",
|
||||
statedatapoint => "4.LEVEL",
|
||||
statedatapoint => "3.LEVEL",
|
||||
stripnumber => 1,
|
||||
substexcl => "control|pct",
|
||||
substitute => "LEVEL!#0-0:closed,#100-100:open;ACTIVITY_STATE!0:unknown,1:up,2:down,3:stop;ERROR_OVERHEAT!(0|false):no,(1|true):yes;ACTUAL_TEMPERATURE_STATUS!0:normal,1:unknown,2:overflow,3:underflow;SELF_CALIBRATION_RESULT!(0|false):failed,(1|true):ok",
|
||||
@ -763,7 +778,7 @@ use vars qw(%HMCCU_SCRIPTS);
|
||||
ccureadingname => "1.LEVEL:valve_position",
|
||||
ccuscaleval => "LEVEL:0:1:0:100",
|
||||
controldatapoint => "1.SET_POINT_TEMPERATURE",
|
||||
eventMap => "/datapoint 1.BOOST_MODE true:Boost/datapoint 1.CONTROL_MODE 0:Auto/datapoint 1.CONTROL_MODE 1:Manual/datapoint 1.CONTROL_MODE 2:Holiday/datapoint 1.SET_POINT_TEMPERATURE 4.5:off/datapoint 1.SET_POINT_TEMPERATURE 30.5:on/",
|
||||
eventMap => "/datapoint 1.BOOST_MODE true:Boost/datapoint 1.CONTROL_MODE 0:Auto/datapoint 1.CONTROL_MODE 1:Manual/datapoint 1.CONTROL_MODE 2:Holiday/datapoint 1.CONTROL_MODE 1 1.SET_POINT_TEMPERATURE 4.5:off/datapoint 1.CONTROL_MODE 0 1.SET_POINT_TEMPERATURE 30.5:on/",
|
||||
genericDeviceType => "thermostat",
|
||||
statedatapoint => "1.SET_POINT_TEMPERATURE",
|
||||
stripnumber => 1,
|
||||
@ -833,7 +848,7 @@ use vars qw(%HMCCU_SCRIPTS);
|
||||
webCmd => "control:Auto:Manu:Boost:on:off",
|
||||
widgetOverride => "control:slider,4.5,0.5,30.5,1"
|
||||
},
|
||||
"HM-Sec-MD|HM-Sec-MDIR|HM-Sec-MDIR-2|HM-Sec-MDIR-3" => {
|
||||
"HM-Sec-MD|HM-Sec-MDIR|HM-Sec-MDIR-2|HM-Sec-MDIR-3|Hm-Sen-MDIR-O-3" => {
|
||||
_description => "Bewegungsmelder",
|
||||
ccureadingfilter => "(BRIGHTNESS|MOTION)",
|
||||
hmstatevals => "ERROR!1:sabotage",
|
||||
@ -843,9 +858,13 @@ use vars qw(%HMCCU_SCRIPTS);
|
||||
"HmIP-SMI" => {
|
||||
_description => "Bewegungsmelder",
|
||||
ccureadingfilter => "(ILLUMINATION|MOTION)",
|
||||
eventMap => "/datapoint 1.MOTION_DETECTION_ACTIVE 1:detection-on/datapoint 1.MOTION_DETECTION_ACTIVE 0:detection-off/",
|
||||
controldatapoint => "1.MOTION_DETECTION_ACTIVE",
|
||||
eventMap => "/datapoint 1.RESET_MOTION 1:reset/datapoint 1.MOTION_DETECTION_ACTIVE 1:detection-on/datapoint 1.MOTION_DETECTION_ACTIVE 0:detection-off/",
|
||||
hmstatevals => "SABOTAGE!(1|true):sabotage",
|
||||
statedatapoint => "1.MOTION",
|
||||
substitute => "MOTION!(0|false):no,(1|true):yes"
|
||||
substitute => "MOTION!(0|false):no,(1|true):yes;MOTION_DETECTION_ACTIVE!(0|false):off,(1|true):on",
|
||||
webCmd => "control",
|
||||
widgetOverride => "control:uzsuToggle,off,on"
|
||||
},
|
||||
"HmIP-SMI55" => {
|
||||
_description => "Bewegungsmelder",
|
||||
|
Loading…
x
Reference in New Issue
Block a user