2
0
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:
zap 2021-05-17 16:06:08 +00:00
parent a8a48134e2
commit e67bb25dec
7 changed files with 288 additions and 237 deletions

View File

@ -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

View File

@ -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 &lt;name&gt; defaults</b><br/>
List device types and channels with default attributes available.
</li><br/>
<li><b>get &lt;name&gt; deviceinfo &lt;device-name-or-address&gt;</b><br/>
<li><b>get &lt;name&gt; deviceinfo &lt;device-name-or-address&gt; [extended]</b><br/>
List device channels, datapoints and the device description.
</li><br/>
<li><b>get &lt;name&gt; dutycycle</b><br/>

View File

@ -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 &lt;name&gt; deviceInfo</b><br/>
<li><b>get &lt;name&gt; 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>

View File

@ -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 &lt;name&gt; defaults</b><br/>
<a href="#HMCCUCHNget">see HMCCUCHN</a>
</li><br/>
<li><b>get &lt;name&gt; deviceinfo</b><br/>
<li><b>get &lt;name&gt; 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>

View File

@ -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;
}

View File

@ -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' },

View File

@ -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