ThingTypeUID thingTypeUID = thing.getThingTypeUID();
if (SUPPORTED_BRIDGE_TYPES_UIDS.contains(thingTypeUID)) {
- return new PowermaxBridgeHandler((Bridge) thing, serialPortManager);
+ return new PowermaxBridgeHandler((Bridge) thing, serialPortManager, timeZoneProvider);
} else if (SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID)) {
- return new PowermaxThingHandler(thing, timeZoneProvider);
+ return new PowermaxThingHandler(thing);
}
return null;
private final String serialPortName;
private final int baudRate;
+ private final SerialPortManager serialPortManager;
private SerialPort serialPort;
- private SerialPortManager serialPortManager;
/**
* Constructor
private static final String INFO_SETUP = "info_setup";
private static final String DOWNLOAD_SETUP = "download_setup";
+ private static final String BRIDGE_STATE = "bridge_state";
private ThingRegistry thingRegistry;
handler.downloadSetup();
console.println("Command '" + args[1] + "' handled.");
break;
+ case BRIDGE_STATE:
+ for (String line : handler.getCurrentState().toString().split("\n")) {
+ console.println(line);
+ }
+ break;
default:
console.println("Unknown Powermax sub command '" + args[1] + "'");
printUsage(console);
@Override
public List<String> getUsages() {
return Arrays.asList(new String[] { buildCommandUsage("<bridgeUID> " + INFO_SETUP, "information on setup"),
- buildCommandUsage("<bridgeUID> " + DOWNLOAD_SETUP, "download setup") });
+ buildCommandUsage("<bridgeUID> " + DOWNLOAD_SETUP, "download setup"),
+ buildCommandUsage("<bridgeUID> " + BRIDGE_STATE, "show current state") });
}
@Reference
import org.openhab.binding.powermax.internal.state.PowermaxPanelSettingsListener;
import org.openhab.binding.powermax.internal.state.PowermaxPanelType;
import org.openhab.binding.powermax.internal.state.PowermaxState;
+import org.openhab.binding.powermax.internal.state.PowermaxStateContainer.Value;
import org.openhab.binding.powermax.internal.state.PowermaxStateEvent;
import org.openhab.binding.powermax.internal.state.PowermaxStateEventListener;
+import org.openhab.core.i18n.TimeZoneProvider;
import org.openhab.core.io.transport.serial.SerialPortManager;
import org.openhab.core.library.types.OnOffType;
import org.openhab.core.library.types.StringType;
public class PowermaxBridgeHandler extends BaseBridgeHandler implements PowermaxStateEventListener {
private final Logger logger = LoggerFactory.getLogger(PowermaxBridgeHandler.class);
+ private final SerialPortManager serialPortManager;
+ private final TimeZoneProvider timeZoneProvider;
private static final long ONE_MINUTE = TimeUnit.MINUTES.toMillis(1);
private PowermaxCommManager commManager;
private int remainingDownloadAttempts;
- private SerialPortManager serialPortManager;
- public PowermaxBridgeHandler(Bridge thing, SerialPortManager serialPortManager) {
+ public PowermaxBridgeHandler(Bridge thing, SerialPortManager serialPortManager, TimeZoneProvider timeZoneProvider) {
super(thing);
this.serialPortManager = serialPortManager;
+ this.timeZoneProvider = timeZoneProvider;
}
@Override
PowermaxArmMode.ARMED_NIGHT_INSTANT.setAllowedCommand(allowArming);
commManager = new PowermaxCommManager(config.serialPort, panelType, forceStandardMode, autoSyncTime,
- serialPortManager, threadName);
+ serialPortManager, threadName, timeZoneProvider);
} else {
if (config.serialPort != null && config.serialPort.trim().startsWith("rfc2217")) {
errorMsg = "Please use the IP Connection thing type for a serial over IP connection.";
PowermaxArmMode.ARMED_NIGHT_INSTANT.setAllowedCommand(allowArming);
commManager = new PowermaxCommManager(config.ip, config.tcpPort, panelType, forceStandardMode, autoSyncTime,
- threadName);
+ threadName, timeZoneProvider);
} else {
errorMsg = "ip and port settings must be defined in thing configuration";
}
PowermaxPanelSettings panelSettings = getPanelSettings();
for (int i = 1; i <= panelSettings.getNbZones(); i++) {
if (panelSettings.getZoneSettings(i) != null && panelSettings.getZoneSettings(i).isMotionSensor()
- && currentState.isLastTripBeforeTime(i, now - motionOffDelay)) {
+ && currentState.getZone(i).isLastTripBeforeTime(now - motionOffDelay)) {
update = true;
- updateState.setSensorTripped(i, false);
+ updateState.getZone(i).tripped.setValue(false);
}
}
if (update) {
*/
private void checkKeepAlive() {
long now = System.currentTimeMillis();
- if (Boolean.TRUE.equals(currentState.isPowerlinkMode()) && (currentState.getLastKeepAlive() != null)
- && ((now - currentState.getLastKeepAlive()) > ONE_MINUTE)) {
+ if (Boolean.TRUE.equals(currentState.powerlinkMode.getValue())
+ && (currentState.lastKeepAlive.getValue() != null)
+ && ((now - currentState.lastKeepAlive.getValue()) > ONE_MINUTE)) {
// Let Powermax know we are alive
commManager.sendRestoreMessage();
- currentState.setLastKeepAlive(now);
+ currentState.lastKeepAlive.setValue(now);
}
}
if (openConnection()) {
updateStatus(ThingStatus.ONLINE);
if (forceStandardMode) {
- currentState.setPowerlinkMode(false);
+ currentState.powerlinkMode.setValue(false);
updateChannelsFromAlarmState(MODE, currentState);
processPanelSettings();
} else {
logger.debug("Powermax alarm binding not connected. Arm command is ignored.");
} else {
commManager.requestArmMode(armMode,
- currentState.isPowerlinkMode() ? getPanelSettings().getFirstPinCode() : pinCode);
+ Boolean.TRUE.equals(currentState.powerlinkMode.getValue()) ? getPanelSettings().getFirstPinCode()
+ : pinCode);
}
}
public void zoneBypassed(byte zoneNr, boolean bypassed) {
if (!isConnected()) {
logger.debug("Powermax alarm binding not connected. Zone bypass command is ignored.");
- } else if (!Boolean.TRUE.equals(currentState.isPowerlinkMode())) {
+ } else if (!Boolean.TRUE.equals(currentState.powerlinkMode.getValue())) {
logger.debug("Powermax alarm binding: Bypass option only supported in Powerlink mode");
} else if (!getPanelSettings().isBypassEnabled()) {
logger.debug("Powermax alarm binding: Bypass option not enabled in panel settings");
if (!isConnected()) {
logger.debug("Powermax alarm binding not connected. Event logs command is ignored.");
} else {
- commManager
- .requestEventLog(currentState.isPowerlinkMode() ? getPanelSettings().getFirstPinCode() : pinCode);
+ commManager.requestEventLog(
+ Boolean.TRUE.equals(currentState.powerlinkMode.getValue()) ? getPanelSettings().getFirstPinCode()
+ : pinCode);
}
}
public void downloadSetup() {
if (!isConnected()) {
logger.debug("Powermax alarm binding not connected. Download setup command is ignored.");
- } else if (!Boolean.TRUE.equals(currentState.isPowerlinkMode())) {
+ } else if (!Boolean.TRUE.equals(currentState.powerlinkMode.getValue())) {
logger.debug("Powermax alarm binding: download setup only supported in Powerlink mode");
} else if (commManager.isDownloadRunning()) {
logger.debug("Powermax alarm binding: download setup not started as one is in progress");
} else {
commManager.startDownload();
- if (currentState.getLastKeepAlive() != null) {
- currentState.setLastKeepAlive(System.currentTimeMillis());
+ if (currentState.lastKeepAlive.getValue() != null) {
+ currentState.lastKeepAlive.setValue(System.currentTimeMillis());
}
}
}
PowermaxStateEvent stateEvent = (PowermaxStateEvent) event;
PowermaxState updateState = stateEvent.getState();
- if (Boolean.TRUE.equals(currentState.isPowerlinkMode())
- && Boolean.TRUE.equals(updateState.isDownloadSetupRequired())) {
+ if (Boolean.TRUE.equals(currentState.powerlinkMode.getValue())
+ && Boolean.TRUE.equals(updateState.downloadSetupRequired.getValue())) {
// After Enrolling Powerlink or if a reset is required
logger.debug("Powermax alarm binding: Reset");
commManager.startDownload();
- if (currentState.getLastKeepAlive() != null) {
- currentState.setLastKeepAlive(System.currentTimeMillis());
+ updateState.downloadSetupRequired.setValue(false);
+ if (currentState.lastKeepAlive.getValue() != null) {
+ currentState.lastKeepAlive.setValue(System.currentTimeMillis());
}
- } else if (Boolean.FALSE.equals(currentState.isPowerlinkMode()) && updateState.getLastKeepAlive() != null) {
+ } else if (Boolean.FALSE.equals(currentState.powerlinkMode.getValue())
+ && updateState.lastKeepAlive.getValue() != null) {
// Were are in standard mode but received a keep alive message
// so we switch in PowerLink mode
logger.debug("Powermax alarm binding: Switching to Powerlink mode");
commManager.startDownload();
}
- boolean doProcessSettings = (updateState.isPowerlinkMode() != null);
+ boolean doProcessSettings = (updateState.powerlinkMode.getValue() != null);
for (int i = 1; i <= getPanelSettings().getNbZones(); i++) {
- if (Boolean.TRUE.equals(updateState.isSensorArmed(i))
- && Boolean.TRUE.equals(currentState.isSensorBypassed(i))) {
- updateState.setSensorArmed(i, false);
+ if (Boolean.TRUE.equals(updateState.getZone(i).armed.getValue())
+ && Boolean.TRUE.equals(currentState.getZone(i).bypassed.getValue())) {
+ updateState.getZone(i).armed.setValue(false);
}
}
}
private void processPanelSettings() {
- if (commManager.processPanelSettings(currentState.isPowerlinkMode())) {
+ if (commManager.processPanelSettings(Boolean.TRUE.equals(currentState.powerlinkMode.getValue()))) {
for (PowermaxPanelSettingsListener listener : listeners) {
listener.onPanelSettingsUpdated(getPanelSettings());
}
remainingDownloadAttempts--;
}
updatePropertiesFromPanelSettings();
- if (currentState.isPowerlinkMode()) {
+ if (Boolean.TRUE.equals(currentState.powerlinkMode.getValue())) {
logger.debug("Powermax alarm binding: running in Powerlink mode");
commManager.sendRestoreMessage();
} else {
return;
}
- if (((channel == null) || channel.equals(MODE)) && isLinked(MODE) && (state.getPanelMode() != null)) {
- updateState(MODE, new StringType(state.getPanelMode()));
- }
- if (((channel == null) || channel.equals(SYSTEM_STATUS)) && isLinked(SYSTEM_STATUS)
- && (state.getStatusStr() != null)) {
- updateState(SYSTEM_STATUS, new StringType(state.getStatusStr()));
- }
- if (((channel == null) || channel.equals(READY)) && isLinked(READY) && (state.isReady() != null)) {
- updateState(READY, state.isReady() ? OnOffType.ON : OnOffType.OFF);
- }
- if (((channel == null) || channel.equals(WITH_ZONES_BYPASSED)) && isLinked(WITH_ZONES_BYPASSED)
- && (state.isBypass() != null)) {
- updateState(WITH_ZONES_BYPASSED, state.isBypass() ? OnOffType.ON : OnOffType.OFF);
- }
- if (((channel == null) || channel.equals(ALARM_ACTIVE)) && isLinked(ALARM_ACTIVE)
- && (state.isAlarmActive() != null)) {
- updateState(ALARM_ACTIVE, state.isAlarmActive() ? OnOffType.ON : OnOffType.OFF);
- }
- if (((channel == null) || channel.equals(TROUBLE)) && isLinked(TROUBLE) && (state.isTrouble() != null)) {
- updateState(TROUBLE, state.isTrouble() ? OnOffType.ON : OnOffType.OFF);
- }
- if (((channel == null) || channel.equals(ALERT_IN_MEMORY)) && isLinked(ALERT_IN_MEMORY)
- && (state.isAlertInMemory() != null)) {
- updateState(ALERT_IN_MEMORY, state.isAlertInMemory() ? OnOffType.ON : OnOffType.OFF);
- }
- if (((channel == null) || channel.equals(SYSTEM_ARMED)) && isLinked(SYSTEM_ARMED)
- && (state.isArmed() != null)) {
- updateState(SYSTEM_ARMED, state.isArmed() ? OnOffType.ON : OnOffType.OFF);
- }
- if (((channel == null) || channel.equals(ARM_MODE)) && isLinked(ARM_MODE)
- && (state.getShortArmMode() != null)) {
- updateState(ARM_MODE, new StringType(state.getShortArmMode()));
- }
- if (((channel == null) || channel.equals(PGM_STATUS)) && isLinked(PGM_STATUS)
- && (state.getPGMX10DeviceStatus(0) != null)) {
- updateState(PGM_STATUS, state.getPGMX10DeviceStatus(0) ? OnOffType.ON : OnOffType.OFF);
+ for (Value<?> value : state.getValues()) {
+ String vChannel = value.getChannel();
+
+ if (((channel == null) || channel.equals(vChannel)) && (vChannel != null) && isLinked(vChannel)
+ && (value.getValue() != null)) {
+ updateState(vChannel, value.getState());
+ }
}
+
for (int i = 1; i <= NB_EVENT_LOG; i++) {
String channel2 = String.format(EVENT_LOG, i);
if (((channel == null) || channel.equals(channel2)) && isLinked(channel2)
PowermaxThingHandler handler = (PowermaxThingHandler) thing.getHandler();
if (handler != null) {
if (thing.getThingTypeUID().equals(THING_TYPE_ZONE)) {
- for (String channelId : List.of(TRIPPED, LAST_TRIP, BYPASSED, ARMED, LOCKED, LOW_BATTERY)) {
- if ((channel == null) || channel.equals(channelId)) {
+
+ // All of the zone state objects will have the same list of values.
+ // The use of getZone(1) here is just to get any PowermaxZoneState
+ // and use it to get the list of zone channels.
+
+ for (Value<?> value : state.getZone(1).getValues()) {
+ String channelId = value.getChannel();
+ if ((channelId != null) && ((channel == null) || channel.equals(channelId))) {
handler.updateChannelFromAlarmState(channelId, state);
}
}
import static org.openhab.binding.powermax.internal.PowermaxBindingConstants.*;
-import java.time.Instant;
-import java.time.ZonedDateTime;
-
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.powermax.internal.config.PowermaxX10Configuration;
import org.openhab.binding.powermax.internal.config.PowermaxZoneConfiguration;
import org.openhab.binding.powermax.internal.state.PowermaxPanelSettings;
import org.openhab.binding.powermax.internal.state.PowermaxPanelSettingsListener;
import org.openhab.binding.powermax.internal.state.PowermaxState;
+import org.openhab.binding.powermax.internal.state.PowermaxStateContainer.Value;
import org.openhab.binding.powermax.internal.state.PowermaxX10Settings;
import org.openhab.binding.powermax.internal.state.PowermaxZoneSettings;
-import org.openhab.core.i18n.TimeZoneProvider;
-import org.openhab.core.library.types.DateTimeType;
import org.openhab.core.library.types.OnOffType;
-import org.openhab.core.library.types.OpenClosedType;
import org.openhab.core.thing.Bridge;
import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing;
private static final int X10_NR_MIN = 1;
private static final int X10_NR_MAX = 16;
- private final TimeZoneProvider timeZoneProvider;
-
private PowermaxBridgeHandler bridgeHandler;
- public PowermaxThingHandler(Thing thing, TimeZoneProvider timeZoneProvider) {
+ public PowermaxThingHandler(Thing thing) {
super(thing);
- this.timeZoneProvider = timeZoneProvider;
}
@Override
if (getThing().getThingTypeUID().equals(THING_TYPE_ZONE)) {
int num = getConfigAs(PowermaxZoneConfiguration.class).zoneNumber.intValue();
- if (channel.equals(TRIPPED) && (state.isSensorTripped(num) != null)) {
- updateState(TRIPPED, state.isSensorTripped(num) ? OpenClosedType.OPEN : OpenClosedType.CLOSED);
- } else if (channel.equals(LAST_TRIP) && (state.getSensorLastTripped(num) != null)) {
- ZonedDateTime zoned = ZonedDateTime.ofInstant(Instant.ofEpochMilli(state.getSensorLastTripped(num)),
- timeZoneProvider.getTimeZone());
- updateState(LAST_TRIP, new DateTimeType(zoned));
- } else if (channel.equals(BYPASSED) && (state.isSensorBypassed(num) != null)) {
- updateState(BYPASSED, state.isSensorBypassed(num) ? OnOffType.ON : OnOffType.OFF);
- } else if (channel.equals(ARMED) && (state.isSensorArmed(num) != null)) {
- updateState(ARMED, state.isSensorArmed(num) ? OnOffType.ON : OnOffType.OFF);
- } else if (channel.equals(LOCKED) && (state.isSensorArmed(num) != null)) {
- updateState(LOCKED, state.isSensorArmed(num) ? OpenClosedType.CLOSED : OpenClosedType.OPEN);
- } else if (channel.equals(LOW_BATTERY) && (state.isSensorLowBattery(num) != null)) {
- updateState(LOW_BATTERY, state.isSensorLowBattery(num) ? OnOffType.ON : OnOffType.OFF);
+
+ for (Value<?> value : state.getZone(num).getValues()) {
+ String v_channel = value.getChannel();
+
+ if (channel.equals(v_channel) && (value.getValue() != null)) {
+ updateState(v_channel, value.getState());
+ }
}
} else if (getThing().getThingTypeUID().equals(THING_TYPE_X10)) {
int num = getConfigAs(PowermaxX10Configuration.class).deviceNumber.intValue();
if (commManager.getLastSendMsg().getSendType() == PowermaxSendType.EXIT) {
updatedState = commManager.createNewState();
- updatedState.setPowerlinkMode(true);
- updatedState.setDownloadMode(false);
+ updatedState.powerlinkMode.setValue(true);
+ updatedState.downloadMode.setValue(false);
}
return updatedState;
import org.openhab.binding.powermax.internal.state.PowermaxStateEvent;
import org.openhab.binding.powermax.internal.state.PowermaxStateEventListener;
import org.openhab.core.common.ThreadPoolManager;
+import org.openhab.core.i18n.TimeZoneProvider;
import org.openhab.core.io.transport.serial.SerialPortManager;
import org.openhab.core.types.Command;
import org.openhab.core.util.HexUtils;
private boolean forceStandardMode;
private boolean autoSyncTime;
+ private final TimeZoneProvider timeZoneProvider;
private List<PowermaxStateEventListener> listeners = new ArrayList<>();
* @param threadName the prefix name of threads to be created
*/
public PowermaxCommManager(String sPort, PowermaxPanelType panelType, boolean forceStandardMode,
- boolean autoSyncTime, SerialPortManager serialPortManager, String threadName) {
+ boolean autoSyncTime, SerialPortManager serialPortManager, String threadName,
+ TimeZoneProvider timeZoneProvider) {
this.panelType = panelType;
this.forceStandardMode = forceStandardMode;
this.autoSyncTime = autoSyncTime;
+ this.timeZoneProvider = timeZoneProvider;
this.panelSettings = new PowermaxPanelSettings(panelType);
this.scheduler = ThreadPoolManager.getScheduledPool(threadName + "-sender");
String serialPort = (sPort != null && !sPort.trim().isEmpty()) ? sPort.trim() : null;
* @param threadName the prefix name of threads to be created
*/
public PowermaxCommManager(String ip, int port, PowermaxPanelType panelType, boolean forceStandardMode,
- boolean autoSyncTime, String threadName) {
+ boolean autoSyncTime, String threadName, TimeZoneProvider timeZoneProvider) {
this.panelType = panelType;
this.forceStandardMode = forceStandardMode;
this.autoSyncTime = autoSyncTime;
+ this.timeZoneProvider = timeZoneProvider;
this.panelSettings = new PowermaxPanelSettings(panelType);
this.scheduler = ThreadPoolManager.getScheduledPool(threadName + "-sender");
String ipAddress = (ip != null && !ip.trim().isEmpty()) ? ip.trim() : null;
* @return a new instance of PowermaxState
*/
public PowermaxState createNewState() {
- return new PowermaxState(panelSettings);
+ return new PowermaxState(panelSettings, timeZoneProvider);
}
/**
} else if (lastSendType == PowermaxSendType.DOWNLOAD) {
logger.debug("Powermax alarm binding: openHAB Powerlink not enrolled");
updatedState = commManager.createNewState();
- updatedState.setPowerlinkMode(false);
+ updatedState.powerlinkMode.setValue(false);
}
return updatedState;
debug("Panel type", panelTypeNr, panelTypeStr);
logger.debug("Reading panel settings");
- updatedState.setDownloadMode(true);
+ updatedState.downloadMode.setValue(true);
commManager.sendMessage(PowermaxSendType.DL_PANELFW);
commManager.sendMessage(PowermaxSendType.DL_SERIAL);
commManager.sendMessage(PowermaxSendType.DL_ZONESTR);
int eventType = logEvent & 0x0000007F;
String logEventStr = PowermaxMessageConstants.getSystemEventString(eventType);
String logUserStr = PowermaxMessageConstants.getZoneOrUserString(eventZone & 0x000000FF);
- updatedState.setPanelStatus(logEventStr + " (" + logUserStr + ")");
+ updatedState.panelStatus.setValue(logEventStr + " (" + logUserStr + ")");
debug("Event " + i + " zone code", eventZone, logUserStr);
debug("Event " + i + " event code", eventType, logEventStr);
} catch (IllegalArgumentException e) {
alarmStatus = "None";
}
- updatedState.setAlarmType(alarmStatus);
+ updatedState.alarmType.setValue(alarmStatus);
String troubleStatus;
try {
} catch (IllegalArgumentException e) {
troubleStatus = "None";
}
- updatedState.setTroubleType(troubleStatus);
+ updatedState.troubleType.setValue(troubleStatus);
if (eventType == 0x60) {
// System reset
- updatedState.setDownloadSetupRequired(true);
+ updatedState.downloadSetupRequired.setValue(true);
}
}
commManager.sendAck(this, (byte) 0x02);
updatedState = commManager.createNewState();
- updatedState.setLastKeepAlive(System.currentTimeMillis());
+ updatedState.lastKeepAlive.setValue(System.currentTimeMillis());
} else if (subType == 0x0A) {
byte enroll = message[4];
logger.debug("Powermax alarm binding: Enrolling Powerlink");
commManager.enrollPowerlink();
updatedState = commManager.createNewState();
- updatedState.setDownloadSetupRequired(true);
+ updatedState.downloadSetupRequired.setValue(true);
} else {
commManager.sendAck(this, (byte) 0x02);
}
String batteryStatusStr = zoneList(batteryStatusBytes);
for (int i = 1; i <= panelSettings.getNbZones(); i++) {
- updatedState.setSensorTripped(i, zoneStatus[i]);
- updatedState.setSensorLowBattery(i, batteryStatus[i]);
+ updatedState.getZone(i).tripped.setValue(zoneStatus[i]);
+ updatedState.getZone(i).lowBattery.setValue(batteryStatus[i]);
}
debug("Zone status", zoneStatusBytes, zoneStatusStr);
String zoneETypeStr = PowermaxMessageConstants.getZoneEventString(zoneEType & 0x000000FF);
if (zoneEType == 0x03) {
- updatedState.setSensorTripped(eventZone, Boolean.TRUE);
- updatedState.setSensorLastTripped(eventZone, System.currentTimeMillis());
+ updatedState.getZone(eventZone).tripped.setValue(true);
+ updatedState.getZone(eventZone).lastTripped.setValue(System.currentTimeMillis());
} else if (zoneEType == 0x04) {
- updatedState.setSensorTripped(eventZone, Boolean.FALSE);
+ updatedState.getZone(eventZone).tripped.setValue(false);
} else if (zoneEType == 0x05) {
PowermaxZoneSettings zone = panelSettings.getZoneSettings(eventZone);
if ((zone != null) && zone.getSensorType().equalsIgnoreCase("unknown")) {
zone.setSensorType("Motion");
}
- updatedState.setSensorTripped(eventZone, Boolean.TRUE);
- updatedState.setSensorLastTripped(eventZone, System.currentTimeMillis());
+ updatedState.getZone(eventZone).tripped.setValue(true);
+ updatedState.getZone(eventZone).lastTripped.setValue(System.currentTimeMillis());
}
// PGM & X10 devices
String sysStatusStr = "";
if ((sysFlags & 0x1) == 1) {
sysStatusStr = sysStatusStr + "Ready, ";
- updatedState.setReady(true);
+ updatedState.ready.setValue(true);
} else {
sysStatusStr = sysStatusStr + "Not ready, ";
- updatedState.setReady(false);
+ updatedState.ready.setValue(false);
}
if (((sysFlags >> 1) & 0x1) == 1) {
sysStatusStr = sysStatusStr + "Alert in memory, ";
- updatedState.setAlertInMemory(true);
+ updatedState.alertInMemory.setValue(true);
} else {
- updatedState.setAlertInMemory(false);
+ updatedState.alertInMemory.setValue(false);
}
if (((sysFlags >> 2) & 0x1) == 1) {
sysStatusStr = sysStatusStr + "Trouble, ";
- updatedState.setTrouble(true);
+ updatedState.trouble.setValue(true);
} else {
- updatedState.setTrouble(false);
+ updatedState.trouble.setValue(false);
}
if (((sysFlags >> 3) & 0x1) == 1) {
sysStatusStr = sysStatusStr + "Bypass on, ";
- updatedState.setBypass(true);
+ updatedState.bypass.setValue(true);
} else {
- updatedState.setBypass(false);
+ updatedState.bypass.setValue(false);
for (int i = 1; i <= panelSettings.getNbZones(); i++) {
- updatedState.setSensorBypassed(i, false);
+ updatedState.getZone(i).bypassed.setValue(false);
}
}
if (((sysFlags >> 4) & 0x1) == 1) {
}
if (((sysFlags >> 7) & 0x1) == 1) {
sysStatusStr = sysStatusStr + "Alarm event, ";
- updatedState.setAlarmActive(true);
+ updatedState.alarmActive.setValue(true);
} else {
- updatedState.setAlarmActive(false);
+ updatedState.alarmActive.setValue(false);
}
sysStatusStr = sysStatusStr.substring(0, sysStatusStr.length() - 2);
String statusStr;
} catch (IllegalArgumentException e) {
statusStr = "UNKNOWN";
}
- updatedState.setArmMode(statusStr);
- updatedState.setStatusStr(statusStr + ", " + sysStatusStr);
+ updatedState.armMode.setValue(statusStr);
+ updatedState.statusStr.setValue(statusStr + ", " + sysStatusStr);
debug("System status", sysStatus, statusStr);
debug("System flags", sysFlags, sysStatusStr);
boolean armed = (!zone.getType().equalsIgnoreCase("Non-Alarm") && (zone.isAlwaysInAlarm()
|| (mode == 0x5) || ((mode == 0x4) && !zone.getType().equalsIgnoreCase("Interior-Follow")
&& !zone.getType().equalsIgnoreCase("Interior"))));
- updatedState.setSensorArmed(i, armed);
+ updatedState.getZone(i).armed.setValue(armed);
}
}
} else if (eventType == 0x06) {
String zoneBypassStr = zoneList(zoneBypassBytes);
for (int i = 1; i <= panelSettings.getNbZones(); i++) {
- updatedState.setSensorBypassed(i, zoneBypass[i]);
+ updatedState.getZone(i).bypassed.setValue(zoneBypass[i]);
}
debug("Zone bypass", zoneBypassBytes, zoneBypassStr);
*/
package org.openhab.binding.powermax.internal.state;
+import static org.openhab.binding.powermax.internal.PowermaxBindingConstants.*;
+
import java.util.HashMap;
import java.util.Map;
+import org.openhab.core.i18n.TimeZoneProvider;
+import org.openhab.core.library.types.OnOffType;
+import org.openhab.core.library.types.StringType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
/**
* A class to store the state of the alarm system
*
* @author Laurent Garnier - Initial contribution
*/
-public class PowermaxState {
+public class PowermaxState extends PowermaxStateContainer {
+
+ private final Logger logger = LoggerFactory.getLogger(PowermaxState.class);
+
+ // For values that are mapped to channels, use a channel name constant from
+ // PowermaxBindingConstants. For values used internally but not mapped to
+ // channels, use a unique name starting with "_".
+
+ public BooleanValue powerlinkMode = new BooleanValue(this, "_powerlink_mode");
+ public BooleanValue downloadMode = new BooleanValue(this, "_download_mode");
+ public BooleanValue ready = new BooleanValue(this, READY);
+ public BooleanValue bypass = new BooleanValue(this, WITH_ZONES_BYPASSED);
+ public BooleanValue alarmActive = new BooleanValue(this, ALARM_ACTIVE);
+ public BooleanValue trouble = new BooleanValue(this, TROUBLE);
+ public BooleanValue alertInMemory = new BooleanValue(this, ALERT_IN_MEMORY);
+ public StringValue statusStr = new StringValue(this, SYSTEM_STATUS);
+ public StringValue armMode = new StringValue(this, "_arm_mode");
+ public BooleanValue downloadSetupRequired = new BooleanValue(this, "_download_setup_required");
+ public DateTimeValue lastKeepAlive = new DateTimeValue(this, "_last_keepalive");
+ public StringValue panelStatus = new StringValue(this, "_panel_status");
+ public StringValue alarmType = new StringValue(this, "_alarm_type");
+ public StringValue troubleType = new StringValue(this, "_trouble_type");
+
+ public DynamicValue<Boolean> isArmed = new DynamicValue<>(this, SYSTEM_ARMED, () -> {
+ return isArmed();
+ }, () -> {
+ return isArmed() ? OnOffType.ON : OnOffType.OFF;
+ });
+
+ public DynamicValue<String> panelMode = new DynamicValue<>(this, MODE, () -> {
+ return getPanelMode();
+ }, () -> {
+ return new StringType(getPanelMode());
+ });
+
+ public DynamicValue<String> shortArmMode = new DynamicValue<>(this, ARM_MODE, () -> {
+ return getShortArmMode();
+ }, () -> {
+ return new StringType(getShortArmMode());
+ });
+
+ public DynamicValue<Boolean> pgmStatus = new DynamicValue<>(this, PGM_STATUS, () -> {
+ return getPGMX10DeviceStatus(0);
+ }, () -> {
+ return getPGMX10DeviceStatus(0) ? OnOffType.ON : OnOffType.OFF;
+ });
- 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;
private Map<Integer, Byte> updatedZoneNames;
private Map<Integer, Integer> updatedZoneInfos;
/**
* Constructor (default values)
*/
- public PowermaxState(PowermaxPanelSettings panelSettings) {
+ public PowermaxState(PowermaxPanelSettings panelSettings, TimeZoneProvider timeZoneProvider) {
+ super(timeZoneProvider);
+
zones = new PowermaxZoneState[panelSettings.getNbZones()];
for (int i = 0; i < panelSettings.getNbZones(); i++) {
- zones[i] = new PowermaxZoneState();
+ zones[i] = new PowermaxZoneState(timeZoneProvider);
}
pgmX10DevicesStatus = new Boolean[panelSettings.getNbPGMX10Devices()];
updatedZoneNames = new HashMap<>();
}
/**
- * 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
+ * Return the PowermaxZoneState object for a given zone. If the zone number is
+ * out of range, returns a dummy PowermaxZoneState object that won't be
+ * persisted. The return value is never null, so it's safe to chain method
+ * calls.
*
* @param zone the index of the zone (first zone is index 1)
- * @param tripped true if tripped
+ * @return the zone state object (or a dummy zone state)
*/
- 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);
- }
- }
-
- /**
- * Compare the sensor last trip with a given time
- *
- * @param zone the index of the zone (first zone is index 1)
- * @param refTime the time in ms to compare with
- *
- * @return true if the sensor is tripped and last trip is older than the given time
- */
- public boolean isLastTripBeforeTime(int zone, long refTime) {
- return ((zone < 1) || (zone > zones.length)) ? false : zones[zone - 1].isLastTripBeforeTime(refTime);
- }
-
- /**
- * 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);
+ public PowermaxZoneState getZone(int zone) {
+ if ((zone < 1) || (zone > zones.length)) {
+ logger.warn("Received update for invalid zone {}", zone);
+ return new PowermaxZoneState(timeZoneProvider);
+ } else {
+ return zones[zone - 1];
}
}
}
}
- /**
- * 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 true if trouble is identified
- */
- 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
*
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
*
*/
public String getPanelMode() {
String mode = null;
- if (Boolean.TRUE.equals(downloadMode)) {
+ if (Boolean.TRUE.equals(downloadMode.getValue())) {
mode = "Download";
- } else if (Boolean.TRUE.equals(powerlinkMode)) {
+ } else if (Boolean.TRUE.equals(powerlinkMode.getValue())) {
mode = "Powerlink";
- } else if (Boolean.FALSE.equals(powerlinkMode)) {
+ } else if (Boolean.FALSE.equals(powerlinkMode.getValue())) {
mode = "Standard";
}
return mode;
* @return true or false
*/
public Boolean isArmed() {
- return isArmed(getArmMode());
+ return isArmed(armMode.getValue());
}
/**
* @return the short description
*/
public String getShortArmMode() {
- return getShortArmMode(getArmMode());
+ return getShortArmMode(armMode.getValue());
}
/**
* @param otherState the other state
*/
public void keepOnlyDifferencesWith(PowermaxState otherState) {
- 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 zone = 1; zone <= zones.length; zone++) {
+ PowermaxZoneState thisZone = getZone(zone);
+ PowermaxZoneState otherZone = otherState.getZone(zone);
+
+ for (int i = 0; i < thisZone.getValues().size(); i++) {
+ Value<?> thisValue = thisZone.getValues().get(i);
+ Value<?> otherValue = otherZone.getValues().get(i);
+
+ if ((thisValue.getValue() != null) && thisValue.getValue().equals(otherValue.getValue())) {
+ thisValue.setValue(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;
+
+ for (int i = 0; i < getValues().size(); i++) {
+ Value<?> thisValue = getValues().get(i);
+ Value<?> otherValue = otherState.getValues().get(i);
+
+ if ((thisValue.getValue() != null) && thisValue.getValue().equals(otherValue.getValue())) {
+ thisValue.setValue(null);
+ }
}
}
* @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 zone = 1; zone <= zones.length; zone++) {
+ PowermaxZoneState thisZone = getZone(zone);
+ PowermaxZoneState otherZone = update.getZone(zone);
+
+ for (int i = 0; i < thisZone.getValues().size(); i++) {
+ Value<?> thisValue = thisZone.getValues().get(i);
+ Value<?> otherValue = otherZone.getValues().get(i);
+
+ if (otherValue.getValue() != null) {
+ thisValue.setValueUnsafe(otherValue.getValue());
+ }
}
}
+
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();
+
+ for (int i = 0; i < getValues().size(); i++) {
+ Value<?> thisValue = getValues().get(i);
+ Value<?> otherValue = update.getValues().get(i);
+
+ if (otherValue.getValue() != null) {
+ thisValue.setValueUnsafe(otherValue.getValue());
+ }
}
+
if (update.getEventLogSize() > getEventLogSize()) {
setEventLogSize(update.getEventLogSize());
}
@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");
+ String str = "Bridge state:";
+
+ for (Value<?> value : getValues()) {
+ if ((value.getChannel() != null) && (value.getValue() != null)) {
+ String channel = value.getChannel();
+ String v_str = value.getValue().toString();
+ String state = value.getState().toString();
+
+ str += "\n - " + channel + " = " + v_str;
+ if (!v_str.equals(state)) {
+ str += " (" + state + ")";
+ }
}
}
+
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 <= zones.length; i++) {
+ for (Value<?> value : zones[i - 1].getValues()) {
+ if ((value.getChannel() != null) && (value.getValue() != null)) {
+ String channel = value.getChannel();
+ String v_str = value.getValue().toString();
+ String state = value.getState().toString();
+
+ str += String.format("\n - sensor zone %d %s = %s", i, channel, v_str);
+ if (!v_str.equals(state)) {
+ str += " (" + state + ")";
+ }
+ }
+ }
}
+
for (int i = 1; i <= getEventLogSize(); i++) {
if (getEventLog(i) != null) {
str += "\n - event log " + i + " = " + getEventLog(i);
--- /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.state;
+
+import java.time.Instant;
+import java.time.ZonedDateTime;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Supplier;
+
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.core.i18n.TimeZoneProvider;
+import org.openhab.core.library.types.DateTimeType;
+import org.openhab.core.library.types.OnOffType;
+import org.openhab.core.library.types.StringType;
+import org.openhab.core.types.State;
+
+/**
+ * Base class for extensible state objects
+ *
+ * @author Ron Isaacson - Initial contribution
+ */
+public abstract class PowermaxStateContainer {
+
+ protected final TimeZoneProvider timeZoneProvider;
+ protected List<Value<?>> values;
+
+ public abstract class Value<T> {
+ protected T value;
+ protected final String channel;
+
+ public Value(PowermaxStateContainer parent, String channel) {
+ this.channel = channel;
+ this.value = null;
+
+ parent.getValues().add(this);
+ }
+
+ public T getValue() {
+ return value;
+ }
+
+ public void setValue(@Nullable T value) {
+ this.value = value;
+ }
+
+ @SuppressWarnings("unchecked")
+ public void setValueUnsafe(@Nullable Object value) {
+ this.value = (T) value;
+ }
+
+ public String getChannel() {
+ return channel;
+ }
+
+ public abstract State getState();
+ }
+
+ public class DynamicValue<T> extends Value<T> {
+ Supplier<T> valueFunction;
+ Supplier<State> stateFunction;
+
+ public DynamicValue(PowermaxStateContainer parent, String channel, Supplier<T> valueFunction,
+ Supplier<State> stateFunction) {
+ super(parent, channel);
+ this.valueFunction = valueFunction;
+ this.stateFunction = stateFunction;
+ }
+
+ // Note: setValue() is still valid, but the saved value will be ignored
+
+ @Override
+ public T getValue() {
+ return valueFunction.get();
+ }
+
+ @Override
+ public State getState() {
+ return stateFunction.get();
+ }
+ }
+
+ public class BooleanValue extends Value<Boolean> {
+ State trueState;
+ State falseState;
+
+ public BooleanValue(PowermaxStateContainer parent, String channel, State trueState, State falseState) {
+ super(parent, channel);
+ this.trueState = trueState;
+ this.falseState = falseState;
+ }
+
+ public BooleanValue(PowermaxStateContainer parent, String channel) {
+ this(parent, channel, OnOffType.ON, OnOffType.OFF);
+ }
+
+ @Override
+ public State getState() {
+ return value ? trueState : falseState;
+ }
+ }
+
+ public class StringValue extends Value<String> {
+ public StringValue(PowermaxStateContainer parent, String channel) {
+ super(parent, channel);
+ }
+
+ @Override
+ public State getState() {
+ return new StringType(value);
+ }
+ }
+
+ public class DateTimeValue extends Value<Long> {
+ public DateTimeValue(PowermaxStateContainer parent, String channel) {
+ super(parent, channel);
+ }
+
+ @Override
+ public State getState() {
+ ZonedDateTime zoned = ZonedDateTime.ofInstant(Instant.ofEpochMilli(value), timeZoneProvider.getTimeZone());
+ return new DateTimeType(zoned);
+ }
+ }
+
+ protected PowermaxStateContainer(TimeZoneProvider timeZoneProvider) {
+ this.timeZoneProvider = timeZoneProvider;
+ this.values = new ArrayList<>();
+ }
+
+ public List<Value<?>> getValues() {
+ return values;
+ }
+}
*/
package org.openhab.binding.powermax.internal.state;
+import static org.openhab.binding.powermax.internal.PowermaxBindingConstants.*;
+
+import org.openhab.core.i18n.TimeZoneProvider;
+import org.openhab.core.library.types.OpenClosedType;
+
/**
* A class to store the state of a zone
*
* @author Laurent Garnier - Initial contribution
*/
-public class PowermaxZoneState {
-
- private Boolean tripped;
- private Long lastTripped;
- private Boolean lowBattery;
- private Boolean bypassed;
- private Boolean armed;
+public class PowermaxZoneState extends PowermaxStateContainer {
- public PowermaxZoneState() {
- tripped = null;
- lastTripped = null;
- lowBattery = null;
- bypassed = null;
- armed = null;
- }
+ public BooleanValue tripped = new BooleanValue(this, TRIPPED, OpenClosedType.OPEN, OpenClosedType.CLOSED);
+ public DateTimeValue lastTripped = new DateTimeValue(this, LAST_TRIP);
+ public BooleanValue lowBattery = new BooleanValue(this, LOW_BATTERY);
+ public BooleanValue bypassed = new BooleanValue(this, BYPASSED);
+ public BooleanValue armed = new BooleanValue(this, ARMED);
- public Boolean isTripped() {
- return tripped;
- }
+ public DynamicValue<Boolean> locked = new DynamicValue<>(this, LOCKED, () -> {
+ return armed.getValue();
+ }, () -> {
+ Boolean isArmed = armed.getValue();
+ if (isArmed == null) {
+ return null;
+ }
+ return isArmed ? OpenClosedType.CLOSED : OpenClosedType.OPEN;
+ });
- public void setTripped(Boolean tripped) {
- this.tripped = tripped;
- }
-
- public Long getLastTripped() {
- return lastTripped;
- }
-
- public void setLastTripped(Long lastTripped) {
- this.lastTripped = lastTripped;
+ public PowermaxZoneState(TimeZoneProvider timeZoneProvider) {
+ super(timeZoneProvider);
}
public boolean isLastTripBeforeTime(long refTime) {
- return isTripped() == Boolean.TRUE && getLastTripped() != null && getLastTripped() < refTime;
- }
-
- public Boolean isLowBattery() {
- return lowBattery;
- }
-
- public void setLowBattery(Boolean lowBattery) {
- this.lowBattery = lowBattery;
- }
-
- public Boolean isBypassed() {
- return bypassed;
- }
-
- public void setBypassed(Boolean bypassed) {
- this.bypassed = bypassed;
- }
-
- public Boolean isArmed() {
- return armed;
- }
-
- public void setArmed(Boolean armed) {
- this.armed = armed;
+ return Boolean.TRUE.equals(tripped.getValue()) && (lastTripped.getValue() != null)
+ && (lastTripped.getValue() < refTime);
}
}