]> git.basschouten.com Git - openhab-addons.git/blob
cd24e7442d8b0068de089d935fafe44312230d6d
[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.binding.plugwiseha.internal.PlugwiseHABindingConstants.*;
16 import static org.openhab.core.thing.ThingStatus.*;
17 import static org.openhab.core.thing.ThingStatusDetail.BRIDGE_OFFLINE;
18 import static org.openhab.core.thing.ThingStatusDetail.COMMUNICATION_ERROR;
19 import static org.openhab.core.thing.ThingStatusDetail.CONFIGURATION_ERROR;
20
21 import java.util.Map;
22 import java.util.Optional;
23
24 import javax.measure.Unit;
25 import javax.measure.quantity.Temperature;
26
27 import org.eclipse.jdt.annotation.NonNullByDefault;
28 import org.eclipse.jdt.annotation.Nullable;
29 import org.openhab.binding.plugwiseha.internal.PlugwiseHABindingConstants;
30 import org.openhab.binding.plugwiseha.internal.api.exception.PlugwiseHAException;
31 import org.openhab.binding.plugwiseha.internal.api.model.PlugwiseHAController;
32 import org.openhab.binding.plugwiseha.internal.api.model.dto.Location;
33 import org.openhab.binding.plugwiseha.internal.config.PlugwiseHAThingConfig;
34 import org.openhab.core.library.types.OnOffType;
35 import org.openhab.core.library.types.QuantityType;
36 import org.openhab.core.library.types.StringType;
37 import org.openhab.core.library.unit.ImperialUnits;
38 import org.openhab.core.library.unit.SIUnits;
39 import org.openhab.core.thing.ChannelUID;
40 import org.openhab.core.thing.Thing;
41 import org.openhab.core.thing.ThingTypeUID;
42 import org.openhab.core.types.Command;
43 import org.openhab.core.types.State;
44 import org.openhab.core.types.UnDefType;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
47
48 /**
49  * The {@link PlugwiseHAZoneHandler} class is responsible for handling commands
50  * and status updates for the Plugwise Home Automation zones/locations.
51  * Extends @{link PlugwiseHABaseHandler}
52  *
53  * @author Bas van Wetten - Initial contribution
54  * @author Leo Siepel - finish initial contribution
55  *
56  */
57
58 @NonNullByDefault
59 public class PlugwiseHAZoneHandler extends PlugwiseHABaseHandler<Location, PlugwiseHAThingConfig> {
60
61     private @Nullable Location location;
62     private final Logger logger = LoggerFactory.getLogger(PlugwiseHAZoneHandler.class);
63
64     // Constructor
65
66     public PlugwiseHAZoneHandler(Thing thing) {
67         super(thing);
68     }
69
70     public static boolean supportsThingType(ThingTypeUID thingTypeUID) {
71         return PlugwiseHABindingConstants.THING_TYPE_ZONE.equals(thingTypeUID);
72     }
73
74     // Overrides
75
76     @Override
77     protected synchronized void initialize(PlugwiseHAThingConfig config, PlugwiseHABridgeHandler bridgeHandler) {
78         if (thing.getStatus() == INITIALIZING) {
79             logger.debug("Initializing Plugwise Home Automation zone handler with config = {}", config);
80             if (!config.isValid()) {
81                 updateStatus(OFFLINE, CONFIGURATION_ERROR,
82                         "Invalid configuration for Plugwise Home Automation zone handler.");
83                 return;
84             }
85
86             try {
87                 PlugwiseHAController controller = bridgeHandler.getController();
88                 if (controller != null) {
89                     this.location = getEntity(controller);
90                     if (this.location != null) {
91                         setLocationProperties();
92                         updateStatus(ONLINE);
93                     } else {
94                         updateStatus(OFFLINE);
95                     }
96                 } else {
97                     updateStatus(OFFLINE, BRIDGE_OFFLINE);
98                 }
99             } catch (PlugwiseHAException e) {
100                 updateStatus(OFFLINE, COMMUNICATION_ERROR, e.getMessage());
101             }
102         }
103     }
104
105     @Override
106     protected @Nullable Location getEntity(PlugwiseHAController controller) throws PlugwiseHAException {
107         PlugwiseHAThingConfig config = getPlugwiseThingConfig();
108         Location location = controller.getLocation(config.getId());
109
110         return location;
111     }
112
113     @Override
114     protected void handleCommand(Location entity, ChannelUID channelUID, Command command) throws PlugwiseHAException {
115         String channelID = channelUID.getIdWithoutGroup();
116         PlugwiseHABridgeHandler bridge = this.getPlugwiseHABridge();
117         if (bridge != null) {
118             PlugwiseHAController controller = bridge.getController();
119             if (controller != null) {
120                 switch (channelID) {
121                     case ZONE_COOLING_CHANNEL:
122                         if (command instanceof OnOffType) {
123                             try {
124                                 controller.setAllowCooling(entity, command == OnOffType.ON);
125                             } catch (PlugwiseHAException e) {
126                                 logger.warn("Unable to switch allow cooling {} for zone '{}'", (State) command,
127                                         entity.getName());
128                             }
129                         }
130                         break;
131                     case ZONE_SETPOINT_CHANNEL:
132                         if (command instanceof QuantityType) {
133                             Unit<Temperature> unit = entity.getSetpointTemperatureUnit().orElse(UNIT_CELSIUS)
134                                     .equals(UNIT_CELSIUS) ? SIUnits.CELSIUS : ImperialUnits.FAHRENHEIT;
135                             QuantityType<?> state = ((QuantityType<?>) command).toUnit(unit);
136                             if (state != null) {
137                                 try {
138                                     controller.setLocationThermostat(entity, state.doubleValue());
139                                 } catch (PlugwiseHAException e) {
140                                     logger.warn("Unable to update setpoint for zone '{}': {} -> {}", entity.getName(),
141                                             entity.getSetpointTemperature().orElse(null), state.doubleValue());
142                                 }
143                             }
144                         }
145                         break;
146                     case ZONE_PREHEAT_CHANNEL:
147                         if (command instanceof OnOffType) {
148                             try {
149                                 controller.setPreHeating(entity, command == OnOffType.ON);
150                             } catch (PlugwiseHAException e) {
151                                 logger.warn("Unable to switch zone pre heating {} for zone '{}'", (State) command,
152                                         entity.getName());
153                             }
154                         }
155                         break;
156                     case ZONE_REGULATION_CHANNEL:
157                         if (command instanceof StringType) {
158                             try {
159                                 controller.setRegulationControl(entity, command.toString());
160                             } catch (PlugwiseHAException e) {
161                                 logger.warn("Unable to switch regulation control {} for zone '{}'", (State) command,
162                                         entity.getName());
163                             }
164                         }
165                         break;
166                     case ZONE_PRESETSCENE_CHANNEL:
167                         if (command instanceof StringType) {
168                             try {
169                                 controller.setPresetScene(entity, command.toString());
170                             } catch (PlugwiseHAException e) {
171                                 logger.warn("Unable to switch preset scene {} for zone '{}'", (State) command,
172                                         entity.getName());
173                             }
174                         }
175                         break;
176                     default:
177                         logger.warn("Ignoring unsupported command = {} for channel = {}", command, channelUID);
178                 }
179             }
180         }
181     }
182
183     private State getDefaultState(String channelID) {
184         State state = UnDefType.NULL;
185         switch (channelID) {
186             case ZONE_COOLING_CHANNEL:
187             case ZONE_PREHEAT_CHANNEL:
188             case ZONE_PRESETSCENE_CHANNEL:
189             case ZONE_REGULATION_CHANNEL:
190             case ZONE_SETPOINT_CHANNEL:
191             case ZONE_TEMPERATURE_CHANNEL:
192                 state = UnDefType.NULL;
193                 break;
194         }
195         return state;
196     }
197
198     @Override
199     protected void refreshChannel(Location entity, ChannelUID channelUID) {
200         String channelID = channelUID.getIdWithoutGroup();
201         State state = getDefaultState(channelID);
202
203         switch (channelID) {
204             case ZONE_COOLING_CHANNEL:
205                 Optional<Boolean> allowCoolingState = entity.getCoolingAllowed();
206                 if (allowCoolingState.isPresent()) {
207                     state = OnOffType.from(allowCoolingState.get());
208                 }
209                 break;
210             case ZONE_PREHEAT_CHANNEL:
211                 Optional<Boolean> preHeatState = entity.getPreHeatState();
212                 if (preHeatState.isPresent()) {
213                     state = OnOffType.from(preHeatState.get());
214                 }
215                 break;
216             case ZONE_PRESETSCENE_CHANNEL:
217                 state = new StringType(entity.getPreset());
218                 break;
219             case ZONE_SETPOINT_CHANNEL:
220                 if (entity.getSetpointTemperature().isPresent()) {
221                     Unit<Temperature> unit = entity.getSetpointTemperatureUnit().orElse(UNIT_CELSIUS)
222                             .equals(UNIT_CELSIUS) ? SIUnits.CELSIUS : ImperialUnits.FAHRENHEIT;
223                     state = new QuantityType<Temperature>(entity.getSetpointTemperature().get(), unit);
224                 }
225                 break;
226             case ZONE_REGULATION_CHANNEL:
227                 String value = entity.getRegulationControl();
228                 if (value != null) {
229                     state = new StringType(entity.getRegulationControl());
230                 }
231                 break;
232             case ZONE_TEMPERATURE_CHANNEL:
233                 if (entity.getTemperature().isPresent()) {
234                     Unit<Temperature> unit = entity.getTemperatureUnit().orElse(UNIT_CELSIUS).equals(UNIT_CELSIUS)
235                             ? SIUnits.CELSIUS
236                             : ImperialUnits.FAHRENHEIT;
237                     state = new QuantityType<Temperature>(entity.getTemperature().get(), unit);
238                 }
239                 break;
240             default:
241                 break;
242         }
243
244         if (state != UnDefType.NULL) {
245             updateState(channelID, state);
246         }
247     }
248
249     protected void setLocationProperties() {
250         if (this.location != null) {
251             Map<String, String> properties = editProperties();
252
253             Location localLocation = this.location;
254             if (localLocation != null) {
255                 properties.put(PlugwiseHABindingConstants.LOCATION_PROPERTY_DESCRIPTION,
256                         localLocation.getDescription());
257                 properties.put(PlugwiseHABindingConstants.LOCATION_PROPERTY_TYPE, localLocation.getType());
258                 properties.put(PlugwiseHABindingConstants.LOCATION_PROPERTY_FUNCTIONALITIES,
259                         String.join(", ", localLocation.getActuatorFunctionalities().keySet()));
260             }
261
262             updateProperties(properties);
263         }
264     }
265 }