[knx] Fix DPT 6.020 and 8.010 (#16453)

Signed-off-by: Holger Friedrich <mail@holger-friedrich.de>
Signed-off-by: Ciprian Pascu <contact@ciprianpascu.ro>
This commit is contained in:
Holger Friedrich 2024-02-25 11:59:19 +01:00 committed by Ciprian Pascu
parent 921ed3b8b3
commit 10b76fbb31
5 changed files with 41 additions and 2 deletions

View File

@ -64,7 +64,7 @@ public class DPTUtil {
Map.entry("3", Set.of(IncreaseDecreaseType.class)), //
Map.entry("4", Set.of(StringType.class)), //
Map.entry("5", Set.of(QuantityType.class, DecimalType.class)), //
Map.entry("6", Set.of(QuantityType.class, DecimalType.class)), //
Map.entry("6", Set.of(QuantityType.class, DecimalType.class, StringType.class)), //
Map.entry("7", Set.of(QuantityType.class, DecimalType.class)), //
Map.entry("8", Set.of(QuantityType.class, DecimalType.class)), //
Map.entry("9", Set.of(QuantityType.class, DecimalType.class)), //

View File

@ -174,6 +174,12 @@ public class ValueDecoder {
return new DecimalType(decValue);
case "3":
return handleDpt3(subType, translator);
case "6":
if ("020".equals(subType)) {
return handleStringOrDecimal(data, value, preferredType, 8);
} else {
return handleNumericDpt(id, translator, preferredType);
}
case "10":
return handleDpt10(value);
case "11":

View File

@ -274,6 +274,14 @@ public class ValueEncoder {
} else {
return "activate " + intVal;
}
case "8":
if ("8.010".equals(dptId)) {
// 8.010 has a resolution of 0.01 and will be scaled. Calimero expects locale-specific separator.
return bigDecimal.stripTrailingZeros().toPlainString().replace('.',
((DecimalFormat) DecimalFormat.getInstance()).getDecimalFormatSymbols()
.getDecimalSeparator());
}
// fallthrough
default:
return bigDecimal.stripTrailingZeros().toPlainString();
}

View File

@ -14,6 +14,7 @@ package org.openhab.binding.knx.internal.dpt;
import static org.junit.jupiter.api.Assertions.*;
import java.text.DecimalFormat;
import java.util.Map;
import java.util.Objects;
import java.util.regex.Matcher;
@ -29,6 +30,7 @@ import org.openhab.core.library.types.DateTimeType;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.HSBType;
import org.openhab.core.library.types.QuantityType;
import org.openhab.core.library.types.StringType;
import org.openhab.core.library.unit.SIUnits;
import org.openhab.core.library.unit.Units;
import org.openhab.core.util.ColorUtil;
@ -95,6 +97,12 @@ class DPTTest {
assertEquals("1", ValueEncoder.encode(new QuantityType<>("1000 ms"), "8.005"));
assertEquals("1", ValueEncoder.encode(new QuantityType<>("60 s"), "8.006"));
assertEquals("1", ValueEncoder.encode(new QuantityType<>("60 min"), "8.007"));
// 8.010 has a resolution of 0.01 and will be scaled. Calimero expects locale-specific separator.
String target = "-327.68".replace('.',
((DecimalFormat) DecimalFormat.getInstance()).getDecimalFormatSymbols().getDecimalSeparator());
assertEquals(target, ValueEncoder.encode(new QuantityType<>("-327.68 %"), "8.010"));
assertEquals("-327.68 %", Objects
.toString(ValueDecoder.decode("8.010", new byte[] { (byte) 0x80, (byte) 0x00 }, QuantityType.class)));
assertEquals("180", ValueEncoder.encode(new QuantityType<>("180 °"), "8.011"));
assertEquals("1000", ValueEncoder.encode(new QuantityType<>("1 km"), "8.012"));
@ -298,6 +306,19 @@ class DPTTest {
assertEquals("42", ValueEncoder.encode(new QuantityType<>("42 varh"), "29.012"));
}
@Test
public void dpt6Value() {
assertEquals("42", ValueEncoder.encode(new DecimalType(42), "6.001"));
assertEquals("42", ValueEncoder.encode(new DecimalType(42), "6.010"));
assertEquals("0/0/0/0/1 0", Objects.toString(ValueDecoder.decode("6.020", new byte[] { 9 }, StringType.class)));
assertEquals("0/0/0/0/0 1", Objects.toString(ValueDecoder.decode("6.020", new byte[] { 2 }, StringType.class)));
assertEquals("1/1/1/1/1 2",
Objects.toString(ValueDecoder.decode("6.020", new byte[] { (byte) 0xfc }, StringType.class)));
assertEquals("0/0/0/0/1 0", ValueEncoder.encode(StringType.valueOf("0/0/0/0/1 0"), "6.020"));
}
@Test
public void dpt232RgbValue() {
// input data

View File

@ -365,6 +365,8 @@ public class Back2BackTest {
helper("6.010", new byte[] { 0 }, new DecimalType(0));
helper("6.010", new byte[] { (byte) 0x7f }, new DecimalType(127));
helper("6.010", new byte[] { (byte) 0xff }, new DecimalType(-1));
helper("6.020", new byte[] { 9 }, StringType.valueOf("0/0/0/0/1 0"));
}
@Test
@ -437,6 +439,7 @@ public class Back2BackTest {
helper("8.007", new byte[] { (byte) 0x7f, (byte) 0xff }, new QuantityType<>("32767 h"));
helper("8.007", new byte[] { (byte) 0x00, (byte) 0x00 }, new QuantityType<>("0 h"));
helper("8.010", new byte[] { (byte) 0x80, (byte) 0x00 }, new QuantityType<>("-327.68 %"));
helper("8.011", new byte[] { (byte) 0x80, (byte) 0x00 }, new QuantityType<>("-32768 °"));
helper("8.011", new byte[] { (byte) 0x7f, (byte) 0xff }, new QuantityType<>("32767 °"));
helper("8.011", new byte[] { (byte) 0x00, (byte) 0x00 }, new QuantityType<>("0 °"));
@ -472,10 +475,10 @@ public class Back2BackTest {
helper("9.004", new byte[] { (byte) 0x07, (byte) 0xff }, new QuantityType<>("20.47 lx"));
helper("9.004", new byte[] { (byte) 0x7f, (byte) 0xfe }, new QuantityType<>("670433.28 lx"));
helper("9.004", new byte[] { (byte) 0x00, (byte) 0x00 }, new QuantityType<>("0 lx"));
// no negative values allowed for DPTs 9.004-9.008
helper("9.005", new byte[] { (byte) 0x07, (byte) 0xff }, new QuantityType<>("20.47 m/s"));
helper("9.005", new byte[] { (byte) 0x7f, (byte) 0xfe }, new QuantityType<>("670433.28 m/s"));
helper("9.005", new byte[] { (byte) 0x00, (byte) 0x00 }, new QuantityType<>("0 m/s"));
// no negative values allowed for DPTs 9.005-9.008
helper("9.005", new byte[] { (byte) 0x07, (byte) 0xff }, new QuantityType<>("20.47 m/s"));
helper("9.005", new byte[] { (byte) 0x7f, (byte) 0xfe }, new QuantityType<>("670433.28 m/s"));
helper("9.005", new byte[] { (byte) 0x00, (byte) 0x00 }, new QuantityType<>("0 m/s"));
@ -804,6 +807,7 @@ public class Back2BackTest {
new DateTimeType("2019-07-15T17:30:00"), new byte[0], new byte[] { 0, 0, 0, 0, 0, 0, 0, 1 });
helper("19.001", new byte[] { (byte) (2019 - 1900), 7, 15, 17, 30, 0, (byte) 0x24, (byte) 0x00 },
new DateTimeType("2019-07-15T17:30:00"), new byte[0], new byte[] { 0, 0, 0, 0, 0, 0, 0, 1 });
// TODO add tests for incompletly filled frames (e.g. containing only date or time)
}
@Test