]> git.basschouten.com Git - openhab-addons.git/commitdiff
[powermax] Improve debugging in message classes (#9314)
authorRon Isaacson <isaacson.ron@gmail.com>
Sat, 2 Jan 2021 19:59:57 +0000 (14:59 -0500)
committerGitHub <noreply@github.com>
Sat, 2 Jan 2021 19:59:57 +0000 (20:59 +0100)
* Improve debugging in message classes
Each PowermaxBaseMessage subclass had its own toString() which added
useful debug info but duplicated a lot of the logic in the message
handler. I've moved the debug info inline and removed the duplication,
and also added decoding for more values to the debug output.
* Fix for 0xFF byte values, which convert to int -1
* Change to inline debug messages

Signed-off-by: Ron Isaacson <isaacson.ron@gmail.com>
17 files changed:
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/handler/PowermaxBridgeHandler.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/message/PowermaxAckMessage.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/message/PowermaxBaseMessage.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/message/PowermaxCommManager.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/message/PowermaxDeniedMessage.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/message/PowermaxDownloadRetryMessage.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/message/PowermaxEventLogMessage.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/message/PowermaxInfoMessage.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/message/PowermaxMessageConstants.java [new file with mode: 0644]
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/message/PowermaxPanelMessage.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/message/PowermaxPowerMasterMessage.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/message/PowermaxPowerlinkMessage.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/message/PowermaxSettingsMessage.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/message/PowermaxStatusMessage.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/message/PowermaxTimeoutMessage.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/message/PowermaxZonesNameMessage.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/message/PowermaxZonesTypeMessage.java

index 978babc8612adc88c868923ec2d0a03d4de504cb..bb69478c39d873e802d7c2be72234efdfed333c9 100644 (file)
@@ -134,7 +134,7 @@ public class PowermaxBridgeHandler extends BaseBridgeHandler implements Powermax
                 // Delay the startup in case the handler is restarted immediately
                 globalJob = scheduler.scheduleWithFixedDelay(() -> {
                     try {
-                        logger.debug("Powermax job...");
+                        logger.trace("Powermax job...");
                         updateMotionSensorState();
                         if (isConnected()) {
                             checkKeepAlive();
index 7718f47b3765b67beb23502e6968c5c29aab0683..e51690d013129847d92cb8f9af2819cd2cf3ca7c 100644 (file)
@@ -32,9 +32,7 @@ public class PowermaxAckMessage extends PowermaxBaseMessage {
     }
 
     @Override
-    public PowermaxState handleMessage(PowermaxCommManager commManager) {
-        super.handleMessage(commManager);
-
+    protected PowermaxState handleMessageInternal(PowermaxCommManager commManager) {
         if (commManager == null) {
             return null;
         }
index 154348e5bc5b586bc00dac7cab9fee6438857628..bc4df5d1d2993844944eb75dd93f6a6c9d65b802 100644 (file)
@@ -12,6 +12,7 @@
  */
 package org.openhab.binding.powermax.internal.message;
 
+import org.eclipse.jdt.annotation.Nullable;
 import org.openhab.binding.powermax.internal.state.PowermaxState;
 import org.openhab.core.util.HexUtils;
 import org.slf4j.Logger;
@@ -30,6 +31,7 @@ public class PowermaxBaseMessage {
     private int code;
     private PowermaxSendType sendType;
     private PowermaxReceiveType receiveType;
+    private Object messageType;
 
     /**
      * Constructor.
@@ -38,6 +40,7 @@ public class PowermaxBaseMessage {
      */
     public PowermaxBaseMessage(byte[] message) {
         this.sendType = null;
+        this.messageType = "UNKNOWN";
         decodeMessage(message);
     }
 
@@ -58,6 +61,7 @@ public class PowermaxBaseMessage {
      */
     public PowermaxBaseMessage(PowermaxSendType sendType, byte[] param) {
         this.sendType = sendType;
+        this.messageType = "UNKNOWN";
         byte[] message = new byte[sendType.getMessage().length + 3];
         int index = 0;
         message[index++] = 0x0D;
@@ -87,6 +91,8 @@ public class PowermaxBaseMessage {
         } catch (IllegalArgumentException e) {
             receiveType = null;
         }
+
+        messageType = sendType != null ? sendType : receiveType != null ? receiveType : "UNKNOWN";
     }
 
     /**
@@ -94,17 +100,26 @@ public class PowermaxBaseMessage {
      *
      * @return a new state containing all changes driven by the message
      */
-    public PowermaxState handleMessage(PowermaxCommManager commManager) {
+    public final PowermaxState handleMessage(PowermaxCommManager commManager) {
         // Send an ACK if needed
         if (isAckRequired() && commManager != null) {
             commManager.sendAck(this, (byte) 0x02);
         }
 
         if (logger.isDebugEnabled()) {
-            logger.debug("{}message handled by class {}: {}", (receiveType == null) ? "Unsupported " : "",
-                    this.getClass().getSimpleName(), this);
+            logger.debug("{}message will be handled by class {}:", (receiveType == null) ? "Unsupported " : "",
+                    this.getClass().getSimpleName());
+
+            debug("Raw data", rawData);
+            debug("Message type", code, messageType.toString());
         }
 
+        PowermaxState newState = handleMessageInternal(commManager);
+
+        return newState;
+    }
+
+    protected PowermaxState handleMessageInternal(PowermaxCommManager commManager) {
         return null;
     }
 
@@ -147,17 +162,42 @@ public class PowermaxBaseMessage {
         return receiveType == null || receiveType.isAckRequired();
     }
 
-    @Override
-    public String toString() {
-        String str = "\n - Raw data = " + HexUtils.bytesToHex(rawData);
-        str += "\n - type = " + String.format("%02X", code);
-        if (sendType != null) {
-            str += " ( " + sendType.toString() + " )";
-        } else if (receiveType != null) {
-            str += " ( " + receiveType.toString() + " )";
+    // Debugging helpers
+
+    public void debug(String name, String info, @Nullable String decoded) {
+        if (!logger.isDebugEnabled()) {
+            return;
         }
 
-        return str;
+        String decodedStr = "";
+
+        if (decoded != null && !decoded.isBlank()) {
+            decodedStr = " - " + decoded;
+        }
+
+        logger.debug("| {} = {}{}", name, info, decodedStr);
+    }
+
+    public void debug(String name, String info) {
+        debug(name, info, null);
+    }
+
+    public void debug(String name, byte[] data, @Nullable String decoded) {
+        String hex = "0x" + HexUtils.bytesToHex(data);
+        debug(name, hex, decoded);
+    }
+
+    public void debug(String name, byte[] data) {
+        debug(name, data, null);
+    }
+
+    public void debug(String name, int data, @Nullable String decoded) {
+        String hex = String.format("0x%02X", data);
+        debug(name, hex, decoded);
+    }
+
+    public void debug(String name, int data) {
+        debug(name, data, null);
     }
 
     /**
index 4fc57ff4942e4b773b0bba12f97ae0fcf7817d87..1e6a9da6bd0200e90780a571ca71847b34ba6b24 100644 (file)
@@ -239,7 +239,8 @@ public class PowermaxCommManager implements PowermaxMessageEventListener {
         PowermaxBaseMessage message = messageEvent.getMessage();
 
         if (logger.isDebugEnabled()) {
-            logger.debug("onNewMessageReceived(): received message {}",
+            logger.debug("onNewMessageReceived(): received message 0x{} ({})",
+                    HexUtils.bytesToHex(message.getRawData()),
                     (message.getReceiveType() != null) ? message.getReceiveType()
                             : String.format("%02X", message.getCode()));
         }
index ca1662dccf574be9dd76d855954c154e10606daa..1fd7bd7ed4c1c54071ceb85e60ac654e79101d7a 100644 (file)
@@ -36,9 +36,7 @@ public class PowermaxDeniedMessage extends PowermaxBaseMessage {
     }
 
     @Override
-    public PowermaxState handleMessage(PowermaxCommManager commManager) {
-        super.handleMessage(commManager);
-
+    protected PowermaxState handleMessageInternal(PowermaxCommManager commManager) {
         if (commManager == null) {
             return null;
         }
index 417125cc7d903420f8a97825cfbc9763a6cf3e79..4a6d828adbe818cbee54c731733506bd819d0851 100644 (file)
@@ -32,9 +32,7 @@ public class PowermaxDownloadRetryMessage extends PowermaxBaseMessage {
     }
 
     @Override
-    public PowermaxState handleMessage(PowermaxCommManager commManager) {
-        super.handleMessage(commManager);
-
+    protected PowermaxState handleMessageInternal(PowermaxCommManager commManager) {
         if (commManager == null) {
             return null;
         }
@@ -42,20 +40,10 @@ public class PowermaxDownloadRetryMessage extends PowermaxBaseMessage {
         byte[] message = getRawData();
         int waitTime = message[4] & 0x000000FF;
 
+        debug("Wait time", waitTime + " seconds");
+
         commManager.sendMessageLater(PowermaxSendType.DOWNLOAD, waitTime);
 
         return null;
     }
-
-    @Override
-    public String toString() {
-        String str = super.toString();
-
-        byte[] message = getRawData();
-        int waitTime = message[4] & 0x000000FF;
-
-        str += "\n - wait time = " + waitTime + " seconds";
-
-        return str;
-    }
 }
index bd17cc91e03ac4125e6a295392100d5e290fdbe7..26b023c350552f89bd2310ab6dfae507f3097c6b 100644 (file)
@@ -22,44 +22,6 @@ import org.openhab.binding.powermax.internal.state.PowermaxState;
  */
 public class PowermaxEventLogMessage extends PowermaxBaseMessage {
 
-    public static final String[] LOG_EVENT_TABLE = new String[] { "None", "Interior Alarm", "Perimeter Alarm",
-            "Delay Alarm", "24h Silent Alarm", "24h Audible Alarm", "Tamper", "Control Panel Tamper", "Tamper Alarm",
-            "Tamper Alarm", "Communication Loss", "Panic From Keyfob", "Panic From Control Panel", "Duress",
-            "Confirm Alarm", "General Trouble", "General Trouble Restore", "Interior Restore", "Perimeter Restore",
-            "Delay Restore", "24h Silent Restore", "24h Audible Restore", "Tamper Restore",
-            "Control Panel Tamper Restore", "Tamper Restore", "Tamper Restore", "Communication Restore", "Cancel Alarm",
-            "General Restore", "Trouble Restore", "Not used", "Recent Close", "Fire", "Fire Restore", "No Active",
-            "Emergency", "No used", "Disarm Latchkey", "Panic Restore", "Supervision (Inactive)",
-            "Supervision Restore (Active)", "Low Battery", "Low Battery Restore", "AC Fail", "AC Restore",
-            "Control Panel Low Battery", "Control Panel Low Battery Restore", "RF Jamming", "RF Jamming Restore",
-            "Communications Failure", "Communications Restore", "Telephone Line Failure", "Telephone Line Restore",
-            "Auto Test", "Fuse Failure", "Fuse Restore", "Keyfob Low Battery", "Keyfob Low Battery Restore",
-            "Engineer Reset", "Battery Disconnect", "1-Way Keypad Low Battery", "1-Way Keypad Low Battery Restore",
-            "1-Way Keypad Inactive", "1-Way Keypad Restore Active", "Low Battery", "Clean Me", "Fire Trouble",
-            "Low Battery", "Battery Restore", "AC Fail", "AC Restore", "Supervision (Inactive)",
-            "Supervision Restore (Active)", "Gas Alert", "Gas Alert Restore", "Gas Trouble", "Gas Trouble Restore",
-            "Flood Alert", "Flood Alert Restore", "X-10 Trouble", "X-10 Trouble Restore", "Arm Home", "Arm Away",
-            "Quick Arm Home", "Quick Arm Away", "Disarm", "Fail To Auto-Arm", "Enter To Test Mode",
-            "Exit From Test Mode", "Force Arm", "Auto Arm", "Instant Arm", "Bypass", "Fail To Arm", "Door Open",
-            "Communication Established By Control Panel", "System Reset", "Installer Programming", "Wrong Password",
-            "Not Sys Event", "Not Sys Event", "Extreme Hot Alert", "Extreme Hot Alert Restore", "Freeze Alert",
-            "Freeze Alert Restore", "Human Cold Alert", "Human Cold Alert Restore", "Human Hot Alert",
-            "Human Hot Alert Restore", "Temperature Sensor Trouble", "Temperature Sensor Trouble Restore",
-            // new values partition models
-            "PIR Mask", "PIR Mask Restore", "", "", "", "", "", "", "", "", "", "", "Alarmed", "Restore", "Alarmed",
-            "Restore", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "Exit Installer", "Enter Installer",
-            "", "", "", "", "" };
-
-    public static final String[] LOG_USER_TABLE = new String[] { "System", "Zone 1", "Zone 2", "Zone 3", "Zone 4",
-            "Zone 5", "Zone 6", "Zone 7", "Zone 8", "Zone 9", "Zone 10", "Zone 11", "Zone 12", "Zone 13", "Zone 14",
-            "Zone 15", "Zone 16", "Zone 17", "Zone 18", "Zone 19", "Zone 20", "Zone 21", "Zone 22", "Zone 23",
-            "Zone 24", "Zone 25", "Zone 26", "Zone 27", "Zone 28", "Zone 29", "Zone 30", "Fob 1", "Fob 2", "Fob 3",
-            "Fob 4", "Fob 5", "Fob 6", "Fob 7", "Fob 8", "User 1", "User 2", "User 3", "User 4", "User 5", "User 6",
-            "User 7", "User 8", "Pad 1", "Pad 2", "Pad 3", "Pad 4", "Pad 5", "Pad 6", "Pad 7", "Pad 8", "Siren 1",
-            "Siren 2", "2Pad 1", "2Pad 2", "2Pad 3", "2Pad 4", "X10 1", "X10 2", "X10 3", "X10 4", "X10 5", "X10 6",
-            "X10 7", "X10 8", "X10 9", "X10 10", "X10 11", "X10 12", "X10 13", "X10 14", "X10 15", "PGM", "GSM",
-            "P-LINK", "PTag 1", "PTag 2", "PTag 3", "PTag 4", "PTag 5", "PTag 6", "PTag 7", "PTag 8" };
-
     /**
      * Constructor
      *
@@ -71,9 +33,7 @@ public class PowermaxEventLogMessage extends PowermaxBaseMessage {
     }
 
     @Override
-    public PowermaxState handleMessage(PowermaxCommManager commManager) {
-        super.handleMessage(commManager);
-
+    protected PowermaxState handleMessageInternal(PowermaxCommManager commManager) {
         if (commManager == null) {
             return null;
         }
@@ -83,11 +43,14 @@ public class PowermaxEventLogMessage extends PowermaxBaseMessage {
 
         byte[] message = getRawData();
         int eventNum = message[3] & 0x000000FF;
-        eventNum--;
 
-        if (eventNum == 0) {
+        debug("Event number", eventNum);
+
+        if (eventNum == 1) {
             int eventCnt = message[2] & 0x000000FF;
             updatedState.setEventLogSize(eventCnt - 1);
+
+            debug("Event count", eventCnt);
         } else {
             int second = message[4] & 0x000000FF;
             int minute = message[5] & 0x000000FF;
@@ -95,14 +58,11 @@ public class PowermaxEventLogMessage extends PowermaxBaseMessage {
             int day = message[7] & 0x000000FF;
             int month = message[8] & 0x000000FF;
             int year = (message[9] & 0x000000FF) + 2000;
+            String timestamp = String.format("%02d/%02d/%04d %02d:%02d:%02d", day, month, year, hour, minute, second);
             byte eventZone = message[10];
             byte logEvent = message[11];
-            String logEventStr = ((logEvent & 0x000000FF) < LOG_EVENT_TABLE.length)
-                    ? LOG_EVENT_TABLE[logEvent & 0x000000FF]
-                    : "UNKNOWN";
-            String logUserStr = ((eventZone & 0x000000FF) < LOG_USER_TABLE.length)
-                    ? LOG_USER_TABLE[eventZone & 0x000000FF]
-                    : "UNKNOWN";
+            String logEventStr = PowermaxMessageConstants.getSystemEventString(logEvent & 0x000000FF);
+            String logUserStr = PowermaxMessageConstants.getZoneOrUserString(eventZone & 0x000000FF);
 
             String eventStr;
             if (panelSettings.getPanelType().getPartitions() > 1) {
@@ -116,55 +76,18 @@ public class PowermaxEventLogMessage extends PowermaxBaseMessage {
                 } else {
                     part = "Panel";
                 }
-                eventStr = String.format("%02d/%02d/%04d %02d:%02d / %s: %s (%s)", day, month, year, hour, minute, part,
-                        logEventStr, logUserStr);
+                eventStr = String.format("%s / %s: %s (%s)", timestamp, part, logEventStr, logUserStr);
             } else {
-                eventStr = String.format("%02d/%02d/%04d %02d:%02d:%02d: %s (%s)", day, month, year, hour, minute,
-                        second, logEventStr, logUserStr);
+                eventStr = String.format("%s: %s (%s)", timestamp, logEventStr, logUserStr);
             }
-            updatedState.setEventLogSize(eventNum);
-            updatedState.setEventLog(eventNum, eventStr);
-        }
-
-        return updatedState;
-    }
-
-    @Override
-    public String toString() {
-        String str = super.toString();
-
-        byte[] message = getRawData();
-        int eventNum = message[3] & 0x000000FF;
-
-        str += "\n - event number = " + eventNum;
+            updatedState.setEventLogSize(eventNum - 1);
+            updatedState.setEventLog(eventNum - 1, eventStr);
 
-        if (eventNum == 1) {
-            int eventCnt = message[2] & 0x000000FF;
-
-            str += "\n - event count = " + eventCnt;
-        } else {
-            int second = message[4] & 0x000000FF;
-            int minute = message[5] & 0x000000FF;
-            int hour = message[6] & 0x000000FF;
-            int day = message[7] & 0x000000FF;
-            int month = message[8] & 0x000000FF;
-            int year = (message[9] & 0x000000FF) + 2000;
-            byte eventZone = message[10];
-            byte logEvent = message[11];
-
-            String logEventStr = ((logEvent & 0x000000FF) < LOG_EVENT_TABLE.length)
-                    ? LOG_EVENT_TABLE[logEvent & 0x000000FF]
-                    : "UNKNOWN";
-            String logUserStr = ((eventZone & 0x000000FF) < LOG_USER_TABLE.length)
-                    ? LOG_USER_TABLE[eventZone & 0x000000FF]
-                    : "UNKNOWN";
-
-            str += "\n - event " + eventNum + " date & time = "
-                    + String.format("%02d/%02d/%04d %02d:%02d:%02d", day, month, year, hour, minute, second);
-            str += "\n - event " + eventNum + " zone code = " + String.format("%08X - %s", eventZone, logUserStr);
-            str += "\n - event " + eventNum + " event code = " + String.format("%08X - %s", logEvent, logEventStr);
+            debug("Event " + eventNum + " date/time", timestamp);
+            debug("Event " + eventNum + " zone code", eventZone, logUserStr);
+            debug("Event " + eventNum + " event code", logEvent, logEventStr);
         }
 
-        return str;
+        return updatedState;
     }
 }
index 2fb089d156db793e89d0f60389160f503e481554..74f25d58fdc982337eafa3af72a8680e341690eb 100644 (file)
@@ -37,9 +37,7 @@ public class PowermaxInfoMessage extends PowermaxBaseMessage {
     }
 
     @Override
-    public PowermaxState handleMessage(PowermaxCommManager commManager) {
-        super.handleMessage(commManager);
-
+    protected PowermaxState handleMessageInternal(PowermaxCommManager commManager) {
         if (commManager == null) {
             return null;
         }
@@ -47,15 +45,20 @@ public class PowermaxInfoMessage extends PowermaxBaseMessage {
         PowermaxState updatedState = commManager.createNewState();
 
         byte[] message = getRawData();
+        byte panelTypeNr = message[7];
+        String panelTypeStr;
 
         PowermaxPanelType panelType = null;
         try {
-            panelType = PowermaxPanelType.fromCode(message[7]);
+            panelType = PowermaxPanelType.fromCode(panelTypeNr);
+            panelTypeStr = panelType.toString();
         } catch (IllegalArgumentException e) {
-            logger.debug("Powermax alarm binding: unknwon panel type for code {}", message[7] & 0x000000FF);
             panelType = null;
+            panelTypeStr = "UNKNOWN";
         }
 
+        debug("Panel type", panelTypeNr, panelTypeStr);
+
         logger.debug("Reading panel settings");
         updatedState.setDownloadMode(true);
         commManager.sendMessage(PowermaxSendType.DL_PANELFW);
@@ -70,16 +73,4 @@ public class PowermaxInfoMessage extends PowermaxBaseMessage {
 
         return updatedState;
     }
-
-    @Override
-    public String toString() {
-        String str = super.toString();
-
-        byte[] message = getRawData();
-        byte panelTypeNr = message[7];
-
-        str += "\n - panel type number = " + String.format("%02X", panelTypeNr);
-
-        return str;
-    }
 }
diff --git a/bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/message/PowermaxMessageConstants.java b/bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/message/PowermaxMessageConstants.java
new file mode 100644 (file)
index 0000000..f4209c9
--- /dev/null
@@ -0,0 +1,102 @@
+/**
+ * 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.powermax.internal.message;
+
+/**
+ * Constants used in Powermax messages
+ *
+ * @author Ron Isaacson - Initial contribution
+ */
+public class PowermaxMessageConstants {
+
+    private PowermaxMessageConstants() {
+    }
+
+    private static String getValue(String[] table, int index) {
+        return (((index >= 0) && (index < table.length)) ? table[index] : "UNKNOWN");
+    }
+
+    /**
+     * System event lookup
+     */
+    public static String getSystemEventString(int code) {
+        return getValue(SYSTEM_EVENT_TABLE, code);
+    }
+
+    private static final String[] SYSTEM_EVENT_TABLE = new String[] { "None", "Interior Alarm", "Perimeter Alarm",
+            "Delay Alarm", "24h Silent Alarm", "24h Audible Alarm", "Tamper", "Control Panel Tamper", "Tamper Alarm",
+            "Tamper Alarm", "Communication Loss", "Panic From Keyfob", "Panic From Control Panel", "Duress",
+            "Confirm Alarm", "General Trouble", "General Trouble Restore", "Interior Restore", "Perimeter Restore",
+            "Delay Restore", "24h Silent Restore", "24h Audible Restore", "Tamper Restore",
+            "Control Panel Tamper Restore", "Tamper Restore", "Tamper Restore", "Communication Restore", "Cancel Alarm",
+            "General Restore", "Trouble Restore", "Not used", "Recent Close", "Fire", "Fire Restore", "No Active",
+            "Emergency", "No used", "Disarm Latchkey", "Panic Restore", "Supervision (Inactive)",
+            "Supervision Restore (Active)", "Low Battery", "Low Battery Restore", "AC Fail", "AC Restore",
+            "Control Panel Low Battery", "Control Panel Low Battery Restore", "RF Jamming", "RF Jamming Restore",
+            "Communications Failure", "Communications Restore", "Telephone Line Failure", "Telephone Line Restore",
+            "Auto Test", "Fuse Failure", "Fuse Restore", "Keyfob Low Battery", "Keyfob Low Battery Restore",
+            "Engineer Reset", "Battery Disconnect", "1-Way Keypad Low Battery", "1-Way Keypad Low Battery Restore",
+            "1-Way Keypad Inactive", "1-Way Keypad Restore Active", "Low Battery", "Clean Me", "Fire Trouble",
+            "Low Battery", "Battery Restore", "AC Fail", "AC Restore", "Supervision (Inactive)",
+            "Supervision Restore (Active)", "Gas Alert", "Gas Alert Restore", "Gas Trouble", "Gas Trouble Restore",
+            "Flood Alert", "Flood Alert Restore", "X-10 Trouble", "X-10 Trouble Restore", "Arm Home", "Arm Away",
+            "Quick Arm Home", "Quick Arm Away", "Disarm", "Fail To Auto-Arm", "Enter To Test Mode",
+            "Exit From Test Mode", "Force Arm", "Auto Arm", "Instant Arm", "Bypass", "Fail To Arm", "Door Open",
+            "Communication Established By Control Panel", "System Reset", "Installer Programming", "Wrong Password",
+            "Not Sys Event", "Not Sys Event", "Extreme Hot Alert", "Extreme Hot Alert Restore", "Freeze Alert",
+            "Freeze Alert Restore", "Human Cold Alert", "Human Cold Alert Restore", "Human Hot Alert",
+            "Human Hot Alert Restore", "Temperature Sensor Trouble", "Temperature Sensor Trouble Restore",
+            // new values partition models
+            "PIR Mask", "PIR Mask Restore", "", "", "", "", "", "", "", "", "", "", "Alarmed", "Restore", "Alarmed",
+            "Restore", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "Exit Installer", "Enter Installer",
+            "", "", "", "", "" };
+
+    /**
+     * Zone/User lookup
+     */
+    public static String getZoneOrUserString(int code) {
+        return getValue(ZONE_OR_USER_TABLE, code);
+    }
+
+    private static final String[] ZONE_OR_USER_TABLE = new String[] { "System", "Zone 1", "Zone 2", "Zone 3", "Zone 4",
+            "Zone 5", "Zone 6", "Zone 7", "Zone 8", "Zone 9", "Zone 10", "Zone 11", "Zone 12", "Zone 13", "Zone 14",
+            "Zone 15", "Zone 16", "Zone 17", "Zone 18", "Zone 19", "Zone 20", "Zone 21", "Zone 22", "Zone 23",
+            "Zone 24", "Zone 25", "Zone 26", "Zone 27", "Zone 28", "Zone 29", "Zone 30", "Fob 1", "Fob 2", "Fob 3",
+            "Fob 4", "Fob 5", "Fob 6", "Fob 7", "Fob 8", "User 1", "User 2", "User 3", "User 4", "User 5", "User 6",
+            "User 7", "User 8", "Pad 1", "Pad 2", "Pad 3", "Pad 4", "Pad 5", "Pad 6", "Pad 7", "Pad 8", "Siren 1",
+            "Siren 2", "2Pad 1", "2Pad 2", "2Pad 3", "2Pad 4", "X10 1", "X10 2", "X10 3", "X10 4", "X10 5", "X10 6",
+            "X10 7", "X10 8", "X10 9", "X10 10", "X10 11", "X10 12", "X10 13", "X10 14", "X10 15", "PGM", "GSM",
+            "P-LINK", "PTag 1", "PTag 2", "PTag 3", "PTag 4", "PTag 5", "PTag 6", "PTag 7", "PTag 8" };
+
+    /**
+     * Zone event lookup
+     */
+    public static String getZoneEventString(int code) {
+        return getValue(ZONE_EVENT_TABLE, code);
+    }
+
+    private static final String[] ZONE_EVENT_TABLE = new String[] { "None", "Tamper Alarm", "Tamper Restore", "Open",
+            "Closed", "Violated (Motion)", "Panic Alarm", "RF Jamming", "Tamper Open", "Communication Failure",
+            "Line Failure", "Fuse", "Not Active", "Low Battery", "AC Failure", "Fire Alarm", "Emergency",
+            "Siren Tamper", "Siren Tamper Restore", "Siren Low Battery", "Siren AC Fail" };
+
+    /**
+     * Message type lookup
+     */
+    public static String getMessageTypeString(int code) {
+        return getValue(MESSAGE_TYPE_TABLE, code);
+    }
+
+    private static final String[] MESSAGE_TYPE_TABLE = new String[] { "None", "Log Message", "Status Message",
+            "Tamper Message", "Zone Message", "Unknown", "Enroll/Bypass Message" };
+}
index 14d16208d785269c9567dd39f900e31594563567..55dd0b4a4e16f1ea8315d0aae4ed94c7aecbbeef 100644 (file)
@@ -32,9 +32,7 @@ public class PowermaxPanelMessage extends PowermaxBaseMessage {
     }
 
     @Override
-    public PowermaxState handleMessage(PowermaxCommManager commManager) {
-        super.handleMessage(commManager);
-
+    protected PowermaxState handleMessageInternal(PowermaxCommManager commManager) {
         if (commManager == null) {
             return null;
         }
@@ -44,18 +42,19 @@ public class PowermaxPanelMessage extends PowermaxBaseMessage {
         byte[] message = getRawData();
         int msgCnt = message[2] & 0x000000FF;
 
+        debug("Event count", msgCnt);
+
         for (int i = 1; i <= msgCnt; i++) {
             byte eventZone = message[2 + 2 * i];
             byte logEvent = message[3 + 2 * i];
             int eventType = logEvent & 0x0000007F;
-            String logEventStr = (eventType < PowermaxEventLogMessage.LOG_EVENT_TABLE.length)
-                    ? PowermaxEventLogMessage.LOG_EVENT_TABLE[eventType]
-                    : "UNKNOWN";
-            String logUserStr = ((eventZone & 0x000000FF) < PowermaxEventLogMessage.LOG_USER_TABLE.length)
-                    ? PowermaxEventLogMessage.LOG_USER_TABLE[eventZone & 0x000000FF]
-                    : "UNKNOWN";
+            String logEventStr = PowermaxMessageConstants.getSystemEventString(eventType);
+            String logUserStr = PowermaxMessageConstants.getZoneOrUserString(eventZone & 0x000000FF);
             updatedState.setPanelStatus(logEventStr + " (" + logUserStr + ")");
 
+            debug("Event " + i + " zone code", eventZone, logUserStr);
+            debug("Event " + i + " event code", eventType, logEventStr);
+
             String alarmStatus;
             try {
                 PowermaxAlarmType alarmType = PowermaxAlarmType.fromCode(eventType);
@@ -82,23 +81,4 @@ public class PowermaxPanelMessage extends PowermaxBaseMessage {
 
         return updatedState;
     }
-
-    @Override
-    public String toString() {
-        String str = super.toString();
-
-        byte[] message = getRawData();
-        int msgCnt = message[2] & 0x000000FF;
-
-        str += "\n - event count = " + msgCnt;
-        for (int i = 1; i <= msgCnt; i++) {
-            byte eventZone = message[2 + 2 * i];
-            byte logEvent = message[3 + 2 * i];
-
-            str += "\n - event " + i + " zone code = " + String.format("%08X", eventZone);
-            str += "\n - event " + i + " event code = " + String.format("%08X", logEvent);
-        }
-
-        return str;
-    }
 }
index d8b047d22b8a83eaded9eb11d8d4500fdda68e1f..1545c729814bab0e613a68c225e46d95e79b8c4d 100644 (file)
@@ -32,9 +32,7 @@ public class PowermaxPowerMasterMessage extends PowermaxBaseMessage {
     }
 
     @Override
-    public PowermaxState handleMessage(PowermaxCommManager commManager) {
-        super.handleMessage(commManager);
-
+    protected PowermaxState handleMessageInternal(PowermaxCommManager commManager) {
         if (commManager == null) {
             return null;
         }
@@ -42,6 +40,11 @@ public class PowermaxPowerMasterMessage extends PowermaxBaseMessage {
         byte[] message = getRawData();
         byte msgType = message[2];
         byte subType = message[3];
+        byte msgLen = message[4];
+
+        debug("Type", msgType);
+        debug("Subtype", subType);
+        debug("Message length", msgLen);
 
         if ((msgType == 0x03) && (subType == 0x39)) {
             commManager.sendMessage(PowermaxSendType.POWERMASTER_ZONE_STAT1);
@@ -50,20 +53,4 @@ public class PowermaxPowerMasterMessage extends PowermaxBaseMessage {
 
         return null;
     }
-
-    @Override
-    public String toString() {
-        String str = super.toString();
-
-        byte[] message = getRawData();
-        byte msgType = message[2];
-        byte subType = message[3];
-        byte msgLen = message[4];
-
-        str += "\n - type = " + String.format("%02X", msgType);
-        str += "\n - subtype = " + String.format("%02X", subType);
-        str += "\n - msgLen = " + String.format("%02X", msgLen);
-
-        return str;
-    }
 }
index f79f385d894078529ef9da7f679b949bb68b1d85..59bd9a9d2d5260b5fb9007a211e4eb1f188aa5ed 100644 (file)
@@ -36,9 +36,7 @@ public class PowermaxPowerlinkMessage extends PowermaxBaseMessage {
     }
 
     @Override
-    public PowermaxState handleMessage(PowermaxCommManager commManager) {
-        super.handleMessage(commManager);
-
+    protected PowermaxState handleMessageInternal(PowermaxCommManager commManager) {
         if (commManager == null) {
             return null;
         }
@@ -50,37 +48,31 @@ public class PowermaxPowerlinkMessage extends PowermaxBaseMessage {
 
         if (subType == 0x03) {
             // keep alive message
+
+            debug("Subtype", subType, "Keep Alive");
+
             commManager.sendAck(this, (byte) 0x02);
             updatedState = commManager.createNewState();
             updatedState.setLastKeepAlive(System.currentTimeMillis());
-        } else if (subType == 0x0A && message[4] == 0x01) {
-            logger.debug("Powermax alarm binding: Enrolling Powerlink");
-            commManager.enrollPowerlink();
-            updatedState = commManager.createNewState();
-            updatedState.setDownloadSetupRequired(true);
-        } else {
-            commManager.sendAck(this, (byte) 0x02);
-        }
-
-        return updatedState;
-    }
-
-    @Override
-    public String toString() {
-        String str = super.toString();
+        } else if (subType == 0x0A) {
+            byte enroll = message[4];
 
-        byte[] message = getRawData();
-        byte subType = message[2];
+            debug("Subtype", subType, "Enroll");
+            debug("Enroll", enroll);
 
-        if (subType == 0x03) {
-            str += "\n - sub type = keep alive";
-        } else if (subType == 0x0A) {
-            str += "\n - sub type = enroll";
-            str += "\n - enroll = " + String.format("%02X", message[4]);
+            if (enroll == 0x01) {
+                logger.debug("Powermax alarm binding: Enrolling Powerlink");
+                commManager.enrollPowerlink();
+                updatedState = commManager.createNewState();
+                updatedState.setDownloadSetupRequired(true);
+            } else {
+                commManager.sendAck(this, (byte) 0x02);
+            }
         } else {
-            str += "\n - sub type = " + String.format("%02X", subType);
+            debug("Subtype", subType, "UNKNOWN");
+            commManager.sendAck(this, (byte) 0x02);
         }
 
-        return str;
+        return updatedState;
     }
 }
index ed36f04c879e37b8f08b77baf338e832c6843183..3d85dc8bdd3a8d3f6ed5c0ca749bec5898695b6f 100644 (file)
@@ -38,9 +38,7 @@ public class PowermaxSettingsMessage extends PowermaxBaseMessage {
     }
 
     @Override
-    public PowermaxState handleMessage(PowermaxCommManager commManager) {
-        super.handleMessage(commManager);
-
+    protected PowermaxState handleMessageInternal(PowermaxCommManager commManager) {
         if (commManager == null) {
             return null;
         }
@@ -52,6 +50,9 @@ public class PowermaxSettingsMessage extends PowermaxBaseMessage {
         int page = message[3] & 0x000000FF;
         int length = 0;
 
+        debug("Page", page, Integer.toString(page));
+        debug("Index", index, Integer.toString(index));
+
         if (getReceiveType() == PowermaxReceiveType.SETTINGS) {
             length = message.length - 6;
             updatedState.setUpdateSettings(Arrays.copyOfRange(message, 2, 2 + 2 + length));
@@ -74,18 +75,4 @@ public class PowermaxSettingsMessage extends PowermaxBaseMessage {
 
         return updatedState;
     }
-
-    @Override
-    public String toString() {
-        String str = super.toString();
-
-        byte[] message = getRawData();
-        int index = message[2] & 0x000000FF;
-        int page = message[3] & 0x000000FF;
-
-        str += "\n - page = " + String.format("%02X (%d)", page, page);
-        str += "\n - index = " + String.format("%02X (%d)", index, index);
-
-        return str;
-    }
 }
index 9739152d210afcf9c2b492377c025c26b0719dca..009957b00352c570214d7d7e9de6e560aeaf16b7 100644 (file)
  */
 package org.openhab.binding.powermax.internal.message;
 
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+
 import org.openhab.binding.powermax.internal.state.PowermaxArmMode;
 import org.openhab.binding.powermax.internal.state.PowermaxPanelSettings;
 import org.openhab.binding.powermax.internal.state.PowermaxState;
@@ -24,10 +28,34 @@ import org.openhab.binding.powermax.internal.state.PowermaxZoneSettings;
  */
 public class PowermaxStatusMessage extends PowermaxBaseMessage {
 
-    private static final String[] EVENT_TYPE_TABLE = new String[] { "None", "Tamper Alarm", "Tamper Restore", "Open",
-            "Closed", "Violated (Motion)", "Panic Alarm", "RF Jamming", "Tamper Open", "Communication Failure",
-            "Line Failure", "Fuse", "Not Active", "Low Battery", "AC Failure", "Fire Alarm", "Emergency",
-            "Siren Tamper", "Siren Tamper Restore", "Siren Low Battery", "Siren AC Fail" };
+    private static byte[] zoneBytes(byte zones1, byte zones9, byte zones17, byte zones25) {
+        return new byte[] { zones25, zones17, zones9, zones1 };
+    }
+
+    private static boolean[] zoneBits(byte[] zoneBytes) {
+        boolean[] zones = new boolean[32];
+        char[] binary = new BigInteger(zoneBytes).toString(2).toCharArray();
+        int len = binary.length - 1;
+
+        for (int i = len; i >= 0; i--) {
+            zones[len - i + 1] = (binary[i] == '1');
+        }
+
+        return zones;
+    }
+
+    private static String zoneList(byte[] zoneBytes) {
+        boolean[] zones = zoneBits(zoneBytes);
+        List<String> names = new ArrayList<>();
+
+        for (int i = 1; i < zones.length; i++) {
+            if (zones[i]) {
+                names.add(String.format("Zone %d", i));
+            }
+        }
+
+        return String.join(", ", names);
+    }
 
     /**
      * Constructor
@@ -40,9 +68,7 @@ public class PowermaxStatusMessage extends PowermaxBaseMessage {
     }
 
     @Override
-    public PowermaxState handleMessage(PowermaxCommManager commManager) {
-        super.handleMessage(commManager);
-
+    protected PowermaxState handleMessageInternal(PowermaxCommManager commManager) {
         if (commManager == null) {
             return null;
         }
@@ -52,17 +78,27 @@ public class PowermaxStatusMessage extends PowermaxBaseMessage {
 
         byte[] message = getRawData();
         byte eventType = message[3];
+        String eventTypeStr = PowermaxMessageConstants.getMessageTypeString(eventType & 0x000000FF);
+
+        debug("Event type", eventType, eventTypeStr);
 
         if (eventType == 0x02) {
-            int zoneStatus = (message[4] & 0x000000FF) | ((message[5] << 8) & 0x0000FF00)
-                    | ((message[6] << 16) & 0x00FF0000) | ((message[7] << 24) & 0xFF000000);
-            int batteryStatus = (message[8] & 0x000000FF) | ((message[9] << 8) & 0x0000FF00)
-                    | ((message[10] << 16) & 0x00FF0000) | ((message[11] << 24) & 0xFF000000);
+            byte[] zoneStatusBytes = zoneBytes(message[4], message[5], message[6], message[7]);
+            byte[] batteryStatusBytes = zoneBytes(message[8], message[9], message[10], message[11]);
+
+            boolean[] zoneStatus = zoneBits(zoneStatusBytes);
+            boolean[] batteryStatus = zoneBits(batteryStatusBytes);
+
+            String zoneStatusStr = zoneList(zoneStatusBytes);
+            String batteryStatusStr = zoneList(batteryStatusBytes);
 
             for (int i = 1; i <= panelSettings.getNbZones(); i++) {
-                updatedState.setSensorTripped(i, ((zoneStatus >> (i - 1)) & 0x1) > 0);
-                updatedState.setSensorLowBattery(i, ((batteryStatus >> (i - 1)) & 0x1) > 0);
+                updatedState.setSensorTripped(i, zoneStatus[i]);
+                updatedState.setSensorLowBattery(i, batteryStatus[i]);
             }
+
+            debug("Zone status", zoneStatusBytes, zoneStatusStr);
+            debug("Battery status", batteryStatusBytes, batteryStatusStr);
         } else if (eventType == 0x04) {
             byte sysStatus = message[4];
             byte sysFlags = message[5];
@@ -70,9 +106,8 @@ public class PowermaxStatusMessage extends PowermaxBaseMessage {
             byte zoneEType = message[7];
             int x10Status = (message[10] & 0x000000FF) | ((message[11] << 8) & 0x0000FF00);
 
-            String zoneETypeStr = ((zoneEType & 0x000000FF) < EVENT_TYPE_TABLE.length)
-                    ? EVENT_TYPE_TABLE[zoneEType & 0x000000FF]
-                    : "UNKNOWN";
+            String eventZoneStr = PowermaxMessageConstants.getZoneOrUserString(eventZone & 0x000000FF);
+            String zoneETypeStr = PowermaxMessageConstants.getZoneEventString(zoneEType & 0x000000FF);
 
             if (zoneEType == 0x03) {
                 updatedState.setSensorTripped(eventZone, Boolean.TRUE);
@@ -155,6 +190,12 @@ public class PowermaxStatusMessage extends PowermaxBaseMessage {
             updatedState.setArmMode(statusStr);
             updatedState.setStatusStr(statusStr + ", " + sysStatusStr);
 
+            debug("System status", sysStatus, statusStr);
+            debug("System flags", sysFlags, sysStatusStr);
+            debug("Event zone", eventZone, eventZoneStr);
+            debug("Zone event type", zoneEType, zoneETypeStr);
+            debug("X10 status", x10Status);
+
             for (int i = 1; i <= panelSettings.getNbZones(); i++) {
                 PowermaxZoneSettings zone = panelSettings.getZoneSettings(i);
                 if (zone != null) {
@@ -171,56 +212,17 @@ public class PowermaxStatusMessage extends PowermaxBaseMessage {
                 }
             }
         } else if (eventType == 0x06) {
-            int zoneBypass = (message[8] & 0x000000FF) | ((message[9] << 8) & 0x0000FF00)
-                    | ((message[10] << 16) & 0x00FF0000) | ((message[11] << 24) & 0xFF000000);
+            byte[] zoneBypassBytes = zoneBytes(message[8], message[9], message[10], message[11]);
+            boolean[] zoneBypass = zoneBits(zoneBypassBytes);
+            String zoneBypassStr = zoneList(zoneBypassBytes);
 
             for (int i = 1; i <= panelSettings.getNbZones(); i++) {
-                updatedState.setSensorBypassed(i, ((zoneBypass >> (i - 1)) & 0x1) > 0);
+                updatedState.setSensorBypassed(i, zoneBypass[i]);
             }
-        }
 
-        return updatedState;
-    }
-
-    @Override
-    public String toString() {
-        String str = super.toString();
-
-        byte[] message = getRawData();
-        byte eventType = message[3];
-
-        str += "\n - event type = " + String.format("%02X", eventType);
-        if (eventType == 0x02) {
-            int zoneStatus = (message[4] & 0x000000FF) | ((message[5] << 8) & 0x0000FF00)
-                    | ((message[6] << 16) & 0x00FF0000) | ((message[7] << 24) & 0xFF000000);
-            int batteryStatus = (message[8] & 0x000000FF) | ((message[9] << 8) & 0x0000FF00)
-                    | ((message[10] << 16) & 0x00FF0000) | ((message[11] << 24) & 0xFF000000);
-
-            str += "\n - zone status = " + String.format("%08X", zoneStatus);
-            str += "\n - battery status = " + String.format("%08X", batteryStatus);
-        } else if (eventType == 0x04) {
-            byte sysStatus = message[4];
-            byte sysFlags = message[5];
-            byte eventZone = message[6];
-            byte zoneEType = message[7];
-            int x10Status = (message[10] & 0x000000FF) | ((message[11] << 8) & 0x0000FF00);
-
-            String zoneETypeStr = ((zoneEType & 0x000000FF) < EVENT_TYPE_TABLE.length)
-                    ? EVENT_TYPE_TABLE[zoneEType & 0x000000FF]
-                    : "UNKNOWN";
-
-            str += "\n - system status = " + String.format("%02X", sysStatus);
-            str += "\n - system flags = " + String.format("%02X", sysFlags);
-            str += "\n - event zone = " + eventZone;
-            str += String.format("\n - zone event type = %02X (%s)", zoneEType, zoneETypeStr);
-            str += "\n - X10 status = " + String.format("%04X", x10Status);
-        } else if (eventType == 0x06) {
-            int zoneBypass = (message[8] & 0x000000FF) | ((message[9] << 8) & 0x0000FF00)
-                    | ((message[10] << 16) & 0x00FF0000) | ((message[11] << 24) & 0xFF000000);
-
-            str += "\n - zone bypass = " + String.format("%08X", zoneBypass);
+            debug("Zone bypass", zoneBypassBytes, zoneBypassStr);
         }
 
-        return str;
+        return updatedState;
     }
 }
index a3d6679e5f453a6211e013ed9e3bbf564a49ca22..54d092a62993ffdc32e05db04b49f8dd6535b1f7 100644 (file)
@@ -32,9 +32,7 @@ public class PowermaxTimeoutMessage extends PowermaxBaseMessage {
     }
 
     @Override
-    public PowermaxState handleMessage(PowermaxCommManager commManager) {
-        super.handleMessage(commManager);
-
+    protected PowermaxState handleMessageInternal(PowermaxCommManager commManager) {
         if (commManager != null) {
             commManager.sendMessage(PowermaxSendType.EXIT);
         }
index 488eb6e4d479858571ce31397f6b5333b38feb1d..dbe454327c419f7d679a890ca0ebd580ea33e229 100644 (file)
@@ -32,9 +32,7 @@ public class PowermaxZonesNameMessage extends PowermaxBaseMessage {
     }
 
     @Override
-    public PowermaxState handleMessage(PowermaxCommManager commManager) {
-        super.handleMessage(commManager);
-
+    protected PowermaxState handleMessageInternal(PowermaxCommManager commManager) {
         if (commManager == null) {
             return null;
         }
index 2d13587658bf5ecce17a35b92d8cf236e34ec9f4..55378d434f08e4b8ca8388d01d6e98f85a7e895a 100644 (file)
@@ -32,9 +32,7 @@ public class PowermaxZonesTypeMessage extends PowermaxBaseMessage {
     }
 
     @Override
-    public PowermaxState handleMessage(PowermaxCommManager commManager) {
-        super.handleMessage(commManager);
-
+    protected PowermaxState handleMessageInternal(PowermaxCommManager commManager) {
         if (commManager == null) {
             return null;
         }