// 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();
}
@Override
- public PowermaxState handleMessage(PowermaxCommManager commManager) {
- super.handleMessage(commManager);
-
+ protected PowermaxState handleMessageInternal(PowermaxCommManager commManager) {
if (commManager == null) {
return null;
}
*/
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;
private int code;
private PowermaxSendType sendType;
private PowermaxReceiveType receiveType;
+ private Object messageType;
/**
* Constructor.
*/
public PowermaxBaseMessage(byte[] message) {
this.sendType = null;
+ this.messageType = "UNKNOWN";
decodeMessage(message);
}
*/
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;
} catch (IllegalArgumentException e) {
receiveType = null;
}
+
+ messageType = sendType != null ? sendType : receiveType != null ? receiveType : "UNKNOWN";
}
/**
*
* @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;
}
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);
}
/**
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()));
}
}
@Override
- public PowermaxState handleMessage(PowermaxCommManager commManager) {
- super.handleMessage(commManager);
-
+ protected PowermaxState handleMessageInternal(PowermaxCommManager commManager) {
if (commManager == null) {
return null;
}
}
@Override
- public PowermaxState handleMessage(PowermaxCommManager commManager) {
- super.handleMessage(commManager);
-
+ protected PowermaxState handleMessageInternal(PowermaxCommManager commManager) {
if (commManager == null) {
return null;
}
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;
- }
}
*/
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
*
}
@Override
- public PowermaxState handleMessage(PowermaxCommManager commManager) {
- super.handleMessage(commManager);
-
+ protected PowermaxState handleMessageInternal(PowermaxCommManager commManager) {
if (commManager == null) {
return null;
}
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;
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) {
} 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;
}
}
}
@Override
- public PowermaxState handleMessage(PowermaxCommManager commManager) {
- super.handleMessage(commManager);
-
+ protected PowermaxState handleMessageInternal(PowermaxCommManager commManager) {
if (commManager == null) {
return null;
}
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);
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;
- }
}
--- /dev/null
+/**
+ * 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" };
+}
}
@Override
- public PowermaxState handleMessage(PowermaxCommManager commManager) {
- super.handleMessage(commManager);
-
+ protected PowermaxState handleMessageInternal(PowermaxCommManager commManager) {
if (commManager == null) {
return null;
}
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);
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;
- }
}
}
@Override
- public PowermaxState handleMessage(PowermaxCommManager commManager) {
- super.handleMessage(commManager);
-
+ protected PowermaxState handleMessageInternal(PowermaxCommManager commManager) {
if (commManager == null) {
return null;
}
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);
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;
- }
}
}
@Override
- public PowermaxState handleMessage(PowermaxCommManager commManager) {
- super.handleMessage(commManager);
-
+ protected PowermaxState handleMessageInternal(PowermaxCommManager commManager) {
if (commManager == null) {
return null;
}
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;
}
}
}
@Override
- public PowermaxState handleMessage(PowermaxCommManager commManager) {
- super.handleMessage(commManager);
-
+ protected PowermaxState handleMessageInternal(PowermaxCommManager commManager) {
if (commManager == null) {
return null;
}
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));
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;
- }
}
*/
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;
*/
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
}
@Override
- public PowermaxState handleMessage(PowermaxCommManager commManager) {
- super.handleMessage(commManager);
-
+ protected PowermaxState handleMessageInternal(PowermaxCommManager commManager) {
if (commManager == null) {
return null;
}
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];
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);
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) {
}
}
} 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;
}
}
}
@Override
- public PowermaxState handleMessage(PowermaxCommManager commManager) {
- super.handleMessage(commManager);
-
+ protected PowermaxState handleMessageInternal(PowermaxCommManager commManager) {
if (commManager != null) {
commManager.sendMessage(PowermaxSendType.EXIT);
}
}
@Override
- public PowermaxState handleMessage(PowermaxCommManager commManager) {
- super.handleMessage(commManager);
-
+ protected PowermaxState handleMessageInternal(PowermaxCommManager commManager) {
if (commManager == null) {
return null;
}
}
@Override
- public PowermaxState handleMessage(PowermaxCommManager commManager) {
- super.handleMessage(commManager);
-
+ protected PowermaxState handleMessageInternal(PowermaxCommManager commManager) {
if (commManager == null) {
return null;
}