2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-03-03 16:56:54 +00:00

HMCCU: Update for 4.4 beta

git-svn-id: https://svn.fhem.de/fhem/trunk@20934 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
zap 2020-01-10 16:04:11 +00:00
parent c89f06024d
commit 6092fb76a5
4 changed files with 299 additions and 181 deletions

View File

@ -293,8 +293,8 @@ sub HMCCU_GetClientDeviceModel ($;$);
sub HMCCU_GetDefaultInterface ($); sub HMCCU_GetDefaultInterface ($);
sub HMCCU_GetDeviceAddresses ($;$$); sub HMCCU_GetDeviceAddresses ($;$$);
sub HMCCU_GetDeviceChannels ($$$); sub HMCCU_GetDeviceChannels ($$$);
sub HMCCU_GetDeviceDesc ($;$$); sub HMCCU_GetDeviceDesc ($$;$);
sub HMCCU_GetDeviceInfo ($$$); sub HMCCU_GetDeviceInfo ($$;$);
sub HMCCU_GetDeviceInterface ($$$); sub HMCCU_GetDeviceInterface ($$$);
sub HMCCU_GetDeviceList ($); sub HMCCU_GetDeviceList ($);
sub HMCCU_GetDeviceModel ($$$;$); sub HMCCU_GetDeviceModel ($$$;$);
@ -303,10 +303,12 @@ sub HMCCU_GetDeviceType ($$$);
sub HMCCU_GetFirmwareVersions ($$); sub HMCCU_GetFirmwareVersions ($$);
sub HMCCU_GetGroupMembers ($$); sub HMCCU_GetGroupMembers ($$);
sub HMCCU_GetMatchingDevices ($$$$); sub HMCCU_GetMatchingDevices ($$$$);
sub HMCCU_GetParamDef ($$$$);
sub HMCCU_GetParamValue ($$$$$);
sub HMCCU_IsValidChannel ($$$); sub HMCCU_IsValidChannel ($$$);
sub HMCCU_IsValidDevice ($$$); sub HMCCU_IsValidDevice ($$$);
sub HMCCU_IsValidDeviceOrChannel ($$$); sub HMCCU_IsValidDeviceOrChannel ($$$);
sub HMCCU_ResetDeviceTables ($$); sub HMCCU_ResetDeviceTables ($;$$);
sub HMCCU_UpdateDeviceTable ($$); sub HMCCU_UpdateDeviceTable ($$);
# Handle datapoints # Handle datapoints
@ -3320,18 +3322,22 @@ sub HMCCU_UpdateDeviceTable ($$)
# Delete device table entries # Delete device table entries
###################################################################### ######################################################################
sub HMCCU_ResetDeviceTables ($$) sub HMCCU_ResetDeviceTables ($;$$)
{ {
my ($hash, $iface) = @_; my ($hash, $iface, $address) = @_;
if (defined($iface)) { if (defined($iface)) {
$hash->{hmccu}{device}{$iface} = (); if (defined($address)) {
$hash->{hmccu}{device}{$iface}{$address} = ();
}
else {
$hash->{hmccu}{device}{$iface} = ();
}
} }
else { else {
$hash->{hmccu}{device} = (); $hash->{hmccu}{device} = ();
$hash->{hmccu}{model} = ();
} }
$hash->{hmccu}{model} = ();
} }
###################################################################### ######################################################################
@ -3358,7 +3364,7 @@ sub HMCCU_AddDeviceDesc ($$$$)
if (ref($desc->{$p}) eq 'ARRAY') { if (ref($desc->{$p}) eq 'ARRAY') {
$hash->{hmccu}{device}{$iface}{$k}{$p} = join(',', @{$desc->{$p}}); $hash->{hmccu}{device}{$iface}{$k}{$p} = join(',', @{$desc->{$p}});
} }
elsif ($p ne $key) { else {
$hash->{hmccu}{device}{$iface}{$k}{$p} = $desc->{$p}; $hash->{hmccu}{device}{$iface}{$k}{$p} = $desc->{$p};
} }
} }
@ -3383,31 +3389,32 @@ sub HMCCU_AddDeviceDesc ($$$$)
} }
###################################################################### ######################################################################
# Get device description # Get device description.
# Parameters: # Parameters:
# $hash - Hash reference of IO device or client device. For client # $hash - Hash reference of IO device.
# devices the parameters $iface and $address are taken from
# client device hash if set to undef.
# $iface - Interface name.
# $address - Address of device or channel. # $address - Address of device or channel.
# $iface - Interface name.
# Return hash reference for device description or undef on error. # Return hash reference for device description or undef on error.
###################################################################### ######################################################################
sub HMCCU_GetDeviceDesc ($;$$) sub HMCCU_GetDeviceDesc ($$;$)
{ {
my ($hash, $iface, $address) = @_; my ($hash, $address, $iface) = @_;
my $ioHash = HMCCU_GetHash ($hash);
my @ifaceList = ();
if ($hash->{TYPE} eq 'HMCCUDEV' || $hash->{TYPE} eq 'HMCCUCHN') { if (defined($iface)) {
$iface = $hash->{ccuif} if (!defined($iface)); push (@ifaceList, $iface);
$address = $hash->{ccuaddr} if (!defined($address));
} }
else { else {
return undef if (!defined($iface) || !defined($address)); push (@ifaceList, keys %${$hash->{hmccu}{device}});
} }
return (exists ($ioHash->{hmccu}{device}{$iface}{$address}) ? foreach my $i (@ifaceList) {
$ioHash->{hmccu}{device}{$iface}{$address} : undef); return $hash->{hmccu}{device}{$i}{$address}
if (exists($hash->{hmccu}{device}{$i}{$address}));
}
return undef;
} }
###################################################################### ######################################################################
@ -3555,17 +3562,94 @@ sub HMCCU_GetDeviceModel ($$$;$)
sub HMCCU_GetClientDeviceModel ($;$) sub HMCCU_GetClientDeviceModel ($;$)
{ {
my ($hash, $chnNo) = @_; my ($clHash, $chnNo) = @_;
return undef if ($hash->{TYPE} ne 'HMCCUCHN' && $hash->{TYPE} ne 'HMCCUDEV'); return undef if ($clHash->{TYPE} ne 'HMCCUCHN' && $clHash->{TYPE} ne 'HMCCUDEV');
my $ioHash = HMCCU_GetHash ($hash); my $ioHash = HMCCU_GetHash ($clHash);
my $devDesc = HMCCU_GetDeviceDesc ($hash); my $devDesc = HMCCU_GetDeviceDesc ($ioHash, $clHash->{ccuaddr}, $clHash->{ccuif});
return defined($devDesc) ? return defined($devDesc) ?
HMCCU_GetDeviceModel ($ioHash, $devDesc->{_model}, $devDesc->{_fw_ver}, $chnNo) : undef; HMCCU_GetDeviceModel ($ioHash, $devDesc->{_model}, $devDesc->{_fw_ver}, $chnNo) : undef;
} }
######################################################################
# Get parameter defintion of device model
# Parameters:
# $hash - Hash reference of IO device.
# $object - Device or channel address or device description
# reference.
# $paramset - Valid paramset for device or channel.
# $parameter - Parameter name.
# Returns undef on error. Otherwise a reference to the parameter
# definition.
######################################################################
sub HMCCU_GetParamDef ($$$$)
{
my ($hash, $object, $paramset, $parameter) = @_;
my $devDesc;
if (ref($object) eq 'HASH') {
$devDesc = $object;
}
else {
$devDesc = HMCCU_GetDeviceDesc ($hash, $object);
}
if (defined($devDesc)) {
# Build device address and channel number
my $address = $devDesc->{ADDRESS};
my ($devAddr, $chnNo) = ($address =~ /:[0-9]{1,2}$/) ?
HMCCU_SplitChnAddr ($address) : ($address, 'd');
my $model = HMCCU_GetDeviceModel ($hash, $devDesc->{_model}, $devDesc->{_fw_ver}, $chnNo);
if (defined($model) && exists($model->{$paramset}) && exists($model->{$paramset}{$parameter})) {
return $model->{$paramset}{$parameter};
}
}
return undef;
}
######################################################################
# Convert parameter value
# Parameters:
# $hash - Hash reference of IO device.
# $object - Device or channel address.
# $paramset - Parameter set.
# $parameter - Parameter name.
# $value - Parameter value.
# Return converted or original value.
######################################################################
sub HMCCU_GetParamValue ($$$$$)
{
my ($hash, $object, $paramset, $parameter, $value) = @_;
# Conversion table
my %ct = (
'BOOL' => { 0 => 'false', 1 => 'true' }
);
my $paramDef = HMCCU_GetParamDef ($hash, $object, $paramset, $parameter);
if (defined($paramDef)) {
my $type = $paramDef->{TYPE};
HMCCU_Log ($hash, 2, "Checking type $type");
return $ct{$type}{$value} if (exists($ct{$type}) && exists($ct{$type}{$value}));
if ($type eq 'ENUM' && exists($paramDef->{VALUE_LIST})) {
my @vl = split(',', $paramDef->{VALUE_LIST});
return $vl[$value] if ($value =~ /^[0-9]+$/ && $value < scalar(@vl));
}
return $value*100.0 if ($parameter eq 'LEVEL');
}
return $value;
}
####################################################################### #######################################################################
# Convert bitmask to text # Convert bitmask to text
# Parameters: # Parameters:
@ -3574,7 +3658,8 @@ sub HMCCU_GetClientDeviceModel ($;$)
# $value - Value of parameter. # $value - Value of parameter.
# $sep - String separator. Default = ''. # $sep - String separator. Default = ''.
# $default - Default value is returned if no bit is set. # $default - Default value is returned if no bit is set.
# Return empty string on error or if no bit set. # Return empty string on error. Return $default if no bit set.
# Return $value if $flag is not a bitmask.
###################################################################### ######################################################################
sub HMCCU_FlagsToStr ($$$;$$) sub HMCCU_FlagsToStr ($$$;$$)
@ -3596,7 +3681,7 @@ sub HMCCU_FlagsToStr ($$$;$$)
} }
); );
return '' if (!exists($bitmasks{$set}{$flag})); return $value if (!exists($bitmasks{$set}{$flag}));
my @list = (); my @list = ();
foreach my $b (sort keys %{$bitmasks{$set}{$flag}}) { foreach my $b (sort keys %{$bitmasks{$set}{$flag}}) {
@ -4530,7 +4615,7 @@ sub HMCCU_IsRPCServerRunning ($$$)
# Get channels and datapoints of CCU device # Get channels and datapoints of CCU device
###################################################################### ######################################################################
sub HMCCU_GetDeviceInfo ($$$) sub HMCCU_GetDeviceInfo ($$;$)
{ {
my ($hash, $device, $ccuget) = @_; my ($hash, $device, $ccuget) = @_;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
@ -4540,6 +4625,8 @@ sub HMCCU_GetDeviceInfo ($$$)
my $hmccu_hash = HMCCU_GetHash ($hash); my $hmccu_hash = HMCCU_GetHash ($hash);
return '' if (!defined ($hmccu_hash)); return '' if (!defined ($hmccu_hash));
$ccuget = 'Value' if (!defined($ccuget));
my @devlist; my @devlist;
if ($hash->{ccuif} eq 'fhem' && exists ($hash->{ccugroup})) { if ($hash->{ccuif} eq 'fhem' && exists ($hash->{ccugroup})) {
push @devlist, split (",", $hash->{ccugroup}); push @devlist, split (",", $hash->{ccugroup});
@ -7298,8 +7385,8 @@ sub HMCCU_UpdateCB ($$$)
###################################################################### ######################################################################
# Execute RPC request # Execute RPC request
# Parameters: # Parameters:
# $method - RPC request method. Use listParamset as an alias for # $method - RPC request method. Use listParamset or listRawParamset
# getParamset if readings should not be updated. # as an alias for getParamset if readings should not be updated.
# $address - Device address. # $address - Device address.
# $paramset - paramset name: VALUE, MASTER, LINK, ... # $paramset - paramset name: VALUE, MASTER, LINK, ...
# $parref - Hash reference with parameter/value pairs (optional). # $parref - Hash reference with parameter/value pairs (optional).
@ -7316,7 +7403,7 @@ sub HMCCU_RPCRequest ($$$$$;$)
my $type = $clHash->{TYPE}; my $type = $clHash->{TYPE};
my $fnc = "RPCRequest"; my $fnc = "RPCRequest";
my $reqMethod = $method eq 'listParamset' ? 'getParamset' : $method; my $reqMethod = $method eq 'listParamset' || $method eq 'listRawParamset' ? 'getParamset' : $method;
$filter = '.*' if (!defined ($filter)); $filter = '.*' if (!defined ($filter));
my $addr = ''; my $addr = '';
my $result = ''; my $result = '';
@ -7382,6 +7469,9 @@ sub HMCCU_RPCRequest ($$$$$;$)
if ($method eq 'listParamset') { if ($method eq 'listParamset') {
$result = join ("\n", map { $_ =~ /$filter/ ? $_.'='.$reqResult->{$_} : () } keys %$reqResult); $result = join ("\n", map { $_ =~ /$filter/ ? $_.'='.$reqResult->{$_} : () } keys %$reqResult);
} }
elsif ($method eq 'listRawParamset') {
$result = $reqResult;
}
elsif ($method eq 'getDeviceDescription') { elsif ($method eq 'getDeviceDescription') {
$result = ''; $result = '';
foreach my $k (sort keys %$reqResult) { foreach my $k (sort keys %$reqResult) {

View File

@ -4,7 +4,7 @@
# #
# $Id: 88_HMCCUCHN.pm 18552 2019-02-10 11:52:28Z zap $ # $Id: 88_HMCCUCHN.pm 18552 2019-02-10 11:52:28Z zap $
# #
# Version 4.4.000 # Version 4.4.001
# #
# (c) 2020 zap (zap01 <at> t-online <dot> de) # (c) 2020 zap (zap01 <at> t-online <dot> de)
# #
@ -170,6 +170,11 @@ sub HMCCUCHN_Attr ($@)
{ {
my ($cmd, $name, $attrname, $attrval) = @_; my ($cmd, $name, $attrname, $attrval) = @_;
my $hash = $defs{$name}; my $hash = $defs{$name};
my %resetReadings = (
'ccureadingfilter' => 1, 'ccureadingname' => 1, 'substitute' => 1,
'ccuscaleval' => 1
);
if ($cmd eq "set") { if ($cmd eq "set") {
return "Missing attribute value" if (!defined ($attrval)); return "Missing attribute value" if (!defined ($attrval));
@ -193,6 +198,15 @@ sub HMCCUCHN_Attr ($@)
} }
} }
if ($init_done) {
my $ioHash = $hash->{IODev};
if (defined($ioHash) && !HMCCU_IsFlag ($ioHash->{NAME}, 'noResetReadings') &&
exists($resetReadings{$attrname}) && $resetReadings{$attrname} == 1) {
HMCCU_DeleteReadings ($hash, '.*');
HMCCU_GetUpdate ($hash, $hash->{ccuaddr}, 'Value');
}
}
return undef; return undef;
} }
@ -209,7 +223,7 @@ sub HMCCUCHN_Set ($@)
return "No set command specified" if (!defined ($opt)); return "No set command specified" if (!defined ($opt));
my $rocmds = "clear defaults:noArg"; my $rocmds = "clear defaults:noArg";
my $rwcmds = "clear config control datapoint defaults:noArg rpcparameter devstate"; my $rwcmds = "clear config control datapoint defaults:noArg paramset devstate";
# Get I/O device, check device state # Get I/O device, check device state
return undef if (!defined ($hash->{ccudevstate}) || $hash->{ccudevstate} eq 'pending' || return undef if (!defined ($hash->{ccudevstate}) || $hash->{ccudevstate} eq 'pending' ||
@ -405,35 +419,32 @@ sub HMCCUCHN_Set ($@)
HMCCU_DeleteReadings ($hash, $rnexp); HMCCU_DeleteReadings ($hash, $rnexp);
return HMCCU_SetState ($hash, "OK"); return HMCCU_SetState ($hash, "OK");
} }
elsif ($opt eq 'config') { elsif ($opt eq 'paramset' || $opt eq 'rpcparameter' || $opt eq 'config') {
return HMCCU_SetError ($hash, "Usage: set $name config [device] {parameter}={value} [...]") return HMCCU_SetError ($hash, "Usage: set $name rpcparameter [device] [paramset] {parameter}={value}[:{type}] [...]")
if ((scalar keys %{$h}) < 1);
my $ccuobj = $ccuaddr;
my $par = shift @$a;
if (defined ($par) && $par eq 'device') {
($ccuobj, undef) = HMCCU_SplitChnAddr ($ccuaddr);
}
($rc, $result) = HMCCU_RPCRequest ($hash, "putParamset", $ccuobj, "MASTER", $h);
return HMCCU_SetError ($hash, min(0, $rc));
}
elsif ($opt eq 'rpcparameter') {
return HMCCU_SetError ($hash, "Usage: set $name rpcparameter [MASTER|LINK|VALUES] {parameter}={value} [...]")
if ((scalar keys %{$h}) < 1); if ((scalar keys %{$h}) < 1);
my $ccuobj = $ccuaddr;
my $p = shift @$a; my $p = shift @$a;
$p = 'VALUES' if (!defined ($p)); if (defined($p) && $p eq 'device') {
my $key = uc($p); ($ccuobj, undef) = HMCCU_SplitChnAddr ($ccuaddr);
$p = shift @$a;
}
my $paramset = defined($p) ? uc($p) : ($opt eq 'config' ? 'MASTER' : 'VALUES');
if ($key eq 'VALUES') { my $devDesc = HMCCU_GetDeviceDesc ($hmccu_hash, $ccuobj, $ccuif);
return HMCCU_SetError ($hash, "Can't get device description")
if (!defined($devDesc));
return HMCCU_SetError ($hash, "Paramset $paramset not supported by device")
if ($devDesc->{PARAMSETS} !~ /$paramset/);
if ($paramset eq 'VALUES') {
($rc, $result) = HMCCU_SetMultipleParameters ($hash, $ccuaddr, $h); ($rc, $result) = HMCCU_SetMultipleParameters ($hash, $ccuaddr, $h);
} }
elsif ($key eq 'MASTER' || $key eq 'LINK') {
($rc, $result) = HMCCU_RPCRequest ($hash, "putParamset", $ccuaddr, $key, $h);
}
else { else {
return HMCCU_SetError ($hash, "Key must be MASTER, LINK or VALUES"); ($rc, $result) = HMCCU_RPCRequest ($hash, "putParamset", $ccuaddr, $paramset, $h);
} }
return HMCCU_SetError ($hash, min(0, $rc)); return HMCCU_SetError ($hash, min(0, $rc));
} }
elsif ($opt eq 'defaults') { elsif ($opt eq 'defaults') {
@ -500,7 +511,7 @@ sub HMCCUCHN_Get ($@)
# Log commands # Log commands
HMCCU_Log ($hash, 3, "get $name $opt ".join (' ', @$a)) HMCCU_Log ($hash, 3, "get $name $opt ".join (' ', @$a))
if ($ccuflags =~ /logCommand/ || HMCCU_IsFlag ($hmccu_name, 'logCommand')); if ($opt ne '?' && $ccuflags =~ /logCommand/ || HMCCU_IsFlag ($hmccu_name, 'logCommand'));
if ($opt eq 'devstate') { if ($opt eq 'devstate') {
return HMCCU_SetError ($hash, -13) if ($sd eq ''); return HMCCU_SetError ($hash, -13) if ($sd eq '');
@ -536,31 +547,33 @@ sub HMCCUCHN_Get ($@)
return undef; return undef;
} }
elsif ($opt eq 'deviceinfo') { elsif ($opt eq 'deviceinfo') {
my $ccuget = shift @$a; my ($a, $c) = HMCCU_SplitChnAddr ($ccuaddr);
$ccuget = 'Attr' if (!defined ($ccuget)); $result = HMCCU_GetDeviceInfo ($hash, $a);
if ($ccuget !~ /^(Attr|State|Value)$/) {
return HMCCU_SetError ($hash, "Usage: get $name deviceinfo [{'State'|'Value'}]");
}
my ($a, $c) = split(":", $hash->{ccuaddr});
$result = HMCCU_GetDeviceInfo ($hash, $a, $ccuget);
return HMCCU_SetError ($hash, -2) if ($result eq ''); return HMCCU_SetError ($hash, -2) if ($result eq '');
return HMCCU_FormatDeviceInfo ($result); return HMCCU_FormatDeviceInfo ($result);
} }
elsif ($opt eq 'config') { elsif ($opt eq 'config' || $opt eq 'configlist') {
my $ccuobj = $ccuaddr; my $ccuobj = $ccuaddr;
my $method = $opt eq 'config' ? 'getParamset' : 'listRawParamset';
my ($devAddr, undef) = HMCCU_SplitChnAddr ($ccuaddr);
my @addList = ();
my $par = shift @$a; my $par = shift @$a;
if (defined ($par)) { if (defined ($par)) {
if ($par eq 'device') { if ($par eq 'device') {
($ccuobj, undef) = HMCCU_SplitChnAddr ($ccuaddr); push (@addList, $devAddr);
$par = shift @$a;
}
elsif ($par eq 'channel') {
$par = shift @$a; $par = shift @$a;
} }
} }
my $devDesc = HMCCU_GetDeviceDesc ($hash, undef, $ccuobj);
return HMCCU_SetError ($hash, "Can't get device description") if (!defined($devDesc));
if (scalar(@addList) == 0) {
push (@addList, "$devAddr:0", $ccuaddr);
}
my $paramset = 'ALL'; my $paramset = 'ALL';
if (defined($par) && $devDesc->{PARAMSETS} =~ /$par/) { if (defined($par)) {
$paramset = $par; $paramset = $par;
$par = shift @$a; $par = shift @$a;
} }
@ -568,85 +581,79 @@ sub HMCCUCHN_Get ($@)
$par = '.*' if (!defined ($par)); $par = '.*' if (!defined ($par));
my $res = ''; my $res = '';
foreach my $ps (split (',', $devDesc->{PARAMSETS})) { foreach my $a (@addList) {
next if ($ps ne $paramset && $paramset ne 'ALL'); my $devDesc = HMCCU_GetDeviceDesc ($hmccu_hash, $a, $ccuif);
($rc, $result) = HMCCU_RPCRequest ($hash, "getParamset", $ccuobj, $ps, undef, $par); return HMCCU_SetError ($hash, "Can't get device description") if (!defined($devDesc));
return HMCCU_SetError ($hash, $rc, $result) if ($rc < 0);
$res .= "$result\n";
}
return $ccureadings ? undef : $res; $res .= $a eq $devAddr ? "Device $a\n" : "Channel $a\n";
} foreach my $ps (split (',', $devDesc->{PARAMSETS})) {
elsif ($opt eq 'configlist') { next if (($ps ne $paramset && $paramset ne 'ALL') || ($ps ne 'MASTER' && $ps ne 'LINK'));
my $ccuobj = $ccuaddr; $res .= " Paramset $ps\n";
my $par = shift @$a; ($rc, $result) = HMCCU_RPCRequest ($hash, $method, $a, $ps, undef, $par);
if (defined ($par)) { return HMCCU_SetError ($hash, $rc, $result) if ($rc < 0);
if ($par eq 'device') { $res .= $opt eq 'config' ?
($ccuobj, undef) = HMCCU_SplitChnAddr ($ccuaddr); $result :
$par = shift @$a; join ("\n", map { $_ =~ /$par/ ?
" ".$_.' = '.HMCCU_GetParamValue ($hmccu_hash, $devDesc, $ps, $_, $result->{$_}) : ()
} sort keys %$result)."\n";
} }
} }
$par = '.*' if (!defined ($par));
my $devDesc = HMCCU_GetDeviceDesc ($hash, undef, $ccuobj);
return HMCCU_SetError ($hash, "Can't get device description") if (!defined($devDesc));
my $res = ''; return $ccureadings && $opt eq 'config' ? undef : $res;
foreach my $paramset (split (',', $devDesc->{PARAMSETS})) {
next if ($paramset ne 'MASTER' && $paramset ne 'LINK');
$res .= "$paramset:\n";
($rc, $result) = HMCCU_RPCRequest ($hash, "listParamset", $ccuobj, $paramset, undef, $par);
$res .= "$result\n";
}
return $res;
} }
elsif ($opt eq 'configdesc') { elsif ($opt eq 'paramsetdesc') {
my $ccuobj = $ccuaddr; my $ccuobj = $ccuaddr;
my ($devAddr, $chnNo) = HMCCU_SplitChnAddr ($ccuaddr);
my $par = shift @$a; my $par = shift @$a;
if (defined ($par) && $par eq 'device') { my ($devAddr, $chnNo) = HMCCU_SplitChnAddr ($ccuaddr);
$ccuobj = $devAddr; $chnNo = 'd' if (defined ($par) && $par eq 'device');
$chnNo = 'd';
}
my $model = HMCCU_GetClientDeviceModel ($hash, $chnNo); my $model = HMCCU_GetClientDeviceModel ($hash);
return HMCCU_SetError ($hash, "Can't get device model") if (!defined($model)); return HMCCU_SetError ($hash, "Can't get device model") if (!defined($model));
my $res = ''; my $res = '';
foreach my $ps (keys %{$model}) { foreach my $c (sort keys %{$model}) {
next if ($ps ne 'MASTER' && $ps ne 'LINK'); next if (($chnNo eq 'd' && $c ne 'd') || ($chnNo ne 'd' && $c ne '0' && $c ne $chnNo));
$res .= "$ps:\n"; $res .= $c eq 'd' ? "Device\n" : "Channel $c\n";
$result = join ("\n", map { foreach my $ps (sort keys %{$model->{$c}}) {
$_.': '. $res .= " Paramset $ps\n";
$model->{$ps}{$_}{TYPE}. $result = join ("\n", map {
" [".HMCCU_FlagsToStr ('model', 'OPERATIONS', $model->{$ps}{$_}{OPERATIONS}, ',', '')."]". " ".$_.": ".
" [".HMCCU_FlagsToStr ('model', 'FLAGS', $model->{$ps}{$_}{FLAGS}, ',', '')."]". $model->{$c}{$ps}{$_}{TYPE}.
" RANGE=".$model->{$ps}{$_}{MIN}."-".$model->{$ps}{$_}{MAX}. " [".HMCCU_FlagsToStr ('model', 'OPERATIONS', $model->{$c}{$ps}{$_}{OPERATIONS}, ',', '')."]".
" DFLT=".$model->{$ps}{$_}{DEFAULT}. " [".HMCCU_FlagsToStr ('model', 'FLAGS', $model->{$c}{$ps}{$_}{FLAGS}, ',', '')."]".
" UNIT=".$model->{$ps}{$_}{UNIT} " RANGE=".$model->{$c}{$ps}{$_}{MIN}."-".$model->{$c}{$ps}{$_}{MAX}.
} sort keys %{$model->{$ps}}); " DFLT=".$model->{$c}{$ps}{$_}{DEFAULT}.
$res .= "$result\n"; " UNIT=".$model->{$c}{$ps}{$_}{UNIT}
} sort keys %{$model->{$c}{$ps}});
$res .= "$result\n";
}
} }
return $res; return $res;
} }
elsif ($opt eq 'devicedesc') { elsif ($opt eq 'devicedesc') {
my $ccuobj = $ccuaddr; my $ccuobj = $ccuaddr;
my $par = shift @$a; my $par = shift @$a;
if (defined ($par) && $par eq 'device') { my @addList = ();
($ccuobj, undef) = HMCCU_SplitChnAddr ($ccuaddr); my ($devAddr, $chnNo) = HMCCU_SplitChnAddr ($ccuaddr);
if (defined($par) && $par eq 'device') {
push (@addList, $devAddr);
}
else {
push (@addList, "$devAddr:0");
push (@addList, $ccuaddr);
} }
my $devDesc = HMCCU_GetDeviceDesc ($hash);
return HMCCU_SetError ($hash, "Can't get device description") if (!defined($devDesc));
$result = ''; $result = '';
foreach my $n (sort keys %{$devDesc}) { foreach my $a (@addList) {
next if ($n =~ /^_/); my $devDesc = HMCCU_GetDeviceDesc ($hmccu_hash, $a, $ccuif);
if ($n eq 'FLAGS' || $n eq 'DIRECTION' || $n eq 'RX_MODE') { return HMCCU_SetError ($hash, "Can't get device description")
$result .= "$n: ".HMCCU_FlagsToStr ('device', $n, $devDesc->{$n}, ',', '')."\n"; if (!defined($devDesc));
}
else { $result .= $a eq $devAddr ? "Device $a\n" : "Channel $a\n";
$result .= "$n: $devDesc->{$n}\n"; foreach my $n (sort keys %{$devDesc}) {
next if ($n =~ /^_/);
$result .= " $n: ".HMCCU_FlagsToStr ('device', $n, $devDesc->{$n}, ',', '')."\n";
} }
} }
@ -662,8 +669,8 @@ sub HMCCUCHN_Get ($@)
my @valuelist; my @valuelist;
my $valuecount = HMCCU_GetValidDatapoints ($hash, $hash->{ccutype}, $c, 1, \@valuelist); my $valuecount = HMCCU_GetValidDatapoints ($hash, $hash->{ccutype}, $c, 1, \@valuelist);
$retmsg .= ":".join(",",@valuelist) if ($valuecount > 0); $retmsg .= ":".join(",",@valuelist) if ($valuecount > 0);
$retmsg .= " update:noArg deviceinfo config configlist". $retmsg .= " update:noArg deviceinfo:noArg config configlist:channel,device".
" configdesc:channel,device devicedesc:channel,device"; " devicedesc:channel,device paramsetdesc:channel,device";
return $retmsg; return $retmsg;
} }
@ -712,11 +719,8 @@ sub HMCCUCHN_Get ($@)
Delete readings matching specified reading name expression. Default expression is '.*'. Delete readings matching specified reading name expression. Default expression is '.*'.
Readings 'state' and 'control' are not deleted. Readings 'state' and 'control' are not deleted.
</li><br/> </li><br/>
<li><b>set &lt;name&gt; config [device] [&lt;rpcport&gt;] &lt;parameter&gt;=&lt;value&gt;] <li><b>set &lt;name&gt; config</b><br/>
[...]</b><br/> Alias for command 'set paramset' with default value for parameter set = 'MASTER'.
Set config parameters of CCU channel. This is equal to setting device parameters in CCU.
Valid parameters can be listed by using commands 'get configdesc' or 'get configlist'.
With option 'device' specified parameters are set in device instead of channel.
</li><br/> </li><br/>
<li><b>set &lt;name&gt; datapoint &lt;datapoint&gt; &lt;value&gt; [...]</b><br/> <li><b>set &lt;name&gt; datapoint &lt;datapoint&gt; &lt;value&gt; [...]</b><br/>
Set datapoint values of a CCU channel. If parameter <i>value</i> contains special Set datapoint values of a CCU channel. If parameter <i>value</i> contains special
@ -753,18 +757,6 @@ sub HMCCUCHN_Get ($@)
set myswitch on set myswitch on
</code> </code>
</li><br/> </li><br/>
<li><b>set &lt;name&gt; toggle</b><br/>
Toggle state datapoint between values defined by attribute 'statevals'. This command is
only available if attribute 'statevals' is set. Toggling supports more than two state
values.
<br/><br/>
Example: Toggle blind actor<br/>
<code>
attr myswitch statedatapoint LEVEL<br/>
attr myswitch statevals up:100,down:0<br/>
set myswitch toggle
</code>
</li><br/>
<li><b>set &lt;name&gt; on-for-timer &lt;ontime&gt;</b><br/> <li><b>set &lt;name&gt; on-for-timer &lt;ontime&gt;</b><br/>
Switch device on for specified number of seconds. This command is only available if Switch device on for specified number of seconds. This command is only available if
channel contains a datapoint ON_TIME. The attribute 'statevals' must contain at least a channel contains a datapoint ON_TIME. The attribute 'statevals' must contain at least a
@ -783,6 +775,15 @@ sub HMCCUCHN_Get ($@)
ON_TIME. The attribute 'statevals' must contain at least a value for 'on'. The Attribute ON_TIME. The attribute 'statevals' must contain at least a value for 'on'. The Attribute
'statedatapoint' must be set to a writeable datapoint. 'statedatapoint' must be set to a writeable datapoint.
</li><br/> </li><br/>
<li><b>set &lt;name&gt; paramset [device] [&lt;paramset&gt;] &lt;parameter&gt;=&lt;value[:&lt;type&gt;]&gt; [...]</b><br/>
Set multiple datapoints or config parameters by using RPC interface instead of Rega.
With option 'device' a parameter set of the device is set instead of the current channel.
Parameter <i>paramset</i> is a valid parameter set name (i.e. MASTER, LINK, ...). The
default parameter set is 'VALUES'.
Supports attribute 'ccuscaleval' for datapoints. Parameter <i>parameter</i> must be a valid
datapoint or config parameter name. The default <i>type</i> is STRING.
Valid types are STRING, BOOL, INTEGER, FLOAT, DOUBLE.
</li><br/>
<li><b>set &lt;name&gt; pct &lt;value&gt; [&lt;ontime&gt; [&lt;ramptime&gt;]]</b><br/> <li><b>set &lt;name&gt; pct &lt;value&gt; [&lt;ontime&gt; [&lt;ramptime&gt;]]</b><br/>
Set datapoint LEVEL of a channel to the specified <i>value</i>. Optionally a <i>ontime</i> Set datapoint LEVEL of a channel to the specified <i>value</i>. Optionally a <i>ontime</i>
and a <i>ramptime</i> (both in seconds) can be specified. This command is only available and a <i>ramptime</i> (both in seconds) can be specified. This command is only available
@ -798,10 +799,20 @@ sub HMCCUCHN_Get ($@)
set myswitch pct 100 600 10 set myswitch pct 100 600 10
</code> </code>
</li><br/> </li><br/>
<li><b>set &lt;name&gt; rpcparameter { VALUES | MASTER | LINK } &lt;parameter&gt;=&lt;value&gt; [...]</b><br/> <li><b>set &lt;name&gt; rpcparamter</b><br/>
Set multiple datapoints or config parameters by using RPC interface instead of Rega. Alias for command 'set paramset'.
Supports attribute 'ccuscaleval' for datapoints. Parameter <i>parameter</i> must be a valid </li><br/>
datapoint or config parameter name. <li><b>set &lt;name&gt; toggle</b><br/>
Toggle state datapoint between values defined by attribute 'statevals'. This command is
only available if attribute 'statevals' is set. Toggling supports more than two state
values.
<br/><br/>
Example: Toggle blind actor<br/>
<code>
attr myswitch statedatapoint LEVEL<br/>
attr myswitch statevals up:100,down:0<br/>
set myswitch toggle
</code>
</li><br/> </li><br/>
<li><b>set &lt;name&gt; up [&lt;value&gt;]</b><br/> <li><b>set &lt;name&gt; up [&lt;value&gt;]</b><br/>
Increment value of datapoint LEVEL. This command is only available if channel contains Increment value of datapoint LEVEL. This command is only available if channel contains
@ -813,18 +824,15 @@ sub HMCCUCHN_Get ($@)
<a name="HMCCUCHNget"></a> <a name="HMCCUCHNget"></a>
<b>Get</b><br/><br/> <b>Get</b><br/><br/>
<ul> <ul>
<li><b>get &lt;name&gt; config [device] [&lt;paramset&gt;|<u>ALL</u>] [&lt;filter-expr&gt;]</b><br/> <li><b>get &lt;name&gt; config [<u>channel</u>|device] [&lt;paramset&gt;|<u>ALL</u>] [&lt;filter-expr&gt;]</b><br/>
Get configuration parameters of CCU channel. If attribute 'ccureadings' is 0 results Get configuration parameters of CCU channel. If attribute 'ccureadings' is 0 results
are displayed in browser window. Parameters can be filtered by <i>filter-expr</i>. are displayed in browser window. Otherwise they are stored as readings beginning with "R_".
Parameters to be stored as readings must be part of 'ccureadingfilter'. If option Parameters can be filtered by <i>filter-expr</i>.
'device' is specified parameters of device are read. If option 'device' is specified parameters of device are read. Without option 'device'
parameters of current channel and channel 0 are read.
</li><br/> </li><br/>
<li><b>get &lt;name&gt; configdesc [<u>channel</u>|device]</b><br/> <li><b>get &lt;name&gt; configlist [<u>channel</u>|device] [&lt;paramset&gt;|<u>ALL</u>] [&lt;filter-expr&gt;]</b><br/>
Display description of configuration parameters of CCU channel or device. Same as 'get config' without storing parameters as readings.
</li><br/>
<li><b>get &lt;name&gt; configlist [device] [&lt;filter-expr&gt;]</b><br/>
Display configuration parameters of CCU channel. Parameters can be filtered by
<i>filter-expr</i>. With option 'device' device parameters are listed.
</li><br/> </li><br/>
<li><b>get &lt;name&gt; datapoint &lt;datapoint&gt;</b><br/> <li><b>get &lt;name&gt; datapoint &lt;datapoint&gt;</b><br/>
Get value of a CCU channel datapoint. Get value of a CCU channel datapoint.
@ -833,9 +841,9 @@ sub HMCCUCHN_Get ($@)
Display default attributes for CCU device type. Display default attributes for CCU device type.
</li><br/> </li><br/>
<li><b>get &lt;name&gt; devicedesc [<u>channel</u>|device]</b><br/> <li><b>get &lt;name&gt; devicedesc [<u>channel</u>|device]</b><br/>
Display device description. Display device or channel description. A channel description always includes channel 0.
</li><br/> </li><br/>
<li><b>get &lt;name&gt; deviceinfo [{State | <u>Value</u>}]</b><br/> <li><b>get &lt;name&gt; deviceinfo</b><br/>
Display all channels and datapoints of device with datapoint values and types. Display all channels and datapoints of device with datapoint values and types.
</li><br/> </li><br/>
<li><b>get &lt;name&gt; devstate</b><br/> <li><b>get &lt;name&gt; devstate</b><br/>
@ -843,6 +851,9 @@ sub HMCCUCHN_Get ($@)
attribute 'statedatapoint'. Command will fail if state datapoint does not exist in attribute 'statedatapoint'. Command will fail if state datapoint does not exist in
channel. channel.
</li><br/> </li><br/>
<li><b>get &lt;name&gt; paramsetdesc [<u>channel</u>|device]</b><br/>
Display description of parameter sets of CCU channel or device.
</li><br/>
<li><b>get &lt;name&gt; update [{State | <u>Value</u>}]</b><br/> <li><b>get &lt;name&gt; update [{State | <u>Value</u>}]</b><br/>
Update all datapoints / readings of channel. With option 'State' the device is queried. Update all datapoints / readings of channel. With option 'State' the device is queried.
This request method is more accurate but slower then 'Value'. This request method is more accurate but slower then 'Value'.

View File

@ -701,7 +701,7 @@ sub HMCCUDEV_Get ($@)
# Log commands # Log commands
HMCCU_Log ($hash, 3, "get $name $opt ".join (' ', @$a)) HMCCU_Log ($hash, 3, "get $name $opt ".join (' ', @$a))
if ($ccuflags =~ /logCommand/ || HMCCU_IsFlag ($hmccu_name, 'logCommand')); if ($opt ne '?' && $ccuflags =~ /logCommand/ || HMCCU_IsFlag ($hmccu_name, 'logCommand'));
if ($opt eq 'devstate') { if ($opt eq 'devstate') {
return HMCCU_SetError ($hash, -11) if ($sc eq ''); return HMCCU_SetError ($hash, -11) if ($sc eq '');

View File

@ -404,13 +404,13 @@ sub HMCCURPCPROC_InitDevice ($$) {
} }
# Read RPC device descriptions # Read RPC device descriptions
if ($dev_hash->{rpcinterface} ne 'CUxD') { # if ($dev_hash->{rpcinterface} ne 'CUxD') {
HMCCU_Log ($dev_hash, 1, "Updating internal device tables"); # HMCCU_Log ($dev_hash, 1, "Updating internal device tables");
HMCCU_ResetDeviceTables ($hmccu_hash, $dev_hash->{rpcinterface}); # HMCCU_ResetDeviceTables ($hmccu_hash, $dev_hash->{rpcinterface});
my $cd = HMCCURPCPROC_GetDeviceDesc ($dev_hash); # my $cd = HMCCURPCPROC_GetDeviceDesc ($dev_hash);
my $cm = HMCCURPCPROC_GetParamsetDesc ($dev_hash); # my $cm = HMCCURPCPROC_GetParamsetDesc ($dev_hash);
HMCCU_Log ($dev_hash, 1, "Read $cd channel and device descriptions and $cm device models from CCU"); # HMCCU_Log ($dev_hash, 1, "Read $cd channel and device descriptions and $cm device models from CCU");
} # }
# RPC device ready # RPC device ready
HMCCURPCPROC_ResetRPCState ($dev_hash); HMCCURPCPROC_ResetRPCState ($dev_hash);
@ -639,8 +639,21 @@ sub HMCCURPCPROC_Get ($@)
my $rc; my $rc;
if ($opt eq 'deviceDesc') { if ($opt eq 'deviceDesc') {
my $address = shift @$a; my $address;
HMCCU_ResetDeviceTables ($ioHash, $hash->{rpcinterface}); my $object = shift @$a;
if (defined($object)) {
if (exists($defs{$object})) {
my $clHash = $defs{$object};
my $clType = $clHash->{TYPE};
return HMCCURPCPROC_SetError ($hash, "Illegal device type $clType", 2)
if ($clType ne 'HMCCUCHN' && $clType ne 'HMCCUDEV');
$address = $clHash->{ccuaddr};
}
else {
$address = $object;
}
}
HMCCU_ResetDeviceTables ($ioHash, $hash->{rpcinterface}, $address);
my $cd = HMCCURPCPROC_GetDeviceDesc ($hash, $address); my $cd = HMCCURPCPROC_GetDeviceDesc ($hash, $address);
my $cm = HMCCURPCPROC_GetParamsetDesc ($hash, $address); my $cm = HMCCURPCPROC_GetParamsetDesc ($hash, $address);
return "Read $cd channel and device descriptions and $cm device models from CCU"; return "Read $cd channel and device descriptions and $cm device models from CCU";
@ -1184,7 +1197,7 @@ sub HMCCURPCPROC_GetParamsetDesc ($;$)
my $c = 0; my $c = 0;
if (defined($address)) { if (defined($address)) {
my $devDesc = HMCCU_GetDeviceDesc ($ioHash, $hash->{rpcinterface}, $address); my $devDesc = HMCCU_GetDeviceDesc ($ioHash, $address, $hash->{rpcinterface});
return 0 if (!defined($devDesc) || !defined($devDesc->{PARAMSETS}) || $devDesc->{PARAMSETS} eq '' || return 0 if (!defined($devDesc) || !defined($devDesc->{PARAMSETS}) || $devDesc->{PARAMSETS} eq '' ||
!exists($devDesc->{_fw_ver})); !exists($devDesc->{_fw_ver}));
@ -1823,6 +1836,7 @@ sub HMCCURPCPROC_StopRPCServer ($$)
# "BASE64" = $BINRPC_BASE64 # "BASE64" = $BINRPC_BASE64
# "ARRAY" = $BINRPC_ARRAY # "ARRAY" = $BINRPC_ARRAY
# "STRUCT" = $BINRPC_STRUCT # "STRUCT" = $BINRPC_STRUCT
# The default parameter type is "STRING".
# Return response or undef on error. # Return response or undef on error.
###################################################################### ######################################################################
@ -3104,9 +3118,12 @@ sub HMCCURPCPROC_DecodeResponse ($)
<a name="HMCCURPCPROCget"></a> <a name="HMCCURPCPROCget"></a>
<b>Get</b><br/><br/> <b>Get</b><br/><br/>
<ul> <ul>
<li><b>get &lt;name&gt; devicedesc [&lt;address&gt;]</b><br/> <li><b>get &lt;name&gt; devicedesc [&lt;fhem-device&gt;|&lt;address&gt;]</b><br/>
Read device descriptions from CCU. If no <i>address</i> is specified, all devices are Read device and paramset descriptions for current RPC interface from CCU and
read. Parameter <i>address</i> can be a device or a channel address. store the information in I/O device. The device description is always read from
CCU. The paramset description is only read if it doesn't exist in IO device.
If a HMCCUCHN device or a channel address is specified, the description of the
corresponding device address with all channels is read.
</li><br/> </li><br/>
<li><b>get &lt;name&gt; rpcevent</b><br/> <li><b>get &lt;name&gt; rpcevent</b><br/>
Show RPC server events statistics. If attribute ccuflags contains flag 'statistics' Show RPC server events statistics. If attribute ccuflags contains flag 'statistics'