]> git.basschouten.com Git - openhab-addons.git/commitdiff
[knx] Fix DPT 6.020 and 8.010 (#16453)
authorHolger Friedrich <mail@holger-friedrich.de>
Sun, 25 Feb 2024 10:59:19 +0000 (11:59 +0100)
committerGitHub <noreply@github.com>
Sun, 25 Feb 2024 10:59:19 +0000 (11:59 +0100)
Signed-off-by: Holger Friedrich <mail@holger-friedrich.de>
bundles/org.openhab.binding.knx/src/main/java/org/openhab/binding/knx/internal/dpt/DPTUtil.java
bundles/org.openhab.binding.knx/src/main/java/org/openhab/binding/knx/internal/dpt/ValueDecoder.java
bundles/org.openhab.binding.knx/src/main/java/org/openhab/binding/knx/internal/dpt/ValueEncoder.java
bundles/org.openhab.binding.knx/src/test/java/org/openhab/binding/knx/internal/dpt/DPTTest.java
bundles/org.openhab.binding.knx/src/test/java/org/openhab/binding/knx/internal/itests/Back2BackTest.java

index c3c7479e377c9199981758e391cb4f8f1771603e..27ec1f3e87c1bc1e03a72fc7fa4b2f76a21d00d8 100644 (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)), //
index ad6cb704e3518b08609dd8a4e4c97664fe4a9b72..13376f1d2f92995ff65f12b284b90bb144a9057f 100644 (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":
index 582a57d561f9c0c05c0b360d4fc3df12f96ec8b6..232d4b8524247a42e2d516050a6aec65b303bcc0 100644 (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();
         }
index 45ce5f8521b26df94846639bae1e85b760e0d26e..d20b550472449b0c06fbae8cfc4d5974bb2b31c5 100644 (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
index 00e12f857cbbf23c2b9f79d26e67441baa61bcd0..48424413d3e44e3abf721c6fc898a1aec26eb851 100644 (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