mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-01-31 00:36:25 +00:00
HMCCU: Fixed ENUM conversion bug
git-svn-id: https://svn.fhem.de/fhem/trunk@25365 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
7c2e260fbf
commit
1069d54cd0
@ -1,5 +1,6 @@
|
||||
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
|
||||
# Do not insert empty lines here, update check depends on it.
|
||||
- bugfix: 88_HMCCU: Fixed ENUM conversion bug
|
||||
- feature: 31_HUEDevice: allow json in set commands for lights.
|
||||
see https://forum.fhem.de/index.php/topic,11020
|
||||
posting #1864 and #1866
|
||||
|
@ -31,7 +31,7 @@ no if $] >= 5.017011, warnings => 'experimental::smartmatch';
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Data::Dumper;
|
||||
# use Data::Dumper;
|
||||
use Encode qw(decode encode);
|
||||
use RPC::XML::Client;
|
||||
use RPC::XML::Server;
|
||||
@ -57,7 +57,7 @@ my %HMCCU_CUST_CHN_DEFAULTS;
|
||||
my %HMCCU_CUST_DEV_DEFAULTS;
|
||||
|
||||
# HMCCU version
|
||||
my $HMCCU_VERSION = '5.0 213491649';
|
||||
my $HMCCU_VERSION = '5.0 213551543';
|
||||
|
||||
# Timeout for CCU requests (seconds)
|
||||
my $HMCCU_TIMEOUT_REQUEST = 4;
|
||||
@ -638,8 +638,6 @@ sub HMCCU_Attr ($@)
|
||||
}
|
||||
elsif ($attrname eq 'ccuflags') {
|
||||
my $ccuflags = AttrVal ($name, 'ccuflags', 'null');
|
||||
my @flags = ($attrval =~ /(intrpc|extrpc|procrpc)/g);
|
||||
return "HMCCU: [$name] Flags extrpc, procrpc and intrpc cannot be combined" if (scalar (@flags) > 1);
|
||||
if ($attrval =~ /(intrpc|extrpc)/) {
|
||||
HMCCU_Log ($hash, 1, "HMCCU: [$name] RPC server mode $1 no longer supported. Using procrpc instead");
|
||||
$attrval =~ s/(extrpc|intrpc)/procrpc/;
|
||||
@ -2884,19 +2882,9 @@ sub HMCCU_Substitute ($$$$$;$$)
|
||||
'BOOL' => { '0' => 'false', '1' => 'true' }
|
||||
);
|
||||
my $parType = $paramDef->{TYPE};
|
||||
if ($parType eq 'ENUM' && defined($paramDef->{VALUE_LIST})) {
|
||||
my $i = defined($paramDef->{MIN}) ? $paramDef->{MIN} : 0;
|
||||
if ($mode == 1) {
|
||||
my %enumVals = map { $_ => $i++ } split(',', $paramDef->{VALUE_LIST});
|
||||
return $enumVals{$value} if (exists($enumVals{$value}));
|
||||
}
|
||||
else {
|
||||
my @enumList = split(',', $paramDef->{VALUE_LIST});
|
||||
if (HMCCU_IsIntNum ($value)) {
|
||||
my $idx = $value-$i;
|
||||
return $enumList[$idx] if ($idx >= 0 && $idx < scalar(@enumList));
|
||||
}
|
||||
}
|
||||
if ($parType eq 'ENUM' && defined($paramDef->{VALUE_LIST}) && HMCCU_IsIntNum($value)
|
||||
) {
|
||||
return HMCCU_GetEnumValues ($ioHash, $paramDef, undef, $value);
|
||||
}
|
||||
elsif (exists($ct{$parType}) && exists($ct{$parType}{$value})) {
|
||||
return $ct{$parType}{$value};
|
||||
@ -2926,7 +2914,7 @@ sub HMCCU_SubstRule ($$$)
|
||||
|
||||
$substitutes =~ s/\$\{value\}/$value/g;
|
||||
|
||||
my @sub_list = split /[, ]/,$substitutes;
|
||||
my @sub_list = split /,/,$substitutes;
|
||||
foreach my $s (@sub_list) {
|
||||
my ($regexp, $text) = split /:/,$s,2;
|
||||
next if (!defined($regexp) || !defined($text));
|
||||
@ -4391,11 +4379,13 @@ sub HMCCU_FindParamDef ($$$)
|
||||
######################################################################
|
||||
# Get values of ENUM datapoint
|
||||
# object - Hash with parameter defintion or channel address
|
||||
# dpt - Datapoint name
|
||||
# value - Either a numeric value or an enumeration constant
|
||||
# If value is not specified, a comma separated list of enumeration
|
||||
# constants is returned.
|
||||
# Return value or undef if datapoint is not of type ENUM.
|
||||
# dpt - Datapoint name. Can be undef if object is a paramDef hash.
|
||||
# value - Either '#', a numeric value or an enumeration constant
|
||||
# If value is not specified, a string with a comma separated list of
|
||||
# enumeration constants is returned.
|
||||
# Return value, constant or list of constants depending on parameter
|
||||
# $value:
|
||||
# $value = '#' : Return list of constant:value pairs
|
||||
######################################################################
|
||||
|
||||
sub HMCCU_GetEnumValues ($$$;$)
|
||||
@ -4405,19 +4395,22 @@ sub HMCCU_GetEnumValues ($$$;$)
|
||||
my $paramDef = ref($object) eq 'HASH' ? $object : HMCCU_GetParamDef ($ioHash, $object, 'VALUES', $dpt);
|
||||
if (defined($paramDef) && defined($paramDef->{TYPE}) && $paramDef->{TYPE} eq 'ENUM' && defined($paramDef->{VALUE_LIST})) {
|
||||
my $i = defined($paramDef->{MIN}) && HMCCU_IsIntNum($paramDef->{MIN}) ? $paramDef->{MIN} : 0;
|
||||
$i--;
|
||||
my $j = $i;
|
||||
my @valList = split(',',$paramDef->{VALUE_LIST});
|
||||
my %valIndex = map { $_ => $i++ } @valList;
|
||||
my %valIndex = map { $i++; $_ => $i if ($_ ne '') } @valList; # Consider blanks in value list
|
||||
if (defined($value)) {
|
||||
if ($value eq '#') {
|
||||
$j--;
|
||||
# Return list of Constant:Value pairs
|
||||
return join(',', map { $j++; $_ ne '' ? "$_:$j" : () } @valList);
|
||||
}
|
||||
elsif (HMCCU_IsIntNum($value)) {
|
||||
# Return Constant for value. Constant might be ''
|
||||
return $valList[$value] if ($value >= 0 && $value < scalar(@valList));
|
||||
}
|
||||
else {
|
||||
return $valIndex{$value} if (exists($valIndex{$value}));
|
||||
# Return Value for Constant
|
||||
return $valIndex{$value} if ($value ne '' && exists($valIndex{$value}));
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -5117,7 +5110,7 @@ sub HMCCU_IsRPCType ($$$)
|
||||
|
||||
######################################################################
|
||||
# Start external RPC server via RPC device.
|
||||
# Return number of RPC servers or 0 on error.
|
||||
# Return number of started/running RPC servers or 0 on error.
|
||||
######################################################################
|
||||
|
||||
sub HMCCU_StartExtRPCServer ($)
|
||||
@ -5127,22 +5120,10 @@ sub HMCCU_StartExtRPCServer ($)
|
||||
|
||||
my $ccuflags = AttrVal ($name, 'ccuflags', 'null');
|
||||
my $attrset = 0;
|
||||
|
||||
# Change RPC type to procrpc
|
||||
if ($ccuflags =~ /(extrpc|intrpc)/) {
|
||||
$ccuflags =~ s/(extrpc|intrpc)/procrpc/g;
|
||||
CommandAttr (undef, "$name ccuflags $ccuflags");
|
||||
$attrset = 1;
|
||||
|
||||
# Disable existing devices of type HMCCURPC
|
||||
foreach my $d (keys %defs) {
|
||||
my $ch = $defs{$d};
|
||||
next if (!exists ($ch->{TYPE}) || !exists ($ch->{NAME}) || $ch->{TYPE} ne 'HMCCURPC');
|
||||
CommandAttr (undef, $ch->{NAME}." disable 1") if (IsDisabled ($ch->{NAME}) != 1);
|
||||
}
|
||||
}
|
||||
|
||||
my $c = 0;
|
||||
my $c = 0; # Started RPC servers
|
||||
my $r = 0; # Running RPC servers
|
||||
my $f = 0; # Failed RPC servers
|
||||
my $d = 0;
|
||||
my $s = 0;
|
||||
my $interfaces = HMCCU_GetRPCInterfaceList ($hash, 0);
|
||||
@ -5166,15 +5147,20 @@ sub HMCCU_StartExtRPCServer ($)
|
||||
my $dh = $defs{$hash->{hmccu}{interfaces}{$ifname2}{device}};
|
||||
$hash->{hmccu}{interfaces}{$ifname2}{manager} = 'HMCCU';
|
||||
my ($rc, $msg) = HMCCURPCPROC_StartRPCServer ($dh);
|
||||
if (!$rc) {
|
||||
if ($rc == 0) {
|
||||
$f++;
|
||||
HMCCU_SetRPCState ($hash, 'error', $ifname2, $msg);
|
||||
}
|
||||
else {
|
||||
elsif ($rc == 1) {
|
||||
$c++;
|
||||
}
|
||||
elsif ($rc == 2) {
|
||||
$r++;
|
||||
}
|
||||
}
|
||||
HMCCU_SetRPCState ($hash, 'starting') if ($c > 0);
|
||||
return $c;
|
||||
HMCCU_Log ($hash, 2, "RPC server start: $c started, $r already running, $f failed to start");
|
||||
return $c+$r;
|
||||
}
|
||||
else {
|
||||
HMCCU_Log ($hash, 0, 'Definition of some RPC devices failed');
|
||||
@ -7017,20 +7003,19 @@ sub HMCCU_UpdateRoleCommands ($$;$)
|
||||
$clHash->{hmccu}{roleCmds}{$cmdType}{$cmd}{subcmd}{$scn}{fnc} = $fnc // '';
|
||||
if ($paramDef->{TYPE} eq 'ENUM' && defined($paramDef->{VALUE_LIST})) {
|
||||
# Build lookup table
|
||||
my @el = split(',', $paramDef->{VALUE_LIST});
|
||||
my $i = 0;
|
||||
foreach my $e (@el) {
|
||||
$clHash->{hmccu}{roleCmds}{$cmdType}{$cmd}{subcmd}{$scn}{look}{$e} = $i;
|
||||
$i++;
|
||||
my $el = HMCCU_GetEnumValues ($ioHash, $paramDef, undef, '#');
|
||||
my $min;
|
||||
my $max;
|
||||
foreach my $e (split(',',$el)) {
|
||||
my ($cNam, $cVal) = split (':', $e);
|
||||
$min = $cVal if (!defined($min) || $cVal<$min);
|
||||
$max = $cVal if (!defined($max) || $cVal>$max);
|
||||
$clHash->{hmccu}{roleCmds}{$cmdType}{$cmd}{subcmd}{$scn}{look}{$cNam} = $cVal;
|
||||
}
|
||||
|
||||
# Parameter definition contains names for min and max value
|
||||
$clHash->{hmccu}{roleCmds}{$cmdType}{$cmd}{subcmd}{$scn}{min} =
|
||||
$clHash->{hmccu}{roleCmds}{$cmdType}{$cmd}{subcmd}{$scn}{look}{$paramDef->{MIN}}
|
||||
if (exists($clHash->{hmccu}{roleCmds}{$cmdType}{$cmd}{subcmd}{$scn}{look}{$paramDef->{MIN}}));
|
||||
$clHash->{hmccu}{roleCmds}{$cmdType}{$cmd}{subcmd}{$scn}{max} =
|
||||
$clHash->{hmccu}{roleCmds}{$cmdType}{$cmd}{subcmd}{$scn}{look}{$paramDef->{MAX}}
|
||||
if (exists($clHash->{hmccu}{roleCmds}{$cmdType}{$cmd}{subcmd}{$scn}{look}{$paramDef->{MAX}}));
|
||||
$clHash->{hmccu}{roleCmds}{$cmdType}{$cmd}{subcmd}{$scn}{min} = $min;
|
||||
$clHash->{hmccu}{roleCmds}{$cmdType}{$cmd}{subcmd}{$scn}{max} = $max;
|
||||
}
|
||||
|
||||
if (defined($par) && $par ne '') {
|
||||
@ -7325,7 +7310,7 @@ sub HMCCU_ExecuteRoleCommand ($@)
|
||||
}
|
||||
|
||||
# Align new value with min/max boundaries
|
||||
if (exists($cmd->{min}) && exists($cmd->{max})) {
|
||||
if (exists($cmd->{min}) && exists($cmd->{max}) && HMCCU_IsFltNum($cmd->{min}) && HMCCU_IsFltNum($cmd->{max})) {
|
||||
# Use mode = 0 in HMCCU_ScaleValue to get the min and max value allowed
|
||||
HMCCU_Trace ($clHash, 2, "MinMax: value=$value, min=$cmd->{min}, max=$cmd->{max}");
|
||||
my $scMin = HMCCU_ScaleValue ($clHash, $channel, $cmd->{dpt}, $cmd->{min}, 2);
|
||||
@ -9230,9 +9215,7 @@ sub HMCCU_SetMultipleDatapoints ($$)
|
||||
$v = "'".$v."'";
|
||||
}
|
||||
elsif ($paramDef->{TYPE} eq 'ENUM' && !HMCCU_IsIntNum($v)) {
|
||||
HMCCU_Log ($clHash, 2, "Enum datapoint value = $v");
|
||||
$v = HMCCU_GetEnumValues ($ioHash, $paramDef, $dpt, $v);
|
||||
HMCCU_Log ($clHash, 2, "Enum datapoint number = $v");
|
||||
}
|
||||
}
|
||||
# my $dptType = HMCCU_GetDatapointAttr ($ioHash, $ccuType, $chn, $dpt, 'type');
|
||||
@ -9293,8 +9276,8 @@ sub HMCCU_ScaleValue ($$$$$;$)
|
||||
}
|
||||
my $paramDef = HMCCU_GetParamDef ($ioHash, $ccuaddr, $paramSet, $dpt);
|
||||
if (defined($paramDef)) {
|
||||
$min = $paramDef->{MIN} if (defined($paramDef->{MIN}) && $paramDef->{MIN} ne '');
|
||||
$max = $paramDef->{MAX} if (defined($paramDef->{MAX}) && $paramDef->{MAX} ne '');
|
||||
$min = $paramDef->{MIN} if (defined($paramDef->{MIN}) && $paramDef->{MIN} ne '' && HMCCU_IsFltNum($paramDef->{MIN}));
|
||||
$max = $paramDef->{MAX} if (defined($paramDef->{MAX}) && $paramDef->{MAX} ne '' && HMCCU_IsFltNum($paramDef->{MAX}));
|
||||
$unit = $paramDef->{UNIT};
|
||||
$unit = '100%' if (!defined($unit) && ($dpt eq 'LEVEL' || $dpt eq 'LEVEL_2' || $dpt eq 'LEVEL_SLATS'));
|
||||
}
|
||||
@ -10014,8 +9997,8 @@ sub HMCCU_Max ($$)
|
||||
sub HMCCU_MinMax ($$$)
|
||||
{
|
||||
my ($v, $min, $max) = @_;
|
||||
$min = $v if (!defined($min) || $min eq '');
|
||||
$max = $min if (!defined($max) || $max eq '');
|
||||
$min = $v if (!defined($min) || $min eq '' || !HMCCU_IsFltNum($min));
|
||||
$max = $min if (!defined($max) || $max eq '' || !HMCCU_IsFltNum($max));
|
||||
|
||||
return HMCCU_Max (HMCCU_Min ($v, $max), $min);
|
||||
}
|
||||
@ -10683,11 +10666,12 @@ sub HMCCU_MaxHashEntries ($$)
|
||||
<br/><br/>
|
||||
<ul>
|
||||
<li>Define used RPC interfaces with attribute 'rpcinterfaces'</li>
|
||||
<li>Start RPC servers with command 'set rpcserver on'</li>
|
||||
<li>Optionally enable automatic start of RPC servers with attribute 'rpcserver'</li>
|
||||
<li>Start RPC servers with command 'set on'</li>
|
||||
<li>Optionally enable automatic start of RPC servers by setting attribute 'rpcserver' to 'on'.</li>
|
||||
</ul><br/>
|
||||
When RPC servers are started for the first time, HMCCU will create a HMCCURPCPROC device for
|
||||
each interface defined in attribut 'rpcinterfaces'.<br/>
|
||||
each interface defined in attribut 'rpcinterfaces'. These devices are assigned xto the same room
|
||||
as I/O device.<br/>
|
||||
After I/O device has been defined, start with the definition of client devices using modules HMCCUDEV (CCU devices)
|
||||
and HMCCUCHN (CCU channels) or with commands 'get createDev' or 'get create'.<br/>
|
||||
</ul>
|
||||
|
@ -30,7 +30,7 @@ sub HMCCUCHN_Set ($@);
|
||||
sub HMCCUCHN_Get ($@);
|
||||
sub HMCCUCHN_Attr ($@);
|
||||
|
||||
my $HMCCUCHN_VERSION = '5.0 213491649';
|
||||
my $HMCCUCHN_VERSION = '5.0 213551543';
|
||||
|
||||
######################################################################
|
||||
# Initialize module
|
||||
|
@ -31,7 +31,7 @@ sub HMCCUDEV_Set ($@);
|
||||
sub HMCCUDEV_Get ($@);
|
||||
sub HMCCUDEV_Attr ($@);
|
||||
|
||||
my $HMCCUDEV_VERSION = '5.0 213491649';
|
||||
my $HMCCUDEV_VERSION = '5.0 213551543';
|
||||
|
||||
######################################################################
|
||||
# Initialize module
|
||||
|
@ -39,7 +39,7 @@ require "$attr{global}{modpath}/FHEM/88_HMCCU.pm";
|
||||
######################################################################
|
||||
|
||||
# HMCCURPC version
|
||||
my $HMCCURPCPROC_VERSION = '5.0 213491649';
|
||||
my $HMCCURPCPROC_VERSION = '5.0 213551543';
|
||||
|
||||
# Maximum number of events processed per call of Read()
|
||||
my $HMCCURPCPROC_MAX_EVENTS = 100;
|
||||
@ -1447,6 +1447,7 @@ sub HMCCURPCPROC_InitRPCServer ($$$$)
|
||||
######################################################################
|
||||
# Start RPC server process
|
||||
# Return (State, Msg)
|
||||
# State: 0=Error, 1=Started, 2=Already running
|
||||
######################################################################
|
||||
|
||||
sub HMCCURPCPROC_StartRPCServer ($)
|
||||
@ -1461,7 +1462,7 @@ sub HMCCURPCPROC_StartRPCServer ($)
|
||||
if (!exists($hash->{hmccu}{localaddr}) || !exists($hash->{rpcid}));
|
||||
|
||||
# Check if RPC server is already running
|
||||
return (0, 'RPC server already running') if (HMCCURPCPROC_CheckProcessState ($hash, 'running'));
|
||||
return (2, 'RPC server already running') if (HMCCURPCPROC_CheckProcessState ($hash, 'running'));
|
||||
|
||||
# Get parameters and attributes
|
||||
my $ping = AttrVal ($ioHash->{NAME}, 'rpcPingCCU', $HMCCURPCPROC_TIME_PING);
|
||||
|
Loading…
Reference in New Issue
Block a user