]> git.basschouten.com Git - openhab-addons.git/blob
9d5ddb37f3a17211dc05f386566a9e89b55a991a
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
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
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.openwebnet.internal.handler;
14
15 import static org.openhab.binding.openwebnet.internal.OpenWebNetBindingConstants.*;
16
17 import java.util.Set;
18
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;
38
39 /**
40  * The {@link OpenWebNetAlarmHandler} is responsible for handling
41  * commands/messages for Alarm system and zones. It extends the abstract
42  * {@link OpenWebNetThingHandler}.
43  *
44  * @author Massimo Valla - Initial contribution
45  */
46 @NonNullByDefault
47 public class OpenWebNetAlarmHandler extends OpenWebNetThingHandler {
48
49     private final Logger logger = LoggerFactory.getLogger(OpenWebNetAlarmHandler.class);
50
51     public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = OpenWebNetBindingConstants.ALARM_SUPPORTED_THING_TYPES;
52
53     private static long lastAllDevicesRefreshTS = 0; // ts when last all device refresh was sent for this handler
54
55     private static final String BATTERY_OK = "OK";
56     private static final String BATTERY_FAULT = "FAULT";
57     private static final String BATTERY_UNLOADED = "UNLOADED";
58
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";
63
64     public OpenWebNetAlarmHandler(Thing thing) {
65         super(thing);
66     }
67
68     @Override
69     protected void handleChannelCommand(ChannelUID channel, Command command) {
70         logger.warn("Alarm.handleChannelCommand() Read only channel, unsupported command {}", command);
71     }
72
73     @Override
74     protected void requestChannelState(ChannelUID channel) {
75         super.requestChannelState(channel);
76         Where w = deviceWhere;
77         ThingTypeUID thingType = thing.getThingTypeUID();
78         try {
79             if (THING_TYPE_BUS_ALARM_SYSTEM.equals(thingType)) {
80                 send(Alarm.requestSystemStatus());
81                 lastAllDevicesRefreshTS = System.currentTimeMillis();
82             } else {
83                 if (w != null) {
84                     send(Alarm.requestZoneStatus("#" + w.value()));
85                 } else {
86                     logger.debug("null where while requesting state for channel {}", channel);
87                 }
88             }
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());
92         }
93     }
94
95     @Override
96     protected long getRefreshAllLastTS() {
97         return lastAllDevicesRefreshTS;
98     };
99
100     @Override
101     protected void refreshDevice(boolean refreshAll) {
102         if (refreshAll) {
103             logger.debug("--- refreshDevice() : refreshing all via ALARM CENTRAL UNIT... ({})", thing.getUID());
104             try {
105                 send(Alarm.requestSystemStatus());
106                 lastAllDevicesRefreshTS = System.currentTimeMillis();
107             } catch (OWNException e) {
108                 logger.warn("Excpetion while requesting alarm system status: {}", e.getMessage());
109             }
110         } else {
111             logger.debug("--- refreshDevice() : refreshing SINGLE... ({})", thing.getUID());
112             requestChannelState(new ChannelUID(thing.getUID(), CHANNEL_ALARM_SYSTEM_STATE));
113         }
114     }
115
116     @Override
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);
123         } else {
124             updateZone((Alarm) msg);
125         }
126     }
127
128     private void updateSystem(Alarm msg) {
129         WhatAlarm w = (WhatAlarm) msg.getWhat();
130         if (w == null) {
131             logger.debug("Alarm.updateSystem() WHAT is null. Frame={}", msg);
132             return;
133         }
134         switch (w) {
135             case SYSTEM_ACTIVE:
136             case SYSTEM_INACTIVE:
137             case SYSTEM_MAINTENANCE:
138                 updateAlarmSystemState(w);
139                 break;
140             case SYSTEM_DISENGAGED:
141             case SYSTEM_ENGAGED:
142                 updateAlarmSystemArmed(w);
143                 break;
144             case SYSTEM_BATTERY_FAULT:
145             case SYSTEM_BATTERY_OK:
146             case SYSTEM_BATTERY_UNLOADED:
147                 updateBatteryState(w);
148                 break;
149             case SYSTEM_NETWORK_ERROR:
150             case SYSTEM_NETWORK_OK:
151                 updateNetworkState(w);
152                 break;
153             case START_PROGRAMMING:
154             case STOP_PROGRAMMING:
155             case DELAY_END:
156             case NO_CONNECTION_TO_DEVICE:
157             default:
158                 logger.debug("Alarm.updateSystem() Ignoring unsupported WHAT {}. Frame={}", msg.getWhat(), msg);
159         }
160     }
161
162     private void updateAlarmSystemState(WhatAlarm w) {
163         updateState(CHANNEL_ALARM_SYSTEM_STATE, OnOffType.from(w == Alarm.WhatAlarm.SYSTEM_ACTIVE));
164     }
165
166     private void updateAlarmSystemArmed(WhatAlarm w) {
167         updateState(CHANNEL_ALARM_SYSTEM_ARMED, OnOffType.from(w == Alarm.WhatAlarm.SYSTEM_ENGAGED));
168     }
169
170     private void updateNetworkState(WhatAlarm w) {
171         updateState(CHANNEL_ALARM_SYSTEM_NETWORK, OnOffType.from(w == Alarm.WhatAlarm.SYSTEM_NETWORK_OK));
172     }
173
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));
179         } else {
180             updateState(CHANNEL_ALARM_SYSTEM_BATTERY, new StringType(BATTERY_FAULT));
181         }
182     }
183
184     private void updateZone(Alarm msg) {
185         WhatAlarm w = (WhatAlarm) msg.getWhat();
186         if (w == null) {
187             logger.debug("Alarm.updateZone() WHAT is null. Frame={}", msg);
188             return;
189         }
190         switch (w) {
191             case ZONE_DISENGAGED:
192             case ZONE_ENGAGED:
193                 updateZoneState(w);
194                 break;
195             case ZONE_ALARM_INTRUSION:
196             case ZONE_ALARM_TAMPERING:
197             case ZONE_ALARM_ANTI_PANIC:
198             case ZONE_ALARM_SILENT:
199                 updateZoneAlarmState(w);
200                 break;
201             case ZONE_ALARM_TECHNICAL:// not handled for now
202             case ZONE_ALARM_TECHNICAL_RESET:
203             default:
204                 logger.debug("Alarm.updateZone() Ignoring unsupported WHAT {}. Frame={}", msg.getWhat(), msg);
205         }
206     }
207
208     private void updateZoneState(WhatAlarm w) {
209         updateState(CHANNEL_ALARM_ZONE_STATE, OnOffType.from(w == Alarm.WhatAlarm.ZONE_ENGAGED));
210     }
211
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));
219         } else {
220             updateState(CHANNEL_ALARM_ZONE_ALARM_STATE, new StringType(TAMPERING));
221         }
222     }
223
224     @Override
225     protected Where buildBusWhere(String wStr) throws IllegalArgumentException {
226         return new WhereAlarm(wStr);
227     }
228
229     @Override
230     protected String ownIdPrefix() {
231         return Who.BURGLAR_ALARM.value().toString();
232     }
233 }