2 * Copyright (c) 2010-2022 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.plugwiseha.internal.handler;
15 import static org.openhab.core.thing.ThingStatus.*;
17 import java.lang.reflect.ParameterizedType;
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;
39 * The {@link PlugwiseHABaseHandler} abstract class provides common methods and
40 * properties for the ThingHandlers of this binding. Extends @{link
43 * @author Bas van Wetten - Initial contribution
44 * @author Leo Siepel - finish initial contribution
46 * @param <E> entity - the Plugwise Home Automation entity class used by this
48 * @param <C> config - the Plugwise Home Automation config class used by this
53 public abstract class PlugwiseHABaseHandler<E, C extends PlugwiseHAThingConfig> extends BaseThingHandler {
55 protected static final String STATUS_DESCRIPTION_COMMUNICATION_ERROR = "Error communicating with the Plugwise Home Automation controller";
57 protected final Logger logger = LoggerFactory.getLogger(PlugwiseHABaseHandler.class);
59 private Class<?> clazz;
62 @SuppressWarnings("null")
63 public PlugwiseHABaseHandler(Thing thing) {
65 clazz = (Class<?>) (((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[1]);
71 * Initializes the Plugwise Entity that this class handles.
73 * @param config the thing configuration
74 * @param bridge the bridge that this thing is part of
76 protected abstract void initialize(C config, PlugwiseHABridgeHandler bridge);
79 * Get the Plugwise Entity that belongs to this ThingHandler
81 * @param controller the controller for this ThingHandler
82 * @param forceRefresh indicated if the entity should be refreshed from the Plugwise API
84 protected abstract @Nullable E getEntity(PlugwiseHAController controller, Boolean forceRefresh)
85 throws PlugwiseHAException;
88 * Handles a {@link RefreshType} command for a given channel.
90 * @param entity the Plugwise Entity
91 * @param channelUID the channel uid the command is for
93 protected abstract void refreshChannel(E entity, ChannelUID channelUID);
96 * Handles a command for a given channel.
98 * @param entity the Plugwise Entity
99 * @param channelUID the channel uid the command is for
100 * @param command the command
102 protected abstract void handleCommand(E entity, ChannelUID channelUID, Command command) throws PlugwiseHAException;
107 public void initialize() {
108 C config = getPlugwiseThingConfig();
110 if (checkConfig(config)) {
111 Bridge bridge = getBridge();
112 if (bridge == null || bridge.getHandler() == null
113 || !(bridge.getHandler() instanceof PlugwiseHABridgeHandler)) {
114 updateStatus(OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
115 "You must choose a Plugwise Home Automation bridge for this thing.");
119 if (bridge.getStatus() == OFFLINE) {
120 updateStatus(OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE,
121 "The Plugwise Home Automation bridge is currently offline.");
124 PlugwiseHABridgeHandler bridgeHandler = (PlugwiseHABridgeHandler) bridge.getHandler();
125 if (bridgeHandler != null) {
126 initialize(config, bridgeHandler);
129 logger.debug("Invalid config for Plugwise Home Automation thing handler with config = {}", config);
134 public final void handleCommand(ChannelUID channelUID, Command command) {
135 logger.debug("Handling command = {} for channel = {}", command, channelUID);
137 if (getThing().getStatus() == ONLINE) {
138 PlugwiseHAController controller = getController();
139 if (controller != null) {
142 E entity = getEntity(controller, false);
143 if (entity != null) {
144 if (this.isLinked(channelUID)) {
145 if (command instanceof RefreshType) {
146 refreshChannel(entity, channelUID);
148 handleCommand(entity, channelUID, command);
152 } catch (PlugwiseHAException e) {
153 logger.warn("Unexpected error handling command = {} for channel = {} : {}", command, channelUID,
160 // Public member methods
162 public @Nullable PlugwiseHABridgeHandler getPlugwiseHABridge() {
163 Bridge bridge = this.getBridge();
164 if (bridge != null) {
165 return (PlugwiseHABridgeHandler) bridge.getHandler();
171 @SuppressWarnings("unchecked")
172 public C getPlugwiseThingConfig() {
173 return (C) getConfigAs(clazz);
176 // Private & protected methods
178 private @Nullable PlugwiseHAController getController() {
179 PlugwiseHABridgeHandler bridgeHandler = getPlugwiseHABridge();
181 if (bridgeHandler != null) {
182 return bridgeHandler.getController();
189 * Checks the configuration for validity, result is reflected in the status of
192 private boolean checkConfig(C config) {
193 if (!config.isValid()) {
194 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
195 "Configuration is missing or corrupted");
203 public void bridgeStatusChanged(ThingStatusInfo bridgeStatusInfo) {
204 super.bridgeStatusChanged(bridgeStatusInfo);
205 if (bridgeStatusInfo.getStatus() == ThingStatus.OFFLINE) {
206 setLinkedChannelsUndef();
210 private void setLinkedChannelsUndef() {
211 for (Channel channel : getThing().getChannels()) {
212 ChannelUID channelUID = channel.getUID();
213 if (this.isLinked(channelUID)) {
214 updateState(channelUID, UnDefType.UNDEF);
219 protected final void refresh() {
220 PlugwiseHABridgeHandler bridgeHandler = getPlugwiseHABridge();
221 if (bridgeHandler != null) {
222 if (bridgeHandler.getThing().getStatusInfo().getStatus() == ThingStatus.ONLINE) {
223 PlugwiseHAController controller = getController();
224 if (controller != null) {
228 entity = getEntity(controller, false);
229 } catch (PlugwiseHAException e) {
230 updateStatus(OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
231 setLinkedChannelsUndef();
233 if (entity != null) {
234 for (Channel channel : getThing().getChannels()) {
235 ChannelUID channelUID = channel.getUID();
236 if (this.isLinked(channelUID)) {
237 refreshChannel(entity, channelUID);