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.openwebnet.internal.handler;
15 import static org.openhab.binding.openwebnet.internal.OpenWebNetBindingConstants.*;
19 import org.eclipse.jdt.annotation.NonNullByDefault;
20 import org.openhab.binding.openwebnet.internal.OpenWebNetBindingConstants;
21 import org.openhab.core.library.types.DecimalType;
22 import org.openhab.core.library.types.QuantityType;
23 import org.openhab.core.library.types.StringType;
24 import org.openhab.core.library.unit.SIUnits;
25 import org.openhab.core.thing.ChannelUID;
26 import org.openhab.core.thing.Thing;
27 import org.openhab.core.thing.ThingStatus;
28 import org.openhab.core.thing.ThingStatusInfo;
29 import org.openhab.core.thing.ThingTypeUID;
30 import org.openhab.core.types.Command;
31 import org.openhab.core.types.UnDefType;
32 import org.openwebnet4j.communication.OWNException;
33 import org.openwebnet4j.message.BaseOpenMessage;
34 import org.openwebnet4j.message.FrameException;
35 import org.openwebnet4j.message.MalformedFrameException;
36 import org.openwebnet4j.message.Thermoregulation;
37 import org.openwebnet4j.message.Where;
38 import org.openwebnet4j.message.WhereThermo;
39 import org.openwebnet4j.message.Who;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
44 * The {@link OpenWebNetThermoregulationHandler} is responsible for handling commands/messages for Thermoregulation
45 * Things. It extends the abstract {@link OpenWebNetThingHandler}.
47 * @author Massimo Valla - Initial contribution
48 * @author Andrea Conte - Thermoregulation
49 * @author Gilberto Cocchi - Thermoregulation
52 public class OpenWebNetThermoregulationHandler extends OpenWebNetThingHandler {
54 private final Logger logger = LoggerFactory.getLogger(OpenWebNetThermoregulationHandler.class);
56 public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = OpenWebNetBindingConstants.THERMOREGULATION_SUPPORTED_THING_TYPES;
58 private boolean isTempSensor = false; // is the thing a sensor ?
60 private double currentSetPointTemp = 11.5d; // 11.5 is the default setTemp used in MyHomeUP mobile app
62 private Thermoregulation.Function currentFunction = Thermoregulation.Function.GENERIC;
64 public OpenWebNetThermoregulationHandler(Thing thing) {
69 public void bridgeStatusChanged(ThingStatusInfo bridgeStatusInfo) {
70 super.bridgeStatusChanged(bridgeStatusInfo);
71 // when the bridge is ONLINE request for thing states (temp, setTemp, fanSpeed...)
72 if (bridgeStatusInfo.getStatus().equals(ThingStatus.ONLINE)) {
78 protected void handleChannelCommand(ChannelUID channel, Command command) {
79 switch (channel.getId()) {
80 case CHANNEL_TEMP_SETPOINT:
81 handleSetpoint(command);
83 case CHANNEL_FUNCTION:
84 handleFunction(command);
89 case CHANNEL_FAN_SPEED:
90 handleSetFanSpeed(command);
93 logger.warn("handleChannelCommand() Unsupported ChannelUID {}", channel.getId());
99 protected void requestChannelState(ChannelUID channel) {
100 super.requestChannelState(channel);
101 refreshDevice(false);
105 protected void refreshDevice(boolean refreshAll) {
106 logger.debug("--- refreshDevice() : refreshing SINGLE... ({})", thing.getUID());
107 if (deviceWhere != null) {
108 String w = deviceWhere.value();
110 send(Thermoregulation.requestTemperature(w));
111 if (!this.isTempSensor) {
112 // for bus_thermo_zone request also other single channels updates
113 send(Thermoregulation.requestSetPointTemperature(w));
114 send(Thermoregulation.requestFanCoilSpeed(w));
115 send(Thermoregulation.requestMode(w));
116 send(Thermoregulation.requestValvesStatus(w));
117 send(Thermoregulation.requestActuatorsStatus(w));
119 } catch (OWNException e) {
120 logger.warn("refreshDevice() where='{}' returned OWNException {}", w, e.getMessage());
126 protected Where buildBusWhere(String wStr) throws IllegalArgumentException {
127 WhereThermo wt = new WhereThermo(wStr);
135 protected String ownIdPrefix() {
136 return Who.THERMOREGULATION.value().toString();
139 private void handleSetFanSpeed(Command command) {
140 if (command instanceof StringType) {
141 Where w = deviceWhere;
144 Thermoregulation.FanCoilSpeed speed = Thermoregulation.FanCoilSpeed.valueOf(command.toString());
145 send(Thermoregulation.requestWriteFanCoilSpeed(w.value(), speed));
146 } catch (OWNException e) {
147 logger.warn("handleSetFanSpeed() {}", e.getMessage());
148 } catch (IllegalArgumentException e) {
149 logger.warn("handleSetFanSpeed() Unsupported command {} for thing {}", command,
150 getThing().getUID());
155 logger.warn("handleSetFanSpeed() Unsupported command {} for thing {}", command, getThing().getUID());
159 private void handleSetpoint(Command command) {
160 if (command instanceof QuantityType || command instanceof DecimalType) {
161 Where w = deviceWhere;
164 if (command instanceof QuantityType) {
165 QuantityType<?> tempCelsius = ((QuantityType<?>) command).toUnit(SIUnits.CELSIUS);
166 if (tempCelsius != null) {
167 newTemp = tempCelsius.doubleValue();
170 newTemp = ((DecimalType) command).doubleValue();
173 send(Thermoregulation.requestWriteSetpointTemperature(w.value(), newTemp, currentFunction));
174 } catch (MalformedFrameException | OWNException e) {
175 logger.warn("handleSetpoint() {}", e.getMessage());
179 logger.warn("handleSetpoint() Unsupported command {} for thing {}", command, getThing().getUID());
183 private void handleMode(Command command) {
184 if (command instanceof StringType) {
185 Where w = deviceWhere;
188 Thermoregulation.OperationMode mode = Thermoregulation.OperationMode.valueOf(command.toString());
189 send(Thermoregulation.requestWriteMode(w.value(), mode, currentFunction, currentSetPointTemp));
190 } catch (OWNException e) {
191 logger.warn("handleMode() {}", e.getMessage());
192 } catch (IllegalArgumentException e) {
193 logger.warn("handleMode() Unsupported command {} for thing {}", command, getThing().getUID());
198 logger.warn("handleMode() Unsupported command {} for thing {}", command, getThing().getUID());
202 private void handleFunction(Command command) {
203 if (command instanceof StringType) {
204 Where w = deviceWhere;
207 Thermoregulation.Function function = Thermoregulation.Function.valueOf(command.toString());
208 send(Thermoregulation.requestWriteFunction(w.value(), function));
209 } catch (OWNException e) {
210 logger.warn("handleFunction() {}", e.getMessage());
211 } catch (IllegalArgumentException e) {
212 logger.warn("handleFunction() Unsupported command {} for thing {}", command, getThing().getUID());
217 logger.warn("handleFunction() Unsupported command {} for thing {}", command, getThing().getUID());
222 protected void handleMessage(BaseOpenMessage msg) {
223 super.handleMessage(msg);
224 if (msg.isCommand()) {
225 updateModeAndFunction((Thermoregulation) msg);
227 if (msg.getDim() == null) {
230 if (msg.getDim() == Thermoregulation.DimThermo.TEMPERATURE
231 || msg.getDim() == Thermoregulation.DimThermo.PROBE_TEMPERATURE) {
232 updateTemperature((Thermoregulation) msg);
233 } else if (msg.getDim() == Thermoregulation.DimThermo.TEMP_SETPOINT
234 || msg.getDim() == Thermoregulation.DimThermo.COMPLETE_PROBE_STATUS) {
235 updateSetpoint((Thermoregulation) msg);
236 } else if (msg.getDim() == Thermoregulation.DimThermo.VALVES_STATUS) {
237 updateValveStatus((Thermoregulation) msg);
238 } else if (msg.getDim() == Thermoregulation.DimThermo.ACTUATOR_STATUS) {
239 updateActuatorStatus((Thermoregulation) msg);
240 } else if (msg.getDim() == Thermoregulation.DimThermo.FAN_COIL_SPEED) {
241 updateFanCoilSpeed((Thermoregulation) msg);
243 logger.debug("handleMessage() Ignoring unsupported DIM {} for thing {}. Frame={}", msg.getDim(),
244 getThing().getUID(), msg);
249 private void updateModeAndFunction(Thermoregulation tmsg) {
250 if (tmsg.getWhat() == null) {
251 logger.debug("updateModeAndFunction() Could not parse Mode or Function from {} (what is null)",
252 tmsg.getFrameValue());
256 Thermoregulation.WhatThermo w = Thermoregulation.WhatThermo.fromValue(tmsg.getWhat().value());
258 if (w.getMode() == null) {
259 logger.debug("updateModeAndFunction() Could not parse Mode from: {}", tmsg.getFrameValue());
262 if (w.getFunction() == null) {
263 logger.debug("updateModeAndFunction() Could not parse Function from: {}", tmsg.getFrameValue());
267 Thermoregulation.OperationMode mode = w.getMode();
268 Thermoregulation.Function function = w.getFunction();
270 if (w == Thermoregulation.WhatThermo.HEATING) {
271 function = Thermoregulation.Function.HEATING;
272 } else if (w == Thermoregulation.WhatThermo.CONDITIONING) {
273 function = Thermoregulation.Function.COOLING;
276 updateState(CHANNEL_MODE, new StringType(mode.toString()));
277 updateState(CHANNEL_FUNCTION, new StringType(function.toString()));
279 // store current function
280 currentFunction = function;
283 private void updateTemperature(Thermoregulation tmsg) {
285 double temp = Thermoregulation.parseTemperature(tmsg);
286 updateState(CHANNEL_TEMPERATURE, getAsQuantityTypeOrNull(temp, SIUnits.CELSIUS));
287 } catch (FrameException e) {
288 logger.warn("updateTemperature() FrameException on frame {}: {}", tmsg, e.getMessage());
289 updateState(CHANNEL_TEMPERATURE, UnDefType.UNDEF);
293 private void updateSetpoint(Thermoregulation tmsg) {
295 double temp = Thermoregulation.parseTemperature(tmsg);
296 updateState(CHANNEL_TEMP_SETPOINT, getAsQuantityTypeOrNull(temp, SIUnits.CELSIUS));
297 currentSetPointTemp = temp;
298 } catch (FrameException e) {
299 logger.warn("updateSetpoint() FrameException on frame {}: {}", tmsg, e.getMessage());
300 updateState(CHANNEL_TEMP_SETPOINT, UnDefType.UNDEF);
304 private void updateFanCoilSpeed(Thermoregulation tmsg) {
306 Thermoregulation.FanCoilSpeed speed = Thermoregulation.parseFanCoilSpeed(tmsg);
307 updateState(CHANNEL_FAN_SPEED, new StringType(speed.toString()));
308 } catch (FrameException e) {
309 logger.warn("updateFanCoilSpeed() FrameException on frame {}: {}", tmsg, e.getMessage());
310 updateState(CHANNEL_FAN_SPEED, UnDefType.UNDEF);
314 private void updateValveStatus(Thermoregulation tmsg) {
316 Thermoregulation.ValveOrActuatorStatus cv = Thermoregulation.parseValveStatus(tmsg,
317 Thermoregulation.WhatThermo.CONDITIONING);
318 updateState(CHANNEL_CONDITIONING_VALVES, new StringType(cv.toString()));
320 Thermoregulation.ValveOrActuatorStatus hv = Thermoregulation.parseValveStatus(tmsg,
321 Thermoregulation.WhatThermo.HEATING);
322 updateState(CHANNEL_HEATING_VALVES, new StringType(hv.toString()));
323 } catch (FrameException e) {
324 logger.warn("updateValveStatus() FrameException on frame {}: {}", tmsg, e.getMessage());
325 updateState(CHANNEL_CONDITIONING_VALVES, UnDefType.UNDEF);
326 updateState(CHANNEL_HEATING_VALVES, UnDefType.UNDEF);
330 private void updateActuatorStatus(Thermoregulation tmsg) {
332 Thermoregulation.ValveOrActuatorStatus hv = Thermoregulation.parseActuatorStatus(tmsg);
333 updateState(CHANNEL_ACTUATORS, new StringType(hv.toString()));
334 } catch (FrameException e) {
335 logger.warn("updateActuatorStatus() FrameException on frame {}: {}", tmsg, e.getMessage());
336 updateState(CHANNEL_ACTUATORS, UnDefType.UNDEF);