2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
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
11 * SPDX-License-Identifier: EPL-2.0
14 package org.openhab.binding.qbus.internal;
16 import java.io.IOException;
17 import java.util.concurrent.ScheduledFuture;
18 import java.util.concurrent.TimeUnit;
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;
34 * {@link QbusBridgeHandler} is the handler for a Qbus controller
36 * @author Koen Schockaert - Initial Contribution
40 public class QbusBridgeHandler extends BaseBridgeHandler {
42 private @Nullable QbusCommunication qbusComm;
44 protected @Nullable QbusConfiguration bridgeConfig = new QbusConfiguration();
46 private @Nullable ScheduledFuture<?> refreshTimer;
48 private final Logger logger = LoggerFactory.getLogger(QbusBridgeHandler.class);
50 public QbusBridgeHandler(Bridge Bridge) {
55 * Initialize the bridge
58 public void initialize() {
61 Integer serverCheck = getServerCheck();
63 if (serverCheck != null) {
64 this.setupRefreshTimer(serverCheck);
67 createCommunicationObject();
71 * Sets the Bridge call back
73 private void setBridgeCallBack() {
74 QbusCommunication qbusCommunication = getQbusCommunication();
75 if (qbusCommunication != null) {
76 qbusCommunication.setBridgeCallBack(this);
81 * Create communication object to Qbus server and start communication.
83 * @param addr : IP address of Qbus server
84 * @param port : Communication port of QbusServer
86 private void createCommunicationObject() {
87 scheduler.submit(() -> {
89 setQbusCommunication(new QbusCommunication(thing));
91 QbusCommunication qbusCommunication = getQbusCommunication();
95 Integer serverCheck = getServerCheck();
97 if (serverCheck != null) {
99 if (qbusCommunication != null) {
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);
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);
116 if (!qbusCommunication.communicationActive()) {
117 bridgeOffline(ThingStatusDetail.COMMUNICATION_ERROR,
118 "No communication with Qbus Server, will try to reconnect every " + serverCheck
123 if (!qbusCommunication.clientConnected()) {
124 bridgePending("Waiting for Qbus client to come online");
135 * Updates offline status off the Bridge when an error occurs.
140 public void bridgeOffline(ThingStatusDetail detail, String message) {
141 updateStatus(ThingStatus.OFFLINE, detail, message);
145 * Updates pending status off the Bridge (usualay when Qbus client id not connected)
149 public void bridgePending(String message) {
150 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.HANDLER_CONFIGURATION_PENDING, message);
154 * Put bridge online when error in communication resolved.
156 public void bridgeOnline() {
157 updateStatus(ThingStatus.ONLINE);
161 * Initializes a timer that check the communication with Qbus server/client and tries to re-establish communication.
163 * @param refreshInterval Time before refresh in minutes.
165 private void setupRefreshTimer(int refreshInterval) {
166 ScheduledFuture<?> timer = refreshTimer;
173 if (refreshInterval == 0) {
177 refreshTimer = scheduler.scheduleWithFixedDelay(() -> {
178 logger.debug("Timer started");
179 QbusCommunication comm = getCommunication();
180 Integer serverCheck = getServerCheck();
183 if (serverCheck != null) {
184 if (!comm.communicationActive()) {
185 // Disconnected from Qbus Server, restart communication
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);
202 }, refreshInterval, refreshInterval, TimeUnit.MINUTES);
206 * Disposes the Bridge and stops communication with the Qbus server
209 public void dispose() {
210 ScheduledFuture<?> timer = refreshTimer;
217 QbusCommunication comm = getCommunication();
221 comm.stopCommunication();
222 } catch (IOException e) {
223 String message = e.toString();
224 logger.debug("Error on stopping communication.{} ", message);
232 * Reconnect to Qbus server if controller is offline
234 public void ctdOffline() {
235 bridgePending("Waiting for CTD connection");
239 * Get BridgeCommunication
241 * @return BridgeCommunication
243 public @Nullable QbusCommunication getQbusCommunication() {
244 if (this.qbusComm != null) {
245 return this.qbusComm;
252 * Sets BridgeCommunication
254 * @param BridgeCommunication
256 void setQbusCommunication(QbusCommunication comm) {
257 this.qbusComm = comm;
261 * Gets the status off the Bridge
265 public ThingStatus getStatus() {
266 return thing.getStatus();
270 * Gets the status off the Bridge
274 public ThingStatusDetail getStatusDetails() {
275 ThingStatusInfo status = thing.getStatusInfo();
276 return status.getStatusDetail();
280 * Sets the configuration parameters
282 protected void readConfig() {
283 bridgeConfig = getConfig().as(QbusConfiguration.class);
287 * Get the Qbus communication object.
289 * @return Qbus communication object
291 public @Nullable QbusCommunication getCommunication() {
292 return this.qbusComm;
296 * Get the ip address of the Qbus server.
298 * @return the ip address
300 public @Nullable String getAddress() {
301 QbusConfiguration localConfig = this.bridgeConfig;
303 if (localConfig != null) {
304 return localConfig.addr;
311 * Get the listening port of the Qbus server.
315 public @Nullable Integer getPort() {
316 QbusConfiguration localConfig = this.bridgeConfig;
318 if (localConfig != null) {
319 return localConfig.port;
326 * Get the serial nr of the Qbus server.
328 * @return the serial nr of the controller
330 public @Nullable String getSn() {
331 QbusConfiguration localConfig = this.bridgeConfig;
333 if (localConfig != null) {
334 return localConfig.sn;
341 * Get the refresh interval.
343 * @return the refresh interval
345 public @Nullable Integer getServerCheck() {
346 QbusConfiguration localConfig = this.bridgeConfig;
348 if (localConfig != null) {
349 return localConfig.serverCheck;
356 public void handleCommand(ChannelUID channelUID, Command command) {