]> git.basschouten.com Git - openhab-addons.git/blob
0337ee1e805a1febade7c02954b6e59f810b3189
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 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.handler;
14
15 import static org.openhab.binding.qbus.internal.QbusBindingConstants.CHANNEL_SWITCH;
16 import static org.openhab.core.types.RefreshType.REFRESH;
17
18 import java.io.IOException;
19 import java.util.Map;
20
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;
34
35 /**
36  * The {@link QbusBistabielHandler} is responsible for handling the Bistable outputs of Qbus
37  *
38  * @author Koen Schockaert - Initial Contribution
39  */
40
41 @NonNullByDefault
42 public class QbusBistabielHandler extends QbusGlobalHandler {
43
44     private final Logger logger = LoggerFactory.getLogger(QbusBistabielHandler.class);
45
46     protected @Nullable QbusThingsConfig bistabielConfig = new QbusThingsConfig();
47
48     private @Nullable Integer bistabielId;
49
50     private @Nullable String sn;
51
52     public QbusBistabielHandler(Thing thing) {
53         super(thing);
54     }
55
56     /**
57      * Main initialization
58      */
59     @Override
60     public void initialize() {
61         readConfig();
62
63         this.bistabielId = getId();
64
65         setSN();
66
67         scheduler.submit(() -> {
68             QbusCommunication controllerComm;
69
70             if (this.bistabielId != null) {
71                 controllerComm = getCommunication("Bistabiel", this.bistabielId);
72             } else {
73                 thingOffline(ThingStatusDetail.CONFIGURATION_ERROR, "ID for BISTABIEL no set! " + this.bistabielId);
74                 return;
75             }
76
77             if (controllerComm == null) {
78                 thingOffline(ThingStatusDetail.CONFIGURATION_ERROR,
79                         "ID for BISTABIEL not known in controller " + this.bistabielId);
80                 return;
81             }
82
83             Map<Integer, QbusBistabiel> bistabielCommLocal = controllerComm.getBistabiel();
84
85             QbusBistabiel outputLocal = bistabielCommLocal.get(this.bistabielId);
86
87             if (outputLocal == null) {
88                 thingOffline(ThingStatusDetail.CONFIGURATION_ERROR,
89                         "Bridge could not initialize BISTABIEL ID " + this.bistabielId);
90                 return;
91             }
92
93             outputLocal.setThingHandler(this);
94             handleStateUpdate(outputLocal);
95
96             QbusBridgeHandler qBridgeHandler = getBridgeHandler("Bistabiel", this.bistabielId);
97
98             if (qBridgeHandler != null) {
99                 if (qBridgeHandler.getStatus() == ThingStatus.ONLINE) {
100                     updateStatus(ThingStatus.ONLINE);
101                 } else {
102                     updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE,
103                             "Bridge offline for BISTABIEL ID " + this.bistabielId);
104                 }
105             }
106         });
107     }
108
109     /**
110      * Handle the status update from the bistabiel
111      */
112     @Override
113     public void handleCommand(ChannelUID channelUID, Command command) {
114         QbusCommunication qComm = getCommunication("Bistabiel", this.bistabielId);
115
116         if (qComm == null) {
117             thingOffline(ThingStatusDetail.CONFIGURATION_ERROR,
118                     "ID for BISTABIEL not known in controller " + this.bistabielId);
119             return;
120         } else {
121             Map<Integer, QbusBistabiel> bistabielComm = qComm.getBistabiel();
122
123             QbusBistabiel qBistabiel = bistabielComm.get(this.bistabielId);
124
125             if (qBistabiel == null) {
126                 thingOffline(ThingStatusDetail.CONFIGURATION_ERROR,
127                         "ID for BISTABIEL not known in controller " + this.bistabielId);
128                 return;
129             } else {
130                 scheduler.submit(() -> {
131                     if (!qComm.communicationActive()) {
132                         restartCommunication(qComm, "Bistabiel", this.bistabielId);
133                     }
134
135                     if (qComm.communicationActive()) {
136                         if (command == REFRESH) {
137                             handleStateUpdate(qBistabiel);
138                             return;
139                         }
140
141                         switch (channelUID.getId()) {
142                             case CHANNEL_SWITCH:
143                                 try {
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();
151                                     logger.warn(
152                                             "Error on executing Switch for bistabiel ID {}. Interruptedexception {}",
153                                             this.bistabielId, message);
154                                 }
155                                 break;
156
157                             default:
158                                 thingOffline(ThingStatusDetail.COMMUNICATION_ERROR,
159                                         "Unknown Channel " + channelUID.getId());
160                         }
161                     }
162                 });
163             }
164         }
165     }
166
167     /**
168      * Executes the switch command
169      *
170      * @throws IOException
171      * @throws InterruptedException
172      */
173     private void handleSwitchCommand(QbusBistabiel qBistabiel, Command command)
174             throws InterruptedException, IOException {
175         String snr = getSN();
176         if (snr != null) {
177             if (command instanceof OnOffType) {
178                 if (command == OnOffType.OFF) {
179                     qBistabiel.execute(0, snr);
180                 } else {
181                     qBistabiel.execute(100, snr);
182                 }
183             } else {
184                 thingOffline(ThingStatusDetail.CONFIGURATION_ERROR,
185                         "No serial number configured for BISTABIEL " + this.bistabielId);
186             }
187         }
188     }
189
190     /**
191      * Method to update state of channel, called from Qbus Bistabiel.
192      *
193      * @param qBistabiel
194      */
195     public void handleStateUpdate(QbusBistabiel qBistabiel) {
196         Integer bistabielState = qBistabiel.getState();
197         if (bistabielState != null) {
198             updateState(CHANNEL_SWITCH, OnOffType.from(bistabielState != 0));
199         }
200     }
201
202     /**
203      * Returns the serial number of the controller
204      *
205      * @return the serial nr
206      */
207     public @Nullable String getSN() {
208         return sn;
209     }
210
211     /**
212      * Sets the serial number of the controller
213      */
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);
219             return;
220         }
221         sn = qBridgeHandler.getSn();
222     }
223
224     /**
225      * Read the configuration
226      */
227     protected synchronized void readConfig() {
228         bistabielConfig = getConfig().as(QbusThingsConfig.class);
229     }
230
231     /**
232      * Returns the Id from the configuration
233      *
234      * @return outputId
235      */
236     public @Nullable Integer getId() {
237         QbusThingsConfig localConfig = bistabielConfig;
238         if (localConfig != null) {
239             return localConfig.bistabielId;
240         } else {
241             return null;
242         }
243     }
244 }