]> git.basschouten.com Git - openhab-addons.git/blob
ee529e2df7822f8449cf0643181103bcedbce028
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2021 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.caddx.internal.handler;
14
15 import java.util.Collection;
16 import java.util.Collections;
17 import java.util.HashMap;
18
19 import org.eclipse.jdt.annotation.NonNullByDefault;
20 import org.eclipse.jdt.annotation.Nullable;
21 import org.openhab.binding.caddx.internal.CaddxBindingConstants;
22 import org.openhab.binding.caddx.internal.CaddxEvent;
23 import org.openhab.binding.caddx.internal.CaddxMessage;
24 import org.openhab.binding.caddx.internal.CaddxMessageType;
25 import org.openhab.binding.caddx.internal.CaddxProperty;
26 import org.openhab.binding.caddx.internal.action.CaddxPanelActions;
27 import org.openhab.core.library.types.OnOffType;
28 import org.openhab.core.library.types.StringType;
29 import org.openhab.core.thing.ChannelUID;
30 import org.openhab.core.thing.Thing;
31 import org.openhab.core.thing.ThingStatus;
32 import org.openhab.core.thing.binding.ThingHandlerService;
33 import org.openhab.core.types.Command;
34 import org.openhab.core.types.RefreshType;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37
38 /**
39  * This is a class for handling a Panel type Thing.
40  *
41  * @author Georgios Moutsos - Initial contribution
42  */
43 @NonNullByDefault
44 public class ThingHandlerPanel extends CaddxBaseThingHandler {
45     private final Logger logger = LoggerFactory.getLogger(ThingHandlerPanel.class);
46     private @Nullable HashMap<String, String> panelLogMessagesMap = null;
47     private @Nullable String communicatorStackPointer = null;
48     private long lastRefreshTime = 0;
49
50     public ThingHandlerPanel(Thing thing) {
51         super(thing, CaddxThingType.PANEL);
52     }
53
54     @Override
55     public void updateChannel(ChannelUID channelUID, String data) {
56         if (channelUID.getId().equals(CaddxBindingConstants.PANEL_FIRMWARE_VERSION)
57                 || channelUID.getId().startsWith("panel_log_message_")) {
58             updateState(channelUID, new StringType(data));
59         } else {
60             // All Panel channels are OnOffType
61             OnOffType onOffType;
62
63             onOffType = ("true".equals(data)) ? OnOffType.ON : OnOffType.OFF;
64             updateState(channelUID, onOffType);
65         }
66     }
67
68     @Override
69     public void handleCommand(ChannelUID channelUID, Command command) {
70         logger.trace("handleCommand(): Command Received - {} {}.", channelUID, command);
71
72         String cmd = null;
73         String data = null;
74         CaddxBridgeHandler bridgeHandler = getCaddxBridgeHandler();
75         if (bridgeHandler == null) {
76             return;
77         }
78
79         if (command instanceof RefreshType) {
80             if (CaddxBindingConstants.PANEL_LOG_MESSAGE_N_0.equals(channelUID.getId())) {
81                 cmd = CaddxBindingConstants.PANEL_SYSTEM_STATUS_REQUEST;
82                 data = "";
83             } else if (System.currentTimeMillis() - lastRefreshTime > 2000) {
84                 // Refresh only if 2 seconds have passed from the last refresh
85                 cmd = CaddxBindingConstants.PANEL_INTERFACE_CONFIGURATION_REQUEST;
86                 data = "";
87             } else {
88                 return;
89             }
90
91             bridgeHandler.sendCommand(cmd, data);
92             lastRefreshTime = System.currentTimeMillis();
93         } else {
94             logger.debug("Unknown command {}", command);
95         }
96     }
97
98     @Override
99     public void caddxEventReceived(CaddxEvent event, Thing thing) {
100         logger.trace("caddxEventReceived(): Event Received - {}.", event);
101
102         if (getThing().equals(thing)) {
103             CaddxMessage message = event.getCaddxMessage();
104             CaddxMessageType mt = message.getCaddxMessageType();
105             ChannelUID channelUID = null;
106
107             // Log event messages have special handling
108             if (CaddxMessageType.SYSTEM_STATUS_MESSAGE.equals(mt)) {
109                 handleSystemStatusMessage(message);
110             } else if (CaddxMessageType.LOG_EVENT_MESSAGE.equals(mt)) {
111                 handleLogEventMessage(message);
112             } else {
113                 for (CaddxProperty p : mt.properties) {
114                     if (!p.getId().isEmpty()) {
115                         String value = message.getPropertyById(p.getId());
116                         channelUID = new ChannelUID(getThing().getUID(), p.getId());
117                         updateChannel(channelUID, value);
118                     }
119                 }
120             }
121
122             updateStatus(ThingStatus.ONLINE);
123         }
124     }
125
126     /*
127      * Gets the pointer into the panel's log messages ring buffer
128      * and sends the command for the retrieval of the last event_message
129      */
130     private void handleSystemStatusMessage(CaddxMessage message) {
131         // Get the bridge handler
132         CaddxBridgeHandler bridgeHandler = getCaddxBridgeHandler();
133         if (bridgeHandler == null) {
134             return;
135         }
136
137         String pointer = message.getPropertyById("panel_communicator_stack_pointer");
138         communicatorStackPointer = pointer;
139
140         // build map of log message channels to event numbers
141         HashMap<String, String> map = new HashMap<String, String>();
142         map.put(pointer, CaddxBindingConstants.PANEL_LOG_MESSAGE_N_0);
143         bridgeHandler.sendCommand(CaddxBindingConstants.PANEL_LOG_EVENT_REQUEST, pointer);
144         panelLogMessagesMap = map;
145     }
146
147     /*
148      * This function handles the panel log messages.
149      * If the received event_number matches our communication stack pointer then this is the last panel message. The
150      * channel gets updated and the required log message requests are generated for the update of the other log message
151      * channels
152      */
153     private void handleLogEventMessage(CaddxMessage message) {
154         // Get the bridge handler
155         CaddxBridgeHandler bridgeHandler = getCaddxBridgeHandler();
156         if (bridgeHandler == null) {
157             return;
158         }
159
160         String eventNumberString = message.getPropertyById("panel_log_event_number");
161         String eventSizeString = message.getPropertyById("panel_log_event_size");
162
163         // build the message
164         LogEventMessage logEventMessage = new LogEventMessage(message);
165
166         logger.trace("Log_event: {}", logEventMessage);
167
168         // get the channel id from the map
169         HashMap<String, String> logMap = panelLogMessagesMap;
170         String id = logMap.get(eventNumberString);
171         if (logMap != null && id != null) {
172             ChannelUID channelUID = new ChannelUID(getThing().getUID(), id);
173             updateChannel(channelUID, logEventMessage.toString());
174         }
175
176         if (communicatorStackPointer != null && eventNumberString.equals(communicatorStackPointer)) {
177             HashMap<String, String> map = new HashMap<String, String>();
178
179             int eventNumber = Integer.parseInt(eventNumberString);
180             int eventSize = Integer.parseInt(eventSizeString);
181
182             // Retrieve at maximum the 10 last log messages from the panel
183             int messagesToRetrieve = Math.min(eventSize, 10);
184             for (int i = 1; i < messagesToRetrieve; i++) {
185                 eventNumber--;
186                 if (eventNumber < 0) {
187                     eventNumber = eventSize;
188                 }
189
190                 map.put(Integer.toString(eventNumber), "panel_log_message_n_" + i);
191                 bridgeHandler.sendCommand(CaddxBindingConstants.PANEL_LOG_EVENT_REQUEST, Integer.toString(eventNumber));
192             }
193
194             communicatorStackPointer = null;
195             panelLogMessagesMap = map;
196         }
197     }
198
199     @Override
200     public Collection<Class<? extends ThingHandlerService>> getServices() {
201         return Collections.singleton(CaddxPanelActions.class);
202     }
203
204     private void sendPrimaryCommand(String pin, String function) {
205         String cmd = CaddxBindingConstants.PARTITION_PRIMARY_COMMAND_WITH_PIN;
206
207         // Build the data
208         StringBuilder sb = new StringBuilder();
209         sb.append("0x").append(pin.charAt(1)).append(pin.charAt(0)).append(",0x").append(pin.charAt(3))
210                 .append(pin.charAt(2)).append(",0x").append(pin.charAt(5)).append(pin.charAt(4)).append(",")
211                 .append(function).append(",").append("255");
212
213         CaddxBridgeHandler bridgeHandler = getCaddxBridgeHandler();
214         if (bridgeHandler == null) {
215             return;
216         }
217         bridgeHandler.sendCommand(cmd, sb.toString());
218     }
219
220     private void sendSecondaryCommand(String function) {
221         String cmd = CaddxBindingConstants.PARTITION_SECONDARY_COMMAND;
222
223         // Build the data
224         StringBuilder sb = new StringBuilder();
225         sb.append(function).append(",").append("255");
226
227         CaddxBridgeHandler bridgeHandler = getCaddxBridgeHandler();
228         if (bridgeHandler == null) {
229             return;
230         }
231         bridgeHandler.sendCommand(cmd, sb.toString());
232     }
233
234     public void turnOffAnySounderOrAlarm(String pin) {
235         sendPrimaryCommand(pin, "0");
236     }
237
238     public void disarm(String pin) {
239         sendPrimaryCommand(pin, "1");
240     }
241
242     public void armInAwayMode(String pin) {
243         sendPrimaryCommand(pin, "2");
244     }
245
246     public void armInStayMode(String pin) {
247         sendPrimaryCommand(pin, "3");
248     }
249
250     public void cancel(String pin) {
251         sendPrimaryCommand(pin, "4");
252     }
253
254     public void initiateAutoArm(String pin) {
255         sendPrimaryCommand(pin, "5");
256     }
257
258     public void startWalkTestMode(String pin) {
259         sendPrimaryCommand(pin, "6");
260     }
261
262     public void stopWalkTestMode(String pin) {
263         sendPrimaryCommand(pin, "7");
264     }
265
266     public void stay() {
267         sendSecondaryCommand("0");
268     }
269
270     public void chime() {
271         sendSecondaryCommand("1");
272     }
273
274     public void exit() {
275         sendSecondaryCommand("2");
276     }
277
278     public void bypassInteriors() {
279         sendSecondaryCommand("3");
280     }
281
282     public void firePanic() {
283         sendSecondaryCommand("4");
284     }
285
286     public void medicalPanic() {
287         sendSecondaryCommand("5");
288     }
289
290     public void policePanic() {
291         sendSecondaryCommand("6");
292     }
293
294     public void smokeDetectorReset() {
295         sendSecondaryCommand("7");
296     }
297
298     public void autoCallbackDownload() {
299         sendSecondaryCommand("8");
300     }
301
302     public void manualPickupDownload() {
303         sendSecondaryCommand("9");
304     }
305
306     public void enableSilentExit() {
307         sendSecondaryCommand("10");
308     }
309
310     public void performTest() {
311         sendSecondaryCommand("11");
312     }
313
314     public void groupBypass() {
315         sendSecondaryCommand("12");
316     }
317
318     public void auxiliaryFunction1() {
319         sendSecondaryCommand("13");
320     }
321
322     public void auxiliaryFunction2() {
323         sendSecondaryCommand("14");
324     }
325
326     public void startKeypadSounder() {
327         sendSecondaryCommand("15");
328     }
329 }