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