]> git.basschouten.com Git - openhab-addons.git/blob
2f625669ae348bb1563ffa7283cd65f81d1cf70c
[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
14 package org.openhab.binding.qbus.internal;
15
16 import java.io.IOException;
17 import java.util.concurrent.ScheduledFuture;
18 import java.util.concurrent.TimeUnit;
19
20 import org.eclipse.jdt.annotation.NonNullByDefault;
21 import org.eclipse.jdt.annotation.Nullable;
22 import org.openhab.binding.qbus.internal.protocol.QbusCommunication;
23 import org.openhab.core.thing.Bridge;
24 import org.openhab.core.thing.ChannelUID;
25 import org.openhab.core.thing.ThingStatus;
26 import org.openhab.core.thing.ThingStatusDetail;
27 import org.openhab.core.thing.ThingStatusInfo;
28 import org.openhab.core.thing.binding.BaseBridgeHandler;
29 import org.openhab.core.types.Command;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32
33 /**
34  * {@link QbusBridgeHandler} is the handler for a Qbus controller
35  *
36  * @author Koen Schockaert - Initial Contribution
37  */
38
39 @NonNullByDefault
40 public class QbusBridgeHandler extends BaseBridgeHandler {
41
42     private @Nullable QbusCommunication qbusComm;
43
44     protected @Nullable QbusConfiguration bridgeConfig = new QbusConfiguration();
45
46     private @Nullable ScheduledFuture<?> refreshTimer;
47
48     private final Logger logger = LoggerFactory.getLogger(QbusBridgeHandler.class);
49
50     public QbusBridgeHandler(Bridge Bridge) {
51         super(Bridge);
52     }
53
54     /**
55      * Initialize the bridge
56      */
57     @Override
58     public void initialize() {
59         Integer serverCheck = getServerCheck();
60
61         readConfig();
62
63         createCommunicationObject();
64
65         if (serverCheck != null) {
66             this.setupRefreshTimer(serverCheck);
67         }
68     }
69
70     /**
71      * Sets the Bridge call back
72      */
73     private void setBridgeCallBack() {
74         QbusCommunication qbusCommunication = getQbusCommunication();
75         if (qbusCommunication != null) {
76             qbusCommunication.setBridgeCallBack(this);
77         }
78     }
79
80     /**
81      * Create communication object to Qbus server and start communication.
82      *
83      * @param addr : IP address of Qbus server
84      * @param port : Communication port of QbusServer
85      */
86     private void createCommunicationObject() {
87         scheduler.submit(() -> {
88
89             setQbusCommunication(new QbusCommunication(thing));
90
91             QbusCommunication qbusCommunication = getQbusCommunication();
92
93             setBridgeCallBack();
94
95             Integer serverCheck = getServerCheck();
96             String sn = getSn();
97             if (serverCheck != null) {
98                 if (sn != null) {
99                     if (qbusCommunication != null) {
100                         try {
101                             qbusCommunication.startCommunication();
102                         } catch (InterruptedException e) {
103                             String msg = e.getMessage();
104                             bridgeOffline(ThingStatusDetail.COMMUNICATION_ERROR,
105                                     "Communication wit Qbus server could not be established, will try to reconnect every "
106                                             + serverCheck + " minutes. InterruptedException: " + msg);
107                             return;
108                         } catch (IOException e) {
109                             String msg = e.getMessage();
110                             bridgeOffline(ThingStatusDetail.COMMUNICATION_ERROR,
111                                     "Communication wit Qbus server could not be established, will try to reconnect every "
112                                             + serverCheck + " minutes. IOException: " + msg);
113                             return;
114                         }
115
116                         if (!qbusCommunication.communicationActive()) {
117                             bridgeOffline(ThingStatusDetail.COMMUNICATION_ERROR,
118                                     "No communication with Qbus Server, will try to reconnect every " + serverCheck
119                                             + " minutes");
120                             return;
121                         }
122
123                         if (!qbusCommunication.clientConnected()) {
124                             bridgePending("Waiting for Qbus client to come online");
125                             return;
126                         }
127
128                     }
129                 }
130             }
131         });
132     }
133
134     /**
135      * Updates offline status off the Bridge when an error occurs.
136      *
137      * @param status
138      * @param detail
139      * @param message
140      */
141     public void bridgeOffline(ThingStatusDetail detail, String message) {
142         updateStatus(ThingStatus.OFFLINE, detail, message);
143     }
144
145     /**
146      * Updates pending status off the Bridge (usualay when Qbus client id not connected)
147      *
148      * @param message
149      */
150     public void bridgePending(String message) {
151         updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.HANDLER_CONFIGURATION_PENDING, message);
152     }
153
154     /**
155      * Put bridge online when error in communication resolved.
156      */
157     public void bridgeOnline() {
158         updateStatus(ThingStatus.ONLINE);
159     }
160
161     /**
162      * Initializes a timer that check the communication with Qbus server/client and tries to re-establish communication.
163      *
164      * @param refreshInterval Time before refresh in minutes.
165      */
166     private void setupRefreshTimer(int refreshInterval) {
167         ScheduledFuture<?> timer = refreshTimer;
168
169         if (timer != null) {
170             timer.cancel(true);
171             refreshTimer = null;
172         }
173
174         if (refreshInterval == 0) {
175             return;
176         }
177
178         refreshTimer = scheduler.scheduleWithFixedDelay(() -> {
179             QbusCommunication comm = getCommunication();
180             Integer serverCheck = getServerCheck();
181
182             if (comm != null) {
183                 if (serverCheck != null) {
184                     if (!comm.communicationActive()) {
185                         // Disconnected from Qbus Server, restart communication
186                         try {
187                             comm.startCommunication();
188                         } catch (InterruptedException e) {
189                             String msg = e.getMessage();
190                             bridgeOffline(ThingStatusDetail.COMMUNICATION_ERROR,
191                                     "Communication wit Qbus server could not be established, will try to reconnect every "
192                                             + serverCheck + " minutes. InterruptedException: " + msg);
193                         } catch (IOException e) {
194                             String msg = e.getMessage();
195                             bridgeOffline(ThingStatusDetail.COMMUNICATION_ERROR,
196                                     "Communication wit Qbus server could not be established, will try to reconnect every "
197                                             + serverCheck + " minutes. IOException: " + msg);
198                         }
199                     }
200                 }
201             }
202         }, refreshInterval, refreshInterval, TimeUnit.MINUTES);
203     }
204
205     /**
206      * Disposes the Bridge and stops communication with the Qbus server
207      */
208     @Override
209     public void dispose() {
210         ScheduledFuture<?> timer = refreshTimer;
211         if (timer != null) {
212             timer.cancel(true);
213         }
214
215         refreshTimer = null;
216
217         QbusCommunication comm = getCommunication();
218
219         if (comm != null) {
220             try {
221                 comm.stopCommunication();
222             } catch (IOException e) {
223                 String message = e.toString();
224                 logger.debug("Error on stopping communication.{} ", message);
225             }
226         }
227
228         comm = null;
229     }
230
231     /**
232      * Reconnect to Qbus server if controller is offline
233      */
234     public void ctdOffline() {
235         bridgePending("Waiting for CTD connection");
236     }
237
238     /**
239      * Get BridgeCommunication
240      *
241      * @return BridgeCommunication
242      */
243     public @Nullable QbusCommunication getQbusCommunication() {
244         if (this.qbusComm != null) {
245             return this.qbusComm;
246         } else {
247             return null;
248         }
249     }
250
251     /**
252      * Sets BridgeCommunication
253      *
254      * @param BridgeCommunication
255      */
256     void setQbusCommunication(QbusCommunication comm) {
257         this.qbusComm = comm;
258     }
259
260     /**
261      * Gets the status off the Bridge
262      *
263      * @return
264      */
265     public ThingStatus getStatus() {
266         return thing.getStatus();
267     }
268
269     /**
270      * Gets the status off the Bridge
271      *
272      * @return
273      */
274     public ThingStatusDetail getStatusDetails() {
275         ThingStatusInfo status = thing.getStatusInfo();
276         ThingStatusDetail detail = status.getStatusDetail();
277         return detail;
278     }
279
280     /**
281      * Sets the configuration parameters
282      */
283     protected void readConfig() {
284         bridgeConfig = getConfig().as(QbusConfiguration.class);
285     }
286
287     /**
288      * Get the Qbus communication object.
289      *
290      * @return Qbus communication object
291      */
292     public @Nullable QbusCommunication getCommunication() {
293         return this.qbusComm;
294     }
295
296     /**
297      * Get the ip address of the Qbus server.
298      *
299      * @return the ip address
300      */
301     public @Nullable String getAddress() {
302         QbusConfiguration localConfig = this.bridgeConfig;
303
304         if (localConfig != null) {
305             return localConfig.addr;
306         } else {
307             return null;
308         }
309     }
310
311     /**
312      * Get the listening port of the Qbus server.
313      *
314      * @return
315      */
316     public @Nullable Integer getPort() {
317         QbusConfiguration localConfig = this.bridgeConfig;
318
319         if (localConfig != null) {
320             return localConfig.port;
321         } else {
322             return null;
323         }
324     }
325
326     /**
327      * Get the serial nr of the Qbus server.
328      *
329      * @return the serial nr of the controller
330      */
331     public @Nullable String getSn() {
332         QbusConfiguration localConfig = this.bridgeConfig;
333
334         if (localConfig != null) {
335             return localConfig.sn;
336         } else {
337             return null;
338         }
339     }
340
341     /**
342      * Get the refresh interval.
343      *
344      * @return the refresh interval
345      */
346     public @Nullable Integer getServerCheck() {
347         QbusConfiguration localConfig = this.bridgeConfig;
348
349         if (localConfig != null) {
350             return localConfig.serverCheck;
351         } else {
352             return null;
353         }
354     }
355
356     @Override
357     public void handleCommand(ChannelUID channelUID, Command command) {
358     }
359 }