2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-04-21 07:56:03 +00:00

HMCCU: Update for 4.4 Beta

git-svn-id: https://svn.fhem.de/fhem/trunk@21179 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
zap 2020-02-11 20:13:08 +00:00
parent 309f227722
commit b4e50be334
4 changed files with 341 additions and 228 deletions

View File

@ -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,35 +2413,43 @@ 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));
# my $grf = AttrVal ($hmccu_hash->{NAME}, 'ccudef-readingfilter', '.*');
# my $rf = AttrVal ($name, 'ccureadingfilter', $grf);
# $rf = $grf.";".$rf if ($rf ne $grf && $grf ne '.*');
if (defined($ps)) {
$ps = 'LINK' if ($ps =~ /^LINK\..+$/);
}
else {
$ps = 'VALUES';
}
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;
@ -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 '');
$ps = 'VALUES' if (!defined($ps));
$c = '' if (!defined ($c));
$i = '' if (!defined ($i));
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, '') :
@ -2546,6 +2575,15 @@ sub HMCCU_GetReadingName ($$$$$$$;$)
$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);
@ -2640,11 +2683,7 @@ sub HMCCU_FormatReadingValue ($$$)
$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); }
@ -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});
@ -4402,41 +4478,33 @@ sub HMCCU_UpdateParamsetReadings ($$$;$)
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 '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 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/);
}
}

View File

@ -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 ".
@ -210,11 +211,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));
if ($attrname eq 'IODev') {
@ -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,25 +616,11 @@ 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) {
@ -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.
</li><br/>
<li><b>set &lt;name&gt; config [device] &lt;parameter&gt;=&lt;value&gt;[:&lt;type&gt;]</b><br/>
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 <i>parameter</i> must be a valid
config parameter name. If <i>type</i> is not specified, it's taken from
parameter set definition. The default <i>type</i> is STRING.
Valid types are STRING, BOOL, INTEGER, FLOAT, DOUBLE.
</li><br/>
<li><b>set &lt;name&gt; datapoint &lt;datapoint&gt; &lt;value&gt; | &lt;datapoint&gt=&lt;value&gt; [...]</b><br/>
Set datapoint values of a CCU channel. If parameter <i>value</i> 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.
</li><br/>
<li><b>set &lt;name&gt; devstate &lt;value&gt;</b><br/>
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.
<br/><br/>
Example:<br/>
<code>set light_entrance devstate true</code>
</li><br/>
<li><b>set &lt;name&gt; down [&lt;value&gt;]</b><br/>
Decrement value of datapoint LEVEL. This command is only available if channel contains
a datapoint LEVEL. Default for <i>value</i> is 10.
@ -756,8 +766,13 @@ sub HMCCUCHN_Get ($@)
<li><b>set &lt;name&gt; pct &lt;value&gt; [&lt;ontime&gt; [&lt;ramptime&gt;]]</b><br/>
Alias for command 'set pct'.
</li><br/>
<li><b>set &lt;name&gt; link &lt;parameter&gt;=&lt;value&gt;[:&lt;type&gt;]</b><br/>
Alias for command 'set paramset' for parameter set LINK.
<li><b>set &lt;name&gt; link &lt;receiver&gt; [&lt;channel&gt;] &lt;parameter&gt;=&lt;value&gt;[:&lt;type&gt;]</b><br/>
Set multiple link parameters (parameter set LINK). Parameter <i>receiver</i> is the
name of a FHEM device of type HMCCUDEV or HMCCUCHN or a channel address. For FHEM
devices of type HMCCUDEV a <i>channel</i> number must be specified. Parameter <i>parameter</i> must be a valid
link configuration parameter name. If <i>type</i> is not specified, it's taken from
parameter set definition. The default <i>type</i> is STRING.
Valid types are STRING, BOOL, INTEGER, FLOAT, DOUBLE.
</li><br/>
<li><b>set &lt;name&gt; &lt;statevalue&gt;</b><br/>
Set state of a CCU device channel to <i>StateValue</i>. 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.
</li><br/>
<li><b>set &lt;name&gt; paramset [device] [&lt;paramset&gt;] &lt;parameter&gt;=&lt;value&gt;[:&lt;type&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. If <i>type</i> is not specified, it's taken from
parameter set definition. 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/>
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
@ -840,7 +845,11 @@ sub HMCCUCHN_Get ($@)
a datapoint LEVEL. Default for <i>value</i> is 10.
</li><br/>
<li><b>set &lt;name&gt; values &lt;parameter&gt;=&lt;value&gt;[:&lt;type&gt;]</b><br/>
Alias for command 'set paramset' for parameter set VALUES.
Set multiple datapoint values (parameter set VALUES).
Supports attribute 'ccuscaleval'. Parameter <i>parameter</i> must be a valid
datapoint name. If <i>type</i> is not specified, it's taken from
parameter set definition. The default <i>type</i> is STRING.
Valid types are STRING, BOOL, INTEGER, FLOAT, DOUBLE.
</li>
</ul>
<br/>
@ -849,7 +858,12 @@ sub HMCCUCHN_Get ($@)
<b>Get</b><br/><br/>
<ul>
<li><b>get &lt;name&gt; config</b><br/>
Same as 'get paramset', but read only parameter sets MASTER and LINK.
Get configuration parameters of device and channel.
If ccuflag noReadings is set results are displayed in browser window. Otherwise
they are stored as readings beginning with "R-" for MASTER parameters and "L-" for
LINK parameters.
Prefixes can be modified with attribute 'ccuReadingPrefix'. 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><b>get &lt;name&gt; datapoint &lt;datapoint&gt;</b><br/>
Get value of a CCU channel datapoint.
@ -863,20 +877,6 @@ sub HMCCUCHN_Get ($@)
<li><b>get &lt;name&gt; deviceInfo</b><br/>
Display all channels and datapoints of device with datapoint values and types.
</li><br/>
<li><b>get &lt;name&gt; devstate</b><br/>
Get state of CCU device. Default datapoint STATE can be changed by setting
attribute 'statedatapoint'. Command will fail if state datapoint does not exist in
channel.
</li><br/>
<li><b>get &lt;name&gt; paramset [&lt;paramset&gt;[,...]]</b><br/>
Get parameters from all or specific parameter sets of device and channel.
If ccuflag noReadings is set results are displayed in browser window. Otherwise
they are stored as readings beginning with "R-" for MASTER parameters and "L-" for
LINK parameters. Values from other parameter sets are stored without prefix.
Prefixes can be modified with attribute 'ccuReadingPrefix'. If no <i>paramset</i>
is specified, all parameter sets will be 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><b>get &lt;name&gt; paramsetDesc</b><br/>
Display description of parameter sets of channel and device.
</li><br/>
@ -913,12 +913,14 @@ sub HMCCUCHN_Get ($@)
Example:<br/>
<code>dewpoint:taupunkt:1.TEMPERATURE,1.HUMIDITY</code>
</li><br/>
<li><b>ccuflags {ackState, logCommand, devState, noReadings, trace}</b><br/>
<li><b>ccuflags {ackState, logCommand, noReadings, showDeviceReadings, showLinkReadings, showConfigReadings, trace}</b><br/>
Control behaviour of device:<br/>
ackState: Acknowledge command execution by setting STATE to error or success.<br/>
logCommand: Write get and set commands to FHEM log with verbose level 3.<br/>
devState: Store channel 0 states in reading 'devstate'<br/>
noReadings: Do not update readings<br/>
showDeviceReadings: Show readings of device and channel 0.<br/>
showLinkReadings: Show link readings.<br/>
showMasterReadings: Show configuration readings.<br/>
trace: Write log file information for operations related to this device.
</li><br/>
<li><b>ccuget {State | <u>Value</u>}</b><br/>

View File

@ -843,9 +843,17 @@ sub HMCCUDEV_Get ($@)
if (scalar(keys %objects) > 0) {
my $convRes = HMCCU_UpdateParamsetReadings ($ioHash, $hash, \%objects);
if (defined($convRes)) {
$res .= join ("\n", map { $_ =~ /$par/ ?
" ".$_.' = '.$convRes->{$_} : ()
} sort keys %$convRes)."\n";
foreach my $da (sort keys %$convRes) {
$res .= "Device $da\n";
foreach my $dc (sort keys %{$convRes->{$da}}) {
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";
}
}
}
}
}

View File

@ -746,7 +746,7 @@ sub HMCCURPCPROC_Read ($)
next if (!defined ($et));
if ($et eq 'EV') {
$events{$par[0]}{$par[1]}{$par[2]} = $par[3];
$events{$par[0]}{$par[1]}{VALUES}{$par[2]} = $par[3];
$evcount++;
$hash->{ccustate} = 'active' if ($hash->{ccustate} ne 'active');