From 6092fb76a59caaf664d42d831f7ae571116f97cb Mon Sep 17 00:00:00 2001 From: zap <> Date: Fri, 10 Jan 2020 16:04:11 +0000 Subject: [PATCH] HMCCU: Update for 4.4 beta git-svn-id: https://svn.fhem.de/fhem/trunk@20934 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/contrib/HMCCU/FHEM/88_HMCCU.pm | 160 +++++++++--- fhem/contrib/HMCCU/FHEM/88_HMCCUCHN.pm | 275 +++++++++++---------- fhem/contrib/HMCCU/FHEM/88_HMCCUDEV.pm | 2 +- fhem/contrib/HMCCU/FHEM/88_HMCCURPCPROC.pm | 43 +++- 4 files changed, 299 insertions(+), 181 deletions(-) diff --git a/fhem/contrib/HMCCU/FHEM/88_HMCCU.pm b/fhem/contrib/HMCCU/FHEM/88_HMCCU.pm index dc137c5c8..f4483a37e 100644 --- a/fhem/contrib/HMCCU/FHEM/88_HMCCU.pm +++ b/fhem/contrib/HMCCU/FHEM/88_HMCCU.pm @@ -293,8 +293,8 @@ sub HMCCU_GetClientDeviceModel ($;$); sub HMCCU_GetDefaultInterface ($); sub HMCCU_GetDeviceAddresses ($;$$); sub HMCCU_GetDeviceChannels ($$$); -sub HMCCU_GetDeviceDesc ($;$$); -sub HMCCU_GetDeviceInfo ($$$); +sub HMCCU_GetDeviceDesc ($$;$); +sub HMCCU_GetDeviceInfo ($$;$); sub HMCCU_GetDeviceInterface ($$$); sub HMCCU_GetDeviceList ($); sub HMCCU_GetDeviceModel ($$$;$); @@ -303,10 +303,12 @@ sub HMCCU_GetDeviceType ($$$); sub HMCCU_GetFirmwareVersions ($$); sub HMCCU_GetGroupMembers ($$); sub HMCCU_GetMatchingDevices ($$$$); +sub HMCCU_GetParamDef ($$$$); +sub HMCCU_GetParamValue ($$$$$); sub HMCCU_IsValidChannel ($$$); sub HMCCU_IsValidDevice ($$$); sub HMCCU_IsValidDeviceOrChannel ($$$); -sub HMCCU_ResetDeviceTables ($$); +sub HMCCU_ResetDeviceTables ($;$$); sub HMCCU_UpdateDeviceTable ($$); # Handle datapoints @@ -3320,18 +3322,22 @@ sub HMCCU_UpdateDeviceTable ($$) # Delete device table entries ###################################################################### -sub HMCCU_ResetDeviceTables ($$) +sub HMCCU_ResetDeviceTables ($;$$) { - my ($hash, $iface) = @_; + my ($hash, $iface, $address) = @_; if (defined($iface)) { - $hash->{hmccu}{device}{$iface} = (); + if (defined($address)) { + $hash->{hmccu}{device}{$iface}{$address} = (); + } + else { + $hash->{hmccu}{device}{$iface} = (); + } } else { $hash->{hmccu}{device} = (); + $hash->{hmccu}{model} = (); } - - $hash->{hmccu}{model} = (); } ###################################################################### @@ -3358,7 +3364,7 @@ sub HMCCU_AddDeviceDesc ($$$$) if (ref($desc->{$p}) eq 'ARRAY') { $hash->{hmccu}{device}{$iface}{$k}{$p} = join(',', @{$desc->{$p}}); } - elsif ($p ne $key) { + else { $hash->{hmccu}{device}{$iface}{$k}{$p} = $desc->{$p}; } } @@ -3383,31 +3389,32 @@ sub HMCCU_AddDeviceDesc ($$$$) } ###################################################################### -# Get device description +# Get device description. # Parameters: -# $hash - Hash reference of IO device or client device. For client -# devices the parameters $iface and $address are taken from -# client device hash if set to undef. -# $iface - Interface name. +# $hash - Hash reference of IO device. # $address - Address of device or channel. +# $iface - Interface name. # Return hash reference for device description or undef on error. ###################################################################### -sub HMCCU_GetDeviceDesc ($;$$) +sub HMCCU_GetDeviceDesc ($$;$) { - my ($hash, $iface, $address) = @_; - my $ioHash = HMCCU_GetHash ($hash); - - if ($hash->{TYPE} eq 'HMCCUDEV' || $hash->{TYPE} eq 'HMCCUCHN') { - $iface = $hash->{ccuif} if (!defined($iface)); - $address = $hash->{ccuaddr} if (!defined($address)); + my ($hash, $address, $iface) = @_; + + my @ifaceList = (); + if (defined($iface)) { + push (@ifaceList, $iface); } else { - return undef if (!defined($iface) || !defined($address)); + push (@ifaceList, keys %${$hash->{hmccu}{device}}); } - - return (exists ($ioHash->{hmccu}{device}{$iface}{$address}) ? - $ioHash->{hmccu}{device}{$iface}{$address} : undef); + + foreach my $i (@ifaceList) { + 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 ($;$) { - 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 $devDesc = HMCCU_GetDeviceDesc ($hash); + my $ioHash = HMCCU_GetHash ($clHash); + my $devDesc = HMCCU_GetDeviceDesc ($ioHash, $clHash->{ccuaddr}, $clHash->{ccuif}); return defined($devDesc) ? 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 # Parameters: @@ -3574,7 +3658,8 @@ sub HMCCU_GetClientDeviceModel ($;$) # $value - Value of parameter. # $sep - String separator. Default = ''. # $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 ($$$;$$) @@ -3596,7 +3681,7 @@ sub HMCCU_FlagsToStr ($$$;$$) } ); - return '' if (!exists($bitmasks{$set}{$flag})); + return $value if (!exists($bitmasks{$set}{$flag})); my @list = (); foreach my $b (sort keys %{$bitmasks{$set}{$flag}}) { @@ -4530,7 +4615,7 @@ sub HMCCU_IsRPCServerRunning ($$$) # Get channels and datapoints of CCU device ###################################################################### -sub HMCCU_GetDeviceInfo ($$$) +sub HMCCU_GetDeviceInfo ($$;$) { my ($hash, $device, $ccuget) = @_; my $name = $hash->{NAME}; @@ -4540,6 +4625,8 @@ sub HMCCU_GetDeviceInfo ($$$) my $hmccu_hash = HMCCU_GetHash ($hash); return '' if (!defined ($hmccu_hash)); + $ccuget = 'Value' if (!defined($ccuget)); + my @devlist; if ($hash->{ccuif} eq 'fhem' && exists ($hash->{ccugroup})) { push @devlist, split (",", $hash->{ccugroup}); @@ -7298,8 +7385,8 @@ sub HMCCU_UpdateCB ($$$) ###################################################################### # Execute RPC request # Parameters: -# $method - RPC request method. Use listParamset as an alias for -# getParamset if readings should not be updated. +# $method - RPC request method. Use listParamset or listRawParamset +# as an alias for getParamset if readings should not be updated. # $address - Device address. # $paramset - paramset name: VALUE, MASTER, LINK, ... # $parref - Hash reference with parameter/value pairs (optional). @@ -7316,7 +7403,7 @@ sub HMCCU_RPCRequest ($$$$$;$) my $type = $clHash->{TYPE}; my $fnc = "RPCRequest"; - my $reqMethod = $method eq 'listParamset' ? 'getParamset' : $method; + my $reqMethod = $method eq 'listParamset' || $method eq 'listRawParamset' ? 'getParamset' : $method; $filter = '.*' if (!defined ($filter)); my $addr = ''; my $result = ''; @@ -7382,6 +7469,9 @@ sub HMCCU_RPCRequest ($$$$$;$) if ($method eq 'listParamset') { $result = join ("\n", map { $_ =~ /$filter/ ? $_.'='.$reqResult->{$_} : () } keys %$reqResult); } + elsif ($method eq 'listRawParamset') { + $result = $reqResult; + } elsif ($method eq 'getDeviceDescription') { $result = ''; foreach my $k (sort keys %$reqResult) { diff --git a/fhem/contrib/HMCCU/FHEM/88_HMCCUCHN.pm b/fhem/contrib/HMCCU/FHEM/88_HMCCUCHN.pm index b7ef31037..1d64d8865 100644 --- a/fhem/contrib/HMCCU/FHEM/88_HMCCUCHN.pm +++ b/fhem/contrib/HMCCU/FHEM/88_HMCCUCHN.pm @@ -4,7 +4,7 @@ # # $Id: 88_HMCCUCHN.pm 18552 2019-02-10 11:52:28Z zap $ # -# Version 4.4.000 +# Version 4.4.001 # # (c) 2020 zap (zap01 t-online de) # @@ -170,6 +170,11 @@ sub HMCCUCHN_Attr ($@) { my ($cmd, $name, $attrname, $attrval) = @_; my $hash = $defs{$name}; + + my %resetReadings = ( + 'ccureadingfilter' => 1, 'ccureadingname' => 1, 'substitute' => 1, + 'ccuscaleval' => 1 + ); if ($cmd eq "set") { 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; } @@ -209,7 +223,7 @@ sub HMCCUCHN_Set ($@) return "No set command specified" if (!defined ($opt)); 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 return undef if (!defined ($hash->{ccudevstate}) || $hash->{ccudevstate} eq 'pending' || @@ -405,35 +419,32 @@ sub HMCCUCHN_Set ($@) HMCCU_DeleteReadings ($hash, $rnexp); return HMCCU_SetState ($hash, "OK"); } - elsif ($opt eq 'config') { - return HMCCU_SetError ($hash, "Usage: set $name config [device] {parameter}={value} [...]") - 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} [...]") + elsif ($opt eq 'paramset' || $opt eq 'rpcparameter' || $opt eq 'config') { + return HMCCU_SetError ($hash, "Usage: set $name rpcparameter [device] [paramset] {parameter}={value}[:{type}] [...]") if ((scalar keys %{$h}) < 1); + + my $ccuobj = $ccuaddr; my $p = shift @$a; - $p = 'VALUES' if (!defined ($p)); - my $key = uc($p); + if (defined($p) && $p eq 'device') { + ($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); } - elsif ($key eq 'MASTER' || $key eq 'LINK') { - ($rc, $result) = HMCCU_RPCRequest ($hash, "putParamset", $ccuaddr, $key, $h); - } 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)); } elsif ($opt eq 'defaults') { @@ -500,7 +511,7 @@ sub HMCCUCHN_Get ($@) # Log commands 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') { return HMCCU_SetError ($hash, -13) if ($sd eq ''); @@ -536,31 +547,33 @@ sub HMCCUCHN_Get ($@) return undef; } elsif ($opt eq 'deviceinfo') { - my $ccuget = shift @$a; - $ccuget = 'Attr' if (!defined ($ccuget)); - 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); + my ($a, $c) = HMCCU_SplitChnAddr ($ccuaddr); + $result = HMCCU_GetDeviceInfo ($hash, $a); return HMCCU_SetError ($hash, -2) if ($result eq ''); return HMCCU_FormatDeviceInfo ($result); } - elsif ($opt eq 'config') { + elsif ($opt eq 'config' || $opt eq 'configlist') { my $ccuobj = $ccuaddr; + my $method = $opt eq 'config' ? 'getParamset' : 'listRawParamset'; + my ($devAddr, undef) = HMCCU_SplitChnAddr ($ccuaddr); + my @addList = (); my $par = shift @$a; if (defined ($par)) { if ($par eq 'device') { - ($ccuobj, undef) = HMCCU_SplitChnAddr ($ccuaddr); + push (@addList, $devAddr); + $par = shift @$a; + } + elsif ($par eq 'channel') { $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'; - if (defined($par) && $devDesc->{PARAMSETS} =~ /$par/) { + if (defined($par)) { $paramset = $par; $par = shift @$a; } @@ -568,85 +581,79 @@ sub HMCCUCHN_Get ($@) $par = '.*' if (!defined ($par)); my $res = ''; - foreach my $ps (split (',', $devDesc->{PARAMSETS})) { - next if ($ps ne $paramset && $paramset ne 'ALL'); - ($rc, $result) = HMCCU_RPCRequest ($hash, "getParamset", $ccuobj, $ps, undef, $par); - return HMCCU_SetError ($hash, $rc, $result) if ($rc < 0); - $res .= "$result\n"; - } + foreach my $a (@addList) { + my $devDesc = HMCCU_GetDeviceDesc ($hmccu_hash, $a, $ccuif); + return HMCCU_SetError ($hash, "Can't get device description") if (!defined($devDesc)); - return $ccureadings ? undef : $res; - } - elsif ($opt eq 'configlist') { - my $ccuobj = $ccuaddr; - my $par = shift @$a; - if (defined ($par)) { - if ($par eq 'device') { - ($ccuobj, undef) = HMCCU_SplitChnAddr ($ccuaddr); - $par = shift @$a; + $res .= $a eq $devAddr ? "Device $a\n" : "Channel $a\n"; + foreach my $ps (split (',', $devDesc->{PARAMSETS})) { + next if (($ps ne $paramset && $paramset ne 'ALL') || ($ps ne 'MASTER' && $ps ne 'LINK')); + $res .= " Paramset $ps\n"; + ($rc, $result) = HMCCU_RPCRequest ($hash, $method, $a, $ps, undef, $par); + return HMCCU_SetError ($hash, $rc, $result) if ($rc < 0); + $res .= $opt eq 'config' ? + $result : + 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 = ''; - 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; + return $ccureadings && $opt eq 'config' ? undef : $res; } - elsif ($opt eq 'configdesc') { + elsif ($opt eq 'paramsetdesc') { my $ccuobj = $ccuaddr; - my ($devAddr, $chnNo) = HMCCU_SplitChnAddr ($ccuaddr); my $par = shift @$a; - if (defined ($par) && $par eq 'device') { - $ccuobj = $devAddr; - $chnNo = 'd'; - } + my ($devAddr, $chnNo) = HMCCU_SplitChnAddr ($ccuaddr); + $chnNo = 'd' if (defined ($par) && $par eq 'device'); - my $model = HMCCU_GetClientDeviceModel ($hash, $chnNo); + my $model = HMCCU_GetClientDeviceModel ($hash); return HMCCU_SetError ($hash, "Can't get device model") if (!defined($model)); my $res = ''; - foreach my $ps (keys %{$model}) { - next if ($ps ne 'MASTER' && $ps ne 'LINK'); - $res .= "$ps:\n"; - $result = join ("\n", map { - $_.': '. - $model->{$ps}{$_}{TYPE}. - " [".HMCCU_FlagsToStr ('model', 'OPERATIONS', $model->{$ps}{$_}{OPERATIONS}, ',', '')."]". - " [".HMCCU_FlagsToStr ('model', 'FLAGS', $model->{$ps}{$_}{FLAGS}, ',', '')."]". - " RANGE=".$model->{$ps}{$_}{MIN}."-".$model->{$ps}{$_}{MAX}. - " DFLT=".$model->{$ps}{$_}{DEFAULT}. - " UNIT=".$model->{$ps}{$_}{UNIT} - } sort keys %{$model->{$ps}}); - $res .= "$result\n"; + foreach my $c (sort keys %{$model}) { + next if (($chnNo eq 'd' && $c ne 'd') || ($chnNo ne 'd' && $c ne '0' && $c ne $chnNo)); + $res .= $c eq 'd' ? "Device\n" : "Channel $c\n"; + foreach my $ps (sort keys %{$model->{$c}}) { + $res .= " Paramset $ps\n"; + $result = join ("\n", map { + " ".$_.": ". + $model->{$c}{$ps}{$_}{TYPE}. + " [".HMCCU_FlagsToStr ('model', 'OPERATIONS', $model->{$c}{$ps}{$_}{OPERATIONS}, ',', '')."]". + " [".HMCCU_FlagsToStr ('model', 'FLAGS', $model->{$c}{$ps}{$_}{FLAGS}, ',', '')."]". + " RANGE=".$model->{$c}{$ps}{$_}{MIN}."-".$model->{$c}{$ps}{$_}{MAX}. + " DFLT=".$model->{$c}{$ps}{$_}{DEFAULT}. + " UNIT=".$model->{$c}{$ps}{$_}{UNIT} + } sort keys %{$model->{$c}{$ps}}); + $res .= "$result\n"; + } } return $res; } elsif ($opt eq 'devicedesc') { my $ccuobj = $ccuaddr; my $par = shift @$a; - if (defined ($par) && $par eq 'device') { - ($ccuobj, undef) = HMCCU_SplitChnAddr ($ccuaddr); + my @addList = (); + 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 = ''; - foreach my $n (sort keys %{$devDesc}) { - next if ($n =~ /^_/); - if ($n eq 'FLAGS' || $n eq 'DIRECTION' || $n eq 'RX_MODE') { - $result .= "$n: ".HMCCU_FlagsToStr ('device', $n, $devDesc->{$n}, ',', '')."\n"; - } - else { - $result .= "$n: $devDesc->{$n}\n"; + foreach my $a (@addList) { + my $devDesc = HMCCU_GetDeviceDesc ($hmccu_hash, $a, $ccuif); + return HMCCU_SetError ($hash, "Can't get device description") + if (!defined($devDesc)); + + $result .= $a eq $devAddr ? "Device $a\n" : "Channel $a\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 $valuecount = HMCCU_GetValidDatapoints ($hash, $hash->{ccutype}, $c, 1, \@valuelist); $retmsg .= ":".join(",",@valuelist) if ($valuecount > 0); - $retmsg .= " update:noArg deviceinfo config configlist". - " configdesc:channel,device devicedesc:channel,device"; + $retmsg .= " update:noArg deviceinfo:noArg config configlist:channel,device". + " devicedesc:channel,device paramsetdesc:channel,device"; return $retmsg; } @@ -712,11 +719,8 @@ sub HMCCUCHN_Get ($@) Delete readings matching specified reading name expression. Default expression is '.*'. Readings 'state' and 'control' are not deleted.
-
  • set <name> config [device] [<rpcport>] <parameter>=<value>] - [...]
    - 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. +
  • set <name> config
    + Alias for command 'set paramset' with default value for parameter set = 'MASTER'.

  • set <name> datapoint <datapoint> <value> [...]
    Set datapoint values of a CCU channel. If parameter value contains special @@ -753,18 +757,6 @@ sub HMCCUCHN_Get ($@) set myswitch on

  • -
  • set <name> toggle
    - 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. -

    - Example: Toggle blind actor
    - - attr myswitch statedatapoint LEVEL
    - attr myswitch statevals up:100,down:0
    - set myswitch toggle -
    -

  • set <name> on-for-timer <ontime>
    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 @@ -783,6 +775,15 @@ sub HMCCUCHN_Get ($@) ON_TIME. The attribute 'statevals' must contain at least a value for 'on'. The Attribute 'statedatapoint' must be set to a writeable datapoint.

  • +
  • set <name> paramset [device] [<paramset>] <parameter>=<value[:<type>]> [...]
    + 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 paramset is a valid parameter set name (i.e. MASTER, LINK, ...). The + default parameter set is 'VALUES'. + Supports attribute 'ccuscaleval' for datapoints. Parameter parameter must be a valid + datapoint or config parameter name. The default type is STRING. + Valid types are STRING, BOOL, INTEGER, FLOAT, DOUBLE. +

  • set <name> pct <value> [<ontime> [<ramptime>]]
    Set datapoint LEVEL of a channel to the specified value. Optionally a ontime and a ramptime (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 <name> rpcparameter { VALUES | MASTER | LINK } <parameter>=<value> [...]
    - Set multiple datapoints or config parameters by using RPC interface instead of Rega. - Supports attribute 'ccuscaleval' for datapoints. Parameter parameter must be a valid - datapoint or config parameter name. +
  • set <name> rpcparamter
    + Alias for command 'set paramset'. +

  • +
  • set <name> toggle
    + 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. +

    + Example: Toggle blind actor
    + + attr myswitch statedatapoint LEVEL
    + attr myswitch statevals up:100,down:0
    + set myswitch toggle +

  • set <name> up [<value>]
    Increment value of datapoint LEVEL. This command is only available if channel contains @@ -813,18 +824,15 @@ sub HMCCUCHN_Get ($@) Get

      -
    • get <name> config [device] [<paramset>|ALL] [<filter-expr>]
      +
    • get <name> config [channel|device] [<paramset>|ALL] [<filter-expr>]
      Get configuration parameters of CCU channel. If attribute 'ccureadings' is 0 results - are displayed in browser window. Parameters can be filtered by filter-expr. - Parameters to be stored as readings must be part of 'ccureadingfilter'. If option - 'device' is specified parameters of device are read. + are displayed in browser window. Otherwise they are stored as readings beginning with "R_". + Parameters can be filtered by filter-expr. + If option 'device' is specified parameters of device are read. Without option 'device' + parameters of current channel and channel 0 are read.

    • -
    • get <name> configdesc [channel|device]
      - Display description of configuration parameters of CCU channel or device. -

    • -
    • get <name> configlist [device] [<filter-expr>]
      - Display configuration parameters of CCU channel. Parameters can be filtered by - filter-expr. With option 'device' device parameters are listed. +
    • get <name> configlist [channel|device] [<paramset>|ALL] [<filter-expr>]
      + Same as 'get config' without storing parameters as readings.

    • get <name> datapoint <datapoint>
      Get value of a CCU channel datapoint. @@ -833,9 +841,9 @@ sub HMCCUCHN_Get ($@) Display default attributes for CCU device type.

    • get <name> devicedesc [channel|device]
      - Display device description. + Display device or channel description. A channel description always includes channel 0.

    • -
    • get <name> deviceinfo [{State | Value}]
      +
    • get <name> deviceinfo
      Display all channels and datapoints of device with datapoint values and types.

    • get <name> devstate
      @@ -843,6 +851,9 @@ sub HMCCUCHN_Get ($@) attribute 'statedatapoint'. Command will fail if state datapoint does not exist in channel.

    • +
    • get <name> paramsetdesc [channel|device]
      + Display description of parameter sets of CCU channel or device. +

    • get <name> update [{State | Value}]
      Update all datapoints / readings of channel. With option 'State' the device is queried. This request method is more accurate but slower then 'Value'. diff --git a/fhem/contrib/HMCCU/FHEM/88_HMCCUDEV.pm b/fhem/contrib/HMCCU/FHEM/88_HMCCUDEV.pm index 944d85add..74c24cc8a 100644 --- a/fhem/contrib/HMCCU/FHEM/88_HMCCUDEV.pm +++ b/fhem/contrib/HMCCU/FHEM/88_HMCCUDEV.pm @@ -701,7 +701,7 @@ sub HMCCUDEV_Get ($@) # Log commands 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') { return HMCCU_SetError ($hash, -11) if ($sc eq ''); diff --git a/fhem/contrib/HMCCU/FHEM/88_HMCCURPCPROC.pm b/fhem/contrib/HMCCU/FHEM/88_HMCCURPCPROC.pm index b9c65201d..390aefa49 100755 --- a/fhem/contrib/HMCCU/FHEM/88_HMCCURPCPROC.pm +++ b/fhem/contrib/HMCCU/FHEM/88_HMCCURPCPROC.pm @@ -404,13 +404,13 @@ sub HMCCURPCPROC_InitDevice ($$) { } # Read RPC device descriptions - if ($dev_hash->{rpcinterface} ne 'CUxD') { - HMCCU_Log ($dev_hash, 1, "Updating internal device tables"); - HMCCU_ResetDeviceTables ($hmccu_hash, $dev_hash->{rpcinterface}); - my $cd = HMCCURPCPROC_GetDeviceDesc ($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"); - } +# if ($dev_hash->{rpcinterface} ne 'CUxD') { +# HMCCU_Log ($dev_hash, 1, "Updating internal device tables"); +# HMCCU_ResetDeviceTables ($hmccu_hash, $dev_hash->{rpcinterface}); +# my $cd = HMCCURPCPROC_GetDeviceDesc ($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"); +# } # RPC device ready HMCCURPCPROC_ResetRPCState ($dev_hash); @@ -639,8 +639,21 @@ sub HMCCURPCPROC_Get ($@) my $rc; if ($opt eq 'deviceDesc') { - my $address = shift @$a; - HMCCU_ResetDeviceTables ($ioHash, $hash->{rpcinterface}); + my $address; + 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 $cm = HMCCURPCPROC_GetParamsetDesc ($hash, $address); return "Read $cd channel and device descriptions and $cm device models from CCU"; @@ -1184,7 +1197,7 @@ sub HMCCURPCPROC_GetParamsetDesc ($;$) my $c = 0; 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 '' || !exists($devDesc->{_fw_ver})); @@ -1823,6 +1836,7 @@ sub HMCCURPCPROC_StopRPCServer ($$) # "BASE64" = $BINRPC_BASE64 # "ARRAY" = $BINRPC_ARRAY # "STRUCT" = $BINRPC_STRUCT +# The default parameter type is "STRING". # Return response or undef on error. ###################################################################### @@ -3104,9 +3118,12 @@ sub HMCCURPCPROC_DecodeResponse ($) Get

        -
      • get <name> devicedesc [<address>]
        - Read device descriptions from CCU. If no address is specified, all devices are - read. Parameter address can be a device or a channel address. +
      • get <name> devicedesc [<fhem-device>|<address>]
        + Read device and paramset descriptions for current RPC interface from CCU and + 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.

      • get <name> rpcevent
        Show RPC server events statistics. If attribute ccuflags contains flag 'statistics'