mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-02-07 16:59:18 +00:00
HMCCU: Update for version 4.4 beta
git-svn-id: https://svn.fhem.de/fhem/trunk@21084 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
bde6d00a73
commit
b3155f0467
@ -4,7 +4,7 @@
|
||||
#
|
||||
# $Id: 88_HMCCU.pm 18745 2019-02-26 17:33:23Z zap $
|
||||
#
|
||||
# Version 4.4.006
|
||||
# Version 4.4.007
|
||||
#
|
||||
# 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.006';
|
||||
my $HMCCU_VERSION = '4.4.007';
|
||||
|
||||
# Constants and default values
|
||||
my $HMCCU_MAX_IOERRORS = 100;
|
||||
@ -226,7 +226,7 @@ sub HMCCU_FilterReading ($$$);
|
||||
sub HMCCU_FormatReadingValue ($$$);
|
||||
sub HMCCU_GetReadingName ($$$$$$$;$);
|
||||
sub HMCCU_ScaleValue ($$$$$);
|
||||
sub HMCCU_Substitute ($$$$$;$);
|
||||
sub HMCCU_Substitute ($$$$$;$$);
|
||||
sub HMCCU_SubstRule ($$$);
|
||||
sub HMCCU_SubstVariables ($$$);
|
||||
|
||||
@ -287,7 +287,7 @@ sub HMCCU_AddDeviceModel ($$$$$$);
|
||||
sub HMCCU_AddPeers ($$$);
|
||||
sub HMCCU_CreateDevice ($$$$$);
|
||||
sub HMCCU_DeleteDevice ($);
|
||||
sub HMCCU_DeviceDescToStr ($);
|
||||
sub HMCCU_DeviceDescToStr ($$);
|
||||
sub HMCCU_ExistsDeviceModel ($$$;$);
|
||||
sub HMCCU_FindParamDef ($$$);
|
||||
sub HMCCU_FormatDeviceInfo ($);
|
||||
@ -295,6 +295,7 @@ sub HMCCU_GetAddress ($$$$);
|
||||
sub HMCCU_GetAffectedAddresses ($);
|
||||
sub HMCCU_GetCCUDeviceParam ($$);
|
||||
sub HMCCU_GetChannelName ($$$);
|
||||
sub HMCCU_GetChannelRole ($;$);
|
||||
sub HMCCU_GetClientDeviceModel ($;$);
|
||||
sub HMCCU_GetDefaultInterface ($);
|
||||
sub HMCCU_GetDeviceAddresses ($;$$);
|
||||
@ -316,9 +317,10 @@ sub HMCCU_GetParamValue ($$$$$);
|
||||
sub HMCCU_IsValidChannel ($$$);
|
||||
sub HMCCU_IsValidDevice ($$$);
|
||||
sub HMCCU_IsValidDeviceOrChannel ($$$);
|
||||
sub HMCCU_ParamsetDescToStr ($);
|
||||
sub HMCCU_ParamsetDescToStr ($$);
|
||||
sub HMCCU_RemoveDevice ($$$;$);
|
||||
sub HMCCU_ResetDeviceTables ($;$$);
|
||||
sub HMCCU_UpdateDevice ($$);
|
||||
sub HMCCU_UpdateDeviceTable ($$);
|
||||
|
||||
# Handle datapoints
|
||||
@ -1855,7 +1857,7 @@ sub HMCCU_Get ($@)
|
||||
$opt = lc($opt);
|
||||
|
||||
my $options = "defaults:noArg exportDefaults deviceList dump dutycycle:noArg vars update".
|
||||
" updateccu configdesc firmware rpcEvents:noArg rpcState:noArg deviceInfo".
|
||||
" updateccu deviceDesc paramsetDesc firmware rpcEvents:noArg rpcState:noArg deviceInfo".
|
||||
" ccuMsg:alarm,service ccuConfig:noArg";
|
||||
my $usage = "HMCCU: Unknown argument $opt, choose one of $options";
|
||||
my $host = $hash->{host};
|
||||
@ -2170,19 +2172,27 @@ sub HMCCU_Get ($@)
|
||||
|
||||
return HMCCU_SetState ($hash, "OK", $ccureadings ? undef : $result);
|
||||
}
|
||||
elsif ($opt eq 'configdesc') {
|
||||
elsif ($opt eq 'devicedesc') {
|
||||
my $ccuobj = shift @$a;
|
||||
$usage = "Usage: get $name $opt {device|channel}";
|
||||
return HMCCU_SetError ($hash, $usage) if (!defined ($ccuobj));
|
||||
|
||||
my $res = "MASTER:\n";
|
||||
my ($rc, $result) = HMCCU_RPCRequest ($hash, "getParamsetDescription", $ccuobj, "MASTER", undef);
|
||||
return HMCCU_SetError ($hash, $rc, $result) if ($rc < 0);
|
||||
$res .= "$result\nLINK:\n";
|
||||
($rc, $result) = HMCCU_RPCRequest ($hash, "getParamsetDescription", $ccuobj, "LINK", undef);
|
||||
return HMCCU_SetError ($hash, $rc, $result) if ($rc < 0);
|
||||
$res .= $result;
|
||||
return HMCCU_SetState ($hash, "OK", $res);
|
||||
return HMCCU_SetError ($hash, "Usage: get $name $opt {device|channel}")
|
||||
if (!defined ($ccuobj));
|
||||
my ($int, $add, $chn, $dpt, $nam, $flags) = HMCCU_ParseObject ($hash, $ccuobj,
|
||||
$HMCCU_FLAG_FULLADDR);
|
||||
return HMCCU_SetError ($hash, "Invalid device or address")
|
||||
if (!($flags & $HMCCU_FLAG_ADDRESS));
|
||||
$result = HMCCU_DeviceDescToStr ($hash, $add);
|
||||
return defined($result) ? $result : HMCCU_SetError ($hash, "Can't get device description");
|
||||
}
|
||||
elsif ($opt eq 'paramsetdesc') {
|
||||
my $ccuobj = shift @$a;
|
||||
return HMCCU_SetError ($hash, "Usage: get $name $opt {device|channel}")
|
||||
if (!defined ($ccuobj));
|
||||
my ($int, $add, $chn, $dpt, $nam, $flags) = HMCCU_ParseObject ($hash, $ccuobj,
|
||||
$HMCCU_FLAG_FULLADDR);
|
||||
return HMCCU_SetError ($hash, "Invalid device or address")
|
||||
if (!($flags & $HMCCU_FLAG_ADDRESS));
|
||||
$result = HMCCU_ParamsetDescToStr ($hash, $add);
|
||||
return defined($result) ? $result : HMCCU_SetError ($hash, "Can't get device description");
|
||||
}
|
||||
elsif ($opt eq 'ccumsg') {
|
||||
my $msgtype = shift @$a;
|
||||
@ -2871,14 +2881,37 @@ sub HMCCU_SetRPCState ($@)
|
||||
# Substitute first occurrence of regular expression or fixed string.
|
||||
# Floating point values are ignored without datapoint specification.
|
||||
# Integer values are compared with complete value.
|
||||
# mode: 0=Substitute regular expression, 1=Substitute text
|
||||
# $mode - 0=Substitute regular expression, 1=Substitute text
|
||||
# $chn - A channel number. Ignored if $dpt contains a Channel
|
||||
# number.
|
||||
# $dpt - Datapoint name. If it contains a channel number, it
|
||||
# overrides parameter $chn
|
||||
# $type - Role of a channel, i.e. SHUTTER_CONTACT (optional).
|
||||
# $devDesc - Device description reference (optional).
|
||||
######################################################################
|
||||
|
||||
sub HMCCU_Substitute ($$$$$;$)
|
||||
sub HMCCU_Substitute ($$$$$;$$)
|
||||
{
|
||||
my ($value, $substrule, $mode, $chn, $dpt, $type) = @_;
|
||||
my ($value, $substrule, $mode, $chn, $dpt, $type, $devDesc) = @_;
|
||||
|
||||
$substrule = '' if (!defined($substrule));
|
||||
my $rc = 0;
|
||||
my $newvalue;
|
||||
|
||||
my %conversion = (
|
||||
'SHUTTER_CONTACT' => {
|
||||
'STATE' => { '0' => 'open', '1' => 'closed', 'false' => 'open', 'true' => 'closed' }
|
||||
},
|
||||
'BLIND' => {
|
||||
'LEVEL' => { '0' => 'closed', '100' => 'open' }
|
||||
},
|
||||
'DIMMER' => {
|
||||
'LEVEL' => { '0' => 'off', '100' => 'on' }
|
||||
},
|
||||
'DEFAULT' => {
|
||||
'STATE' => { '0' => 'false', '1' => 'true' }
|
||||
}
|
||||
);
|
||||
|
||||
return $value if (!defined ($substrule) || $substrule eq '');
|
||||
|
||||
@ -2917,7 +2950,23 @@ sub HMCCU_Substitute ($$$$$;$)
|
||||
}
|
||||
}
|
||||
|
||||
# Original value not modified by rules. Use default conversion
|
||||
# Original value not modified by rules. Use default conversion depending on type/role
|
||||
# Default conversion can be overriden by attribute ccudef-substitute in I/O device
|
||||
if ((!defined($type) || $type eq '') && defined($devDesc) && defined($devDesc->{INDEX})) {
|
||||
$type = $devDesc->{TYPE};
|
||||
}
|
||||
|
||||
if (defined($type) && $type ne '') {
|
||||
if (exists($conversion{$type})) {
|
||||
if (exists($conversion{$type}{$dpt}) && exists($conversion{$type}{$dpt}{$value})) {
|
||||
return $conversion{$type}{$dpt}{$value};
|
||||
}
|
||||
}
|
||||
elsif (exists($conversion{DEFAULT}{$dpt}) && exists($conversion{DEFAULT}{$dpt}{$value})) {
|
||||
return $conversion{DEFAULT}{$dpt}{$value};
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
@ -2935,7 +2984,7 @@ sub HMCCU_Substitute ($$$$$;$)
|
||||
|
||||
sub HMCCU_SubstRule ($$$)
|
||||
{
|
||||
my ($value, $substitutes, $mode ) = @_;
|
||||
my ($value, $substitutes, $mode) = @_;
|
||||
my $rc = 0;
|
||||
|
||||
$substitutes =~ s/\$\{value\}/$value/g;
|
||||
@ -3446,6 +3495,7 @@ sub HMCCU_RemoveDevice ($$$;$)
|
||||
|
||||
######################################################################
|
||||
# Update client device ot channel
|
||||
# Store receiver, sender and ccurole
|
||||
######################################################################
|
||||
|
||||
sub HMCCU_UpdateDevice ($$)
|
||||
@ -3470,7 +3520,8 @@ sub HMCCU_UpdateDevice ($$)
|
||||
next if ($clType eq 'HMCCUCHN' && "$c" ne "$dc");
|
||||
foreach my $r (keys %{$ioHash->{hmccu}{snd}{$iface}{$da}{$c}}) {
|
||||
my @rcvNames = HMCCU_GetDeviceIdentifier ($ioHash, $r, $iface);
|
||||
my $rcvFlags = HMCCU_FlagsToStr ('peer', 'FLAGS', $ioHash->{hmccu}{snd}{$iface}{$da}{$c}{$r}{FLAGS});
|
||||
my $rcvFlags = HMCCU_FlagsToStr ('peer', 'FLAGS',
|
||||
$ioHash->{hmccu}{snd}{$iface}{$da}{$c}{$r}{FLAGS}, ',');
|
||||
push @rcvList, map { $_." [".$rcvFlags."]" } @rcvNames;
|
||||
}
|
||||
}
|
||||
@ -3479,7 +3530,8 @@ sub HMCCU_UpdateDevice ($$)
|
||||
next if ($clType eq 'HMCCUCHN' && "$c" ne "$dc");
|
||||
foreach my $s (keys %{$ioHash->{hmccu}{rcv}{$iface}{$da}{$c}}) {
|
||||
my @sndNames = HMCCU_GetDeviceIdentifier ($ioHash, $s, $iface);
|
||||
my $sndFlags = HMCCU_FlagsToStr ('peer', 'FLAGS', $ioHash->{hmccu}{snd}{$iface}{$da}{$c}{$s}{FLAGS});
|
||||
my $sndFlags = HMCCU_FlagsToStr ('peer', 'FLAGS',
|
||||
$ioHash->{hmccu}{snd}{$iface}{$da}{$c}{$s}{FLAGS}, ',');
|
||||
push @sndList, map { $_." [".$sndFlags."]" } @sndNames;
|
||||
}
|
||||
}
|
||||
@ -3488,14 +3540,48 @@ sub HMCCU_UpdateDevice ($$)
|
||||
$clHash->{receiver} = join (',', @rcvList) if (scalar(@rcvList) > 0);
|
||||
}
|
||||
|
||||
# Update channel roles
|
||||
my $devDesc = HMCCU_GetDeviceDesc ($ioHash, $address, $iface);
|
||||
if (defined($devDesc)) {
|
||||
if ($clType eq 'HMCCUCHN' && !exists($clHash->{ccurole}) && exists($devDesc->{TYPE})) {
|
||||
if ($clType eq 'HMCCUCHN' && defined($devDesc->{TYPE})) {
|
||||
$clHash->{ccurole} = $devDesc->{TYPE};
|
||||
}
|
||||
elsif ($clType eq 'HMCCUDEV' && defined($devDesc->{CHILDREN})) {
|
||||
my @roles = ();
|
||||
foreach my $c (split(',', $devDesc->{CHILDREN})) {
|
||||
my $childDevDesc = HMCCU_GetDeviceDesc ($ioHash, $c, $iface);
|
||||
if (defined($childDevDesc) && defined($childDevDesc->{TYPE})) {
|
||||
push @roles, $childDevDesc->{INDEX}.':'.$childDevDesc->{TYPE};
|
||||
}
|
||||
}
|
||||
$clHash->{ccurole} = join(',', @roles) if (scalar(@roles) > 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
######################################################################
|
||||
# Return role of a channel as stored in device hash
|
||||
######################################################################
|
||||
|
||||
sub HMCCU_GetChannelRole ($;$)
|
||||
{
|
||||
my ($clHash, $chnNo) = @_;
|
||||
|
||||
return '' if (!defined($clHash->{ccurole}));
|
||||
|
||||
if ($clHash->{TYPE} eq 'HMCCUCHN') {
|
||||
return $clHash->{ccurole};
|
||||
}
|
||||
elsif ($clHash->{TYPE} eq 'HMCCUDEV' && defined($chnNo)) {
|
||||
foreach my $role (split(',', $clHash->{ccurole})) {
|
||||
my ($c, $r) = split(':', $role);
|
||||
return $r if (defined($r) && "$c" eq "$chnNo");
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
######################################################################
|
||||
# Get device configuration for all interfaces from CCU
|
||||
# Currently binary interfaces like CUxD are not supported
|
||||
@ -3607,7 +3693,7 @@ sub HMCCU_GetDeviceDesc ($$;$)
|
||||
push (@ifaceList, $iface);
|
||||
}
|
||||
else {
|
||||
push (@ifaceList, keys %${$hash->{hmccu}{device}});
|
||||
push (@ifaceList, keys %{$hash->{hmccu}{device}});
|
||||
}
|
||||
|
||||
$address =~ s/:d//;
|
||||
@ -3652,18 +3738,28 @@ sub HMCCU_GetDeviceIdentifier ($$;$$)
|
||||
|
||||
######################################################################
|
||||
# Convert device description to string
|
||||
# Parameter $object can be a device or channel address or a client
|
||||
# device hash reference.
|
||||
######################################################################
|
||||
|
||||
sub HMCCU_DeviceDescToStr ($)
|
||||
sub HMCCU_DeviceDescToStr ($$)
|
||||
{
|
||||
my ($clHash) = @_;
|
||||
my ($ioHash, $object) = @_;
|
||||
|
||||
my $result = '';
|
||||
my $ioHash = HMCCU_GetHash ($clHash);
|
||||
return undef if (!defined($ioHash));
|
||||
|
||||
my ($devAddr, $chnNo) = HMCCU_SplitChnAddr ($clHash->{ccuaddr});
|
||||
my $devDesc = HMCCU_GetDeviceDesc ($ioHash, $devAddr, $clHash->{ccuif});
|
||||
my $address;
|
||||
my $iface;
|
||||
|
||||
if (ref($object) eq 'HASH') {
|
||||
$address = $object->{ccuaddr};
|
||||
$iface = $object->{ccuif};
|
||||
}
|
||||
else {
|
||||
$address = $object;
|
||||
}
|
||||
|
||||
my ($devAddr, $chnNo) = HMCCU_SplitChnAddr ($address);
|
||||
my $devDesc = HMCCU_GetDeviceDesc ($ioHash, $devAddr, $iface);
|
||||
return undef if (!defined($devDesc));
|
||||
my @addList = ($devAddr);
|
||||
push (@addList, split (',', $devDesc->{CHILDREN}))
|
||||
@ -3671,9 +3767,9 @@ sub HMCCU_DeviceDescToStr ($)
|
||||
|
||||
foreach my $a (@addList) {
|
||||
my ($d, $c) = HMCCU_SplitChnAddr ($a);
|
||||
next if ($clHash->{TYPE} eq 'HMCCUCHN' && "$c" ne '0' && "$c" ne "$chnNo" && $c ne '');
|
||||
next if ($chnNo ne '' && "$c" ne '0' && "$c" ne "$chnNo" && $c ne '');
|
||||
|
||||
$devDesc = HMCCU_GetDeviceDesc ($ioHash, $a, $clHash->{ccuif});
|
||||
$devDesc = HMCCU_GetDeviceDesc ($ioHash, $a, $iface);
|
||||
return undef if (!defined($devDesc));
|
||||
|
||||
$result .= $a eq $devAddr ? "Device $a" : "Channel $a";
|
||||
@ -3692,20 +3788,31 @@ sub HMCCU_DeviceDescToStr ($)
|
||||
# Convert parameter set description to string
|
||||
######################################################################
|
||||
|
||||
sub HMCCU_ParamsetDescToStr ($)
|
||||
sub HMCCU_ParamsetDescToStr ($$)
|
||||
{
|
||||
my ($clHash) = @_;
|
||||
my ($ioHash, $object) = @_;
|
||||
|
||||
my $result = '';
|
||||
my $ioHash = HMCCU_GetHash ($clHash);
|
||||
return undef if (!defined($ioHash));
|
||||
my $address;
|
||||
my $iface;
|
||||
|
||||
if (ref($object) eq 'HASH') {
|
||||
$address = $object->{ccuaddr};
|
||||
$iface = $object->{ccuif};
|
||||
}
|
||||
else {
|
||||
$address = $object;
|
||||
}
|
||||
|
||||
my ($devAddr, $chnNo) = HMCCU_SplitChnAddr ($clHash->{ccuaddr});
|
||||
my $model = HMCCU_GetClientDeviceModel ($clHash);
|
||||
my ($devAddr, $chnNo) = HMCCU_SplitChnAddr ($address);
|
||||
|
||||
my $devDesc = HMCCU_GetDeviceDesc ($ioHash, $address, $iface);
|
||||
return undef if (!defined($devDesc));
|
||||
my $model = HMCCU_GetDeviceModel ($ioHash, $devDesc->{_model}, $devDesc->{_fw_ver});
|
||||
return undef if (!defined($model));
|
||||
|
||||
my @chnList = ();
|
||||
if ($clHash->{TYPE} eq 'HMCCUDEV') {
|
||||
if ($chnNo eq '') {
|
||||
push @chnList, sort keys %{$model};
|
||||
unshift (@chnList, pop(@chnList)) if (exists($model->{'d'}));
|
||||
}
|
||||
@ -3963,7 +4070,7 @@ sub HMCCU_FindParamDef ($$$)
|
||||
# Convert parameter value
|
||||
# Parameters:
|
||||
# $hash - Hash reference of IO device.
|
||||
# $object - Device or channel address.
|
||||
# $object - Device/channel address or device description reference.
|
||||
# $paramset - Parameter set.
|
||||
# $parameter - Parameter name.
|
||||
# $value - Parameter value.
|
||||
@ -3989,8 +4096,6 @@ sub HMCCU_GetParamValue ($$$$$)
|
||||
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;
|
||||
@ -4050,7 +4155,7 @@ sub HMCCU_FlagsToStr ($$$;$$)
|
||||
'OPERATIONS' => { 1 => 'R', 2 => 'W', 4 => 'E' }
|
||||
},
|
||||
'peer' => {
|
||||
'FLAGS' => { 1 => "SENDER_BROKEN", 2 => "RECEIVER_BROKEN", 3 => "LINK_BROKEN" }
|
||||
'FLAGS' => { 1 => "SENDER_BROKEN", 2 => "RECEIVER_BROKEN" }
|
||||
}
|
||||
);
|
||||
|
||||
@ -4163,7 +4268,7 @@ sub HMCCU_UpdateParamsetReadings ($$$;$)
|
||||
|
||||
my $chnAddr = "$devAddr:$c";
|
||||
my $devDesc = HMCCU_GetDeviceDesc ($ioHash, $chnAddr, $clHash->{ccuif});
|
||||
my $chnType = defined($devDesc) ? $devDesc->{TYPE} : undef;
|
||||
my $chnType = defined($devDesc) ? $devDesc->{TYPE} : HMCCU_GetChannelRole ($clHash, $c);
|
||||
|
||||
# Loop over all parameter sets
|
||||
foreach my $ps (keys %{$objects->{$a}{$c}}) {
|
||||
@ -4187,11 +4292,8 @@ sub HMCCU_UpdateParamsetReadings ($$$;$)
|
||||
# Modify value: scale, format, substitute
|
||||
$sv = HMCCU_ScaleValue ($clHash, $c, $p, $v, 0);
|
||||
$fv = HMCCU_FormatReadingValue ($clHash, $sv, $p);
|
||||
$cv = HMCCU_Substitute ($fv, $substitute, 0, $c, $p, $chnType);
|
||||
if ("$cv" eq "$fv") {
|
||||
# If value has not been changed by rules, use default conversion
|
||||
$cv = HMCCU_GetParamValue ($ioHash, $devDesc, $ps, $p, $fv);
|
||||
}
|
||||
$cv = HMCCU_Substitute ($fv, $substitute, 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;
|
||||
@ -4301,6 +4403,9 @@ sub HMCCU_UpdateSingleDevice ($$$$)
|
||||
next if ($clttype eq 'HMCCUCHN' && "$chnnum" ne "$cnum" && "$chnnum" ne "0");
|
||||
next if ("$chnnum" eq "0" && $cf =~ /nochn0/);
|
||||
my $chnadd = "$addr:$chnnum";
|
||||
|
||||
my $devDesc = HMCCU_GetDeviceDesc ($ccuhash, $chnadd, $clthash->{ccuif});
|
||||
my $chnType = defined($devDesc) ? $devDesc->{TYPE} : HMCCU_GetChannelRole ($clthash, $chnnum);
|
||||
|
||||
# Update datapoints of channel
|
||||
foreach my $dpt (keys (%{$objects->{$addr}{$chnnum}})) {
|
||||
@ -4321,7 +4426,8 @@ sub HMCCU_UpdateSingleDevice ($$$$)
|
||||
my @readings = HMCCU_GetReadingName ($clthash, '', $addr, $chnnum, $dpt, '', $crf);
|
||||
my $svalue = HMCCU_ScaleValue ($clthash, $chnnum, $dpt, $value, 0);
|
||||
my $fvalue = HMCCU_FormatReadingValue ($clthash, $svalue, $dpt);
|
||||
my $cvalue = HMCCU_Substitute ($fvalue, $substitute, 0, $chnnum, $dpt);
|
||||
my $cvalue = HMCCU_Substitute ($fvalue, $substitute, 0, $chnnum, $dpt, $chnType, $devDesc);
|
||||
$cvalue = HMCCU_GetParamValue ($ccuhash, $devDesc, 'VALUES', $dpt, $fvalue) if ("$fvalue" eq "$cvalue");
|
||||
# my %calcs = HMCCU_CalculateReading ($clthash, $chkey);
|
||||
|
||||
# Store the resulting value after scaling, formatting and substitution
|
||||
@ -7573,6 +7679,7 @@ sub HMCCU_ScaleValue ($$$$$)
|
||||
{
|
||||
my ($hash, $chnno, $dpt, $value, $mode) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
my $ioHash = HMCCU_GetHash ($hash);
|
||||
|
||||
my $ccuscaleval = AttrVal ($name, 'ccuscaleval', '');
|
||||
return $value if ($ccuscaleval eq '');
|
||||
@ -7623,6 +7730,22 @@ sub HMCCU_ScaleValue ($$$$$)
|
||||
}
|
||||
}
|
||||
|
||||
if ($dpt eq 'LEVEL') {
|
||||
return ($mode == 0) ? min($value,100.0)/100.0 : min($value,1.0)*100.0;
|
||||
}
|
||||
# my $address = $hash->{TYPE} eq 'HMCCUDEV' ? $hash->{ccuaddr}.":$chnno" : $hash->{ccuaddr};
|
||||
# my $devDesc = HMCCU_GetDeviceDesc ($ioHash, $address, $hash->{ccuif});
|
||||
# if (defined($devDesc)) {
|
||||
# my $devModel = HMCCU_GetDeviceModel ($ioHash, $devDesc->{_model}, $devDesc->{_fw_ver}, $chnno);
|
||||
# if (defined($devModel)) {
|
||||
# if ($devDesc->{TYPE} eq 'BLIND' || $devDesc->{TYPE} eq 'DIMMER' && $dpt eq 'LEVEL') {
|
||||
# my $f = $devModel->{VALUES}{LEVEL}{MAX}-$devModel->{VALUES}{LEVEL}{MIN};
|
||||
# $f = 1.0 if (!defined($f) || $f == 0.0);
|
||||
# return ($mode == 0) ? $value/$f : $value*$f;
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
@ -9348,14 +9471,12 @@ sub HMCCU_CCURPC_ListDevicesCB ($$)
|
||||
<li><b>get <name> ccumsg {service|alarm}</b><br/>
|
||||
Query active service or alarm messages from CCU. Generate FHEM event for each message.
|
||||
</li><br/>
|
||||
<li><b>get <name> configdesc {<device>|<channel>}</b><br/>
|
||||
Get configuration parameter description of CCU device or channel (similar
|
||||
to device settings in CCU). Not every CCU device or channel provides a configuration
|
||||
parameter description. So result may be empty.
|
||||
</li><br/>
|
||||
<li><b>get <name> defaults</b><br/>
|
||||
List device types and channels with default attributes available.
|
||||
</li><br/>
|
||||
<li><b>get <name> deviceDesc {<device>|<channel>}</b><br/>
|
||||
Get description of CCU device or channel.
|
||||
</li><br/>
|
||||
<li><b>get <name> deviceinfo <device-name> [{State | <u>Value</u>}]</b><br/>
|
||||
List device channels and datapoints. If option 'State' is specified the device is
|
||||
queried directly. Otherwise device information from CCU is listed.
|
||||
@ -9408,6 +9529,9 @@ sub HMCCU_CCURPC_ListDevicesCB ($$)
|
||||
With parameter <i>type-expr</i> one can filter displayed firmware versions by
|
||||
Homematic device type.
|
||||
</li><br/>
|
||||
<li><b>get <name> paramsetDesc {<device>|<channel>}</b><br/>
|
||||
Get parameter set description of CCU device or channel.
|
||||
</li><br/>
|
||||
<li><b>get <name> rpcstate</b><br/>
|
||||
Check if RPC server process is running.
|
||||
</li><br/>
|
||||
|
@ -4,7 +4,7 @@
|
||||
#
|
||||
# $Id: 88_HMCCUCHN.pm 18552 2019-02-10 11:52:28Z zap $
|
||||
#
|
||||
# Version 4.4.005
|
||||
# Version 4.4.007
|
||||
#
|
||||
# (c) 2020 zap (zap01 <at> t-online <dot> de)
|
||||
#
|
||||
@ -276,13 +276,13 @@ sub HMCCUCHN_Set ($@)
|
||||
if ($opt ne '?' && $ccuflags =~ /logCommand/ || HMCCU_IsFlag ($hmccu_name, 'logCommand'));
|
||||
|
||||
if ($opt eq 'datapoint') {
|
||||
my $usage = "Usage: set $name datapoint {datapoint} {value} [...]";
|
||||
my $usage = "Usage: set $name datapoint {{datapoint} {value} | {datapoint}={value}} [...]";
|
||||
my %dpval;
|
||||
my $i = 0;
|
||||
|
||||
while (my $objname = shift @$a) {
|
||||
my $objvalue = shift @$a;
|
||||
$i += 1;
|
||||
$i++;
|
||||
|
||||
return HMCCU_SetError ($hash, $usage) if (!defined ($objvalue));
|
||||
return HMCCU_SetError ($hash, -8)
|
||||
@ -292,6 +292,18 @@ sub HMCCUCHN_Set ($@)
|
||||
$objvalue =~ s/\\_/%20/g;
|
||||
$dpval{"$no.$ccuif.$ccuaddr.$objname"} = HMCCU_Substitute ($objvalue, $statevals, 1, undef, '');
|
||||
}
|
||||
|
||||
if (defined($h)) {
|
||||
foreach my $objname (keys %$h) {
|
||||
my $objvalue = $h->{$objname};
|
||||
$i++;
|
||||
my $no = sprintf ("%03d", $i);
|
||||
return HMCCU_SetError ($hash, -8)
|
||||
if (!HMCCU_IsValidDatapoint ($hash, $ccutype, $ccuaddr, $objname, 2));
|
||||
$objvalue =~ s/\\_/%20/g;
|
||||
$dpval{"$no.$ccuif.$ccuaddr.$objname"} = HMCCU_Substitute ($objvalue, $statevals, 1, undef, '');
|
||||
}
|
||||
}
|
||||
|
||||
return HMCCU_SetError ($hash, $usage) if (scalar (keys %dpval) < 1);
|
||||
|
||||
@ -365,10 +377,10 @@ sub HMCCUCHN_Set ($@)
|
||||
return HMCCU_SetError ($hash, "Can't find LEVEL datapoint for device type $ccutype")
|
||||
if (!HMCCU_IsValidDatapoint ($hash, $ccutype, $ccuaddr, "LEVEL", 2));
|
||||
|
||||
if ($opt eq 'pct') {
|
||||
if ($opt eq 'pct' || $opt eq 'level') {
|
||||
my $objname = '';
|
||||
my $objvalue = shift @$a;
|
||||
return HMCCU_SetError ($hash, "Usage: set $name pct {value} [{ontime} [{ramptime}]]")
|
||||
return HMCCU_SetError ($hash, "Usage: set $name $opt {value} [{ontime} [{ramptime}]]")
|
||||
if (!defined ($objvalue));
|
||||
|
||||
my $timespec = shift @$a;
|
||||
@ -443,7 +455,7 @@ sub HMCCUCHN_Set ($@)
|
||||
my %parSets = ('config' => 'MASTER', 'links' => 'LINK', 'values' => 'VALUES');
|
||||
my $paramset = '';
|
||||
|
||||
return HMCCU_SetError ($hash, "Usage: set $name $opt [device] [paramset] {parameter}={value}[:{type}] [...]")
|
||||
return HMCCU_SetError ($hash, "No parameter specified")
|
||||
if ((scalar keys %{$h}) < 1);
|
||||
|
||||
if (exists($parSets{$opt})) {
|
||||
@ -453,6 +465,8 @@ sub HMCCUCHN_Set ($@)
|
||||
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;
|
||||
}
|
||||
@ -496,9 +510,9 @@ sub HMCCUCHN_Set ($@)
|
||||
}
|
||||
$retmsg .= " toggle:noArg";
|
||||
$retmsg .= " on-for-timer on-till"
|
||||
if (HMCCU_IsValidDatapoint ($hash, $hash->{ccutype}, $ccuaddr, "ON_TIME", 2));
|
||||
$retmsg .= " pct up down"
|
||||
if (HMCCU_IsValidDatapoint ($hash, $hash->{ccutype}, $ccuaddr, "LEVEL", 2));
|
||||
if (HMCCU_IsValidDatapoint ($hash, $hash->{ccutype}, $sc, "ON_TIME", 2));
|
||||
$retmsg .= " pct up down level"
|
||||
if (HMCCU_IsValidDatapoint ($hash, $hash->{ccutype}, $cc, "LEVEL", 2));
|
||||
}
|
||||
}
|
||||
return AttrTemplate_Set ($hash, $retmsg, $name, $opt, @$a);
|
||||
@ -590,17 +604,18 @@ sub HMCCUCHN_Get ($@)
|
||||
my @addList = ($devAddr, "$devAddr:0", $ccuaddr);
|
||||
my $par = shift @$a;
|
||||
|
||||
if (exists($parSets{$opt})) {
|
||||
$defParamset = $parSets{$opt};
|
||||
}
|
||||
else {
|
||||
if (defined($par)) {
|
||||
if (defined($par)) {
|
||||
if ($opt eq 'paramset') {
|
||||
$defParamset = $par;
|
||||
$par = shift @$a;
|
||||
}
|
||||
else {
|
||||
return "Usage: get $name $opt";
|
||||
}
|
||||
}
|
||||
|
||||
$par = '.*' if (!defined ($par));
|
||||
if (exists($parSets{$opt})) {
|
||||
$defParamset = $parSets{$opt};
|
||||
}
|
||||
|
||||
my %objects;
|
||||
foreach my $a (@addList) {
|
||||
@ -629,8 +644,8 @@ sub HMCCUCHN_Get ($@)
|
||||
$res .= "Device $da\n";
|
||||
foreach my $dc (sort keys %{$convRes->{$da}}) {
|
||||
$res .= " Channel $dc\n";
|
||||
$res .= join ("\n", map { $_ =~ /$par/ ?
|
||||
" ".$_.' = '.$convRes->{$da}{$dc}{$_} : ()
|
||||
$res .= join ("\n", map {
|
||||
" ".$_.' = '.$convRes->{$da}{$dc}{$_}
|
||||
} sort keys %{$convRes->{$da}{$dc}})."\n";
|
||||
}
|
||||
}
|
||||
@ -640,11 +655,11 @@ sub HMCCUCHN_Get ($@)
|
||||
return $res eq '' ? "No data found" : $res;
|
||||
}
|
||||
elsif ($opt eq 'paramsetdesc') {
|
||||
$result = HMCCU_ParamsetDescToStr ($hash);
|
||||
$result = HMCCU_ParamsetDescToStr ($ioHash, $hash);
|
||||
return defined($result) ? $result : HMCCU_SetError ($hash, "Can't get device model");
|
||||
}
|
||||
elsif ($opt eq 'devicedesc') {
|
||||
$result = HMCCU_DeviceDescToStr ($hash);
|
||||
$result = HMCCU_DeviceDescToStr ($ioHash, $hash);
|
||||
return defined($result) ? $result : HMCCU_SetError ($hash, "Can't get device description");
|
||||
}
|
||||
elsif ($opt eq 'defaults') {
|
||||
@ -707,10 +722,10 @@ sub HMCCUCHN_Get ($@)
|
||||
Delete readings matching specified reading name expression. Default expression is '.*'.
|
||||
Readings 'state' and 'control' are not deleted.
|
||||
</li><br/>
|
||||
<li><b>set <name> config</b><br/>
|
||||
<li><b>set <name> config [device] <parameter>=<value[:<type>]></b><br/>
|
||||
Alias for command 'set paramset' for parameter set MASTER.
|
||||
</li><br/>
|
||||
<li><b>set <name> datapoint <datapoint> <value> [...]</b><br/>
|
||||
<li><b>set <name> datapoint <datapoint> <value> | <datapoint>=<value> [...]</b><br/>
|
||||
Set datapoint values of a CCU channel. If parameter <i>value</i> contains special
|
||||
character \_ it's substituted by blank.
|
||||
<br/><br/>
|
||||
@ -733,7 +748,10 @@ sub HMCCUCHN_Get ($@)
|
||||
Decrement value of datapoint LEVEL. This command is only available if channel contains
|
||||
a datapoint LEVEL. Default for <i>value</i> is 10.
|
||||
</li><br/>
|
||||
<li><b>set <name> link</b><br/>
|
||||
<li><b>set <name> pct <value> [<ontime> [<ramptime>]]</b><br/>
|
||||
Alias for command 'set pct'.
|
||||
</li><br/>
|
||||
<li><b>set <name> link <parameter>=<value[:<type>]></b><br/>
|
||||
Alias for command 'set paramset' for parameter set LINK.
|
||||
</li><br/>
|
||||
<li><b>set <name> <statevalue></b><br/>
|
||||
@ -819,8 +837,8 @@ sub HMCCUCHN_Get ($@)
|
||||
<a name="HMCCUCHNget"></a>
|
||||
<b>Get</b><br/><br/>
|
||||
<ul>
|
||||
<li><b>get <name> config [<filter-expr>]</b><br/>
|
||||
Same as 'get paramset', but read only parameter set MASTER.
|
||||
<li><b>get <name> config</b><br/>
|
||||
Same as 'get paramset', but read only parameter sets MASTER and LINK.
|
||||
</li><br/>
|
||||
<li><b>get <name> datapoint <datapoint></b><br/>
|
||||
Get value of a CCU channel datapoint.
|
||||
@ -828,10 +846,10 @@ sub HMCCUCHN_Get ($@)
|
||||
<li><b>get <name> defaults</b><br/>
|
||||
Display default attributes for CCU device type.
|
||||
</li><br/>
|
||||
<li><b>get <name> devicedesc</b><br/>
|
||||
<li><b>get <name> deviceDesc</b><br/>
|
||||
Display device or channel description. A channel description always includes channel 0.
|
||||
</li><br/>
|
||||
<li><b>get <name> deviceinfo</b><br/>
|
||||
<li><b>get <name> deviceInfo</b><br/>
|
||||
Display all channels and datapoints of device with datapoint values and types.
|
||||
</li><br/>
|
||||
<li><b>get <name> devstate</b><br/>
|
||||
@ -839,36 +857,24 @@ sub HMCCUCHN_Get ($@)
|
||||
attribute 'statedatapoint'. Command will fail if state datapoint does not exist in
|
||||
channel.
|
||||
</li><br/>
|
||||
<li><b>get <name> links [<filter-expr>]</b><br/>
|
||||
Same as 'get paramset', but read only parameter set LINK.
|
||||
</li><br/>
|
||||
<li><b>get <name> paramset [<paramset>[,...]] [<filter-expr>]</b><br/>
|
||||
<li><b>get <name> paramset [<paramset>[,...]]</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.
|
||||
Parameters can be filtered by <i>filter-expr</i>. If option 'device' is specified parameters
|
||||
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 <name> paramsetdesc</b><br/>
|
||||
<li><b>get <name> paramsetDesc</b><br/>
|
||||
Display description of parameter sets of channel and device.
|
||||
</li><br/>
|
||||
<li><b>get <name> peers</b><br/>
|
||||
Read links for current channel and store them as readings beginning with "P-".
|
||||
This prefix can be modified with attribut 'ccuReadingPrefix'.
|
||||
</li><br/>
|
||||
<li><b>get <name> peerlist</b><br/>
|
||||
Read links for current channel and list them in browser window.
|
||||
</li><br/>
|
||||
<li><b>get <name> update [{State | <u>Value</u>}]</b><br/>
|
||||
Update all datapoints / readings of channel. With option 'State' the device is queried.
|
||||
This request method is more accurate but slower then 'Value'.
|
||||
</li><br/>
|
||||
<li><b>get <name> values [<filter-expr>]</b><br/>
|
||||
Same as 'get update' but using RPC instead of ReGa. Datapoint read from CCU can be
|
||||
filtered by <i>filter-expr</i>.
|
||||
<li><b>get <name> values</b><br/>
|
||||
Same as 'get update' but using RPC instead of ReGa.
|
||||
</li>
|
||||
</ul>
|
||||
<br/>
|
||||
|
@ -646,7 +646,7 @@ sub HMCCUDEV_Set ($@)
|
||||
$retmsg .= " toggle:noArg";
|
||||
$retmsg .= " on-for-timer on-till"
|
||||
if (HMCCU_IsValidDatapoint ($hash, $hash->{ccutype}, $sc, "ON_TIME", 2));
|
||||
$retmsg .= " pct up down"
|
||||
$retmsg .= " pct up down level"
|
||||
if (HMCCU_IsValidDatapoint ($hash, $hash->{ccutype}, $sc, "LEVEL", 2) ||
|
||||
HMCCU_IsValidDatapoint ($hash, $hash->{ccutype}, $cc, "LEVEL", 2));
|
||||
}
|
||||
@ -832,11 +832,11 @@ sub HMCCUDEV_Get ($@)
|
||||
return $res;
|
||||
}
|
||||
elsif ($opt eq 'paramsetdesc') {
|
||||
$result = HMCCU_ParamsetDescToStr ($hash);
|
||||
$result = HMCCU_ParamsetDescToStr ($ioHash, $hash);
|
||||
return defined($result) ? $result : HMCCU_SetError ($hash, "Can't get device model");
|
||||
}
|
||||
elsif ($opt eq 'devicedesc') {
|
||||
$result = HMCCU_DeviceDescToStr ($hash);
|
||||
$result = HMCCU_DeviceDescToStr ($ioHash, $hash);
|
||||
return defined($result) ? $result : HMCCU_SetError ($hash, "Can't get device description");
|
||||
}
|
||||
elsif ($opt eq 'defaults') {
|
||||
|
Loading…
x
Reference in New Issue
Block a user