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.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
83 protected abstract @Nullable E getEntity(PlugwiseHAController controller) throws PlugwiseHAException;
86 * Handles a {@link RefreshType} command for a given channel.
88 * @param entity the Plugwise Entity
89 * @param channelUID the channel uid the command is for
91 protected abstract void refreshChannel(E entity, ChannelUID channelUID);
94 * Handles a command for a given channel.
96 * @param entity the Plugwise Entity
97 * @param channelUID the channel uid the command is for
98 * @param command the command
100 protected abstract void handleCommand(E entity, ChannelUID channelUID, Command command) throws PlugwiseHAException;
105 public void initialize() {
106 C config = getPlugwiseThingConfig();
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.");
117 if (bridge.getStatus() == OFFLINE) {
118 updateStatus(OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE,
119 "The Plugwise Home Automation bridge is currently offline.");
122 PlugwiseHABridgeHandler bridgeHandler = (PlugwiseHABridgeHandler) bridge.getHandler();
123 if (bridgeHandler != null) {
124 initialize(config, bridgeHandler);
127 logger.debug("Invalid config for Plugwise Home Automation thing handler with config = {}", config);
132 public final void handleCommand(ChannelUID channelUID, Command command) {
133 logger.debug("Handling command = {} for channel = {}", command, channelUID);
135 if (getThing().getStatus() == ONLINE) {
136 PlugwiseHAController controller = getController();
137 if (controller != null) {
140 E entity = getEntity(controller);
141 if (entity != null) {
142 if (this.isLinked(channelUID)) {
143 if (command instanceof RefreshType) {
144 refreshChannel(entity, channelUID);
146 handleCommand(entity, channelUID, command);
150 } catch (PlugwiseHAException e) {
151 logger.warn("Unexpected error handling command = {} for channel = {} : {}", command, channelUID,
158 // Public member methods
160 public @Nullable PlugwiseHABridgeHandler getPlugwiseHABridge() {
161 Bridge bridge = this.getBridge();
162 if (bridge != null) {
163 return (PlugwiseHABridgeHandler) bridge.getHandler();
169 @SuppressWarnings("unchecked")
170 public C getPlugwiseThingConfig() {
171 return (C) getConfigAs(clazz);
174 // Private & protected methods
176 private @Nullable PlugwiseHAController getController() {
177 PlugwiseHABridgeHandler bridgeHandler = getPlugwiseHABridge();
179 if (bridgeHandler != null) {
180 return bridgeHandler.getController();
187 * Checks the configuration for validity, result is reflected in the status of
190 private boolean checkConfig(C config) {
191 if (!config.isValid()) {
192 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
193 "Configuration is missing or corrupted");
201 public void bridgeStatusChanged(ThingStatusInfo bridgeStatusInfo) {
202 super.bridgeStatusChanged(bridgeStatusInfo);
203 if (bridgeStatusInfo.getStatus() == ThingStatus.OFFLINE) {
204 setLinkedChannelsUndef();
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);
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) {
226 entity = getEntity(controller);
227 } catch (PlugwiseHAException e) {
228 updateStatus(OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
229 setLinkedChannelsUndef();
231 if (entity != null) {
232 for (Channel channel : getThing().getChannels()) {
233 ChannelUID channelUID = channel.getUID();
234 if (this.isLinked(channelUID)) {
235 refreshChannel(entity, channelUID);