]> git.basschouten.com Git - openhab-addons.git/commitdiff
[knx] DPT 1 to support Switch and Contact (#16238)
authorHolger Friedrich <mail@holger-friedrich.de>
Sun, 21 Jan 2024 20:43:21 +0000 (21:43 +0100)
committerGitHub <noreply@github.com>
Sun, 21 Jan 2024 20:43:21 +0000 (21:43 +0100)
* Allow assigning Switch or Contact to most of the DPT 1 subtypes
(exceptions 1.008 UpDownType, 1.010 StopMoveType, 1.022 DecimalType).
* Tests for all published subtypes for DPT 1.
* Fix sending of DPT 1.022.

Signed-off-by: Holger Friedrich <mail@holger-friedrich.de>
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/itests/Back2BackTest.java

index 9969b6bc0ad319f8a89f05c8c52631f2d33e9ec6..1fc19b0ce423738d4729627d03552fc70eaf6a63 100644 (file)
@@ -116,7 +116,7 @@ public class ValueDecoder {
 
             switch (mainType) {
                 case "1":
-                    return handleDpt1(subType, translator);
+                    return handleDpt1(subType, translator, preferredType);
                 case "2":
                     DPTXlator1BitControlled translator1BitControlled = (DPTXlator1BitControlled) translator;
                     int decValue = (translator1BitControlled.getControlBit() ? 2 : 0)
@@ -172,13 +172,18 @@ public class ValueDecoder {
         return null;
     }
 
-    private static Type handleDpt1(String subType, DPTXlator translator) {
+    private static Type handleDpt1(String subType, DPTXlator translator, Class<? extends Type> preferredType) {
         DPTXlatorBoolean translatorBoolean = (DPTXlatorBoolean) translator;
         switch (subType) {
             case "008":
                 return translatorBoolean.getValueBoolean() ? UpDownType.DOWN : UpDownType.UP;
             case "009":
             case "019":
+                // default is OpenClosedType (Contact), but it may be mapped to OnOffType as well
+                if (OnOffType.class.equals(preferredType)) {
+                    return OnOffType.from(translatorBoolean.getValueBoolean());
+                }
+
                 // This is wrong for DPT 1.009. It should be true -> CLOSE, false -> OPEN, but unfortunately
                 // can't be fixed without breaking a lot of working installations.
                 // The documentation has been updated to reflect that. / @J-N-K
@@ -188,6 +193,11 @@ public class ValueDecoder {
             case "022":
                 return DecimalType.valueOf(translatorBoolean.getValueBoolean() ? "1" : "0");
             default:
+                // default is OnOffType (Switch), but it may be mapped to OpenClosedType as well
+                if (OpenClosedType.class.equals(preferredType)) {
+                    return translatorBoolean.getValueBoolean() ? OpenClosedType.OPEN : OpenClosedType.CLOSED;
+                }
+
                 return OnOffType.from(translatorBoolean.getValueBoolean());
         }
     }
index 0a1688082f9bdd3ec8c424c6583f50610e9ca2b7..cbf5de4bab04d9eb77e34a4674588b4375393b2f 100644 (file)
@@ -47,6 +47,7 @@ import tuwien.auto.calimero.dptxlator.DPTXlator1BitControlled;
 import tuwien.auto.calimero.dptxlator.DPTXlator2ByteFloat;
 import tuwien.auto.calimero.dptxlator.DPTXlator3BitControlled;
 import tuwien.auto.calimero.dptxlator.DPTXlator4ByteFloat;
+import tuwien.auto.calimero.dptxlator.DPTXlatorBoolean;
 import tuwien.auto.calimero.dptxlator.DPTXlatorDate;
 import tuwien.auto.calimero.dptxlator.DPTXlatorDateTime;
 import tuwien.auto.calimero.dptxlator.DPTXlatorTime;
@@ -236,6 +237,11 @@ public class ValueEncoder {
             }
         }
         switch (mainNumber) {
+            case "1":
+                if (DPTXlatorBoolean.DPT_SCENE_AB.getID().equals(dptId)) {
+                    return (bigDecimal.intValue() == 0) ? dpt.getLowerValue() : dpt.getUpperValue();
+                }
+                return bigDecimal.stripTrailingZeros().toPlainString();
             case "2":
                 DPT valueDPT = ((DPTXlator1BitControlled.DPT1BitControlled) dpt).getValueDPT();
                 switch (bigDecimal.intValue()) {
index 29708a7af9448927ac9ca8d55436cf4d66c6f04e..80499040032e626829eca36438501131d2d72ea9 100644 (file)
@@ -190,40 +190,112 @@ public class Back2BackTest {
 
     @Test
     void testDpt1() {
-        // for now only the DPTs for general use, others omitted
-        // TODO add tests for more subtypes
-
         helper("1.001", new byte[] { 0 }, OnOffType.OFF);
         helper("1.001", new byte[] { 1 }, OnOffType.ON);
+        helper("1.001", new byte[] { 0 }, OpenClosedType.CLOSED);
+        helper("1.001", new byte[] { 1 }, OpenClosedType.OPEN);
         helper("1.002", new byte[] { 0 }, OnOffType.OFF);
         helper("1.002", new byte[] { 1 }, OnOffType.ON);
+        helper("1.002", new byte[] { 0 }, OpenClosedType.CLOSED);
+        helper("1.002", new byte[] { 1 }, OpenClosedType.OPEN);
         helper("1.003", new byte[] { 0 }, OnOffType.OFF);
         helper("1.003", new byte[] { 1 }, OnOffType.ON);
-
+        helper("1.003", new byte[] { 0 }, OpenClosedType.CLOSED);
+        helper("1.003", new byte[] { 1 }, OpenClosedType.OPEN);
+        helper("1.004", new byte[] { 0 }, OnOffType.OFF);
+        helper("1.004", new byte[] { 1 }, OnOffType.ON);
+        helper("1.004", new byte[] { 0 }, OpenClosedType.CLOSED);
+        helper("1.004", new byte[] { 1 }, OpenClosedType.OPEN);
+        helper("1.005", new byte[] { 0 }, OnOffType.OFF);
+        helper("1.005", new byte[] { 1 }, OnOffType.ON);
+        helper("1.005", new byte[] { 0 }, OpenClosedType.CLOSED);
+        helper("1.005", new byte[] { 1 }, OpenClosedType.OPEN);
+        helper("1.006", new byte[] { 0 }, OnOffType.OFF);
+        helper("1.006", new byte[] { 1 }, OnOffType.ON);
+        helper("1.006", new byte[] { 0 }, OpenClosedType.CLOSED);
+        helper("1.006", new byte[] { 1 }, OpenClosedType.OPEN);
+        helper("1.007", new byte[] { 0 }, OnOffType.OFF);
+        helper("1.007", new byte[] { 1 }, OnOffType.ON);
+        helper("1.007", new byte[] { 0 }, OpenClosedType.CLOSED);
+        helper("1.007", new byte[] { 1 }, OpenClosedType.OPEN);
         helper("1.008", new byte[] { 0 }, UpDownType.UP);
         helper("1.008", new byte[] { 1 }, UpDownType.DOWN);
         // NOTE: This is how DPT 1.009 is defined: 0: open, 1: closed
         // For historical reasons it is defined the other way on OH
+        helper("1.009", new byte[] { 0 }, OnOffType.OFF);
+        helper("1.009", new byte[] { 1 }, OnOffType.ON);
         helper("1.009", new byte[] { 0 }, OpenClosedType.CLOSED);
         helper("1.009", new byte[] { 1 }, OpenClosedType.OPEN);
         helper("1.010", new byte[] { 0 }, StopMoveType.STOP);
         helper("1.010", new byte[] { 1 }, StopMoveType.MOVE);
-
+        helper("1.011", new byte[] { 0 }, OnOffType.OFF);
+        helper("1.011", new byte[] { 1 }, OnOffType.ON);
+        helper("1.011", new byte[] { 0 }, OpenClosedType.CLOSED);
+        helper("1.011", new byte[] { 1 }, OpenClosedType.OPEN);
+        helper("1.012", new byte[] { 0 }, OnOffType.OFF);
+        helper("1.012", new byte[] { 1 }, OnOffType.ON);
+        helper("1.012", new byte[] { 0 }, OpenClosedType.CLOSED);
+        helper("1.012", new byte[] { 1 }, OpenClosedType.OPEN);
+        helper("1.013", new byte[] { 0 }, OnOffType.OFF);
+        helper("1.013", new byte[] { 1 }, OnOffType.ON);
+        helper("1.013", new byte[] { 0 }, OpenClosedType.CLOSED);
+        helper("1.013", new byte[] { 1 }, OpenClosedType.OPEN);
+        helper("1.014", new byte[] { 0 }, OnOffType.OFF);
+        helper("1.014", new byte[] { 1 }, OnOffType.ON);
+        helper("1.014", new byte[] { 0 }, OpenClosedType.CLOSED);
+        helper("1.014", new byte[] { 1 }, OpenClosedType.OPEN);
         helper("1.015", new byte[] { 0 }, OnOffType.OFF);
         helper("1.015", new byte[] { 1 }, OnOffType.ON);
+        helper("1.015", new byte[] { 0 }, OpenClosedType.CLOSED);
+        helper("1.015", new byte[] { 1 }, OpenClosedType.OPEN);
         helper("1.016", new byte[] { 0 }, OnOffType.OFF);
         helper("1.016", new byte[] { 1 }, OnOffType.ON);
+        helper("1.016", new byte[] { 0 }, OpenClosedType.CLOSED);
+        helper("1.016", new byte[] { 1 }, OpenClosedType.OPEN);
         // DPT 1.017 is a special case, "trigger" has no "value", both 0 and 1 shall trigger
         helper("1.017", new byte[] { 0 }, OnOffType.OFF);
+        helper("1.017", new byte[] { 0 }, OpenClosedType.CLOSED);
         // Calimero maps it always to 0
         // helper("1.017", new byte[] { 1 }, OnOffType.ON);
         helper("1.018", new byte[] { 0 }, OnOffType.OFF);
         helper("1.018", new byte[] { 1 }, OnOffType.ON);
+        helper("1.018", new byte[] { 0 }, OpenClosedType.CLOSED);
+        helper("1.018", new byte[] { 1 }, OpenClosedType.OPEN);
+        helper("1.019", new byte[] { 0 }, OnOffType.OFF);
+        helper("1.019", new byte[] { 1 }, OnOffType.ON);
         helper("1.019", new byte[] { 0 }, OpenClosedType.CLOSED);
         helper("1.019", new byte[] { 1 }, OpenClosedType.OPEN);
 
+        helper("1.021", new byte[] { 0 }, OnOffType.OFF);
+        helper("1.021", new byte[] { 1 }, OnOffType.ON);
+        helper("1.021", new byte[] { 0 }, OpenClosedType.CLOSED);
+        helper("1.021", new byte[] { 1 }, OpenClosedType.OPEN);
+        // DPT 1.022 is mapped to decimal, Calimero does not follow the recommendation
+        // from KNX spec to add offset 1
+        helper("1.022", new byte[] { 0 }, DecimalType.valueOf("0"));
+        helper("1.022", new byte[] { 1 }, DecimalType.valueOf("1"));
+        helper("1.023", new byte[] { 0 }, OnOffType.OFF);
+        helper("1.023", new byte[] { 1 }, OnOffType.ON);
+        helper("1.023", new byte[] { 0 }, OpenClosedType.CLOSED);
+        helper("1.023", new byte[] { 1 }, OpenClosedType.OPEN);
         helper("1.024", new byte[] { 0 }, OnOffType.OFF);
         helper("1.024", new byte[] { 1 }, OnOffType.ON);
+        helper("1.024", new byte[] { 0 }, OpenClosedType.CLOSED);
+        helper("1.024", new byte[] { 1 }, OpenClosedType.OPEN);
+
+        helper("1.100", new byte[] { 0 }, OnOffType.OFF);
+        helper("1.100", new byte[] { 1 }, OnOffType.ON);
+        helper("1.100", new byte[] { 0 }, OpenClosedType.CLOSED);
+        helper("1.100", new byte[] { 1 }, OpenClosedType.OPEN);
+
+        helper("1.1200", new byte[] { 0 }, OnOffType.OFF);
+        helper("1.1200", new byte[] { 1 }, OnOffType.ON);
+        helper("1.1200", new byte[] { 0 }, OpenClosedType.CLOSED);
+        helper("1.1200", new byte[] { 1 }, OpenClosedType.OPEN);
+        helper("1.1201", new byte[] { 0 }, OnOffType.OFF);
+        helper("1.1201", new byte[] { 1 }, OnOffType.ON);
+        helper("1.1201", new byte[] { 0 }, OpenClosedType.CLOSED);
+        helper("1.1201", new byte[] { 1 }, OpenClosedType.OPEN);
     }
 
     @Test