/**
* Copyright (c) 2010-2016 by the respective copyright holders.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.openhab.binding.powermax.internal.state;
import java.util.HashMap;
/**
* A class to store the state of the alarm system
*
* @author Laurent Garnier
* @since 1.9.0
*/
public class PowerMaxState {
private static HashMap<String, Boolean> armedTable = null;
private static HashMap<String, String> armModeTable = null;
private Boolean powerlinkMode;
private Boolean downloadMode;
private PowerMaxZoneState[] zones;
private Boolean[] pgmX10DevicesStatus;
private Boolean ready;
private Boolean bypass;
private Boolean alarmActive;
private Boolean trouble;
private Boolean alertInMemory;
private String statusStr;
private String armMode;
private Boolean downloadSetupRequired;
private Long lastKeepAlive;
private byte[] updateSettings;
private String panelStatus;
private String alarmType;
private String troubleType;
private String[] eventLog;
/**
* Constructor (default values)
*/
public PowerMaxState() {
PowerMaxPanelSettings settings = PowerMaxPanelSettings.getThePanelSettings();
powerlinkMode = null;
downloadMode = null;
zones = new PowerMaxZoneState[settings.getNbZones()];
for (int i = 0; i < settings.getNbZones(); i++) {
zones[i] = new PowerMaxZoneState();
}
pgmX10DevicesStatus = new Boolean[settings.getNbPGMX10Devices()];
for (int i = 0; i < settings.getNbPGMX10Devices(); i++) {
pgmX10DevicesStatus[i] = null;
}
ready = null;
bypass = null;
alarmActive = null;
trouble = null;
alertInMemory = null;
statusStr = null;
armMode = null;
downloadSetupRequired = null;
lastKeepAlive = null;
updateSettings = null;
panelStatus = null;
alarmType = null;
troubleType = null;
eventLog = null;
}
/**
* Get the current mode (standard or Powerlink)
*
* @return true when the current mode is Powerlink; false when standard
*/
public Boolean isPowerlinkMode() {
return powerlinkMode;
}
/**
* Set the current mode (standard or Powerlink)
*
* @param powerlinkMode
* true for Powerlink or false for standard
*/
public void setPowerlinkMode(Boolean powerlinkMode) {
this.powerlinkMode = powerlinkMode;
}
/**
* Get whether or not the setup is being downloaded
*
* @return true when downloading the setup
*/
public Boolean isDownloadMode() {
return downloadMode;
}
/**
* Set whether or not the setup is being downloaded
*
* @param downloadMode
* true when downloading the setup
*/
public void setDownloadMode(Boolean downloadMode) {
this.downloadMode = downloadMode;
}
/**
* Get whether or not the zone sensor is tripped
*
* @param zone
* the index of the zone (first zone is index 1)
*
* @return true when the zone sensor is tripped
*/
public Boolean isSensorTripped(int zone) {
return ((zone < 1) || (zone > zones.length)) ? null : zones[zone - 1].isTripped();
}
/**
* Set whether or not the zone sensor is tripped
*
* @param zone
* the index of the zone (first zone is index 1)
* @param tripped
* true if tripped
*/
public void setSensorTripped(int zone, Boolean tripped) {
if ((zone >= 1) && (zone <= zones.length)) {
this.zones[zone - 1].setTripped(tripped);
}
}
/**
* Get the timestamp when the zone sensor was last tripped
*
* @param zone
* the index of the zone (first zone is index 1)
*
* @return the timestamp
*/
public Long getSensorLastTripped(int zone) {
return ((zone < 1) || (zone > zones.length)) ? null : zones[zone - 1].getLastTripped();
}
/**
* Set the timestamp when the zone sensor was last tripped
*
* @param zone
* the index of the zone (first zone is index 1)
* @param lastTripped
* the timestamp
*/
public void setSensorLastTripped(int zone, Long lastTripped) {
if ((zone >= 1) && (zone <= zones.length)) {
this.zones[zone - 1].setLastTripped(lastTripped);
}
}
/**
* Get whether or not the battery of the zone sensor is low
*
* @param zone
* the index of the zone (first zone is index 1)
*
* @return true when the battery is low
*/
public Boolean isSensorLowBattery(int zone) {
return ((zone < 1) || (zone > zones.length)) ? null : zones[zone - 1].isLowBattery();
}
/**
* Set whether or not the battery of the zone sensor is low
*
* @param zone
* the index of the zone (first zone is index 1)
* @param lowBattery
* true if battery is low
*/
public void setSensorLowBattery(int zone, Boolean lowBattery) {
if ((zone >= 1) && (zone <= zones.length)) {
this.zones[zone - 1].setLowBattery(lowBattery);
}
}
/**
* Get whether or not the zone sensor is bypassed
*
* @param zone
* the index of the zone (first zone is index 1)
*
* @return true if bypassed
*/
public Boolean isSensorBypassed(int zone) {
return ((zone < 1) || (zone > zones.length)) ? null : zones[zone - 1].isBypassed();
}
/**
* Set whether or not the zone sensor is bypassed
*
* @param zone
* the index of the zone (first zone is index 1)
* @param bypassed
* true if bypassed
*/
public void setSensorBypassed(int zone, Boolean bypassed) {
if ((zone >= 1) && (zone <= zones.length)) {
this.zones[zone - 1].setBypassed(bypassed);
}
}
/**
* Get whether or not the zone sensor is armed
*
* @param zone
* the index of the zone (first zone is index 1)
*
* @return true if armed
*/
public Boolean isSensorArmed(int zone) {
return ((zone < 1) || (zone > zones.length)) ? null : zones[zone - 1].isArmed();
}
/**
* Set whether or not the zone sensor is armed
*
* @param zone
* the index of the zone (first zone is index 1)
* @param armed
* true if armed
*/
public void setSensorArmed(int zone, Boolean armed) {
if ((zone >= 1) && (zone <= zones.length)) {
this.zones[zone - 1].setArmed(armed);
}
}
/**
* Get the status of a PGM or X10 device
*
* @param device
* the index of the PGM/X10 device (0 s for PGM; for X10 device is index 1)
*
* @return the status (true or false)
*/
public Boolean getPGMX10DeviceStatus(int device) {
return ((device < 0) || (device >= pgmX10DevicesStatus.length)) ? null : pgmX10DevicesStatus[device];
}
/**
* Set the status of a PGM or X10 device
*
* @param device
* the index of the PGM/X10 device (0 s for PGM; for X10 device is index 1)
* @param status
* true or false
*/
public void setPGMX10DeviceStatus(int device, Boolean status) {
if ((device >= 0) && (device < pgmX10DevicesStatus.length)) {
this.pgmX10DevicesStatus[device] = status;
}
}
/**
* Get whether or not the panel is ready
*
* @return true if ready
*/
public Boolean isReady() {
return ready;
}
/**
* Set whether or not the panel is ready
*
* @param ready
* true if ready
*/
public void setReady(Boolean ready) {
this.ready = ready;
}
/**
* Get whether or not at least one zone is bypassed
*
* @return true if at least one zone is bypassed
*/
public Boolean isBypass() {
return bypass;
}
/**
* Set whether or not at least one zone is bypassed
*
* @param bypass
* true if at least one zone is bypassed
*/
public void setBypass(Boolean bypass) {
this.bypass = bypass;
}
/**
* Get whether or not the alarm is active
*
* @return true if active
*/
public Boolean isAlarmActive() {
return alarmActive;
}
/**
* Set whether or not the alarm is active
*
* @param alarmActive
* true if the alarm is active
*/
public void setAlarmActive(Boolean alarmActive) {
this.alarmActive = alarmActive;
}
/**
* Get whether or not the panel is identifying a trouble
*
* @return true if the panel is identifying a trouble
*/
public Boolean isTrouble() {
return trouble;
}
/**
* Set whether or not the panel is identifying a trouble
*
* @param trouble
* the zone name
*/
public void setTrouble(Boolean trouble) {
this.trouble = trouble;
}
/**
* Get whether or not the panel has saved an alert in memory
*
* @return true if the panel has saved an alert in memory
*/
public Boolean isAlertInMemory() {
return alertInMemory;
}
/**
* Set whether or not the panel has saved an alert in memory
*
* @param alertInMemory
* true if an alert is saved in memory
*/
public void setAlertInMemory(Boolean alertInMemory) {
this.alertInMemory = alertInMemory;
}
/**
* Get the partition status
*
* @return the status as a short string
*/
public String getStatusStr() {
return statusStr;
}
/**
* Set the partition status
*
* @param statusStr
* the status as a short string
*/
public void setStatusStr(String statusStr) {
this.statusStr = statusStr;
}
/**
* Get the arming name
*
* @return the arming mode
*/
public String getArmMode() {
return armMode;
}
/**
* Set the arming name
*
* @param armMode
* the arming name
*/
public void setArmMode(String armMode) {
this.armMode = armMode;
}
/**
* Get whether or not the setup downloading is required
*
* @return true when downloading the setup is required
*/
public Boolean isDownloadSetupRequired() {
return downloadSetupRequired;
}
/**
* Set whether or not the setup downloading is required
*
* @param downloadSetupRequired
* true when downloading setup is required
*/
public void setDownloadSetupRequired(Boolean downloadSetupRequired) {
this.downloadSetupRequired = downloadSetupRequired;
}
/**
* Get the timestamp of the last received "keep alive" message
*
* @return the timestamp
*/
public Long getLastKeepAlive() {
return lastKeepAlive;
}
/**
* Set the timestamp of the last received "keep alive" message
*
* @param lastKeepAlive
* the timestamp
*/
public void setLastKeepAlive(Long lastKeepAlive) {
this.lastKeepAlive = lastKeepAlive;
}
/**
* Get the raw buffer containing all the settings
*
* @return the raw buffer as a table of bytes
*/
public byte[] getUpdateSettings() {
return updateSettings;
}
/**
* Set the raw buffer containing all the settings
*
* @param updateSettings
* the raw buffer as a table of bytes
*/
public void setUpdateSettings(byte[] updateSettings) {
this.updateSettings = updateSettings;
}
/**
* Get the panel status
*
* @return the panel status
*/
public String getPanelStatus() {
return panelStatus;
}
/**
* Set the panel status
*
* @param panelStatus
* the status as a short string
*/
public void setPanelStatus(String panelStatus) {
this.panelStatus = panelStatus;
}
/**
* Get the kind of the current alarm identified by the panel
*
* @return the kind of the current alarm; null if no alarm
*/
public String getAlarmType() {
return alarmType;
}
/**
* Set the kind of the current alarm identified by the panel
*
* @param alarmType
* the kind of alarm (set it to null if no alarm)
*/
public void setAlarmType(String alarmType) {
this.alarmType = alarmType;
}
/**
* Get the kind of the current trouble identified by the panel
*
* @return the kind of the current trouble; null if no trouble
*/
public String getTroubleType() {
return troubleType;
}
/**
* Set the kind of the current trouble identified by the panel
*
* @param troubleType
* the kind of trouble (set it to null if no trouble)
*/
public void setTroubleType(String troubleType) {
this.troubleType = troubleType;
}
/**
* Get the number of entries in the event log
*
* @return the number of entries
*/
public int getEventLogSize() {
return (eventLog == null) ? 0 : eventLog.length;
}
/**
* Set the number of entries in the event log
*
* @param size
* the number of entries
*/
public void setEventLogSize(int size) {
eventLog = new String[size];
for (int i = 0; i < eventLog.length; i++) {
eventLog[i] = null;
}
}
/**
* Get one entry from the event logs
*
* @param index
* the entry index (1 for the most recent entry)
*
* @return the entry value (event)
*/
public String getEventLog(int index) {
return ((index < 1) || (index > getEventLogSize())) ? null : eventLog[index - 1];
}
/**
* Set one entry from the event logs
*
* @param index
* the entry index (1 for the most recent entry)
* @param event
* the entry value (event)
*/
public void setEventLog(int index, String event) {
if ((index >= 1) && (index <= getEventLogSize())) {
this.eventLog[index - 1] = event;
}
}
/**
* Get the panel mode
*
* @return either Download or Powerlink or Standard
*/
public String getPanelMode() {
String mode = null;
if ((downloadMode != null) && downloadMode.equals(Boolean.TRUE)) {
mode = "Download";
} else if ((powerlinkMode != null) && powerlinkMode.equals(Boolean.TRUE)) {
mode = "Powerlink";
} else if ((powerlinkMode != null) && powerlinkMode.equals(Boolean.FALSE)) {
mode = "Standard";
}
return mode;
}
/**
* Get whether or not the current arming mode is considered as armed
*
* @return true or false
*/
public Boolean isArmed() {
return isArmed(getArmMode());
}
/**
* Get whether or not an arming mode is considered as armed
*
* @param armMode
* the arming mode
*
* @return true or false; null if mode is unexpected
*/
private static Boolean isArmed(String armMode) {
if (armedTable == null) {
armedTable = new HashMap<String, Boolean>();
armedTable.put("Disarmed", false);
armedTable.put("Home Exit Delay", false);
armedTable.put("Away Exit Delay", false);
armedTable.put("Entry Delay", true);
armedTable.put("Armed Home", true);
armedTable.put("Armed Away", true);
armedTable.put("User Test", false);
armedTable.put("Downloading", false);
armedTable.put("Programming", false);
armedTable.put("Installer", false);
armedTable.put("Home Bypass", true);
armedTable.put("Away Bypass", true);
armedTable.put("Ready", false);
armedTable.put("Not Ready", false);
armedTable.put("Disarmed Instant", false);
armedTable.put("Home Instant Exit Delay", false);
armedTable.put("Away Instant Exit Delay", false);
armedTable.put("Entry Delay Instant", true);
armedTable.put("Armed Home Instant", true);
armedTable.put("Armed Away Instant", true);
}
Boolean result = null;
if (armMode != null) {
result = armedTable.get(armMode);
if (result == null) {
result = Boolean.FALSE;
}
}
return result;
}
/**
* Get the short description associated to the current arming mode
*
* @return the short description
*/
public String getShortArmMode() {
return getShortArmMode(getArmMode());
}
/**
* Get the short description associated to an arming mode
*
* @param armMode
* the arming mode
*
* @return the short description or null if mode is unexpected
*/
private static String getShortArmMode(String armMode) {
if (armModeTable == null) {
armModeTable = new HashMap<String, String>();
armModeTable.put("Disarmed", "Disarmed");
armModeTable.put("Home Exit Delay", "ExitDelay");
armModeTable.put("Away Exit Delay", "Disarmed");
armModeTable.put("Entry Delay", "EntryDelay");
armModeTable.put("Armed Home", "Stay");
armModeTable.put("Armed Away", "Armed");
armModeTable.put("User Test", "UserTest");
armModeTable.put("Downloading", "NotReady");
armModeTable.put("Programming", "NotReady");
armModeTable.put("Installer", "NotReady");
armModeTable.put("Home Bypass", "Force");
armModeTable.put("Away Bypass", "Force");
armModeTable.put("Ready", "Ready");
armModeTable.put("Not Ready", "NotReady");
armModeTable.put("Disarmed Instant", "Disarmed");
armModeTable.put("Home Instant Exit Delay", "ExitDelay");
armModeTable.put("Away Instant Exit Delay", "ExitDelay");
armModeTable.put("Entry Delay Instant", "EntryDelay");
armModeTable.put("Armed Home Instant", "StayInstant");
armModeTable.put("Armed Away Instant", "ArmedInstant");
}
String result = null;
if (armMode != null) {
result = armModeTable.get(armMode);
if (result == null) {
result = armMode;
}
}
return result;
}
/**
* Keep only data that are different from another state and reset all others data to undefined
*
* @param otherState
* the other state
*/
public void keepOnlyDifferencesWith(PowerMaxState otherState) {
if ((powerlinkMode != null) && powerlinkMode.equals(otherState.isPowerlinkMode())) {
powerlinkMode = null;
}
if ((downloadMode != null) && downloadMode.equals(otherState.isDownloadMode())) {
downloadMode = null;
}
for (int i = 1; i <= zones.length; i++) {
if ((isSensorTripped(i) != null) && isSensorTripped(i).equals(otherState.isSensorTripped(i))) {
setSensorTripped(i, null);
}
if ((getSensorLastTripped(i) != null)
&& getSensorLastTripped(i).equals(otherState.getSensorLastTripped(i))) {
setSensorLastTripped(i, null);
}
if ((isSensorLowBattery(i) != null) && isSensorLowBattery(i).equals(otherState.isSensorLowBattery(i))) {
setSensorLowBattery(i, null);
}
if ((isSensorBypassed(i) != null) && isSensorBypassed(i).equals(otherState.isSensorBypassed(i))) {
setSensorBypassed(i, null);
}
if ((isSensorArmed(i) != null) && isSensorArmed(i).equals(otherState.isSensorArmed(i))) {
setSensorArmed(i, null);
}
}
for (int i = 0; i < pgmX10DevicesStatus.length; i++) {
if ((getPGMX10DeviceStatus(i) != null)
&& getPGMX10DeviceStatus(i).equals(otherState.getPGMX10DeviceStatus(i))) {
setPGMX10DeviceStatus(i, null);
}
}
if ((ready != null) && ready.equals(otherState.isReady())) {
ready = null;
}
if ((bypass != null) && bypass.equals(otherState.isBypass())) {
bypass = null;
}
if ((alarmActive != null) && alarmActive.equals(otherState.isAlarmActive())) {
alarmActive = null;
}
if ((trouble != null) && trouble.equals(otherState.isTrouble())) {
trouble = null;
}
if ((alertInMemory != null) && alertInMemory.equals(otherState.isAlertInMemory())) {
alertInMemory = null;
}
if ((statusStr != null) && statusStr.equals(otherState.getStatusStr())) {
statusStr = null;
}
if ((armMode != null) && armMode.equals(otherState.getArmMode())) {
armMode = null;
}
if ((lastKeepAlive != null) && lastKeepAlive.equals(otherState.getLastKeepAlive())) {
lastKeepAlive = null;
}
if ((panelStatus != null) && panelStatus.equals(otherState.getPanelStatus())) {
panelStatus = null;
}
if ((alarmType != null) && alarmType.equals(otherState.getAlarmType())) {
alarmType = null;
}
if ((troubleType != null) && troubleType.equals(otherState.getTroubleType())) {
troubleType = null;
}
}
/**
* Update (override) the current state data from another state, ignoring in this other state
* the undefined data
*
* @param update
* the other state to consider for the update
*/
public void merge(PowerMaxState update) {
if (update.isPowerlinkMode() != null) {
powerlinkMode = update.isPowerlinkMode();
}
if (update.isDownloadMode() != null) {
downloadMode = update.isDownloadMode();
}
for (int i = 1; i <= zones.length; i++) {
if (update.isSensorTripped(i) != null) {
setSensorTripped(i, update.isSensorTripped(i));
}
if (update.getSensorLastTripped(i) != null) {
setSensorLastTripped(i, update.getSensorLastTripped(i));
}
if (update.isSensorLowBattery(i) != null) {
setSensorLowBattery(i, update.isSensorLowBattery(i));
}
if (update.isSensorBypassed(i) != null) {
setSensorBypassed(i, update.isSensorBypassed(i));
}
if (update.isSensorArmed(i) != null) {
setSensorArmed(i, update.isSensorArmed(i));
}
}
for (int i = 0; i < pgmX10DevicesStatus.length; i++) {
if (update.getPGMX10DeviceStatus(i) != null) {
setPGMX10DeviceStatus(i, update.getPGMX10DeviceStatus(i));
}
}
if (update.isReady() != null) {
ready = update.isReady();
}
if (update.isBypass() != null) {
bypass = update.isBypass();
}
if (update.isAlarmActive() != null) {
alarmActive = update.isAlarmActive();
}
if (update.isTrouble() != null) {
trouble = update.isTrouble();
}
if (update.isAlertInMemory() != null) {
alertInMemory = update.isAlertInMemory();
}
if (update.getStatusStr() != null) {
statusStr = update.getStatusStr();
}
if (update.getArmMode() != null) {
armMode = update.getArmMode();
}
if (update.getLastKeepAlive() != null) {
lastKeepAlive = update.getLastKeepAlive();
}
if (update.getPanelStatus() != null) {
panelStatus = update.getPanelStatus();
}
if (update.getAlarmType() != null) {
alarmType = update.getAlarmType();
}
if (update.getTroubleType() != null) {
troubleType = update.getTroubleType();
}
if (update.getEventLogSize() > getEventLogSize()) {
setEventLogSize(update.getEventLogSize());
}
for (int i = 1; i <= getEventLogSize(); i++) {
if (update.getEventLog(i) != null) {
setEventLog(i, update.getEventLog(i));
}
}
}
@Override
public String toString() {
String str = "";
if (powerlinkMode != null) {
str += "\n - powerlink mode = " + (powerlinkMode ? "yes" : "no");
}
if (downloadMode != null) {
str += "\n - download mode = " + (downloadMode ? "yes" : "no");
}
for (int i = 1; i <= zones.length; i++) {
if (isSensorTripped(i) != null) {
str += String.format("\n - sensor zone %d %s", i, isSensorTripped(i) ? "tripped" : "untripped");
}
if (getSensorLastTripped(i) != null) {
str += String.format("\n - sensor zone %d last trip %d", i, getSensorLastTripped(i));
}
if (isSensorLowBattery(i) != null) {
str += String.format("\n - sensor zone %d %s", i, isSensorLowBattery(i) ? "low battery" : "battery ok");
}
if (isSensorBypassed(i) != null) {
str += String.format("\n - sensor zone %d %sbypassed", i, isSensorBypassed(i) ? "" : "not ");
}
if (isSensorArmed(i) != null) {
str += String.format("\n - sensor zone %d %s", i, isSensorArmed(i) ? "armed" : "disarmed");
}
}
for (int i = 0; i < pgmX10DevicesStatus.length; i++) {
if (getPGMX10DeviceStatus(i) != null) {
str += String.format("\n - %s status = %s", (i == 0) ? "PGM device" : String.format("X10 device %d", i),
getPGMX10DeviceStatus(i) ? "ON" : "OFF");
}
}
if (ready != null) {
str += "\n - ready = " + (ready ? "yes" : "no");
}
if (bypass != null) {
str += "\n - bypass = " + (bypass ? "yes" : "no");
}
if (alarmActive != null) {
str += "\n - alarm active = " + (alarmActive ? "yes" : "no");
}
if (trouble != null) {
str += "\n - trouble = " + (trouble ? "yes" : "no");
}
if (alertInMemory != null) {
str += "\n - alert in memory = " + (alertInMemory ? "yes" : "no");
}
if (statusStr != null) {
str += "\n - status = " + statusStr;
}
if (armMode != null) {
str += "\n - arm mode = " + armMode;
}
if (lastKeepAlive != null) {
str += "\n - last keep alive = " + lastKeepAlive;
}
if (panelStatus != null) {
str += "\n - panel status = " + panelStatus;
}
if (alarmType != null) {
str += "\n - alarm type = " + alarmType;
}
if (troubleType != null) {
str += "\n - trouble type = " + troubleType;
}
for (int i = 1; i <= getEventLogSize(); i++) {
if (getEventLog(i) != null) {
str += "\n - event log " + i + " = " + getEventLog(i);
}
}
return str;
}
}