]> git.basschouten.com Git - openhab-addons.git/blob
4dba0b938e088fee60213fab4c258916071082d6
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2022 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.openwebnet.internal.handler;
14
15 import static org.openhab.binding.openwebnet.internal.OpenWebNetBindingConstants.*;
16
17 import java.util.Set;
18
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;
42
43 /**
44  * The {@link OpenWebNetThermoregulationHandler} is responsible for handling commands/messages for Thermoregulation
45  * Things. It extends the abstract {@link OpenWebNetThingHandler}.
46  *
47  * @author Massimo Valla - Initial contribution
48  * @author Andrea Conte - Thermoregulation
49  * @author Gilberto Cocchi - Thermoregulation
50  */
51 @NonNullByDefault
52 public class OpenWebNetThermoregulationHandler extends OpenWebNetThingHandler {
53
54     private final Logger logger = LoggerFactory.getLogger(OpenWebNetThermoregulationHandler.class);
55
56     public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = OpenWebNetBindingConstants.THERMOREGULATION_SUPPORTED_THING_TYPES;
57
58     private boolean isTempSensor = false; // is the thing a sensor ?
59
60     private double currentSetPointTemp = 11.5d; // 11.5 is the default setTemp used in MyHomeUP mobile app
61
62     private Thermoregulation.Function currentFunction = Thermoregulation.Function.GENERIC;
63
64     public OpenWebNetThermoregulationHandler(Thing thing) {
65         super(thing);
66     }
67
68     @Override
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)) {
73             refreshDevice(false);
74         }
75     }
76
77     @Override
78     protected void handleChannelCommand(ChannelUID channel, Command command) {
79         switch (channel.getId()) {
80             case CHANNEL_TEMP_SETPOINT:
81                 handleSetpoint(command);
82                 break;
83             case CHANNEL_FUNCTION:
84                 handleFunction(command);
85                 break;
86             case CHANNEL_MODE:
87                 handleMode(command);
88                 break;
89             case CHANNEL_FAN_SPEED:
90                 handleSetFanSpeed(command);
91                 break;
92             default: {
93                 logger.warn("handleChannelCommand() Unsupported ChannelUID {}", channel.getId());
94             }
95         }
96     }
97
98     @Override
99     protected void requestChannelState(ChannelUID channel) {
100         super.requestChannelState(channel);
101         refreshDevice(false);
102     }
103
104     @Override
105     protected void refreshDevice(boolean refreshAll) {
106         logger.debug("--- refreshDevice() : refreshing SINGLE... ({})", thing.getUID());
107         if (deviceWhere != null) {
108             String w = deviceWhere.value();
109             try {
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));
118                 }
119             } catch (OWNException e) {
120                 logger.warn("refreshDevice() where='{}' returned OWNException {}", w, e.getMessage());
121             }
122         }
123     }
124
125     @Override
126     protected Where buildBusWhere(String wStr) throws IllegalArgumentException {
127         WhereThermo wt = new WhereThermo(wStr);
128         if (wt.isProbe()) {
129             isTempSensor = true;
130         }
131         return wt;
132     }
133
134     @Override
135     protected String ownIdPrefix() {
136         return Who.THERMOREGULATION.value().toString();
137     }
138
139     private void handleSetFanSpeed(Command command) {
140         if (command instanceof StringType) {
141             Where w = deviceWhere;
142             if (w != null) {
143                 try {
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());
151                     return;
152                 }
153             }
154         } else {
155             logger.warn("handleSetFanSpeed() Unsupported command {} for thing {}", command, getThing().getUID());
156         }
157     }
158
159     private void handleSetpoint(Command command) {
160         if (command instanceof QuantityType || command instanceof DecimalType) {
161             Where w = deviceWhere;
162             if (w != null) {
163                 double newTemp = 0;
164                 if (command instanceof QuantityType) {
165                     QuantityType<?> tempCelsius = ((QuantityType<?>) command).toUnit(SIUnits.CELSIUS);
166                     if (tempCelsius != null) {
167                         newTemp = tempCelsius.doubleValue();
168                     }
169                 } else {
170                     newTemp = ((DecimalType) command).doubleValue();
171                 }
172                 try {
173                     send(Thermoregulation.requestWriteSetpointTemperature(w.value(), newTemp, currentFunction));
174                 } catch (MalformedFrameException | OWNException e) {
175                     logger.warn("handleSetpoint() {}", e.getMessage());
176                 }
177             }
178         } else {
179             logger.warn("handleSetpoint() Unsupported command {} for thing {}", command, getThing().getUID());
180         }
181     }
182
183     private void handleMode(Command command) {
184         if (command instanceof StringType) {
185             Where w = deviceWhere;
186             if (w != null) {
187                 try {
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());
194                     return;
195                 }
196             }
197         } else {
198             logger.warn("handleMode() Unsupported command {} for thing {}", command, getThing().getUID());
199         }
200     }
201
202     private void handleFunction(Command command) {
203         if (command instanceof StringType) {
204             Where w = deviceWhere;
205             if (w != null) {
206                 try {
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());
213                     return;
214                 }
215             }
216         } else {
217             logger.warn("handleFunction() Unsupported command {} for thing {}", command, getThing().getUID());
218         }
219     }
220
221     @Override
222     protected void handleMessage(BaseOpenMessage msg) {
223         super.handleMessage(msg);
224         if (msg.isCommand()) {
225             updateModeAndFunction((Thermoregulation) msg);
226         } else {
227             if (msg.getDim() == null) {
228                 return;
229             }
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);
242             } else {
243                 logger.debug("handleMessage() Ignoring unsupported DIM {} for thing {}. Frame={}", msg.getDim(),
244                         getThing().getUID(), msg);
245             }
246         }
247     }
248
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());
253             return;
254         }
255
256         Thermoregulation.WhatThermo w = Thermoregulation.WhatThermo.fromValue(tmsg.getWhat().value());
257
258         if (w.getMode() == null) {
259             logger.debug("updateModeAndFunction() Could not parse Mode from: {}", tmsg.getFrameValue());
260             return;
261         }
262         if (w.getFunction() == null) {
263             logger.debug("updateModeAndFunction() Could not parse Function from: {}", tmsg.getFrameValue());
264             return;
265         }
266
267         Thermoregulation.OperationMode mode = w.getMode();
268         Thermoregulation.Function function = w.getFunction();
269
270         if (w == Thermoregulation.WhatThermo.HEATING) {
271             function = Thermoregulation.Function.HEATING;
272         } else if (w == Thermoregulation.WhatThermo.CONDITIONING) {
273             function = Thermoregulation.Function.COOLING;
274         }
275
276         updateState(CHANNEL_MODE, new StringType(mode.toString()));
277         updateState(CHANNEL_FUNCTION, new StringType(function.toString()));
278
279         // store current function
280         currentFunction = function;
281     }
282
283     private void updateTemperature(Thermoregulation tmsg) {
284         try {
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);
290         }
291     }
292
293     private void updateSetpoint(Thermoregulation tmsg) {
294         try {
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);
301         }
302     }
303
304     private void updateFanCoilSpeed(Thermoregulation tmsg) {
305         try {
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);
311         }
312     }
313
314     private void updateValveStatus(Thermoregulation tmsg) {
315         try {
316             Thermoregulation.ValveOrActuatorStatus cv = Thermoregulation.parseValveStatus(tmsg,
317                     Thermoregulation.WhatThermo.CONDITIONING);
318             updateState(CHANNEL_CONDITIONING_VALVES, new StringType(cv.toString()));
319
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);
327         }
328     }
329
330     private void updateActuatorStatus(Thermoregulation tmsg) {
331         try {
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);
337         }
338     }
339 }