2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-04-20 13:26:02 +00:00

10_KNX.pm: seperated limit and scale from encode/decode in order to avoid warnings and clean up

git-svn-id: https://svn.fhem.de/fhem/trunk@16828 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
andi291 2018-06-07 07:05:01 +00:00
parent aa0d5612d9
commit 47fd0cd326

View File

@ -1408,14 +1408,16 @@ KNX_checkAndClean ($$$)
return undef if ($found == 0); return undef if ($found == 0);
#get min #get min
my $min = $dpttypes{"$model"}{MIN}; #my $min = $dpttypes{"$model"}{MIN};
#if min is numeric, cast to min #if min is numeric, cast to min
$value = $min if (defined ($min) and ($min =~ /^[+-]?\d*[.,]?\d+/) and ($value < $min)); #$value = $min if (defined ($min) and ($min =~ /^[+-]?\d*[.,]?\d+/) and ($value < $min));
#get max #get max
my $max = $dpttypes{"$model"}{MAX}; #my $max = $dpttypes{"$model"}{MAX};
#if max is numeric, cast to max #if max is numeric, cast to max
$value = $max if (defined ($max) and ($max =~ /^[+-]?\d*[.,]?\d+/) and ($value > $max)); #$value = $max if (defined ($max) and ($max =~ /^[+-]?\d*[.,]?\d+/) and ($value > $max));
$value = KNX_limit ($hash, $value, $gadName);
Log3 ($name, 3, "check value: input-value $orgValue was casted to $value") if (not($orgValue eq $value)); Log3 ($name, 3, "check value: input-value $orgValue was casted to $value") if (not($orgValue eq $value));
Log3 ($name, 5, "check value: $value, gadName: $gadName, model: $model, pattern: $pattern"); Log3 ($name, 5, "check value: $value, gadName: $gadName, model: $model, pattern: $pattern");
@ -1424,6 +1426,107 @@ KNX_checkAndClean ($$$)
} }
#Private function to replace state-values
#############################
sub
KNX_replaceByRegex ($$$) {
my ($regAttr, $prefix, $input) = @_;
my $retVal = $input;
#execute regex, if defined
if (defined($regAttr))
{
#get array of given attributes
my @reg = split(" /", $regAttr);
my $tempVal = $prefix . $input;
#loop over all regex
foreach my $regex (@reg)
{
#trim leading and trailing slashes
$regex =~ s/^\/|\/$//gi;
#get pairs
my @regPair = split("\/", $regex);
#skip if not at least 2 values supplied
#next if (int(@regPair < 2));
next if (not defined($regPair[0]));
if (not defined ($regPair[1]))
{
#cut value
$tempVal =~ s/$regPair[0]//gi;
}
else
{
#replace value
$tempVal =~ s/$regPair[0]/$regPair[1]/gi;
}
#restore value
$retVal = $tempVal;
}
}
return $retVal;
}
#Private function to limit numeric values. Valid directions: encode, decode
#############################
sub
KNX_limit ($$$$) {
my ($hash, $value, $gadName, $direction) = @_;
my $name = $hash->{NAME};
my $model = $hash->{GADDETAILS}{$gadName}{MODEL};
my $retVal = $value;
#get correction details
my $factor = $dpttypes{$model}{FACTOR};
my $offset = $dpttypes{$model}{OFFSET};
#get limits
my $min = $dpttypes{"$model"}{MIN};
my $max = $dpttypes{"$model"}{MAX};
#only execute, if nummeric value
if (looks_like_number ($value))
{
#determine direction of scaling, do only if defined
if (defined ($direction))
{
if ($direction =~ m/^encode/i)
{
$retVal = $value / $factor if (defined ($factor));
$retVal = $value - $offset if (defined ($offset));
}
elsif ($direction =~ m/^decode/i)
{
#correct value
$retVal = $value + $offset if (defined ($offset));
$retVal = $value * $factor if (defined ($factor));
}
Log3 ($name, 5, "limit: FACTOR: $min" ) if (defined ($factor));
Log3 ($name, 5, "limit: OFFSET: $min" ) if (defined ($offset));
Log3 ($name, 5, "limit: scaled... Output: $retVal, Input: $value") if ($retVal != $value);
}
#limitValue
$retVal = $min if (defined ($min) and ($value < $min));
$retVal = $max if (defined ($max) and ($value > $max));
Log3 ($name, 5, "limit: MIN: $min" ) if (defined ($min));
Log3 ($name, 5, "limit: MAX: $min" ) if (defined ($max));
Log3 ($name, 5, "limit: casted... Output: $retVal, Input: $value" ) if ($retVal != $value);
}
else
{
#Log3 ($name, 2, "limit: did not execute any action. Value should be numeric, but wasn't...");
}
return $retVal;
}
#Private function to encode KNX-Message according DPT #Private function to encode KNX-Message according DPT
############################# #############################
sub sub
@ -1447,15 +1550,7 @@ KNX_encodeByDpt ($$$) {
Log3 ($name, 5, "encode model: $model, code: $code, value: $value"); Log3 ($name, 5, "encode model: $model, code: $code, value: $value");
#get correction details $value = KNX_limit ($hash, $value, $gadName, "ENCODE");
my $factor = $dpttypes{$model}{FACTOR};
my $offset = $dpttypes{$model}{OFFSET};
#correct value
$value /= $factor if (defined ($factor));
$value -= $offset if (defined ($offset));
Log3 ($name, 5, "encode normalized value: $value");
#Binary value #Binary value
if ($code eq "dpt1") if ($code eq "dpt1")
@ -1713,52 +1808,6 @@ KNX_encodeByDpt ($$$) {
return $hexval; return $hexval;
} }
#Private function to replace state-values
#############################
sub
KNX_replaceByRegex ($$$) {
my ($regAttr, $prefix, $input) = @_;
my $retVal = $input;
#execute regex, if defined
if (defined($regAttr))
{
#get array of given attributes
my @reg = split(" /", $regAttr);
my $tempVal = $prefix . $input;
#loop over all regex
foreach my $regex (@reg)
{
#trim leading and trailing slashes
$regex =~ s/^\/|\/$//gi;
#get pairs
my @regPair = split("\/", $regex);
#skip if not at least 2 values supplied
#next if (int(@regPair < 2));
next if (not defined($regPair[0]));
if (not defined ($regPair[1]))
{
#cut value
$tempVal =~ s/$regPair[0]//gi;
}
else
{
#replace value
$tempVal =~ s/$regPair[0]/$regPair[1]/gi;
}
#restore value
$retVal = $tempVal;
}
}
return $retVal;
}
#Private function to decode KNX-Message according DPT #Private function to decode KNX-Message according DPT
############################# #############################
sub sub
@ -1785,10 +1834,6 @@ KNX_decodeByDpt ($$$) {
my $min = $dpttypes{"$model"}{MIN}; my $min = $dpttypes{"$model"}{MIN};
my $max = $dpttypes{"$model"}{MAX}; my $max = $dpttypes{"$model"}{MAX};
#get correction details
my $factor = $dpttypes{$model}{FACTOR};
my $offset = $dpttypes{$model}{OFFSET};
#Binary value #Binary value
if ($code eq "dpt1") if ($code eq "dpt1")
{ {
@ -1824,21 +1869,13 @@ KNX_decodeByDpt ($$$) {
#get dim-direction #get dim-direction
$state = 0 - $state if (not ($numval & 8)); $state = 0 - $state if (not ($numval & 8));
#correct value
$state += $offset if (defined ($offset));
$state *= $factor if (defined ($factor));
$state = sprintf ("%.0f", $state); $state = sprintf ("%.0f", $state);
} }
#1-Octet unsigned value #1-Octet unsigned value
elsif ($code eq "dpt5") elsif ($code eq "dpt5")
{ {
$numval = hex ($value); $numval = hex ($value);
$state = $numval; $state = KNX_limit ($hash, $numval, $gadName, "DECODE");
#correct value
$state += $offset if (defined ($offset));
$state *= $factor if (defined ($factor));
$state = sprintf ("%.0f", $state); $state = sprintf ("%.0f", $state);
} }
@ -1847,11 +1884,7 @@ KNX_decodeByDpt ($$$) {
{ {
$numval = hex ($value); $numval = hex ($value);
$numval -= 0x100 if ($numval >= 0x80); $numval -= 0x100 if ($numval >= 0x80);
$state = $numval; $state = KNX_limit ($hash, $numval, $gadName, "DECODE");
#correct value
$state += $offset if (defined ($offset));
$state *= $factor if (defined ($factor));
$state = sprintf ("%.0f", $state); $state = sprintf ("%.0f", $state);
} }
@ -1859,11 +1892,7 @@ KNX_decodeByDpt ($$$) {
elsif ($code eq "dpt7") elsif ($code eq "dpt7")
{ {
$numval = hex ($value); $numval = hex ($value);
$state = $numval; $state = KNX_limit ($hash, $numval, $gadName, "DECODE");
#correct value
$state += $offset if (defined ($offset));
$state *= $factor if (defined ($factor));
$state = sprintf ("%.0f", $state); $state = sprintf ("%.0f", $state);
} }
@ -1872,11 +1901,7 @@ KNX_decodeByDpt ($$$) {
{ {
$numval = hex ($value); $numval = hex ($value);
$numval -= 0x10000 if ($numval >= 0x8000); $numval -= 0x10000 if ($numval >= 0x8000);
$state = $numval; $state = KNX_limit ($hash, $numval, $gadName, "DECODE");
#correct value
$state += $offset if (defined ($offset));
$state *= $factor if (defined ($factor));
$state = sprintf ("%.0f", $state); $state = sprintf ("%.0f", $state);
} }
@ -1891,9 +1916,7 @@ KNX_decodeByDpt ($$$) {
$mant = -(~($mant-1) & 0x07FF) if($sign == -1); $mant = -(~($mant-1) & 0x07FF) if($sign == -1);
$numval = (1 << $exp) * 0.01 * $mant; $numval = (1 << $exp) * 0.01 * $mant;
#correct value $numval = KNX_limit ($hash, $numval, $gadName, "DECODE");
$state += $offset if (defined ($offset));
$state *= $factor if (defined ($factor));
$state = sprintf ("%.2f","$numval"); $state = sprintf ("%.2f","$numval");
} }
@ -1924,11 +1947,7 @@ KNX_decodeByDpt ($$$) {
elsif ($code eq "dpt12") elsif ($code eq "dpt12")
{ {
$numval = hex ($value); $numval = hex ($value);
$state = $numval; $state = KNX_limit ($hash, $numval, $gadName, "DECODE");
#correct value
$state += $offset if (defined ($offset));
$state *= $factor if (defined ($factor));
$state = sprintf ("%.0f", $state); $state = sprintf ("%.0f", $state);
} }
@ -1937,11 +1956,7 @@ KNX_decodeByDpt ($$$) {
{ {
$numval = hex ($value); $numval = hex ($value);
$numval -= 4294967296 if ($numval >= 0x80000000); $numval -= 4294967296 if ($numval >= 0x80000000);
$state = $numval; $state = KNX_limit ($hash, $numval, $gadName, "DECODE");
#correct value
$state += $offset if (defined ($offset));
$state *= $factor if (defined ($factor));
$state = sprintf ("%.0f", $state); $state = sprintf ("%.0f", $state);
} }
@ -1949,10 +1964,7 @@ KNX_decodeByDpt ($$$) {
elsif ($code eq "dpt14") elsif ($code eq "dpt14")
{ {
$numval = unpack "f", pack "L", hex ($value); $numval = unpack "f", pack "L", hex ($value);
$numval = KNX_limit ($hash, $numval, $gadName, "DECODE");
#correct value
$state += $offset if (defined ($offset));
$state *= $factor if (defined ($factor));
$state = sprintf ("%.3f","$numval"); $state = sprintf ("%.3f","$numval");
} }
@ -2010,12 +2022,6 @@ KNX_decodeByDpt ($$$) {
return undef; return undef;
} }
#optionally limit
my $orgVal = $state;
$state = $min if (defined ($min) and ($state < $min));
$state = $max if (defined ($max) and ($state > $max));
Log3 ($name, 5, "decode: limited. OrgVal: $orgVal, state: $state") if ($orgVal != $state);
#append unit, if supplied #append unit, if supplied
my $unit = $dpttypes{$model}{UNIT}; my $unit = $dpttypes{$model}{UNIT};
$state = $state . " " . $unit if (defined ($unit) and not($unit eq "")); $state = $state . " " . $unit if (defined ($unit) and not($unit eq ""));