From fcacfed9013b3caf20497256b5c3e78aa047fc1a Mon Sep 17 00:00:00 2001 From: zap Date: Tue, 11 Feb 2020 20:13:08 +0000 Subject: [PATCH] HMCCU: Update for 4.4 Beta git-svn-id: https://svn.fhem.de/fhem/trunk@21179 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/contrib/HMCCU/FHEM/88_HMCCU.pm | 341 ++++++++++++++------- fhem/contrib/HMCCU/FHEM/88_HMCCUCHN.pm | 212 ++++++------- fhem/contrib/HMCCU/FHEM/88_HMCCUDEV.pm | 14 +- fhem/contrib/HMCCU/FHEM/88_HMCCURPCPROC.pm | 2 +- 4 files changed, 341 insertions(+), 228 deletions(-) diff --git a/fhem/contrib/HMCCU/FHEM/88_HMCCU.pm b/fhem/contrib/HMCCU/FHEM/88_HMCCU.pm index 51c2293f3..51f73b817 100644 --- a/fhem/contrib/HMCCU/FHEM/88_HMCCU.pm +++ b/fhem/contrib/HMCCU/FHEM/88_HMCCU.pm @@ -4,7 +4,7 @@ # # $Id: 88_HMCCU.pm 18745 2019-02-26 17:33:23Z zap $ # -# Version 4.4.007 +# Version 4.4.008 # # Module for communication between FHEM and Homematic CCU2/3. # @@ -52,7 +52,7 @@ my %HMCCU_CUST_CHN_DEFAULTS; my %HMCCU_CUST_DEV_DEFAULTS; # HMCCU version -my $HMCCU_VERSION = '4.4.007'; +my $HMCCU_VERSION = '4.4.008'; # Constants and default values my $HMCCU_MAX_IOERRORS = 100; @@ -222,11 +222,11 @@ sub HMCCU_SetRPCState ($@); # Filter and modify readings sub HMCCU_CalculateScaleValue ($$$$;$$$); -sub HMCCU_FilterReading ($$$); +sub HMCCU_FilterReading ($$$;$); sub HMCCU_FormatReadingValue ($$$); sub HMCCU_GetReadingName ($$$$$$$;$); sub HMCCU_ScaleValue ($$$$$); -sub HMCCU_StripNumber ($$); +sub HMCCU_StripNumber ($$;$); sub HMCCU_Substitute ($$$$$;$$); sub HMCCU_SubstRule ($$$); sub HMCCU_SubstVariables ($$$); @@ -234,11 +234,13 @@ sub HMCCU_SubstVariables ($$$); # Update client device readings sub HMCCU_BulkUpdate ($$$$); sub HMCCU_GetUpdate ($$$); +sub HMCCU_RefreshReadings ($); sub HMCCU_UpdateCB ($$$); sub HMCCU_UpdateClients ($$$$$$); -sub HMCCU_UpdateInternalValues ($$$$); +sub HMCCU_UpdateInternalValues ($$$$$); sub HMCCU_UpdateMultipleDevices ($$); sub HMCCU_UpdatePeers ($$$$); +sub HMCCU_UpdateParamsetReadings ($$$;$); sub HMCCU_UpdateSingleDatapoint ($$$$); sub HMCCU_UpdateSingleDevice ($$$$); @@ -316,9 +318,11 @@ sub HMCCU_GetGroupMembers ($$); sub HMCCU_GetMatchingDevices ($$$$); sub HMCCU_GetParamDef ($$$$); sub HMCCU_GetParamValue ($$$$$); +sub HMCCU_GetReceivers ($$$); sub HMCCU_IsValidChannel ($$$); sub HMCCU_IsValidDevice ($$$); sub HMCCU_IsValidDeviceOrChannel ($$$); +sub HMCCU_IsValidReceiver ($$$$); sub HMCCU_ParamsetDescToStr ($$); sub HMCCU_RemoveDevice ($$$;$); sub HMCCU_RenameDevice ($$$); @@ -1195,6 +1199,20 @@ sub HMCCU_Notify ($$) HMCCU_Log ($hash, 0, "Scheduling post FHEM initialization tasks in $delay seconds"); InternalTimer (gettimeofday()+$delay, "HMCCU_PostInit", $hash, 0); } + elsif ($event =~ /^(ATTR|DELETEATTR)/) { + my $refreshAttrList = "ccucalculate|ccuflags|ccureadingfilter|ccureadingformat|". + "ccureadingname|ccuReadingPrefix|ccuscaleval|controldatapoint|hmstatevals|". + "statedatapoint|statevals|substitute:textField-long|substexcl|stripnumber"; + my ($aCmd, $aDev, $aAtt, $aVal) = split (/\s+/, $event); + if (defined($aAtt)) { + my $clHash = $defs{$aDev}; + if (defined($clHash->{TYPE}) && + ($clHash->{TYPE} eq 'HMCCUCHN' || $clHash->{TYPE} eq 'HMCCUDEV') && + $aAtt =~ /^($refreshAttrList)$/) { + HMCCU_RefreshReadings ($clHash); + } + } + } } else { return if ($devtype ne 'HMCCUDEV' && $devtype ne 'HMCCUCHN'); @@ -1737,7 +1755,7 @@ sub HMCCU_Set ($@) ($add, $chn) = HMCCU_GetAddress ($hash, $nam, '', '') if ($flags == $HMCCU_FLAGS_NCD); if ($flags == $HMCCU_FLAGS_IACD || $flags == $HMCCU_FLAGS_NCD) { - $objects{$add}{$chn}{$dpt} = $tokens[1]; + $objects{$add}{$chn}{VALUES}{$dpt} = $tokens[1]; $objcount++; } else { @@ -2395,36 +2413,44 @@ sub HMCCU_ParseObject ($$$) # Multiple filter rules must be separated by ; ###################################################################### -sub HMCCU_FilterReading ($$$) +sub HMCCU_FilterReading ($$$;$) { - my ($hash, $chn, $dpt) = @_; + my ($hash, $chn, $dpt, $ps) = @_; my $name = $hash->{NAME}; my $fnc = "FilterReading"; - my $hmccu_hash = HMCCU_GetHash ($hash); - return 1 if (!defined ($hmccu_hash)); + my $ioHash = HMCCU_GetHash ($hash); + return 1 if (!defined ($ioHash)); + + if (defined($ps)) { + $ps = 'LINK' if ($ps =~ /^LINK\..+$/); + } + else { + $ps = 'VALUES'; + } -# my $grf = AttrVal ($hmccu_hash->{NAME}, 'ccudef-readingfilter', '.*'); -# my $rf = AttrVal ($name, 'ccureadingfilter', $grf); -# $rf = $grf.";".$rf if ($rf ne $grf && $grf ne '.*'); + my $flags = HMCCU_GetFlags ($name); + my @flagList = $flags =~ /show(Master|Link|Device)Readings/g; + push (@flagList, 'VALUES'); + my $dispFlags = uc(join(',', @flagList)); my $rf = AttrVal ($name, 'ccureadingfilter', '.*'); my $chnnam = ''; -# my $chnnum = ''; -# my $devadd = ''; - my ($devadd, $chnnum) = HMCCU_SplitChnAddr ($chn); if ($chnnum ne 'd') { # Get channel name and channel number - $chnnam = HMCCU_GetChannelName ($hmccu_hash, $chn, ''); + $chnnam = HMCCU_GetChannelName ($ioHash, $chn, ''); if ($chnnam eq '') { ($devadd, $chnnum) = HMCCU_GetAddress ($hash, $chn, '', ''); $chnnam = $chn; } } - - HMCCU_Trace ($hash, 2, $fnc, "chn=$chn, chnnam=$chnnam chnnum=$chnnum dpt=$dpt, rules=$rf"); - + + HMCCU_Trace ($hash, 2, $fnc, "chn=$chn, chnnam=$chnnam chnnum=$chnnum dpt=$dpt, rules=$rf dispFlags=$dispFlags ps=$ps"); + + return 0 if ($dispFlags !~ /DEVICE/ && ($chnnum eq 'd' || $chnnum eq '0')); + return 0 if ($dispFlags !~ /$ps/); + foreach my $r (split (';', $rf)) { my $rm = 1; my $cn = ''; @@ -2507,12 +2533,25 @@ sub HMCCU_GetReadingName ($$$$$$$;$) my $type = $hash->{TYPE}; my %prefix = ( 'MASTER' => 'R-', 'LINK' => 'L-', 'VALUES' => '', 'SERVICE' => 'S-', - 'PEER' => 'P-' ); + 'PEER' => 'P-', 'DEVICE' => 'D-' ); my $ioHash = HMCCU_GetHash ($hash); return () if (!defined ($ioHash) || !defined($d) || $d eq ''); + + $c = '' if (!defined ($c)); + $i = '' if (!defined ($i)); - $ps = 'VALUES' if (!defined($ps)); + my @rcv = (); + if (defined($ps)) { + if ($ps =~ /^LINK\.(.+)$/) { + @rcv = HMCCU_GetDeviceIdentifier ($ioHash, $1, undef); + $ps = 'LINK'; + } + } + else { + $ps = 'VALUES'; + } + my $rn = ''; my @rnlist; @@ -2523,17 +2562,7 @@ sub HMCCU_GetReadingName ($$$$$$$;$) my $sr = AttrVal ($name, 'ccureadingname', $gsr); $sr .= ";".$gsr if ($sr ne $gsr && $gsr ne ''); - # Get reading prefix definitions - my $readingPrefix = HMCCU_GetAttribute ($ioHash, $hash, 'ccuReadingPrefix', ''); - foreach my $pd (split (',', $readingPrefix)) { - my ($rSet, $rPre) = split (':', $pd); - $prefix{$rSet} = $rPre if (defined($rPre) && exists($prefix{$rSet})); - } - my $rpf = exists($prefix{$ps}) ? $prefix{$ps} : ''; - # Complete missing values - $c = '' if (!defined ($c)); - $i = '' if (!defined ($i)); if ($n eq '' && $a ne '') { $n = ($c ne '') ? HMCCU_GetChannelName ($ioHash, $a.':'.$c, '') : @@ -2545,6 +2574,15 @@ sub HMCCU_GetReadingName ($$$$$$$;$) if ($i eq '' && $a ne '') { $i = HMCCU_GetDeviceInterface ($ioHash, $a, ''); } + + # Get reading prefix definitions + $ps = 'DEVICE' if ($c eq '0' || $c eq 'd'); + my $readingPrefix = HMCCU_GetAttribute ($ioHash, $hash, 'ccuReadingPrefix', ''); + foreach my $pd (split (',', $readingPrefix)) { + my ($rSet, $rPre) = split (':', $pd); + $prefix{$rSet} = $rPre if (defined($rPre) && exists($prefix{$rSet})); + } + my $rpf = exists($prefix{$ps}) ? $prefix{$ps} : ''; if ($rf eq 'datapoint' || $rf =~ /^datapoint(lc|uc)$/) { $rn = $c ne '' && $type ne 'HMCCUCHN' ? $c.'.'.$d : $d; @@ -2572,7 +2610,12 @@ sub HMCCU_GetReadingName ($$$$$$$;$) $rn =~ s/\%D/uc($d)/ge; } - push (@rnlist, $rpf.$rn); + if (scalar (@rcv) > 0) { + push (@rnlist, map { $rpf.$_.'-'.$rn } @rcv); + } + else { + push (@rnlist, $rpf.$rn); + } # Rename and/or add reading names my @rules = split (';', $sr); @@ -2629,7 +2672,7 @@ sub HMCCU_FormatReadingValue ($$$) my $stripnumber = HMCCU_GetAttrStripNumber ($hash); if ($stripnumber ne 'null' && $value =~ /^[+-]?\d*\.?\d+(?:(?:e|E)\d+)?$/) { - my $isint = $value =~ /^[+-]?[0-9]+$/ ? 1 : 0; + my $isint = $value =~ /^[+-]?[0-9]+$/ ? 2 : 0; foreach my $sr (split (';', $stripnumber)) { my ($d, $s) = split ('!', $sr); @@ -2639,12 +2682,8 @@ sub HMCCU_FormatReadingValue ($$$) else { $s = $sr; } - - if ($s eq '0' && !$isint) { return sprintf ("%d", $value); } - elsif ($s eq '1' && !$isint) { return sprintf ("%.1f", $value); } - elsif ($s eq '2' && !$isint) { return sprintf ("%g", $value); } - elsif ($s =~ /^-([0-9])$/ && !$isint) { my $f = '%.'.$1.'f'; return sprintf ($f, $value); } - elsif ($s =~ /^%.+$/) { return sprintf ($s, $value); } + + return HMCCU_StripNumber ($value, $s, $isint | 1); } HMCCU_Trace ($hash, 2, $fnc, "sn = $stripnumber, dpt=$dpt, isint=$isint, value $value not changed"); @@ -2659,14 +2698,20 @@ sub HMCCU_FormatReadingValue ($$$) ###################################################################### # Format number +# Parameter: +# $value - Any value (non numeric values will be ignored) +# $strip - +# $number - 0=detect, 1=number, 2=integer ###################################################################### -sub HMCCU_StripNumber ($$) +sub HMCCU_StripNumber ($$;$) { - my ($value, $strip) = @_; + my ($value, $strip, $number) = @_; - if ($value =~ /^[+-]?\d*\.?\d+(?:(?:e|E)\d+)?$/) { - my $isint = $value =~ /^[+-]?[0-9]+$/ ? 1 : 0; + $number = 0 if (!defined($number)); + + if ($number & 1 || $value =~ /^[+-]?\d*\.?\d+(?:(?:e|E)\d+)?$/) { + my $isint = ($number & 2 || $value =~ /^[+-]?[0-9]+$/) ? 1 : 0; if ($strip eq '0' && !$isint) { return sprintf ("%d", $value); } elsif ($strip eq '1' && !$isint) { return sprintf ("%.1f", $value); } @@ -2967,7 +3012,7 @@ sub HMCCU_Substitute ($$$$$;$$) if ($dpt =~ /^([0-9]{1,2})\.(.+)$/) { ($chn, $dpt) = ($1, $2); } - + my @rulelist = split (';', $substrule); foreach my $rule (@rulelist) { my @ruletoks = split ('!', $rule); @@ -3004,7 +3049,8 @@ sub HMCCU_Substitute ($$$$$;$$) # Substitute enumerations if (defined($devDesc) && defined($ioHash)) { my $paramDef = HMCCU_GetParamDef ($ioHash, $devDesc, 'VALUES', $dpt); - if (!defined($paramDef) && $paramDef->{TYPE} eq 'ENUM' && defined($paramDef->{VALUE_LIST})) { + if (!defined($paramDef) && defined($paramDef->{TYPE}) && + $paramDef->{TYPE} eq 'ENUM' && defined($paramDef->{VALUE_LIST})) { my $i = defined($paramDef->{MIN}) ? $paramDef->{MIN} : 0; if ($mode) { my %enumVals = map { $_ => $i++ } split(',', $paramDef->{VALUE_LIST}); @@ -3113,21 +3159,21 @@ sub HMCCU_SubstVariables ($$$) HMCCU_Trace ($clhash, 2, $fnc, "var=$dp"); - if (defined ($clhash->{hmccu}{dp}{$dp}{OSVAL})) { - $text =~ s/\$\$\{?$dp\}?/$clhash->{hmccu}{dp}{$dp}{OSVAL}/g; - $text =~ s/\$\$\{?$dpt\}?/$clhash->{hmccu}{dp}{$dp}{OSVAL}/g; + if (defined ($clhash->{hmccu}{dp}{$dp}{VALUES}{OSVAL})) { + $text =~ s/\$\$\{?$dp\}?/$clhash->{hmccu}{dp}{$dp}{VALUES}{OSVAL}/g; + $text =~ s/\$\$\{?$dpt\}?/$clhash->{hmccu}{dp}{$dp}{VALUES}{OSVAL}/g; } - if (defined ($clhash->{hmccu}{dp}{$dp}{SVAL})) { - $text =~ s/\$\{?$dp\}?/$clhash->{hmccu}{dp}{$dp}{SVAL}/g; - $text =~ s/\$\{?$dpt\}?/$clhash->{hmccu}{dp}{$dp}{SVAL}/g; + if (defined ($clhash->{hmccu}{dp}{$dp}{VALUES}{SVAL})) { + $text =~ s/\$\{?$dp\}?/$clhash->{hmccu}{dp}{$dp}{VALUES}{SVAL}/g; + $text =~ s/\$\{?$dpt\}?/$clhash->{hmccu}{dp}{$dp}{VALUES}{SVAL}/g; } - if (defined ($clhash->{hmccu}{dp}{$dp}{OVAL})) { - $text =~ s/\%\%\{?$dp\}?/$clhash->{hmccu}{dp}{$dp}{OVAL}/g; - $text =~ s/\%\%\{?$dpt\}?/$clhash->{hmccu}{dp}{$dp}{OVAL}/g; + if (defined ($clhash->{hmccu}{dp}{$dp}{VALUES}{OVAL})) { + $text =~ s/\%\%\{?$dp\}?/$clhash->{hmccu}{dp}{$dp}{VALUES}{OVAL}/g; + $text =~ s/\%\%\{?$dpt\}?/$clhash->{hmccu}{dp}{$dp}{VALUES}{OVAL}/g; } - if (defined ($clhash->{hmccu}{dp}{$dp}{VAL})) { - $text =~ s/\%\{?$dp\}?/$clhash->{hmccu}{dp}{$dp}{VAL}/g; - $text =~ s/\%\{?$dpt\}?/$clhash->{hmccu}{dp}{$dp}{VAL}/g; + if (defined ($clhash->{hmccu}{dp}{$dp}{VALUES}{VAL})) { + $text =~ s/\%\{?$dp\}?/$clhash->{hmccu}{dp}{$dp}{VALUES}{VAL}/g; + $text =~ s/\%\{?$dpt\}?/$clhash->{hmccu}{dp}{$dp}{VALUES}{VAL}/g; $text =~ s/$dp/$clhash->{hmccu}{dp}{$dp}{VAL}/g; } } @@ -3818,7 +3864,6 @@ sub HMCCU_GetDeviceDesc ($$;$) ###################################################################### # Get list of device identifiers -# FHEM device names are preceeded by "fhem:". # CCU device names are preceeded by "ccu:". # If no names were found, the address is returned. ###################################################################### @@ -4204,6 +4249,7 @@ sub HMCCU_GetParamValue ($$$$$) 'BOOL' => { 0 => 'false', 1 => 'true' } ); + $paramset = 'LINK' if ($paramset =~ /^LINK\..+$/); my $paramDef = HMCCU_GetParamDef ($hash, $object, $paramset, $parameter); if (defined($paramDef)) { my $type = $paramDef->{TYPE}; @@ -4242,6 +4288,34 @@ sub HMCCU_AddPeers ($$$) return scalar(@$peerList); } +###################################################################### +# Get list of receivers for a source address +###################################################################### + +sub HMCCU_GetReceivers ($$$) +{ + my ($ioHash, $address, $iface) = @_; + + my ($sd, $sc) = HMCCU_SplitChnAddr ($address); + if (exists($ioHash->{hmccu}{snd}{$iface}{$sd}{$sc})) { + return keys %{$ioHash->{hmccu}{snd}{$iface}{$sd}{$sc}}; + } + + return (); +} + +###################################################################### +# Check if receiver exists for a source address +###################################################################### + +sub HMCCU_IsValidReceiver ($$$$) +{ + my ($ioHash, $address, $iface, $receiver) = @_; + + my ($sd, $sc) = HMCCU_SplitChnAddr ($address); + return exists($ioHash->{hmccu}{snd}{$iface}{$sd}{$sc}{$receiver}) ? 1 : 0; +} + ####################################################################### # Convert bitmask to text # Parameters: @@ -4311,20 +4385,22 @@ sub HMCCU_FlagsToStr ($$$;$$) sub HMCCU_UpdateSingleDatapoint ($$$$) { - my ($hash, $chn, $dpt, $value) = @_; + my ($clHash, $chn, $dpt, $value) = @_; - my $hmccu_hash = HMCCU_GetHash ($hash); - return $value if (!defined ($hmccu_hash)); + my $ioHash = HMCCU_GetHash ($clHash); + return $value if (!defined ($ioHash)); my %objects; - my $ccuaddr = $hash->{ccuaddr}; + my $ccuaddr = $clHash->{ccuaddr}; my ($devaddr, $chnnum) = HMCCU_SplitChnAddr ($ccuaddr); - $objects{$devaddr}{$chn}{$dpt} = $value; +# $objects{$devaddr}{$chn}{$dpt} = $value; + $objects{$devaddr}{$chn}{VALUES}{$dpt} = $value; # my $rc = HMCCU_UpdateMultipleDevices ($hmccu_hash, \%objects); - my $rc = HMCCU_UpdateSingleDevice ($hmccu_hash, $hash, \%objects, undef); - return (ref ($rc)) ? $rc->{$devaddr}{$chn}{$dpt} : $value; +# my $rc = HMCCU_UpdateSingleDevice ($hmccu_hash, $hash, \%objects, undef); + my $rc = HMCCU_UpdateParamsetReadings ($ioHash, $clHash, \%objects); + return (ref($rc)) ? $rc->{$devaddr}{$chn}{VALUES}{$dpt} : $value; } ###################################################################### @@ -4332,6 +4408,7 @@ sub HMCCU_UpdateSingleDatapoint ($$$$) # Parameter objects is a hash reference which contains updated data # for devices: # {devaddr}{channelno}{paramset}{parameter} = value +# For links format of paramset is "LINK.receiver". # channelno = 'd' for device parameters. # Return hash reference for results or undef on error. ###################################################################### @@ -4380,8 +4457,7 @@ sub HMCCU_UpdateParamsetReadings ($$$;$) foreach my $a (@addList) { # Loop over all channels of device, including channel 'd' foreach my $c (keys %{$objects->{$a}}) { - next if (($clType eq 'HMCCUCHN' && "$c" ne "$chnNo" && "$c" ne "0" && "$c" ne "d") || - ("$c" eq "0" && $clFlags =~ /nochn0/)); + next if (($clType eq 'HMCCUCHN' && "$c" ne "$chnNo" && "$c" ne "0" && "$c" ne "d")); my $chnAddr = "$devAddr:$c"; my $devDesc = HMCCU_GetDeviceDesc ($ioHash, $chnAddr, $clHash->{ccuif}); @@ -4396,47 +4472,39 @@ sub HMCCU_UpdateParamsetReadings ($$$;$) my $fv = $v; my $cv = $v; my $sv; - + # Key for storing values in client device hash. Indirect updates of virtual # devices are stored with device address in key. my $chKey = $devAddr ne $a ? "$chnAddr.$p" : "$c.$p"; - + # Store raw value in client device hash - HMCCU_UpdateInternalValues ($clHash, $chKey, 'VAL', $v) if ($ps eq 'VALUES'); + HMCCU_UpdateInternalValues ($clHash, $chKey, $ps, 'VAL', $v); - # Store the resulting value after scaling, formatting and substitution - if ($ps eq 'VALUES') { - # Modify value: scale, format, substitute - $sv = HMCCU_ScaleValue ($clHash, $c, $p, $v, 0); - $fv = HMCCU_FormatReadingValue ($clHash, $sv, $p); - $cv = HMCCU_Substitute ($fv, $clHash, 0, $c, $p, $chnType, $devDesc); - $cv = HMCCU_GetParamValue ($ioHash, $devDesc, $ps, $p, $fv) if ("$fv" eq "$cv"); + # Modify value: scale, format, substitute + $sv = HMCCU_ScaleValue ($clHash, $c, $p, $v, 0); + $fv = HMCCU_FormatReadingValue ($clHash, $sv, $p); + $cv = HMCCU_Substitute ($fv, $clHash, 0, $c, $p, $chnType, $devDesc); + $cv = HMCCU_GetParamValue ($ioHash, $devDesc, $ps, $p, $fv) if ("$fv" eq "$cv"); - HMCCU_UpdateInternalValues ($clHash, $chKey, 'SVAL', $cv); - push @chKeys, $chKey; + HMCCU_UpdateInternalValues ($clHash, $chKey, $ps, 'SVAL', $cv); + push @chKeys, $chKey; - # Update 'state' and 'control' - HMCCU_BulkUpdate ($clHash, 'control', $fv, $cv) - if ($cd ne '' && $p eq $cd && $c eq $cc); - HMCCU_BulkUpdate ($clHash, 'state', $fv, $cv) - if ($p eq $sd && ($sc eq '' || $sc eq $c)); - - # Update peers - HMCCU_UpdatePeers ($clHash, "$c.$p", $cv, $peer) if (!$vg && $peer ne 'null'); - } - else { - $fv = $v; - $cv = HMCCU_GetParamValue ($ioHash, $devDesc, $ps, $p, $v); - } + # Update 'state' and 'control' + HMCCU_BulkUpdate ($clHash, 'control', $fv, $cv) + if ($cd ne '' && $p eq $cd && $c eq $cc); + HMCCU_BulkUpdate ($clHash, 'state', $fv, $cv) + if ($p eq $sd && ($sc eq '' || $sc eq $c)); + + # Update peers + HMCCU_UpdatePeers ($clHash, "$c.$p", $cv, $peer) if (!$vg && $peer ne 'null'); # Store result, but not for indirect updates of virtual devices - $results{$devAddr}{$c}{$p} = $cv if ($devAddr eq $a); + $results{$devAddr}{$c}{$ps}{$p} = $cv if ($devAddr eq $a); - if (HMCCU_FilterReading ($clHash, $chnAddr, $p) && ("$c" ne "0" || $clFlags =~ /devState/)) { - my @rnList = HMCCU_GetReadingName ($clHash, $clInt, $a, $c, $p, '', $clRF, $ps); - foreach my $rn (@rnList) { - HMCCU_BulkUpdate ($clHash, $rn, $fv, $cv); - } + my @rnList = HMCCU_GetReadingName ($clHash, $clInt, $a, $c, $p, '', $clRF, $ps); + my $dispFlag = HMCCU_FilterReading ($clHash, $chnAddr, $p, $ps) ? '' : '.'; + foreach my $rn (@rnList) { + HMCCU_BulkUpdate ($clHash, $dispFlag.$rn, $fv, $cv); } } } @@ -4453,7 +4521,7 @@ sub HMCCU_UpdateParamsetReadings ($$$;$) # Update device states my ($devState, $battery, $activity) = HMCCU_GetDeviceStates ($clHash); - HMCCU_BulkUpdate ($clHash, 'battery', $battery, $battery); + HMCCU_BulkUpdate ($clHash, 'battery', $battery, $battery) if ($battery ne 'unknown'); HMCCU_BulkUpdate ($clHash, 'activity', $activity, $activity); HMCCU_BulkUpdate ($clHash, 'devstate', $devState, $devState); @@ -4468,6 +4536,36 @@ sub HMCCU_UpdateParamsetReadings ($$$;$) return \%results; } +###################################################################### +# Refresh readings of a client device +###################################################################### + +sub HMCCU_RefreshReadings ($) +{ + my ($clHash) = @_; + + my $ioHash = HMCCU_GetHash ($clHash); + return if (!defined($ioHash)); + + HMCCU_DeleteReadings ($clHash, '.*'); + + my %objects; + my ($devAddr, undef) = HMCCU_SplitChnAddr ($clHash->{ccuaddr}); + + for my $dp (keys %{$clHash->{hmccu}{dp}}) { + foreach my $ps (keys %{$clHash->{hmccu}{dp}{$dp}}) { + my ($chnNo, $par) = split (/\./, $dp); + if (defined($par) && defined($clHash->{hmccu}{dp}{$dp}{$ps}{VAL})) { + $objects{$devAddr}{$chnNo}{$ps}{$par} = $clHash->{hmccu}{dp}{$dp}{$ps}{VAL}; + } + } + } + + if (scalar(keys %objects) > 0) { + HMCCU_UpdateParamsetReadings ($ioHash, $clHash, \%objects); + } +} + ###################################################################### # Update readings of client device. # Parameter objects is a hash reference which contains updated data @@ -4546,7 +4644,7 @@ sub HMCCU_UpdateSingleDevice ($$$$) my $chkey = $devaddr ne $addr ? "$chnadd.$dpt" : "$chnnum.$dpt"; # Store datapoint raw value in device hash - HMCCU_UpdateInternalValues ($clthash, $chkey, 'VAL', $value); + HMCCU_UpdateInternalValues ($clthash, $chkey, 'VALUES', 'VAL', $value); HMCCU_Trace ($clthash, 2, $fnc, "dev=$cltname, chnadd/object=$chnadd, dpt=$dpt, key=$chkey, value=$value"); @@ -4560,7 +4658,7 @@ sub HMCCU_UpdateSingleDevice ($$$$) # my %calcs = HMCCU_CalculateReading ($clthash, $chkey); # Store the resulting value after scaling, formatting and substitution - HMCCU_UpdateInternalValues ($clthash, $chkey, 'SVAL', $cvalue); + HMCCU_UpdateInternalValues ($clthash, $chkey, 'VALUES', 'SVAL', $cvalue); push @chkeys, $chkey; # Store result, but not for indirect updates of virtual devices @@ -4620,21 +4718,21 @@ sub HMCCU_UpdateSingleDevice ($$$$) # Parameter type is VAL or SVAL. ###################################################################### -sub HMCCU_UpdateInternalValues ($$$$) +sub HMCCU_UpdateInternalValues ($$$$$) { - my ($ch, $chkey, $type, $value) = @_; + my ($ch, $chkey, $paramset, $type, $value) = @_; my $otype = "O".$type; # Save old value - if (exists ($ch->{hmccu}{dp}{$chkey}{$type})) { - $ch->{hmccu}{dp}{$chkey}{$otype} = $ch->{hmccu}{dp}{$chkey}{$type}; + if (exists ($ch->{hmccu}{dp}{$chkey}{$paramset}{$type})) { + $ch->{hmccu}{dp}{$chkey}{$paramset}{$otype} = $ch->{hmccu}{dp}{$chkey}{$paramset}{$type}; } else { - $ch->{hmccu}{dp}{$chkey}{$otype} = $value; + $ch->{hmccu}{dp}{$chkey}{$paramset}{$otype} = $value; } # Store new value - $ch->{hmccu}{dp}{$chkey}{$type} = $value; + $ch->{hmccu}{dp}{$chkey}{$paramset}{$type} = $value; } ###################################################################### @@ -4669,8 +4767,9 @@ sub HMCCU_UpdateMultipleDevices ($$) next if (scalar (@addrlist) == 0); foreach my $addr (@addrlist) { if (exists ($objects->{$addr})) { - my $rc = HMCCU_UpdateSingleDevice ($hash, $ch, $objects, \@addrlist); - $c++ if (ref ($rc)); +# my $rc = HMCCU_UpdateSingleDevice ($hash, $ch, $objects, \@addrlist); + my $rc = HMCCU_UpdateParamsetReadings ($hash, $ch, $objects, \@addrlist); + $c++ if (ref($rc)); last; } } @@ -8189,7 +8288,7 @@ sub HMCCU_UpdateCB ($$$) ($add, $chn) = HMCCU_SplitChnAddr ($chnadd); } next if ($chn eq ''); - $events{$add}{$chn}{$dpt} = $value; + $events{$add}{$chn}{VALUES}{$dpt} = $value; } my $c_ok = HMCCU_UpdateMultipleDevices ($hash, \%events); @@ -8532,13 +8631,15 @@ sub HMCCU_GetDeviceStates ($) if (exists($clHash->{hmccu}{dp})) { foreach my $dp (keys %stName) { push @state, $stName{$dp} if (exists($clHash->{hmccu}{dp}{$dp}) && - defined($clHash->{hmccu}{dp}{$dp}{VAL}) && - $clHash->{hmccu}{dp}{$dp}{VAL} =~ /^(1|true)$/); + exists($clHash->{hmccu}{dp}{$dp}{VALUES}) && + defined($clHash->{hmccu}{dp}{$dp}{VALUES}{VAL}) && + $clHash->{hmccu}{dp}{$dp}{VALUES}{VAL} =~ /^(1|true)$/); } push @values, scalar(@state) > 0 ? join(',', @state) : 'ok'; foreach my $dp (keys %stVal) { - if (exists($clHash->{hmccu}{dp}{$dp}) && defined($clHash->{hmccu}{dp}{$dp}{SVAL})) { - push @values, $clHash->{hmccu}{dp}{SVAL}; + if (exists($clHash->{hmccu}{dp}{$dp}) && exists($clHash->{hmccu}{dp}{$dp}{VALUES})&& + defined($clHash->{hmccu}{dp}{$dp}{VALUES}{SVAL})) { + push @values, $clHash->{hmccu}{dp}{$dp}{VALUES}{SVAL}; } else { push @values, 'unknown'; @@ -8596,9 +8697,11 @@ sub HMCCU_GetHMState ($$$) } next if ($dp eq ''); my ($chn, $dpt) = split (/\./, $dp); - my $value = HMCCU_FormatReadingValue ($clhash, $clhash->{hmccu}{dp}{$dp}{VAL}, $hmstate[0]); - my ($rc, $newvalue) = HMCCU_SubstRule ($value, $subst, 0); - return ($hmstate[0], $chn, $dpt, $newvalue) if ($rc); + if (exists($clhash->{hmccu}{dp}{$dp}) && exists($clhash->{hmccu}{dp}{$dp}{VALUES}{VAL})) { + my $value = HMCCU_FormatReadingValue ($clhash, $clhash->{hmccu}{dp}{$dp}{VALUES}{VAL}, $hmstate[0]); + my ($rc, $newvalue) = HMCCU_SubstRule ($value, $subst, 0); + return ($hmstate[0], $chn, $dpt, $newvalue) if ($rc); + } } return @hmstate; @@ -8900,7 +9003,7 @@ sub HMCCU_DeleteReadings ($$) $rnexp = '.*' if (!defined ($rnexp)); my @readlist = keys %{$hash->{READINGS}}; foreach my $rd (@readlist) { - delete ($hash->{READINGS}{$rd}) if ($rd ne 'state' && $rd ne 'control' && $rd =~ /$rnexp/); + readingsDelete ($hash, $rd) if ($rd ne 'state' && $rd ne 'control' && $rd =~ /$rnexp/); } } diff --git a/fhem/contrib/HMCCU/FHEM/88_HMCCUCHN.pm b/fhem/contrib/HMCCU/FHEM/88_HMCCUCHN.pm index 34c454aa6..108c761e7 100644 --- a/fhem/contrib/HMCCU/FHEM/88_HMCCUCHN.pm +++ b/fhem/contrib/HMCCU/FHEM/88_HMCCUCHN.pm @@ -48,7 +48,8 @@ sub HMCCUCHN_Initialize ($) $hash->{parseParams} = 1; $hash->{AttrList} = "IODev ccucalculate ". - "ccuflags:multiple-strict,ackState,logCommand,devState,noReadings,trace ccureadingfilter ". + "ccuflags:multiple-strict,ackState,logCommand,noReadings,trace,showMasterReadings,showLinkReadings,showDeviceReadings ". + "ccureadingfilter ". "ccureadingformat:name,namelc,address,addresslc,datapoint,datapointlc ". "ccureadingname:textField-long ccuSetOnChange ccuReadingPrefix ". "ccuscaleval ccuverify:0,1,2 ccuget:State,Value controldatapoint ". @@ -209,11 +210,6 @@ sub HMCCUCHN_Attr ($@) { my ($cmd, $name, $attrname, $attrval) = @_; my $hash = $defs{$name}; - - my %resetReadings = ( - 'ccureadingfilter' => 1, 'ccureadingformat' => 1, 'ccureadingname' => 1, - 'substitute' => 1, 'ccuscaleval' => 1 - ); if ($cmd eq "set") { return "Missing attribute value" if (!defined ($attrval)); @@ -226,11 +222,7 @@ 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_RefreshReadings ($hash); } return undef; @@ -250,7 +242,7 @@ sub HMCCUCHN_Set ($@) $opt = lc($opt); my $rocmds = "clear defaults:noArg"; - my $rwcmds = "clear config control datapoint defaults:noArg paramset link devstate values"; + my $rwcmds = "clear config control datapoint defaults:noArg link values"; # Get I/O device, check device state return undef if (!defined ($hash->{ccudevstate}) || $hash->{ccudevstate} eq 'pending' || @@ -353,8 +345,8 @@ sub HMCCUCHN_Set ($@) if (!HMCCU_IsValidDatapoint ($hash, $ccutype, $ccuaddr, $cd, 2)); my $stc = scalar (@states); - my $curState = defined($hash->{hmccu}{dp}{"$cc.$cd"}{SVAL}) ? - $hash->{hmccu}{dp}{"$cc.$cd"}{SVAL} : $states[0]; + my $curState = defined($hash->{hmccu}{dp}{"$cc.$cd"}{VALUES}{SVAL}) ? + $hash->{hmccu}{dp}{"$cc.$cd"}{VALUES}{SVAL} : $states[0]; my $newState = ''; my $st = 0; @@ -461,36 +453,24 @@ sub HMCCUCHN_Set ($@) HMCCU_DeleteReadings ($hash, $rnexp); return HMCCU_SetState ($hash, "OK"); } - elsif ($opt =~ /^(paramset|rpcparameter|config|link|values)$/) { - my %parSets = ('config' => 'MASTER', 'links' => 'LINK', 'values' => 'VALUES'); - my $paramset = ''; + elsif ($opt =~ /^(config|values)$/) { + my %parSets = ('config' => 'MASTER', 'values' => 'VALUES'); + my $paramset = $parSets{$opt}; return HMCCU_SetError ($hash, "No parameter specified") if ((scalar keys %{$h}) < 1); - if (exists($parSets{$opt})) { - $paramset = $parSets{$opt}; - } - my $ccuobj = $ccuaddr; my $p = shift @$a; if (defined($p) && $p eq 'device') { - return HMCCU_SetError ($hash, "Link parameters can only be set for channels") - if ($opt eq 'link'); ($ccuobj, undef) = HMCCU_SplitChnAddr ($ccuaddr); $p = shift @$a; } - if ($opt =~ /(paramset|rpcparameter)/) { - return HMCCU_SetError ($hash, "Command $opt requires a parameter set") - if (!defined($p)); - $paramset = $p; - } - my $devDesc = HMCCU_GetDeviceDesc ($ioHash, $ccuobj, $ccuif); return HMCCU_SetError ($hash, "Can't get device description") if (!defined($devDesc)); - return HMCCU_SetError ($hash, "Paramset $paramset not supported by device") + return HMCCU_SetError ($hash, "Paramset $paramset not supported by device or channel") if ($devDesc->{PARAMSETS} !~ /$paramset/); if ($paramset eq 'VALUES') { @@ -502,6 +482,50 @@ sub HMCCUCHN_Set ($@) return HMCCU_SetError ($hash, min(0, $rc)); } + elsif ($opt eq 'link') { + return HMCCU_SetError ($hash, "No parameter specified") + if ((scalar keys %{$h}) < 1); + my @rcvList = (); + my $receiver = shift @$a; + + if (defined($receiver)) { + if (exists($defs{$receiver}) && defined($defs{$receiver}->{TYPE})) { + my $clHash = $defs{$receiver}; + if ($clHash->{TYPE} eq 'HMCCUDEV') { + my $chnNo = shift @$a; + return HMCCU_SetError ($hash, "Channel number required for link receiver") + if (!defined($chnNo) || $chnNo !~ /^[0-9]{1,2}$/); + $receiver = $clHash->{ccuaddr}.":$chnNo"; + } + elsif ($clHash->{TYPE} eq 'HMCCUCHN') { + $receiver = $clHash->{ccuaddr}; + } + else { + return HMCCU_SetError ($hash, "Receiver $receiver is not a HMCCUCHN or HMCCUDEV device"); + } + } + push @rcvList, $receiver; + } + else { + push @rcvList, HMCCU_GetReceivers ($ioHash, $ccuaddr, $ccuif); + } + + return HMCCU_SetError ($hash, "$receiver is not a link receiver of $name") + if (!HMCCU_IsValidReceiver ($ioHash, $ccuaddr, $ccuif, $receiver)); + + my $devDesc = HMCCU_GetDeviceDesc ($ioHash, $ccuaddr, $ccuif); + return HMCCU_SetError ($hash, "Can't get device description") + if (!defined($devDesc)); + return HMCCU_SetError ($hash, "Paramset LINK not supported by device or channel") + if ($devDesc->{PARAMSETS} !~ /LINK/); + + foreach my $rcv (@rcvList) { + ($rc, $result) = HMCCU_RPCRequest ($hash, "putParamset", $ccuaddr, $rcv, $h); + return HMCCU_SetError ($hash, $rc) if ($rc < 0); + } + + return HMCCU_SetState ($hash, "OK"); + } elsif ($opt eq 'defaults') { $rc = HMCCU_SetDefaults ($hash); return HMCCU_SetError ($hash, $rc == 0 ? "No default attributes found" : "OK"); @@ -563,17 +587,7 @@ sub HMCCUCHN_Get ($@) HMCCU_Log ($hash, 3, "get $name $opt ".join (' ', @$a)) if ($opt ne '?' && $ccuflags =~ /logCommand/ || HMCCU_IsFlag ($hmccu_name, 'logCommand')); - if ($opt eq 'devstate') { - return HMCCU_SetError ($hash, -13) if ($sd eq ''); - return HMCCU_SetError ($hash, -8) - if (!HMCCU_IsValidDatapoint ($hash, $ccutype, $ccuaddr, $sd, 1)); - - my $objname = $ccuif.'.'.$ccuaddr.'.'.$sd; - ($rc, $result) = HMCCU_GetDatapoint ($hash, $objname, 0); - return HMCCU_SetError ($hash, $rc, $result) if ($rc < 0); - return $result; - } - elsif ($opt eq 'datapoint') { + if ($opt eq 'datapoint') { my $objname = shift @$a; return HMCCU_SetError ($hash, "Usage: get $name datapoint {datapoint}") @@ -602,26 +616,12 @@ sub HMCCUCHN_Get ($@) return HMCCU_SetError ($hash, -2) if ($result eq ''); return HMCCU_FormatDeviceInfo ($result); } - elsif ($opt =~ /^(paramset|config|values)$/) { - my $defParamset = ''; + elsif ($opt =~ /^(config|values)$/) { my %parSets = ('config' => 'MASTER,LINK', 'values' => 'VALUES'); + my $defParamset = $parSets{$opt}; my ($devAddr, undef) = HMCCU_SplitChnAddr ($ccuaddr); my @addList = ($devAddr, "$devAddr:0", $ccuaddr); - my $par = shift @$a; - if (defined($par)) { - if ($opt eq 'paramset') { - $defParamset = $par; - } - else { - return "Usage: get $name $opt"; - } - } - - if (exists($parSets{$opt})) { - $defParamset = $parSets{$opt}; - } - my %objects; foreach my $a (@addList) { my $devDesc = HMCCU_GetDeviceDesc ($ioHash, $a, $ccuif); @@ -634,10 +634,20 @@ sub HMCCUCHN_Get ($@) foreach my $ps (split (',', $paramset)) { next if ($devDesc->{PARAMSETS} !~ /$ps/); - ($rc, $result) = HMCCU_RPCRequest ($hash, 'getRawParamset', $a, $ps, undef, undef); - return HMCCU_SetError ($hash, $rc, $result) if ($rc < 0); - - foreach my $p (keys %$result) { $objects{$da}{$dc}{$ps}{$p} = $result->{$p}; } + if ($ps eq 'LINK') { + foreach my $rcv (HMCCU_GetReceivers ($ioHash, $ccuaddr, $ccuif)) { + ($rc, $result) = HMCCU_RPCRequest ($hash, 'getRawParamset', $a, $rcv, undef, undef); + next if ($rc < 0); + foreach my $p (keys %$result) { + $objects{$da}{$dc}{"LINK.$rcv"}{$p} = $result->{$p}; + } + } + } + else { + ($rc, $result) = HMCCU_RPCRequest ($hash, 'getRawParamset', $a, $ps, undef, undef); + return HMCCU_SetError ($hash, $rc, $result) if ($rc < 0); + foreach my $p (keys %$result) { $objects{$da}{$dc}{$ps}{$p} = $result->{$p}; } + } } } @@ -648,10 +658,12 @@ sub HMCCUCHN_Get ($@) foreach my $da (sort keys %$convRes) { $res .= "Device $da\n"; foreach my $dc (sort keys %{$convRes->{$da}}) { - $res .= " Channel $dc\n"; - $res .= join ("\n", map { - " ".$_.' = '.$convRes->{$da}{$dc}{$_} - } sort keys %{$convRes->{$da}{$dc}})."\n"; + foreach my $ps (sort keys %{$convRes->{$da}{$dc}}) { + $res .= " Channel $dc [$ps]\n"; + $res .= join ("\n", map { + " ".$_.' = '.$convRes->{$da}{$dc}{$ps}{$_} + } sort keys %{$convRes->{$da}{$dc}{$ps}})."\n"; + } } } } @@ -671,14 +683,14 @@ sub HMCCUCHN_Get ($@) return HMCCU_GetDefaults ($hash, 0); } else { - my $retmsg = "HMCCUCHN: Unknown argument $opt, choose one of devstate:noArg defaults:noArg datapoint"; + my $retmsg = "HMCCUCHN: Unknown argument $opt, choose one of defaults:noArg datapoint"; my ($a, $c) = split(":", $hash->{ccuaddr}); my @valuelist; my $valuecount = HMCCU_GetValidDatapoints ($hash, $hash->{ccutype}, $c, 1, \@valuelist); $retmsg .= ":".join(",",@valuelist) if ($valuecount > 0); $retmsg .= " update:noArg deviceInfo:noArg config:noArg". - " deviceDesc:noArg paramset paramsetDesc:noArg values:noArg"; + " deviceDesc:noArg paramsetDesc:noArg values:noArg"; return $retmsg; } @@ -728,7 +740,12 @@ sub HMCCUCHN_Get ($@) Readings 'state' and 'control' are not deleted.
  • set <name> config [device] <parameter>=<value>[:<type>]
    - Alias for command 'set paramset' for parameter set MASTER. + Set multiple config parameters (parameter set MASTER). + With option 'device' a parameter set of the device is set instead of the current channel. + Supports attribute 'ccuscaleval' for datapoints. Parameter parameter must be a valid + config parameter name. If type is not specified, it's taken from + parameter set definition. The default type is STRING. + Valid types are STRING, BOOL, INTEGER, FLOAT, DOUBLE.

  • set <name> datapoint <datapoint> <value> | <datapoint>=<value> [...]
    Set datapoint values of a CCU channel. If parameter value contains special @@ -742,13 +759,6 @@ sub HMCCUCHN_Get ($@) Set default attributes for CCU device type. Default attributes are only available for some device types and for some channels of a device type.

  • -
  • set <name> devstate <value>
    - Set state of a CCU device channel. The state datapoint of a channel must be defined - by setting attribute 'statedatapoint' to a valid datapoint name. -

    - Example:
    - set light_entrance devstate true -

  • set <name> down [<value>]
    Decrement value of datapoint LEVEL. This command is only available if channel contains a datapoint LEVEL. Default for value is 10. @@ -756,8 +766,13 @@ sub HMCCUCHN_Get ($@)
  • set <name> pct <value> [<ontime> [<ramptime>]]
    Alias for command 'set pct'.

  • -
  • set <name> link <parameter>=<value>[:<type>]
    - Alias for command 'set paramset' for parameter set LINK. +
  • set <name> link <receiver> [<channel>] <parameter>=<value>[:<type>]
    + Set multiple link parameters (parameter set LINK). Parameter receiver is the + name of a FHEM device of type HMCCUDEV or HMCCUCHN or a channel address. For FHEM + devices of type HMCCUDEV a channel number must be specified. Parameter parameter must be a valid + link configuration parameter name. If type is not specified, it's taken from + parameter set definition. The default type is STRING. + Valid types are STRING, BOOL, INTEGER, FLOAT, DOUBLE.

  • set <name> <statevalue>
    Set state of a CCU device channel to StateValue. The state datapoint of a channel @@ -791,16 +806,6 @@ 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. If type is not specified, it's taken from - parameter set definition. 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 @@ -840,7 +845,11 @@ sub HMCCUCHN_Get ($@) a datapoint LEVEL. Default for value is 10.

  • set <name> values <parameter>=<value>[:<type>]
    - Alias for command 'set paramset' for parameter set VALUES. + Set multiple datapoint values (parameter set VALUES). + Supports attribute 'ccuscaleval'. Parameter parameter must be a valid + datapoint name. If type is not specified, it's taken from + parameter set definition. The default type is STRING. + Valid types are STRING, BOOL, INTEGER, FLOAT, DOUBLE.

  • @@ -849,7 +858,12 @@ sub HMCCUCHN_Get ($@) Get