2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-04-07 19:04:20 +00:00

HMCCU: 4.4 Beta RC3

git-svn-id: https://svn.fhem.de/fhem/trunk@24257 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
zap 2021-04-16 10:04:26 +00:00
parent 9e54fea830
commit 1b0a5390f4
5 changed files with 161 additions and 56 deletions

View File

@ -4,7 +4,7 @@
# #
# $Id: 88_HMCCU.pm 18745 2019-02-26 17:33:23Z zap $ # $Id: 88_HMCCU.pm 18745 2019-02-26 17:33:23Z zap $
# #
# Version 4.4.065 # Version 4.4.066
# #
# Module for communication between FHEM and Homematic CCU2/3. # Module for communication between FHEM and Homematic CCU2/3.
# #
@ -58,7 +58,7 @@ my %HMCCU_CUST_CHN_DEFAULTS;
my %HMCCU_CUST_DEV_DEFAULTS; my %HMCCU_CUST_DEV_DEFAULTS;
# HMCCU version # HMCCU version
my $HMCCU_VERSION = '4.4.065'; my $HMCCU_VERSION = '4.4.066';
# Timeout for CCU requests (seconds) # Timeout for CCU requests (seconds)
my $HMCCU_TIMEOUT_REQUEST = 4; my $HMCCU_TIMEOUT_REQUEST = 4;
@ -263,6 +263,7 @@ sub HMCCU_GetAffectedAddresses ($);
sub HMCCU_GetCCUDeviceParam ($$); sub HMCCU_GetCCUDeviceParam ($$);
sub HMCCU_GetChannelName ($$;$); sub HMCCU_GetChannelName ($$;$);
sub HMCCU_GetChannelRole ($;$); sub HMCCU_GetChannelRole ($;$);
sub HMCCU_GetDeviceRoles ($$$;$);
sub HMCCU_GetClientDeviceModel ($;$); sub HMCCU_GetClientDeviceModel ($;$);
sub HMCCU_GetDefaultInterface ($); sub HMCCU_GetDefaultInterface ($);
sub HMCCU_GetDeviceAddresses ($;$$); sub HMCCU_GetDeviceAddresses ($;$$);
@ -308,6 +309,7 @@ sub HMCCU_SetSCDatapoints ($$;$$);
sub HMCCU_GetStateValues ($;$$); sub HMCCU_GetStateValues ($;$$);
sub HMCCU_GetValidDatapoints ($$$$;$); sub HMCCU_GetValidDatapoints ($$$$;$);
sub HMCCU_IsValidDatapoint ($$$$$); sub HMCCU_IsValidDatapoint ($$$$$);
sub HMCCU_SetInitialAttributes ($$);
sub HMCCU_SetDefaultAttributes ($;$); sub HMCCU_SetDefaultAttributes ($;$);
sub HMCCU_SetMultipleDatapoints ($$); sub HMCCU_SetMultipleDatapoints ($$);
sub HMCCU_SetMultipleParameters ($$$;$); sub HMCCU_SetMultipleParameters ($$$;$);
@ -375,7 +377,7 @@ sub HMCCU_Initialize ($)
' ccudefaults'. ' ccudefaults'.
' ccudef-hmstatevals:textField-long ccudef-substitute:textField-long'. ' ccudef-hmstatevals:textField-long ccudef-substitute:textField-long'.
' ccudef-readingformat:name,namelc,address,addresslc,datapoint,datapointlc'. ' ccudef-readingformat:name,namelc,address,addresslc,datapoint,datapointlc'.
' ccudef-stripnumber ccuReadingPrefix'. ' ccudef-stripnumber ccudef-attributes ccuReadingPrefix'.
' ccuflags:multiple-strict,procrpc,dptnocheck,logCommand,noagg,nohmstate,updGroupMembers,'. ' ccuflags:multiple-strict,procrpc,dptnocheck,logCommand,noagg,nohmstate,updGroupMembers,'.
'logEvents,noEvents,noInitialUpdate,noReadings,nonBlocking,reconnect,logPong,trace,logEnhanced'. 'logEvents,noEvents,noInitialUpdate,noReadings,nonBlocking,reconnect,logPong,trace,logEnhanced'.
' ccuReqTimeout ccuGetVars rpcPingCCU'. ' ccuReqTimeout ccuGetVars rpcPingCCU'.
@ -1678,15 +1680,19 @@ sub HMCCU_Get ($@)
} }
elsif ($opt eq 'ccudevices') { elsif ($opt eq 'ccudevices') {
my $devTable = '<html><table border="1">'. my $devTable = '<html><table border="1">'.
'<tr><th>Name</th><th>Model</th><th>Interface</th><th>Address</th><th>Channels</th></tr>'; '<tr><th>Name</th><th>Model</th><th>Interface</th><th>Address</th><th>Channels</th><th>Supported roles</th></tr>';
foreach my $di (sort keys %{$hash->{hmccu}{device}}) { foreach my $di (sort keys %{$hash->{hmccu}{device}}) {
foreach my $da (sort keys %{$hash->{hmccu}{device}{$di}}) { foreach my $da (sort keys %{$hash->{hmccu}{device}{$di}}) {
next if ($hash->{hmccu}{device}{$di}{$da}{_addtype} ne 'dev'); next if ($hash->{hmccu}{device}{$di}{$da}{_addtype} ne 'dev');
my $chn = exists($hash->{hmccu}{dev}{$da}) ? $hash->{hmccu}{dev}{$da}{channels} : '?'; my $chn = exists($hash->{hmccu}{dev}{$da}) ? $hash->{hmccu}{dev}{$da}{channels} : '?';
my @roles = HMCCU_GetDeviceRoles ($hash, $di, $da, 1);
my %suppRoles;
$suppRoles{$_}++ for @roles;
$devTable .= "<tr>". $devTable .= "<tr>".
"<td>$hash->{hmccu}{device}{$di}{$da}{_name}</td>". "<td>$hash->{hmccu}{device}{$di}{$da}{_name}</td>".
"<td>$hash->{hmccu}{device}{$di}{$da}{_model}</td>". "<td>$hash->{hmccu}{device}{$di}{$da}{_model}</td>".
"<td>$di</td><td>$da</td><td>$chn</td>". "<td>$di</td><td>$da</td><td>$chn</td>".
"<td>".join('<br/>', map { "$_ [$suppRoles{$_}x]" } sort keys %suppRoles)."</td>".
"</tr>\n"; "</tr>\n";
} }
} }
@ -3186,6 +3192,7 @@ sub HMCCU_CreateDevice ($$$$$$$$)
$cs->{defSuccess}{$devName} = "$defAdd [$ccuName]"; $cs->{defSuccess}{$devName} = "$defAdd [$ccuName]";
# Set device attributes # Set device attributes
HMCCU_SetInitialAttributes ($hash, $devName);
foreach my $da (keys %$ah) { foreach my $da (keys %$ah) {
$ret = CommandAttr (undef, "$devName $da ".$ah->{$da}); $ret = CommandAttr (undef, "$devName $da ".$ah->{$da});
if ($ret) { if ($ret) {
@ -3452,7 +3459,7 @@ sub HMCCU_SetSCAttributes ($$;$)
my $ccuType = $clHash->{ccutype} // return; my $ccuType = $clHash->{ccutype} // return;
my $ccuAddr = $clHash->{ccuaddr} // return; my $ccuAddr = $clHash->{ccuaddr} // return;
my $ccuIf = $clHash->{ccuif} // return; my $ccuIf = $clHash->{ccuif} // return;
$detect = HMCCU_DetectDevice ($ioHash, $ccuAddr, $ccuIf) if ($detect == -1); $detect //= HMCCU_DetectDevice ($ioHash, $ccuAddr, $ccuIf);
# Get readable and writeable datapoints # Get readable and writeable datapoints
my @dpWrite = (); my @dpWrite = ();
@ -3522,6 +3529,36 @@ sub HMCCU_GetChannelRole ($;$)
return ''; return '';
} }
######################################################################
# Return role(s) of a device or a channel identified by address
# Parameters:
# $mode: 0 = All roles, 1 = Only supported roles
######################################################################
sub HMCCU_GetDeviceRoles ($$$;$)
{
my ($ioHash, $iface, $address, $mode) = @_;
$mode //= 0; # By default get all roles
my @roles = ();
if (exists($ioHash->{hmccu}{device}{$iface}{$address})) {
if ($ioHash->{hmccu}{device}{$iface}{$address}{_addtype} eq 'dev') {
foreach my $chAddress (split(',', $ioHash->{hmccu}{device}{$iface}{$address}{CHILDREN})) {
my $r = $ioHash->{hmccu}{device}{$iface}{$chAddress}{TYPE};
push @roles, $r if (exists($ioHash->{hmccu}{device}{$iface}{$chAddress}) &&
$ioHash->{hmccu}{device}{$iface}{$chAddress}{_addtype} eq 'chn' &&
($mode == 0 || ($mode == 1 && exists($HMCCU_STATECONTROL->{$r}))));
}
}
elsif ($ioHash->{hmccu}{device}{$iface}{$address}{_addtype} eq 'chn') {
my $r = $ioHash->{hmccu}{device}{$iface}{$address}{TYPE};
push @roles, $r if ($mode == 0 || ($mode == 1 && exists($HMCCU_STATECONTROL->{$r})));
}
}
return @roles;
}
###################################################################### ######################################################################
# Get device configuration for all interfaces from CCU # Get device configuration for all interfaces from CCU
# Currently binary interfaces like CUxD are not supported # Currently binary interfaces like CUxD are not supported
@ -3591,7 +3628,7 @@ sub HMCCU_GetDeviceConfig ($)
foreach my $d (@devList) { foreach my $d (@devList) {
my $clHash = $defs{$d}; my $clHash = $defs{$d};
HMCCU_SetSCAttributes ($ioHash, $clHash, -1); HMCCU_SetSCAttributes ($ioHash, $clHash);
HMCCU_UpdateDevice ($ioHash, $clHash); HMCCU_UpdateDevice ($ioHash, $clHash);
HMCCU_UpdateDeviceRoles ($ioHash, $clHash); HMCCU_UpdateDeviceRoles ($ioHash, $clHash);
@ -3763,11 +3800,11 @@ sub HMCCU_DeviceDescToStr ($$)
my $channelType = $devDesc->{TYPE}; my $channelType = $devDesc->{TYPE};
my $status = exists($HMCCU_STATECONTROL->{$channelType}) ? ' known' : ''; my $status = exists($HMCCU_STATECONTROL->{$channelType}) ? ' known' : '';
$result .= $a eq $devAddr ? "Device $a" : "Channel $a"; $result .= $a eq $devAddr ? "Device $a" : "Channel $a";
$result .= " $devDesc->{_name} [$channelType]$status\n"; $result .= " $devDesc->{_name} [$channelType]$status<br/>";
foreach my $n (sort keys %{$devDesc}) { foreach my $n (sort keys %{$devDesc}) {
next if ($n =~ /^_/ || $n =~ /^(ADDRESS|TYPE|INDEX|VERSION)$/ || next if ($n =~ /^_/ || $n =~ /^(ADDRESS|TYPE|INDEX|VERSION)$/ ||
!defined($devDesc->{$n}) || $devDesc->{$n} eq ''); !defined($devDesc->{$n}) || $devDesc->{$n} eq '');
$result .= " $n: ".HMCCU_FlagsToStr ('device', $n, $devDesc->{$n}, ',', '')."\n"; $result .= "&nbsp;&nbsp;$n: ".HMCCU_FlagsToStr ('device', $n, $devDesc->{$n}, ',', '')."<br/>";
} }
} }
@ -3783,7 +3820,7 @@ sub HMCCU_ParamsetDescToStr ($$)
{ {
my ($ioHash, $object) = @_; my ($ioHash, $object) = @_;
my $result = ''; my $result = '<html>';
my $address; my $address;
my $iface; my $iface;
@ -3814,11 +3851,11 @@ sub HMCCU_ParamsetDescToStr ($$)
} }
foreach my $c (@chnList) { foreach my $c (@chnList) {
$result .= $c eq 'd' ? "Device\n" : "Channel $c\n"; $result .= $c eq 'd' ? "Device<br/>" : "Channel $c<br/>";
foreach my $ps (sort keys %{$model->{$c}}) { foreach my $ps (sort keys %{$model->{$c}}) {
$result .= " Paramset $ps\n"; $result .= "&nbsp;&nbsp;Paramset $ps<br/>";
$result .= join ("\n", map { $result .= join ("<br/>", map {
" ".$_.": ". "&nbsp;&nbsp;&nbsp;&nbsp;".$_.": ".
$model->{$c}{$ps}{$_}{TYPE}. $model->{$c}{$ps}{$_}{TYPE}.
" [".HMCCU_FlagsToStr ('model', 'OPERATIONS', $model->{$c}{$ps}{$_}{OPERATIONS}, ',', '')."]". " [".HMCCU_FlagsToStr ('model', 'OPERATIONS', $model->{$c}{$ps}{$_}{OPERATIONS}, ',', '')."]".
" [".HMCCU_FlagsToStr ('model', 'FLAGS', $model->{$c}{$ps}{$_}{FLAGS}, ',', '')."]". " [".HMCCU_FlagsToStr ('model', 'FLAGS', $model->{$c}{$ps}{$_}{FLAGS}, ',', '')."]".
@ -3827,10 +3864,12 @@ sub HMCCU_ParamsetDescToStr ($$)
" DFLT=".HMCCU_StripNumber ($model->{$c}{$ps}{$_}{DEFAULT}, 2). " DFLT=".HMCCU_StripNumber ($model->{$c}{$ps}{$_}{DEFAULT}, 2).
HMCCU_ISO2UTF (HMCCU_DefStr ($model->{$c}{$ps}{$_}{UNIT}, " UNIT=")). HMCCU_ISO2UTF (HMCCU_DefStr ($model->{$c}{$ps}{$_}{UNIT}, " UNIT=")).
HMCCU_DefStr ($model->{$c}{$ps}{$_}{VALUE_LIST}, " VALUES=") HMCCU_DefStr ($model->{$c}{$ps}{$_}{VALUE_LIST}, " VALUES=")
} sort keys %{$model->{$c}{$ps}})."\n"; } sort keys %{$model->{$c}{$ps}})."<br/>";
} }
} }
$result .= '</html>';
return $result; return $result;
} }
@ -4992,16 +5031,17 @@ sub HMCCU_FormatDeviceInfo ($)
foreach my $dpspec (split ("\n", $devinfo)) { foreach my $dpspec (split ("\n", $devinfo)) {
if ($dpspec =~ /^D/) { if ($dpspec =~ /^D/) {
my ($t, $d_iface, $d_addr, $d_name, $d_type) = split (';', $dpspec); my ($t, $d_iface, $d_addr, $d_name, $d_type) = split (';', $dpspec);
$result .= "DEV $d_name $d_addr interface=$d_iface type=$d_type\n"; $result .= "DEV $d_name $d_addr interface=$d_iface type=$d_type<br/>";
} }
else { else {
my ($t, $c_addr, $c_name, $d_name, $d_type, $d_value, $d_flags) = split (';', $dpspec); my ($t, $c_addr, $c_name, $d_name, $d_type, $d_value, $d_flags) = split (';', $dpspec);
$d_name =~ s/^[^:]+:(.+)$/$1/;
if ($c_addr ne $c_oaddr) { if ($c_addr ne $c_oaddr) {
$result .= "CHN $c_addr $c_name\n"; $result .= "CHN $c_addr $c_name<br/>";
$c_oaddr = $c_addr; $c_oaddr = $c_addr;
} }
my $dt = exists($vtypes{$d_type}) ? $vtypes{$d_type} : $d_type; my $dt = exists($vtypes{$d_type}) ? $vtypes{$d_type} : $d_type;
$result .= " DPT {$dt} $d_name = $d_value [$d_flags]\n"; $result .= "&nbsp;&nbsp;&nbsp;$d_name = $d_value {$dt} [$d_flags]<br/>";
} }
} }
@ -6299,6 +6339,21 @@ sub HMCCU_GetAttribute ($$$$)
return $value; return $value;
} }
######################################################################
# Set initial attributes after device definition
######################################################################
sub HMCCU_SetInitialAttributes ($$)
{
my ($ioHash, $clName) = @_;
my $ccudefAttributes = AttrVal ($ioHash->{NAME}, 'ccudef-attributes', 'room=Homematic');
foreach my $a (split(',', $ccudefAttributes)) {
my ($an, $av) = split('=', $a);
CommandAttr (undef, "$clName $an $av") if (defined($av));
}
}
###################################################################### ######################################################################
# Set default attributes for client device. # Set default attributes for client device.
# Optionally delete obsolete attributes. # Optionally delete obsolete attributes.
@ -6494,11 +6549,11 @@ sub HMCCU_UpdateRoleCommands ($$;$)
} }
if (defined($par) && $par ne '') { if (defined($par) && $par ne '') {
if ($par =~ /^#(.+)$/) { if ($par =~ /^#([^=]+)/) {
# Parameter list # Parameter list
my $argList = ''; my $argList = '';
$clHash->{hmccu}{roleCmds}{$cmdType}{$cmd}{subcmd}{$scn}{parname} = $1; $clHash->{hmccu}{roleCmds}{$cmdType}{$cmd}{subcmd}{$scn}{parname} = $1;
$pt = 1; # Enum $pt = 1; # Enum / List of fixed values
if ($paramDef->{TYPE} eq 'ENUM' && defined($paramDef->{VALUE_LIST})) { if ($paramDef->{TYPE} eq 'ENUM' && defined($paramDef->{VALUE_LIST})) {
$argList = $paramDef->{VALUE_LIST}; $argList = $paramDef->{VALUE_LIST};
@ -6506,8 +6561,14 @@ sub HMCCU_UpdateRoleCommands ($$;$)
else { else {
my ($pn, $pv) = split('=', $par); my ($pn, $pv) = split('=', $par);
$argList = $pv // ''; $argList = $pv // '';
foreach my $e (split(',', $argList)) { my %valList;
$clHash->{hmccu}{roleCmds}{$cmdType}{$cmd}{subcmd}{$scn}{look}{$e} = $e; foreach my $cv (split(',', $HMCCU_STATECONTROL->{$role}{V})) {
my ($vn, $vv) = split(':', $cv);
$valList{$vn} = $vv // $vn;
}
my @el = split(',', $argList);
while (my ($i, $e) = each @el) {
$clHash->{hmccu}{roleCmds}{$cmdType}{$cmd}{subcmd}{$scn}{look}{$e} = $valList{$e} // $i;
} }
} }
@ -6538,9 +6599,16 @@ sub HMCCU_UpdateRoleCommands ($$;$)
} }
else { else {
# Fix value. Command has no argument # Fix value. Command has no argument
my ($pn, $pv) = split('=', $par);
$pt = 3; $pt = 3;
$clHash->{hmccu}{roleCmds}{$cmdType}{$cmd}{subcmd}{$scn}{parname} = $dpt; if (defined($pv)) {
$clHash->{hmccu}{roleCmds}{$cmdType}{$cmd}{subcmd}{$scn}{args} = $par; $clHash->{hmccu}{roleCmds}{$cmdType}{$cmd}{subcmd}{$scn}{parname} = $pn;
$clHash->{hmccu}{roleCmds}{$cmdType}{$cmd}{subcmd}{$scn}{args} = $pv;
}
else {
$clHash->{hmccu}{roleCmds}{$cmdType}{$cmd}{subcmd}{$scn}{parname} = $dpt;
$clHash->{hmccu}{roleCmds}{$cmdType}{$cmd}{subcmd}{$scn}{args} = $par;
}
} }
} }
@ -6559,6 +6627,8 @@ sub HMCCU_UpdateRoleCommands ($$;$)
} }
if (exists($clHash->{hmccu}{roleCmds}{$cmdType}{$cmd}{channel})) { if (exists($clHash->{hmccu}{roleCmds}{$cmdType}{$cmd}{channel})) {
# Same command in multiple channels.
# Channel number will be set to control channel during command execution
$clHash->{hmccu}{roleCmds}{$cmdType}{$cmd}{channel} = '?'; $clHash->{hmccu}{roleCmds}{$cmdType}{$cmd}{channel} = '?';
} }
else { else {
@ -6973,7 +7043,7 @@ sub HMCCU_ExecuteGetDeviceInfoCommand ($@)
my $iface = HMCCU_GetDeviceInterface ($ioHash, $address); my $iface = HMCCU_GetDeviceInterface ($ioHash, $address);
my $result = HMCCU_GetDeviceInfo ($clHash, $address); my $result = HMCCU_GetDeviceInfo ($clHash, $address);
return HMCCU_SetError ($clHash, -2) if ($result eq ''); return HMCCU_SetError ($clHash, -2) if ($result eq '');
my $devInfo = '<b>Device channels and datapoints</b><br/><br/>'; my $devInfo = '<html><b>Device channels and datapoints</b><br/><br/>';
$devInfo .= HMCCU_FormatDeviceInfo ($result); $devInfo .= HMCCU_FormatDeviceInfo ($result);
my $detect = HMCCU_DetectDevice ($ioHash, $address, $iface); my $detect = HMCCU_DetectDevice ($ioHash, $address, $iface);
if (defined($detect)) { if (defined($detect)) {
@ -7004,11 +7074,12 @@ sub HMCCU_ExecuteGetDeviceInfoCommand ($@)
$devInfo .= "<br/>Current control datapoint = $cc.$cd<br/>" if ($cc ne '?'); $devInfo .= "<br/>Current control datapoint = $cc.$cd<br/>" if ($cc ne '?');
$devInfo .= '<br/><b>Device description</b><br/><br/>'; $devInfo .= '<br/><b>Device description</b><br/><br/>';
$result = HMCCU_DeviceDescToStr ($ioHash, $clHash->{TYPE} eq 'HMCCU' ? $address : $clHash); $result = HMCCU_DeviceDescToStr ($ioHash, $clHash->{TYPE} eq 'HMCCU' ? $address : $clHash);
$devInfo .= defined($result) ? $result : "Can't get device description"; $devInfo .= defined($result) ? $result : "Can't get device description<br/>";
if ($clHash->{TYPE} ne 'HMCCU') { if ($clHash->{TYPE} ne 'HMCCU') {
$devInfo .= '<br/>Defaults<br/><br/>'; $devInfo .= '<br/>Defaults<br/><br/>';
$devInfo .= HMCCU_GetDefaults ($clHash); $devInfo .= HMCCU_GetDefaults ($clHash);
} }
$devInfo .= '</html>';
return $devInfo; return $devInfo;
} }
@ -7626,14 +7697,14 @@ sub HMCCU_DetectDevice ($$$)
# Determine parameters for device definition # Determine parameters for device definition
if ($stateRoleCnt == 1 && $ctrlRoleCnt == 0) { if ($stateRoleCnt == 1 && $ctrlRoleCnt == 0) {
# One channel with statedatapoint => HMCCUCHN # One channel with statedatapoint, but no controldatapoint (read only) => HMCCUCHN
$di{defSCh} = $stateRoles[0]->{channel}; $di{defSCh} = $stateRoles[0]->{channel};
$di{defMod} = 'HMCCUCHN'; $di{defMod} = 'HMCCUCHN';
$di{defAdd} = "$devAdd:$di{defSCh}"; $di{defAdd} = "$devAdd:$di{defSCh}";
$di{level} = 1; $di{level} = 1;
} }
elsif ($stateRoleCnt == 0 && $ctrlRoleCnt == 1) { elsif ($stateRoleCnt == 0 && $ctrlRoleCnt == 1) {
# One channel with controldatapoint => HMCCUCHN # One channel with controldatapoint, but no statedatapoint (write only) => HMCCUCHN
$di{defCCh} = $controlRoles[0]->{channel}; $di{defCCh} = $controlRoles[0]->{channel};
$di{defMod} = 'HMCCUCHN'; $di{defMod} = 'HMCCUCHN';
$di{defAdd} = "$devAdd:$di{defCCh}"; $di{defAdd} = "$devAdd:$di{defCCh}";
@ -7643,13 +7714,13 @@ sub HMCCU_DetectDevice ($$$)
$di{defSCh} = $stateRoles[0]->{channel}; $di{defSCh} = $stateRoles[0]->{channel};
$di{defCCh} = $controlRoles[0]->{channel}; $di{defCCh} = $controlRoles[0]->{channel};
if ($stateRoles[0]->{channel} == $controlRoles[0]->{channel}) { if ($stateRoles[0]->{channel} == $controlRoles[0]->{channel}) {
# One channel with controldatapoint and statedatapoint => HMCCUCHN # One channel with controldatapoint and statedatapoint (read + write)=> HMCCUCHN
$di{defMod} = 'HMCCUCHN'; $di{defMod} = 'HMCCUCHN';
$di{defAdd} = "$devAdd:$di{defCCh}"; $di{defAdd} = "$devAdd:$di{defCCh}";
$di{level} = 1; $di{level} = 1;
} }
else { else {
# Two different channels for controldatapoint and statedatapoint => HMCCUDEV # Two different channels for controldatapoint and statedatapoint (read + write) => HMCCUDEV
$di{defMod} = 'HMCCUDEV'; $di{defMod} = 'HMCCUDEV';
$di{defAdd} = $devAdd; $di{defAdd} = $devAdd;
$di{level} = 4; $di{level} = 4;
@ -7658,7 +7729,8 @@ sub HMCCU_DetectDevice ($$$)
elsif ($stateRoleCnt > 1 || $ctrlRoleCnt > 1) { elsif ($stateRoleCnt > 1 || $ctrlRoleCnt > 1) {
# Multiple channels found # Multiple channels found
if ($cntUniqStateRoles == 1 && $cntUniqCtrlRoles == 0 || if ($cntUniqStateRoles == 1 && $cntUniqCtrlRoles == 0 ||
$cntUniqStateRoles == 0 && $cntUniqCtrlRoles == 1 || ( $cntUniqStateRoles == 0 && $cntUniqCtrlRoles == 1 ||
$cntUniqCtrlRoles > 1 || (
$cntUniqStateRoles == 1 && $cntUniqCtrlRoles == 1 && $stateRoles[0]->{role} eq $controlRoles[0]->{role} $cntUniqStateRoles == 1 && $cntUniqCtrlRoles == 1 && $stateRoles[0]->{role} eq $controlRoles[0]->{role}
) )
) { ) {
@ -9651,7 +9723,7 @@ sub HMCCU_MaxHashEntries ($$)
which reacts with execution of command 'get ccuConfig' on these events. which reacts with execution of command 'get ccuConfig' on these events.
</li><br/> </li><br/>
<li><b>get &lt;name&gt; ccuDevices</b><br/> <li><b>get &lt;name&gt; ccuDevices</b><br/>
Show table of CCU devices. Show table of CCU devices including channel roles supported by HMCCU auto detection.
</li><br/> </li><br/>
<li><b>get &lt;name&gt; ccumsg {service|alarm}</b><br/> <li><b>get &lt;name&gt; ccumsg {service|alarm}</b><br/>
Query active service or alarm messages from CCU. Generate FHEM event for each message. Query active service or alarm messages from CCU. Generate FHEM event for each message.
@ -9770,6 +9842,12 @@ sub HMCCU_MaxHashEntries ($$)
Example: Find devices with low batteries. Generate reading in HTML format.<br/> Example: Find devices with low batteries. Generate reading in HTML format.<br/>
name=battery,filter:name=.*,read:(LOWBAT|LOW_BAT),if:any=yes,else:no,prefix:batt_,coll:NAME!All batteries OK,html:/home/battery.cfg<br/> name=battery,filter:name=.*,read:(LOWBAT|LOW_BAT),if:any=yes,else:no,prefix:batt_,coll:NAME!All batteries OK,html:/home/battery.cfg<br/>
</li><br/> </li><br/>
<li><b>ccudef-attributes {&lt;attrName&gt;=&lt;attrValue&gt;[;...] | none}</b><br/>
Define attributes which are assigned to newly defined HMCCUDEV or HMCCUCHN devices. By default the following
attributes will be assigned:<br/>
room=Homematic<br/>
If attribute is set to 'none', no attributes will be assigned to new devices.
</li><br/>
<li><b>ccudef-hmstatevals &lt;subst-rule[;...]&gt;</b><br/> <li><b>ccudef-hmstatevals &lt;subst-rule[;...]&gt;</b><br/>
Set global rules for calculation of reading hmstate. Set global rules for calculation of reading hmstate.
</li><br/> </li><br/>

View File

@ -4,7 +4,7 @@
# #
# $Id: 88_HMCCUCHN.pm 18552 2019-02-10 11:52:28Z zap $ # $Id: 88_HMCCUCHN.pm 18552 2019-02-10 11:52:28Z zap $
# #
# Version 4.4.037 # Version 4.4.038
# #
# (c) 2021 zap (zap01 <at> t-online <dot> de) # (c) 2021 zap (zap01 <at> t-online <dot> de)
# #
@ -117,7 +117,7 @@ sub HMCCUCHN_Define ($@)
else { else {
# CCU not ready during FHEM start # CCU not ready during FHEM start
if (!defined($ioHash) || $ioHash->{ccustate} ne 'active') { if (!defined($ioHash) || $ioHash->{ccustate} ne 'active') {
HMCCU_Log ($hash, 2, 'Cannot detect IO device, maybe CCU not ready. Trying later ...'); HMCCU_Log ($hash, 3, 'Cannot detect IO device, maybe CCU not ready. Trying later ...');
$hash->{ccudevstate} = 'pending'; $hash->{ccudevstate} = 'pending';
return undef; return undef;
} }
@ -142,6 +142,7 @@ sub HMCCUCHN_Define ($@)
sub HMCCUCHN_InitDevice ($$) sub HMCCUCHN_InitDevice ($$)
{ {
my ($ioHash, $devHash) = @_; my ($ioHash, $devHash) = @_;
my $name = $devHash->{NAME};
my $devspec = $devHash->{hmccu}{devspec}; my $devspec = $devHash->{hmccu}{devspec};
return 1 if (!HMCCU_IsValidChannel ($ioHash, $devspec, 7)); return 1 if (!HMCCU_IsValidChannel ($ioHash, $devspec, 7));
@ -173,6 +174,8 @@ sub HMCCUCHN_InitDevice ($$)
HMCCU_Log ($devHash, 2, "Cannot set default state- and control datapoints"); HMCCU_Log ($devHash, 2, "Cannot set default state- and control datapoints");
} }
HMCCU_SetInitialAttributes ($ioHash, $name);
if (!exists($devHash->{hmccu}{nodefaults}) || $devHash->{hmccu}{nodefaults} == 0) { if (!exists($devHash->{hmccu}{nodefaults}) || $devHash->{hmccu}{nodefaults} == 0) {
if (!HMCCU_SetDefaultAttributes ($devHash)) { if (!HMCCU_SetDefaultAttributes ($devHash)) {
HMCCU_SetDefaults ($devHash); HMCCU_SetDefaults ($devHash);

View File

@ -4,7 +4,7 @@
# #
# $Id: 88_HMCCUDEV.pm 18552 2019-02-10 11:52:28Z zap $ # $Id: 88_HMCCUDEV.pm 18552 2019-02-10 11:52:28Z zap $
# #
# Version 4.4.045 # Version 4.4.046
# #
# (c) 2021 zap (zap01 <at> t-online <dot> de) # (c) 2021 zap (zap01 <at> t-online <dot> de)
# #
@ -139,7 +139,7 @@ sub HMCCUDEV_Define ($@)
else { else {
# CCU not ready during FHEM start # CCU not ready during FHEM start
if (!defined($ioHash) || $ioHash->{ccustate} ne 'active') { if (!defined($ioHash) || $ioHash->{ccustate} ne 'active') {
HMCCU_Log ($hash, 2, 'Cannot detect IO device, maybe CCU not ready. Trying later ...'); HMCCU_Log ($hash, 3, 'Cannot detect IO device, maybe CCU not ready. Trying later ...');
$hash->{ccudevstate} = 'pending'; $hash->{ccudevstate} = 'pending';
return undef; return undef;
} }
@ -215,6 +215,8 @@ sub HMCCUDEV_InitDevice ($$)
HMCCU_Log ($devHash, 2, "Cannot set default state- and control datapoints"); HMCCU_Log ($devHash, 2, "Cannot set default state- and control datapoints");
} }
HMCCU_SetInitialAttributes ($ioHash, $name);
if (!exists($devHash->{hmccu}{nodefaults}) || $devHash->{hmccu}{nodefaults} == 0) { if (!exists($devHash->{hmccu}{nodefaults}) || $devHash->{hmccu}{nodefaults} == 0) {
my $chn = $detect->{defCCh} != -1 ? $detect->{defCCh} : $detect->{defSCh}; my $chn = $detect->{defCCh} != -1 ? $detect->{defCCh} : $detect->{defSCh};
if (!HMCCU_SetDefaultAttributes ($devHash, { if (!HMCCU_SetDefaultAttributes ($devHash, {

View File

@ -4,7 +4,7 @@
# #
# $Id: HMCCUConf.pm 18552 2019-02-10 11:52:28Z zap $ # $Id: HMCCUConf.pm 18552 2019-02-10 11:52:28Z zap $
# #
# Version 4.8.025 # Version 4.8.027
# #
# Configuration parameters for HomeMatic devices. # 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_DEV_DEFAULTS);
use vars qw(%HMCCU_SCRIPTS); use vars qw(%HMCCU_SCRIPTS);
$HMCCU_CONFIG_VERSION = '4.8.025'; $HMCCU_CONFIG_VERSION = '4.8.027';
###################################################################### ######################################################################
# Map subtype to default role. Subtype is only available for HMIP # Map subtype to default role. Subtype is only available for HMIP
@ -67,11 +67,14 @@ $HMCCU_CONFIG_VERSION = '4.8.025';
'ALARM_SWITCH_VIRTUAL_RECEIVER' => { 'ALARM_SWITCH_VIRTUAL_RECEIVER' => {
F => 3, S => 'ACOUSTIC_ALARM_ACTIVE', C => 'ACOUSTIC_ALARM_SELECTION', V => '', P => 2 F => 3, S => 'ACOUSTIC_ALARM_ACTIVE', C => 'ACOUSTIC_ALARM_SELECTION', V => '', P => 2
}, },
'MOTION_DETECTOR' => {
F => 3, S => 'MOTION', C => '', V => '', P => 1
},
'MOTIONDETECTOR_TRANSCEIVER' => { 'MOTIONDETECTOR_TRANSCEIVER' => {
F => 3, S => 'MOTION', C => 'MOTION_DETECTION_ACTIVE', V => 'on:1,off:0', P => 2 F => 3, S => 'MOTION', C => 'MOTION_DETECTION_ACTIVE', V => 'active:1,inactive:0', P => 2
}, },
'PRESENCEDETECTOR_TRANSCEIVER' => { 'PRESENCEDETECTOR_TRANSCEIVER' => {
F => 3, S => 'PRESENCE_DETECTION_STATE', C => 'PRESENCE_DETECTION_ACTIVE', V => 'on:1,off:0', P => 2 F => 3, S => 'PRESENCE_DETECTION_STATE', C => 'PRESENCE_DETECTION_ACTIVE', V => 'active:1,inactive:0', P => 2
}, },
'SMOKE_DETECTOR' => { 'SMOKE_DETECTOR' => {
F => 3, S => 'BidCos-RF:STATE,SMOKE_DETECTOR_ALARM_STATUS', C => 'HmIP-RF:SMOKE_DETECTOR_COMMAND', V => '', P => 2 F => 3, S => 'BidCos-RF:STATE,SMOKE_DETECTOR_ALARM_STATUS', C => 'HmIP-RF:SMOKE_DETECTOR_COMMAND', V => '', P => 2
@ -141,6 +144,9 @@ $HMCCU_CONFIG_VERSION = '4.8.025';
}, },
'CLIMATECONTROL_REGULATOR' => { 'CLIMATECONTROL_REGULATOR' => {
F => 3, S => 'LEVEL', C => 'SETPOINT', V => 'on:30.5,off:4.5', P => 2 F => 3, S => 'LEVEL', C => 'SETPOINT', V => 'on:30.5,off:4.5', P => 2
},
'CLIMATECONTROL_VENT_DRIVE' => {
F => 3, S => 'VALVE_STATE', C => '', V => '', P => 2
} }
); );
@ -162,8 +168,12 @@ $HMCCU_CONFIG_VERSION = '4.8.025';
'(C#\.)?LEVEL$:+pct', '(C#\.)?LEVEL$:+pct',
'DIMMER_VIRTUAL_RECEIVER' => 'DIMMER_VIRTUAL_RECEIVER' =>
'(C#\.)?LEVEL$:+pct', '(C#\.)?LEVEL$:+pct',
'MOTION_DETECTOR' =>
'^(C#\.)?BRIGHTNESS$:brightness;(C#\.)?MOTION:motion',
'MOTIONDETECTOR_TRANSCEIVER' =>
'^(C#\.)?ILLUMINATION$:brightness;^(C#\.)?MOTION$:motion;(C#\.)?MOTION_DETECTION_ACTIVE$:detection',
'PRESENCEDETECTOR_TRANSCEIVER' => 'PRESENCEDETECTOR_TRANSCEIVER' =>
'(C#\.)?ILLUMINATION:brightness;(C#\.)?PRESENCE_DETECTION_STATE:presence', '^(C#\.)?ILLUMINATION$:brightness;(C#\.)?PRESENCE_DETECTION_STATE:presence;(C#\.)?PRESENCE_DETECTION_ACTIVE:detection',
'WEATHER' => 'WEATHER' =>
'(C#\.)?TEMPERATURE$:+measured-temp;'. '(C#\.)?TEMPERATURE$:+measured-temp;'.
'(C#\.)?HUMIDITY$:+humidity', '(C#\.)?HUMIDITY$:+humidity',
@ -203,17 +213,18 @@ $HMCCU_CONFIG_VERSION = '4.8.025';
# Function: # Function:
# A Perl function name # A Perl function name
# Datapoint-Definition: # Datapoint-Definition:
# Paramset:Datapoint:[Parameter=]FixedValue[,FixedValue] # Paramset:Datapoint:[Parameter=]FixedValue
# Paramset:Datapoint:?Parameter # Paramset:Datapoint:?Parameter
# Paramset:Datapoint:?Parameter=Default-Value # Paramset:Datapoint:?Parameter=Default-Value
# Paramset:Datapoint:#Parameter # Paramset:Datapoint:#Parameter[=FixedValue,[...]]
# Paramset:Datapoint:*Parameter=Default-Value # Paramset:Datapoint:*Parameter=Default-Value
# Paramset: # Paramset:
# V=VALUES, M=MASTER (channel), D=MASTER (device), I=INTERNAL # V=VALUES, M=MASTER (channel), D=MASTER (device), I=INTERNAL
# Parameter characters: # Parameter characters:
# ? = any value is accepted # ? = any value is accepted
# # = datapoint must have type ENUM. Valid values are taken from # # = If datapoint is of type ENUM, values are taken from
# parameter set description. # parameter set description. Otherwise a list of values must
# be specified.
# * = internal value $hash->{hmccu}{values}{parameterName} # * = internal value $hash->{hmccu}{values}{parameterName}
# If Default-Value is preceeded by + or -, value is added to or # If Default-Value is preceeded by + or -, value is added to or
# subtracted from current datapoint value # subtracted from current datapoint value
@ -221,12 +232,11 @@ $HMCCU_CONFIG_VERSION = '4.8.025';
%HMCCU_ROLECMDS = ( %HMCCU_ROLECMDS = (
'MOTIONDETECTOR_TRANSCEIVER' => { 'MOTIONDETECTOR_TRANSCEIVER' => {
'on' => 'V:MOTION_DETECTION_ACTIVE:1', 'detection' => 'V:MOTION_DETECTION_ACTIVE:#detection=inactive,active',
'off' => 'V:MOTION_DETECTION_ACTIVE:0' 'reset' => 'V:RESET_MOTION:1'
}, },
'PRESENCEDETECTOR_TRANSCEIVER' => { 'PRESENCEDETECTOR_TRANSCEIVER' => {
'on' => 'V:PRESENCE_DETECTION_ACTIVE:1', 'detection' => 'V:PRESENCE_DETECTION_ACTIVE:#detection=inactive,active',
'off' => 'V:PRESENCE_DETECTION_ACTIVE:0',
'reset' => 'V:RESET_PRESENCE:1' 'reset' => 'V:RESET_PRESENCE:1'
}, },
'SMOKE_DETECTOR' => { 'SMOKE_DETECTOR' => {
@ -351,11 +361,16 @@ $HMCCU_CONFIG_VERSION = '4.8.025';
'SHUTTER_CONTACT_TRANSCEIVER' => { 'SHUTTER_CONTACT_TRANSCEIVER' => {
'_none_' => '' '_none_' => ''
}, },
'MOTION_DETECTOR' => {
'_none_' => ''
},
'MOTIONDETECTOR_TRANSCEIVER' => { 'MOTIONDETECTOR_TRANSCEIVER' => {
'cmdIcon' => 'on:general_an off:general_aus' 'cmdIcon' => 'reset:rc_BACK',
'webCmd' => 'detection:reset'
}, },
'PRESENCEDETECTOR_TRANSCEIVER' => { 'PRESENCEDETECTOR_TRANSCEIVER' => {
'cmdIcon' => 'on:general_an off:general_aus' 'cmdIcon' => 'reset:rc_BACK',
'webCmd' => 'detection:reset'
}, },
'KEY' => { 'KEY' => {
'event-on-update-reading' => 'PRESS.*', 'event-on-update-reading' => 'PRESS.*',
@ -426,6 +441,9 @@ $HMCCU_CONFIG_VERSION = '4.8.025';
'cmdIcon' => 'on:general_an off:general_aus', 'cmdIcon' => 'on:general_an off:general_aus',
'webCmd' => 'desired-temp:on:off', 'webCmd' => 'desired-temp:on:off',
'widgetOverride' => 'desired-temp:slider,4.5,0.5,30.5,1' 'widgetOverride' => 'desired-temp:slider,4.5,0.5,30.5,1'
},
'CLIMATECONTROL_VENT_DRIVE' => {
'_none_' => ''
} }
); );
@ -438,12 +456,16 @@ $HMCCU_CONFIG_VERSION = '4.8.025';
###################################################################### ######################################################################
%HMCCU_CONVERSIONS = ( %HMCCU_CONVERSIONS = (
'MOTION_DETECTOR' => {
'MOTION' => { '0' => 'noMotion', 'false' => 'noMotion', '1' => 'motion', 'true' => 'motion' }
},
'MOTIONDETECTOR_TRANSCEIVER' => { 'MOTIONDETECTOR_TRANSCEIVER' => {
'MOTION' => { '0' => 'noMotion', 'false' => 'noMotion', '1' => 'motion', 'true' => 'motion' }, 'MOTION' => { '0' => 'noMotion', 'false' => 'noMotion', '1' => 'motion', 'true' => 'motion' },
'MOTION_DETECTION_ACTIVE' => { '0' => 'inactive', 'false' => 'inactive', '1' => 'active', 'true', 'active' }
}, },
'PRESENCEDETECTOR_TRANSCEIVER' => { 'PRESENCEDETECTOR_TRANSCEIVER' => {
'PRESENCE_DETECTION_STATE' => { '0' => 'noPresence', 'false' => 'noPresence', '1' => 'presence', 'true' => 'presence' }, 'PRESENCE_DETECTION_STATE' => { '0' => 'noPresence', 'false' => 'noPresence', '1' => 'presence', 'true' => 'presence' },
'PRESENCE_DETECTION_ACTIVE' => { '0' => 'off', 'false' => 'off', '1' => 'on', 'true', 'on' } 'PRESENCE_DETECTION_ACTIVE' => { '0' => 'inactive', 'false' => 'inactive', '1' => 'active', 'true', 'active' }
}, },
'KEY' => { 'KEY' => {
'PRESS_SHORT' => { '1' => 'pressed', 'true' => 'pressed' }, 'PRESS_SHORT' => { '1' => 'pressed', 'true' => 'pressed' },

View File

@ -1,5 +1,5 @@
UPD 2021-04-09_14:16:13 102657 FHEM/88_HMCCURPCPROC.pm UPD 2021-04-16_11:55:59 102657 FHEM/88_HMCCURPCPROC.pm
UPD 2021-04-09_14:16:13 80676 FHEM/HMCCUConf.pm UPD 2021-04-16_11:55:50 81576 FHEM/HMCCUConf.pm
UPD 2021-04-09_14:16:13 42605 FHEM/88_HMCCUCHN.pm UPD 2021-04-16_11:55:30 42683 FHEM/88_HMCCUCHN.pm
UPD 2021-04-09_14:16:13 331948 FHEM/88_HMCCU.pm UPD 2021-04-16_11:55:22 335317 FHEM/88_HMCCU.pm
UPD 2021-04-09_14:16:13 31582 FHEM/88_HMCCUDEV.pm UPD 2021-04-16_11:55:38 31630 FHEM/88_HMCCUDEV.pm