2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.openwebnet.internal.handler;
15 import static org.openhab.binding.openwebnet.internal.OpenWebNetBindingConstants.*;
19 import org.eclipse.jdt.annotation.NonNullByDefault;
20 import org.openhab.binding.openwebnet.internal.OpenWebNetBindingConstants;
21 import org.openhab.core.library.types.OnOffType;
22 import org.openhab.core.library.types.StringType;
23 import org.openhab.core.thing.ChannelUID;
24 import org.openhab.core.thing.Thing;
25 import org.openhab.core.thing.ThingStatus;
26 import org.openhab.core.thing.ThingStatusDetail;
27 import org.openhab.core.thing.ThingTypeUID;
28 import org.openhab.core.types.Command;
29 import org.openwebnet4j.communication.OWNException;
30 import org.openwebnet4j.message.Alarm;
31 import org.openwebnet4j.message.Alarm.WhatAlarm;
32 import org.openwebnet4j.message.BaseOpenMessage;
33 import org.openwebnet4j.message.Where;
34 import org.openwebnet4j.message.WhereAlarm;
35 import org.openwebnet4j.message.Who;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
40 * The {@link OpenWebNetAlarmHandler} is responsible for handling
41 * commands/messages for Alarm system and zones. It extends the abstract
42 * {@link OpenWebNetThingHandler}.
44 * @author Massimo Valla - Initial contribution
47 public class OpenWebNetAlarmHandler extends OpenWebNetThingHandler {
49 private final Logger logger = LoggerFactory.getLogger(OpenWebNetAlarmHandler.class);
51 public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = OpenWebNetBindingConstants.ALARM_SUPPORTED_THING_TYPES;
53 private static long lastAllDevicesRefreshTS = 0; // ts when last all device refresh was sent for this handler
55 private static final String BATTERY_OK = "OK";
56 private static final String BATTERY_FAULT = "FAULT";
57 private static final String BATTERY_UNLOADED = "UNLOADED";
59 private static final String SILENT = "SILENT";
60 private static final String INTRUSION = "INTRUSION";
61 private static final String ANTI_PANIC = "ANTI_PANIC";
62 private static final String TAMPERING = "TAMPERING";
64 public OpenWebNetAlarmHandler(Thing thing) {
69 protected void handleChannelCommand(ChannelUID channel, Command command) {
70 logger.warn("Alarm.handleChannelCommand() Read only channel, unsupported command {}", command);
74 protected void requestChannelState(ChannelUID channel) {
75 super.requestChannelState(channel);
76 Where w = deviceWhere;
77 ThingTypeUID thingType = thing.getThingTypeUID();
79 if (THING_TYPE_BUS_ALARM_SYSTEM.equals(thingType)) {
80 send(Alarm.requestSystemStatus());
81 lastAllDevicesRefreshTS = System.currentTimeMillis();
84 send(Alarm.requestZoneStatus("#" + w.value()));
86 logger.debug("null where while requesting state for channel {}", channel);
89 } catch (OWNException e) {
90 logger.debug("Exception while requesting state for channel {}: {} ", channel, e.getMessage());
91 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
96 protected long getRefreshAllLastTS() {
97 return lastAllDevicesRefreshTS;
101 protected void refreshDevice(boolean refreshAll) {
103 logger.debug("--- refreshDevice() : refreshing all via ALARM CENTRAL UNIT... ({})", thing.getUID());
105 send(Alarm.requestSystemStatus());
106 lastAllDevicesRefreshTS = System.currentTimeMillis();
107 } catch (OWNException e) {
108 logger.warn("Excpetion while requesting alarm system status: {}", e.getMessage());
111 logger.debug("--- refreshDevice() : refreshing SINGLE... ({})", thing.getUID());
112 requestChannelState(new ChannelUID(thing.getUID(), CHANNEL_ALARM_SYSTEM_STATE));
117 protected void handleMessage(BaseOpenMessage msg) {
118 logger.debug("handleMessage({}) for thing: {}", msg, thing.getUID());
119 super.handleMessage(msg);
120 ThingTypeUID thingType = thing.getThingTypeUID();
121 if (THING_TYPE_BUS_ALARM_SYSTEM.equals(thingType)) {
122 updateSystem((Alarm) msg);
124 updateZone((Alarm) msg);
128 private void updateSystem(Alarm msg) {
129 WhatAlarm w = (WhatAlarm) msg.getWhat();
131 logger.debug("Alarm.updateSystem() WHAT is null. Frame={}", msg);
136 case SYSTEM_INACTIVE:
137 case SYSTEM_MAINTENANCE:
138 updateAlarmSystemState(w);
140 case SYSTEM_DISENGAGED:
142 updateAlarmSystemArmed(w);
144 case SYSTEM_BATTERY_FAULT:
145 case SYSTEM_BATTERY_OK:
146 case SYSTEM_BATTERY_UNLOADED:
147 updateBatteryState(w);
149 case SYSTEM_NETWORK_ERROR:
150 case SYSTEM_NETWORK_OK:
151 updateNetworkState(w);
153 case START_PROGRAMMING:
154 case STOP_PROGRAMMING:
156 case NO_CONNECTION_TO_DEVICE:
158 logger.debug("Alarm.updateSystem() Ignoring unsupported WHAT {}. Frame={}", msg.getWhat(), msg);
162 private void updateAlarmSystemState(WhatAlarm w) {
163 updateState(CHANNEL_ALARM_SYSTEM_STATE, OnOffType.from(w == Alarm.WhatAlarm.SYSTEM_ACTIVE));
166 private void updateAlarmSystemArmed(WhatAlarm w) {
167 updateState(CHANNEL_ALARM_SYSTEM_ARMED, OnOffType.from(w == Alarm.WhatAlarm.SYSTEM_ENGAGED));
170 private void updateNetworkState(WhatAlarm w) {
171 updateState(CHANNEL_ALARM_SYSTEM_NETWORK, OnOffType.from(w == Alarm.WhatAlarm.SYSTEM_NETWORK_OK));
174 private void updateBatteryState(WhatAlarm w) {
175 if (w == Alarm.WhatAlarm.SYSTEM_BATTERY_OK) {
176 updateState(CHANNEL_ALARM_SYSTEM_BATTERY, new StringType(BATTERY_OK));
177 } else if (w == Alarm.WhatAlarm.SYSTEM_BATTERY_UNLOADED) {
178 updateState(CHANNEL_ALARM_SYSTEM_BATTERY, new StringType(BATTERY_UNLOADED));
180 updateState(CHANNEL_ALARM_SYSTEM_BATTERY, new StringType(BATTERY_FAULT));
184 private void updateZone(Alarm msg) {
185 WhatAlarm w = (WhatAlarm) msg.getWhat();
187 logger.debug("Alarm.updateZone() WHAT is null. Frame={}", msg);
191 case ZONE_DISENGAGED:
195 case ZONE_ALARM_INTRUSION:
196 case ZONE_ALARM_TAMPERING:
197 case ZONE_ALARM_ANTI_PANIC:
198 case ZONE_ALARM_SILENT:
199 updateZoneAlarmState(w);
201 case ZONE_ALARM_TECHNICAL:// not handled for now
202 case ZONE_ALARM_TECHNICAL_RESET:
204 logger.debug("Alarm.updateZone() Ignoring unsupported WHAT {}. Frame={}", msg.getWhat(), msg);
208 private void updateZoneState(WhatAlarm w) {
209 updateState(CHANNEL_ALARM_ZONE_STATE, OnOffType.from(w == Alarm.WhatAlarm.ZONE_ENGAGED));
212 private void updateZoneAlarmState(WhatAlarm w) {
213 if (w == Alarm.WhatAlarm.ZONE_ALARM_SILENT) {
214 updateState(CHANNEL_ALARM_ZONE_ALARM_STATE, new StringType(SILENT));
215 } else if (w == Alarm.WhatAlarm.ZONE_ALARM_INTRUSION) {
216 updateState(CHANNEL_ALARM_ZONE_ALARM_STATE, new StringType(INTRUSION));
217 } else if (w == Alarm.WhatAlarm.ZONE_ALARM_ANTI_PANIC) {
218 updateState(CHANNEL_ALARM_ZONE_ALARM_STATE, new StringType(ANTI_PANIC));
220 updateState(CHANNEL_ALARM_ZONE_ALARM_STATE, new StringType(TAMPERING));
225 protected Where buildBusWhere(String wStr) throws IllegalArgumentException {
226 return new WhereAlarm(wStr);
230 protected String ownIdPrefix() {
231 return Who.BURGLAR_ALARM.value().toString();