]> git.basschouten.com Git - openhab-addons.git/blob
713c3c480c47a7fb361f2ae9597104e2169df253
[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 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             logger.debug("Timer started");
180             QbusCommunication comm = getCommunication();
181             Integer serverCheck = getServerCheck();
182
183             if (comm != null) {
184                 if (serverCheck != null) {
185                     if (!comm.communicationActive()) {
186                         // Disconnected from Qbus Server, restart communication
187                         try {
188                             comm.startCommunication();
189                         } catch (InterruptedException e) {
190                             String msg = e.getMessage();
191                             bridgeOffline(ThingStatusDetail.COMMUNICATION_ERROR,
192                                     "Communication wit Qbus server could not be established, will try to reconnect every "
193                                             + serverCheck + " minutes. InterruptedException: " + msg);
194                         } catch (IOException e) {
195                             String msg = e.getMessage();
196                             bridgeOffline(ThingStatusDetail.COMMUNICATION_ERROR,
197                                     "Communication wit Qbus server could not be established, will try to reconnect every "
198                                             + serverCheck + " minutes. IOException: " + msg);
199                         }
200                     }
201                 }
202             }
203         }, refreshInterval, refreshInterval, TimeUnit.MINUTES);
204     }
205
206     /**
207      * Disposes the Bridge and stops communication with the Qbus server
208      */
209     @Override
210     public void dispose() {
211         ScheduledFuture<?> timer = refreshTimer;
212         if (timer != null) {
213             timer.cancel(true);
214         }
215
216         refreshTimer = null;
217
218         QbusCommunication comm = getCommunication();
219
220         if (comm != null) {
221             try {
222                 comm.stopCommunication();
223             } catch (IOException e) {
224                 String message = e.toString();
225                 logger.debug("Error on stopping communication.{} ", message);
226             }
227         }
228
229         comm = null;
230     }
231
232     /**
233      * Reconnect to Qbus server if controller is offline
234      */
235     public void ctdOffline() {
236         bridgePending("Waiting for CTD connection");
237     }
238
239     /**
240      * Get BridgeCommunication
241      *
242      * @return BridgeCommunication
243      */
244     public @Nullable QbusCommunication getQbusCommunication() {
245         if (this.qbusComm != null) {
246             return this.qbusComm;
247         } else {
248             return null;
249         }
250     }
251
252     /**
253      * Sets BridgeCommunication
254      *
255      * @param BridgeCommunication
256      */
257     void setQbusCommunication(QbusCommunication comm) {
258         this.qbusComm = comm;
259     }
260
261     /**
262      * Gets the status off the Bridge
263      *
264      * @return
265      */
266     public ThingStatus getStatus() {
267         return thing.getStatus();
268     }
269
270     /**
271      * Gets the status off the Bridge
272      *
273      * @return
274      */
275     public ThingStatusDetail getStatusDetails() {
276         ThingStatusInfo status = thing.getStatusInfo();
277         return status.getStatusDetail();
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 }