]> git.basschouten.com Git - openhab-addons.git/blob
495390c212a2851636f01c0e5ce14a3b551a1af2
[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_SCENE;
16
17 import java.io.IOException;
18 import java.util.Map;
19
20 import org.eclipse.jdt.annotation.NonNullByDefault;
21 import org.eclipse.jdt.annotation.Nullable;
22 import org.openhab.binding.qbus.internal.QbusBridgeHandler;
23 import org.openhab.binding.qbus.internal.protocol.QbusCommunication;
24 import org.openhab.binding.qbus.internal.protocol.QbusScene;
25 import org.openhab.core.library.types.OnOffType;
26 import org.openhab.core.thing.ChannelUID;
27 import org.openhab.core.thing.Thing;
28 import org.openhab.core.thing.ThingStatus;
29 import org.openhab.core.thing.ThingStatusDetail;
30 import org.openhab.core.types.Command;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33
34 /**
35  * The {@link QbusSceneHandler} is responsible for handling commands, which are
36  * sent to one of the channels.
37  *
38  * @author Koen Schockaert - Initial Contribution
39  */
40
41 @NonNullByDefault
42 public class QbusSceneHandler extends QbusGlobalHandler {
43
44     private final Logger logger = LoggerFactory.getLogger(QbusSceneHandler.class);
45
46     protected @Nullable QbusThingsConfig sceneConfig = new QbusThingsConfig();
47
48     private @Nullable Integer sceneId;
49
50     private @Nullable String sn;
51
52     public QbusSceneHandler(Thing thing) {
53         super(thing);
54     }
55
56     /**
57      * Main initialization
58      */
59     @Override
60     public void initialize() {
61         readConfig();
62
63         this.sceneId = getId();
64
65         setSN();
66
67         scheduler.submit(() -> {
68             QbusCommunication controllerComm;
69
70             if (this.sceneId != null) {
71                 controllerComm = getCommunication("Scene", this.sceneId);
72             } else {
73                 thingOffline(ThingStatusDetail.CONFIGURATION_ERROR, "ID for SCENE no set! " + this.sceneId);
74                 return;
75             }
76
77             if (controllerComm == null) {
78                 thingOffline(ThingStatusDetail.CONFIGURATION_ERROR,
79                         "ID for SCENE not known in controller " + this.sceneId);
80                 return;
81             }
82
83             Map<Integer, QbusScene> sceneCommLocal = controllerComm.getScene();
84
85             QbusScene outputLocal = sceneCommLocal.get(this.sceneId);
86
87             if (outputLocal == null) {
88                 thingOffline(ThingStatusDetail.CONFIGURATION_ERROR,
89                         "Bridge could not initialize SCENE ID " + this.sceneId);
90                 return;
91             }
92
93             outputLocal.setThingHandler(this);
94
95             QbusBridgeHandler qBridgeHandler = getBridgeHandler("Scene", this.sceneId);
96
97             if ((qBridgeHandler != null) && (qBridgeHandler.getStatus() == ThingStatus.ONLINE)) {
98                 updateStatus(ThingStatus.ONLINE);
99             } else {
100                 thingOffline(ThingStatusDetail.COMMUNICATION_ERROR, "Bridge offline for SCENE ID " + this.sceneId);
101             }
102         });
103     }
104
105     /**
106      * Handle the status update from the thing
107      */
108     @Override
109     public void handleCommand(ChannelUID channelUID, Command command) {
110         QbusCommunication qComm = getCommunication("Scene", this.sceneId);
111
112         if (qComm == null) {
113             thingOffline(ThingStatusDetail.CONFIGURATION_ERROR, "ID for SCENE not known in controller " + this.sceneId);
114             return;
115         } else {
116             Map<Integer, QbusScene> sceneComm = qComm.getScene();
117             QbusScene qScene = sceneComm.get(this.sceneId);
118
119             if (qScene == null) {
120                 thingOffline(ThingStatusDetail.CONFIGURATION_ERROR,
121                         "ID for SCENE not known in controller " + this.sceneId);
122                 return;
123             } else {
124                 scheduler.submit(() -> {
125                     if (!qComm.communicationActive()) {
126                         restartCommunication(qComm, "Scene", this.sceneId);
127                     }
128
129                     if (qComm.communicationActive()) {
130                         switch (channelUID.getId()) {
131                             case CHANNEL_SCENE:
132                                 try {
133                                     handleSwitchCommand(qScene, channelUID, command);
134                                 } catch (IOException e) {
135                                     String message = e.getMessage();
136                                     logger.warn("Error on executing Scene for scene ID {}. IOException: {}",
137                                             this.sceneId, message);
138                                 } catch (InterruptedException e) {
139                                     String message = e.getMessage();
140                                     logger.warn("Error on executing Scene for scene ID {}. Interruptedexception {}",
141                                             this.sceneId, message);
142                                 }
143                                 break;
144
145                             default:
146                                 thingOffline(ThingStatusDetail.COMMUNICATION_ERROR,
147                                         "Unknown Channel " + channelUID.getId());
148                         }
149                     }
150                 });
151             }
152         }
153     }
154
155     /**
156      * Executes the scene command
157      *
158      * @throws IOException
159      * @throws InterruptedException
160      */
161     void handleSwitchCommand(QbusScene qScene, ChannelUID channelUID, Command command)
162             throws InterruptedException, IOException {
163         String snr = getSN();
164         if (snr != null) {
165             if (command instanceof OnOffType) {
166                 if (command == OnOffType.OFF) {
167                     qScene.execute(0, snr);
168                 } else {
169                     qScene.execute(100, snr);
170                 }
171             }
172         }
173     }
174
175     /**
176      * Returns the serial number of the controller
177      *
178      * @return the serial nr
179      */
180     public @Nullable String getSN() {
181         return sn;
182     }
183
184     /**
185      * Sets the serial number of the controller
186      */
187     public void setSN() {
188         QbusBridgeHandler qBridgeHandler = getBridgeHandler("Scene", this.sceneId);
189         if (qBridgeHandler == null) {
190             thingOffline(ThingStatusDetail.COMMUNICATION_ERROR,
191                     "No communication with Qbus Bridge for SCENE " + this.sceneId);
192             return;
193         }
194         sn = qBridgeHandler.getSn();
195     }
196
197     /**
198      * Read the configuration
199      */
200     protected synchronized void readConfig() {
201         sceneConfig = getConfig().as(QbusThingsConfig.class);
202     }
203
204     /**
205      * Returns the Id from the configuration
206      *
207      * @return outputId
208      */
209     public @Nullable Integer getId() {
210         QbusThingsConfig localConfig = sceneConfig;
211         if (localConfig != null) {
212             return localConfig.sceneId;
213         } else {
214             return null;
215         }
216     }
217 }