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.
141 public void bridgeOffline(ThingStatusDetail detail, String message) {
142 updateStatus(ThingStatus.OFFLINE, detail, message);
146 * Updates pending status off the Bridge (usualay when Qbus client id not connected)
150 public void bridgePending(String message) {
151 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.HANDLER_CONFIGURATION_PENDING, message);
155 * Put bridge online when error in communication resolved.
157 public void bridgeOnline() {
158 updateStatus(ThingStatus.ONLINE);
162 * Initializes a timer that check the communication with Qbus server/client and tries to re-establish communication.
164 * @param refreshInterval Time before refresh in minutes.
166 private void setupRefreshTimer(int refreshInterval) {
167 ScheduledFuture<?> timer = refreshTimer;
174 if (refreshInterval == 0) {
178 refreshTimer = scheduler.scheduleWithFixedDelay(() -> {
179 logger.debug("Timer started");
180 QbusCommunication comm = getCommunication();
181 Integer serverCheck = getServerCheck();
184 if (serverCheck != null) {
185 if (!comm.communicationActive()) {
186 // Disconnected from Qbus Server, restart communication
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);
203 }, refreshInterval, refreshInterval, TimeUnit.MINUTES);
207 * Disposes the Bridge and stops communication with the Qbus server
210 public void dispose() {
211 ScheduledFuture<?> timer = refreshTimer;
218 QbusCommunication comm = getCommunication();
222 comm.stopCommunication();
223 } catch (IOException e) {
224 String message = e.toString();
225 logger.debug("Error on stopping communication.{} ", message);
233 * Reconnect to Qbus server if controller is offline
235 public void ctdOffline() {
236 bridgePending("Waiting for CTD connection");
240 * Get BridgeCommunication
242 * @return BridgeCommunication
244 public @Nullable QbusCommunication getQbusCommunication() {
245 if (this.qbusComm != null) {
246 return this.qbusComm;
253 * Sets BridgeCommunication
255 * @param BridgeCommunication
257 void setQbusCommunication(QbusCommunication comm) {
258 this.qbusComm = comm;
262 * Gets the status off the Bridge
266 public ThingStatus getStatus() {
267 return thing.getStatus();
271 * Gets the status off the Bridge
275 public ThingStatusDetail getStatusDetails() {
276 ThingStatusInfo status = thing.getStatusInfo();
277 return status.getStatusDetail();
281 * Sets the configuration parameters
283 protected void readConfig() {
284 bridgeConfig = getConfig().as(QbusConfiguration.class);
288 * Get the Qbus communication object.
290 * @return Qbus communication object
292 public @Nullable QbusCommunication getCommunication() {
293 return this.qbusComm;
297 * Get the ip address of the Qbus server.
299 * @return the ip address
301 public @Nullable String getAddress() {
302 QbusConfiguration localConfig = this.bridgeConfig;
304 if (localConfig != null) {
305 return localConfig.addr;
312 * Get the listening port of the Qbus server.
316 public @Nullable Integer getPort() {
317 QbusConfiguration localConfig = this.bridgeConfig;
319 if (localConfig != null) {
320 return localConfig.port;
327 * Get the serial nr of the Qbus server.
329 * @return the serial nr of the controller
331 public @Nullable String getSn() {
332 QbusConfiguration localConfig = this.bridgeConfig;
334 if (localConfig != null) {
335 return localConfig.sn;
342 * Get the refresh interval.
344 * @return the refresh interval
346 public @Nullable Integer getServerCheck() {
347 QbusConfiguration localConfig = this.bridgeConfig;
349 if (localConfig != null) {
350 return localConfig.serverCheck;
357 public void handleCommand(ChannelUID channelUID, Command command) {