mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-04-21 14:04:15 +00:00
HMCCU: bugfixes
git-svn-id: https://svn.fhem.de/fhem/trunk@28721 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
4c39034387
commit
3c5872e593
@ -307,7 +307,6 @@ sub HMCCU_UpdateDevice ($$);
|
|||||||
sub HMCCU_UpdateDeviceRoles ($$;$$);
|
sub HMCCU_UpdateDeviceRoles ($$;$$);
|
||||||
sub HMCCU_UpdateDeviceTable ($$);
|
sub HMCCU_UpdateDeviceTable ($$);
|
||||||
sub HMCCU_UpdateRoleCommands ($$);
|
sub HMCCU_UpdateRoleCommands ($$);
|
||||||
sub HMCCU_UpdateAdditionalCommands ($$;$$);
|
|
||||||
|
|
||||||
# Handle datapoints
|
# Handle datapoints
|
||||||
sub HMCCU_GetSCDatapoints ($);
|
sub HMCCU_GetSCDatapoints ($);
|
||||||
@ -483,9 +482,10 @@ sub HMCCU_Define ($$$)
|
|||||||
$hash->{hmccu}{postInit} = 0;
|
$hash->{hmccu}{postInit} = 0;
|
||||||
|
|
||||||
# Check if authentication is active
|
# Check if authentication is active
|
||||||
my ($erruser, $encuser) = getKeyValue ($name.'_username');
|
my ($username, $password) = HMCCU_GetCredentials ($hash);
|
||||||
my ($errpass, $encpass) = getKeyValue ($name.'_password');
|
$hash->{authentication} = $username ne '' && $password ne '' ? 'on' : 'off';
|
||||||
$hash->{authentication} = (defined($encuser) && defined($encpass)) ? 'on' : 'off';
|
($username, $password) = HMCCU_GetCredentials ($hash, '_json_');
|
||||||
|
$hash->{json} = $username ne '' && $password ne '' ? 'on' : 'off';
|
||||||
|
|
||||||
HMCCU_Log ($hash, 1, "Initialized version $HMCCU_VERSION");
|
HMCCU_Log ($hash, 1, "Initialized version $HMCCU_VERSION");
|
||||||
|
|
||||||
@ -1329,10 +1329,8 @@ sub HMCCU_Undef ($$)
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Delete CCU credentials
|
# Delete CCU credentials
|
||||||
my ($erruser, $encuser) = getKeyValue ($name.'_username');
|
HMCCU_SetCredentials ($hash);
|
||||||
my ($errpass, $encpass) = getKeyValue ($name.'_password');
|
HMCCU_SetCredentials ($hash, '_json_');
|
||||||
setKeyValue ($name."_username", undef) if (!defined($erruser) && defined($encuser));
|
|
||||||
setKeyValue ($name."_password", undef) if (!defined($errpass) && defined($encpass));
|
|
||||||
|
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
@ -1345,15 +1343,15 @@ sub HMCCU_Rename ($$)
|
|||||||
{
|
{
|
||||||
my ($oldName, $newName);
|
my ($oldName, $newName);
|
||||||
|
|
||||||
my ($erruser, $encuser) = getKeyValue ($oldName.'_username');
|
my ($username, $password) = HMCCU_GetCredentials ($oldName);
|
||||||
my ($errpass, $encpass) = getKeyValue ($oldName.'_password');
|
if ($username ne '' && $password ne '') {
|
||||||
if (!defined($erruser) && defined($encuser)) {
|
HMCCU_SetCredentials ($oldName);
|
||||||
setKeyValue ($newName."_username", $encuser);
|
HMCCU_SetCredentials ($newName, '_', $username, $password);
|
||||||
setKeyValue ($oldName."_username", undef);
|
|
||||||
}
|
}
|
||||||
if (!defined($errpass) && defined($encpass)) {
|
($username, $password) = HMCCU_GetCredentials ($oldName, '_json_');
|
||||||
setKeyValue ($newName."_password", $encpass);
|
if ($username ne '' && $password ne '') {
|
||||||
setKeyValue ($oldName."_password", undef);
|
HMCCU_SetCredentials ($oldName, '_json_');
|
||||||
|
HMCCU_SetCredentials ($newName, '_json_', $username, $password);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1495,29 +1493,35 @@ sub HMCCU_Set ($@)
|
|||||||
return HMCCU_SetState ($hash, 'OK');
|
return HMCCU_SetState ($hash, 'OK');
|
||||||
}
|
}
|
||||||
elsif ($opt eq 'authentication') {
|
elsif ($opt eq 'authentication') {
|
||||||
|
my $json = 0;
|
||||||
|
my $credKey = '_';
|
||||||
|
my $credInt = 'authentication';
|
||||||
my $username = shift @$a;
|
my $username = shift @$a;
|
||||||
|
if (defined($username) && $username eq 'json') {
|
||||||
|
$json = 1;
|
||||||
|
$credKey = '_json_';
|
||||||
|
$credInt = 'json';
|
||||||
|
$username = shift @$a;
|
||||||
|
}
|
||||||
my $password = shift @$a;
|
my $password = shift @$a;
|
||||||
$usage = "set $name $opt username password";
|
$usage = "set $name $opt ['json'] username password";
|
||||||
|
|
||||||
if (!defined($username)) {
|
if (!defined($username)) {
|
||||||
setKeyValue ($name."_username", undef);
|
my $err = HMCCU_SetCredentials ($hash, $credKey);
|
||||||
setKeyValue ($name."_password", undef);
|
if (!defined($err)) {
|
||||||
$hash->{authentication} = 'off';
|
$hash->{$credInt} = 'off';
|
||||||
return 'Credentials for CCU authentication deleted';
|
return 'Credentials for CCU authentication deleted';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return HMCCU_SetError ($hash, "Can't delete credentials. $err");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return HMCCU_SetError ($hash, $usage) if (!defined($password));
|
return HMCCU_SetError ($hash, $usage) if (!defined($password));
|
||||||
|
|
||||||
my $encuser = HMCCU_Encrypt ($username);
|
my $err = HMCCU_SetCredentials ($hash, $credKey, $username, $password);
|
||||||
my $encpass = HMCCU_Encrypt ($password);
|
return HMCCU_SetError ($hash, "Can't store credentials. $err") if (defined($err));
|
||||||
return HMCCU_SetError ($hash, 'Encryption of credentials failed') if ($encuser eq '' || $encpass eq '');
|
|
||||||
|
|
||||||
my $err = setKeyValue ($name."_username", $encuser);
|
|
||||||
return HMCCU_SetError ($hash, "Can't store credentials. $err") if (defined ($err));
|
|
||||||
$err = setKeyValue ($name."_password", $encpass);
|
|
||||||
return HMCCU_SetError ($hash, "Can't store credentials. $err") if (defined ($err));
|
|
||||||
|
|
||||||
$hash->{authentication} = 'on';
|
|
||||||
|
|
||||||
|
$hash->{$credInt} = 'on';
|
||||||
return 'Credentials for CCU authentication stored';
|
return 'Credentials for CCU authentication stored';
|
||||||
}
|
}
|
||||||
elsif ($opt eq 'clear') {
|
elsif ($opt eq 'clear') {
|
||||||
@ -2251,22 +2255,35 @@ sub HMCCU_GetReadingName ($$$$$;$$$)
|
|||||||
my $rn = '';
|
my $rn = '';
|
||||||
my @rnlist = ();
|
my @rnlist = ();
|
||||||
|
|
||||||
|
# Get reading prefix definitions
|
||||||
|
$ps = 'DEVICE' if (($c eq '0' && $ps eq 'MASTER') || $c eq 'd');
|
||||||
|
my $readingPrefix = HMCCU_GetAttribute ($ioHash, $hash, 'ccuReadingPrefix', '');
|
||||||
|
foreach my $pd (split (',', $readingPrefix)) {
|
||||||
|
my ($rSet, $rPre) = split (':', $pd);
|
||||||
|
if (exists($prefix{$rSet})) {
|
||||||
|
$prefix{$rSet} = defined($rPre) && $rPre ne '' ? $rPre : '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
my $rpf = exists($prefix{$ps}) ? $prefix{$ps} : '';
|
||||||
|
|
||||||
# Add device state reading
|
# Add device state reading
|
||||||
if (exists($newReadings{$d}) && ($c eq '' || $c eq '0')) {
|
if (exists($newReadings{$d}) && ($c eq '' || $c eq '0')) {
|
||||||
push @rnlist, $newReadings{$d};
|
push @rnlist, $newReadings{$d};
|
||||||
}
|
}
|
||||||
|
|
||||||
# Build list of reading name rul
|
# Build list of reading name rules
|
||||||
my @srl = ();
|
my @srl = ();
|
||||||
my $crn = AttrVal ($name, 'ccureadingname', '');
|
my $crn = AttrVal ($name, 'ccureadingname', '');
|
||||||
push @srl, split(';', $crn) if ($crn ne '');
|
push @srl, split(';', $crn) if ($crn ne '');
|
||||||
if (!$hideStandard &&
|
# if (!$hideStandard &&
|
||||||
(exists($hash->{hmccu}{control}{chn}) && "$c" eq $hash->{hmccu}{control}{chn}) ||
|
# (exists($hash->{hmccu}{control}{chn}) && "$c" eq $hash->{hmccu}{control}{chn}) ||
|
||||||
(exists($hash->{hmccu}{state}{chn}) && "$c" eq $hash->{hmccu}{state}{chn})
|
# (exists($hash->{hmccu}{state}{chn}) && "$c" eq $hash->{hmccu}{state}{chn})
|
||||||
) {
|
# ) {
|
||||||
my $role = HMCCU_GetChannelRole ($hash, $c);
|
if (!$hideStandard) {
|
||||||
|
my $role = $c ne '' && $c ne 'd' ? HMCCU_GetChannelRole ($hash, $c) : '';
|
||||||
$crn = $role ne '' && exists($HMCCU_READINGS->{$role}) ? $HMCCU_READINGS->{$role} : $HMCCU_READINGS->{DEFAULT};
|
$crn = $role ne '' && exists($HMCCU_READINGS->{$role}) ? $HMCCU_READINGS->{$role} : $HMCCU_READINGS->{DEFAULT};
|
||||||
$crn =~ s/C#\\/$c\\/g;
|
$crn =~ s/C#\\/$c\\/g;
|
||||||
|
$crn =~ s/P#/$rpf/g;
|
||||||
push @srl, map { $replaceStandard ? $_ =~ s/\+//g : $_ } split(';',$crn);
|
push @srl, map { $replaceStandard ? $_ =~ s/\+//g : $_ } split(';',$crn);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2281,17 +2298,6 @@ sub HMCCU_GetReadingName ($$$$$;$$$)
|
|||||||
$i = HMCCU_GetDeviceInterface ($ioHash, $a);
|
$i = HMCCU_GetDeviceInterface ($ioHash, $a);
|
||||||
}
|
}
|
||||||
|
|
||||||
# Get reading prefix definitions
|
|
||||||
$ps = 'DEVICE' if (($c eq '0' && $ps eq 'MASTER') || $c eq 'd');
|
|
||||||
my $readingPrefix = HMCCU_GetAttribute ($ioHash, $hash, 'ccuReadingPrefix', '');
|
|
||||||
foreach my $pd (split (',', $readingPrefix)) {
|
|
||||||
my ($rSet, $rPre) = split (':', $pd);
|
|
||||||
if (exists($prefix{$rSet})) {
|
|
||||||
$prefix{$rSet} = defined($rPre) && $rPre ne '' ? $rPre : '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
my $rpf = exists($prefix{$ps}) ? $prefix{$ps} : '';
|
|
||||||
|
|
||||||
# Format reading name
|
# Format reading name
|
||||||
if (!$h) {
|
if (!$h) {
|
||||||
$rf //= HMCCU_GetAttrReadingFormat ($hash, $ioHash);
|
$rf //= HMCCU_GetAttrReadingFormat ($hash, $ioHash);
|
||||||
@ -4381,6 +4387,16 @@ sub HMCCU_GetEnumValues ($$$$;$$)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
elsif (defined($paramDef) &&
|
||||||
|
defined($paramDef->{MIN}) && HMCCU_IsIntNum($paramDef->{MIN}) &&
|
||||||
|
defined($paramDef->{MAX}) && HMCCU_IsIntNum($paramDef->{MAX}) &&
|
||||||
|
$paramDef->{MAX}-$paramDef->{MIN} < 10
|
||||||
|
) {
|
||||||
|
for (my $i=$paramDef->{MIN}; $i<=$paramDef->{MAX}; $i++) {
|
||||||
|
$valList{$i} = $i;
|
||||||
|
$valIndex{$i} = $i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (defined($value)) {
|
if (defined($value)) {
|
||||||
if ($value eq '#') {
|
if ($value eq '#') {
|
||||||
@ -6708,35 +6724,43 @@ sub HMCCU_UpdateRoleCommands ($$)
|
|||||||
|
|
||||||
$cmdChn = 'd' if ($ps eq 'D');
|
$cmdChn = 'd' if ($ps eq 'D');
|
||||||
|
|
||||||
# Allow different datapoint/config parameter names for same command, if name depends on firmware revision of device type
|
|
||||||
my $dptValid = 0;
|
my $dptValid = 0;
|
||||||
my $dpt = '';
|
my $dpt = '';
|
||||||
# Find supported datapoint/config parameter
|
my $paramDef = { };
|
||||||
foreach my $d (split /,/, $dptList) {
|
|
||||||
next if (!defined($d) || $d eq '');
|
if ($dptList ne '*') {
|
||||||
if ($combDpt ne '') {
|
# Allow different datapoint/config parameter names for same command, if name depends on firmware revision of device type
|
||||||
next if (!exists($HMCCU_ROLECMDS->{$role}{$combDpt}{$d}));
|
# Find supported datapoint/config parameter
|
||||||
$dpt = $HMCCU_ROLECMDS->{$role}{$combDpt}{$d};
|
foreach my $d (split /,/, $dptList) {
|
||||||
push @combArgs, $d;
|
next if (!defined($d) || $d eq '');
|
||||||
|
if ($combDpt ne '') {
|
||||||
|
next if (!exists($HMCCU_ROLECMDS->{$role}{$combDpt}{$d}));
|
||||||
|
$dpt = $HMCCU_ROLECMDS->{$role}{$combDpt}{$d};
|
||||||
|
push @combArgs, $d;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$dpt = $d;
|
||||||
|
}
|
||||||
|
if (HMCCU_IsValidParameter ($clHash, "$addr:$cmdChn", $psName, $dpt, $parAccess)) {
|
||||||
|
$dptValid = 1;
|
||||||
|
last;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
if (!$dptValid) {
|
||||||
$dpt = $d;
|
HMCCU_Log ($clHash, 4, "HMCCUConf: Unsupported parameter $addr:$cmdChn $psName $dpt $parAccess. Ignoring sub command $subCmd in role $role for $devType device $devName");
|
||||||
|
next URCSUB;
|
||||||
}
|
}
|
||||||
if (HMCCU_IsValidParameter ($clHash, "$addr:$cmdChn", $psName, $dpt, $parAccess)) {
|
|
||||||
$dptValid = 1;
|
$paramDef = HMCCU_GetParamDef ($ioHash, "$addr:$cmdChn", $psName, $dpt);
|
||||||
last;
|
if (!defined($paramDef)) {
|
||||||
|
HMCCU_Log ($ioHash, 4, "HMCCUConf: Can't get definition of datapoint $addr:$cmdChn.$dpt. Ignoring command $cmd in role $role for $devType device $devName");
|
||||||
|
next URCCMD;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!$dptValid) {
|
else {
|
||||||
HMCCU_Log ($clHash, 4, "HMCCUConf: Unsupported parameter $addr:$cmdChn $psName $dpt $parAccess. Ignoring sub command $subCmd in role $role for $devType device $devName");
|
$dpt = '_any_';
|
||||||
next URCSUB;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
my $paramDef = HMCCU_GetParamDef ($ioHash, "$addr:$cmdChn", $psName, $dpt);
|
|
||||||
if (!defined($paramDef)) {
|
|
||||||
HMCCU_Log ($ioHash, 4, "HMCCUConf: Can't get definition of datapoint $addr:$cmdChn.$dpt. Ignoring command $cmd in role $role for $devType device $devName");
|
|
||||||
next URCCMD;
|
|
||||||
}
|
|
||||||
$clHash->{hmccu}{roleCmds}{$cmdType}{$cmd}{subcmd}{$scn}{scn} = sprintf("%03d", $subCmdNo);
|
$clHash->{hmccu}{roleCmds}{$cmdType}{$cmd}{subcmd}{$scn}{scn} = sprintf("%03d", $subCmdNo);
|
||||||
$clHash->{hmccu}{roleCmds}{$cmdType}{$cmd}{subcmd}{$scn}{type} = $paramDef->{TYPE} // '';
|
$clHash->{hmccu}{roleCmds}{$cmdType}{$cmd}{subcmd}{$scn}{type} = $paramDef->{TYPE} // '';
|
||||||
$clHash->{hmccu}{roleCmds}{$cmdType}{$cmd}{subcmd}{$scn}{min} = $paramDef->{MIN};
|
$clHash->{hmccu}{roleCmds}{$cmdType}{$cmd}{subcmd}{$scn}{min} = $paramDef->{MIN};
|
||||||
@ -6753,7 +6777,19 @@ sub HMCCU_UpdateRoleCommands ($$)
|
|||||||
|
|
||||||
# Build lookup table
|
# Build lookup table
|
||||||
my $argList = '';
|
my $argList = '';
|
||||||
my $el = HMCCU_GetEnumValues ($ioHash, $paramDef, $dpt, $role, '#', $pv);
|
my $el = '';
|
||||||
|
|
||||||
|
if (defined($pv) && $pv =~ /^[A-Z0-9_]+$/) {
|
||||||
|
$paramDef = HMCCU_GetParamDef ($ioHash, "$addr:$cmdChn", 'VALUES', $pv);
|
||||||
|
if (defined($paramDef)) {
|
||||||
|
$clHash->{hmccu}{roleCmds}{$cmdType}{$cmd}{subcmd}{$scn}{min} = $paramDef->{MIN};
|
||||||
|
$clHash->{hmccu}{roleCmds}{$cmdType}{$cmd}{subcmd}{$scn}{max} = $paramDef->{MAX};
|
||||||
|
$el = HMCCU_GetEnumValues ($ioHash, $paramDef, $pv, $role, '#');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$el = HMCCU_GetEnumValues ($ioHash, $paramDef, $dpt, $role, '#', $pv);
|
||||||
|
}
|
||||||
if ($el ne '') {
|
if ($el ne '') {
|
||||||
my $min;
|
my $min;
|
||||||
my $max;
|
my $max;
|
||||||
@ -6776,6 +6812,9 @@ sub HMCCU_UpdateRoleCommands ($$)
|
|||||||
$clHash->{hmccu}{roleCmds}{$cmdType}{$cmd}{subcmd}{$scn}{min} = $min;
|
$clHash->{hmccu}{roleCmds}{$cmdType}{$cmd}{subcmd}{$scn}{min} = $min;
|
||||||
$clHash->{hmccu}{roleCmds}{$cmdType}{$cmd}{subcmd}{$scn}{max} = $max;
|
$clHash->{hmccu}{roleCmds}{$cmdType}{$cmd}{subcmd}{$scn}{max} = $max;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
HMCCU_Log ($clHash, 2, "$cmdType $cmd: Cannot find enum values for parameter $pn, pv = $pv");
|
||||||
|
}
|
||||||
|
|
||||||
# Parameter list
|
# Parameter list
|
||||||
$clHash->{hmccu}{roleCmds}{$cmdType}{$cmd}{subcmd}{$scn}{parname} = $pn;
|
$clHash->{hmccu}{roleCmds}{$cmdType}{$cmd}{subcmd}{$scn}{parname} = $pn;
|
||||||
@ -6833,7 +6872,7 @@ sub HMCCU_UpdateRoleCommands ($$)
|
|||||||
if ($parTypes[1] == 1 && $parTypes[2] == 0 && $cmdArgList ne '') {
|
if ($parTypes[1] == 1 && $parTypes[2] == 0 && $cmdArgList ne '') {
|
||||||
# Only one variable argument. Argument belongs to a predefined value list
|
# Only one variable argument. Argument belongs to a predefined value list
|
||||||
# If values contain blanks, substitute blanks by # and enclose strings in quotes
|
# If values contain blanks, substitute blanks by # and enclose strings in quotes
|
||||||
$cmdDef .= ':'.join(',', map { $_ =~ / / ? '"'.(s/ /#/gr).'"' : $_ } split(',', $cmdArgList));
|
$cmdDef .= ':'.join(',', sort map { $_ =~ / / ? '"'.(s/ /#/gr).'"' : $_ } split(',', $cmdArgList));
|
||||||
}
|
}
|
||||||
elsif ($parTypes[1] == 0 && $parTypes[2] == 0) {
|
elsif ($parTypes[1] == 0 && $parTypes[2] == 0) {
|
||||||
$cmdDef .= ':noArg';
|
$cmdDef .= ':noArg';
|
||||||
@ -6873,72 +6912,6 @@ sub HMCCU_UpdateRoleCommands ($$)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
######################################################################
|
|
||||||
# Update additional commands which depend on device state
|
|
||||||
######################################################################
|
|
||||||
|
|
||||||
sub HMCCU_UpdateAdditionalCommands ($$;$$)
|
|
||||||
{
|
|
||||||
my ($ioHash, $clHash, $cc, $cd) = @_;
|
|
||||||
$cc //= '';
|
|
||||||
$cd //= '';
|
|
||||||
|
|
||||||
# No controldatapoint available (read only device)
|
|
||||||
if ($cd eq '' || $cc eq '') {
|
|
||||||
HMCCU_Log ($clHash, 4, "No control datapoint. Maybe device is read only or attribute will be set later");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
my $s = exists($clHash->{hmccu}{cmdlist}{set}) && $clHash->{hmccu}{cmdlist}{set} ne '' ? ' ' : '';
|
|
||||||
my ($addr, $chn) = HMCCU_SplitChnAddr ($clHash->{ccuaddr});
|
|
||||||
|
|
||||||
# Check if role of control channel is supported by HMCCU
|
|
||||||
my $role = HMCCU_GetChannelRole ($clHash, $cc);
|
|
||||||
if ($role ne '' && exists($HMCCU_STATECONTROL->{$role}) &&
|
|
||||||
HMCCU_DetectSCDatapoint ($HMCCU_STATECONTROL->{$role}{C}, $clHash->{ccuif}) eq $cd) {
|
|
||||||
# Only add toggle command, ignore attribute statevals
|
|
||||||
my $stVals = $HMCCU_STATECONTROL->{$role}{V} eq '#' ?
|
|
||||||
HMCCU_GetEnumValues ($ioHash, HMCCU_GetChannelAddr ($clHash, $cc), $HMCCU_STATECONTROL->{$role}{C}, $role, '#') :
|
|
||||||
$HMCCU_STATECONTROL->{$role}{V};
|
|
||||||
my %stateCmds = split (/[:,]/, $stVals);
|
|
||||||
my @states = keys %stateCmds;
|
|
||||||
$clHash->{hmccu}{cmdlist}{set} .= $s.'toggle:noArg' if (scalar(@states) > 1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
my $sv = AttrVal ($clHash->{NAME}, 'statevals', '');
|
|
||||||
if ($sv ne '') {
|
|
||||||
my %stateCmds = split (/[:,]/, $sv);
|
|
||||||
my @states = keys %stateCmds;
|
|
||||||
|
|
||||||
my $paramDef = HMCCU_GetParamDef ($ioHash, "$addr:$cc", 'VALUES', $cd);
|
|
||||||
if (defined($paramDef)) {
|
|
||||||
foreach my $cmd (@states) {
|
|
||||||
$clHash->{hmccu}{roleCmds}{set}{$cmd}{channel} = $cc;
|
|
||||||
$clHash->{hmccu}{roleCmds}{set}{$cmd}{role} = $role;
|
|
||||||
$clHash->{hmccu}{roleCmds}{set}{$cmd}{subcount} = 1;
|
|
||||||
$clHash->{hmccu}{roleCmds}{set}{$cmd}{syntax} = "V:$cd:".$stateCmds{$cmd};
|
|
||||||
$clHash->{hmccu}{roleCmds}{set}{$cmd}{usage} = $cmd;
|
|
||||||
$clHash->{hmccu}{roleCmds}{set}{$cmd}{subcmd}{'000'}{partype} = 3;
|
|
||||||
$clHash->{hmccu}{roleCmds}{set}{$cmd}{subcmd}{'000'}{args} = $stateCmds{$cmd};
|
|
||||||
$clHash->{hmccu}{roleCmds}{set}{$cmd}{subcmd}{'000'}{min} = $paramDef->{MIN};
|
|
||||||
$clHash->{hmccu}{roleCmds}{set}{$cmd}{subcmd}{'000'}{max} = $paramDef->{MAX};
|
|
||||||
$clHash->{hmccu}{roleCmds}{set}{$cmd}{subcmd}{'000'}{unit} = $paramDef->{UNIT} // '';
|
|
||||||
$clHash->{hmccu}{roleCmds}{set}{$cmd}{subcmd}{'000'}{ps} = 'VALUES';
|
|
||||||
$clHash->{hmccu}{roleCmds}{set}{$cmd}{subcmd}{'000'}{dpt} = $cd;
|
|
||||||
$clHash->{hmccu}{roleCmds}{set}{$cmd}{subcmd}{'000'}{fnc} = '';
|
|
||||||
}
|
|
||||||
$clHash->{hmccu}{cmdlist}{set} .= $s.join(' ', map { $_ . ':noArg' } @states)
|
|
||||||
if (scalar(@states) > 0);
|
|
||||||
$clHash->{hmccu}{cmdlist}{set} .= ' toggle:noArg'
|
|
||||||
if (scalar(@states) > 1);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
HMCCU_Log ($clHash, 3, "Can't get definition of datapoint $addr:$cc.$cd. Ignoring commands ".join(',',@states)." for device $clHash->{NAME}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
# Execute command related to role
|
# Execute command related to role
|
||||||
# Parameters:
|
# Parameters:
|
||||||
@ -6988,7 +6961,7 @@ sub HMCCU_ExecuteRoleCommand ($@)
|
|||||||
my @par = ();
|
my @par = ();
|
||||||
my $autoscale = 0;
|
my $autoscale = 0;
|
||||||
|
|
||||||
if ($cmd->{ps} ne 'INTERNAL' && !HMCCU_IsValidParameter ($clHash, $chnAddr, $cmd->{ps}, $cmd->{dpt})) {
|
if ($cmd->{ps} ne 'INTERNAL' && $cmd->{dpt} ne '_any_' && !HMCCU_IsValidParameter ($clHash, $chnAddr, $cmd->{ps}, $cmd->{dpt})) {
|
||||||
HMCCU_Trace ($clHash, 2, "Invalid parameter $cmd->{ps}.$cmd->{dpt} for command $command");
|
HMCCU_Trace ($clHash, 2, "Invalid parameter $cmd->{ps}.$cmd->{dpt} for command $command");
|
||||||
return HMCCU_SetError ($clHash, -8, "$cmd->{ps}.$cmd->{dpt}");
|
return HMCCU_SetError ($clHash, -8, "$cmd->{ps}.$cmd->{dpt}");
|
||||||
}
|
}
|
||||||
@ -7671,9 +7644,9 @@ sub HMCCU_DisplayWeekProgram ($$$;$$)
|
|||||||
my $pn = $programName ne 'all' ? $programName : $w+1;
|
my $pn = $programName ne 'all' ? $programName : $w+1;
|
||||||
$s .= '<p><b>Week Program '.$pn.'</b></p><br/><table border="1">';
|
$s .= '<p><b>Week Program '.$pn.'</b></p><br/><table border="1">';
|
||||||
foreach my $d (sort keys %{$p->{ENDTIME}}) {
|
foreach my $d (sort keys %{$p->{ENDTIME}}) {
|
||||||
$s .= '<tr><td><b>'.$weekDay[$d].'</b></td>';
|
$s .= '<tr><td style="padding: 2px"><b>'.$weekDay[$d].'</b></td>';
|
||||||
foreach my $h (sort { $a <=> $b } keys %{$p->{ENDTIME}{$d}}) {
|
foreach my $h (sort { $a <=> $b } keys %{$p->{ENDTIME}{$d}}) {
|
||||||
$s .= '<td>'.$p->{ENDTIME}{$d}{$h}.' / '.$p->{TEMPERATURE}{$d}{$h}.'</td>';
|
$s .= '<td style="padding: 2px">'.$p->{ENDTIME}{$d}{$h}.' / '.$p->{TEMPERATURE}{$d}{$h}.'</td>';
|
||||||
last if ($p->{ENDTIME}{$d}{$h} eq '24:00');
|
last if ($p->{ENDTIME}{$d}{$h} eq '24:00');
|
||||||
}
|
}
|
||||||
$s .= '</tr>';
|
$s .= '</tr>';
|
||||||
@ -9681,16 +9654,8 @@ sub HMCCU_BuildURL ($$)
|
|||||||
|
|
||||||
my $url = '';
|
my $url = '';
|
||||||
|
|
||||||
my $username = '';
|
my ($username, $password) = HMCCU_GetCredentials ($hash);
|
||||||
my $password = '';
|
my $authorization = $username ne '' && $password ne '' ? encode_base64 ("$username:$password", '') : '';
|
||||||
my $authorization = '';
|
|
||||||
my ($erruser, $encuser) = getKeyValue ($name.'_username');
|
|
||||||
my ($errpass, $encpass) = getKeyValue ($name.'_password');
|
|
||||||
if (!defined($erruser) && !defined($errpass) && defined($encuser) && defined($encpass)) {
|
|
||||||
$username = HMCCU_Decrypt ($encuser);
|
|
||||||
$password = HMCCU_Decrypt ($encpass);
|
|
||||||
$authorization = encode_base64 ("$username:$password", '');
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($backend eq 'rega') {
|
if ($backend eq 'rega') {
|
||||||
$url = $hash->{prot}."://".$hash->{host}.':'.
|
$url = $hash->{prot}."://".$hash->{host}.':'.
|
||||||
@ -10303,6 +10268,68 @@ sub HMCCU_MaxHashEntries ($$)
|
|||||||
return \%result;
|
return \%result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
# Set or delete credentials
|
||||||
|
#######################################################################
|
||||||
|
|
||||||
|
sub HMCCU_SetCredentials ($@)
|
||||||
|
{
|
||||||
|
my ($ioHashOrName, $key, $username, $password) = @_;
|
||||||
|
$key //= '_';
|
||||||
|
|
||||||
|
my $name = ref($ioHashOrName) eq 'HASH' ? $ioHashOrName->{NAME} : $ioHashOrName;
|
||||||
|
my $userkey = $name.$key.'username';
|
||||||
|
my $passkey = $name.$key.'password';
|
||||||
|
my $rc;
|
||||||
|
|
||||||
|
# Delete CCU credentials
|
||||||
|
if (!defined($username)) {
|
||||||
|
my ($erruser, $encuser) = getKeyValue ($userkey);
|
||||||
|
my ($errpass, $encpass) = getKeyValue ($passkey);
|
||||||
|
$rc = setKeyValue ($userkey, undef) if (!defined($erruser) && defined($encuser));
|
||||||
|
return $rc if (defined($rc));
|
||||||
|
$rc = setKeyValue ($passkey, undef) if (!defined($errpass) && defined($encpass));
|
||||||
|
return $rc if (defined($rc));
|
||||||
|
}
|
||||||
|
elsif (defined($password)) {
|
||||||
|
my $encuser = HMCCU_Encrypt ($username);
|
||||||
|
return 'Cannot encrypt username' if ($encuser eq '');
|
||||||
|
my $encpass = HMCCU_Encrypt ($password);
|
||||||
|
return 'Cannot encrypt password' if ($encpass eq '');
|
||||||
|
$rc = setKeyValue ($userkey, $encuser);
|
||||||
|
return $rc if (defined($rc));
|
||||||
|
$rc = setKeyValue ($passkey, $encpass);
|
||||||
|
return $rc if (defined($rc));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return 'Missing password';
|
||||||
|
}
|
||||||
|
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
# Read credentials
|
||||||
|
#######################################################################
|
||||||
|
|
||||||
|
sub HMCCU_GetCredentials ($@)
|
||||||
|
{
|
||||||
|
my ($ioHashOrName, $key) = @_;
|
||||||
|
$key //= '_';
|
||||||
|
|
||||||
|
my $name = ref($ioHashOrName) eq 'HASH' ? $ioHashOrName->{NAME} : $ioHashOrName;
|
||||||
|
my $userkey = $name.$key.'username';
|
||||||
|
my $passkey = $name.$key.'password';
|
||||||
|
|
||||||
|
my ($erruser, $encuser) = getKeyValue ($userkey);
|
||||||
|
my ($errpass, $encpass) = getKeyValue ($passkey);
|
||||||
|
|
||||||
|
my $username = defined($encuser) ? HMCCU_Decrypt ($encuser) : '';
|
||||||
|
my $password = defined($encpass) ? HMCCU_Decrypt ($encpass) : '';
|
||||||
|
|
||||||
|
return ($username, $password);
|
||||||
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
||||||
|
|
||||||
@ -10365,9 +10392,9 @@ sub HMCCU_MaxHashEntries ($$)
|
|||||||
<li><b>set <name> ackmessages</b><br/>
|
<li><b>set <name> ackmessages</b><br/>
|
||||||
Acknowledge "device was unreachable" messages in CCU.
|
Acknowledge "device was unreachable" messages in CCU.
|
||||||
</li><br/>
|
</li><br/>
|
||||||
<li><b>set <name> authentication [<username> <password>]</b><br/>
|
<li><b>set <name> authentication ['json'] [<username> <password>]</b><br/>
|
||||||
Set credentials for CCU authentication.<br/>
|
Set credentials for CCU authentication. With option 'json' the CCU JSON interface is used for syncing the CCU configuration.<br/>
|
||||||
When executing this command without arguments, the credentials are deleted.
|
When executing this command without username and password, the credentials are deleted.
|
||||||
</li><br/>
|
</li><br/>
|
||||||
<li><b>set <name> clear [<reading-exp>]</b><br/>
|
<li><b>set <name> clear [<reading-exp>]</b><br/>
|
||||||
Delete readings matching specified reading name expression. Default expression is '.*'.
|
Delete readings matching specified reading name expression. Default expression is '.*'.
|
||||||
|
@ -254,8 +254,6 @@ $HMCCU_CONFIG_VERSION = '5.0';
|
|||||||
'^(C#\.)?LEVEL$:+pct,+level',
|
'^(C#\.)?LEVEL$:+pct,+level',
|
||||||
'BLIND_TRANSMITTER' =>
|
'BLIND_TRANSMITTER' =>
|
||||||
'^(C#\.)?LEVEL$:+pct,+level;^(C#\.)?LEVEL_2$:+pctSlats',
|
'^(C#\.)?LEVEL$:+pct,+level;^(C#\.)?LEVEL_2$:+pctSlats',
|
||||||
# 'BLIND_VIRTUAL_RECEIVER' =>
|
|
||||||
# '^(C#\.)?LEVEL$:+pct,+level',
|
|
||||||
'CAPACITIVE_FILLING_LEVEL_SENSOR' =>
|
'CAPACITIVE_FILLING_LEVEL_SENSOR' =>
|
||||||
'^(C#\.)?FILLING_LEVEL$:+level',
|
'^(C#\.)?FILLING_LEVEL$:+level',
|
||||||
'CLIMATECONTROL_REGULATOR' =>
|
'CLIMATECONTROL_REGULATOR' =>
|
||||||
@ -274,8 +272,6 @@ $HMCCU_CONFIG_VERSION = '5.0';
|
|||||||
'^(C#\.)?LEVEL$:+pct,+level',
|
'^(C#\.)?LEVEL$:+pct,+level',
|
||||||
'DIMMER_TRANSMITTER' =>
|
'DIMMER_TRANSMITTER' =>
|
||||||
'^(C#\.)?LEVEL$:+pct,+level;(C#\.)?COLOR$:+color',
|
'^(C#\.)?LEVEL$:+pct,+level;(C#\.)?COLOR$:+color',
|
||||||
# 'DIMMER_VIRTUAL_RECEIVER' =>
|
|
||||||
# '^(C#\.)?LEVEL$:+pct,+level;(C#\.)?COLOR$:+color',
|
|
||||||
'DIMMER_WEEK_PROFILE' =>
|
'DIMMER_WEEK_PROFILE' =>
|
||||||
'^(C#\.)?WEEK_PROGRAM_CHANNEL_LOCKS$:+progMode',
|
'^(C#\.)?WEEK_PROGRAM_CHANNEL_LOCKS$:+progMode',
|
||||||
'HB_GENERIC_DIST' =>
|
'HB_GENERIC_DIST' =>
|
||||||
@ -301,8 +297,6 @@ $HMCCU_CONFIG_VERSION = '5.0';
|
|||||||
'^(C#\.)?ILLUMINATION$:+brightness;(C#\.)?PRESENCE_DETECTION_STATE:+presence;(C#\.)?PRESENCE_DETECTION_ACTIVE:+detection',
|
'^(C#\.)?ILLUMINATION$:+brightness;(C#\.)?PRESENCE_DETECTION_STATE:+presence;(C#\.)?PRESENCE_DETECTION_ACTIVE:+detection',
|
||||||
'SHUTTER_TRANSMITTER' =>
|
'SHUTTER_TRANSMITTER' =>
|
||||||
'^(C#\.)?LEVEL$:+pct,+level',
|
'^(C#\.)?LEVEL$:+pct,+level',
|
||||||
# 'SHUTTER_VIRTUAL_RECEIVER' =>
|
|
||||||
# '^(C#\.)?LEVEL$:+pct,+level',
|
|
||||||
'SWITCH_PANIC' =>
|
'SWITCH_PANIC' =>
|
||||||
'^(C#\.)?STATE$:+panic',
|
'^(C#\.)?STATE$:+panic',
|
||||||
'SWITCH_SENSOR' =>
|
'SWITCH_SENSOR' =>
|
||||||
@ -321,11 +315,11 @@ $HMCCU_CONFIG_VERSION = '5.0';
|
|||||||
'^(C#\.)?TEMPERATURE$:+measured-temp;'.
|
'^(C#\.)?TEMPERATURE$:+measured-temp;'.
|
||||||
'^(C#\.)?HUMIDITY$:+humidity',
|
'^(C#\.)?HUMIDITY$:+humidity',
|
||||||
'DEFAULT' =>
|
'DEFAULT' =>
|
||||||
# '^([0-9]{1,2}\.)?LEVEL$:+pct,+level;'.
|
|
||||||
'^([0-9]{1,2}\.)?SET_TEMPERATURE$:+desired-temp;'.
|
'^([0-9]{1,2}\.)?SET_TEMPERATURE$:+desired-temp;'.
|
||||||
'^([0-9]{1,2}\.)?(ACTUAL_TEMPERATURE|TEMPERATURE)$:+measured-temp;'.
|
'^([0-9]{1,2}\.)?(ACTUAL_TEMPERATURE|TEMPERATURE)$:+measured-temp;'.
|
||||||
'^([0-9]{1,2}\.)?SET_POINT_TEMPERATURE$:+desired-temp;'.
|
'^([0-9]{1,2}\.)?SET_POINT_TEMPERATURE$:+desired-temp;'.
|
||||||
'^([0-9]{1,2}\.)?ACTUAL_HUMIDITY$:+humidity'
|
'^([0-9]{1,2}\.)?ACTUAL_HUMIDITY$:+humidity;'.
|
||||||
|
'^(P#)?WEEK_PROGRAM_POINTER$:+week-program'
|
||||||
);
|
);
|
||||||
|
|
||||||
#######################################################################################
|
#######################################################################################
|
||||||
@ -484,9 +478,8 @@ $HMCCU_CONFIG_VERSION = '5.0';
|
|||||||
'boost' => 'V:BOOST_MODE:#boost=on,off',
|
'boost' => 'V:BOOST_MODE:#boost=on,off',
|
||||||
'on' => 'V:CONTROL_MODE:1 V:SET_POINT_TEMPERATURE:30.5',
|
'on' => 'V:CONTROL_MODE:1 V:SET_POINT_TEMPERATURE:30.5',
|
||||||
'off' => 'V:CONTROL_MODE:1 V:SET_POINT_TEMPERATURE:4.5',
|
'off' => 'V:CONTROL_MODE:1 V:SET_POINT_TEMPERATURE:4.5',
|
||||||
'week-program' => 'V:ACTIVE_PROFILE:#profile=1,2,3',
|
'week-program' => 'V:ACTIVE_PROFILE:#profile=ACTIVE_PROFILE',
|
||||||
# For getting parameters from MASTER paramset the parameter is not used. But it must be a valid parameter of the role
|
'get week-program' => 'M:*:#profile=ACTIVE_PROFILE:HMCCU_DisplayWeekProgram'
|
||||||
'get week-program' => 'M:P1_ENDTIME_MONDAY_1:#profile=1,2,3:HMCCU_DisplayWeekProgram'
|
|
||||||
},
|
},
|
||||||
'JALOUSIE' => {
|
'JALOUSIE' => {
|
||||||
'pct' => 'V:LEVEL:?level',
|
'pct' => 'V:LEVEL:?level',
|
||||||
@ -2136,21 +2129,21 @@ string chnid;
|
|||||||
string sifid;
|
string sifid;
|
||||||
string prgid;
|
string prgid;
|
||||||
foreach(devid, root.Devices().EnumUsedIDs()) {
|
foreach(devid, root.Devices().EnumUsedIDs()) {
|
||||||
object odev=dom.GetObject(devid);
|
object odev=dom.GetObject(devid);
|
||||||
if(odev) {
|
if(odev) {
|
||||||
var intid=odev.Interface();
|
var intid=odev.Interface();
|
||||||
object oiface=dom.GetObject(intid);
|
object oiface=dom.GetObject(intid);
|
||||||
if(oiface) {
|
if(oiface) {
|
||||||
string intna=oiface.Name();
|
string intna=oiface.Name();
|
||||||
integer cc=0;
|
integer cc=0;
|
||||||
foreach (chnid, odev.Channels()) {
|
foreach (chnid, odev.Channels()) {
|
||||||
object ochn=dom.GetObject(chnid);
|
object ochn=dom.GetObject(chnid);
|
||||||
WriteLine("C;" # ochn.Address() # ";" # ochn.Name() # ";" # ochn.ChnDirection());
|
WriteLine("C;" # ochn.Address() # ";" # ochn.Name() # ";" # ochn.ChnDirection());
|
||||||
cc=cc+1;
|
cc=cc+1;
|
||||||
}
|
|
||||||
WriteLine("D;" # intna # ";" # odev.Address() # ";" # odev.Name() # ";" # odev.HssType() # ";" # cc);
|
|
||||||
}
|
}
|
||||||
}
|
WriteLine("D;" # intna # ";" # odev.Address() # ";" # odev.Name() # ";" # odev.HssType() # ";" # cc);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
foreach(sifid, root.Interfaces().EnumIDs()) {
|
foreach(sifid, root.Interfaces().EnumIDs()) {
|
||||||
object oIf=dom.GetObject(sifid);
|
object oIf=dom.GetObject(sifid);
|
||||||
@ -2411,13 +2404,44 @@ else {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
"AddMetaData" => {
|
"SetMetaData" => {
|
||||||
description => "Add metadata to channel",
|
description => "Set metadata value in device or channel",
|
||||||
syntax => "name key value",
|
syntax => "name key value",
|
||||||
parameters => 3,
|
parameters => 3,
|
||||||
code => qq(
|
code => qq(
|
||||||
object chnObj = channels.Get("\$name");
|
string name = "\$name";
|
||||||
chnObj.AddMetaData("\$key", "\$value");
|
object hmObj = dom.GetObject(name);
|
||||||
|
if (hmObj) {
|
||||||
|
if (hmObj.IsTypeOf(OT_CHANNEL) || hmObj.IsTypeOf(OT_DEVICE)) {
|
||||||
|
hmObj.SetMetaData("\$key", "\$value");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
WriteLine(name # " is no device or channel");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
WriteLine("Device or channel " # name # " not found");
|
||||||
|
}
|
||||||
|
)
|
||||||
|
},
|
||||||
|
"DelMetaData" => {
|
||||||
|
description => "Remove metadata from device or channel",
|
||||||
|
syntax => "name key",
|
||||||
|
parameters => 2,
|
||||||
|
code => qq(
|
||||||
|
string name = "\$name";
|
||||||
|
object hmObj = dom.GetObject(name);
|
||||||
|
if (hmObj) {
|
||||||
|
if (hmObj.IsTypeOf(OT_CHANNEL) || hmObj.IsTypeOf(OT_DEVICE)) {
|
||||||
|
hmObj.RemoveMetaData("\$key");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
WriteLine(name # " is no device or channel");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
WriteLine("Device or channel " # name # " not found");
|
||||||
|
}
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
"GetServiceMessages" => {
|
"GetServiceMessages" => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user