]> git.basschouten.com Git - openhab-addons.git/commitdiff
[caddx] Add new channels and support for ignoring zone status transitions (#10923)
authorGeorgios Moutsos <50378548+jossuar@users.noreply.github.com>
Fri, 16 Jul 2021 12:43:37 +0000 (15:43 +0300)
committerGitHub <noreply@github.com>
Fri, 16 Jul 2021 12:43:37 +0000 (14:43 +0200)
* Cleanup of binding configuration classes
* Added context to CaddxMessage
* Logging enhancements
* Added support for ignoring Zone Status Transitions

Signed-off-by: Georgios Moutsos <georgios.moutsos@gmail.com>
20 files changed:
bundles/org.openhab.binding.caddx/README.md
bundles/org.openhab.binding.caddx/src/main/java/org/openhab/binding/caddx/internal/CaddxCommunicator.java
bundles/org.openhab.binding.caddx/src/main/java/org/openhab/binding/caddx/internal/CaddxEvent.java
bundles/org.openhab.binding.caddx/src/main/java/org/openhab/binding/caddx/internal/CaddxMessage.java
bundles/org.openhab.binding.caddx/src/main/java/org/openhab/binding/caddx/internal/CaddxMessageContext.java [new file with mode: 0644]
bundles/org.openhab.binding.caddx/src/main/java/org/openhab/binding/caddx/internal/CaddxMessageType.java
bundles/org.openhab.binding.caddx/src/main/java/org/openhab/binding/caddx/internal/CaddxPanelListener.java
bundles/org.openhab.binding.caddx/src/main/java/org/openhab/binding/caddx/internal/config/CaddxBridgeConfiguration.java
bundles/org.openhab.binding.caddx/src/main/java/org/openhab/binding/caddx/internal/config/CaddxPartitionConfiguration.java
bundles/org.openhab.binding.caddx/src/main/java/org/openhab/binding/caddx/internal/handler/CaddxBaseThingHandler.java
bundles/org.openhab.binding.caddx/src/main/java/org/openhab/binding/caddx/internal/handler/CaddxBridgeHandler.java
bundles/org.openhab.binding.caddx/src/main/java/org/openhab/binding/caddx/internal/handler/ThingHandlerKeypad.java
bundles/org.openhab.binding.caddx/src/main/java/org/openhab/binding/caddx/internal/handler/ThingHandlerPanel.java
bundles/org.openhab.binding.caddx/src/main/java/org/openhab/binding/caddx/internal/handler/ThingHandlerPartition.java
bundles/org.openhab.binding.caddx/src/main/java/org/openhab/binding/caddx/internal/handler/ThingHandlerZone.java
bundles/org.openhab.binding.caddx/src/main/resources/OH-INF/thing/bridge.xml
bundles/org.openhab.binding.caddx/src/main/resources/OH-INF/thing/panel.xml
bundles/org.openhab.binding.caddx/src/test/java/org/openhab/binding/caddx/internal/CaddxMessageReaderUtil.java
bundles/org.openhab.binding.caddx/src/test/java/org/openhab/binding/caddx/internal/message/CaddxMessageParseTest.java
bundles/org.openhab.binding.caddx/src/test/resources/org/openhab/binding/caddx/internal/zones_snapshot_message.msg [new file with mode: 0644]

index df46713c9e722742b887106becea192da3e3c9a8..e59408a1df307cffbeb3747ae6305863767d54bd 100644 (file)
@@ -125,6 +125,9 @@ Caddx Alarm things support a variety of channels as seen below in the following
 | panel_primary_keypad_function_without_pin        | Switch    | Configuration       | Primary Keypad Function without PIN        |
 | panel_secondary_keypad_function                  | Switch    | Configuration       | Secondary Keypad Function                  |
 | panel_zone_bypass_toggle                         | Switch    | Configuration       | Zone Bypass Toggle                         |
+| panel_ac_fail                                    | Switch    | Configuration       | AC fail                                    |
+| panel_ac_power_on                                | Switch    | Configuration       | AC Power on                                |
+| panel_low_battery_memory                         | Switch    | Configuration       | Low Battery Memory                         |
 | partition_bypass_code_required                   | Switch    | Partition Condition | Bypass code required                       |
 | partition_fire_trouble                           | Switch    | Partition Condition | Fire trouble                               |
 | partition_fire                                   | Switch    | Partition Condition | Fire                                       |
index c06204c20f510b82aef8e28ada3c3604b061ef14..b5c3ed33d6492a19d787119445aac3f1b66ff04a 100644 (file)
@@ -179,17 +179,17 @@ public class CaddxCommunicator implements SerialPortEventListener {
 
     @SuppressWarnings("null")
     private void messageDispatchLoop() {
-        int @Nullable [] expectedMessageNumbers = null;
-
-        @Nullable
+        int[] expectedMessageNumbers = null;
         CaddxMessage outgoingMessage = null;
         boolean skipTransmit = true;
+        CaddxMessageContext context = null;
 
         try {
             // loop until the thread is interrupted, sending out messages
             while (!Thread.currentThread().isInterrupted()) {
                 // Initialize the state
                 outgoingMessage = null;
+                context = null;
                 expectedMessageNumbers = null;
 
                 if (!skipTransmit) {
@@ -203,6 +203,7 @@ public class CaddxCommunicator implements SerialPortEventListener {
                         out.flush();
 
                         expectedMessageNumbers = outgoingMessage.getReplyMessageNumbers();
+                        context = outgoingMessage.getContext();
 
                         // Log message
                         if (logger.isDebugEnabled()) {
@@ -248,10 +249,12 @@ public class CaddxCommunicator implements SerialPortEventListener {
                         if (incomingMessage.hasAcknowledgementFlag()) {
                             if (incomingMessage.isChecksumCorrect()) {
                                 // send ACK
-                                transmitFirst(new CaddxMessage(CaddxMessageType.POSITIVE_ACKNOWLEDGE, ""));
+                                transmitFirst(new CaddxMessage(CaddxMessageContext.NONE,
+                                        CaddxMessageType.POSITIVE_ACKNOWLEDGE, ""));
                             } else {
                                 // Send NAK
-                                transmitFirst(new CaddxMessage(CaddxMessageType.NEGATIVE_ACKNOWLEDGE, ""));
+                                transmitFirst(new CaddxMessage(CaddxMessageContext.NONE,
+                                        CaddxMessageType.NEGATIVE_ACKNOWLEDGE, ""));
                             }
                         }
                     }
@@ -289,7 +292,10 @@ public class CaddxCommunicator implements SerialPortEventListener {
                 if (incomingMessage != null) {
                     if (incomingMessage.isChecksumCorrect()) {
                         for (CaddxPanelListener listener : listenerQueue) {
-                            listener.caddxMessage(this, incomingMessage);
+                            if (context != null) {
+                                incomingMessage.setContext(context);
+                            }
+                            listener.caddxMessage(incomingMessage);
                         }
                     } else {
                         logger.warn(
@@ -367,7 +373,7 @@ public class CaddxCommunicator implements SerialPortEventListener {
         logger.trace("Offering received message");
 
         // Full message received in data byte array
-        CaddxMessage caddxMessage = new CaddxMessage(message, true);
+        CaddxMessage caddxMessage = new CaddxMessage(CaddxMessageContext.NONE, message, true);
         if (!exchanger.offer(caddxMessage, 3, TimeUnit.SECONDS)) {
             logger.debug("Offered message was not received");
         }
index ce33fd92b34fd516e658db2c5bf5f1d57b2ef222..2a1170ff16039f46ac2bdf87eb09f180c5dd1b01 100644 (file)
@@ -60,4 +60,18 @@ public class CaddxEvent extends EventObject {
     public @Nullable Integer getKeypad() {
         return keypad;
     }
+
+    /**
+     * Returns a string representation of a CaddxEvent.
+     *
+     */
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append(String.format("partition: %d, zone: %d, keypad: %d\r\n", partition, zone, keypad));
+        sb.append(caddxMessage.toString());
+
+        return sb.toString();
+    }
 }
index 150d4b223ae7b4368066a7c147651a09e447fc47..a0b3486a02fa0e5d29cc6f63e0775d2251e83aed 100644 (file)
@@ -40,8 +40,9 @@ public class CaddxMessage {
     private final byte checksum2In;
     private final byte checksum1Calc;
     private final byte checksum2Calc;
+    private CaddxMessageContext context;
 
-    public CaddxMessage(byte[] message, boolean withChecksum) {
+    public CaddxMessage(CaddxMessageContext context, byte[] message, boolean withChecksum) {
         if (withChecksum && message.length < 3) {
             logger.debug("CaddxMessage: The message should be at least 3 bytes long.");
             throw new IllegalArgumentException("The message should be at least 3 bytes long");
@@ -52,6 +53,7 @@ public class CaddxMessage {
         }
 
         // Received data
+        this.context = context;
         byte[] msg = message;
 
         // Fill in the checksum
@@ -94,7 +96,7 @@ public class CaddxMessage {
         processCaddxMessage();
     }
 
-    public CaddxMessage(CaddxMessageType type, String data) {
+    public CaddxMessage(CaddxMessageContext context, CaddxMessageType type, String data) {
         int length = type.length;
         String[] tokens = data.split("\\,");
         if (length != 1 && tokens.length != length - 1) {
@@ -102,6 +104,7 @@ public class CaddxMessage {
             throw new IllegalArgumentException("CaddxMessage: data has not the correct format.");
         }
 
+        this.context = context;
         byte[] msg = new byte[length];
         msg[0] = (byte) type.number;
         for (int i = 0; i < length - 1; i++) {
@@ -133,6 +136,14 @@ public class CaddxMessage {
         processCaddxMessage();
     }
 
+    public CaddxMessageContext getContext() {
+        return context;
+    }
+
+    public void setContext(CaddxMessageContext context) {
+        this.context = context;
+    }
+
     public byte getChecksum1In() {
         return checksum1In;
     }
@@ -259,6 +270,9 @@ public class CaddxMessage {
             return "Unknown message type";
         }
 
+        sb.append(String.format("Context: %s", context.toString()));
+        sb.append(System.lineSeparator());
+
         sb.append("Message: ");
         sb.append(String.format("%2s", Integer.toHexString(message[0])));
         sb.append(" ");
diff --git a/bundles/org.openhab.binding.caddx/src/main/java/org/openhab/binding/caddx/internal/CaddxMessageContext.java b/bundles/org.openhab.binding.caddx/src/main/java/org/openhab/binding/caddx/internal/CaddxMessageContext.java
new file mode 100644 (file)
index 0000000..dc02be0
--- /dev/null
@@ -0,0 +1,27 @@
+/**
+ * Copyright (c) 2010-2021 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.caddx.internal;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * Used to map thing types from the binding string to a ENUM value.
+ *
+ * @author Georgios Moutsos - Initial contribution
+ */
+@NonNullByDefault
+public enum CaddxMessageContext {
+    NONE,
+    DISCOVERY,
+    COMMAND;
+}
index 94f37e8d6063ecb73ffff285e12fb71f6d43c894..ad357576fc2c531315973b0afaeab4ee271525c7 100644 (file)
@@ -197,100 +197,134 @@ public enum CaddxMessageType {
                     false),
 
             // Byte 3 Zone 1 & 2 (+offset) status flags
-            new CaddxProperty("", 3, 1, 0, 1, CaddxPropertyType.BIT, "Zone 1 faulted (or delayed trip)", false),
-            new CaddxProperty("", 3, 1, 1, 1, CaddxPropertyType.BIT, "Zone 1 bypass (or inhibited)", false),
+            new CaddxProperty("zone_1_faulted", 3, 1, 0, 1, CaddxPropertyType.BIT, "Zone 1 faulted (or delayed trip)",
+                    false),
+            new CaddxProperty("zone_1_bypassed", 3, 1, 1, 1, CaddxPropertyType.BIT, "Zone 1 bypass (or inhibited)",
+                    false),
             new CaddxProperty("zone_1_trouble", 3, 1, 2, 1, CaddxPropertyType.BIT,
                     "Zone 1 trouble (tamper, low battery, or lost)", false),
-            new CaddxProperty("", 3, 1, 3, 1, CaddxPropertyType.BIT, "Zone 1 alarm memory", false),
-            new CaddxProperty("", 3, 1, 4, 1, CaddxPropertyType.BIT, "Zone 2 faulted (or delayed trip)", false),
-            new CaddxProperty("", 3, 1, 5, 1, CaddxPropertyType.BIT, "Zone 2 bypass (or inhibited)", false),
+            new CaddxProperty("zone_1_alarm_memory", 3, 1, 3, 1, CaddxPropertyType.BIT, "Zone 1 alarm memory", false),
+            new CaddxProperty("zone_2_faulted", 3, 1, 4, 1, CaddxPropertyType.BIT, "Zone 2 faulted (or delayed trip)",
+                    false),
+            new CaddxProperty("zone_2_bypassed", 3, 1, 5, 1, CaddxPropertyType.BIT, "Zone 2 bypass (or inhibited)",
+                    false),
             new CaddxProperty("zone_2_trouble", 3, 1, 6, 1, CaddxPropertyType.BIT,
                     "Zone 2 trouble (tamper, low battery, or lost)", false),
-            new CaddxProperty("", 3, 1, 7, 1, CaddxPropertyType.BIT, "Zone 2 alarm memory", false),
+            new CaddxProperty("zone_2_alarm_memory", 3, 1, 7, 1, CaddxPropertyType.BIT, "Zone 2 alarm memory", false),
 
             // Byte 4 Zone 3 & 4 status flags (see byte 3)
-            new CaddxProperty("", 4, 1, 0, 1, CaddxPropertyType.BIT, "Zone 3 faulted (or delayed trip)", false),
-            new CaddxProperty("", 4, 1, 1, 1, CaddxPropertyType.BIT, "Zone 3 bypass (or inhibited)", false),
+            new CaddxProperty("zone_3_faulted", 4, 1, 0, 1, CaddxPropertyType.BIT, "Zone 3 faulted (or delayed trip)",
+                    false),
+            new CaddxProperty("zone_3_bypassed", 4, 1, 1, 1, CaddxPropertyType.BIT, "Zone 3 bypass (or inhibited)",
+                    false),
             new CaddxProperty("zone_3_trouble", 4, 1, 2, 1, CaddxPropertyType.BIT,
                     "Zone 3 trouble (tamper, low battery, or lost)", false),
-            new CaddxProperty("", 4, 1, 3, 1, CaddxPropertyType.BIT, "Zone 3 alarm memory", false),
-            new CaddxProperty("", 4, 1, 4, 1, CaddxPropertyType.BIT, "Zone 4 faulted (or delayed trip)", false),
-            new CaddxProperty("", 4, 1, 5, 1, CaddxPropertyType.BIT, "Zone 4 bypass (or inhibited)", false),
+            new CaddxProperty("zone_3_alarm_memory", 4, 1, 3, 1, CaddxPropertyType.BIT, "Zone 3 alarm memory", false),
+            new CaddxProperty("zone_4_faulted", 4, 1, 4, 1, CaddxPropertyType.BIT, "Zone 4 faulted (or delayed trip)",
+                    false),
+            new CaddxProperty("zone_4_bypassed", 4, 1, 5, 1, CaddxPropertyType.BIT, "Zone 4 bypass (or inhibited)",
+                    false),
             new CaddxProperty("zone_4_trouble", 4, 1, 6, 1, CaddxPropertyType.BIT,
                     "Zone 4 trouble (tamper, low battery, or lost)", false),
-            new CaddxProperty("", 4, 1, 7, 1, CaddxPropertyType.BIT, "Zone 4 alarm memory", false),
+            new CaddxProperty("zone_4_alarm_memory", 4, 1, 7, 1, CaddxPropertyType.BIT, "Zone 4 alarm memory", false),
 
             // Byte 5 Zone 5 & 6 status flags (see byte 3)
-            new CaddxProperty("", 5, 1, 0, 1, CaddxPropertyType.BIT, "Zone 5 faulted (or delayed trip)", false),
-            new CaddxProperty("", 5, 1, 1, 1, CaddxPropertyType.BIT, "Zone 5 bypass (or inhibited)", false),
+            new CaddxProperty("zone_5_faulted", 5, 1, 0, 1, CaddxPropertyType.BIT, "Zone 5 faulted (or delayed trip)",
+                    false),
+            new CaddxProperty("zone_5_bypassed", 5, 1, 1, 1, CaddxPropertyType.BIT, "Zone 5 bypass (or inhibited)",
+                    false),
             new CaddxProperty("zone_5_trouble", 5, 1, 2, 1, CaddxPropertyType.BIT,
                     "Zone 5 trouble (tamper, low battery, or lost)", false),
-            new CaddxProperty("", 5, 1, 3, 1, CaddxPropertyType.BIT, "Zone 5 alarm memory", false),
-            new CaddxProperty("", 5, 1, 4, 1, CaddxPropertyType.BIT, "Zone 6 faulted (or delayed trip)", false),
-            new CaddxProperty("", 5, 1, 5, 1, CaddxPropertyType.BIT, "Zone 6 bypass (or inhibited)", false),
+            new CaddxProperty("zone_5_alarm_memory", 5, 1, 3, 1, CaddxPropertyType.BIT, "Zone 5 alarm memory", false),
+            new CaddxProperty("zone_6_faulted", 5, 1, 4, 1, CaddxPropertyType.BIT, "Zone 6 faulted (or delayed trip)",
+                    false),
+            new CaddxProperty("zone_6_bypassed", 5, 1, 5, 1, CaddxPropertyType.BIT, "Zone 6 bypass (or inhibited)",
+                    false),
             new CaddxProperty("zone_6_trouble", 5, 1, 6, 1, CaddxPropertyType.BIT,
                     "Zone 6 trouble (tamper, low battery, or lost)", false),
-            new CaddxProperty("", 5, 1, 7, 1, CaddxPropertyType.BIT, "Zone 6 alarm memory", false),
+            new CaddxProperty("zone_6_alarm_memory", 5, 1, 7, 1, CaddxPropertyType.BIT, "Zone 6 alarm memory", false),
 
             // Byte 6 Zone 7 & 8 status flags (see byte 3)
-            new CaddxProperty("", 6, 1, 0, 1, CaddxPropertyType.BIT, "Zone 7 faulted (or delayed trip)", false),
-            new CaddxProperty("", 6, 1, 1, 1, CaddxPropertyType.BIT, "Zone 7 bypass (or inhibited)", false),
+            new CaddxProperty("zone_7_faulted", 6, 1, 0, 1, CaddxPropertyType.BIT, "Zone 7 faulted (or delayed trip)",
+                    false),
+            new CaddxProperty("zone_7_bypassed", 6, 1, 1, 1, CaddxPropertyType.BIT, "Zone 7 bypass (or inhibited)",
+                    false),
             new CaddxProperty("zone_7_trouble", 6, 1, 2, 1, CaddxPropertyType.BIT,
                     "Zone 7 trouble (tamper, low battery, or lost)", false),
-            new CaddxProperty("", 6, 1, 3, 1, CaddxPropertyType.BIT, "Zone 7 alarm memory", false),
-            new CaddxProperty("", 6, 1, 4, 1, CaddxPropertyType.BIT, "Zone 8 faulted (or delayed trip)", false),
-            new CaddxProperty("", 6, 1, 5, 1, CaddxPropertyType.BIT, "Zone 8 bypass (or inhibited)", false),
+            new CaddxProperty("zone_7_alarm_memory", 6, 1, 3, 1, CaddxPropertyType.BIT, "Zone 7 alarm memory", false),
+            new CaddxProperty("zone_8_faulted", 6, 1, 4, 1, CaddxPropertyType.BIT, "Zone 8 faulted (or delayed trip)",
+                    false),
+            new CaddxProperty("zone_8_bypassed", 6, 1, 5, 1, CaddxPropertyType.BIT, "Zone 8 bypass (or inhibited)",
+                    false),
             new CaddxProperty("zone_8_trouble", 6, 1, 6, 1, CaddxPropertyType.BIT,
                     "Zone 8 trouble (tamper, low battery, or lost)", false),
-            new CaddxProperty("", 6, 1, 7, 1, CaddxPropertyType.BIT, "Zone 8 alarm memory", false),
+            new CaddxProperty("zone_8_alarm_memory", 6, 1, 7, 1, CaddxPropertyType.BIT, "Zone 8 alarm memory", false),
 
             // Byte 7 Zone 9 & 10 status flags (see byte 3)
-            new CaddxProperty("", 7, 1, 0, 1, CaddxPropertyType.BIT, "Zone 9 faulted (or delayed trip)", false),
-            new CaddxProperty("", 7, 1, 1, 1, CaddxPropertyType.BIT, "Zone 9 bypass (or inhibited)", false),
+            new CaddxProperty("zone_9_faulted", 7, 1, 0, 1, CaddxPropertyType.BIT, "Zone 9 faulted (or delayed trip)",
+                    false),
+            new CaddxProperty("zone_9_bypassed", 7, 1, 1, 1, CaddxPropertyType.BIT, "Zone 9 bypass (or inhibited)",
+                    false),
             new CaddxProperty("zone_9_trouble", 7, 1, 2, 1, CaddxPropertyType.BIT,
                     "Zone 9 trouble (tamper, low battery, or lost)", false),
-            new CaddxProperty("", 7, 1, 3, 1, CaddxPropertyType.BIT, "Zone 9 alarm memory", false),
-            new CaddxProperty("", 7, 1, 4, 1, CaddxPropertyType.BIT, "Zone 10 faulted (or delayed trip)", false),
-            new CaddxProperty("", 7, 1, 5, 1, CaddxPropertyType.BIT, "Zone 10 bypass (or inhibited)", false),
+            new CaddxProperty("zone_9_alarm_memory", 7, 1, 3, 1, CaddxPropertyType.BIT, "Zone 9 alarm memory", false),
+            new CaddxProperty("zone_10_faulted", 7, 1, 4, 1, CaddxPropertyType.BIT, "Zone 10 faulted (or delayed trip)",
+                    false),
+            new CaddxProperty("zone_10_bypassed", 7, 1, 5, 1, CaddxPropertyType.BIT, "Zone 10 bypass (or inhibited)",
+                    false),
             new CaddxProperty("zone_10_trouble", 7, 1, 6, 1, CaddxPropertyType.BIT,
                     "Zone 10 trouble (tamper, low battery, or lost)", false),
-            new CaddxProperty("", 7, 1, 7, 1, CaddxPropertyType.BIT, "Zone 10 alarm memory", false),
+            new CaddxProperty("zone_10_alarm_memory", 7, 1, 7, 1, CaddxPropertyType.BIT, "Zone 10 alarm memory", false),
 
             // Byte 8 Zone 11 & 12 status flags (see byte 3)
-            new CaddxProperty("", 8, 1, 0, 1, CaddxPropertyType.BIT, "Zone 11 faulted (or delayed trip)", false),
-            new CaddxProperty("", 8, 1, 1, 1, CaddxPropertyType.BIT, "Zone 11 bypass (or inhibited)", false),
+            new CaddxProperty("zone_11_faulted", 8, 1, 0, 1, CaddxPropertyType.BIT, "Zone 11 faulted (or delayed trip)",
+                    false),
+            new CaddxProperty("zone_11_bypassed", 8, 1, 1, 1, CaddxPropertyType.BIT, "Zone 11 bypass (or inhibited)",
+                    false),
             new CaddxProperty("zone_11_trouble", 8, 1, 2, 1, CaddxPropertyType.BIT,
                     "Zone 11 trouble (tamper, low battery, or lost)", false),
-            new CaddxProperty("", 8, 1, 3, 1, CaddxPropertyType.BIT, "Zone 11 alarm memory", false),
-            new CaddxProperty("", 8, 1, 4, 1, CaddxPropertyType.BIT, "Zone 12 faulted (or delayed trip)", false),
-            new CaddxProperty("", 8, 1, 5, 1, CaddxPropertyType.BIT, "Zone 12 bypass (or inhibited)", false),
+            new CaddxProperty("zone_11_alarm_memory", 8, 1, 3, 1, CaddxPropertyType.BIT, "Zone 11 alarm memory", false),
+            new CaddxProperty("zone_12_faulted", 8, 1, 4, 1, CaddxPropertyType.BIT, "Zone 12 faulted (or delayed trip)",
+                    false),
+            new CaddxProperty("zone_12_bypassed", 8, 1, 5, 1, CaddxPropertyType.BIT, "Zone 12 bypass (or inhibited)",
+                    false),
             new CaddxProperty("zone_12_trouble", 8, 1, 6, 1, CaddxPropertyType.BIT,
                     "Zone 12 trouble (tamper, low battery, or lost)", false),
-            new CaddxProperty("", 8, 1, 7, 1, CaddxPropertyType.BIT, "Zone 12 alarm memory", false),
+            new CaddxProperty("zone_12_alarm_memory", 8, 1, 7, 1, CaddxPropertyType.BIT, "Zone 12 alarm memory", false),
 
             // Byte 9 Zone 13 & 14 status flags (see byte 3)
-            new CaddxProperty("", 9, 1, 0, 1, CaddxPropertyType.BIT, "Zone 13 faulted (or delayed trip)", false),
-            new CaddxProperty("", 9, 1, 1, 1, CaddxPropertyType.BIT, "Zone 13 bypass (or inhibited)", false),
+            new CaddxProperty("zone_13_faulted", 9, 1, 0, 1, CaddxPropertyType.BIT, "Zone 13 faulted (or delayed trip)",
+                    false),
+            new CaddxProperty("zone_13_bypassed", 9, 1, 1, 1, CaddxPropertyType.BIT, "Zone 13 bypass (or inhibited)",
+                    false),
             new CaddxProperty("zone_13_trouble", 9, 1, 2, 1, CaddxPropertyType.BIT,
                     "Zone 13 trouble (tamper, low battery, or lost)", false),
-            new CaddxProperty("", 9, 1, 3, 1, CaddxPropertyType.BIT, "Zone 13 alarm memory", false),
-            new CaddxProperty("", 9, 1, 4, 1, CaddxPropertyType.BIT, "Zone 14 faulted (or delayed trip)", false),
-            new CaddxProperty("", 9, 1, 5, 1, CaddxPropertyType.BIT, "Zone 14 bypass (or inhibited)", false),
+            new CaddxProperty("zone_13_alarm_memory", 9, 1, 3, 1, CaddxPropertyType.BIT, "Zone 13 alarm memory", false),
+            new CaddxProperty("zone_14_faulted", 9, 1, 4, 1, CaddxPropertyType.BIT, "Zone 14 faulted (or delayed trip)",
+                    false),
+            new CaddxProperty("zone_14_bypassed", 9, 1, 5, 1, CaddxPropertyType.BIT, "Zone 14 bypass (or inhibited)",
+                    false),
             new CaddxProperty("zone_14_trouble", 9, 1, 6, 1, CaddxPropertyType.BIT,
                     "Zone 14 trouble (tamper, low battery, or lost)", false),
-            new CaddxProperty("", 9, 1, 7, 1, CaddxPropertyType.BIT, "Zone 14 alarm memory", false),
+            new CaddxProperty("zone_14_alarm_memory", 9, 1, 7, 1, CaddxPropertyType.BIT, "Zone 14 alarm memory", false),
 
             // Byte 10 Zone 15 & 16 status flags (see byte 3)
-            new CaddxProperty("", 10, 1, 0, 1, CaddxPropertyType.BIT, "Zone 15 faulted (or delayed trip)", false),
-            new CaddxProperty("", 10, 1, 1, 1, CaddxPropertyType.BIT, "Zone 15 bypass (or inhibited)", false),
+            new CaddxProperty("zone_15_faulted", 10, 1, 0, 1, CaddxPropertyType.BIT,
+                    "Zone 15 faulted (or delayed trip)", false),
+            new CaddxProperty("zone_15_bypassed", 10, 1, 1, 1, CaddxPropertyType.BIT, "Zone 15 bypass (or inhibited)",
+                    false),
             new CaddxProperty("zone_15_trouble", 10, 1, 2, 1, CaddxPropertyType.BIT,
                     "Zone 15 trouble (tamper, low battery, or lost)", false),
-            new CaddxProperty("", 10, 1, 3, 1, CaddxPropertyType.BIT, "Zone 15 alarm memory", false),
-            new CaddxProperty("", 10, 1, 4, 1, CaddxPropertyType.BIT, "Zone 16 faulted (or delayed trip)", false),
-            new CaddxProperty("", 10, 1, 5, 1, CaddxPropertyType.BIT, "Zone 16 bypass (or inhibited)", false),
+            new CaddxProperty("zone_15_alarm_memory", 10, 1, 3, 1, CaddxPropertyType.BIT, "Zone 15 alarm memory",
+                    false),
+            new CaddxProperty("zone_16_faulted", 10, 1, 4, 1, CaddxPropertyType.BIT,
+                    "Zone 16 faulted (or delayed trip)", false),
+            new CaddxProperty("zone_16_bypassed", 10, 1, 5, 1, CaddxPropertyType.BIT, "Zone 16 bypass (or inhibited)",
+                    false),
             new CaddxProperty("zone_16_trouble", 10, 1, 6, 1, CaddxPropertyType.BIT,
                     "Zone 16 trouble (tamper, low battery, or lost)", false),
-            new CaddxProperty("", 10, 1, 7, 1, CaddxPropertyType.BIT, "Zone 16 alarm memory", false)),
+            new CaddxProperty("zone_16_alarm_memory", 10, 1, 7, 1, CaddxPropertyType.BIT, "Zone 16 alarm memory",
+                    false)),
 
     PARTITION_STATUS_MESSAGE(0x06, null, 9, "Partition Status Message",
             "This message will contain all information relevant to a single partition in the system.",
@@ -508,7 +542,7 @@ public enum CaddxMessageType {
             new CaddxProperty("", 4, 1, 4, 1, CaddxPropertyType.BIT, "Box tamper", false),
             new CaddxProperty("", 4, 1, 5, 1, CaddxPropertyType.BIT, "Siren tamper / trouble", false),
             new CaddxProperty("", 4, 1, 6, 1, CaddxPropertyType.BIT, "Low Battery", false),
-            new CaddxProperty("", 4, 1, 7, 1, CaddxPropertyType.BIT, "AC fail", false),
+            new CaddxProperty("panel_ac_fail", 4, 1, 7, 1, CaddxPropertyType.BIT, "AC fail", false),
 
             // Byte 5
             new CaddxProperty("", 5, 1, 0, 1, CaddxPropertyType.BIT, "Expander box tamper", false),
@@ -531,8 +565,9 @@ public enum CaddxMessageType {
 
             // Byte 7
             new CaddxProperty("", 7, 1, 0, 1, CaddxPropertyType.BIT, "Dynamic battery test", false),
-            new CaddxProperty("", 7, 1, 1, 1, CaddxPropertyType.BIT, "AC power on", false),
-            new CaddxProperty("", 7, 1, 2, 1, CaddxPropertyType.BIT, "Low battery memory", false),
+            new CaddxProperty("panel_ac_power_on", 7, 1, 1, 1, CaddxPropertyType.BIT, "AC power on", false),
+            new CaddxProperty("panel_low_battery_memory", 7, 1, 2, 1, CaddxPropertyType.BIT, "Low battery memory",
+                    false),
             new CaddxProperty("", 7, 1, 3, 1, CaddxPropertyType.BIT, "Ground fault memory", false),
             new CaddxProperty("", 7, 1, 4, 1, CaddxPropertyType.BIT, "Fire alarm verification being timed", false),
             new CaddxProperty("", 7, 1, 5, 1, CaddxPropertyType.BIT, "Smoke power reset", false),
index a0459aab7f0be986d975abb8f0f2f398731329c1..7d904494348f6ccc1480ba2fcc30d0c360703522 100644 (file)
@@ -21,5 +21,5 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
  */
 @NonNullByDefault
 public interface CaddxPanelListener {
-    public void caddxMessage(CaddxCommunicator communicator, CaddxMessage message);
+    public void caddxMessage(CaddxMessage message);
 }
index 96d485827cfba4ac8e1cee9aeadfc81a429d43e6..0cc18f485f53bacf4fb15b8795535d478f59e385 100644 (file)
@@ -30,11 +30,13 @@ public class CaddxBridgeConfiguration {
     public static final String SERIAL_PORT = "serialPort";
     public static final String BAUD = "baud";
     public static final String MAX_ZONE_NUMBER = "maxZoneNumber";
+    public static final String IGNORE_ZONE_STATUS_TRANSITIONS = "ignoreZoneStatusTransitions";
 
     private CaddxProtocol protocol = CaddxProtocol.Binary;
     private @Nullable String serialPort;
     private int baudrate = 9600;
     private int maxZoneNumber = 16;
+    private boolean ignoreZoneStatusTransitions = false;
 
     public CaddxProtocol getProtocol() {
         return protocol;
@@ -51,4 +53,8 @@ public class CaddxBridgeConfiguration {
     public int getMaxZoneNumber() {
         return maxZoneNumber;
     }
+
+    public boolean isIgnoreZoneStatusTransitions() {
+        return ignoreZoneStatusTransitions;
+    }
 }
index 673e5b2db5d81c6f674a18f155f04d0fd5afe800..b346ab1564b62ac5ea324f3f7e814a96d705f720 100644 (file)
@@ -30,16 +30,7 @@ public class CaddxPartitionConfiguration {
      */
     private int partitionNumber;
 
-    /**
-     * The User Number of the user that will execute commands against the partition.
-     */
-    private int userNumber;
-
     public int getPartitionNumber() {
         return partitionNumber;
     }
-
-    public int getUserNumber() {
-        return userNumber;
-    }
 }
index 98625104d721d1b869d7137438df85cdb04b7d0b..ef1bcd09d127e9292f6776fdd813332acf687792 100644 (file)
@@ -49,7 +49,6 @@ public abstract class CaddxBaseThingHandler extends BaseThingHandler {
 
     /** Partition */
     private int partitionNumber;
-    private int userNumber;
 
     /** Zone */
     private int zoneNumber;
@@ -130,7 +129,6 @@ public abstract class CaddxBaseThingHandler extends BaseThingHandler {
             case PARTITION:
                 CaddxPartitionConfiguration partitionConfiguration = getConfigAs(CaddxPartitionConfiguration.class);
                 setPartitionNumber(partitionConfiguration.getPartitionNumber());
-                setUserNumber(partitionConfiguration.getUserNumber());
                 break;
             case ZONE:
                 CaddxZoneConfiguration zoneConfiguration = getConfigAs(CaddxZoneConfiguration.class);
@@ -139,6 +137,7 @@ public abstract class CaddxBaseThingHandler extends BaseThingHandler {
             case KEYPAD:
                 CaddxKeypadConfiguration keypadConfiguration = getConfigAs(CaddxKeypadConfiguration.class);
                 setKeypadAddress(keypadConfiguration.getKeypadAddress());
+                setTerminalModeSeconds(keypadConfiguration.getTerminalModeSeconds());
             default:
                 break;
         }
@@ -171,24 +170,6 @@ public abstract class CaddxBaseThingHandler extends BaseThingHandler {
         this.partitionNumber = partitionNumber;
     }
 
-    /**
-     * Get User Number.
-     *
-     * @return userNumber
-     */
-    public int getUserNumber() {
-        return userNumber;
-    }
-
-    /**
-     * Set User Number.
-     *
-     * @param userNumber
-     */
-    public void setUserNumber(int userNumber) {
-        this.userNumber = userNumber;
-    }
-
     /**
      * Get Zone Number.
      *
@@ -228,16 +209,16 @@ public abstract class CaddxBaseThingHandler extends BaseThingHandler {
     /**
      * Get Keypad Terminal Mode Seconds.
      *
-     * @return keypadAddress
+     * @return terminalModeSeconds
      */
     public int getTerminalModeSeconds() {
         return terminalModeSeconds;
     }
 
     /**
-     * Set Keypad Address.
+     * Set Keypad Terminal Mode Seconds.
      *
-     * @param keypadAddress
+     * @param terminalModeSeconds
      */
     public void setTerminalModeSeconds(int terminalModeSeconds) {
         this.terminalModeSeconds = terminalModeSeconds;
index 73a6657e75c560adba7f568d1ec2d3274762f5a0..d086b0b2d33b82da09ff81451ada8f8f96011fae 100644 (file)
@@ -29,6 +29,7 @@ import org.openhab.binding.caddx.internal.CaddxBindingConstants;
 import org.openhab.binding.caddx.internal.CaddxCommunicator;
 import org.openhab.binding.caddx.internal.CaddxEvent;
 import org.openhab.binding.caddx.internal.CaddxMessage;
+import org.openhab.binding.caddx.internal.CaddxMessageContext;
 import org.openhab.binding.caddx.internal.CaddxMessageType;
 import org.openhab.binding.caddx.internal.CaddxPanelListener;
 import org.openhab.binding.caddx.internal.CaddxProtocol;
@@ -85,6 +86,7 @@ public class CaddxBridgeHandler extends BaseBridgeHandler implements CaddxPanelL
     private String serialPortName = "";
     private int baudRate;
     private int maxZoneNumber;
+    private boolean isIgnoreZoneStatusTransitions;
     private @Nullable CaddxCommunicator communicator = null;
 
     // Things served by the bridge
@@ -120,6 +122,7 @@ public class CaddxBridgeHandler extends BaseBridgeHandler implements CaddxPanelL
         protocol = configuration.getProtocol();
         baudRate = configuration.getBaudrate();
         maxZoneNumber = configuration.getMaxZoneNumber();
+        isIgnoreZoneStatusTransitions = configuration.isIgnoreZoneStatusTransitions();
         updateStatus(ThingStatus.OFFLINE);
 
         // create & start panel interface
@@ -141,27 +144,28 @@ public class CaddxBridgeHandler extends BaseBridgeHandler implements CaddxPanelL
             comm.addListener(this);
 
             // Send discovery commands for the zones
-            comm.transmit(new CaddxMessage(DISCOVERY_ZONES_SNAPSHOT_REQUEST_00, false));
-            comm.transmit(new CaddxMessage(DISCOVERY_ZONES_SNAPSHOT_REQUEST_10, false));
-            comm.transmit(new CaddxMessage(DISCOVERY_ZONES_SNAPSHOT_REQUEST_20, false));
-            comm.transmit(new CaddxMessage(DISCOVERY_ZONES_SNAPSHOT_REQUEST_30, false));
-            comm.transmit(new CaddxMessage(DISCOVERY_ZONES_SNAPSHOT_REQUEST_40, false));
-            comm.transmit(new CaddxMessage(DISCOVERY_ZONES_SNAPSHOT_REQUEST_50, false));
-            comm.transmit(new CaddxMessage(DISCOVERY_ZONES_SNAPSHOT_REQUEST_60, false));
-            comm.transmit(new CaddxMessage(DISCOVERY_ZONES_SNAPSHOT_REQUEST_70, false));
-            comm.transmit(new CaddxMessage(DISCOVERY_ZONES_SNAPSHOT_REQUEST_80, false));
-            comm.transmit(new CaddxMessage(DISCOVERY_ZONES_SNAPSHOT_REQUEST_90, false));
-            comm.transmit(new CaddxMessage(DISCOVERY_ZONES_SNAPSHOT_REQUEST_A0, false));
-            comm.transmit(new CaddxMessage(DISCOVERY_ZONES_SNAPSHOT_REQUEST_B0, false));
+            comm.transmit(new CaddxMessage(CaddxMessageContext.DISCOVERY, DISCOVERY_ZONES_SNAPSHOT_REQUEST_00, false));
+            comm.transmit(new CaddxMessage(CaddxMessageContext.DISCOVERY, DISCOVERY_ZONES_SNAPSHOT_REQUEST_10, false));
+            comm.transmit(new CaddxMessage(CaddxMessageContext.DISCOVERY, DISCOVERY_ZONES_SNAPSHOT_REQUEST_20, false));
+            comm.transmit(new CaddxMessage(CaddxMessageContext.DISCOVERY, DISCOVERY_ZONES_SNAPSHOT_REQUEST_30, false));
+            comm.transmit(new CaddxMessage(CaddxMessageContext.DISCOVERY, DISCOVERY_ZONES_SNAPSHOT_REQUEST_40, false));
+            comm.transmit(new CaddxMessage(CaddxMessageContext.DISCOVERY, DISCOVERY_ZONES_SNAPSHOT_REQUEST_50, false));
+            comm.transmit(new CaddxMessage(CaddxMessageContext.DISCOVERY, DISCOVERY_ZONES_SNAPSHOT_REQUEST_60, false));
+            comm.transmit(new CaddxMessage(CaddxMessageContext.DISCOVERY, DISCOVERY_ZONES_SNAPSHOT_REQUEST_70, false));
+            comm.transmit(new CaddxMessage(CaddxMessageContext.DISCOVERY, DISCOVERY_ZONES_SNAPSHOT_REQUEST_80, false));
+            comm.transmit(new CaddxMessage(CaddxMessageContext.DISCOVERY, DISCOVERY_ZONES_SNAPSHOT_REQUEST_90, false));
+            comm.transmit(new CaddxMessage(CaddxMessageContext.DISCOVERY, DISCOVERY_ZONES_SNAPSHOT_REQUEST_A0, false));
+            comm.transmit(new CaddxMessage(CaddxMessageContext.DISCOVERY, DISCOVERY_ZONES_SNAPSHOT_REQUEST_B0, false));
 
             // Send discovery commands for the partitions
-            comm.transmit(new CaddxMessage(DISCOVERY_PARTITIONS_SNAPSHOT_REQUEST, false));
+            comm.transmit(
+                    new CaddxMessage(CaddxMessageContext.DISCOVERY, DISCOVERY_PARTITIONS_SNAPSHOT_REQUEST, false));
 
             // Send status commands to the zones and partitions
-            thingZonesMap.forEach((k, v) -> sendCommand(CaddxBindingConstants.ZONE_STATUS_REQUEST,
-                    k.subtract(BigDecimal.ONE).toString()));
-            thingPartitionsMap.forEach((k, v) -> sendCommand(CaddxBindingConstants.PARTITION_STATUS_REQUEST,
-                    k.subtract(BigDecimal.ONE).toString()));
+            thingZonesMap.forEach((k, v) -> sendCommand(CaddxMessageContext.COMMAND,
+                    CaddxBindingConstants.ZONE_STATUS_REQUEST, k.subtract(BigDecimal.ONE).toString()));
+            thingPartitionsMap.forEach((k, v) -> sendCommand(CaddxMessageContext.COMMAND,
+                    CaddxBindingConstants.PARTITION_STATUS_REQUEST, k.subtract(BigDecimal.ONE).toString()));
         }
 
         // list all channels
@@ -224,7 +228,7 @@ public class CaddxBridgeHandler extends BaseBridgeHandler implements CaddxPanelL
                         data = tokens[1];
                     }
 
-                    sendCommand(cmd, data);
+                    sendCommand(CaddxMessageContext.COMMAND, cmd, data);
 
                     updateState(channelUID, new StringType(""));
                 }
@@ -241,44 +245,44 @@ public class CaddxBridgeHandler extends BaseBridgeHandler implements CaddxPanelL
      * @param command The command to be send
      * @param data The associated command data
      */
-    public boolean sendCommand(String command, String data) {
+    public boolean sendCommand(CaddxMessageContext context, String command, String data) {
         logger.trace("sendCommand(): Attempting to send Command: command - {} - data: {}", command, data);
 
         CaddxMessage msg = null;
 
         switch (command) {
             case CaddxBindingConstants.ZONE_BYPASSED:
-                msg = new CaddxMessage(CaddxMessageType.ZONE_BYPASS_TOGGLE, data);
+                msg = new CaddxMessage(context, CaddxMessageType.ZONE_BYPASS_TOGGLE, data);
                 break;
             case CaddxBindingConstants.ZONE_STATUS_REQUEST:
-                msg = new CaddxMessage(CaddxMessageType.ZONE_STATUS_REQUEST, data);
+                msg = new CaddxMessage(context, CaddxMessageType.ZONE_STATUS_REQUEST, data);
                 break;
             case CaddxBindingConstants.ZONE_NAME_REQUEST:
-                msg = new CaddxMessage(CaddxMessageType.ZONE_NAME_REQUEST, data);
+                msg = new CaddxMessage(context, CaddxMessageType.ZONE_NAME_REQUEST, data);
                 break;
             case CaddxBindingConstants.PARTITION_STATUS_REQUEST:
-                msg = new CaddxMessage(CaddxMessageType.PARTITION_STATUS_REQUEST, data);
+                msg = new CaddxMessage(context, CaddxMessageType.PARTITION_STATUS_REQUEST, data);
                 break;
             case CaddxBindingConstants.PARTITION_PRIMARY_COMMAND_WITH_PIN:
-                msg = new CaddxMessage(CaddxMessageType.PRIMARY_KEYPAD_FUNCTION_WITH_PIN, data);
+                msg = new CaddxMessage(context, CaddxMessageType.PRIMARY_KEYPAD_FUNCTION_WITH_PIN, data);
                 break;
             case CaddxBindingConstants.PARTITION_SECONDARY_COMMAND:
-                msg = new CaddxMessage(CaddxMessageType.SECONDARY_KEYPAD_FUNCTION, data);
+                msg = new CaddxMessage(context, CaddxMessageType.SECONDARY_KEYPAD_FUNCTION, data);
                 break;
             case CaddxBindingConstants.PANEL_SYSTEM_STATUS_REQUEST:
-                msg = new CaddxMessage(CaddxMessageType.SYSTEM_STATUS_REQUEST, data);
+                msg = new CaddxMessage(context, CaddxMessageType.SYSTEM_STATUS_REQUEST, data);
                 break;
             case CaddxBindingConstants.PANEL_INTERFACE_CONFIGURATION_REQUEST:
-                msg = new CaddxMessage(CaddxMessageType.INTERFACE_CONFIGURATION_REQUEST, data);
+                msg = new CaddxMessage(context, CaddxMessageType.INTERFACE_CONFIGURATION_REQUEST, data);
                 break;
             case CaddxBindingConstants.PANEL_LOG_EVENT_REQUEST:
-                msg = new CaddxMessage(CaddxMessageType.LOG_EVENT_REQUEST, data);
+                msg = new CaddxMessage(context, CaddxMessageType.LOG_EVENT_REQUEST, data);
                 break;
             case CaddxBindingConstants.KEYPAD_TERMINAL_MODE_REQUEST:
-                msg = new CaddxMessage(CaddxMessageType.KEYPAD_TERMINAL_MODE_REQUEST, data);
+                msg = new CaddxMessage(context, CaddxMessageType.KEYPAD_TERMINAL_MODE_REQUEST, data);
                 break;
             case CaddxBindingConstants.KEYPAD_SEND_KEYPAD_TEXT_MESSAGE:
-                msg = new CaddxMessage(CaddxMessageType.SEND_KEYPAD_TEXT_MESSAGE, data);
+                msg = new CaddxMessage(context, CaddxMessageType.SEND_KEYPAD_TEXT_MESSAGE, data);
                 break;
             default:
                 logger.debug("Unknown command {}", command);
@@ -312,16 +316,13 @@ public class CaddxBridgeHandler extends BaseBridgeHandler implements CaddxPanelL
     }
 
     @Override
-    public void caddxMessage(CaddxCommunicator communicator, CaddxMessage caddxMessage) {
+    public void caddxMessage(CaddxMessage caddxMessage) {
         CaddxSource source = caddxMessage.getSource();
 
         if (source != CaddxSource.NONE) {
             CaddxThingType caddxThingType = null;
-            @Nullable
             Integer partition = null;
-            @Nullable
             Integer zone = null;
-            @Nullable
             Integer keypad = null;
 
             switch (source) {
@@ -347,6 +348,14 @@ public class CaddxBridgeHandler extends BaseBridgeHandler implements CaddxPanelL
 
             CaddxEvent event = new CaddxEvent(caddxMessage, partition, zone, keypad);
 
+            // Ignore Zone Status messages according to the configuration
+            if (isIgnoreZoneStatusTransitions
+                    && caddxMessage.getCaddxMessageType() == CaddxMessageType.ZONE_STATUS_MESSAGE
+                    && caddxMessage.getContext() == CaddxMessageContext.NONE) {
+                logger.debug("Zone {} Transition ignored.", zone);
+                return;
+            }
+
             // Find the thing
             Thing thing = findThing(caddxThingType, partition, zone, keypad);
             CaddxDiscoveryService discoveryService = getDiscoveryService();
index 69f93cfd8f345cc947d89ec9530da0378c56ffc5..19da26eedcce2207e5f0acfd9748a6cadd6339a6 100644 (file)
@@ -19,6 +19,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.openhab.binding.caddx.internal.CaddxBindingConstants;
 import org.openhab.binding.caddx.internal.CaddxEvent;
 import org.openhab.binding.caddx.internal.CaddxMessage;
+import org.openhab.binding.caddx.internal.CaddxMessageContext;
 import org.openhab.binding.caddx.internal.CaddxMessageType;
 import org.openhab.binding.caddx.internal.CaddxProperty;
 import org.openhab.binding.caddx.internal.action.CaddxKeypadActions;
@@ -44,6 +45,19 @@ public class ThingHandlerKeypad extends CaddxBaseThingHandler {
         super(thing, CaddxThingType.KEYPAD);
     }
 
+    @Override
+    public void initialize() {
+        super.initialize();
+
+        CaddxBridgeHandler bridgeHandler = getCaddxBridgeHandler();
+        if (bridgeHandler == null) {
+            return;
+        }
+
+        // Follow the bridge status
+        updateStatus(bridgeHandler.getThing().getStatus());
+    }
+
     @Override
     public void updateChannel(ChannelUID channelUID, String data) {
         if (channelUID.getId().equals(CaddxBindingConstants.KEYPAD_KEY_PRESSED)) {
@@ -97,7 +111,7 @@ public class ThingHandlerKeypad extends CaddxBaseThingHandler {
         if (bridgeHandler == null) {
             return;
         }
-        bridgeHandler.sendCommand(cmd, data);
+        bridgeHandler.sendCommand(CaddxMessageContext.COMMAND, cmd, data);
     }
 
     public void sendKeypadTextMessage(String displayLocation, String text) {
@@ -114,6 +128,6 @@ public class ThingHandlerKeypad extends CaddxBaseThingHandler {
         if (bridgeHandler == null) {
             return;
         }
-        bridgeHandler.sendCommand(cmd, data);
+        bridgeHandler.sendCommand(CaddxMessageContext.COMMAND, cmd, data);
     }
 }
index 3c3053f418437877b83a19e6f059e70b9dc4a582..4103b8fad47b9898287dfee37f4e6c38b6e1b920 100644 (file)
@@ -21,6 +21,7 @@ import org.eclipse.jdt.annotation.Nullable;
 import org.openhab.binding.caddx.internal.CaddxBindingConstants;
 import org.openhab.binding.caddx.internal.CaddxEvent;
 import org.openhab.binding.caddx.internal.CaddxMessage;
+import org.openhab.binding.caddx.internal.CaddxMessageContext;
 import org.openhab.binding.caddx.internal.CaddxMessageType;
 import org.openhab.binding.caddx.internal.CaddxProperty;
 import org.openhab.binding.caddx.internal.action.CaddxPanelActions;
@@ -51,6 +52,20 @@ public class ThingHandlerPanel extends CaddxBaseThingHandler {
         super(thing, CaddxThingType.PANEL);
     }
 
+    @Override
+    public void initialize() {
+        super.initialize();
+
+        CaddxBridgeHandler bridgeHandler = getCaddxBridgeHandler();
+        if (bridgeHandler == null) {
+            return;
+        }
+
+        String cmd = CaddxBindingConstants.PANEL_SYSTEM_STATUS_REQUEST;
+        String data = "";
+        bridgeHandler.sendCommand(CaddxMessageContext.COMMAND, cmd, data);
+    }
+
     @Override
     public void updateChannel(ChannelUID channelUID, String data) {
         if (channelUID.getId().equals(CaddxBindingConstants.PANEL_FIRMWARE_VERSION)
@@ -82,13 +97,13 @@ public class ThingHandlerPanel extends CaddxBaseThingHandler {
                 data = "";
             } else if (System.currentTimeMillis() - lastRefreshTime > 2000) {
                 // Refresh only if 2 seconds have passed from the last refresh
-                cmd = CaddxBindingConstants.PANEL_INTERFACE_CONFIGURATION_REQUEST;
+                cmd = CaddxBindingConstants.PANEL_SYSTEM_STATUS_REQUEST;
                 data = "";
             } else {
                 return;
             }
 
-            bridgeHandler.sendCommand(cmd, data);
+            bridgeHandler.sendCommand(CaddxMessageContext.COMMAND, cmd, data);
             lastRefreshTime = System.currentTimeMillis();
         } else {
             logger.debug("Unknown command {}", command);
@@ -104,19 +119,22 @@ public class ThingHandlerPanel extends CaddxBaseThingHandler {
             CaddxMessageType mt = message.getCaddxMessageType();
             ChannelUID channelUID = null;
 
+            for (CaddxProperty p : mt.properties) {
+                if (!p.getId().isEmpty()) {
+                    String value = message.getPropertyById(p.getId());
+                    channelUID = new ChannelUID(getThing().getUID(), p.getId());
+                    updateChannel(channelUID, value);
+                    logger.trace("Updating panel channel: {}", channelUID.getAsString());
+                }
+            }
+
             // Log event messages have special handling
             if (CaddxMessageType.SYSTEM_STATUS_MESSAGE.equals(mt)) {
                 handleSystemStatusMessage(message);
             } else if (CaddxMessageType.LOG_EVENT_MESSAGE.equals(mt)) {
                 handleLogEventMessage(message);
-            } else {
-                for (CaddxProperty p : mt.properties) {
-                    if (!p.getId().isEmpty()) {
-                        String value = message.getPropertyById(p.getId());
-                        channelUID = new ChannelUID(getThing().getUID(), p.getId());
-                        updateChannel(channelUID, value);
-                    }
-                }
+            } else if (CaddxMessageType.ZONES_SNAPSHOT_MESSAGE.equals(mt)) {
+                handleZonesSnapshotMessage(message);
             }
 
             updateStatus(ThingStatus.ONLINE);
@@ -140,7 +158,7 @@ public class ThingHandlerPanel extends CaddxBaseThingHandler {
         // build map of log message channels to event numbers
         HashMap<String, String> map = new HashMap<String, String>();
         map.put(pointer, CaddxBindingConstants.PANEL_LOG_MESSAGE_N_0);
-        bridgeHandler.sendCommand(CaddxBindingConstants.PANEL_LOG_EVENT_REQUEST, pointer);
+        bridgeHandler.sendCommand(CaddxMessageContext.COMMAND, CaddxBindingConstants.PANEL_LOG_EVENT_REQUEST, pointer);
         panelLogMessagesMap = map;
     }
 
@@ -190,7 +208,8 @@ public class ThingHandlerPanel extends CaddxBaseThingHandler {
                 }
 
                 map.put(Integer.toString(eventNumber), "panel_log_message_n_" + i);
-                bridgeHandler.sendCommand(CaddxBindingConstants.PANEL_LOG_EVENT_REQUEST, Integer.toString(eventNumber));
+                bridgeHandler.sendCommand(CaddxMessageContext.COMMAND, CaddxBindingConstants.PANEL_LOG_EVENT_REQUEST,
+                        Integer.toString(eventNumber));
             }
 
             communicatorStackPointer = null;
@@ -198,6 +217,45 @@ public class ThingHandlerPanel extends CaddxBaseThingHandler {
         }
     }
 
+    private void handleZonesSnapshotMessage(CaddxMessage message) {
+        // Get the bridge handler
+        CaddxBridgeHandler bridgeHandler = getCaddxBridgeHandler();
+        if (bridgeHandler == null) {
+            return;
+        }
+
+        int zoneOffset = Integer.parseInt(message.getPropertyById("zone_offset"));
+
+        for (int i = 1; i <= 16; i++) {
+            int zoneNumber = zoneOffset * 16 + i;
+
+            String zoneFaulted = message.getPropertyById("zone_" + i + "_faulted");
+            String zoneBypassed = message.getPropertyById("zone_" + i + "_bypassed");
+            String zoneTrouble = message.getPropertyById("zone_" + i + "_trouble");
+            String zoneAlarmMemory = message.getPropertyById("zone_" + i + "_alarm_memory");
+
+            logger.debug("Flags for zone {}. faulted:{}, bypassed:{}, trouble:{}, alarm_memory:{}", zoneNumber,
+                    zoneFaulted, zoneBypassed, zoneTrouble, zoneAlarmMemory);
+
+            // Get thing
+            Thing thing = bridgeHandler.findThing(CaddxThingType.ZONE, null, zoneNumber, null);
+            if (thing != null) {
+                ChannelUID channelUID;
+
+                logger.debug("Thing found for zone {}.", zoneNumber);
+
+                channelUID = new ChannelUID(thing.getUID(), "zone_faulted");
+                updateChannel(channelUID, zoneFaulted);
+                channelUID = new ChannelUID(thing.getUID(), "zone_bypassed");
+                updateChannel(channelUID, zoneBypassed);
+                channelUID = new ChannelUID(thing.getUID(), "zone_trouble");
+                updateChannel(channelUID, zoneTrouble);
+                channelUID = new ChannelUID(thing.getUID(), "zone_alarm_memory");
+                updateChannel(channelUID, zoneAlarmMemory);
+            }
+        }
+    }
+
     @Override
     public Collection<Class<? extends ThingHandlerService>> getServices() {
         return Collections.singleton(CaddxPanelActions.class);
@@ -216,7 +274,7 @@ public class ThingHandlerPanel extends CaddxBaseThingHandler {
         if (bridgeHandler == null) {
             return;
         }
-        bridgeHandler.sendCommand(cmd, sb.toString());
+        bridgeHandler.sendCommand(CaddxMessageContext.COMMAND, cmd, sb.toString());
     }
 
     private void sendSecondaryCommand(String function) {
@@ -230,7 +288,7 @@ public class ThingHandlerPanel extends CaddxBaseThingHandler {
         if (bridgeHandler == null) {
             return;
         }
-        bridgeHandler.sendCommand(cmd, sb.toString());
+        bridgeHandler.sendCommand(CaddxMessageContext.COMMAND, cmd, sb.toString());
     }
 
     public void turnOffAnySounderOrAlarm(String pin) {
index b7ddffbede3425b10c9a8cb6a77082f762d2e58e..c308b5bd553b589391418fd69d8aefaee97f3db0 100644 (file)
@@ -19,6 +19,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.openhab.binding.caddx.internal.CaddxBindingConstants;
 import org.openhab.binding.caddx.internal.CaddxEvent;
 import org.openhab.binding.caddx.internal.CaddxMessage;
+import org.openhab.binding.caddx.internal.CaddxMessageContext;
 import org.openhab.binding.caddx.internal.CaddxMessageType;
 import org.openhab.binding.caddx.internal.CaddxProperty;
 import org.openhab.binding.caddx.internal.action.CaddxPartitionActions;
@@ -48,6 +49,20 @@ public class ThingHandlerPartition extends CaddxBaseThingHandler {
         super(thing, CaddxThingType.PARTITION);
     }
 
+    @Override
+    public void initialize() {
+        super.initialize();
+
+        CaddxBridgeHandler bridgeHandler = getCaddxBridgeHandler();
+        if (bridgeHandler == null) {
+            return;
+        }
+
+        String cmd = CaddxBindingConstants.PARTITION_STATUS_REQUEST;
+        String data = String.format("%d", getPartitionNumber() - 1);
+        bridgeHandler.sendCommand(CaddxMessageContext.COMMAND, cmd, data);
+    }
+
     @Override
     public void updateChannel(ChannelUID channelUID, String data) {
         if (CaddxBindingConstants.PARTITION_SECONDARY_COMMAND.equals(channelUID.getId())) {
@@ -87,7 +102,7 @@ public class ThingHandlerPartition extends CaddxBaseThingHandler {
         }
 
         if (!data.startsWith("-")) {
-            bridgeHandler.sendCommand(cmd, data);
+            bridgeHandler.sendCommand(CaddxMessageContext.COMMAND, cmd, data);
         }
     }
 
@@ -105,6 +120,7 @@ public class ThingHandlerPartition extends CaddxBaseThingHandler {
                     String value = message.getPropertyById(p.getId());
                     channelUID = new ChannelUID(getThing().getUID(), p.getId());
                     updateChannel(channelUID, value);
+                    logger.trace("Updating partition channel: {}", channelUID.getAsString());
                 }
             }
 
@@ -135,7 +151,7 @@ public class ThingHandlerPartition extends CaddxBaseThingHandler {
         if (bridgeHandler == null) {
             return;
         }
-        bridgeHandler.sendCommand(cmd, sb.toString());
+        bridgeHandler.sendCommand(CaddxMessageContext.COMMAND, cmd, sb.toString());
     }
 
     private void sendSecondaryCommand(String function) {
@@ -149,7 +165,7 @@ public class ThingHandlerPartition extends CaddxBaseThingHandler {
         if (bridgeHandler == null) {
             return;
         }
-        bridgeHandler.sendCommand(cmd, sb.toString());
+        bridgeHandler.sendCommand(CaddxMessageContext.COMMAND, cmd, sb.toString());
     }
 
     public void turnOffAnySounderOrAlarm(String pin) {
index b8bff044e8f8118be28e995727e40392399987e0..7200d320e4a19b953e8bcd24c57bec4b9c83d2ab 100644 (file)
@@ -19,6 +19,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.openhab.binding.caddx.internal.CaddxBindingConstants;
 import org.openhab.binding.caddx.internal.CaddxEvent;
 import org.openhab.binding.caddx.internal.CaddxMessage;
+import org.openhab.binding.caddx.internal.CaddxMessageContext;
 import org.openhab.binding.caddx.internal.CaddxMessageType;
 import org.openhab.binding.caddx.internal.CaddxProperty;
 import org.openhab.binding.caddx.internal.action.CaddxZoneActions;
@@ -49,6 +50,23 @@ public class ThingHandlerZone extends CaddxBaseThingHandler {
         super(thing, CaddxThingType.ZONE);
     }
 
+    @Override
+    public void initialize() {
+        super.initialize();
+
+        CaddxBridgeHandler bridgeHandler = getCaddxBridgeHandler();
+        if (bridgeHandler == null) {
+            return;
+        }
+
+        String cmd1 = CaddxBindingConstants.ZONE_STATUS_REQUEST;
+        String cmd2 = CaddxBindingConstants.ZONE_NAME_REQUEST;
+        String data = String.format("%d", getZoneNumber() - 1);
+
+        bridgeHandler.sendCommand(CaddxMessageContext.COMMAND, cmd1, data);
+        bridgeHandler.sendCommand(CaddxMessageContext.COMMAND, cmd2, data);
+    }
+
     @Override
     public void updateChannel(ChannelUID channelUID, String data) {
         if (channelUID.getId().equals(CaddxBindingConstants.ZONE_NAME)) {
@@ -99,8 +117,8 @@ public class ThingHandlerZone extends CaddxBaseThingHandler {
         if (bridgeHandler == null) {
             return;
         }
-        bridgeHandler.sendCommand(cmd1, data);
-        bridgeHandler.sendCommand(cmd2, data);
+        bridgeHandler.sendCommand(CaddxMessageContext.COMMAND, cmd1, data);
+        bridgeHandler.sendCommand(CaddxMessageContext.COMMAND, cmd2, data);
     }
 
     @Override
@@ -119,8 +137,7 @@ public class ThingHandlerZone extends CaddxBaseThingHandler {
                     String value = message.getPropertyById(p.getId());
                     channelUID = new ChannelUID(getThing().getUID(), p.getId());
                     updateChannel(channelUID, value);
-
-                    logger.trace("  updateChannel: {} = {}", channelUID, value);
+                    logger.trace("Updating zone channel: {}", channelUID.getAsString());
                 }
             }
         }
@@ -141,6 +158,6 @@ public class ThingHandlerZone extends CaddxBaseThingHandler {
         if (bridgeHandler == null) {
             return;
         }
-        bridgeHandler.sendCommand(cmd, data);
+        bridgeHandler.sendCommand(CaddxMessageContext.COMMAND, cmd, data);
     }
 }
index e0458b34ee57e4b008fb47394de226a6f6ad960e..663cb0b532a888eecac52b1700e49e0a06ac4036 100644 (file)
                                <default>16</default>
                        </parameter>
 
+                       <parameter name="ignoreZoneStatusTransitions" type="boolean" required="true">
+                               <label>Ignore Zone Status Transitions</label>
+                               <description>Flag specifying if the Zone Status Transitions should be ignored</description>
+                               <default>false</default>
+                       </parameter>
                </config-description>
        </bridge-type>
 
index 4cce0123e59a00157329b74df818a665f126ad63..7cf962634c9b7c3be9bf4b6632db074ad76d5170 100644 (file)
                                <label>Zone Bypass Toggle</label>
                                <description>Zone Bypass Toggle</description>
                        </channel>
+
+                       <channel id="panel_ac_fail" typeId="panel_flag">
+                               <label>AC fail</label>
+                               <description>AC fail</description>
+                       </channel>
+                       <channel id="panel_ac_power_on" typeId="panel_flag">
+                               <label>AC Power On</label>
+                               <description>AC Power On</description>
+                       </channel>
+                       <channel id="panel_low_battery_memory" typeId="panel_flag">
+                               <label>Low Battery Memory</label>
+                               <description>Low Battery Memory</description>
+                       </channel>
+
                </channels>
        </thing-type>
 
index 72f799c000abcf911a1c13966604fb3fb7962563..edf10de20a2769d2246843923c3f1307001afb29 100644 (file)
@@ -60,6 +60,6 @@ public final class CaddxMessageReaderUtil {
      */
     public static CaddxMessage readCaddxMessage(String messageName) {
         byte[] bytes = readRawMessage(messageName);
-        return new CaddxMessage(bytes, true);
+        return new CaddxMessage(CaddxMessageContext.NONE, bytes, true);
     }
 }
index 3eccc4e201a844725b99bbad55b2c87d229d00a3..519b492f685ae676999a2d407cc1505e72bf8fb3 100644 (file)
@@ -34,10 +34,80 @@ public class CaddxMessageParseTest {
     // @formatter:off
     public static final List<Object[]> data() {
         return Arrays.asList(new Object[][] {
-            { "zone_status_message", "zone_number", "4", },
             { "interface_configuration_message", "panel_firmware_version", "5.37", },
             { "interface_configuration_message", "panel_interface_configuration_message", "true", },
 
+            { "zone_status_message", "zone_number", "4", },
+            { "zone_status_message", "zone_partition1", "true", },
+            { "zone_status_message", "zone_partition2", "false", },
+            { "zone_status_message", "zone_partition3", "false", },
+            { "zone_status_message", "zone_partition4", "false", },
+            { "zone_status_message", "zone_partition5", "false", },
+            { "zone_status_message", "zone_partition6", "false", },
+            { "zone_status_message", "zone_partition7", "false", },
+            { "zone_status_message", "zone_partition8", "false", },
+            { "zone_status_message", "zone_fire", "true", },
+            { "zone_status_message", "zone_24hour", "false", },
+            { "zone_status_message", "zone_key_switch", "false", },
+            { "zone_status_message", "zone_follower", "false", },
+            { "zone_status_message", "zone_entry_exit_delay_1", "false", },
+            { "zone_status_message", "zone_entry_exit_delay_2", "false", },
+            { "zone_status_message", "zone_interior", "false", },
+            { "zone_status_message", "zone_local_only", "false", },
+            { "zone_status_message", "zone_keypad_sounder", "true", },
+            { "zone_status_message", "zone_yelping_siren", "false", },
+            { "zone_status_message", "zone_steady_siren", "true", },
+            { "zone_status_message", "zone_chime", "false", },
+            { "zone_status_message", "zone_bypassable", "false", },
+            { "zone_status_message", "zone_group_bypassable", "false", },
+            { "zone_status_message", "zone_force_armable", "false", },
+            { "zone_status_message", "zone_entry_guard", "false", },
+            { "zone_status_message", "zone_fast_loop_response", "false", },
+            { "zone_status_message", "zone_double_eol_tamper", "false", },
+            { "zone_status_message", "zone_type_trouble", "true", },
+            { "zone_status_message", "zone_cross_zone", "false", },
+            { "zone_status_message", "zone_dialer_delay", "false", },
+            { "zone_status_message", "zone_swinger_shutdown", "false", },
+            { "zone_status_message", "zone_restorable", "true", },
+            { "zone_status_message", "zone_listen_in", "true", },
+            { "zone_status_message", "zone_faulted", "false", },
+            { "zone_status_message", "zone_tampered", "false", },
+            { "zone_status_message", "zone_trouble", "false", },
+            { "zone_status_message", "zone_bypassed", "false", },
+            { "zone_status_message", "zone_inhibited", "false", },
+            { "zone_status_message", "zone_low_battery", "false", },
+            { "zone_status_message", "zone_loss_of_supervision", "false", },
+            { "zone_status_message", "zone_alarm_memory", "false", },
+            { "zone_status_message", "zone_bypass_memory", "false", },
+
+            { "zones_snapshot_message", "zone_offset", "1", },
+            { "zones_snapshot_message", "zone_1_faulted", "false", },
+            { "zones_snapshot_message", "zone_1_bypassed", "false", },
+            { "zones_snapshot_message", "zone_1_trouble", "false", },
+            { "zones_snapshot_message", "zone_1_alarm_memory", "false", },
+            { "zones_snapshot_message", "zone_2_faulted", "false", },
+            { "zones_snapshot_message", "zone_2_bypassed", "false", },
+            { "zones_snapshot_message", "zone_2_trouble", "false", },
+            { "zones_snapshot_message", "zone_2_alarm_memory", "false", },
+            { "zones_snapshot_message", "zone_3_faulted", "false", },
+            { "zones_snapshot_message", "zone_3_bypassed", "false", },
+            { "zones_snapshot_message", "zone_3_trouble", "false", },
+            { "zones_snapshot_message", "zone_3_alarm_memory", "false", },
+            { "zones_snapshot_message", "zone_4_faulted", "true", },
+            { "zones_snapshot_message", "zone_4_bypassed", "false", },
+            { "zones_snapshot_message", "zone_4_trouble", "false", },
+            { "zones_snapshot_message", "zone_4_alarm_memory", "false", },
+            { "zones_snapshot_message", "zone_5_faulted", "false", },
+            { "zones_snapshot_message", "zone_6_faulted", "false", },
+            { "zones_snapshot_message", "zone_7_faulted", "false", },
+            { "zones_snapshot_message", "zone_8_faulted", "false", },
+            { "zones_snapshot_message", "zone_9_faulted", "false", },
+            { "zones_snapshot_message", "zone_10_faulted", "true", },
+            { "zones_snapshot_message", "zone_11_faulted", "false", },
+            { "zones_snapshot_message", "zone_12_faulted", "false", },
+            { "zones_snapshot_message", "zone_13_faulted", "false", },
+            { "zones_snapshot_message", "zone_14_faulted", "true", },
+
         });
     }
     // @formatter:on
diff --git a/bundles/org.openhab.binding.caddx/src/test/resources/org/openhab/binding/caddx/internal/zones_snapshot_message.msg b/bundles/org.openhab.binding.caddx/src/test/resources/org/openhab/binding/caddx/internal/zones_snapshot_message.msg
new file mode 100644 (file)
index 0000000..a8b041d
--- /dev/null
@@ -0,0 +1 @@
+85 01 00 10 00 00 10 00 10 00 C0 7F
\ No newline at end of file