]> git.basschouten.com Git - openhab-addons.git/blob
c199590104c2dea08edbcc277b24e6ce792cb3dd
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2020 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.HashMap;
16
17 import org.eclipse.jdt.annotation.NonNullByDefault;
18 import org.eclipse.jdt.annotation.Nullable;
19 import org.openhab.binding.caddx.internal.CaddxBindingConstants;
20 import org.openhab.binding.caddx.internal.CaddxEvent;
21 import org.openhab.binding.caddx.internal.CaddxMessage;
22 import org.openhab.binding.caddx.internal.CaddxMessageType;
23 import org.openhab.binding.caddx.internal.CaddxProperty;
24 import org.openhab.core.library.types.OnOffType;
25 import org.openhab.core.library.types.StringType;
26 import org.openhab.core.thing.ChannelUID;
27 import org.openhab.core.thing.Thing;
28 import org.openhab.core.thing.ThingStatus;
29 import org.openhab.core.types.Command;
30 import org.openhab.core.types.RefreshType;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33
34 /**
35  * This is a class for handling a Panel type Thing.
36  *
37  * @author Georgios Moutsos - Initial contribution
38  */
39 @NonNullByDefault
40 public class ThingHandlerPanel extends CaddxBaseThingHandler {
41     private final Logger logger = LoggerFactory.getLogger(ThingHandlerPanel.class);
42     private @Nullable HashMap<String, String> panelLogMessagesMap = null;
43     private @Nullable String communicatorStackPointer = null;
44     private long lastRefreshTime = 0;
45
46     public ThingHandlerPanel(Thing thing) {
47         super(thing, CaddxThingType.PANEL);
48     }
49
50     @Override
51     public void updateChannel(ChannelUID channelUID, String data) {
52         if (channelUID.getId().equals(CaddxBindingConstants.PANEL_FIRMWARE_VERSION)
53                 || channelUID.getId().startsWith("panel_log_message_")) {
54             updateState(channelUID, new StringType(data));
55         } else {
56             // All Panel channels are OnOffType
57             OnOffType onOffType;
58
59             onOffType = ("true".equals(data)) ? OnOffType.ON : OnOffType.OFF;
60             updateState(channelUID, onOffType);
61         }
62     }
63
64     @Override
65     public void handleCommand(ChannelUID channelUID, Command command) {
66         logger.trace("handleCommand(): Command Received - {} {}.", channelUID, command);
67
68         String cmd = null;
69         String data = null;
70         CaddxBridgeHandler bridgeHandler = getCaddxBridgeHandler();
71         if (bridgeHandler == null) {
72             return;
73         }
74
75         if (command instanceof RefreshType) {
76             if (CaddxBindingConstants.PANEL_LOG_MESSAGE_N_0.equals(channelUID.getId())) {
77                 cmd = CaddxBindingConstants.PANEL_SYSTEM_STATUS_REQUEST;
78                 data = "";
79             } else if (System.currentTimeMillis() - lastRefreshTime > 2000) {
80                 // Refresh only if 2 seconds have passed from the last refresh
81                 cmd = CaddxBindingConstants.PANEL_INTERFACE_CONFIGURATION_REQUEST;
82                 data = "";
83             } else {
84                 return;
85             }
86
87             bridgeHandler.sendCommand(cmd, data);
88             lastRefreshTime = System.currentTimeMillis();
89         } else {
90             logger.debug("Unknown command {}", command);
91         }
92     }
93
94     @Override
95     public void caddxEventReceived(CaddxEvent event, Thing thing) {
96         logger.trace("caddxEventReceived(): Event Received - {}.", event);
97
98         if (getThing().equals(thing)) {
99             CaddxMessage message = event.getCaddxMessage();
100             CaddxMessageType mt = message.getCaddxMessageType();
101             ChannelUID channelUID = null;
102
103             // Log event messages have special handling
104             if (CaddxMessageType.SYSTEM_STATUS_MESSAGE.equals(mt)) {
105                 handleSystemStatusMessage(message);
106             } else if (CaddxMessageType.LOG_EVENT_MESSAGE.equals(mt)) {
107                 handleLogEventMessage(message);
108             } else {
109                 for (CaddxProperty p : mt.properties) {
110                     if (!p.getId().isEmpty()) {
111                         String value = message.getPropertyById(p.getId());
112                         channelUID = new ChannelUID(getThing().getUID(), p.getId());
113                         updateChannel(channelUID, value);
114                     }
115                 }
116             }
117
118             updateStatus(ThingStatus.ONLINE);
119         }
120     }
121
122     /*
123      * Gets the pointer into the panel's log messages ring buffer
124      * and sends the command for the retrieval of the last event_message
125      */
126     private void handleSystemStatusMessage(CaddxMessage message) {
127         // Get the bridge handler
128         CaddxBridgeHandler bridgeHandler = getCaddxBridgeHandler();
129         if (bridgeHandler == null) {
130             return;
131         }
132
133         String pointer = message.getPropertyById("panel_communicator_stack_pointer");
134         communicatorStackPointer = pointer;
135
136         // build map of log message channels to event numbers
137         HashMap<String, String> map = new HashMap<String, String>();
138         map.put(pointer, CaddxBindingConstants.PANEL_LOG_MESSAGE_N_0);
139         bridgeHandler.sendCommand(CaddxBindingConstants.PANEL_LOG_EVENT_REQUEST, pointer);
140         panelLogMessagesMap = map;
141     }
142
143     /*
144      * This function handles the panel log messages.
145      * If the received event_number matches our communication stack pointer then this is the last panel message. The
146      * channel gets updated and the required log message requests are generated for the update of the other log message
147      * channels
148      */
149     private void handleLogEventMessage(CaddxMessage message) {
150         // Get the bridge handler
151         CaddxBridgeHandler bridgeHandler = getCaddxBridgeHandler();
152         if (bridgeHandler == null) {
153             return;
154         }
155
156         String eventNumberString = message.getPropertyById("panel_log_event_number");
157         String eventSizeString = message.getPropertyById("panel_log_event_size");
158
159         // build the message
160         LogEventMessage logEventMessage = new LogEventMessage(message);
161
162         logger.trace("Log_event: {}", logEventMessage);
163
164         // get the channel id from the map
165         HashMap<String, String> logMap = panelLogMessagesMap;
166         String id = logMap.get(eventNumberString);
167         if (logMap != null && id != null) {
168             ChannelUID channelUID = new ChannelUID(getThing().getUID(), id);
169             updateChannel(channelUID, logEventMessage.toString());
170         }
171
172         if (communicatorStackPointer != null && eventNumberString.equals(communicatorStackPointer)) {
173             HashMap<String, String> map = new HashMap<String, String>();
174
175             int eventNumber = Integer.parseInt(eventNumberString);
176             int eventSize = Integer.parseInt(eventSizeString);
177
178             // Retrieve at maximum the 10 last log messages from the panel
179             int messagesToRetrieve = Math.min(eventSize, 10);
180             for (int i = 1; i < messagesToRetrieve; i++) {
181                 eventNumber--;
182                 if (eventNumber < 0) {
183                     eventNumber = eventSize;
184                 }
185
186                 map.put(Integer.toString(eventNumber), "panel_log_message_n_" + i);
187                 bridgeHandler.sendCommand(CaddxBindingConstants.PANEL_LOG_EVENT_REQUEST, Integer.toString(eventNumber));
188             }
189
190             communicatorStackPointer = null;
191             panelLogMessagesMap = map;
192         }
193     }
194 }