2 * Copyright (c) 2010-2024 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
13 package org.openhab.binding.qbus.internal;
15 import java.io.IOException;
16 import java.util.concurrent.ScheduledFuture;
17 import java.util.concurrent.TimeUnit;
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;
33 * {@link QbusBridgeHandler} is the handler for a Qbus controller
35 * @author Koen Schockaert - Initial Contribution
39 public class QbusBridgeHandler extends BaseBridgeHandler {
41 private @Nullable QbusCommunication qbusComm;
43 protected @Nullable QbusConfiguration bridgeConfig = new QbusConfiguration();
45 private @Nullable ScheduledFuture<?> refreshTimer;
47 private final Logger logger = LoggerFactory.getLogger(QbusBridgeHandler.class);
49 public QbusBridgeHandler(Bridge Bridge) {
54 * Initialize the bridge
57 public void initialize() {
60 Integer serverCheck = getServerCheck();
62 if (serverCheck != null) {
63 this.setupRefreshTimer(serverCheck);
66 createCommunicationObject();
70 * Sets the Bridge call back
72 private void setBridgeCallBack() {
73 QbusCommunication qbusCommunication = getQbusCommunication();
74 if (qbusCommunication != null) {
75 qbusCommunication.setBridgeCallBack(this);
80 * Create communication object to Qbus server and start communication.
82 * @param addr : IP address of Qbus server
83 * @param port : Communication port of QbusServer
85 private void createCommunicationObject() {
86 scheduler.submit(() -> {
88 setQbusCommunication(new QbusCommunication(thing));
90 QbusCommunication qbusCommunication = getQbusCommunication();
94 Integer serverCheck = getServerCheck();
96 if (serverCheck != null) {
98 if (qbusCommunication != null) {
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);
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);
115 if (!qbusCommunication.communicationActive()) {
116 bridgeOffline(ThingStatusDetail.COMMUNICATION_ERROR,
117 "No communication with Qbus Server, will try to reconnect every " + serverCheck
122 if (!qbusCommunication.clientConnected()) {
123 bridgePending("Waiting for Qbus client to come online");
134 * Updates offline status off the Bridge when an error occurs.
139 public void bridgeOffline(ThingStatusDetail detail, String message) {
140 updateStatus(ThingStatus.OFFLINE, detail, message);
144 * Updates pending status off the Bridge (usualay when Qbus client id not connected)
148 public void bridgePending(String message) {
149 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.HANDLER_CONFIGURATION_PENDING, message);
153 * Put bridge online when error in communication resolved.
155 public void bridgeOnline() {
156 updateStatus(ThingStatus.ONLINE);
160 * Initializes a timer that check the communication with Qbus server/client and tries to re-establish communication.
162 * @param refreshInterval Time before refresh in minutes.
164 private void setupRefreshTimer(int refreshInterval) {
165 ScheduledFuture<?> timer = refreshTimer;
172 if (refreshInterval == 0) {
176 refreshTimer = scheduler.scheduleWithFixedDelay(() -> {
177 logger.debug("Timer started");
178 QbusCommunication comm = getCommunication();
179 Integer serverCheck = getServerCheck();
182 if (serverCheck != null) {
183 if (!comm.communicationActive()) {
184 // Disconnected from Qbus Server, restart communication
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);
201 }, refreshInterval, refreshInterval, TimeUnit.MINUTES);
205 * Disposes the Bridge and stops communication with the Qbus server
208 public void dispose() {
209 ScheduledFuture<?> timer = refreshTimer;
216 QbusCommunication comm = getCommunication();
220 comm.stopCommunication();
221 } catch (IOException e) {
222 String message = e.toString();
223 logger.debug("Error on stopping communication.{} ", message);
231 * Reconnect to Qbus server if controller is offline
233 public void ctdOffline() {
234 bridgePending("Waiting for CTD connection");
238 * Get BridgeCommunication
240 * @return BridgeCommunication
242 public @Nullable QbusCommunication getQbusCommunication() {
243 if (this.qbusComm != null) {
244 return this.qbusComm;
251 * Sets BridgeCommunication
253 * @param BridgeCommunication
255 void setQbusCommunication(QbusCommunication comm) {
256 this.qbusComm = comm;
260 * Gets the status off the Bridge
264 public ThingStatus getStatus() {
265 return thing.getStatus();
269 * Gets the status off the Bridge
273 public ThingStatusDetail getStatusDetails() {
274 ThingStatusInfo status = thing.getStatusInfo();
275 return status.getStatusDetail();
279 * Sets the configuration parameters
281 protected void readConfig() {
282 bridgeConfig = getConfig().as(QbusConfiguration.class);
286 * Get the Qbus communication object.
288 * @return Qbus communication object
290 public @Nullable QbusCommunication getCommunication() {
291 return this.qbusComm;
295 * Get the ip address of the Qbus server.
297 * @return the ip address
299 public @Nullable String getAddress() {
300 QbusConfiguration localConfig = this.bridgeConfig;
302 if (localConfig != null) {
303 return localConfig.addr;
310 * Get the listening port of the Qbus server.
314 public @Nullable Integer getPort() {
315 QbusConfiguration localConfig = this.bridgeConfig;
317 if (localConfig != null) {
318 return localConfig.port;
325 * Get the serial nr of the Qbus server.
327 * @return the serial nr of the controller
329 public @Nullable String getSn() {
330 QbusConfiguration localConfig = this.bridgeConfig;
332 if (localConfig != null) {
333 return localConfig.sn;
340 * Get the refresh interval.
342 * @return the refresh interval
344 public @Nullable Integer getServerCheck() {
345 QbusConfiguration localConfig = this.bridgeConfig;
347 if (localConfig != null) {
348 return localConfig.serverCheck;
355 public void handleCommand(ChannelUID channelUID, Command command) {