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
13 package org.openhab.binding.qbus.internal.handler;
15 import static org.openhab.binding.qbus.internal.QbusBindingConstants.CHANNEL_SWITCH;
16 import static org.openhab.core.types.RefreshType.REFRESH;
18 import java.io.IOException;
21 import org.eclipse.jdt.annotation.NonNullByDefault;
22 import org.eclipse.jdt.annotation.Nullable;
23 import org.openhab.binding.qbus.internal.QbusBridgeHandler;
24 import org.openhab.binding.qbus.internal.protocol.QbusBistabiel;
25 import org.openhab.binding.qbus.internal.protocol.QbusCommunication;
26 import org.openhab.core.library.types.OnOffType;
27 import org.openhab.core.thing.ChannelUID;
28 import org.openhab.core.thing.Thing;
29 import org.openhab.core.thing.ThingStatus;
30 import org.openhab.core.thing.ThingStatusDetail;
31 import org.openhab.core.types.Command;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
36 * The {@link QbusBistabielHandler} is responsible for handling the Bistable outputs of Qbus
38 * @author Koen Schockaert - Initial Contribution
42 public class QbusBistabielHandler extends QbusGlobalHandler {
44 private final Logger logger = LoggerFactory.getLogger(QbusBistabielHandler.class);
46 protected @Nullable QbusThingsConfig bistabielConfig = new QbusThingsConfig();
48 private @Nullable Integer bistabielId;
50 private @Nullable String sn;
52 public QbusBistabielHandler(Thing thing) {
60 public void initialize() {
63 this.bistabielId = getId();
67 scheduler.submit(() -> {
68 QbusCommunication controllerComm;
70 if (this.bistabielId != null) {
71 controllerComm = getCommunication("Bistabiel", this.bistabielId);
73 thingOffline(ThingStatusDetail.CONFIGURATION_ERROR, "ID for BISTABIEL no set! " + this.bistabielId);
77 if (controllerComm == null) {
78 thingOffline(ThingStatusDetail.CONFIGURATION_ERROR,
79 "ID for BISTABIEL not known in controller " + this.bistabielId);
83 Map<Integer, QbusBistabiel> bistabielCommLocal = controllerComm.getBistabiel();
85 QbusBistabiel outputLocal = bistabielCommLocal.get(this.bistabielId);
87 if (outputLocal == null) {
88 thingOffline(ThingStatusDetail.CONFIGURATION_ERROR,
89 "Bridge could not initialize BISTABIEL ID " + this.bistabielId);
93 outputLocal.setThingHandler(this);
94 handleStateUpdate(outputLocal);
96 QbusBridgeHandler qBridgeHandler = getBridgeHandler("Bistabiel", this.bistabielId);
98 if (qBridgeHandler != null) {
99 if (qBridgeHandler.getStatus() == ThingStatus.ONLINE) {
100 updateStatus(ThingStatus.ONLINE);
102 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE,
103 "Bridge offline for BISTABIEL ID " + this.bistabielId);
110 * Handle the status update from the bistabiel
113 public void handleCommand(ChannelUID channelUID, Command command) {
114 QbusCommunication qComm = getCommunication("Bistabiel", this.bistabielId);
117 thingOffline(ThingStatusDetail.CONFIGURATION_ERROR,
118 "ID for BISTABIEL not known in controller " + this.bistabielId);
121 Map<Integer, QbusBistabiel> bistabielComm = qComm.getBistabiel();
123 QbusBistabiel qBistabiel = bistabielComm.get(this.bistabielId);
125 if (qBistabiel == null) {
126 thingOffline(ThingStatusDetail.CONFIGURATION_ERROR,
127 "ID for BISTABIEL not known in controller " + this.bistabielId);
130 scheduler.submit(() -> {
131 if (!qComm.communicationActive()) {
132 restartCommunication(qComm, "Bistabiel", this.bistabielId);
135 if (qComm.communicationActive()) {
136 if (command == REFRESH) {
137 handleStateUpdate(qBistabiel);
141 switch (channelUID.getId()) {
144 handleSwitchCommand(qBistabiel, command);
145 } catch (IOException e) {
146 String message = e.getMessage();
147 logger.warn("Error on executing Switch for bistabiel ID {}. IOException: {}",
148 this.bistabielId, message);
149 } catch (InterruptedException e) {
150 String message = e.getMessage();
152 "Error on executing Switch for bistabiel ID {}. Interruptedexception {}",
153 this.bistabielId, message);
158 thingOffline(ThingStatusDetail.COMMUNICATION_ERROR,
159 "Unknown Channel " + channelUID.getId());
168 * Executes the switch command
170 * @throws IOException
171 * @throws InterruptedException
173 private void handleSwitchCommand(QbusBistabiel qBistabiel, Command command)
174 throws InterruptedException, IOException {
175 String snr = getSN();
177 if (command instanceof OnOffType) {
178 if (command == OnOffType.OFF) {
179 qBistabiel.execute(0, snr);
181 qBistabiel.execute(100, snr);
184 thingOffline(ThingStatusDetail.CONFIGURATION_ERROR,
185 "No serial number configured for BISTABIEL " + this.bistabielId);
191 * Method to update state of channel, called from Qbus Bistabiel.
195 public void handleStateUpdate(QbusBistabiel qBistabiel) {
196 Integer bistabielState = qBistabiel.getState();
197 if (bistabielState != null) {
198 updateState(CHANNEL_SWITCH, OnOffType.from(bistabielState != 0));
203 * Returns the serial number of the controller
205 * @return the serial nr
207 public @Nullable String getSN() {
212 * Sets the serial number of the controller
214 public void setSN() {
215 QbusBridgeHandler qBridgeHandler = getBridgeHandler("Bistabiel", this.bistabielId);
216 if (qBridgeHandler == null) {
217 thingOffline(ThingStatusDetail.COMMUNICATION_ERROR,
218 "No communication with Qbus Bridge for BISTABIEL " + this.bistabielId);
221 sn = qBridgeHandler.getSn();
225 * Read the configuration
227 protected synchronized void readConfig() {
228 bistabielConfig = getConfig().as(QbusThingsConfig.class);
232 * Returns the Id from the configuration
236 public @Nullable Integer getId() {
237 QbusThingsConfig localConfig = bistabielConfig;
238 if (localConfig != null) {
239 return localConfig.bistabielId;