]> git.basschouten.com Git - openhab-addons.git/blob
ea6d4769de84dc5b94e3169e0b6ea00a4bd46165
[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
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         readConfig();
60
61         Integer serverCheck = getServerCheck();
62
63         if (serverCheck != null) {
64             this.setupRefreshTimer(serverCheck);
65         }
66
67         createCommunicationObject();
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 detail
138      * @param message
139      */
140     public void bridgeOffline(ThingStatusDetail detail, String message) {
141         updateStatus(ThingStatus.OFFLINE, detail, message);
142     }
143
144     /**
145      * Updates pending status off the Bridge (usualay when Qbus client id not connected)
146      *
147      * @param message
148      */
149     public void bridgePending(String message) {
150         updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.HANDLER_CONFIGURATION_PENDING, message);
151     }
152
153     /**
154      * Put bridge online when error in communication resolved.
155      */
156     public void bridgeOnline() {
157         updateStatus(ThingStatus.ONLINE);
158     }
159
160     /**
161      * Initializes a timer that check the communication with Qbus server/client and tries to re-establish communication.
162      *
163      * @param refreshInterval Time before refresh in minutes.
164      */
165     private void setupRefreshTimer(int refreshInterval) {
166         ScheduledFuture<?> timer = refreshTimer;
167
168         if (timer != null) {
169             timer.cancel(true);
170             refreshTimer = null;
171         }
172
173         if (refreshInterval == 0) {
174             return;
175         }
176
177         refreshTimer = scheduler.scheduleWithFixedDelay(() -> {
178             logger.debug("Timer started");
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         return status.getStatusDetail();
277     }
278
279     /**
280      * Sets the configuration parameters
281      */
282     protected void readConfig() {
283         bridgeConfig = getConfig().as(QbusConfiguration.class);
284     }
285
286     /**
287      * Get the Qbus communication object.
288      *
289      * @return Qbus communication object
290      */
291     public @Nullable QbusCommunication getCommunication() {
292         return this.qbusComm;
293     }
294
295     /**
296      * Get the ip address of the Qbus server.
297      *
298      * @return the ip address
299      */
300     public @Nullable String getAddress() {
301         QbusConfiguration localConfig = this.bridgeConfig;
302
303         if (localConfig != null) {
304             return localConfig.addr;
305         } else {
306             return null;
307         }
308     }
309
310     /**
311      * Get the listening port of the Qbus server.
312      *
313      * @return
314      */
315     public @Nullable Integer getPort() {
316         QbusConfiguration localConfig = this.bridgeConfig;
317
318         if (localConfig != null) {
319             return localConfig.port;
320         } else {
321             return null;
322         }
323     }
324
325     /**
326      * Get the serial nr of the Qbus server.
327      *
328      * @return the serial nr of the controller
329      */
330     public @Nullable String getSn() {
331         QbusConfiguration localConfig = this.bridgeConfig;
332
333         if (localConfig != null) {
334             return localConfig.sn;
335         } else {
336             return null;
337         }
338     }
339
340     /**
341      * Get the refresh interval.
342      *
343      * @return the refresh interval
344      */
345     public @Nullable Integer getServerCheck() {
346         QbusConfiguration localConfig = this.bridgeConfig;
347
348         if (localConfig != null) {
349             return localConfig.serverCheck;
350         } else {
351             return null;
352         }
353     }
354
355     @Override
356     public void handleCommand(ChannelUID channelUID, Command command) {
357     }
358 }