]> git.basschouten.com Git - openhab-addons.git/commitdiff
[caddx] Add thing actions to the binding (#9248)
authorGeorgios Moutsos <50378548+jossuar@users.noreply.github.com>
Sat, 12 Dec 2020 19:57:10 +0000 (21:57 +0200)
committerGitHub <noreply@github.com>
Sat, 12 Dec 2020 19:57:10 +0000 (11:57 -0800)
* Added keypad support and thing actions
* Related to #8116

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/CaddxBindingConstants.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/CaddxMessageType.java
bundles/org.openhab.binding.caddx/src/main/java/org/openhab/binding/caddx/internal/CaddxProperty.java
bundles/org.openhab.binding.caddx/src/main/java/org/openhab/binding/caddx/internal/action/CaddxBridgeActions.java [new file with mode: 0644]
bundles/org.openhab.binding.caddx/src/main/java/org/openhab/binding/caddx/internal/action/CaddxKeypadActions.java [new file with mode: 0644]
bundles/org.openhab.binding.caddx/src/main/java/org/openhab/binding/caddx/internal/action/CaddxPanelActions.java [new file with mode: 0644]
bundles/org.openhab.binding.caddx/src/main/java/org/openhab/binding/caddx/internal/action/CaddxPartitionActions.java [new file with mode: 0644]
bundles/org.openhab.binding.caddx/src/main/java/org/openhab/binding/caddx/internal/action/CaddxZoneActions.java [new file with mode: 0644]
bundles/org.openhab.binding.caddx/src/main/java/org/openhab/binding/caddx/internal/config/CaddxKeypadConfiguration.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/channels.xml
bundles/org.openhab.binding.caddx/src/main/resources/OH-INF/thing/keypad.xml

index a5d869896e5987e80c38fbf08bc89f0ed58d1d36..6c222a57415e679fd8cbcb652d98c53da4f4a67c 100644 (file)
@@ -14,7 +14,7 @@ This binding supports the following Thing types
 | panel      | Thing      | The basic representation of the alarm System.                          |
 | partition  | Thing      | Represents a controllable area within the alarm system.                |
 | zone       | Thing      | Represents a physical device such as a door, window, or motion sensor. |
-| keypad     | Thing      | Represents a keypad. (Not yet functional)                              |
+| keypad     | Thing      | Represents a keypad.                                                   |
 
 ## Discovery
 
@@ -22,7 +22,7 @@ First the bridge must be **manually** defined. The serial port, baud rate and pr
 After the bridge is manually added and available to openHAB, the binding will automatically start to discover partitions and zones and add them to the discovery inbox.
 
 Note:
-There is currently no support to discover the available keypads.
+There is no support to discover the available keypads.
 
 ## Prerequisites
 
@@ -41,7 +41,7 @@ For the binding to work the panel has also to be programmed appropriately.
 | 211      | 2       | 1,2,3,4,5   | (Flags 4 and 5 are not yet functional. Can be ignored.)                                                |
 | 211      | 3       |             |                                                                                                        |
 | 211      | 4       | 5,7,8       |                                                                                                        |
-| 212      | 1       | 192         | Programming the LCD keypad address. (Not yet functional. Can be ignored.)                              |
+| 212      | 1       | 192         | Programming the LCD keypad address.                                                                    |
 
 ### Programming locations for the NX-584E home automation module
 
@@ -55,24 +55,23 @@ For the binding to work the panel has also to be programmed appropriately.
 | 3        | 2       | 1,2,3,4,5   | (Flags 4 and 5 are not yet functional. Can be ignored.)                                                |
 | 3        | 3       |             |                                                                                                        |
 | 3        | 4       | 5,7,8       |                                                                                                        |
-| 4        | 1       | 192         | Programming the LCD keypad address. (Not yet functional. Can be ignored.)                              |
+| 4        | 1       | 192         | Programming the LCD keypad address.                                                                    |
 
 ## Thing Configuration
 
 The things can be configured either through the online configuration utility via discovery, or manually through the configuration file.
 The following table shows the available configuration parameters for each thing.
 
-| Thing     | Configuration Parameters                                                                       |
-|-----------|------------------------------------------------------------------------------------------------|
-| bridge    | `serialPort` - Serial port for the bridge - Required                                           |
-|           | `protocol` - Protocol used for the communication (Binary, Ascii) - Required - Default = Binary |
-|           | `baud` - Baud rate of the bridge - Required - Default = 9600                                   |
-|           | `maxZoneNumber` - Maximum zone number to be added during discovery - Required - Default = 16   |
-| partition | `partitionNumber` - Partition number (1-8) - Required                                          |
-| zone      | `zoneNumber` - Zone number (1-192) - Required                                                  |
-| keypad    | `keypadAddress` - Keypad address (192-255) - Required                                          |
-
-A full example is further below.
+| Thing     | Configuration Parameters                                                                            |
+|-----------|-----------------------------------------------------------------------------------------------------|
+| bridge    | `serialPort` - Serial port for the bridge - Required                                                |
+|           | `protocol` - Protocol used for the communication (Binary, Ascii) - Required - Default = Binary      |
+|           | `baud` - Baud rate of the bridge - Required - Default = 9600                                        |
+|           | `maxZoneNumber` - Maximum zone number to be added during discovery - Required - Default = 16        |
+| partition | `partitionNumber` - Partition number (1-8) - Required                                               |
+| zone      | `zoneNumber` - Zone number (1-192) - Required                                                       |
+| keypad    | `keypadAddress` - Keypad address (192-255) - Required                                               |
+| keypad    | `terminalModeSeconds` - The number of Seconds the keypad has to remain in Terminal Mode. - Required |
 
 ## Channels
 
@@ -214,6 +213,66 @@ Caddx Alarm things support a variety of channels as seen below in the following
 | zone_loss_of_supervision                         | Switch    | Zone Condition      | Loss of supervision                        |
 | zone_alarm_memory                                | Switch    | Zone Condition      | Alarm memory                               |
 | zone_bypass_memory                               | Switch    | Zone Condition      | Bypass memory                              |
+| keypad_key_pressed                               | String    | Button press        | The pressed button on the keypad           |
+
+## Thing actions
+
+The binding supports the following actions on the respective things.
+
+| Thing     | Name                            | Description                                              | Specification                                                   |
+|-----------|---------------------------------|----------------------------------------------------------|-----------------------------------------------------------------|
+| bridge    | restart                         | Restart the binding                                      | void restart()                                                  |
+| zone      | bypass                          | Bypass the zone                                          | void bypass()                                                   |
+| keypad    | enterTerminalMode               | Enter terminal mode on the selected keypad               | void enterTerminalMode()                                        |
+| keypad    | sendKeypadTextMessage           | Display a message on the Keypad                          | void sendKeypadTextMessage(String displayLocation, String text) |
+| partition | turnOffAnySounderOrAlarm        | Turn off any sounder or alarm                            | void turnOffAnySounderOrAlarm(String pin)                       |
+| partition | disarm                          | Dis-arm                                                  | void disarm(String pin)                                         |
+| partition | armInAwayMode                   | Arm in away mode                                         | void armInAwayMode(String pin)                                  |
+| partition | armInStayMode                   | Arm in stay mode                                         | void armInStayMode(String pin)                                  |
+| partition | cancel                          | Cancel                                                   | void cancel(String pin)                                         |
+| partition | initiateAutoArm                 | Initiate auto arm                                        | void initiateAutoArm(String pin)                                |
+| partition | startWalkTestMode               | Start walk-test mode                                     | void startWalkTestMode(String pin)                              |
+| partition | stopWalkTestMode                | Stop walk-test mode                                      | void stopWalkTestMode(String pin)                               |
+| partition | stay                            | Stay (1 button arm / toggle interiors)                   | void stay()                                                     |
+| partition | chime                           | Chime (toggle chime mode)                                | void chime()                                                    |
+| partition | exit                            | Exit (1 button arm / toggle instant)                     | void exit()                                                     |
+| partition | bypassInteriors                 | Bypass Interiors                                         | void bypassInteriors()                                          |
+| partition | firePanic                       | Fire Panic                                               | void firePanic()                                                |
+| partition | medicalPanic                    | Medical Panic                                            | void medicalPanic()                                             |
+| partition | policePanic                     | Police Panic                                             | void policePanic()                                              |
+| partition | smokeDetectorReset              | Smoke detector reset                                     | void smokeDetectorReset()                                       |
+| partition | autoCallbackDownload            | Auto callback download                                   | void autoCallbackDownload()                                     |
+| partition | manualPickupDownload            | Manual pickup download                                   | void manualPickupDownload()                                     |
+| partition | enableSilentExit                | Enable silent exit                                       | void enableSilentExit()                                         |
+| partition | performTest                     | Perform test                                             | void performTest()                                              |
+| partition | groupBypass                     | Group Bypass                                             | void groupBypass()                                              |
+| partition | auxiliaryFunction1              | Auxiliary Function 1                                     | void auxiliaryFunction1()                                       |
+| partition | auxiliaryFunction2              | Auxiliary Function 2                                     | void auxiliaryFunction2()                                       |
+| partition | startKeypadSounder              | Start keypad sounder                                     | void startKeypadSounder()                                       |
+| panel     | turnOffAnySounderOrAlarmOnPanel | Turn off any sounder or alarm on all partitions          | void turnOffAnySounderOrAlarm(String pin)                       |
+| panel     | disarmOnPanel                   | Dis-arm all partitions                                   | void disarm(String pin)                                         |
+| panel     | armInAwayModeOnPanel            | Arm in away mode on all partitions                       | void armInAwayMode(String pin)                                  |
+| panel     | armInStayModeOnPanel            | Arm in stay mode on all partitions                       | void armInStayMode(String pin)                                  |
+| panel     | cancelOnPanel                   | Cancel command on all partitions                         | void cancel(String pin)                                         |
+| panel     | initiateAutoArmOnPanel          | Initiate auto arm on all partitions                      | void initiateAutoArm(String pin)                                |
+| panel     | startWalkTestModeOnPanel        | Start walk-test mode on all partitions                   | void startWalkTestMode(String pin)                              |
+| panel     | stopWalkTestModeOnPanel         | Stop walk-test mode on all partitions                    | void stopWalkTestMode(String pin)                               |
+| panel     | stayOnPanel                     | Stay (1 button arm / toggle interiors) on all partitions | void stay()                                                     |
+| panel     | chimeOnPanel                    | Chime (toggle chime mode) on all partitions              | void chime()                                                    |
+| panel     | exitOnPanel                     | Exit (1 button arm / toggle instant) on all partitions   | void exit()                                                     |
+| panel     | bypassInteriorsOnPanel          | Bypass Interiors on all partitions                       | void bypassInteriors()                                          |
+| panel     | firePanicOnPanel                | Fire Panic on all partitions                             | void firePanic()                                                |
+| panel     | medicalPanicOnPanel             | Medical Panic on all partitions                          | void medicalPanic()                                             |
+| panel     | policePanicOnPanel              | Police Panic on all partitions                           | void policePanic()                                              |
+| panel     | smokeDetectorResetOnPanel       | Smoke detector reset on all partitions                   | void smokeDetectorReset()                                       |
+| panel     | autoCallbackDownloadOnPanel     | Auto callback download on all partitions                 | void autoCallbackDownload()                                     |
+| panel     | manualPickupDownloadOnPanel     | Manual pickup download on all partitions                 | void manualPickupDownload()                                     |
+| panel     | enableSilentExitOnPanel         | Enable silent exit on all partitions                     | void enableSilentExit()                                         |
+| panel     | performTestOnPanel              | Perform test on all partitions                           | void performTest()                                              |
+| panel     | groupBypassOnPanel              | Group Bypass on all partitions                           | void groupBypass()                                              |
+| panel     | auxiliaryFunction1OnPanel       | Auxiliary Function 1 on all partitions                   | void auxiliaryFunction1()                                       |
+| panel     | auxiliaryFunction2OnPanel       | Auxiliary Function 2 on all partitions                   | void auxiliaryFunction2()                                       |
+| panel     | startKeypadSounderOnPanel       | Start keypad sounder on all partitions                   | void startKeypadSounder()                                       |
 
 ## Full Example
 
@@ -272,3 +331,20 @@ sitemap home label="Home" {
     }
 }
 ```
+
+The following is a rule example with calling of an action on the binding
+
+```
+rule "Zone Bypass on Chime Off"
+when
+    Item caddx_partition_thebridge_partition1_partition_chime_mode_on changed from ON to OFF
+then
+    val actions = getActions("caddx","caddx:zone:thebridge:zone4")
+    if (null === actions) {
+        logWarn("actions", "Actions not found, check thing ID for the Zone")
+        return
+    }
+    
+    actions.bypass()
+end
+```
\ No newline at end of file
index 6cf850912059f65b6dba13b6a6390ec0bd26ebb4..5a2f267cfd1b08876ef9f396334c0a794bba7a66 100644 (file)
@@ -83,6 +83,11 @@ public class CaddxBindingConstants {
     public static final String ZONE_BYPASSED = "zone_bypassed";
 
     // Keypad
+    // Commands
+    public static final String KEYPAD_TERMINAL_MODE_REQUEST = "keypad_terminal_mode_request";
+    public static final String KEYPAD_SEND_KEYPAD_TEXT_MESSAGE = "keypad_send_keypad_text_message";
+    // Channels
+    public static final String KEYPAD_KEY_PRESSED = "keypad_key_pressed";
 
     // Set of all supported Thing Type UIDs
     public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Collections.unmodifiableSet(Stream
index ca5edefa0caed7cb42b9f33df352879bfaf54fea..e6fb88cf8a65427a1ec940246dc62d3c558d2f44 100644 (file)
@@ -30,11 +30,6 @@ public class CaddxEvent extends EventObject {
     private final @Nullable Integer zone;
     private final @Nullable Integer keypad;
 
-    /**
-     * Constructor.
-     *
-     * @param source
-     */
     public CaddxEvent(CaddxMessage caddxMessage, @Nullable Integer partition, @Nullable Integer zone,
             @Nullable Integer keypad) {
         super(caddxMessage);
index 6e875d6754878376b83729414cc1afceeefab27c..22bdc71ce30039356f15977f742ec84a764455e8 100644 (file)
@@ -41,12 +41,6 @@ public class CaddxMessage {
     private final byte checksum1Calc;
     private final byte checksum2Calc;
 
-    /**
-     * Constructor.
-     *
-     * @param message
-     *            - the message received
-     */
     public CaddxMessage(byte[] message, boolean withChecksum) {
         if (withChecksum && message.length < 3) {
             logger.debug("CaddxMessage: The message should be at least 3 bytes long.");
index c45072a95a16a451e96c18b6bab1d8483e3d1d64..0666db6297d0be20e07299e76b273877e6c9a9da 100644 (file)
@@ -636,10 +636,10 @@ public enum CaddxMessageType {
             new CaddxProperty("", 1, 1, 0, 0, CaddxPropertyType.INT, "Message number", false),
 
             // Byte 2
-            new CaddxProperty("keypad_address", 1, 2, 0, 0, CaddxPropertyType.INT, "Keypad address", false),
+            new CaddxProperty("", 1, 2, 0, 0, CaddxPropertyType.INT, "Keypad address", false),
 
             // Byte 3
-            new CaddxProperty("", 1, 1, 0, 0, CaddxPropertyType.INT, "Key value", false)),
+            new CaddxProperty("keypad_key_pressed", 1, 1, 0, 0, CaddxPropertyType.INT, "Key value", false)),
 
     PROGRAM_DATA_REPLY(0x10, null, 13, "Program Data Reply",
             "This message will contain a system device’s buss address, logical location, and program data that was previously requested (via Program Data Request (3Ch)).",
index bc16a5d4b01d99cdb07a9cb5eeb2f270b364eeb2..981067a8f28980a64a6198144c33c32bf8246f65 100644 (file)
@@ -38,7 +38,6 @@ public class CaddxProperty {
     private final boolean external;
     private final String id;
 
-    // Constructor
     public CaddxProperty(String id, int byteFrom, int byteLength, int bitFrom, int bitLength, CaddxPropertyType type,
             String name, boolean external) {
         this.id = id;
diff --git a/bundles/org.openhab.binding.caddx/src/main/java/org/openhab/binding/caddx/internal/action/CaddxBridgeActions.java b/bundles/org.openhab.binding.caddx/src/main/java/org/openhab/binding/caddx/internal/action/CaddxBridgeActions.java
new file mode 100644 (file)
index 0000000..a1bf102
--- /dev/null
@@ -0,0 +1,66 @@
+/**
+ * Copyright (c) 2010-2020 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.action;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.caddx.internal.handler.CaddxBridgeHandler;
+import org.openhab.core.automation.annotation.RuleAction;
+import org.openhab.core.thing.binding.ThingActions;
+import org.openhab.core.thing.binding.ThingActionsScope;
+import org.openhab.core.thing.binding.ThingHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This is the automation engine action handler service for the
+ * caddx bridge actions.
+ *
+ * @author Georgios Moutsos - Initial contribution
+ */
+@ThingActionsScope(name = "caddx")
+@NonNullByDefault
+public class CaddxBridgeActions implements ThingActions {
+    private final Logger logger = LoggerFactory.getLogger(CaddxBridgeActions.class);
+
+    private static final String HANDLER_IS_NULL = "CaddxBridgeHandler is null!";
+    private @Nullable CaddxBridgeHandler handler;
+
+    @Override
+    public void setThingHandler(@Nullable ThingHandler handler) {
+        if (handler instanceof CaddxBridgeHandler) {
+            this.handler = (CaddxBridgeHandler) handler;
+        }
+    }
+
+    @Override
+    public @Nullable ThingHandler getThingHandler() {
+        return this.handler;
+    }
+
+    @RuleAction(label = "restart", description = "Restart the binding")
+    public void restart() {
+        // Check of parameters
+        CaddxBridgeHandler handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        handler.restart();
+    }
+
+    public static void restart(ThingActions actions) {
+        ((CaddxBridgeActions) actions).restart();
+    }
+}
diff --git a/bundles/org.openhab.binding.caddx/src/main/java/org/openhab/binding/caddx/internal/action/CaddxKeypadActions.java b/bundles/org.openhab.binding.caddx/src/main/java/org/openhab/binding/caddx/internal/action/CaddxKeypadActions.java
new file mode 100644 (file)
index 0000000..f3131d2
--- /dev/null
@@ -0,0 +1,108 @@
+/**
+ * Copyright (c) 2010-2020 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.action;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.caddx.internal.handler.ThingHandlerKeypad;
+import org.openhab.core.automation.annotation.ActionInput;
+import org.openhab.core.automation.annotation.RuleAction;
+import org.openhab.core.thing.binding.ThingActions;
+import org.openhab.core.thing.binding.ThingActionsScope;
+import org.openhab.core.thing.binding.ThingHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This is the automation engine action handler service for the
+ * caddx bridge actions.
+ *
+ * @author Georgios Moutsos - Initial contribution
+ */
+@ThingActionsScope(name = "caddx")
+@NonNullByDefault
+public class CaddxKeypadActions implements ThingActions {
+    private final Logger logger = LoggerFactory.getLogger(CaddxKeypadActions.class);
+
+    private static final String HANDLER_IS_NULL = "ThingHandlerKeypad is null!";
+    private static final String TEXT_IS_NULL = "The value for the text is null. Action not executed.";
+    private static final String DISPLAY_LOCATION_IS_NULL = "The value for the display location is null. Action not executed.";
+    private static final String DISPLAY_LOCATION_IS_INVALID = "The value for the display location [{}] is invalid. Action not executed.";
+
+    private @Nullable ThingHandlerKeypad handler;
+
+    @Override
+    public void setThingHandler(@Nullable ThingHandler handler) {
+        if (handler instanceof ThingHandlerKeypad) {
+            this.handler = (ThingHandlerKeypad) handler;
+        }
+    }
+
+    @Override
+    public @Nullable ThingHandler getThingHandler() {
+        return this.handler;
+    }
+
+    @RuleAction(label = "enterTerminalMode", description = "Enter terminal mode on the selected keypad")
+    public void enterTerminalMode() {
+        ThingHandlerKeypad thingHandler = this.handler;
+        if (thingHandler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        thingHandler.enterTerminalMode();
+    }
+
+    public static void enterTerminalMode(ThingActions actions) {
+        ((CaddxKeypadActions) actions).enterTerminalMode();
+    }
+
+    @RuleAction(label = "sendKeypadTextMessage", description = "Display a message on the Keypad")
+    public void sendKeypadTextMessage(
+            @ActionInput(name = "displayLocation", label = "Display Location", description = "Display storage location (0=top left corner)") @Nullable String displayLocation,
+            @ActionInput(name = "text", label = "Text", description = "The text to be displayed") @Nullable String text) {
+        ThingHandlerKeypad thingHandler = handler;
+        if (thingHandler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        if (text == null) {
+            logger.debug(TEXT_IS_NULL);
+            return;
+        }
+
+        if (displayLocation == null) {
+            logger.debug(DISPLAY_LOCATION_IS_NULL);
+            return;
+        }
+
+        if (!displayLocation.matches("^\\d$")) {
+            logger.debug(DISPLAY_LOCATION_IS_INVALID, displayLocation);
+            return;
+        }
+
+        // Adjust parameters
+        String paddedText = text + "        ";
+        paddedText = paddedText.substring(0, 8);
+
+        // Build the command
+        thingHandler.sendKeypadTextMessage(displayLocation, text);
+    }
+
+    public static void sendKeypadTextMessage(ThingActions actions, @Nullable String displayLocation,
+            @Nullable String text) {
+        ((CaddxKeypadActions) actions).sendKeypadTextMessage(displayLocation, text);
+    }
+}
diff --git a/bundles/org.openhab.binding.caddx/src/main/java/org/openhab/binding/caddx/internal/action/CaddxPanelActions.java b/bundles/org.openhab.binding.caddx/src/main/java/org/openhab/binding/caddx/internal/action/CaddxPanelActions.java
new file mode 100644 (file)
index 0000000..06a55df
--- /dev/null
@@ -0,0 +1,477 @@
+/**
+ * Copyright (c) 2010-2020 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.action;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.caddx.internal.handler.ThingHandlerPanel;
+import org.openhab.core.automation.annotation.ActionInput;
+import org.openhab.core.automation.annotation.RuleAction;
+import org.openhab.core.thing.binding.ThingActions;
+import org.openhab.core.thing.binding.ThingActionsScope;
+import org.openhab.core.thing.binding.ThingHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This is the automation engine action handler service for the
+ * caddx bridge actions.
+ *
+ * @author Georgios Moutsos - Initial contribution
+ */
+@ThingActionsScope(name = "caddx")
+@NonNullByDefault
+public class CaddxPanelActions implements ThingActions {
+    private final Logger logger = LoggerFactory.getLogger(CaddxPanelActions.class);
+
+    private static final String HANDLER_IS_NULL = "ThingHandlerPanel is null!";
+    private static final String PIN_IS_NULL = "The value for the pin is null. Action not executed.";
+    private static final String PIN_IS_INVALID = "The value for the pin [{}] is invalid. Action not executed.";
+
+    private @Nullable ThingHandlerPanel handler;
+
+    @Override
+    public void setThingHandler(@Nullable ThingHandler handler) {
+        if (handler instanceof ThingHandlerPanel) {
+            this.handler = (ThingHandlerPanel) handler;
+        }
+    }
+
+    @Override
+    public @Nullable ThingHandler getThingHandler() {
+        return this.handler;
+    }
+
+    // Valid are only 4 or 6 digit pins
+    private @Nullable String adjustPin(@Nullable String pin) {
+        if (pin == null) {
+            logger.debug(PIN_IS_NULL);
+            return null;
+        }
+
+        if (!pin.matches("^\\d{4,4}|\\d{6,6}$")) {
+            logger.debug(PIN_IS_INVALID, pin);
+            return null;
+        }
+
+        return (pin.length() == 4) ? pin + "00" : pin;
+    }
+
+    @RuleAction(label = "turnOffAnySounderOrAlarmOnPanel", description = "Turn off any sounder or alarm on all partitions")
+    public void turnOffAnySounderOrAlarmOnPanel(
+            @ActionInput(name = "pin", label = "pin", description = "The pin 4 or 6 digit pin") @Nullable String pin) {
+        ThingHandlerPanel handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        String adjustedPin = adjustPin(pin);
+        if (adjustedPin == null) {
+            return;
+        }
+
+        handler.turnOffAnySounderOrAlarm(adjustedPin);
+    }
+
+    public static void turnOffAnySounderOrAlarmOnPanel(ThingActions actions, @Nullable String pin) {
+        ((CaddxPanelActions) actions).turnOffAnySounderOrAlarmOnPanel(pin);
+    }
+
+    @RuleAction(label = "disarmOnPanel", description = "Disarm all partitions")
+    public void disarmOnPanel(
+            @ActionInput(name = "pin", label = "pin", description = "The pin 4 or 6 digit pin") @Nullable String pin) {
+        ThingHandlerPanel handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        String adjustedPin = adjustPin(pin);
+        if (adjustedPin == null) {
+            return;
+        }
+
+        handler.disarm(adjustedPin);
+    }
+
+    public static void disarmOnPanel(ThingActions actions, @Nullable String pin) {
+        ((CaddxPanelActions) actions).disarmOnPanel(pin);
+    }
+
+    @RuleAction(label = "armInAwayModeOnPanel", description = "Arm in away mode on all partitions")
+    public void armInAwayModeOnPanel(
+            @ActionInput(name = "pin", label = "pin", description = "The pin 4 or 6 digit pin") @Nullable String pin) {
+        ThingHandlerPanel handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        String adjustedPin = adjustPin(pin);
+        if (adjustedPin == null) {
+            return;
+        }
+
+        handler.armInAwayMode(adjustedPin);
+    }
+
+    public static void armInAwayModeOnPanel(ThingActions actions, @Nullable String pin) {
+        ((CaddxPanelActions) actions).armInAwayModeOnPanel(pin);
+    }
+
+    @RuleAction(label = "armInStayModeOnPanel", description = "Arm in stay mode on all partitions")
+    public void armInStayModeOnPanel(
+            @ActionInput(name = "pin", label = "pin", description = "The pin 4 or 6 digit pin") @Nullable String pin) {
+        ThingHandlerPanel handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        String adjustedPin = adjustPin(pin);
+        if (adjustedPin == null) {
+            return;
+        }
+
+        handler.armInStayMode(adjustedPin);
+    }
+
+    public static void armInStayModeOnPanel(ThingActions actions, @Nullable String pin) {
+        ((CaddxPanelActions) actions).armInStayModeOnPanel(pin);
+    }
+
+    @RuleAction(label = "cancelOnPanel", description = "Cancel command on all partitions")
+    public void cancelOnPanel(
+            @ActionInput(name = "pin", label = "pin", description = "The pin 4 or 6 digit pin") @Nullable String pin) {
+        ThingHandlerPanel handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        String adjustedPin = adjustPin(pin);
+        if (adjustedPin == null) {
+            return;
+        }
+
+        handler.cancel(adjustedPin);
+    }
+
+    public static void cancelOnPanel(ThingActions actions, @Nullable String pin) {
+        ((CaddxPanelActions) actions).cancelOnPanel(pin);
+    }
+
+    @RuleAction(label = "initiateAutoArmOnPanel", description = "Initiate auto arm on all partitions")
+    public void initiateAutoArmOnPanel(
+            @ActionInput(name = "pin", label = "pin", description = "The pin 4 or 6 digit pin") @Nullable String pin) {
+        ThingHandlerPanel handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        String adjustedPin = adjustPin(pin);
+        if (adjustedPin == null) {
+            return;
+        }
+
+        handler.initiateAutoArm(adjustedPin);
+    }
+
+    public static void initiateAutoArmOnPanel(ThingActions actions, @Nullable String pin) {
+        ((CaddxPanelActions) actions).initiateAutoArmOnPanel(pin);
+    }
+
+    @RuleAction(label = "startWalkTestModeOnPanel", description = "Start walk-test mode on all partitions")
+    public void startWalkTestModeOnPanel(
+            @ActionInput(name = "pin", label = "pin", description = "The pin 4 or 6 digit pin") @Nullable String pin) {
+        ThingHandlerPanel handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        String adjustedPin = adjustPin(pin);
+        if (adjustedPin == null) {
+            return;
+        }
+
+        handler.startWalkTestMode(adjustedPin);
+    }
+
+    public static void startWalkTestModeOnPanel(ThingActions actions, @Nullable String pin) {
+        ((CaddxPanelActions) actions).startWalkTestModeOnPanel(pin);
+    }
+
+    @RuleAction(label = "stopWalkTestModeOnPanel", description = "Stop walk-test mode on all partitions")
+    public void stopWalkTestModeOnPanel(
+            @ActionInput(name = "pin", label = "pin", description = "The pin 4 or 6 digit pin") @Nullable String pin) {
+        ThingHandlerPanel handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        String adjustedPin = adjustPin(pin);
+        if (adjustedPin == null) {
+            return;
+        }
+
+        handler.stopWalkTestMode(adjustedPin);
+    }
+
+    public static void stopWalkTestModeOnPanel(ThingActions actions, @Nullable String pin) {
+        ((CaddxPanelActions) actions).stopWalkTestModeOnPanel(pin);
+    }
+
+    @RuleAction(label = "stayOnPanel", description = "Stay (1 button arm / toggle interiors) on all partitions")
+    public void stayOnPanel() {
+        ThingHandlerPanel handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        handler.stay();
+    }
+
+    public static void stayOnPanel(ThingActions actions) {
+        ((CaddxPanelActions) actions).stayOnPanel();
+    }
+
+    @RuleAction(label = "chimeOnPanel", description = "Chime (toggle chime mode) on all partitions")
+    public void chimeOnPanel() {
+        ThingHandlerPanel handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        handler.chime();
+    }
+
+    public static void chimeOnPanel(ThingActions actions) {
+        ((CaddxPanelActions) actions).chimeOnPanel();
+    }
+
+    @RuleAction(label = "exitOnPanel", description = "Exit (1 button arm / toggle instant) on all partitions")
+    public void exitOnPanel() {
+        ThingHandlerPanel handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        handler.exit();
+    }
+
+    public static void exitOnPanel(ThingActions actions) {
+        ((CaddxPanelActions) actions).exitOnPanel();
+    }
+
+    @RuleAction(label = "bypassInteriorsOnPanel", description = "Bypass Interiors on all partitions")
+    public void bypassInteriorsOnPanel() {
+        ThingHandlerPanel handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        handler.bypassInteriors();
+    }
+
+    public static void bypassInteriorsOnPanel(ThingActions actions) {
+        ((CaddxPanelActions) actions).bypassInteriorsOnPanel();
+    }
+
+    @RuleAction(label = "firePanicOnPanel", description = "Fire Panic on all partitions")
+    public void firePanicOnPanel() {
+        ThingHandlerPanel handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        handler.firePanic();
+    }
+
+    public static void firePanicOnPanel(ThingActions actions) {
+        ((CaddxPanelActions) actions).firePanicOnPanel();
+    }
+
+    @RuleAction(label = "medicalPanicOnPanel", description = "Medical Panic on all partitions")
+    public void medicalPanicOnPanel() {
+        ThingHandlerPanel handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        handler.medicalPanic();
+    }
+
+    public static void medicalPanicOnPanel(ThingActions actions) {
+        ((CaddxPanelActions) actions).medicalPanicOnPanel();
+    }
+
+    @RuleAction(label = "policePanicOnPanel", description = "Police Panic on all partitions")
+    public void policePanicOnPanel() {
+        ThingHandlerPanel handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        handler.policePanic();
+    }
+
+    public static void policePanicOnPanel(ThingActions actions) {
+        ((CaddxPanelActions) actions).policePanicOnPanel();
+    }
+
+    @RuleAction(label = "smokeDetectorResetOnPanel", description = "Smoke detector reset on all partitions")
+    public void smokeDetectorResetOnPanel() {
+        ThingHandlerPanel handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        handler.smokeDetectorReset();
+    }
+
+    public static void smokeDetectorResetOnPanel(ThingActions actions) {
+        ((CaddxPanelActions) actions).smokeDetectorResetOnPanel();
+    }
+
+    @RuleAction(label = "autoCallbackDownloadOnPanel", description = "Auto callback download on all partitions")
+    public void autoCallbackDownloadOnPanel() {
+        ThingHandlerPanel handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        handler.autoCallbackDownload();
+    }
+
+    public static void autoCallbackDownloadOnPanel(ThingActions actions) {
+        ((CaddxPanelActions) actions).autoCallbackDownloadOnPanel();
+    }
+
+    @RuleAction(label = "manualPickupDownloadOnPanel", description = "Manual pickup download on all partitions")
+    public void manualPickupDownloadOnPanel() {
+        ThingHandlerPanel handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        handler.manualPickupDownload();
+    }
+
+    public static void manualPickupDownloadOnPanel(ThingActions actions) {
+        ((CaddxPanelActions) actions).manualPickupDownloadOnPanel();
+    }
+
+    @RuleAction(label = "enableSilentExitOnPanel", description = "Enable silent exit on all partitions")
+    public void enableSilentExitOnPanel() {
+        ThingHandlerPanel handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        handler.enableSilentExit();
+    }
+
+    public static void enableSilentExitOnPanel(ThingActions actions) {
+        ((CaddxPanelActions) actions).enableSilentExitOnPanel();
+    }
+
+    @RuleAction(label = "performTestOnPanel", description = "Perform test on all partitions")
+    public void performTestOnPanel() {
+        ThingHandlerPanel handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        handler.performTest();
+    }
+
+    public static void performTestOnPanel(ThingActions actions) {
+        ((CaddxPanelActions) actions).performTestOnPanel();
+    }
+
+    @RuleAction(label = "groupBypassOnPanel", description = "Group Bypass on all partitions")
+    public void groupBypassOnPanel() {
+        ThingHandlerPanel handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        handler.groupBypass();
+    }
+
+    public static void groupBypassOnPanel(ThingActions actions) {
+        ((CaddxPanelActions) actions).groupBypassOnPanel();
+    }
+
+    @RuleAction(label = "auxiliaryFunction1OnPanel", description = "Auxiliary Function 1 on all partitions")
+    public void auxiliaryFunction1OnPanel() {
+        ThingHandlerPanel handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        handler.auxiliaryFunction1();
+    }
+
+    public static void auxiliaryFunction1OnPanel(ThingActions actions) {
+        ((CaddxPanelActions) actions).auxiliaryFunction1OnPanel();
+    }
+
+    @RuleAction(label = "auxiliaryFunction2OnPanel", description = "Auxiliary Function 2 on all partitions")
+    public void auxiliaryFunction2OnPanel() {
+        ThingHandlerPanel handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        handler.auxiliaryFunction2();
+    }
+
+    public static void auxiliaryFunction2OnPanel(ThingActions actions) {
+        ((CaddxPanelActions) actions).auxiliaryFunction2OnPanel();
+    }
+
+    @RuleAction(label = "startKeypadSounderOnPanel", description = "Start keypad sounder on all partitions")
+    public void startKeypadSounderOnPanel() {
+        ThingHandlerPanel handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        handler.startKeypadSounder();
+    }
+
+    public static void startKeypadSounderOnPanel(ThingActions actions) {
+        ((CaddxPanelActions) actions).startKeypadSounderOnPanel();
+    }
+}
diff --git a/bundles/org.openhab.binding.caddx/src/main/java/org/openhab/binding/caddx/internal/action/CaddxPartitionActions.java b/bundles/org.openhab.binding.caddx/src/main/java/org/openhab/binding/caddx/internal/action/CaddxPartitionActions.java
new file mode 100644 (file)
index 0000000..4e5f6a2
--- /dev/null
@@ -0,0 +1,475 @@
+/**
+ * Copyright (c) 2010-2020 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.action;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.caddx.internal.handler.ThingHandlerPartition;
+import org.openhab.core.automation.annotation.ActionInput;
+import org.openhab.core.automation.annotation.RuleAction;
+import org.openhab.core.thing.binding.ThingActions;
+import org.openhab.core.thing.binding.ThingActionsScope;
+import org.openhab.core.thing.binding.ThingHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This is the automation engine action handler service for the
+ * caddx bridge actions.
+ *
+ * @author Georgios Moutsos - Initial contribution
+ */
+@ThingActionsScope(name = "caddx")
+@NonNullByDefault
+public class CaddxPartitionActions implements ThingActions {
+    private final Logger logger = LoggerFactory.getLogger(CaddxPartitionActions.class);
+
+    private static final String HANDLER_IS_NULL = "ThingHandlerPartition is null!";
+
+    private @Nullable ThingHandlerPartition handler;
+
+    @Override
+    public void setThingHandler(@Nullable ThingHandler handler) {
+        if (handler instanceof ThingHandlerPartition) {
+            this.handler = (ThingHandlerPartition) handler;
+        }
+    }
+
+    @Override
+    public @Nullable ThingHandler getThingHandler() {
+        return this.handler;
+    }
+
+    // Valid are only 4 or 6 digit pins
+    private @Nullable String adjustPin(@Nullable String pin) {
+        if (pin == null) {
+            logger.debug("Skipping command due to null value for pin.");
+            return null;
+        }
+
+        if (!pin.matches("^\\d{4,4}|\\d{6,6}$")) {
+            logger.debug("Skipping command due to invalid value for pin. {}", pin);
+            return null;
+        }
+
+        return (pin.length() == 4) ? pin + "00" : pin;
+    }
+
+    @RuleAction(label = "turnOffAnySounderOrAlarm", description = "Turn off any sounder or alarm")
+    public void turnOffAnySounderOrAlarm(
+            @ActionInput(name = "pin", label = "pin", description = "The pin 4 or 6 digit pin") @Nullable String pin) {
+        ThingHandlerPartition handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        String adjustedPin = adjustPin(pin);
+        if (adjustedPin == null) {
+            return;
+        }
+
+        handler.turnOffAnySounderOrAlarm(adjustedPin);
+    }
+
+    public static void turnOffAnySounderOrAlarm(ThingActions actions, @Nullable String pin) {
+        ((CaddxPartitionActions) actions).turnOffAnySounderOrAlarm(pin);
+    }
+
+    @RuleAction(label = "disarm", description = "Dis-arm")
+    public void disarm(
+            @ActionInput(name = "pin", label = "pin", description = "The pin 4 or 6 digit pin") @Nullable String pin) {
+        ThingHandlerPartition handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        String adjustedPin = adjustPin(pin);
+        if (adjustedPin == null) {
+            return;
+        }
+
+        handler.disarm(adjustedPin);
+    }
+
+    public static void disarm(ThingActions actions, @Nullable String pin) {
+        ((CaddxPartitionActions) actions).disarm(pin);
+    }
+
+    @RuleAction(label = "armInAwayMode", description = "Arm in away mode")
+    public void armInAwayMode(
+            @ActionInput(name = "pin", label = "pin", description = "The pin 4 or 6 digit pin") @Nullable String pin) {
+        ThingHandlerPartition handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        String adjustedPin = adjustPin(pin);
+        if (adjustedPin == null) {
+            return;
+        }
+
+        handler.armInAwayMode(adjustedPin);
+    }
+
+    public static void armInAwayMode(ThingActions actions, @Nullable String pin) {
+        ((CaddxPartitionActions) actions).armInAwayMode(pin);
+    }
+
+    @RuleAction(label = "armInStayMode", description = "Arm in stay mode")
+    public void armInStayMode(
+            @ActionInput(name = "pin", label = "pin", description = "The pin 4 or 6 digit pin") @Nullable String pin) {
+        ThingHandlerPartition handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        String adjustedPin = adjustPin(pin);
+        if (adjustedPin == null) {
+            return;
+        }
+
+        handler.armInStayMode(adjustedPin);
+    }
+
+    public static void armInStayMode(ThingActions actions, @Nullable String pin) {
+        ((CaddxPartitionActions) actions).armInStayMode(pin);
+    }
+
+    @RuleAction(label = "cancel", description = "Cancel")
+    public void cancel(
+            @ActionInput(name = "pin", label = "pin", description = "The pin 4 or 6 digit pin") @Nullable String pin) {
+        ThingHandlerPartition handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        String adjustedPin = adjustPin(pin);
+        if (adjustedPin == null) {
+            return;
+        }
+
+        handler.cancel(adjustedPin);
+    }
+
+    public static void cancel(ThingActions actions, @Nullable String pin) {
+        ((CaddxPartitionActions) actions).cancel(pin);
+    }
+
+    @RuleAction(label = "initiateAutoArm", description = "Initiate auto arm")
+    public void initiateAutoArm(
+            @ActionInput(name = "pin", label = "pin", description = "The pin 4 or 6 digit pin") @Nullable String pin) {
+        ThingHandlerPartition handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        String adjustedPin = adjustPin(pin);
+        if (adjustedPin == null) {
+            return;
+        }
+
+        handler.initiateAutoArm(adjustedPin);
+    }
+
+    public static void initiateAutoArm(ThingActions actions, @Nullable String pin) {
+        ((CaddxPartitionActions) actions).initiateAutoArm(pin);
+    }
+
+    @RuleAction(label = "startWalkTestMode", description = "Start walk-test mode")
+    public void startWalkTestMode(
+            @ActionInput(name = "pin", label = "pin", description = "The pin 4 or 6 digit pin") @Nullable String pin) {
+        ThingHandlerPartition handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        String adjustedPin = adjustPin(pin);
+        if (adjustedPin == null) {
+            return;
+        }
+
+        handler.startWalkTestMode(adjustedPin);
+    }
+
+    public static void startWalkTestMode(ThingActions actions, @Nullable String pin) {
+        ((CaddxPartitionActions) actions).startWalkTestMode(pin);
+    }
+
+    @RuleAction(label = "stopWalkTestMode", description = "Stop walk-test mode")
+    public void stopWalkTestMode(
+            @ActionInput(name = "pin", label = "pin", description = "The pin 4 or 6 digit pin") @Nullable String pin) {
+        ThingHandlerPartition handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        String adjustedPin = adjustPin(pin);
+        if (adjustedPin == null) {
+            return;
+        }
+
+        handler.stopWalkTestMode(adjustedPin);
+    }
+
+    public static void stopWalkTestMode(ThingActions actions, @Nullable String pin) {
+        ((CaddxPartitionActions) actions).stopWalkTestMode(pin);
+    }
+
+    @RuleAction(label = "stay", description = "Stay (1 button arm / toggle interiors)")
+    public void stay() {
+        ThingHandlerPartition handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        handler.stay();
+    }
+
+    public static void stay(ThingActions actions) {
+        ((CaddxPartitionActions) actions).stay();
+    }
+
+    @RuleAction(label = "chime", description = "Chime (toggle chime mode)")
+    public void chime() {
+        ThingHandlerPartition handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        handler.chime();
+    }
+
+    public static void chime(ThingActions actions) {
+        ((CaddxPartitionActions) actions).chime();
+    }
+
+    @RuleAction(label = "exit", description = "Exit (1 button arm / toggle instant)")
+    public void exit() {
+        ThingHandlerPartition handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        handler.exit();
+    }
+
+    public static void exit(ThingActions actions) {
+        ((CaddxPartitionActions) actions).exit();
+    }
+
+    @RuleAction(label = "bypassInteriors", description = "Bypass Interiors")
+    public void bypassInteriors() {
+        ThingHandlerPartition handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        handler.bypassInteriors();
+    }
+
+    public static void bypassInteriors(ThingActions actions) {
+        ((CaddxPartitionActions) actions).bypassInteriors();
+    }
+
+    @RuleAction(label = "firePanic", description = "Fire Panic")
+    public void firePanic() {
+        ThingHandlerPartition handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        handler.firePanic();
+    }
+
+    public static void firePanic(ThingActions actions) {
+        ((CaddxPartitionActions) actions).firePanic();
+    }
+
+    @RuleAction(label = "medicalPanic", description = "Medical Panic")
+    public void medicalPanic() {
+        ThingHandlerPartition handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        handler.medicalPanic();
+    }
+
+    public static void medicalPanic(ThingActions actions) {
+        ((CaddxPartitionActions) actions).medicalPanic();
+    }
+
+    @RuleAction(label = "policePanic", description = "Police Panic")
+    public void policePanic() {
+        ThingHandlerPartition handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        handler.policePanic();
+    }
+
+    public static void policePanic(ThingActions actions) {
+        ((CaddxPartitionActions) actions).policePanic();
+    }
+
+    @RuleAction(label = "smokeDetectorReset", description = "Smoke detector reset")
+    public void smokeDetectorReset() {
+        ThingHandlerPartition handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        handler.smokeDetectorReset();
+    }
+
+    public static void smokeDetectorReset(ThingActions actions) {
+        ((CaddxPartitionActions) actions).smokeDetectorReset();
+    }
+
+    @RuleAction(label = "autoCallbackDownload", description = "Auto callback download")
+    public void autoCallbackDownload() {
+        ThingHandlerPartition handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        handler.autoCallbackDownload();
+    }
+
+    public static void autoCallbackDownload(ThingActions actions) {
+        ((CaddxPartitionActions) actions).autoCallbackDownload();
+    }
+
+    @RuleAction(label = "manualPickupDownload", description = "Manual pickup download")
+    public void manualPickupDownload() {
+        ThingHandlerPartition handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        handler.manualPickupDownload();
+    }
+
+    public static void manualPickupDownload(ThingActions actions) {
+        ((CaddxPartitionActions) actions).manualPickupDownload();
+    }
+
+    @RuleAction(label = "enableSilentExit", description = "Enable silent exit")
+    public void enableSilentExit() {
+        ThingHandlerPartition handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        handler.enableSilentExit();
+    }
+
+    public static void enableSilentExit(ThingActions actions) {
+        ((CaddxPartitionActions) actions).enableSilentExit();
+    }
+
+    @RuleAction(label = "performTest", description = "Perform test")
+    public void performTest() {
+        ThingHandlerPartition handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        handler.performTest();
+    }
+
+    public static void performTest(ThingActions actions) {
+        ((CaddxPartitionActions) actions).performTest();
+    }
+
+    @RuleAction(label = "groupBypass", description = "Group Bypass")
+    public void groupBypass() {
+        ThingHandlerPartition handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        handler.groupBypass();
+    }
+
+    public static void groupBypass(ThingActions actions) {
+        ((CaddxPartitionActions) actions).groupBypass();
+    }
+
+    @RuleAction(label = "auxiliaryFunction1", description = "Auxiliary Function 1")
+    public void auxiliaryFunction1() {
+        ThingHandlerPartition handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        handler.auxiliaryFunction1();
+    }
+
+    public static void auxiliaryFunction1(ThingActions actions) {
+        ((CaddxPartitionActions) actions).auxiliaryFunction1();
+    }
+
+    @RuleAction(label = "auxiliaryFunction2", description = "Auxiliary Function 2")
+    public void auxiliaryFunction2() {
+        ThingHandlerPartition handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        handler.auxiliaryFunction2();
+    }
+
+    public static void auxiliaryFunction2(ThingActions actions) {
+        ((CaddxPartitionActions) actions).auxiliaryFunction2();
+    }
+
+    @RuleAction(label = "startKeypadSounder", description = "Start keypad sounder")
+    public void startKeypadSounder() {
+        ThingHandlerPartition handler = this.handler;
+        if (handler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        handler.startKeypadSounder();
+    }
+
+    public static void startKeypadSounder(ThingActions actions) {
+        ((CaddxPartitionActions) actions).startKeypadSounder();
+    }
+}
diff --git a/bundles/org.openhab.binding.caddx/src/main/java/org/openhab/binding/caddx/internal/action/CaddxZoneActions.java b/bundles/org.openhab.binding.caddx/src/main/java/org/openhab/binding/caddx/internal/action/CaddxZoneActions.java
new file mode 100644 (file)
index 0000000..37883e6
--- /dev/null
@@ -0,0 +1,67 @@
+/**
+ * Copyright (c) 2010-2020 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.action;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.caddx.internal.handler.ThingHandlerZone;
+import org.openhab.core.automation.annotation.RuleAction;
+import org.openhab.core.thing.binding.ThingActions;
+import org.openhab.core.thing.binding.ThingActionsScope;
+import org.openhab.core.thing.binding.ThingHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This is the automation engine action handler service for the
+ * caddx bridge actions.
+ *
+ * @author Georgios Moutsos - Initial contribution
+ */
+@ThingActionsScope(name = "caddx")
+@NonNullByDefault
+public class CaddxZoneActions implements ThingActions {
+    private final Logger logger = LoggerFactory.getLogger(CaddxZoneActions.class);
+
+    private static final String HANDLER_IS_NULL = "ThingHandlerZone is null!";
+
+    private @Nullable ThingHandlerZone handler;
+
+    @Override
+    public void setThingHandler(@Nullable ThingHandler handler) {
+        if (handler instanceof ThingHandlerZone) {
+            this.handler = (ThingHandlerZone) handler;
+        }
+    }
+
+    @Override
+    public @Nullable ThingHandler getThingHandler() {
+        return this.handler;
+    }
+
+    @RuleAction(label = "bypass", description = "Bypass the zone")
+    public void bypass() {
+        // Check of parameters
+        ThingHandlerZone thingHandler = this.handler;
+        if (thingHandler == null) {
+            logger.debug(HANDLER_IS_NULL);
+            return;
+        }
+
+        thingHandler.bypass();
+    }
+
+    public static void bypass(ThingActions actions) {
+        ((CaddxZoneActions) actions).bypass();
+    }
+}
index 807efcc8257afb1a6dc2ad665132bc4c4bbab3d7..b1fdfbafbeeb14a21eac25ed3025db60fcbe41db 100644 (file)
@@ -25,10 +25,16 @@ public class CaddxKeypadConfiguration {
 
     // Keypad Thing constants
     public static final String KEYPAD_ADDRESS = "keypadAddress";
+    public static final String TERMINAL_MODE_SECONDS = "terminalModeSeconds";
 
     private int keypadAddress;
+    private int terminalModeSeconds;
 
     public int getKeypadAddress() {
         return keypadAddress;
     }
+
+    public int getTerminalModeSeconds() {
+        return terminalModeSeconds;
+    }
 }
index 9649c5f07bd4a943e51174040bc03be16b60ce56..f7775c5d2a045ede7f2b179326495aa281a35b57 100644 (file)
@@ -47,17 +47,16 @@ public abstract class CaddxBaseThingHandler extends BaseThingHandler {
     /** Caddx Alarm Thing type. */
     private CaddxThingType caddxThingType;
 
-    /** Partition Number. */
+    /** Partition */
     private int partitionNumber;
-
-    /** User Number. */
     private int userNumber;
 
-    /** Zone Number. */
+    /** Zone */
     private int zoneNumber;
 
-    /** Keypad Address. */
+    /** Keypad */
     private int keypadAddress;
+    private int terminalModeSeconds;
 
     public CaddxBaseThingHandler(Thing thing, CaddxThingType caddxThingType) {
         super(thing);
@@ -226,6 +225,24 @@ public abstract class CaddxBaseThingHandler extends BaseThingHandler {
         this.keypadAddress = keypadAddress;
     }
 
+    /**
+     * Get Keypad Terminal Mode Seconds.
+     *
+     * @return keypadAddress
+     */
+    public int getTerminalModeSeconds() {
+        return terminalModeSeconds;
+    }
+
+    /**
+     * Set Keypad Address.
+     *
+     * @param keypadAddress
+     */
+    public void setTerminalModeSeconds(int terminalModeSeconds) {
+        this.terminalModeSeconds = terminalModeSeconds;
+    }
+
     /**
      * Get Channel by ChannelUID.
      *
index 18bb0e54e8bbe20c23d335d15e8b150f90a2a039..6d193f0cfc08f764a984004e8cc7ccd475e8cf55 100644 (file)
@@ -17,8 +17,9 @@ import static org.openhab.binding.caddx.internal.CaddxBindingConstants.SEND_COMM
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.util.Collection;
-import java.util.Collections;
+import java.util.HashSet;
 import java.util.Map;
+import java.util.Set;
 import java.util.TooManyListenersException;
 import java.util.concurrent.ConcurrentHashMap;
 
@@ -32,6 +33,7 @@ import org.openhab.binding.caddx.internal.CaddxMessageType;
 import org.openhab.binding.caddx.internal.CaddxPanelListener;
 import org.openhab.binding.caddx.internal.CaddxProtocol;
 import org.openhab.binding.caddx.internal.CaddxSource;
+import org.openhab.binding.caddx.internal.action.CaddxBridgeActions;
 import org.openhab.binding.caddx.internal.config.CaddxBridgeConfiguration;
 import org.openhab.binding.caddx.internal.config.CaddxKeypadConfiguration;
 import org.openhab.binding.caddx.internal.config.CaddxPartitionConfiguration;
@@ -267,6 +269,12 @@ public class CaddxBridgeHandler extends BaseBridgeHandler implements CaddxPanelL
             case CaddxBindingConstants.PANEL_LOG_EVENT_REQUEST:
                 msg = new CaddxMessage(CaddxMessageType.LOG_EVENT_REQUEST, data);
                 break;
+            case CaddxBindingConstants.KEYPAD_TERMINAL_MODE_REQUEST:
+                msg = new CaddxMessage(CaddxMessageType.KEYPAD_TERMINAL_MODE_REQUEST, data);
+                break;
+            case CaddxBindingConstants.KEYPAD_SEND_KEYPAD_TEXT_MESSAGE:
+                msg = new CaddxMessage(CaddxMessageType.SEND_KEYPAD_TEXT_MESSAGE, data);
+                break;
             default:
                 logger.debug("Unknown command {}", command);
                 return false;
@@ -387,11 +395,6 @@ public class CaddxBridgeHandler extends BaseBridgeHandler implements CaddxPanelL
         updateStatus(ThingStatus.ONLINE);
     }
 
-    @Override
-    public Collection<Class<? extends ThingHandlerService>> getServices() {
-        return Collections.singleton(CaddxDiscoveryService.class);
-    }
-
     @Override
     public void childHandlerInitialized(ThingHandler childHandler, Thing childThing) {
         if (childHandler instanceof ThingHandlerPartition) {
@@ -429,4 +432,24 @@ public class CaddxBridgeHandler extends BaseBridgeHandler implements CaddxPanelL
 
         super.childHandlerDisposed(childHandler, childThing);
     }
+
+    @Override
+    public Collection<Class<? extends ThingHandlerService>> getServices() {
+        Set<Class<? extends ThingHandlerService>> set = new HashSet<Class<? extends ThingHandlerService>>(2);
+        set.add(CaddxDiscoveryService.class);
+        set.add(CaddxBridgeActions.class);
+        return set;
+    }
+
+    public void restart() {
+        // Stop the currently running communicator
+        CaddxCommunicator comm = communicator;
+        if (comm != null) {
+            comm.stop();
+            comm = null;
+        }
+
+        // Initialize again
+        initialize();
+    }
 }
index 05431441c2430d69c33600966441df30417639fb..47fb3af424920d023a7c14092a111d30c8f418de 100644 (file)
  */
 package org.openhab.binding.caddx.internal.handler;
 
+import java.util.Collection;
+import java.util.Collections;
+
 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.CaddxMessageType;
+import org.openhab.binding.caddx.internal.CaddxProperty;
+import org.openhab.binding.caddx.internal.action.CaddxKeypadActions;
+import org.openhab.core.library.types.StringType;
 import org.openhab.core.thing.ChannelUID;
 import org.openhab.core.thing.Thing;
 import org.openhab.core.thing.ThingStatus;
-import org.openhab.core.types.Command;
+import org.openhab.core.thing.ThingStatusInfo;
+import org.openhab.core.thing.binding.ThingHandlerService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * This is a class for handling a Keypad type Thing.
@@ -26,25 +38,82 @@ import org.openhab.core.types.Command;
  */
 @NonNullByDefault
 public class ThingHandlerKeypad extends CaddxBaseThingHandler {
-    /**
-     * Constructor.
-     *
-     * @param thing
-     */
+    private final Logger logger = LoggerFactory.getLogger(ThingHandlerKeypad.class);
+
     public ThingHandlerKeypad(Thing thing) {
         super(thing, CaddxThingType.KEYPAD);
     }
 
     @Override
     public void updateChannel(ChannelUID channelUID, String data) {
+        if (channelUID.getId().equals(CaddxBindingConstants.KEYPAD_KEY_PRESSED)) {
+            StringType stringType = new StringType(data);
+            updateState(channelUID, stringType);
+        }
     }
 
     @Override
-    public void handleCommand(ChannelUID channelUID, Command command) {
+    public void caddxEventReceived(CaddxEvent event, Thing thing) {
+        logger.trace("caddxEventReceived(): Event Received - {}.", event);
+
+        if (getThing().equals(thing)) {
+            CaddxMessage message = event.getCaddxMessage();
+            CaddxMessageType mt = message.getCaddxMessageType();
+
+            // Log event messages have special handling
+            if (CaddxMessageType.KEYPAD_MESSAGE_RECEIVED.equals(mt)) {
+                for (CaddxProperty p : mt.properties) {
+                    if (!("".equals(p.getId()))) {
+                        String value = message.getPropertyById(p.getId());
+                        ChannelUID channelUID = new ChannelUID(getThing().getUID(), p.getId());
+                        updateChannel(channelUID, value);
+                    }
+                }
+            }
+
+            updateStatus(ThingStatus.ONLINE);
+        }
     }
 
     @Override
-    public void caddxEventReceived(CaddxEvent event, Thing thing) {
-        updateStatus(ThingStatus.ONLINE);
+    public void bridgeStatusChanged(ThingStatusInfo bridgeStatusInfo) {
+        // Keypad follows the status of the bridge
+        updateStatus(bridgeStatusInfo.getStatus());
+
+        super.bridgeStatusChanged(bridgeStatusInfo);
+    }
+
+    @Override
+    public Collection<Class<? extends ThingHandlerService>> getServices() {
+        return Collections.singleton(CaddxKeypadActions.class);
+    }
+
+    public void enterTerminalMode() {
+        String cmd = CaddxBindingConstants.KEYPAD_TERMINAL_MODE_REQUEST;
+        logger.debug("Address: {}, Seconds: {}", getKeypadAddress(), getTerminalModeSeconds());
+        String data = String.format("%d,15", getKeypadAddress(), getTerminalModeSeconds());
+
+        CaddxBridgeHandler bridgeHandler = getCaddxBridgeHandler();
+        if (bridgeHandler == null) {
+            return;
+        }
+        bridgeHandler.sendCommand(cmd, data);
+    }
+
+    public void sendKeypadTextMessage(String displayLocation, String text) {
+        if (text.length() != 8) {
+            logger.debug("Text to be displayed on the keypad has not the correct length");
+            return;
+        }
+        String cmd = CaddxBindingConstants.KEYPAD_SEND_KEYPAD_TEXT_MESSAGE;
+        String data = String.format("%d,0,%d,%d,%d,%d,%d,%d,%d,%d,%d", getKeypadAddress(), displayLocation,
+                text.charAt(0), text.charAt(1), text.charAt(2), text.charAt(3), text.charAt(4), text.charAt(5),
+                text.charAt(6), text.charAt(7));
+
+        CaddxBridgeHandler bridgeHandler = getCaddxBridgeHandler();
+        if (bridgeHandler == null) {
+            return;
+        }
+        bridgeHandler.sendCommand(cmd, data);
     }
 }
index c199590104c2dea08edbcc277b24e6ce792cb3dd..d6dddd96703282a8914169469425f0ea7f5e49d1 100644 (file)
@@ -12,6 +12,8 @@
  */
 package org.openhab.binding.caddx.internal.handler;
 
+import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
@@ -21,11 +23,13 @@ import org.openhab.binding.caddx.internal.CaddxEvent;
 import org.openhab.binding.caddx.internal.CaddxMessage;
 import org.openhab.binding.caddx.internal.CaddxMessageType;
 import org.openhab.binding.caddx.internal.CaddxProperty;
+import org.openhab.binding.caddx.internal.action.CaddxPanelActions;
 import org.openhab.core.library.types.OnOffType;
 import org.openhab.core.library.types.StringType;
 import org.openhab.core.thing.ChannelUID;
 import org.openhab.core.thing.Thing;
 import org.openhab.core.thing.ThingStatus;
+import org.openhab.core.thing.binding.ThingHandlerService;
 import org.openhab.core.types.Command;
 import org.openhab.core.types.RefreshType;
 import org.slf4j.Logger;
@@ -191,4 +195,135 @@ public class ThingHandlerPanel extends CaddxBaseThingHandler {
             panelLogMessagesMap = map;
         }
     }
+
+    @Override
+    public Collection<Class<? extends ThingHandlerService>> getServices() {
+        return Collections.singleton(CaddxPanelActions.class);
+    }
+
+    private void sendPrimaryCommand(String pin, String function) {
+        String cmd = CaddxBindingConstants.PARTITION_PRIMARY_COMMAND_WITH_PIN;
+
+        // Build the data
+        StringBuilder sb = new StringBuilder();
+        sb.append("0x").append(pin.charAt(1)).append(pin.charAt(0)).append(",0x").append(pin.charAt(3))
+                .append(pin.charAt(2)).append(",0x").append(pin.charAt(5)).append(pin.charAt(4)).append(",")
+                .append(function).append(",").append("255");
+
+        CaddxBridgeHandler bridgeHandler = getCaddxBridgeHandler();
+        if (bridgeHandler == null) {
+            return;
+        }
+        bridgeHandler.sendCommand(cmd, sb.toString());
+    }
+
+    private void sendSecondaryCommand(String function) {
+        String cmd = CaddxBindingConstants.PARTITION_SECONDARY_COMMAND;
+
+        // Build the data
+        StringBuilder sb = new StringBuilder();
+        sb.append(function).append(",").append("255");
+
+        CaddxBridgeHandler bridgeHandler = getCaddxBridgeHandler();
+        if (bridgeHandler == null) {
+            return;
+        }
+        bridgeHandler.sendCommand(cmd, sb.toString());
+    }
+
+    public void turnOffAnySounderOrAlarm(String pin) {
+        sendPrimaryCommand(pin, "0");
+    }
+
+    public void disarm(String pin) {
+        sendPrimaryCommand(pin, "1");
+    }
+
+    public void armInAwayMode(String pin) {
+        sendPrimaryCommand(pin, "2");
+    }
+
+    public void armInStayMode(String pin) {
+        sendPrimaryCommand(pin, "3");
+    }
+
+    public void cancel(String pin) {
+        sendPrimaryCommand(pin, "4");
+    }
+
+    public void initiateAutoArm(String pin) {
+        sendPrimaryCommand(pin, "5");
+    }
+
+    public void startWalkTestMode(String pin) {
+        sendPrimaryCommand(pin, "6");
+    }
+
+    public void stopWalkTestMode(String pin) {
+        sendPrimaryCommand(pin, "7");
+    }
+
+    public void stay() {
+        sendSecondaryCommand("0");
+    }
+
+    public void chime() {
+        sendSecondaryCommand("1");
+    }
+
+    public void exit() {
+        sendSecondaryCommand("2");
+    }
+
+    public void bypassInteriors() {
+        sendSecondaryCommand("3");
+    }
+
+    public void firePanic() {
+        sendSecondaryCommand("4");
+    }
+
+    public void medicalPanic() {
+        sendSecondaryCommand("5");
+    }
+
+    public void policePanic() {
+        sendSecondaryCommand("6");
+    }
+
+    public void smokeDetectorReset() {
+        sendSecondaryCommand("7");
+    }
+
+    public void autoCallbackDownload() {
+        sendSecondaryCommand("8");
+    }
+
+    public void manualPickupDownload() {
+        sendSecondaryCommand("9");
+    }
+
+    public void enableSilentExit() {
+        sendSecondaryCommand("10");
+    }
+
+    public void performTest() {
+        sendSecondaryCommand("11");
+    }
+
+    public void groupBypass() {
+        sendSecondaryCommand("12");
+    }
+
+    public void auxiliaryFunction1() {
+        sendSecondaryCommand("13");
+    }
+
+    public void auxiliaryFunction2() {
+        sendSecondaryCommand("14");
+    }
+
+    public void startKeypadSounder() {
+        sendSecondaryCommand("15");
+    }
 }
index c7e25f777f6b47351a48e0dd9e89264cb87d26d1..29c609dc29de1ed1a8e7ed71b78208a88c68332e 100644 (file)
  */
 package org.openhab.binding.caddx.internal.handler;
 
+import java.util.Collection;
+import java.util.Collections;
+
 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.CaddxMessageType;
 import org.openhab.binding.caddx.internal.CaddxProperty;
+import org.openhab.binding.caddx.internal.action.CaddxPartitionActions;
 import org.openhab.core.library.types.DecimalType;
 import org.openhab.core.library.types.OnOffType;
 import org.openhab.core.thing.ChannelUID;
 import org.openhab.core.thing.Thing;
 import org.openhab.core.thing.ThingStatus;
+import org.openhab.core.thing.binding.ThingHandlerService;
 import org.openhab.core.types.Command;
 import org.openhab.core.types.RefreshType;
 import org.slf4j.Logger;
@@ -111,4 +116,135 @@ public class ThingHandlerPartition extends CaddxBaseThingHandler {
             updateStatus(ThingStatus.ONLINE);
         }
     }
+
+    @Override
+    public Collection<Class<? extends ThingHandlerService>> getServices() {
+        return Collections.singleton(CaddxPartitionActions.class);
+    }
+
+    private void sendPrimaryCommand(String pin, String function) {
+        String cmd = CaddxBindingConstants.PARTITION_PRIMARY_COMMAND_WITH_PIN;
+
+        // Build the data
+        StringBuilder sb = new StringBuilder();
+        sb.append("0x").append(pin.charAt(1)).append(pin.charAt(0)).append(",0x").append(pin.charAt(3))
+                .append(pin.charAt(2)).append(",0x").append(pin.charAt(5)).append(pin.charAt(4)).append(",")
+                .append(function).append(",").append(Integer.toString(1 << getPartitionNumber() - 1));
+
+        CaddxBridgeHandler bridgeHandler = getCaddxBridgeHandler();
+        if (bridgeHandler == null) {
+            return;
+        }
+        bridgeHandler.sendCommand(cmd, sb.toString());
+    }
+
+    private void sendSecondaryCommand(String function) {
+        String cmd = CaddxBindingConstants.PARTITION_SECONDARY_COMMAND;
+
+        // Build the data
+        StringBuilder sb = new StringBuilder();
+        sb.append(function).append(",").append(Integer.toString(1 << getPartitionNumber() - 1));
+
+        CaddxBridgeHandler bridgeHandler = getCaddxBridgeHandler();
+        if (bridgeHandler == null) {
+            return;
+        }
+        bridgeHandler.sendCommand(cmd, sb.toString());
+    }
+
+    public void turnOffAnySounderOrAlarm(String pin) {
+        sendPrimaryCommand(pin, "0");
+    }
+
+    public void disarm(String pin) {
+        sendPrimaryCommand(pin, "1");
+    }
+
+    public void armInAwayMode(String pin) {
+        sendPrimaryCommand(pin, "2");
+    }
+
+    public void armInStayMode(String pin) {
+        sendPrimaryCommand(pin, "3");
+    }
+
+    public void cancel(String pin) {
+        sendPrimaryCommand(pin, "4");
+    }
+
+    public void initiateAutoArm(String pin) {
+        sendPrimaryCommand(pin, "5");
+    }
+
+    public void startWalkTestMode(String pin) {
+        sendPrimaryCommand(pin, "6");
+    }
+
+    public void stopWalkTestMode(String pin) {
+        sendPrimaryCommand(pin, "7");
+    }
+
+    public void stay() {
+        sendSecondaryCommand("0");
+    }
+
+    public void chime() {
+        sendSecondaryCommand("1");
+    }
+
+    public void exit() {
+        sendSecondaryCommand("2");
+    }
+
+    public void bypassInteriors() {
+        sendSecondaryCommand("3");
+    }
+
+    public void firePanic() {
+        sendSecondaryCommand("4");
+    }
+
+    public void medicalPanic() {
+        sendSecondaryCommand("5");
+    }
+
+    public void policePanic() {
+        sendSecondaryCommand("6");
+    }
+
+    public void smokeDetectorReset() {
+        sendSecondaryCommand("7");
+    }
+
+    public void autoCallbackDownload() {
+        sendSecondaryCommand("8");
+    }
+
+    public void manualPickupDownload() {
+        sendSecondaryCommand("9");
+    }
+
+    public void enableSilentExit() {
+        sendSecondaryCommand("10");
+    }
+
+    public void performTest() {
+        sendSecondaryCommand("11");
+    }
+
+    public void groupBypass() {
+        sendSecondaryCommand("12");
+    }
+
+    public void auxiliaryFunction1() {
+        sendSecondaryCommand("13");
+    }
+
+    public void auxiliaryFunction2() {
+        sendSecondaryCommand("14");
+    }
+
+    public void startKeypadSounder() {
+        sendSecondaryCommand("15");
+    }
 }
index 91c6d66ad86af68f32551e50d17204fa9512fff8..349b5ea89a7d69a22331c8c927b62478b6de92c2 100644 (file)
  */
 package org.openhab.binding.caddx.internal.handler;
 
+import java.util.Collection;
+import java.util.Collections;
+
 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.CaddxMessageType;
 import org.openhab.binding.caddx.internal.CaddxProperty;
+import org.openhab.binding.caddx.internal.action.CaddxZoneActions;
 import org.openhab.core.library.types.OnOffType;
 import org.openhab.core.library.types.OpenClosedType;
 import org.openhab.core.library.types.StringType;
 import org.openhab.core.thing.ChannelUID;
 import org.openhab.core.thing.Thing;
 import org.openhab.core.thing.ThingStatus;
+import org.openhab.core.thing.binding.ThingHandlerService;
 import org.openhab.core.types.Command;
 import org.openhab.core.types.RefreshType;
 import org.slf4j.Logger;
@@ -123,4 +128,20 @@ public class ThingHandlerZone extends CaddxBaseThingHandler {
             updateStatus(ThingStatus.ONLINE);
         }
     }
+
+    @Override
+    public Collection<Class<? extends ThingHandlerService>> getServices() {
+        return Collections.singleton(CaddxZoneActions.class);
+    }
+
+    public void bypass() {
+        String cmd = CaddxBindingConstants.ZONE_BYPASSED;
+        String data = String.format("%d", getZoneNumber() - 1);
+
+        CaddxBridgeHandler bridgeHandler = getCaddxBridgeHandler();
+        if (bridgeHandler == null) {
+            return;
+        }
+        bridgeHandler.sendCommand(cmd, data);
+    }
 }
index 86d06e2e13ed2ebeac5f127d865f71d510977cde..836bdb4b99e90989ac4e611efbedca8695010415 100644 (file)
        </channel-type>
 
        <!-- keypad -->
-       <channel-type id="led">
-               <item-type>Number</item-type>
-               <label>Keypad Led</label>
-               <description>Keypad Led (0=Off, 1=On, 2=Flashing)</description>
-               <state pattern="%d" readOnly="true">
-                       <options>
-                               <option value="0">Off</option>
-                               <option value="1">On</option>
-                               <option value="2">Flashing</option>
-                       </options>
-               </state>
+       <channel-type id="keypad_button_press">
+               <item-type>String</item-type>
+               <label>Key</label>
+               <description>Key text</description>
+               <state pattern="%s" readOnly="true"></state>
        </channel-type>
 
 </thing:thing-descriptions>
index b339f196825c95c180910bca5889c35c99e424ba..03a19616afa3f6df2539352ac650ba0aa3b14430 100644 (file)
                <label>Caddx Alarm Keypad</label>
                <description>Represents any of the keypads of the Caddx Alarm System.</description>
 
+               <channels>
+                       <channel id="keypad_key_pressed" typeId="keypad_button_press">
+                               <label>Key</label>
+                               <description>Key pressed</description>
+                       </channel>
+               </channels>
+
                <representation-property>keypadAddress</representation-property>
 
                <config-description>
-                       <parameter name="keypadAddress" type="text" required="true">
+                       <parameter name="keypadAddress" type="integer" required="true" min="192" max="255">
                                <label>Keypad Address</label>
                                <description>The Keypad Address.</description>
+                               <default>192</default>
+                       </parameter>
+                       <parameter name="terminalModeSeconds" type="integer" required="true" min="1" max="120">
+                               <label>Terminal Mode Seconds</label>
+                               <description>The number of Seconds the keypad has to remain in Terminal Mode.</description>
                        </parameter>
                </config-description>
        </thing-type>