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

HMCCU: 4.4 Beta RC 6

git-svn-id: https://svn.fhem.de/fhem/trunk@24598 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
zap 2021-06-07 16:59:15 +00:00
parent 268ae36376
commit 0a3e1643f7
5 changed files with 325 additions and 112 deletions

View File

@ -1,8 +1,9 @@
- bugfix: 88_HMCCU.pm: Release candidate 6
- bugfix: 88_HMCCU.pm: Release candidate 5 - bugfix: 88_HMCCU.pm: Release candidate 5
- bugfix: 88_HMCCU.pm: Release candidate 4 - bugfix: 88_HMCCU.pm: Release candidate 4
- bugfix: 88_HMCCU.pm: Release candidate 3 - bugfix: 88_HMCCU.pm: Release candidate 3
- bugfix: 88_HMCCU.pm: Release candidate 2 - bugfix: 88_HMCCU.pm: Release candidate 2
- bugfix: 88_HMCCU.pm: Fixed bug in set defaults command - bugfix: 88_HMCCU.pm: Fixed bug in set defaults command
- bugfix: 88_HMCCU.pm: Fixed state/controldatapoint bug during FHEM 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 some bugs. New command set readingFilter
- bugfix: 88_HMCCU.pm: Fixed device detection bugs - 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 $ # $Id: 88_HMCCU.pm 18745 2019-02-26 17:33:23Z zap $
# #
# Version 4.4.068 # Version 4.4.069
# #
# 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.068'; my $HMCCU_VERSION = '4.4.069';
# Timeout for CCU requests (seconds) # Timeout for CCU requests (seconds)
my $HMCCU_TIMEOUT_REQUEST = 4; my $HMCCU_TIMEOUT_REQUEST = 4;
@ -245,7 +245,10 @@ sub HMCCU_AddDeviceModel ($$$$$$);
sub HMCCU_AddPeers ($$$); sub HMCCU_AddPeers ($$$);
sub HMCCU_CheckParameter ($$;$$$); sub HMCCU_CheckParameter ($$;$$$);
sub HMCCU_DetectDevice ($$$); sub HMCCU_DetectDevice ($$$);
sub HMCCU_CreateFHEMDevices ($@);
sub HMCCU_CreateDevice ($@);
sub HMCCU_IdentifyRole ($$$$$); sub HMCCU_IdentifyRole ($$$$$);
sub HMCCU_DetectRolePattern ($;$$$$);
sub HMCCU_GetSCInfo ($$;$); sub HMCCU_GetSCInfo ($$;$);
sub HMCCU_DeviceDescToStr ($$); sub HMCCU_DeviceDescToStr ($$);
sub HMCCU_ExecuteRoleCommand ($@); sub HMCCU_ExecuteRoleCommand ($@);
@ -260,6 +263,7 @@ sub HMCCU_DisplayWeekProgram ($$$;$$);
sub HMCCU_ExistsDeviceModel ($$$;$); sub HMCCU_ExistsDeviceModel ($$$;$);
sub HMCCU_FindParamDef ($$$); sub HMCCU_FindParamDef ($$$);
sub HMCCU_FormatDeviceInfo ($); sub HMCCU_FormatDeviceInfo ($);
sub HMCCU_FormatHashTable ($);
sub HMCCU_GetAddress ($$;$$); sub HMCCU_GetAddress ($$;$$);
sub HMCCU_GetAffectedAddresses ($); sub HMCCU_GetAffectedAddresses ($);
sub HMCCU_GetCCUDeviceParam ($$); sub HMCCU_GetCCUDeviceParam ($$);
@ -1644,9 +1648,12 @@ sub HMCCU_Get ($@)
my $options = "create createDev defaults:noArg exportDefaults dutycycle:noArg vars update". my $options = "create createDev defaults:noArg exportDefaults dutycycle:noArg vars update".
" updateCCU paramsetDesc firmware rpcEvents:noArg rpcState:noArg deviceInfo". " updateCCU paramsetDesc firmware rpcEvents:noArg rpcState:noArg deviceInfo".
" ccuMsg:alarm,service ccuConfig:noArg ccuDevices:noArg"; " ccuMsg:alarm,service ccuConfig:noArg ccuDevices:noArg".
" internal:groups,interfaces";
if (defined($hash->{hmccu}{ccuSuppDevList}) && $hash->{hmccu}{ccuSuppDevList} ne '') {
$options =~ s/createDev/createDev:$hash->{hmccu}{ccuSuppDevList}/;
}
if (defined($hash->{hmccu}{ccuDevList}) && $hash->{hmccu}{ccuDevList} ne '') { if (defined($hash->{hmccu}{ccuDevList}) && $hash->{hmccu}{ccuDevList} ne '') {
$options =~ s/createDev/createDev:$hash->{hmccu}{ccuDevList}/;
$options =~ s/deviceInfo/deviceInfo:$hash->{hmccu}{ccuDevList}/; $options =~ s/deviceInfo/deviceInfo:$hash->{hmccu}{ccuDevList}/;
$options =~ s/paramsetDesc/paramsetDesc:$hash->{hmccu}{ccuDevList}/; $options =~ s/paramsetDesc/paramsetDesc:$hash->{hmccu}{ccuDevList}/;
} }
@ -1742,7 +1749,8 @@ sub HMCCU_Get ($@)
HMCCU_ResetDeviceTables ($hash); HMCCU_ResetDeviceTables ($hash);
my ($cDev, $cPar, $cLnk) = HMCCU_GetDeviceConfig ($hash); my ($cDev, $cPar, $cLnk) = HMCCU_GetDeviceConfig ($hash);
return "Devices: $devcount, Channels: $chncount\nDevice descriptions: $cDev\n". return "Devices: $devcount, Channels: $chncount\nDevice descriptions: $cDev\n".
"Paramset descriptions: $cPar\nLinks/Peerings: $cLnk"; "Paramset descriptions: $cPar\nLinks/Peerings: $cLnk\n".
"Interfaces: $ifcount\nPrograms: $prgcount\nVirtual groups: $gcount";
} }
elsif ($opt eq 'create' || $opt eq 'createdev') { elsif ($opt eq 'create' || $opt eq 'createdev') {
$usage = $opt eq 'createdev' ? $usage = $opt eq 'createdev' ?
@ -1756,11 +1764,11 @@ sub HMCCU_Get ($@)
my $devSuffix = $h->{'s'} // ''; # Suffix of FHEM device name my $devSuffix = $h->{'s'} // ''; # Suffix of FHEM device name
my $devFormat = $h->{'f'} // '%n'; # Format string for FHEM device name my $devFormat = $h->{'f'} // '%n'; # Format string for FHEM device name
my @options = (); my @options = ();
my ($forceDev, $saveDef) = (0, 0); my $saveDef = 0;
foreach my $defOpt (@$a) { foreach my $defOpt (@$a) {
if (lc($defOpt) eq 'nodefaults') { push @options, 'noDefaults'; } if (lc($defOpt) eq 'nodefaults') { push @options, 'noDefaults'; }
elsif (lc($defOpt) eq 'save') { $saveDef = 1; } elsif (lc($defOpt) eq 'save') { $saveDef = 1; }
elsif (lc($defOpt) eq 'forcedev') { push @options, 'forceDev'; $forceDev = 1; } elsif (lc($defOpt) eq 'forcedev') { push @options, 'forceDev'; }
else { return HMCCU_SetError ($hash, $usage); } else { return HMCCU_SetError ($hash, $usage); }
} }
$devSpec = '^'.$devSpec.'$' if ($opt eq 'createdev'); $devSpec = '^'.$devSpec.'$' if ($opt eq 'createdev');
@ -1770,6 +1778,8 @@ sub HMCCU_Get ($@)
my %ah = (); my %ah = ();
foreach my $da (keys %$h) { $ah{$da} = $h->{$da} if ($da !~ /^[psf]$/); } foreach my $da (keys %$h) { $ah{$da} = $h->{$da} if ($da !~ /^[psf]$/); }
my $cs = HMCCU_CreateFHEMDevices ($hash, $devSpec, $devPrefix, $devSuffix, $devFormat, $defOpts, \%ah);
# Statistics # Statistics
# #
# {statsValue}{devName} = addr.ccuName # {statsValue}{devName} = addr.ccuName
@ -1781,71 +1791,9 @@ sub HMCCU_Get ($@)
# {defFailed}{$fhemDevName}: Device definition failed # {defFailed}{$fhemDevName}: Device definition failed
# {defSuccess}{$fhemDevName}: Device defined # {defSuccess}{$fhemDevName}: Device defined
# {attrFailed}{$fhemDevName.$attr}: Attribute setting failed # {attrFailed}{$fhemDevName.$attr}: Attribute setting failed
my %cs;
foreach my $iface (keys %{$hash->{hmccu}{device}}) {
foreach my $address (keys %{$hash->{hmccu}{device}{$iface}}) {
my $ccuName = $hash->{hmccu}{device}{$iface}{$address}{_name};
next if ($hash->{hmccu}{device}{$iface}{$address}{_addtype} ne 'dev' ||
HMCCU_ExprNotMatch ($ccuName, $devSpec, 1));
if ($hash->{hmccu}{device}{$iface}{$address}{_model} =~ /^(HM-RCV-50|HmIP-RCV-50)$/) {
$cs{notSupported}{$ccuName} = "$address [$ccuName]";
next;
}
# Detect FHEM device type
my $detect = HMCCU_DetectDevice ($hash, $address, $iface);
if (!defined($detect) || $detect->{level} == 0) {
$cs{notDetected}{$ccuName} = "$address [$ccuName]";
next;
}
my $defMod = $detect->{defMod};
my $defAdd = $detect->{defAdd};
# Build FHEM device name
my $devName = HMCCU_MakeDeviceName ($defAdd, $devPrefix, $devFormat, $devSuffix, $ccuName);
if ($detect->{level} == 1) {
# Simple HMCCUCHN device
HMCCU_CreateDevice ($hash, $ccuName, $devName, $defMod, $defAdd, $defOpts, \%ah, \%cs);
}
elsif ($detect->{level} == 2) {
# Multiple identical channels
if ($forceDev) {
# Force creation of HMCCUDEV
$ah{statedatapoint} = $detect->{defSDP} if ($detect->{defSCh} != -1 && $detect->{stateRoleCount} > 1);
$ah{controldatapoint} = $detect->{defCDP} if ($detect->{defCCh} != -1 && $detect->{controlRoleCount} > 1);
HMCCU_CreateDevice ($hash, $ccuName, $devName, 'HMCCUDEV', $defAdd, $defOpts, \%ah, \%cs);
}
else {
# Create a HMCCUCHN for each channel
if ($detect->{controlRoleCount} > 0) {
# First create a HMCCUCHN for each control channel
foreach my $cc (keys %{$detect->{controlRole}}) {
HMCCU_CreateDevice ($hash, $ccuName, $devName.'_'.$cc, $defMod, "$defAdd:$cc", $defOpts, \%ah, \%cs);
}
}
# Create a HMCCUCHN for each channel without control datapoint
foreach my $sc (keys %{$detect->{stateRole}}) {
if (!exists($detect->{controlRole}{$sc})) {
HMCCU_CreateDevice ($hash, $ccuName, $devName.'_'.$sc, $defMod, "$defAdd:$sc", $defOpts, \%ah, \%cs);
}
}
}
}
elsif ($detect->{level} == 3 || $detect->{level} == 4) {
# Multiple roles
$ah{statedatapoint} = $detect->{defSDP} if ($detect->{defSCh} != -1 && $detect->{stateRoleCount} > 1);
$ah{controldatapoint} = $detect->{defCDP} if ($detect->{defCCh} != -1 && $detect->{controlRoleCount} > 1);
HMCCU_CreateDevice ($hash, $ccuName, $devName, $defMod, $defAdd, $defOpts, \%ah, \%cs);
}
}
}
# Save FHEM config # Save FHEM config
CommandSave (undef, undef) if (scalar(keys %{$cs{defSuccess}}) > 0 && $saveDef); CommandSave (undef, undef) if (scalar(keys %{$cs->{defSuccess}}) > 0 && $saveDef);
# Prepare summary # Prepare summary
my %csText = ( my %csText = (
@ -1859,7 +1807,7 @@ sub HMCCU_Get ($@)
); );
$result = "Results of create command:"; $result = "Results of create command:";
foreach my $sk (keys %csText) { foreach my $sk (keys %csText) {
$result .= "\n$csText{$sk}\n".join('', map { " $_ = $cs{$sk}{$_}\n" } keys %{$cs{$sk}}) if (scalar(keys %{$cs{$sk}}) > 0); $result .= "\n$csText{$sk}\n".join('', map { " $_ = $cs->{$sk}{$_}\n" } keys %{$cs->{$sk}}) if (scalar(keys %{$cs->{$sk}}) > 0);
} }
return HMCCU_SetState ($hash, 'OK', $result); return HMCCU_SetState ($hash, 'OK', $result);
@ -1958,6 +1906,22 @@ sub HMCCU_Get ($@)
return HMCCU_SetState ($hash, 'OK', $res); return HMCCU_SetState ($hash, 'OK', $res);
} }
elsif ($opt eq 'internal') {
my $parameter = shift @$a // return HMCCU_SetError ($hash, "Usage: get $name $opt {internalParameter}");
if ($parameter eq 'groups') {
return exists($hash->{hmccu}{grp}) && scalar(keys %{$hash->{hmccu}{grp}}) > 0 ?
'<html>'.HMCCU_FormatHashTable ($hash->{hmccu}{grp}).'</html>' :
'No virtual groups found';
}
elsif ($parameter eq 'interfaces') {
return exists($hash->{hmccu}{interfaces}) && scalar(keys %{$hash->{hmccu}{interfaces}}) > 0 ?
'<html>'.HMCCU_FormatHashTable ($hash->{hmccu}{interfaces}).'</html>' :
'No interfaces found';
}
else {
return HMCCU_SetError ($hash, "Invalid internal parameter $parameter");
}
}
else { else {
if (exists ($hash->{hmccu}{agg})) { if (exists ($hash->{hmccu}{agg})) {
my @rules = keys %{$hash->{hmccu}{agg}}; my @rules = keys %{$hash->{hmccu}{agg}};
@ -3146,6 +3110,95 @@ sub HMCCU_ResetDeviceTables ($;$$)
} }
} }
######################################################################
# Create FHEM device(s) for CCU device(s)
######################################################################
sub HMCCU_CreateFHEMDevices ($@)
{
my ($hash, $devSpec, $devPrefix, $devSuffix, $devFormat, $defOpts, $ah) = @_;
# Statistics
#
# {statsValue}{devName} = addr.ccuName
#
# {notDetected}{$ccuDevName}: CCU device with $devName not detected
# {notSupported}{$ccuDevName}: CCU device type is not supported by create commands
# {fhemExists}{$fhemDevName}: FHEM device with $devName already exists
# {devDefined}{$fhemDevName}: FHEM device for $devAdd already exists
# {defFailed}{$fhemDevName}: Device definition failed
# {defSuccess}{$fhemDevName}: Device defined
# {attrFailed}{$fhemDevName.$attr}: Attribute setting failed
my %cs = ();
foreach my $iface (keys %{$hash->{hmccu}{device}}) {
foreach my $address (keys %{$hash->{hmccu}{device}{$iface}}) {
my $ccuName = $hash->{hmccu}{device}{$iface}{$address}{_name};
next if ($hash->{hmccu}{device}{$iface}{$address}{_addtype} ne 'dev' ||
HMCCU_ExprNotMatch ($ccuName, $devSpec, 1));
if ($hash->{hmccu}{device}{$iface}{$address}{_model} =~ /^(HM-RCV-50|HmIP-RCV-50)$/) {
$cs{notSupported}{$ccuName} = "$address [$ccuName]";
next;
}
# Detect FHEM device type
my $detect = HMCCU_DetectDevice ($hash, $address, $iface);
if (!defined($detect) || $detect->{level} == 0) {
$cs{notDetected}{$ccuName} = "$address [$ccuName]";
next;
}
my $defMod = $detect->{defMod};
my $defAdd = $detect->{defAdd};
# Build FHEM device name
my $devName = HMCCU_MakeDeviceName ($defAdd, $devPrefix, $devFormat, $devSuffix, $ccuName);
if ($detect->{level} == 1) {
# Simple HMCCUCHN device
HMCCU_CreateDevice ($hash, $ccuName, $devName, $defMod, $defAdd, $defOpts, $ah, \%cs);
}
elsif ($detect->{level} == 2) {
# Multiple identical channels
if ($defOpts =~ /forcedev/i) {
# Force creation of HMCCUDEV
$ah->{statedatapoint} = $detect->{defSDP} if ($detect->{defSCh} != -1 && $detect->{stateRoleCount} > 1);
$ah->{controldatapoint} = $detect->{defCDP} if ($detect->{defCCh} != -1 && $detect->{controlRoleCount} > 1);
HMCCU_CreateDevice ($hash, $ccuName, $devName, 'HMCCUDEV', $defAdd, $defOpts, $ah, \%cs);
}
else {
# Create a HMCCUCHN for each channel
if ($detect->{controlRoleCount} > 0) {
# First create a HMCCUCHN for each control channel
foreach my $cc (keys %{$detect->{controlRole}}) {
my $ccuChnName = $hash->{hmccu}{device}{$iface}{"$address:$cc"}{_name};
my $devChnName = HMCCU_MakeDeviceName ($defAdd, $devPrefix, $devFormat, $devSuffix, $ccuChnName);
HMCCU_CreateDevice ($hash, $ccuChnName, $devChnName, $defMod, "$defAdd:$cc", $defOpts, $ah, \%cs);
}
}
# Create a HMCCUCHN for each channel without control datapoint
foreach my $sc (keys %{$detect->{stateRole}}) {
if (!exists($detect->{controlRole}{$sc})) {
my $ccuChnName = $hash->{hmccu}{device}{$iface}{"$address:$sc"}{_name};
my $devChnName = HMCCU_MakeDeviceName ($defAdd, $devPrefix, $devFormat, $devSuffix, $ccuChnName);
HMCCU_CreateDevice ($hash, $ccuChnName, $devChnName, $defMod, "$defAdd:$sc", $defOpts, $ah, \%cs);
}
}
}
}
elsif ($detect->{level} == 3 || $detect->{level} == 4) {
# Multiple roles
$ah->{statedatapoint} = $detect->{defSDP} if ($detect->{defSCh} != -1 && $detect->{stateRoleCount} > 1);
$ah->{controldatapoint} = $detect->{defCDP} if ($detect->{defCCh} != -1 && $detect->{controlRoleCount} > 1);
HMCCU_CreateDevice ($hash, $ccuName, $devName, $defMod, $defAdd, $defOpts, $ah, \%cs);
}
}
}
return \%cs;
}
###################################################################### ######################################################################
# Create a new FHEM HMCCUCHN or HMCCUDEV device # Create a new FHEM HMCCUCHN or HMCCUDEV device
# Parameters: # Parameters:
@ -3167,7 +3220,7 @@ sub HMCCU_ResetDeviceTables ($;$$)
# {attrFailed}{$devName.$attr}: Attribute setting failed # {attrFailed}{$devName.$attr}: Attribute setting failed
###################################################################### ######################################################################
sub HMCCU_CreateDevice ($$$$$$$$) sub HMCCU_CreateDevice ($@)
{ {
my ($hash, $ccuName, $devName, $defMod, $defAdd, $defOpts, $ah, $cs) = @_; my ($hash, $ccuName, $devName, $defMod, $defAdd, $defOpts, $ah, $cs) = @_;
@ -3220,7 +3273,7 @@ sub HMCCU_MakeDeviceName ($$$$$)
my $devName = $devPrefix.$devFormat.$devSuffix; my $devName = $devPrefix.$devFormat.$devSuffix;
$devName =~ s/%n/$ccuName/g; $devName =~ s/%n/$ccuName/g;
$devName =~ s/%a/$defAdd/g; $devName =~ s/%a/$defAdd/g;
$devName =~ s/[^A-Za-z\d_\.]+/_/g; $devName =~ s/[^A-Za-z\d_\. ]+/_/g;
return $devName; return $devName;
} }
@ -3603,18 +3656,33 @@ sub HMCCU_GetDeviceConfig ($)
} }
my @ccuDevList = (); my @ccuDevList = ();
my @ccuSuppDevList = ();
my @ccuSuppTypes = ();
my @ccuNotSuppTypes = ();
foreach my $di (sort keys %{$ioHash->{hmccu}{device}}) { foreach my $di (sort keys %{$ioHash->{hmccu}{device}}) {
foreach my $da (sort keys %{$ioHash->{hmccu}{device}{$di}}) { foreach my $da (sort keys %{$ioHash->{hmccu}{device}{$di}}) {
next if ($ioHash->{hmccu}{device}{$di}{$da}{_addtype} ne 'dev'); next if ($ioHash->{hmccu}{device}{$di}{$da}{_addtype} ne 'dev');
my $devName = $ioHash->{hmccu}{device}{$di}{$da}{_name}; my $devName = $ioHash->{hmccu}{device}{$di}{$da}{_name};
my $devModel = $ioHash->{hmccu}{device}{$di}{$da}{_model};
if ($devName =~ / /) { if ($devName =~ / /) {
$devName = qq("$devName"); $devName = qq("$devName");
$devName =~ s/ /#/g; $devName =~ s/ /#/g;
} }
push @ccuDevList, $devName; push @ccuDevList, $devName;
my $detect = HMCCU_DetectDevice ($ioHash, $da, $di);
if (defined($detect) && $da ne 'HmIP-RCV-1' && $da ne 'BidCoS-RF') {
push @ccuSuppDevList, $devName;
push @ccuSuppTypes, $devModel;
}
else {
push @ccuNotSuppTypes, $devModel;
}
} }
} }
$ioHash->{hmccu}{ccuDevList} = join(',', sort @ccuDevList); $ioHash->{hmccu}{ccuDevList} = join(',', sort @ccuDevList);
$ioHash->{hmccu}{ccuSuppDevList} = join(',', sort @ccuSuppDevList);
$ioHash->{hmccu}{ccuTypes}{supported} = join(',', sort @ccuSuppTypes);
$ioHash->{hmccu}{ccuTypes}{unsupported} = join(',', sort @ccuNotSuppTypes);
# Set CCU firmware version # Set CCU firmware version
if (exists($ioHash->{hmccu}{device}{'BidCos-RF'}) && exists($ioHash->{hmccu}{device}{'BidCos-RF'}{'BidCoS-RF'})) { if (exists($ioHash->{hmccu}{device}{'BidCos-RF'}) && exists($ioHash->{hmccu}{device}{'BidCos-RF'}{'BidCoS-RF'})) {
@ -4370,7 +4438,7 @@ sub HMCCU_UpdateParamsetReadings ($$$;$)
my @addList = defined ($addListRef) ? @$addListRef : ($devAddr); my @addList = defined ($addListRef) ? @$addListRef : ($devAddr);
# Determine virtual device flag # Determine virtual device flag
my $vg = ($clHash->{ccuif} eq 'VirtualDevices' && exists($clHash->{ccugroup})) ? 1 : 0; my $vg = ($clHash->{ccuif} eq 'VirtualDevices' && exists($clHash->{ccugroup}) && $clHash->{ccugroup} ne '') ? 1 : 0;
# Get client device attributes # Get client device attributes
my $clFlags = HMCCU_GetFlags ($clName); my $clFlags = HMCCU_GetFlags ($clName);
@ -4621,7 +4689,7 @@ sub HMCCU_GetAffectedAddresses ($)
my ($devaddr, $cnum) = HMCCU_SplitChnAddr ($clHash->{ccuaddr}); my ($devaddr, $cnum) = HMCCU_SplitChnAddr ($clHash->{ccuaddr});
push @addlist, $devaddr; push @addlist, $devaddr;
} }
if ($clHash->{ccuif} eq 'VirtualDevices' && $ccuFlags =~ /updGroupMembers/ && exists($clHash->{ccugroup})) { if ($clHash->{ccuif} eq 'VirtualDevices' && $ccuFlags =~ /updGroupMembers/ && exists($clHash->{ccugroup}) && $clHash->{ccugroup} ne '') {
push @addlist, split (',', $clHash->{ccugroup}); push @addlist, split (',', $clHash->{ccugroup});
} }
} }
@ -4879,8 +4947,8 @@ sub HMCCU_StartExtRPCServer ($)
my $interfaces = HMCCU_GetRPCInterfaceList ($hash, 1); my $interfaces = HMCCU_GetRPCInterfaceList ($hash, 1);
my @iflist = keys %$interfaces; my @iflist = keys %$interfaces;
foreach my $ifname1 (@iflist) { foreach my $ifname1 (@iflist) {
HMCCU_Log ($hash, 2, "Get RPC device for interface $ifname1");
my ($rpcdev, $save) = HMCCU_GetRPCDevice ($hash, 1, $ifname1); my ($rpcdev, $save) = HMCCU_GetRPCDevice ($hash, 1, $ifname1);
HMCCU_Log ($hash, 2, "RPC device for interface $ifname1: ".($rpcdev eq '' ? 'not found' : $rpcdev));
next if ($rpcdev eq '' || !defined ($hash->{hmccu}{interfaces}{$ifname1}{device})); next if ($rpcdev eq '' || !defined ($hash->{hmccu}{interfaces}{$ifname1}{device}));
$d++; $d++;
$s++ if ($save); $s++ if ($save);
@ -5059,6 +5127,42 @@ sub HMCCU_FormatDeviceInfo ($)
return $result; return $result;
} }
######################################################################
# Format a hash as HTML table
# {row1}{col1} = Value12
# {row1}{col2} = Value12
# {row2}{col1} = Value21
# ...
######################################################################
sub HMCCU_FormatHashTable ($)
{
my ($hash) = @_;
my $t = 0;
my $result = '';
foreach my $row (sort keys %$hash) {
if ($t == 0) {
# Begin of table with header
$result .= '<table border="1">\n<tr>';
$result .= '<th>Key</th>';
foreach my $col (sort keys %{$hash->{$row}}) {
$result .= "<th>$col</th>";
}
$result .= "</tr>\n";
$t = 1;
}
$result .= "<tr><td>$row</td>";
foreach my $col (sort keys %{$hash->{$row}}) {
$result .= "<td>$hash->{$row}{$col}</td>";
}
$result .= "</tr>\n";
}
$result .= '</table>';
return $result;
}
###################################################################### ######################################################################
# Get available firmware versions from EQ-3 server. # Get available firmware versions from EQ-3 server.
# Firmware version, date and download link are stored in hash # Firmware version, date and download link are stored in hash
@ -5262,6 +5366,7 @@ sub HMCCU_GetDeviceList ($)
$hash->{ccustate} = 'active'; $hash->{ccustate} = 'active';
# Delete old entries # Delete old entries
HMCCU_Log ($hash, 2, "Deleting old groups");
%{$hash->{hmccu}{dev}} = (); %{$hash->{hmccu}{dev}} = ();
%{$hash->{hmccu}{adr}} = (); %{$hash->{hmccu}{adr}} = ();
%{$hash->{hmccu}{interfaces}} = (); %{$hash->{hmccu}{interfaces}} = ();
@ -5415,6 +5520,9 @@ sub HMCCU_GetDeviceList ($)
$gcount++; $gcount++;
} }
} }
else {
HMCCU_Log ($hash, 1, "Can't read virtual groups from CCU. Response: $groups");
}
# Store asset counters # Store asset counters
$hash->{hmccu}{ccu}{devcount} = $devcount; $hash->{hmccu}{ccu}{devcount} = $devcount;
@ -7073,20 +7181,20 @@ sub HMCCU_ExecuteGetDeviceInfoCommand ($@)
my ($ioHash, $clHash, $address, $extended) = @_; my ($ioHash, $clHash, $address, $extended) = @_;
$extended //= 0; $extended //= 0;
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 ($sc, $sd, $cc, $cd) = HMCCU_GetSCDatapoints ($clHash); my ($sc, $sd, $cc, $cd) = HMCCU_GetSCDatapoints ($clHash);
my $devInfo = '<html><b>Device channels and datapoints</b><br/><br/><pre>'; my $devInfo = '<html><b>Device channels and datapoints</b><br/><br/>';
$devInfo .= '</pre>'; $devInfo .= '<pre>';
$devInfo .= HMCCU_FormatDeviceInfo ($result); $devInfo .= HMCCU_FormatDeviceInfo ($result);
$devInfo .= '</pre>';
my $detect = HMCCU_DetectDevice ($ioHash, $address, $iface); my $detect = HMCCU_DetectDevice ($ioHash, $address, $iface);
if (defined($detect)) { if (defined($detect)) {
$devInfo .= "<br/>Device detection:<br/>"; $devInfo .= "<br/>Device detection:<br/>";
if ($detect->{stateRoleCount} > 0) { if ($detect->{stateRoleCount} > 0) {
foreach my $c (keys %{$detect->{stateRole}}) { foreach my $c (sort keys %{$detect->{stateRole}}) {
my $stateChn = $detect->{stateRole}{$c}; my $stateChn = $detect->{stateRole}{$c};
$devInfo .= "StateDatapoint = $c.$stateChn->{datapoint} [$stateChn->{role}]<br/>"; $devInfo .= "StateDatapoint = $c.$stateChn->{datapoint} [$stateChn->{role}]<br/>";
} }
@ -7095,7 +7203,7 @@ sub HMCCU_ExecuteGetDeviceInfoCommand ($@)
$devInfo .= 'No state datapoint detected<br/>'; $devInfo .= 'No state datapoint detected<br/>';
} }
if ($detect->{controlRoleCount} > 0) { if ($detect->{controlRoleCount} > 0) {
foreach my $c (keys %{$detect->{controlRole}}) { foreach my $c (sort keys %{$detect->{controlRole}}) {
my $ctrlChn = $detect->{controlRole}{$c}; my $ctrlChn = $detect->{controlRole}{$c};
$devInfo .= "ControlDatapoint = $c.$ctrlChn->{datapoint} [$ctrlChn->{role}]<br/>"; $devInfo .= "ControlDatapoint = $c.$ctrlChn->{datapoint} [$ctrlChn->{role}]<br/>";
} }
@ -7667,7 +7775,7 @@ sub HMCCU_DetectSCDev ($;$$$$)
# 3 = device detected with multiple channels with different known # 3 = device detected with multiple channels with different known
# roles (i.e. roles KEY and THERMALCONTROL) => HMCCUDEV # roles (i.e. roles KEY and THERMALCONTROL) => HMCCUDEV
# 4 = device type detected with different state and control role # 4 = device type detected with different state and control role
# (2 different channels) => HMCCUDEV # (>=2 different channels) => HMCCUDEV
# #
# Structure of stateRole / controlRole hashes: # Structure of stateRole / controlRole hashes:
# int <channel>: Channel number # int <channel>: Channel number
@ -7680,6 +7788,7 @@ sub HMCCU_DetectDevice ($$$)
{ {
my ($ioHash, $address, $iface) = @_; my ($ioHash, $address, $iface) = @_;
my @allRoles = ();
my @stateRoles = (); my @stateRoles = ();
my @controlRoles = (); my @controlRoles = ();
my ($prioState, $prioControl) = (-1, -1); my ($prioState, $prioControl) = (-1, -1);
@ -7695,6 +7804,7 @@ sub HMCCU_DetectDevice ($$$)
if ($devDesc->{_addtype} eq 'dev') { if ($devDesc->{_addtype} eq 'dev') {
foreach my $child (split(',', $devDesc->{CHILDREN})) { foreach my $child (split(',', $devDesc->{CHILDREN})) {
$devDesc = HMCCU_GetDeviceDesc ($ioHash, $child, $devDesc->{_interface}) // next; $devDesc = HMCCU_GetDeviceDesc ($ioHash, $child, $devDesc->{_interface}) // next;
push @allRoles, $devDesc->{TYPE};
HMCCU_IdentifyRole ($ioHash, $devDesc, $iface, \@stateRoles, \@controlRoles); HMCCU_IdentifyRole ($ioHash, $devDesc, $iface, \@stateRoles, \@controlRoles);
} }
} }
@ -7742,14 +7852,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, but no controldatapoint (read only) => HMCCUCHN # Type 1: 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, but no statedatapoint (write only) => HMCCUCHN # Type 1: 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}";
@ -7759,13 +7869,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 (read + write)=> HMCCUCHN # Type 1: 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 (read + write) => HMCCUDEV # Type 4: 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;
@ -7779,7 +7889,7 @@ sub HMCCU_DetectDevice ($$$)
$cntUniqStateRoles == 1 && $cntUniqCtrlRoles == 1 && $stateRoles[0]->{role} eq $controlRoles[0]->{role} $cntUniqStateRoles == 1 && $cntUniqCtrlRoles == 1 && $stateRoles[0]->{role} eq $controlRoles[0]->{role}
) )
) { ) {
# Device with multiple identical channels # Type 2: Device with multiple identical channels
$di{defSCh} = $cntUniqStateRoles == 1 ? $stateRoles[0]->{channel} : -1; $di{defSCh} = $cntUniqStateRoles == 1 ? $stateRoles[0]->{channel} : -1;
$di{defCCh} = $cntUniqCtrlRoles == 1 ? $controlRoles[0]->{channel} : -1; $di{defCCh} = $cntUniqCtrlRoles == 1 ? $controlRoles[0]->{channel} : -1;
$di{defMod} = 'HMCCUCHN'; $di{defMod} = 'HMCCUCHN';
@ -7787,10 +7897,37 @@ sub HMCCU_DetectDevice ($$$)
$di{level} = 2; $di{level} = 2;
} }
else { else {
# Device with multiple different channels, default channels depend on role priority # Type 3: Device with multiple different channels
$di{defMod} = 'HMCCUDEV'; $di{defMod} = 'HMCCUDEV';
$di{defAdd} = $devAdd; $di{defAdd} = $devAdd;
$di{level} = 3; $di{level} = 3;
# Try to find channel role pattern with 4 channels.
# If no pattern can be found, default channels depend on role priorities
my $rolePatterns = HMCCU_DetectRolePattern (\@allRoles,
'^(?!([A-Z]+_VIRTUAL))([A-Z]+)[A-Z_]+(,\g2_VIRTUAL_[A-Z_]+){3}$', 4, 4);
if (defined($rolePatterns)) {
ROLEPATTERN: foreach my $rp (keys %$rolePatterns) {
my @patternRoles = split(',', $rp);
my $firstChannel = (split(',', $rolePatterns->{$rp}{i}))[0];
PATTERNROLE: foreach my $pr (@patternRoles) {
next ROLEPATTERN if (!exists($HMCCU_STATECONTROL->{$pr}));
}
# state/control channel is the first channel with a state/control datapoint
while (my ($i, $pr) = each @patternRoles) {
if ($HMCCU_STATECONTROL->{$pr}{S} ne '') {
$di{defSCh} = $firstChannel+$i;
last;
}
}
while (my ($i, $pr) = each @patternRoles) {
if ($HMCCU_STATECONTROL->{$pr}{C} ne '') {
$di{defCCh} = $firstChannel+$i;
last;
}
}
}
}
} }
} }
@ -7826,6 +7963,69 @@ sub HMCCU_IdentifyRole ($$$$$)
} }
} }
######################################################################
# Detect role patterns
#
# Parameters:
# $roles - Array reference containing a list of channel roles
# $regMatch - Regular expression describing the pattern
# $minPatternLen - Minimum number of roles in the pattern
# $maxPatternLen - Maximum number of roles in the pattern
# $minOcc - Minimum number of occurrences of the pattern
#
# Example expression for matching groups of 1 TRANSMITTER and 3
# virtual RECEIVER channels (default):
#
# '^(?!([A-Z]+_VIRTUAL))([A-Z]+)[A-Z_]+(,\g2_VIRTUAL_[A-Z_]+){3}$'
#
# Return hash reference with role patterns or undef on error.
# Role pattern hash (key = pattern):
# c - Occurrences of the pattern
# i - Comma separated list of the starting positions of the pattern
######################################################################
sub HMCCU_DetectRolePattern ($;$$$$)
{
my ($roles, $regMatch, $minPatternLen, $maxPatternLen, $minOcc) = @_;
$regMatch //= '^(?!([A-Z]+_VIRTUAL))([A-Z]+)[A-Z_]+(,\g2_VIRTUAL_[A-Z_]+){3}$';
$minPatternLen //= 2;
$minOcc //= 1;
$minOcc = HMCCU_Max ($minOcc, 1);
my $n = scalar(@$roles);
my $skip = 1;
return undef if ($n-$skip < $minPatternLen);
$maxPatternLen //= int(($n-$skip)/$minOcc);
return undef if ($maxPatternLen < $minPatternLen);
my %patternList;
for (my $i=$skip; $i<$n; $i++) {
for (my $patternLen=$minPatternLen; $patternLen<=$maxPatternLen; $patternLen++) {
my @p = ();
for (my $j=$i; $j<=$n-$patternLen; $j++) {
my $k=$j+$patternLen-1;
my $patStr = join(',',@$roles[$j..$k]);
push @p, { i => $j, p => $patStr } if ($patStr =~ /$regMatch/);
}
my $first = shift @p // next;
my $cnt = 1;
foreach my $t (@p) {
last if ($t->{p} ne $first->{p});
$cnt++;
}
if ($cnt >= $minOcc && !exists($patternList{$first->{p}})) {
unshift @p, $first;
$patternList{$first->{p}}{c} = $cnt;
$patternList{$first->{p}}{i} = join(',',map { $_->{i}; } @p);
}
}
}
return \%patternList;
}
###################################################################### ######################################################################
# Return state or control datapoint information # Return state or control datapoint information
# $mode: 0=State 1=Control # $mode: 0=State 1=Control
@ -8606,7 +8806,7 @@ sub HMCCU_GetUpdate ($$$)
# Consider members of group device # Consider members of group device
if ($type eq 'HMCCUDEV' && $clHash->{ccuif} eq 'VirtualDevices' && HMCCU_IsFlag ($ioHash, 'updGroupMembers') && if ($type eq 'HMCCUDEV' && $clHash->{ccuif} eq 'VirtualDevices' && HMCCU_IsFlag ($ioHash, 'updGroupMembers') &&
exists($clHash->{ccugroup})) { exists($clHash->{ccugroup}) && $clHash->{ccugroup} ne '') {
foreach my $gd (split (',', $clHash->{ccugroup})) { foreach my $gd (split (',', $clHash->{ccugroup})) {
$nam = HMCCU_GetDeviceName ($ioHash, $gd); $nam = HMCCU_GetDeviceName ($ioHash, $gd);
$list .= ','.$nam if ($nam ne ''); $list .= ','.$nam if ($nam ne '');

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.047 # Version 4.4.048
# #
# (c) 2021 zap (zap01 <at> t-online <dot> de) # (c) 2021 zap (zap01 <at> t-online <dot> de)
# #
@ -257,9 +257,9 @@ sub HMCCUDEV_InitDevice ($$)
$gdcount = scalar (@devlist); $gdcount = scalar (@devlist);
} }
return 3 if ($gdcount == 0); # return 3 if ($gdcount == 0);
$devHash->{ccugroup} = join (',', @devlist); $devHash->{ccugroup} = join (',', @devlist) if (scalar(@devlist) > 0);
} }
return 0; return 0;

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.028 # Version 4.8.030
# #
# 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.028'; $HMCCU_CONFIG_VERSION = '4.8.030';
###################################################################### ######################################################################
# Map subtype to default role. Subtype is only available for HMIP # Map subtype to default role. Subtype is only available for HMIP
@ -95,7 +95,7 @@ $HMCCU_CONFIG_VERSION = '4.8.028';
F => 3, S => 'PRESS_SHORT', C => 'PRESS_SHORT', V => 'pressed:true', P => 1 F => 3, S => 'PRESS_SHORT', C => 'PRESS_SHORT', V => 'pressed:true', P => 1
}, },
'KEY_TRANSCEIVER' => { 'KEY_TRANSCEIVER' => {
F => 3, S => 'PRESS_SHORT', C => 'PRESS_SHORT', V => 'pressed:true', P => 1 F => 3, S => 'PRESS_SHORT', C => '', V => '', P => 1
}, },
'VIRTUAL_KEY' => { 'VIRTUAL_KEY' => {
F => 3, S => 'PRESS_SHORT', C => 'PRESS_SHORT', V => 'pressed:true', P => 1 F => 3, S => 'PRESS_SHORT', C => 'PRESS_SHORT', V => 'pressed:true', P => 1
@ -109,6 +109,9 @@ $HMCCU_CONFIG_VERSION = '4.8.028';
'BLIND_VIRTUAL_RECEIVER' => { 'BLIND_VIRTUAL_RECEIVER' => {
F => 3, S => 'LEVEL', C => 'LEVEL', V => 'open:100,close:0', P => 2 F => 3, S => 'LEVEL', C => 'LEVEL', V => 'open:100,close:0', P => 2
}, },
'SHUTTER_TRANSMITTER' => {
F => 3, S => 'LEVEL', C => '', V => '', P => 1
},
'SHUTTER_VIRTUAL_RECEIVER' => { 'SHUTTER_VIRTUAL_RECEIVER' => {
F => 3, S => 'LEVEL', C => 'LEVEL', V => 'open:100,close:0', P => 2 F => 3, S => 'LEVEL', C => 'LEVEL', V => 'open:100,close:0', P => 2
}, },
@ -124,6 +127,9 @@ $HMCCU_CONFIG_VERSION = '4.8.028';
'DIMMER' => { 'DIMMER' => {
F => 3, S => 'LEVEL', C => 'LEVEL', V => 'on:100,off:0', P => 2 F => 3, S => 'LEVEL', C => 'LEVEL', V => 'on:100,off:0', P => 2
}, },
'DIMMER_TRANSMITTER' => {
F => 3, S => 'LEVEL', C => '', V => '', P => 1
},
'DIMMER_VIRTUAL_RECEIVER' => { 'DIMMER_VIRTUAL_RECEIVER' => {
F => 3, S => 'LEVEL', C => 'LEVEL', V => 'on:100,off:0', P => 2 F => 3, S => 'LEVEL', C => 'LEVEL', V => 'on:100,off:0', P => 2
}, },
@ -167,10 +173,14 @@ $HMCCU_CONFIG_VERSION = '4.8.028';
'(C#\.)?LEVEL$:+pct', '(C#\.)?LEVEL$:+pct',
'BLIND_VIRTUAL_RECEIVER' => 'BLIND_VIRTUAL_RECEIVER' =>
'(C#\.)?LEVEL$:+pct', '(C#\.)?LEVEL$:+pct',
'SHUTTER_TRANSMITTER' =>
'(C#\.)?LEVEL$:+pct',
'SHUTTER_VIRTUAL_RECEIVER' => 'SHUTTER_VIRTUAL_RECEIVER' =>
'(C#\.)?LEVEL$:+pct', '(C#\.)?LEVEL$:+pct',
'DIMMER' => 'DIMMER' =>
'(C#\.)?LEVEL$:+pct', '(C#\.)?LEVEL$:+pct',
'DIMMER_TRANSMITTER' =>
'(C#\.)?LEVEL$:+pct',
'DIMMER_VIRTUAL_RECEIVER' => 'DIMMER_VIRTUAL_RECEIVER' =>
'(C#\.)?LEVEL$:+pct', '(C#\.)?LEVEL$:+pct',
'MOTION_DETECTOR' => 'MOTION_DETECTOR' =>
@ -257,11 +267,6 @@ $HMCCU_CONFIG_VERSION = '4.8.028';
'off' => 'V:PRESS_SHORT:1', 'off' => 'V:PRESS_SHORT:1',
'press' => 'V:PRESS_SHORT:1' 'press' => 'V:PRESS_SHORT:1'
}, },
'KEY_TRANSCEIVER' => {
'on' => 'V:PRESS_SHORT:1',
'off' => 'V:PRESS_SHORT:1',
'press' => 'V:PRESS_SHORT:1'
},
'VIRTUAL_KEY' => { 'VIRTUAL_KEY' => {
'on' => 'V:PRESS_SHORT:1', 'on' => 'V:PRESS_SHORT:1',
'off' => 'V:PRESS_SHORT:1', 'off' => 'V:PRESS_SHORT:1',
@ -383,9 +388,7 @@ $HMCCU_CONFIG_VERSION = '4.8.028';
'webCmd' => 'press' 'webCmd' => 'press'
}, },
'KEY_TRANSCEIVER' => { 'KEY_TRANSCEIVER' => {
'event-on-update-reading' => 'PRESS.*', 'event-on-update-reading' => 'PRESS.*'
'cmdIcon' => 'press:taster',
'webCmd' => 'press'
}, },
'BLIND' => { 'BLIND' => {
'substexcl' => 'pct', 'substexcl' => 'pct',
@ -402,6 +405,9 @@ $HMCCU_CONFIG_VERSION = '4.8.028';
'webCmd' => 'pct:open:close:stop', 'webCmd' => 'pct:open:close:stop',
'widgetOverride' => 'pct:slider,0,10,100' 'widgetOverride' => 'pct:slider,0,10,100'
}, },
'SHUTTER_TRANSMITTER' => {
'substexcl' => 'pct',
},
'SHUTTER_VIRTUAL_RECEIVER' => { 'SHUTTER_VIRTUAL_RECEIVER' => {
'substexcl' => 'pct', 'substexcl' => 'pct',
'cmdIcon' => 'open:fts_shutter_up stop:fts_shutter_manual close:fts_shutter_down', 'cmdIcon' => 'open:fts_shutter_up stop:fts_shutter_manual close:fts_shutter_down',
@ -420,6 +426,9 @@ $HMCCU_CONFIG_VERSION = '4.8.028';
'webCmd' => 'pct', 'webCmd' => 'pct',
'widgetOverride' => 'pct:slider,0,10,100' 'widgetOverride' => 'pct:slider,0,10,100'
}, },
'DIMMER_TRANSMITTER' => {
'substexcl' => 'pct'
},
'DIMMER_VIRTUAL_RECEIVER' => { 'DIMMER_VIRTUAL_RECEIVER' => {
'cmdIcon' => 'on:general_an off:general_aus', 'cmdIcon' => 'on:general_an off:general_aus',
'substexcl' => 'pct', 'substexcl' => 'pct',
@ -524,6 +533,9 @@ $HMCCU_CONFIG_VERSION = '4.8.028';
'DIRECTION' => { '0' => 'none', '1' => 'up', '2' => 'down' }, 'DIRECTION' => { '0' => 'none', '1' => 'up', '2' => 'down' },
'WORKING' => { '0' => 'no', 'false' => 'no', '1' => 'yes', 'true' => 'yes' } 'WORKING' => { '0' => 'no', 'false' => 'no', '1' => 'yes', 'true' => 'yes' }
}, },
'SHUTTER_TRANSMITTER' => {
'LEVEL' => { '0' => 'closed', '100' => 'open', 'close' => '0', 'open' => '100' }
},
'SHUTTER_VIRTUAL_RECEIVER' => { 'SHUTTER_VIRTUAL_RECEIVER' => {
'LEVEL' => { '0' => 'closed', '100' => 'open', 'close' => '0', 'open' => '100' } 'LEVEL' => { '0' => 'closed', '100' => 'open', 'close' => '0', 'open' => '100' }
}, },

View File

@ -1,5 +1,5 @@
UPD 2021-05-17_18:01:13 102813 FHEM/88_HMCCURPCPROC.pm UPD 2021-06-07_18:52:09 102813 FHEM/88_HMCCURPCPROC.pm
UPD 2021-05-17_18:01:13 81874 FHEM/HMCCUConf.pm UPD 2021-06-07_18:52:09 82168 FHEM/HMCCUConf.pm
UPD 2021-05-17_18:01:13 42050 FHEM/88_HMCCUCHN.pm UPD 2021-06-07_18:52:09 42050 FHEM/88_HMCCUCHN.pm
UPD 2021-05-17_18:01:13 337736 FHEM/88_HMCCU.pm UPD 2021-06-07_18:52:09 344833 FHEM/88_HMCCU.pm
UPD 2021-05-17_18:01:13 30869 FHEM/88_HMCCUDEV.pm UPD 2021-06-07_18:52:09 30896 FHEM/88_HMCCUDEV.pm