]> git.basschouten.com Git - openhab-addons.git/blob
5f81329edd0577086270c172e3777aaa193ccf57
[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.plugwiseha.internal.handler;
14
15 import static org.openhab.core.thing.ThingStatus.*;
16
17 import java.lang.reflect.ParameterizedType;
18
19 import org.eclipse.jdt.annotation.NonNullByDefault;
20 import org.eclipse.jdt.annotation.Nullable;
21 import org.openhab.binding.plugwiseha.internal.api.exception.PlugwiseHAException;
22 import org.openhab.binding.plugwiseha.internal.api.model.PlugwiseHAController;
23 import org.openhab.binding.plugwiseha.internal.config.PlugwiseHAThingConfig;
24 import org.openhab.core.thing.Bridge;
25 import org.openhab.core.thing.Channel;
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.thing.ThingStatusInfo;
31 import org.openhab.core.thing.binding.BaseThingHandler;
32 import org.openhab.core.types.Command;
33 import org.openhab.core.types.RefreshType;
34 import org.openhab.core.types.UnDefType;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37
38 /**
39  * The {@link PlugwiseHABaseHandler} abstract class provides common methods and
40  * properties for the ThingHandlers of this binding. Extends @{link
41  * BaseThingHandler}
42  *
43  * @author Bas van Wetten - Initial contribution
44  * @author Leo Siepel - finish initial contribution
45  *
46  * @param <E> entity - the Plugwise Home Automation entity class used by this
47  *            thing handler
48  * @param <C> config - the Plugwise Home Automation config class used by this
49  *            thing handler
50  */
51
52 @NonNullByDefault
53 public abstract class PlugwiseHABaseHandler<E, C extends PlugwiseHAThingConfig> extends BaseThingHandler {
54
55     protected static final String STATUS_DESCRIPTION_COMMUNICATION_ERROR = "Error communicating with the Plugwise Home Automation controller";
56
57     protected final Logger logger = LoggerFactory.getLogger(PlugwiseHABaseHandler.class);
58
59     private Class<?> clazz;
60
61     // Constructor
62     @SuppressWarnings("null")
63     public PlugwiseHABaseHandler(Thing thing) {
64         super(thing);
65         clazz = (Class<?>) (((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[1]);
66     }
67
68     // Abstract methods
69
70     /**
71      * Initializes the Plugwise Entity that this class handles.
72      *
73      * @param config the thing configuration
74      * @param bridge the bridge that this thing is part of
75      */
76     protected abstract void initialize(C config, PlugwiseHABridgeHandler bridge);
77
78     /**
79      * Get the Plugwise Entity that belongs to this ThingHandler
80      *
81      * @param controller the controller for this ThingHandler
82      */
83     protected abstract @Nullable E getEntity(PlugwiseHAController controller) throws PlugwiseHAException;
84
85     /**
86      * Handles a {@link RefreshType} command for a given channel.
87      *
88      * @param entity the Plugwise Entity
89      * @param channelUID the channel uid the command is for
90      */
91     protected abstract void refreshChannel(E entity, ChannelUID channelUID);
92
93     /**
94      * Handles a command for a given channel.
95      * 
96      * @param entity the Plugwise Entity
97      * @param channelUID the channel uid the command is for
98      * @param command the command
99      */
100     protected abstract void handleCommand(E entity, ChannelUID channelUID, Command command) throws PlugwiseHAException;
101
102     // Overrides
103
104     @Override
105     public void initialize() {
106         C config = getPlugwiseThingConfig();
107
108         if (checkConfig(config)) {
109             Bridge bridge = getBridge();
110             if (bridge == null || bridge.getHandler() == null
111                     || !(bridge.getHandler() instanceof PlugwiseHABridgeHandler)) {
112                 updateStatus(OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
113                         "You must choose a Plugwise Home Automation bridge for this thing.");
114                 return;
115             }
116
117             if (bridge.getStatus() == OFFLINE) {
118                 updateStatus(OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE,
119                         "The Plugwise Home Automation bridge is currently offline.");
120             }
121
122             PlugwiseHABridgeHandler bridgeHandler = (PlugwiseHABridgeHandler) bridge.getHandler();
123             if (bridgeHandler != null) {
124                 initialize(config, bridgeHandler);
125             }
126         } else {
127             logger.debug("Invalid config for Plugwise Home Automation thing handler with config = {}", config);
128         }
129     }
130
131     @Override
132     public final void handleCommand(ChannelUID channelUID, Command command) {
133         logger.debug("Handling command = {} for channel = {}", command, channelUID);
134
135         if (getThing().getStatus() == ONLINE) {
136             PlugwiseHAController controller = getController();
137             if (controller != null) {
138                 try {
139                     @Nullable
140                     E entity = getEntity(controller);
141                     if (entity != null) {
142                         if (this.isLinked(channelUID)) {
143                             if (command instanceof RefreshType) {
144                                 refreshChannel(entity, channelUID);
145                             } else {
146                                 handleCommand(entity, channelUID, command);
147                             }
148                         }
149                     }
150                 } catch (PlugwiseHAException e) {
151                     logger.warn("Unexpected error handling command = {} for channel = {} : {}", command, channelUID,
152                             e.getMessage());
153                 }
154             }
155         }
156     }
157
158     // Public member methods
159
160     public @Nullable PlugwiseHABridgeHandler getPlugwiseHABridge() {
161         Bridge bridge = this.getBridge();
162         if (bridge != null) {
163             return (PlugwiseHABridgeHandler) bridge.getHandler();
164         }
165
166         return null;
167     }
168
169     @SuppressWarnings("unchecked")
170     public C getPlugwiseThingConfig() {
171         return (C) getConfigAs(clazz);
172     }
173
174     // Private & protected methods
175
176     private @Nullable PlugwiseHAController getController() {
177         PlugwiseHABridgeHandler bridgeHandler = getPlugwiseHABridge();
178
179         if (bridgeHandler != null) {
180             return bridgeHandler.getController();
181         }
182
183         return null;
184     }
185
186     /**
187      * Checks the configuration for validity, result is reflected in the status of
188      * the Thing
189      */
190     private boolean checkConfig(C config) {
191         if (!config.isValid()) {
192             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
193                     "Configuration is missing or corrupted");
194             return false;
195         } else {
196             return true;
197         }
198     }
199
200     @Override
201     public void bridgeStatusChanged(ThingStatusInfo bridgeStatusInfo) {
202         super.bridgeStatusChanged(bridgeStatusInfo);
203         if (bridgeStatusInfo.getStatus() == ThingStatus.OFFLINE) {
204             setLinkedChannelsUndef();
205         }
206     }
207
208     private void setLinkedChannelsUndef() {
209         for (Channel channel : getThing().getChannels()) {
210             ChannelUID channelUID = channel.getUID();
211             if (this.isLinked(channelUID)) {
212                 updateState(channelUID, UnDefType.UNDEF);
213             }
214         }
215     }
216
217     protected final void refresh() {
218         PlugwiseHABridgeHandler bridgeHandler = getPlugwiseHABridge();
219         if (bridgeHandler != null) {
220             if (bridgeHandler.getThing().getStatusInfo().getStatus() == ThingStatus.ONLINE) {
221                 PlugwiseHAController controller = getController();
222                 if (controller != null) {
223                     @Nullable
224                     E entity = null;
225                     try {
226                         entity = getEntity(controller);
227                     } catch (PlugwiseHAException e) {
228                         updateStatus(OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
229                         setLinkedChannelsUndef();
230                     }
231                     if (entity != null) {
232                         for (Channel channel : getThing().getChannels()) {
233                             ChannelUID channelUID = channel.getUID();
234                             if (this.isLinked(channelUID)) {
235                                 refreshChannel(entity, channelUID);
236                             }
237                         }
238                     }
239                 }
240             }
241         }
242     }
243 }