mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-03-10 09:16:53 +00:00
HMCCU: Update 4.4 Beta
git-svn-id: https://svn.fhem.de/fhem/trunk@24463 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
a8a48134e2
commit
e67bb25dec
@ -1,6 +1,8 @@
|
||||
- bugfix: 88_HMCCU.pm: Release candidate 5
|
||||
- bugfix: 88_HMCCU.pm: Release candidate 4
|
||||
- bugfix: 88_HMCCU.pm: Release candidate 3
|
||||
- bugfix: 88_HMCCU.pm: Release candidate 2
|
||||
- bugfix: 88_HMCCU.pm: Fixed bug in set defaults command
|
||||
- bugfix: 88_HMCCU.pm: Fixed state-/controldatapoint bug during start
|
||||
- bugfix: 88_HMCCU.pm: Fixed state/controldatapoint bug during FHEM start
|
||||
- bugfix: 88_HMCCU.pm: Fixed some bugs. New command set readingFilter
|
||||
- bugfix: 88_HMCCU.pm: Fixed device detection bugs
|
||||
|
@ -4,7 +4,7 @@
|
||||
#
|
||||
# $Id: 88_HMCCU.pm 18745 2019-02-26 17:33:23Z zap $
|
||||
#
|
||||
# Version 4.4.066
|
||||
# Version 4.4.068
|
||||
#
|
||||
# Module for communication between FHEM and Homematic CCU2/3.
|
||||
#
|
||||
@ -58,7 +58,7 @@ my %HMCCU_CUST_CHN_DEFAULTS;
|
||||
my %HMCCU_CUST_DEV_DEFAULTS;
|
||||
|
||||
# HMCCU version
|
||||
my $HMCCU_VERSION = '4.4.066';
|
||||
my $HMCCU_VERSION = '4.4.068';
|
||||
|
||||
# Timeout for CCU requests (seconds)
|
||||
my $HMCCU_TIMEOUT_REQUEST = 4;
|
||||
@ -97,6 +97,7 @@ my %HMCCU_RPC_SSL = (
|
||||
# Default values for delayed initialization during FHEM startup
|
||||
my $HMCCU_INIT_INTERVAL0 = 12;
|
||||
my $HMCCU_CCU_PING_TIMEOUT = 1;
|
||||
my $HMCCU_CCU_PING_SLEEP = 1;
|
||||
my $HMCCU_CCU_BOOT_DELAY = 180;
|
||||
my $HMCCU_CCU_DELAYED_INIT = 59;
|
||||
my $HMCCU_CCU_RPC_OFFSET = 20;
|
||||
@ -148,7 +149,7 @@ my $HMCCU_EXT_ADDR = 'ZZZ0000000';
|
||||
|
||||
# FHEM standard functions
|
||||
sub HMCCU_Initialize ($);
|
||||
sub HMCCU_Define ($$);
|
||||
sub HMCCU_Define ($$$);
|
||||
sub HMCCU_InitDevice ($);
|
||||
sub HMCCU_Undef ($$);
|
||||
sub HMCCU_DelayedShutdown ($);
|
||||
@ -184,7 +185,7 @@ sub HMCCU_SetRPCState ($@);
|
||||
sub HMCCU_FilterReading ($$$;$);
|
||||
sub HMCCU_FormatReadingValue ($$$);
|
||||
sub HMCCU_GetReadingName ($$$$$$$;$);
|
||||
sub HMCCU_ScaleValue ($$$$$);
|
||||
sub HMCCU_ScaleValue ($$$$$;$);
|
||||
sub HMCCU_StripNumber ($$;$);
|
||||
sub HMCCU_Substitute ($$$$$;$$);
|
||||
sub HMCCU_SubstRule ($$$);
|
||||
@ -251,6 +252,7 @@ sub HMCCU_ExecuteRoleCommand ($@);
|
||||
sub HMCCU_ExecuteGetDeviceInfoCommand ($@);
|
||||
sub HMCCU_ExecuteGetParameterCommand ($@);
|
||||
sub HMCCU_ExecuteSetClearCommand ($@);
|
||||
sub HMCCU_ExecuteSetControlCommand ($@);
|
||||
sub HMCCU_ExecuteSetDatapointCommand ($@);
|
||||
sub HMCCU_ExecuteSetParameterCommand ($@);
|
||||
sub HMCCU_DisplayGetParameterResult ($$$);
|
||||
@ -347,9 +349,10 @@ sub HMCCU_ISO2UTF ($);
|
||||
sub HMCCU_Max ($$);
|
||||
sub HMCCU_MaxHashEntries ($$);
|
||||
sub HMCCU_Min ($$);
|
||||
sub HMCCU_MinMax ($$$);
|
||||
sub HMCCU_RefToString ($);
|
||||
sub HMCCU_ResolveName ($$);
|
||||
sub HMCCU_TCPConnect ($$);
|
||||
sub HMCCU_TCPConnect ($$;$);
|
||||
sub HMCCU_TCPPing ($$$);
|
||||
sub HMCCU_UpdateReadings ($$;$);
|
||||
|
||||
@ -390,7 +393,7 @@ sub HMCCU_Initialize ($)
|
||||
# Define device
|
||||
######################################################################
|
||||
|
||||
sub HMCCU_Define ($$)
|
||||
sub HMCCU_Define ($$$)
|
||||
{
|
||||
my ($hash, $a, $h) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
@ -1700,11 +1703,12 @@ sub HMCCU_Get ($@)
|
||||
return $devTable;
|
||||
}
|
||||
elsif ($opt eq 'deviceinfo') {
|
||||
my $device = shift @$a // return HMCCU_SetError ($hash, "Usage: get $name $opt {device}");
|
||||
my $device = shift @$a // return HMCCU_SetError ($hash, "Usage: get $name $opt {device} [extended]");
|
||||
my $extended = shift @$a;
|
||||
my ($int, $add, $chn, $dpt, $nam, $flags) = HMCCU_ParseObject ($hash, $device,
|
||||
$HMCCU_FLAG_FULLADDR);
|
||||
return HMCCU_SetError ($hash, -1, $device) if (!($flags & $HMCCU_FLAG_ADDRESS));
|
||||
return HMCCU_ExecuteGetDeviceInfoCommand ($hash, $hash, $add);
|
||||
return HMCCU_ExecuteGetDeviceInfoCommand ($hash, $hash, $add, defined($extended) ? 1 : 0);
|
||||
}
|
||||
elsif ($opt eq 'rpcevents') {
|
||||
$result = '';
|
||||
@ -3296,6 +3300,11 @@ sub HMCCU_UpdateDevice ($$)
|
||||
my $iface = $clHash->{ccuif};
|
||||
my ($da, $dc) = HMCCU_SplitChnAddr ($address);
|
||||
|
||||
# Update device information
|
||||
if (exists($ioHash->{hmccu}{device}{$iface}{$da})) {
|
||||
$clHash->{firmware} = $ioHash->{hmccu}{device}{$iface}{$da}{FIRMWARE} // '?';
|
||||
}
|
||||
|
||||
# Update link receivers
|
||||
if (exists($ioHash->{hmccu}{snd}{$iface}{$da})) {
|
||||
delete $clHash->{receiver} if (exists($clHash->{receiver}));
|
||||
@ -3561,7 +3570,6 @@ sub HMCCU_GetDeviceRoles ($$$;$)
|
||||
|
||||
######################################################################
|
||||
# Get device configuration for all interfaces from CCU
|
||||
# Currently binary interfaces like CUxD are not supported
|
||||
######################################################################
|
||||
|
||||
sub HMCCU_GetDeviceConfig ($)
|
||||
@ -4419,6 +4427,8 @@ sub HMCCU_UpdateParamsetReadings ($$$;$)
|
||||
|
||||
# Modify value: scale, format, substitute
|
||||
$sv = HMCCU_ScaleValue ($clHash, $c, $p, $v, 0);
|
||||
HMCCU_UpdateInternalValues ($clHash, $chKey, $ps, 'NVAL', $sv);
|
||||
HMCCU_Trace ($clHash, 2, "$p: sv = $sv");
|
||||
$fv = HMCCU_FormatReadingValue ($clHash, $sv, $p);
|
||||
$cv = HMCCU_Substitute ($fv, $clHash, 0, $c, $p, $chnType, $devDesc);
|
||||
$cv = HMCCU_GetParamValueConversion ($ioHash, $devDesc, $ps, $p, $fv)
|
||||
@ -4944,10 +4954,11 @@ sub HMCCU_IsRPCStateBlocking ($)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
|
||||
return ($hash->{RPCState} eq 'starting' ||
|
||||
return (exists($hash->{RPCState}) && (
|
||||
$hash->{RPCState} eq 'starting' ||
|
||||
$hash->{RPCState} eq 'restarting' ||
|
||||
$hash->{RPCState} eq 'stopping'
|
||||
) ? 1 : 0;
|
||||
)) ? 1 : 0;
|
||||
}
|
||||
|
||||
######################################################################
|
||||
@ -6348,7 +6359,7 @@ sub HMCCU_SetInitialAttributes ($$)
|
||||
my ($ioHash, $clName) = @_;
|
||||
|
||||
my $ccudefAttributes = AttrVal ($ioHash->{NAME}, 'ccudef-attributes', 'room=Homematic');
|
||||
foreach my $a (split(',', $ccudefAttributes)) {
|
||||
foreach my $a (split(';', $ccudefAttributes)) {
|
||||
my ($an, $av) = split('=', $a);
|
||||
CommandAttr (undef, "$clName $an $av") if (defined($av));
|
||||
}
|
||||
@ -6365,8 +6376,9 @@ sub HMCCU_SetDefaultAttributes ($;$)
|
||||
my $ioHash = HMCCU_GetHash ($clHash);
|
||||
my $clName = $clHash->{NAME};
|
||||
|
||||
my ($sc, $sd, $cc, $cd) = HMCCU_GetSCDatapoints ($clHash);
|
||||
$parRef //= { mode => 'update', role => undef, roleChn => undef };
|
||||
my $role = $parRef->{role} // HMCCU_GetChannelRole ($clHash, $parRef->{roleChn});
|
||||
my $role = $parRef->{role} // HMCCU_GetChannelRole ($clHash, $parRef->{roleChn} // $cc);
|
||||
|
||||
if ($role ne '') {
|
||||
$clHash->{hmccu}{semDefaults} = 1;
|
||||
@ -6674,11 +6686,12 @@ sub HMCCU_UpdateAdditionalCommands ($$;$$)
|
||||
# Execute command related to role
|
||||
# Parameters:
|
||||
# $mode: 'set' or 'get'
|
||||
# $command: The command
|
||||
######################################################################
|
||||
|
||||
sub HMCCU_ExecuteRoleCommand ($@)
|
||||
{
|
||||
my ($ioHash, $clHash, $mode, $command, $cc, $a, $h) = @_;
|
||||
my ($ioHash, $clHash, $mode, $command, $a, $h) = @_;
|
||||
|
||||
my $name = $clHash->{NAME};
|
||||
my $rc;
|
||||
@ -6692,6 +6705,7 @@ sub HMCCU_ExecuteRoleCommand ($@)
|
||||
|
||||
my $channel = $clHash->{hmccu}{roleCmds}{$mode}{$command}{channel};
|
||||
if ("$channel" eq '?') {
|
||||
my ($sc, $sd, $cc, $cd) = HMCCU_GetSCDatapoints ($clHash);
|
||||
return HMCCU_SetError ($clHash, -12) if ($cc eq '');
|
||||
$channel = $cc;
|
||||
}
|
||||
@ -6732,8 +6746,8 @@ sub HMCCU_ExecuteRoleCommand ($@)
|
||||
# Delta value. Sign depends on sign of default value. Sign of specified value is ignored
|
||||
my $sign = $1 eq '+' ? 1 : -1;
|
||||
return HMCCU_SetError ($clHash, "Current value of $channel.$cmd->{dpt} not available")
|
||||
if (!defined($clHash->{hmccu}{dp}{"$channel.$cmd->{dpt}"}{$cmd->{ps}}{SVAL}));
|
||||
$value = $clHash->{hmccu}{dp}{"$channel.$cmd->{dpt}"}{$cmd->{ps}}{SVAL}+abs(int($value))*$sign;
|
||||
if (!defined($clHash->{hmccu}{dp}{"$channel.$cmd->{dpt}"}{$cmd->{ps}}{NVAL}));
|
||||
$value = $clHash->{hmccu}{dp}{"$channel.$cmd->{dpt}"}{$cmd->{ps}}{NVAL}+abs(int($value))*$sign;
|
||||
}
|
||||
if ($cmd->{unit} eq 's') {
|
||||
$value = HMCCU_GetTimeSpec ($value);
|
||||
@ -6750,10 +6764,13 @@ sub HMCCU_ExecuteRoleCommand ($@)
|
||||
push @par, $vl;
|
||||
}
|
||||
|
||||
$value = HMCCU_Min ($value, HMCCU_ScaleValue ($clHash, $channel, $cmd->{dpt}, $cmd->{max}, 0))
|
||||
if (defined($cmd->{max}) && $cmd->{max} ne '');
|
||||
$value = HMCCU_Max ($value, HMCCU_ScaleValue ($clHash, $channel, $cmd->{dpt}, $cmd->{min}, 0))
|
||||
if (defined($cmd->{min}) && $cmd->{min} ne '');
|
||||
# Align new value with min/max boundaries
|
||||
if (exists($cmd->{min}) && exists($cmd->{max})) {
|
||||
$value = HMCCU_MinMax ($value,
|
||||
HMCCU_ScaleValue ($clHash, $channel, $cmd->{dpt}, $cmd->{min}, 0),
|
||||
HMCCU_ScaleValue ($clHash, $channel, $cmd->{dpt}, $cmd->{max}, 0)
|
||||
);
|
||||
}
|
||||
|
||||
if ($cmd->{ps} eq 'VALUES') {
|
||||
my $dno = sprintf ("%03d", $c);
|
||||
@ -6847,18 +6864,36 @@ sub HMCCU_ExecuteSetClearCommand ($@)
|
||||
return HMCCU_SetState ($clHash, "OK");
|
||||
}
|
||||
|
||||
######################################################################
|
||||
# Execute set control command
|
||||
######################################################################
|
||||
|
||||
sub HMCCU_ExecuteSetControlCommand ($@)
|
||||
{
|
||||
my ($clHash, $a, $h) = @_;
|
||||
|
||||
my $value = shift @$a // return HMCCU_SetError ($clHash, "Usage: set $clHash->{NAME} control {value}");
|
||||
my ($sc, $sd, $cc, $cd) = HMCCU_GetSCDatapoints ($clHash);
|
||||
my $stateVals = HMCCU_GetStateValues ($clHash, $cd, $cc);
|
||||
my $rc = HMCCU_SetMultipleDatapoints ($clHash,
|
||||
{ "001.$clHash->{ccuif}.$clHash->{ccuaddr}:$cc.$cd" => HMCCU_Substitute ($value, $stateVals, 1, undef, '') }
|
||||
);
|
||||
return HMCCU_SetError ($clHash, HMCCU_Min(0, $rc));
|
||||
}
|
||||
|
||||
######################################################################
|
||||
# Execute set datapoint command
|
||||
######################################################################
|
||||
|
||||
sub HMCCU_ExecuteSetDatapointCommand ($@)
|
||||
{
|
||||
my ($clHash, $a, $h, $cc, $cd) = @_;
|
||||
my ($clHash, $a, $h) = @_;
|
||||
|
||||
my $usage = "Usage: set $clHash->{NAME} datapoint [{channel-number}.]{datapoint} {value} [...]";
|
||||
my %dpval;
|
||||
my $i = 0;
|
||||
my ($devAddr, $chnNo) = HMCCU_SplitChnAddr ($clHash->{ccuaddr});
|
||||
my ($sc, $sd, $cc, $cd) = HMCCU_GetSCDatapoints ($clHash);
|
||||
my $stVals = HMCCU_GetStateValues ($clHash, $cd, $cc);
|
||||
|
||||
push (@$a, %${h}) if (defined($h));
|
||||
@ -6994,9 +7029,10 @@ sub HMCCU_ExecuteSetParameterCommand ($@)
|
||||
|
||||
sub HMCCU_ExecuteToggleCommand ($@)
|
||||
{
|
||||
my ($clHash, $cc, $cd) = @_;
|
||||
my ($clHash) = @_;
|
||||
|
||||
# Get state values related to control channel and datapoint
|
||||
my ($sc, $sd, $cc, $cd) = HMCCU_GetSCDatapoints ($clHash);
|
||||
my $stateVals = HMCCU_GetStateValues ($clHash, $cd, $cc);
|
||||
my %stateCmds = split (/[:,]/, $stateVals);
|
||||
my @states = keys %stateCmds;
|
||||
@ -7034,16 +7070,17 @@ sub HMCCU_ExecuteToggleCommand ($@)
|
||||
|
||||
sub HMCCU_ExecuteGetDeviceInfoCommand ($@)
|
||||
{
|
||||
my ($ioHash, $clHash, $address, $sc, $sd, $cc, $cd) = @_;
|
||||
$sc = '?' if (!defined($sc) || $sc eq '');
|
||||
$sd = '?' if (!defined($sd) || $sd eq '');
|
||||
$cc = '?' if (!defined($cc) || $cc eq '');
|
||||
$cd = '?' if (!defined($cd) || $cd eq '');
|
||||
my ($ioHash, $clHash, $address, $extended) = @_;
|
||||
$extended //= 0;
|
||||
|
||||
|
||||
my $iface = HMCCU_GetDeviceInterface ($ioHash, $address);
|
||||
my $result = HMCCU_GetDeviceInfo ($clHash, $address);
|
||||
return HMCCU_SetError ($clHash, -2) if ($result eq '');
|
||||
my $devInfo = '<html><b>Device channels and datapoints</b><br/><br/>';
|
||||
|
||||
my ($sc, $sd, $cc, $cd) = HMCCU_GetSCDatapoints ($clHash);
|
||||
my $devInfo = '<html><b>Device channels and datapoints</b><br/><br/><pre>';
|
||||
$devInfo .= '</pre>';
|
||||
$devInfo .= HMCCU_FormatDeviceInfo ($result);
|
||||
my $detect = HMCCU_DetectDevice ($ioHash, $address, $iface);
|
||||
if (defined($detect)) {
|
||||
@ -7069,17 +7106,24 @@ sub HMCCU_ExecuteGetDeviceInfoCommand ($@)
|
||||
$devInfo .= $detect->{defMod} ne '' ?
|
||||
"<br/>Recommended module for device definition: $detect->{defMod}<br/>" :
|
||||
"<br/>Failed to detect device settings. Device must be configured manually.<br/>";
|
||||
if ($extended) {
|
||||
$devInfo .= "<br/>Detection level: $detect->{level}<br/>".
|
||||
"<br/>Detected default state datapoint: $detect->{defSCh}.$detect->{defSDP}<br/>".
|
||||
"<br/>Detected default control datapoint: $detect->{defCCh}.$detect->{defCDP}<br/>".
|
||||
"<br/>Unique state roles: $detect->{uniqueStateRoleCount}<br/>".
|
||||
"<br/>Unique state roles: $detect->{uniqueControlRoleCount}<br/>";
|
||||
}
|
||||
}
|
||||
$devInfo .= "<br/>Current state datapoint = $sc.$sd<br/>" if ($sc ne '?');
|
||||
$devInfo .= "<br/>Current control datapoint = $cc.$cd<br/>" if ($cc ne '?');
|
||||
$devInfo .= '<br/><b>Device description</b><br/><br/>';
|
||||
$devInfo .= "<br/>Current state datapoint = $sc.$sd<br/>";
|
||||
$devInfo .= "<br/>Current control datapoint = $cc.$cd<br/>";
|
||||
$devInfo .= '<br/><b>Device description</b><br/><br/><pre>';
|
||||
$result = HMCCU_DeviceDescToStr ($ioHash, $clHash->{TYPE} eq 'HMCCU' ? $address : $clHash);
|
||||
$devInfo .= '</pre>';
|
||||
$devInfo .= defined($result) ? $result : "Can't get device description<br/>";
|
||||
if ($clHash->{TYPE} ne 'HMCCU') {
|
||||
$devInfo .= '<br/>Defaults<br/><br/>';
|
||||
$devInfo .= HMCCU_GetDefaults ($clHash);
|
||||
}
|
||||
$devInfo .= '</html>';
|
||||
|
||||
return $devInfo;
|
||||
}
|
||||
@ -7671,6 +7715,7 @@ sub HMCCU_DetectDevice ($$$)
|
||||
# Build device information to be returned
|
||||
my %di = (
|
||||
stateRoleCount => $stateRoleCnt, controlRoleCount => $ctrlRoleCnt,
|
||||
uniqueStateRoleCount => $cntUniqStateRoles, uniqueControlRoleCount => $cntUniqCtrlRoles,
|
||||
defSCh => -1, defCCh => -1, defSDP => '', defCDP => '',
|
||||
level => 0
|
||||
);
|
||||
@ -8311,12 +8356,31 @@ sub HMCCU_SetMultipleDatapoints ($$) {
|
||||
# an error original value is returned.
|
||||
######################################################################
|
||||
|
||||
sub HMCCU_ScaleValue ($$$$$)
|
||||
sub HMCCU_ScaleValue ($$$$$;$)
|
||||
{
|
||||
my ($hash, $chnno, $dpt, $value, $mode) = @_;
|
||||
my ($hash, $chnno, $dpt, $value, $mode, $paramSet) = @_;
|
||||
$chnno //= '';
|
||||
$paramSet //= 'VALUES';
|
||||
my $name = $hash->{NAME};
|
||||
my $ioHash = HMCCU_GetHash ($hash);
|
||||
|
||||
# Get parameter definition and min/max values
|
||||
my $min;
|
||||
my $max;
|
||||
my $unit;
|
||||
my $ccuaddr = $hash->{ccuaddr};
|
||||
$ccuaddr .= ':'.$chnno if ($hash->{TYPE} eq 'HMCCUDEV' && $chnno ne '');
|
||||
my $paramDef = HMCCU_GetParamDef ($ioHash, $ccuaddr, 'VALUES', $dpt);
|
||||
if (defined($paramDef)) {
|
||||
$min = $paramDef->{MIN} if (defined($paramDef->{MIN}) && $paramDef->{MIN} ne '');
|
||||
$max = $paramDef->{MAX} if (defined($paramDef->{MAX}) && $paramDef->{MAX} ne '');
|
||||
$unit = $paramDef->{UNIT};
|
||||
}
|
||||
else {
|
||||
HMCCU_Trace ($hash, 2, "Can't get parameter definion for addr=$hash->{ccuaddr} chn=$chnno");
|
||||
}
|
||||
|
||||
# Default values can be overriden by attribute
|
||||
my $ccuscaleval = AttrVal ($name, 'ccuscaleval', '');
|
||||
|
||||
HMCCU_Trace ($hash, 2, "chnno=$chnno, dpt=$dpt, value=$value, mode=$mode");
|
||||
@ -8347,14 +8411,12 @@ sub HMCCU_ScaleValue ($$$$$)
|
||||
|
||||
if ($n == 2) {
|
||||
$f = ($a[1] == 0.0) ? 1.0 : $a[1];
|
||||
return ($mode == 0) ? $value/$f : $value*$f;
|
||||
$value = ($mode == 0) ? $value/$f : $value*$f;
|
||||
}
|
||||
else {
|
||||
# Do not scale if value out of range or interval wrong
|
||||
return $value if ($a[1] > $a[2] || $a[3] > $a[4]);
|
||||
return $value if ($mode == 0 && ($value < $a[1] || $value > $a[2]));
|
||||
return $value if ($mode == 1 && ($value < $a[3] || $value > $a[4]));
|
||||
|
||||
elsif ($a[1] <= $a[2] && $a[3] <= $a[4] && (
|
||||
($mode == 0 && $value >= $a[1] && $value <= $a[2]) ||
|
||||
($mode == 1 && $value >= $a[3] && $value <= $a[4])
|
||||
)) {
|
||||
# Reverse value
|
||||
if ($rev) {
|
||||
my $dr = ($mode == 0) ? $a[1]+$a[2] : $a[3]+$a[4];
|
||||
@ -8363,46 +8425,54 @@ sub HMCCU_ScaleValue ($$$$$)
|
||||
|
||||
my $d1 = $a[2]-$a[1];
|
||||
my $d2 = $a[4]-$a[3];
|
||||
return $value if ($d1 == 0.0 || $d2 == 0.0);
|
||||
$f = $d1/$d2;
|
||||
return ($mode == 0) ? $value/$f+$a[3] : ($value-$a[3])*$f;
|
||||
if ($d1 != 0.0 && $d2 != 0.0) {
|
||||
$f = $d1/$d2;
|
||||
$value = ($mode == 0) ? $value/$f+$a[3] : ($value-$a[3])*$f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Align value with min/max boundaries for set mode
|
||||
if ($mode == 1 && defined($min) && defined($max)) {
|
||||
$value = HMCCU_MinMax ($value, $min, $max);
|
||||
}
|
||||
|
||||
HMCCU_Trace ($hash, 2, "Attribute scaled value of $dpt = $value");
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
if ($dpt eq 'LEVEL') {
|
||||
my $rv = ($mode == 0) ? HMCCU_Min($value,1.0)*100.0 : HMCCU_Min($value,100.0)/100.0;
|
||||
HMCCU_Trace ($hash, 2, "LEVEL: $rv");
|
||||
return $rv;
|
||||
# return ($mode == 0) ? HMCCU_Min($value,1.0)*100.0 : HMCCU_Min($value,100.0)/100.0;
|
||||
}
|
||||
elsif ($dpt =~ /^RSSI_/) {
|
||||
return abs ($value) == 65535 || $value == 1 ? 'N/A' : ($value > 0 ? $value-256 : $value);
|
||||
# if ($dpt eq 'LEVEL') {
|
||||
# my $rv = ($mode == 0) ? HMCCU_Min($value,1.0)*100.0 : HMCCU_Min($value,100.0)/100.0;
|
||||
# HMCCU_Trace ($hash, 2, "LEVEL: $rv");
|
||||
# return $rv;
|
||||
## return ($mode == 0) ? HMCCU_Min($value,1.0)*100.0 : HMCCU_Min($value,100.0)/100.0;
|
||||
# }
|
||||
if ($dpt =~ /^RSSI_/) {
|
||||
# Subtract 256 from Rega value (Rega bug)
|
||||
$value = abs ($value) == 65535 || $value == 0 ? 'N/A' : ($value > 0 ? $value-256 : $value);
|
||||
}
|
||||
elsif ($dpt =~ /^(P[0-9]_)?ENDTIME/) {
|
||||
if ($mode == 0) {
|
||||
my $hh = sprintf ("%02d", int($value/60));
|
||||
my $mm = sprintf ("%02d", $value%60);
|
||||
return "$hh:$mm";
|
||||
$value = "$hh:$mm";
|
||||
}
|
||||
else {
|
||||
my ($hh, $mm) = split (':', $value);
|
||||
$mm = 0 if (!defined($mm));
|
||||
return $hh*60+$mm;
|
||||
$mm //= 0;
|
||||
$value = $hh*60+$mm;
|
||||
}
|
||||
}
|
||||
# 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;
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
elsif (defined($unit) && $unit =~ /^([0-9]+)%$/) {
|
||||
my $f = $1;
|
||||
$min //= 0;
|
||||
$max //= 1.0;
|
||||
$value = ($mode == 0) ? HMCCU_MinMax ($value, $min, $max)*$f :
|
||||
HMCCU_MinMax($value, $min*$f, $max*$f)/$f;
|
||||
}
|
||||
|
||||
HMCCU_Trace ($hash, 2, "Auto scaled value of $dpt = $value");
|
||||
|
||||
return $value;
|
||||
}
|
||||
@ -8951,7 +9021,8 @@ sub HMCCU_GetTimeSpec ($)
|
||||
}
|
||||
|
||||
######################################################################
|
||||
# Get minimum of 2 values
|
||||
# Get minimum or maximum of 2 values
|
||||
# Align value with boundaries
|
||||
######################################################################
|
||||
|
||||
sub HMCCU_Min ($$)
|
||||
@ -8961,10 +9032,6 @@ sub HMCCU_Min ($$)
|
||||
return $a < $b ? $a : $b;
|
||||
}
|
||||
|
||||
######################################################################
|
||||
# Get maximum of 2 values
|
||||
######################################################################
|
||||
|
||||
sub HMCCU_Max ($$)
|
||||
{
|
||||
my ($a, $b) = @_;
|
||||
@ -8972,6 +9039,15 @@ sub HMCCU_Max ($$)
|
||||
return $a > $b ? $a : $b;
|
||||
}
|
||||
|
||||
sub HMCCU_MinMax ($$$)
|
||||
{
|
||||
my ($v, $min, $max) = @_;
|
||||
$min = $v if (!defined($min) || $min eq '');
|
||||
$max = $min if (!defined($max) || $max eq '');
|
||||
|
||||
return HMCCU_Max (HMCCU_Min ($v, $max), $min);
|
||||
}
|
||||
|
||||
######################################################################
|
||||
# Build ReGa or RPC client URL
|
||||
# Parameter backend specifies type of URL, 'rega' or name or port of
|
||||
@ -9482,8 +9558,8 @@ sub HMCCU_TCPPing ($$$)
|
||||
my $t = time ();
|
||||
|
||||
while (time() < $t+$timeout) {
|
||||
return 1 if (HMCCU_TCPConnect ($addr, $port) ne '');
|
||||
sleep (20);
|
||||
return 1 if (HMCCU_TCPConnect ($addr, $port, 1) ne '');
|
||||
sleep ($HMCCU_CCU_PING_SLEEP);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -9498,11 +9574,11 @@ sub HMCCU_TCPPing ($$$)
|
||||
# Return empty string on error or local IP address on success.
|
||||
######################################################################
|
||||
|
||||
sub HMCCU_TCPConnect ($$)
|
||||
sub HMCCU_TCPConnect ($$;$)
|
||||
{
|
||||
my ($addr, $port) = @_;
|
||||
my ($addr, $port, $timeout) = @_;
|
||||
|
||||
my $socket = IO::Socket::INET->new (PeerAddr => $addr, PeerPort => $port);
|
||||
my $socket = IO::Socket::INET->new (PeerAddr => $addr, PeerPort => $port, Timeout => $timeout);
|
||||
if ($socket) {
|
||||
my $ipaddr = $socket->sockhost ();
|
||||
close ($socket);
|
||||
@ -9750,7 +9826,7 @@ sub HMCCU_MaxHashEntries ($$)
|
||||
<li><b>get <name> defaults</b><br/>
|
||||
List device types and channels with default attributes available.
|
||||
</li><br/>
|
||||
<li><b>get <name> deviceinfo <device-name-or-address></b><br/>
|
||||
<li><b>get <name> deviceinfo <device-name-or-address> [extended]</b><br/>
|
||||
List device channels, datapoints and the device description.
|
||||
</li><br/>
|
||||
<li><b>get <name> dutycycle</b><br/>
|
||||
|
@ -4,7 +4,7 @@
|
||||
#
|
||||
# $Id: 88_HMCCUCHN.pm 18552 2019-02-10 11:52:28Z zap $
|
||||
#
|
||||
# Version 4.4.038
|
||||
# Version 4.4.039
|
||||
#
|
||||
# (c) 2021 zap (zap01 <at> t-online <dot> de)
|
||||
#
|
||||
@ -281,42 +281,39 @@ sub HMCCUCHN_Set ($@)
|
||||
return ($opt eq '?' ? undef : 'Cannot perform set commands. CCU busy')
|
||||
if (HMCCU_IsRPCStateBlocking ($ioHash));
|
||||
|
||||
# Get state and control datapoints
|
||||
my ($sc, $sd, $cc, $cd) = HMCCU_GetSCDatapoints ($hash);
|
||||
# Build set command syntax
|
||||
my $syntax = 'clear defaults:reset,update';
|
||||
|
||||
# Additional commands, including state commands
|
||||
my $cmdList = $hash->{hmccu}{cmdlist}{set} // '';
|
||||
# Command readingFilter depends on readable datapoints
|
||||
my ($add, $chn) = split(":", $hash->{ccuaddr});
|
||||
my @dpRList = ();
|
||||
my $dpRCount = HMCCU_GetValidDatapoints ($hash, $hash->{ccutype}, $chn, 5, \@dpRList);
|
||||
$syntax .= ' readingFilter:multiple-strict,'.join(',', @dpRList) if ($dpRCount > 0);
|
||||
|
||||
# Some commands require a control datapoint
|
||||
if ($opt =~ /^(control|toggle)$/) {
|
||||
return HMCCU_SetError ($hash, -14) if ($cd eq '');
|
||||
return HMCCU_SetError ($hash, -8, $cd)
|
||||
if (!HMCCU_IsValidDatapoint ($hash, $hash->{ccutype}, $hash->{ccuaddr}, $cd, 2));
|
||||
# Commands only available in read/write mode
|
||||
if ($hash->{readonly} ne 'yes') {
|
||||
$syntax .= ' config';
|
||||
my $dpWCount = HMCCU_GetValidDatapoints ($hash, $hash->{ccutype}, $chn, 2);
|
||||
$syntax .= ' datapoint' if ($dpWCount > 0);
|
||||
my $addCmds = $hash->{hmccu}{cmdlist}{set} // '';
|
||||
$syntax .= " $addCmds" if ($addCmds ne '');
|
||||
}
|
||||
|
||||
my $result = '';
|
||||
my $rc;
|
||||
|
||||
# Log commands
|
||||
HMCCU_Log ($hash, 3, "set $name $opt ".join (' ', @$a))
|
||||
if ($opt ne '?' && (HMCCU_IsFlag ($name, 'logCommand') || HMCCU_IsFlag ($ioName, 'logCommand')));
|
||||
|
||||
if ($lcopt eq 'control') {
|
||||
my $value = shift @$a // return HMCCU_SetError ($hash, "Usage: set $name control {value}");
|
||||
my $stateVals = HMCCU_GetStateValues ($hash, $cd, $cc);
|
||||
$rc = HMCCU_SetMultipleDatapoints ($hash,
|
||||
{ "001.$hash->{ccuif}.$hash->{ccuaddr}.$cd" => HMCCU_Substitute ($value, $stateVals, 1, undef, '') }
|
||||
);
|
||||
return HMCCU_SetError ($hash, HMCCU_Min(0, $rc));
|
||||
return HMCCU_ExecuteSetControlCommand ($hash, $a, $h);
|
||||
}
|
||||
elsif ($lcopt eq 'datapoint') {
|
||||
return HMCCU_ExecuteSetDatapointCommand ($hash, $a, $h, $cc, $cd);
|
||||
return HMCCU_ExecuteSetDatapointCommand ($hash, $a, $h);
|
||||
}
|
||||
elsif ($lcopt eq 'toggle') {
|
||||
return HMCCU_ExecuteToggleCommand ($hash, $cc, $cd);
|
||||
return HMCCU_ExecuteToggleCommand ($hash);
|
||||
}
|
||||
elsif (exists($hash->{hmccu}{roleCmds}{set}{$opt})) {
|
||||
return HMCCU_ExecuteRoleCommand ($ioHash, $hash, 'set', $opt, $cc, $a, $h);
|
||||
return HMCCU_ExecuteRoleCommand ($ioHash, $hash, 'set', $opt, $a, $h);
|
||||
}
|
||||
elsif ($opt eq 'clear') {
|
||||
return HMCCU_ExecuteSetClearCommand ($hash, $a);
|
||||
@ -332,27 +329,13 @@ sub HMCCUCHN_Set ($@)
|
||||
}
|
||||
elsif ($lcopt eq 'defaults') {
|
||||
my $mode = shift @$a // 'update';
|
||||
$rc = HMCCU_SetDefaultAttributes ($hash, { mode => $mode, role => undef, roleChn => $cc });
|
||||
my $rc = HMCCU_SetDefaultAttributes ($hash, { mode => $mode, role => undef, roleChn => undef });
|
||||
$rc = HMCCU_SetDefaults ($hash) if (!$rc);
|
||||
HMCCU_RefreshReadings ($hash) if ($rc);
|
||||
return HMCCU_SetError ($hash, $rc == 0 ? "No default attributes found" : "OK");
|
||||
}
|
||||
else {
|
||||
my $retmsg = "clear defaults:reset,update";
|
||||
|
||||
my ($a, $c) = split(":", $hash->{ccuaddr});
|
||||
my @dpRList = ();
|
||||
my $dpRCount = HMCCU_GetValidDatapoints ($hash, $hash->{ccutype}, $c, 5, \@dpRList);
|
||||
$retmsg .= ' readingFilter:multiple-strict,'.join(',', @dpRList) if ($dpRCount > 0);
|
||||
|
||||
if ($hash->{readonly} ne 'yes') {
|
||||
$retmsg .= ' config';
|
||||
my $dpWCount = HMCCU_GetValidDatapoints ($hash, $hash->{ccutype}, $c, 2);
|
||||
$retmsg .= ' datapoint' if ($dpWCount > 0);
|
||||
$retmsg .= " $cmdList" if ($cmdList ne '');
|
||||
}
|
||||
# return AttrTemplate_Set ($hash, $retmsg, $name, $opt, @$a);
|
||||
return $retmsg;
|
||||
return "Unknown argument $opt choose one of $syntax";
|
||||
}
|
||||
}
|
||||
|
||||
@ -368,10 +351,7 @@ sub HMCCUCHN_Get ($@)
|
||||
my $lcopt = lc($opt);
|
||||
|
||||
return undef if (!defined ($hash->{ccudevstate}) || $hash->{ccudevstate} eq 'pending' ||
|
||||
!defined ($hash->{IODev}));
|
||||
|
||||
my $disable = AttrVal ($name, "disable", 0);
|
||||
return undef if ($disable == 1);
|
||||
!defined ($hash->{IODev}) || AttrVal ($name, "disable", 0) == 1);
|
||||
|
||||
my $ioHash = $hash->{IODev};
|
||||
my $ioName = $ioHash->{NAME};
|
||||
@ -383,13 +363,19 @@ sub HMCCUCHN_Get ($@)
|
||||
my $ccuaddr = $hash->{ccuaddr};
|
||||
my $ccuif = $hash->{ccuif};
|
||||
my $ccuflags = AttrVal ($name, 'ccuflags', 'null');
|
||||
my ($sc, $sd, $cc, $cd) = HMCCU_GetSCDatapoints ($hash);
|
||||
|
||||
# Additional commands, including state commands
|
||||
my $cmdList = $hash->{hmccu}{cmdlist}{get} // '';
|
||||
# Build set command syntax
|
||||
my $syntax = 'update:noArg config:noArg paramsetDesc:noArg deviceInfo:noArg values:noArg';
|
||||
|
||||
my $result = '';
|
||||
my $rc;
|
||||
# Command datapoint depends on readable datapoints
|
||||
my ($add, $chn) = split(":", $hash->{ccuaddr});
|
||||
my @dpRList;
|
||||
my $dpRCount = HMCCU_GetValidDatapoints ($hash, $ccutype, $chn, 1, \@dpRList);
|
||||
$syntax .= ' datapoint:'.join(",", @dpRList) if ($dpRCount > 0);
|
||||
|
||||
# Additional device specific commands
|
||||
my $addCmds = $hash->{hmccu}{cmdlist}{get} // '';
|
||||
$syntax .= " $addCmds" if ($addCmds ne '');
|
||||
|
||||
# Log commands
|
||||
HMCCU_Log ($hash, 3, "get $name $opt ".join (' ', @$a))
|
||||
@ -401,37 +387,30 @@ sub HMCCUCHN_Get ($@)
|
||||
if (!HMCCU_IsValidDatapoint ($hash, $ccutype, $ccuaddr, $objname, 1));
|
||||
|
||||
$objname = $ccuif.'.'.$ccuaddr.'.'.$objname;
|
||||
($rc, $result) = HMCCU_GetDatapoint ($hash, $objname, 0);
|
||||
my ($rc, $result) = HMCCU_GetDatapoint ($hash, $objname, 0);
|
||||
return $rc < 0 ? HMCCU_SetError ($hash, $rc, $result) : $result;
|
||||
}
|
||||
elsif ($lcopt eq 'deviceinfo') {
|
||||
my $extended = shift @$a;
|
||||
my ($devAddr, undef) = HMCCU_SplitChnAddr ($ccuaddr);
|
||||
return HMCCU_ExecuteGetDeviceInfoCommand ($ioHash, $hash, $devAddr, $sc, $sd, $cc, $cd);
|
||||
return HMCCU_ExecuteGetDeviceInfoCommand ($ioHash, $hash, $devAddr, defined($extended) ? 1 : 0);
|
||||
}
|
||||
elsif ($lcopt =~ /^(config|values|update)$/) {
|
||||
my ($devAddr, undef) = HMCCU_SplitChnAddr ($ccuaddr);
|
||||
my @addList = ($devAddr, "$devAddr:0", $ccuaddr);
|
||||
my $resp = HMCCU_ExecuteGetParameterCommand ($ioHash, $hash, $lcopt, \@addList);
|
||||
return HMCCU_SetError ($hash, "Can't get device description") if (!defined($resp));
|
||||
return HMCCU_DisplayGetParameterResult ($ioHash, $hash, $resp);
|
||||
my $result = HMCCU_ExecuteGetParameterCommand ($ioHash, $hash, $lcopt, \@addList);
|
||||
return HMCCU_SetError ($hash, "Can't get device description") if (!defined($result));
|
||||
return HMCCU_DisplayGetParameterResult ($ioHash, $hash, $result);
|
||||
}
|
||||
elsif ($lcopt eq 'paramsetdesc') {
|
||||
$result = HMCCU_ParamsetDescToStr ($ioHash, $hash);
|
||||
my $result = HMCCU_ParamsetDescToStr ($ioHash, $hash);
|
||||
return defined($result) ? $result : HMCCU_SetError ($hash, "Can't get device model");
|
||||
}
|
||||
elsif (exists($hash->{hmccu}{roleCmds}{get}{$opt})) {
|
||||
return HMCCU_ExecuteRoleCommand ($ioHash, $hash, 'get', $opt, $cc, $a, $h);
|
||||
return HMCCU_ExecuteRoleCommand ($ioHash, $hash, 'get', $opt, $a, $h);
|
||||
}
|
||||
else {
|
||||
my $retmsg = "HMCCUCHN: Unknown argument $opt, choose one of";
|
||||
$retmsg .= ' update:noArg deviceInfo:noArg config:noArg paramsetDesc:noArg values:noArg';
|
||||
my ($a, $c) = split(":", $hash->{ccuaddr});
|
||||
my @dpList;
|
||||
my $dpCount = HMCCU_GetValidDatapoints ($hash, $hash->{ccutype}, $c, 1, \@dpList);
|
||||
$retmsg .= ' datapoint:'.join(",",@dpList) if ($dpCount > 0);
|
||||
$retmsg .= " $cmdList" if ($cmdList ne '');
|
||||
|
||||
return $retmsg;
|
||||
return "Unknown argument $opt choose one of $syntax";
|
||||
}
|
||||
}
|
||||
|
||||
@ -450,7 +429,7 @@ sub HMCCUCHN_Get ($@)
|
||||
exist before a client device can be defined. If a CCU channel is not found, execute command
|
||||
'get ccuConfig' in I/O device. This will synchronize devices and channels between CCU
|
||||
and HMCCU.
|
||||
</br></br>
|
||||
<br/><br/>
|
||||
<a name="HMCCUCHNdefine"></a>
|
||||
<b>Define</b><br/><br/>
|
||||
<ul>
|
||||
@ -569,9 +548,9 @@ sub HMCCUCHN_Get ($@)
|
||||
Toggle state datapoint between values defined by attribute 'statevals'. This command is
|
||||
only available if state values can be detected or are defined by using attribute
|
||||
'statevals'. Toggling supports more than two state values.<br/><br/>
|
||||
Example: Toggle blind actor<br/>
|
||||
Example: Toggle blind actor between states 'open', 'half' and 'close'<br/>
|
||||
<code>
|
||||
attr myswitch statevals up:100,down:0<br/>
|
||||
attr myswitch statevals open:100,half:50,close:0<br/>
|
||||
set myswitch toggle
|
||||
</code>
|
||||
</li><br/>
|
||||
@ -617,7 +596,7 @@ sub HMCCUCHN_Get ($@)
|
||||
This command has been removed in version 4.4. The default attributes are included in the
|
||||
output of command 'get deviceInfo'.
|
||||
</li><br/>
|
||||
<li><b>get <name> deviceInfo</b><br/>
|
||||
<li><b>get <name> deviceInfo ['extended']</b><br/>
|
||||
Display information about device type and channels:<br/>
|
||||
<ul>
|
||||
<li>all channels and datapoints of device with datapoint values and types</li>
|
||||
|
@ -4,7 +4,7 @@
|
||||
#
|
||||
# $Id: 88_HMCCUDEV.pm 18552 2019-02-10 11:52:28Z zap $
|
||||
#
|
||||
# Version 4.4.046
|
||||
# Version 4.4.047
|
||||
#
|
||||
# (c) 2021 zap (zap01 <at> t-online <dot> de)
|
||||
#
|
||||
@ -376,44 +376,38 @@ sub HMCCUDEV_Set ($@)
|
||||
return ($opt eq '?' ? undef : 'Cannot perform set commands. CCU busy')
|
||||
if (HMCCU_IsRPCStateBlocking ($ioHash));
|
||||
|
||||
# Get state and control datapoints
|
||||
my ($sc, $sd, $cc, $cd) = HMCCU_GetSCDatapoints ($hash);
|
||||
# Build set command syntax
|
||||
my $syntax = 'clear defaults:reset,update';
|
||||
|
||||
# Get additional commands
|
||||
my $cmdList = $hash->{hmccu}{cmdlist}{set} // '';
|
||||
# Command readingFilter depends on readable datapoints
|
||||
my @dpRList = ();
|
||||
my $dpRCount = HMCCU_GetValidDatapoints ($hash, $hash->{ccutype}, -1, 5, \@dpRList);
|
||||
$syntax .= ' readingFilter:multiple-strict,'.join(',', @dpRList) if ($dpRCount > 0);
|
||||
|
||||
# Some commands require a control channel and datapoint
|
||||
if ($lcopt =~ /^(control|toggle)$/) {
|
||||
return HMCCU_SetError ($hash, -14) if ($cd eq '');
|
||||
return HMCCU_SetError ($hash, -12) if ($cc eq '');
|
||||
return HMCCU_SetError ($hash, -8, $cd)
|
||||
if (!HMCCU_IsValidDatapoint ($hash, $hash->{ccutype}, $cc, $cd, 2));
|
||||
return HMCCU_SetError ($hash, -7) if ($cc >= $hash->{hmccu}{channels});
|
||||
# Commands only available in read/write mode
|
||||
if ($hash->{readonly} ne 'yes') {
|
||||
$syntax .= ' config';
|
||||
my $dpWCount = HMCCU_GetValidDatapoints ($hash, $hash->{ccutype}, -1, 2);
|
||||
$syntax .= ' datapoint' if ($dpWCount > 0);
|
||||
my $addCmds = $hash->{hmccu}{cmdlist}{set} // '';
|
||||
$syntax .= " $addCmds" if ($addCmds ne '');
|
||||
}
|
||||
|
||||
my $result = '';
|
||||
my $rc;
|
||||
|
||||
# Log commands
|
||||
HMCCU_Log ($hash, 3, "set $name $opt ".join (' ', @$a))
|
||||
if ($opt ne '?' && (HMCCU_IsFlag ($name, 'logCommand') || HMCCU_IsFlag ($ioName, 'logCommand')));
|
||||
|
||||
if ($lcopt eq 'control') {
|
||||
my $value = shift @$a // return HMCCU_SetError ($hash, "Usage: set $name control {value}");
|
||||
my $stateVals = HMCCU_GetStateValues ($hash, $cd, $cc);
|
||||
$rc = HMCCU_SetMultipleDatapoints ($hash,
|
||||
{ "001.$hash->{ccuif}.$hash->{ccuaddr}:$cc.$cd" => HMCCU_Substitute ($value, $stateVals, 1, undef, '') }
|
||||
);
|
||||
return HMCCU_SetError ($hash, HMCCU_Min(0, $rc));
|
||||
return HMCCU_ExecuteSetControlCommand ($hash, $a, $h);
|
||||
}
|
||||
elsif ($lcopt eq 'datapoint') {
|
||||
return HMCCU_ExecuteSetDatapointCommand ($hash, $a, $h, $cc, $cd);
|
||||
return HMCCU_ExecuteSetDatapointCommand ($hash, $a, $h);
|
||||
}
|
||||
elsif ($lcopt eq 'toggle') {
|
||||
return HMCCU_ExecuteToggleCommand ($hash, $cc, $cd);
|
||||
return HMCCU_ExecuteToggleCommand ($hash);
|
||||
}
|
||||
elsif (exists($hash->{hmccu}{roleCmds}{set}{$opt})) {
|
||||
return HMCCU_ExecuteRoleCommand ($ioHash, $hash, 'set', $opt, $cc, $a, $h);
|
||||
return HMCCU_ExecuteRoleCommand ($ioHash, $hash, 'set', $opt, $a, $h);
|
||||
}
|
||||
elsif ($lcopt eq 'clear') {
|
||||
return HMCCU_ExecuteSetClearCommand ($hash, $a);
|
||||
@ -428,26 +422,13 @@ sub HMCCUDEV_Set ($@)
|
||||
}
|
||||
elsif ($lcopt eq 'defaults') {
|
||||
my $mode = shift @$a // 'update';
|
||||
$rc = HMCCU_SetDefaultAttributes ($hash, { mode => $mode, role => undef, roleChn => $cc });
|
||||
my $rc = HMCCU_SetDefaultAttributes ($hash, { mode => $mode, role => undef, roleChn => undef });
|
||||
$rc = HMCCU_SetDefaults ($hash) if (!$rc);
|
||||
HMCCU_RefreshReadings ($hash) if ($rc);
|
||||
return HMCCU_SetError ($hash, $rc == 0 ? 'No default attributes found' : 'OK');
|
||||
}
|
||||
else {
|
||||
my $retmsg = 'clear defaults:reset,update';
|
||||
|
||||
my @dpRList = ();
|
||||
my $dpRCount = HMCCU_GetValidDatapoints ($hash, $hash->{ccutype}, -1, 5, \@dpRList);
|
||||
$retmsg .= ' readingFilter:multiple-strict,'.join(',', @dpRList) if ($dpRCount > 0);
|
||||
|
||||
if ($hash->{readonly} ne 'yes') {
|
||||
$retmsg .= ' config';
|
||||
my $dpWCount = HMCCU_GetValidDatapoints ($hash, $hash->{ccutype}, -1, 2);
|
||||
$retmsg .= ' datapoint' if ($dpWCount > 0);
|
||||
$retmsg .= " $cmdList" if ($cmdList ne '');
|
||||
}
|
||||
# return AttrTemplate_Set ($hash, $retmsg, $name, $opt, @$a);
|
||||
return $retmsg;
|
||||
return "Unknown argument $opt choose one of $syntax";
|
||||
}
|
||||
}
|
||||
|
||||
@ -478,13 +459,18 @@ sub HMCCUDEV_Get ($@)
|
||||
my $ccuaddr = $hash->{ccuaddr};
|
||||
my $ccuif = $hash->{ccuif};
|
||||
my $ccuflags = AttrVal ($name, 'ccuflags', 'null');
|
||||
my ($sc, $sd, $cc, $cd) = HMCCU_GetSCDatapoints ($hash);
|
||||
|
||||
# Get additional commands
|
||||
my $cmdList = $hash->{hmccu}{cmdlist}{get} // '';
|
||||
# Build set command syntax
|
||||
my $syntax = 'update:noArg config:noArg paramsetDesc:noArg deviceInfo:noArg values:noArg';
|
||||
|
||||
my $result = '';
|
||||
my $rc;
|
||||
# Command datapoint depends on readable datapoints
|
||||
my @dpRList;
|
||||
my $dpRCount = HMCCU_GetValidDatapoints ($hash, $ccutype, -1, 1, \@dpRList);
|
||||
$syntax .= ' datapoint:'.join(",", @dpRList) if ($dpRCount > 0);
|
||||
|
||||
# Additional device specific commands
|
||||
my $addCmds = $hash->{hmccu}{cmdlist}{get} // '';
|
||||
$syntax .= " $addCmds" if ($addCmds ne '');
|
||||
|
||||
# Log commands
|
||||
HMCCU_Log ($hash, 3, "get $name $opt ".join (' ', @$a))
|
||||
@ -498,6 +484,7 @@ sub HMCCUDEV_Get ($@)
|
||||
return HMCCU_SetError ($hash, -7) if ($chn >= $hash->{hmccu}{channels});
|
||||
}
|
||||
else {
|
||||
my ($sc, $sd, $cc, $cd) = HMCCU_GetSCDatapoints ($hash);
|
||||
return HMCCU_SetError ($hash, -11) if ($sc eq '');
|
||||
$objname = $sc.'.'.$objname;
|
||||
}
|
||||
@ -506,14 +493,14 @@ sub HMCCUDEV_Get ($@)
|
||||
if (!HMCCU_IsValidDatapoint ($hash, $ccutype, undef, $objname, 1));
|
||||
|
||||
$objname = $ccuif.'.'.$ccuaddr.':'.$objname;
|
||||
($rc, $result) = HMCCU_GetDatapoint ($hash, $objname, 0);
|
||||
my ($rc, $result) = HMCCU_GetDatapoint ($hash, $objname, 0);
|
||||
|
||||
return HMCCU_SetError ($hash, $rc, $result) if ($rc < 0);
|
||||
HMCCU_SetState ($hash, "OK") if (exists ($hash->{STATE}) && $hash->{STATE} eq "Error");
|
||||
return $result;
|
||||
}
|
||||
elsif ($lcopt eq 'deviceinfo') {
|
||||
return HMCCU_ExecuteGetDeviceInfoCommand ($ioHash, $hash, $ccuaddr, $sc, $sd, $cc, $cd);
|
||||
my $extended = shift @$a;
|
||||
return HMCCU_ExecuteGetDeviceInfoCommand ($ioHash, $hash, $ccuaddr, defined($extended) ? 1 : 0);
|
||||
}
|
||||
elsif ($lcopt =~ /^(config|values|update)$/) {
|
||||
my @addList = ($ccuaddr);
|
||||
@ -522,26 +509,19 @@ sub HMCCUDEV_Get ($@)
|
||||
return HMCCU_SetError ($hash, "Can't get device description") if (!defined($devDesc));
|
||||
push @addList, split (',', $devDesc->{CHILDREN});
|
||||
|
||||
my $resp = HMCCU_ExecuteGetParameterCommand ($ioHash, $hash, $lcopt, \@addList);
|
||||
return HMCCU_SetError ($hash, "Can't get device description") if (!defined($resp));
|
||||
return HMCCU_DisplayGetParameterResult ($ioHash, $hash, $resp);
|
||||
my $result = HMCCU_ExecuteGetParameterCommand ($ioHash, $hash, $lcopt, \@addList);
|
||||
return HMCCU_SetError ($hash, "Can't get device description") if (!defined($result));
|
||||
return HMCCU_DisplayGetParameterResult ($ioHash, $hash, $result);
|
||||
}
|
||||
elsif ($lcopt eq 'paramsetdesc') {
|
||||
$result = HMCCU_ParamsetDescToStr ($ioHash, $hash);
|
||||
my $result = HMCCU_ParamsetDescToStr ($ioHash, $hash);
|
||||
return defined($result) ? $result : HMCCU_SetError ($hash, "Can't get device model");
|
||||
}
|
||||
elsif (exists($hash->{hmccu}{roleCmds}{get}{$opt})) {
|
||||
return HMCCU_ExecuteRoleCommand ($ioHash, $hash, 'get', $opt, $cc, $a, $h);
|
||||
return HMCCU_ExecuteRoleCommand ($ioHash, $hash, 'get', $opt, $a, $h);
|
||||
}
|
||||
else {
|
||||
my $retmsg = "HMCCUDEV: Unknown argument $opt, choose one of";
|
||||
$retmsg .= ' update:noArg config:noArg paramsetDesc:noArg deviceInfo:noArg values:noArg';
|
||||
my @dpList;
|
||||
my $dpCount = HMCCU_GetValidDatapoints ($hash, $ccutype, -1, 1, \@dpList);
|
||||
$retmsg .= ' datapoint:'.join(",", @dpList) if ($dpCount > 0);
|
||||
$retmsg .= " $cmdList" if ($cmdList ne '');
|
||||
|
||||
return $retmsg;
|
||||
return "Unknown argument $opt choose one of $syntax";
|
||||
}
|
||||
}
|
||||
|
||||
@ -723,7 +703,7 @@ sub HMCCUDEV_Get ($@)
|
||||
<li><b>get <name> defaults</b><br/>
|
||||
<a href="#HMCCUCHNget">see HMCCUCHN</a>
|
||||
</li><br/>
|
||||
<li><b>get <name> deviceinfo</b><br/>
|
||||
<li><b>get <name> deviceinfo ['extended']</b><br/>
|
||||
Display information about device and channels:<br/>
|
||||
<ul>
|
||||
<li>all channels and datapoints of device with datapoint values and types</li>
|
||||
|
@ -4,11 +4,11 @@
|
||||
#
|
||||
# $Id: 88_HMCCURPCPROC.pm 18745 2019-02-26 17:33:23Z zap $
|
||||
#
|
||||
# Version 4.4.013
|
||||
# Version 4.4.014
|
||||
#
|
||||
# Subprocess based RPC Server module for HMCCU.
|
||||
#
|
||||
# (c) 2020 by zap (zap01 <at> t-online <dot> de)
|
||||
# (c) 2021 by zap (zap01 <at> t-online <dot> de)
|
||||
#
|
||||
##############################################################################
|
||||
#
|
||||
@ -39,7 +39,7 @@ require "$attr{global}{modpath}/FHEM/88_HMCCU.pm";
|
||||
######################################################################
|
||||
|
||||
# HMCCURPC version
|
||||
my $HMCCURPCPROC_VERSION = '4.4.013';
|
||||
my $HMCCURPCPROC_VERSION = '4.4.014';
|
||||
|
||||
# Maximum number of events processed per call of Read()
|
||||
my $HMCCURPCPROC_MAX_EVENTS = 100;
|
||||
@ -266,14 +266,15 @@ sub HMCCURPCPROC_Define ($$)
|
||||
my $rpcip = '';
|
||||
my $iface;
|
||||
my $usage = 'Usage: define $name HMCCURPCPROC { CCUHost | iodev={device} } { RPCPort | RPCInterface }';
|
||||
my $errSource = "HMCCURPCPROC [$name]";
|
||||
|
||||
$hash->{version} = $HMCCURPCPROC_VERSION;
|
||||
|
||||
if (exists($h->{iodev})) {
|
||||
$ioname = $h->{iodev};
|
||||
return $usage if (scalar(@$a) < 3);
|
||||
return "HMCCU I/O device $ioname not found" if (!exists($defs{$ioname}));
|
||||
return "Device $ioname is not a HMCCU device" if ($defs{$ioname}->{TYPE} ne 'HMCCU');
|
||||
return "$errSource HMCCU I/O device $ioname not found" if (!exists($defs{$ioname}));
|
||||
return "$errSource Device $ioname is not a HMCCU device" if ($defs{$ioname}->{TYPE} ne 'HMCCU');
|
||||
$ioHash = $defs{$ioname};
|
||||
if (scalar(@$a) < 4) {
|
||||
$hash->{host} = $ioHash->{host};
|
||||
@ -310,8 +311,10 @@ sub HMCCURPCPROC_Define ($$)
|
||||
foreach my $d (keys %defs) {
|
||||
my $dh = $defs{$d};
|
||||
next if (!exists ($dh->{TYPE}) || !exists ($dh->{NAME}) || $dh->{TYPE} ne 'HMCCU');
|
||||
if ($dh->{ccuip} eq $rpcip) { $ioHash = $dh; last; }
|
||||
if ($dh->{ccuip} eq $rpcip) { $ioHash = $dh; last; }
|
||||
}
|
||||
|
||||
return $errSource."HMCCU I/O device not found" if (!defined($ioHash));
|
||||
}
|
||||
|
||||
# Store some definitions for delayed initialization
|
||||
@ -322,15 +325,15 @@ sub HMCCURPCPROC_Define ($$)
|
||||
# Interactive define command while CCU not ready or no IO device defined
|
||||
if (!defined($ioHash)) {
|
||||
my ($ccuactive, $ccuinactive) = HMCCU_IODeviceStates ();
|
||||
return $ccuinactive > 0 ?
|
||||
'CCU and/or IO device not ready. Please try again later' :
|
||||
'Cannot detect IO device';
|
||||
return $errSource.($ccuinactive > 0 ?
|
||||
' CCU and/or IO device not ready. Please try again later' :
|
||||
' Cannot detect IO device');
|
||||
}
|
||||
}
|
||||
else {
|
||||
# CCU not ready during FHEM start
|
||||
if (!defined ($ioHash) || $ioHash->{ccustate} ne 'active') {
|
||||
HMCCU_Log ($hash, 2, 'Cannot detect IO device, maybe CCU not ready. Trying later ...');
|
||||
if ($ioHash->{ccustate} ne 'active') {
|
||||
HMCCU_Log ($hash, 2, 'CCU not ready. Trying later ...');
|
||||
readingsSingleUpdate ($hash, 'state', 'Pending', 1);
|
||||
$hash->{ccudevstate} = 'pending';
|
||||
return undef;
|
||||
@ -339,11 +342,11 @@ sub HMCCURPCPROC_Define ($$)
|
||||
|
||||
# Initialize FHEM device, set IO device
|
||||
my $rc = HMCCURPCPROC_InitDevice ($ioHash, $hash);
|
||||
return "Invalid port or interface $iface" if ($rc == 1);
|
||||
return "Can't assign I/O device $ioname" if ($rc == 2);
|
||||
return "Invalid local IP address ".$hash->{hmccu}{localaddr} if ($rc == 3);
|
||||
return "RPC device for CCU/port already exists" if ($rc == 4);
|
||||
return "Cannot connect to CCU ".$hash->{host}." interface $iface" if ($rc == 5);
|
||||
return "$errSource Invalid port or interface $iface" if ($rc == 1);
|
||||
return "$errSource Can't assign I/O device $ioname" if ($rc == 2);
|
||||
return "$errSource Invalid local IP address ".$hash->{hmccu}{localaddr} if ($rc == 3);
|
||||
return "$errSource RPC device for CCU/port already exists" if ($rc == 4);
|
||||
return "$errSource Cannot connect to CCU ".$hash->{host}." interface $iface" if ($rc == 5);
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
#
|
||||
# $Id: HMCCUConf.pm 18552 2019-02-10 11:52:28Z zap $
|
||||
#
|
||||
# Version 4.8.027
|
||||
# Version 4.8.028
|
||||
#
|
||||
# Configuration parameters for HomeMatic devices.
|
||||
#
|
||||
@ -28,7 +28,7 @@ use vars qw(%HMCCU_CHN_DEFAULTS);
|
||||
use vars qw(%HMCCU_DEV_DEFAULTS);
|
||||
use vars qw(%HMCCU_SCRIPTS);
|
||||
|
||||
$HMCCU_CONFIG_VERSION = '4.8.027';
|
||||
$HMCCU_CONFIG_VERSION = '4.8.028';
|
||||
|
||||
######################################################################
|
||||
# Map subtype to default role. Subtype is only available for HMIP
|
||||
@ -103,6 +103,9 @@ $HMCCU_CONFIG_VERSION = '4.8.027';
|
||||
'BLIND' => {
|
||||
F => 3, S => 'LEVEL', C => 'LEVEL', V => 'open:100,close:0', P => 2
|
||||
},
|
||||
'BLIND_TRANSMITTER' => {
|
||||
F => 3, S => 'LEVEL', C => '', V => '', P => 1
|
||||
},
|
||||
'BLIND_VIRTUAL_RECEIVER' => {
|
||||
F => 3, S => 'LEVEL', C => 'LEVEL', V => 'open:100,close:0', P => 2
|
||||
},
|
||||
@ -160,6 +163,8 @@ $HMCCU_CONFIG_VERSION = '4.8.027';
|
||||
%HMCCU_READINGS = (
|
||||
'BLIND' =>
|
||||
'(C#\.)?LEVEL$:+pct',
|
||||
'BLIND_TRANSMITTER' =>
|
||||
'(C#\.)?LEVEL$:+pct',
|
||||
'BLIND_VIRTUAL_RECEIVER' =>
|
||||
'(C#\.)?LEVEL$:+pct',
|
||||
'SHUTTER_VIRTUAL_RECEIVER' =>
|
||||
@ -388,6 +393,9 @@ $HMCCU_CONFIG_VERSION = '4.8.027';
|
||||
'webCmd' => 'pct:open:close:stop',
|
||||
'widgetOverride' => 'pct:slider,0,10,100'
|
||||
},
|
||||
'BLIND_TRANSMITTER' => {
|
||||
'substexcl' => 'pct',
|
||||
},
|
||||
'BLIND_VIRTUAL_RECEIVER' => {
|
||||
'substexcl' => 'pct',
|
||||
'cmdIcon' => 'open:fts_shutter_up stop:fts_shutter_manual close:fts_shutter_down',
|
||||
@ -508,6 +516,9 @@ $HMCCU_CONFIG_VERSION = '4.8.027';
|
||||
'DIRECTION' => { '0' => 'none', '1' => 'up', '2' => 'down' },
|
||||
'WORKING' => { '0' => 'no', 'false' => 'no', '1' => 'yes', 'true' => 'yes' }
|
||||
},
|
||||
'BLIND_TRANSMITTER' => {
|
||||
'LEVEL' => { '0' => 'closed', '100' => 'open', 'close' => '0', 'open' => '100' }
|
||||
},
|
||||
'BLIND_VIRTUAL_RECEIVER' => {
|
||||
'LEVEL' => { '0' => 'closed', '100' => 'open', 'close' => '0', 'open' => '100' },
|
||||
'DIRECTION' => { '0' => 'none', '1' => 'up', '2' => 'down' },
|
||||
|
@ -1,5 +1,5 @@
|
||||
UPD 2021-04-16_11:55:59 102657 FHEM/88_HMCCURPCPROC.pm
|
||||
UPD 2021-04-16_11:55:50 81576 FHEM/HMCCUConf.pm
|
||||
UPD 2021-04-16_11:55:30 42683 FHEM/88_HMCCUCHN.pm
|
||||
UPD 2021-04-16_11:55:22 335317 FHEM/88_HMCCU.pm
|
||||
UPD 2021-04-16_11:55:38 31630 FHEM/88_HMCCUDEV.pm
|
||||
UPD 2021-05-17_18:01:13 102813 FHEM/88_HMCCURPCPROC.pm
|
||||
UPD 2021-05-17_18:01:13 81874 FHEM/HMCCUConf.pm
|
||||
UPD 2021-05-17_18:01:13 42050 FHEM/88_HMCCUCHN.pm
|
||||
UPD 2021-05-17_18:01:13 337736 FHEM/88_HMCCU.pm
|
||||
UPD 2021-05-17_18:01:13 30869 FHEM/88_HMCCUDEV.pm
|
||||
|
Loading…
x
Reference in New Issue
Block a user