]> git.basschouten.com Git - openhab-addons.git/blob
42c7fd4133a314423b4272642f6d87b3618c4905
[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         refreshDevice(false);
101     }
102
103     @Override
104     protected Where buildBusWhere(String wStr) throws IllegalArgumentException {
105         WhereThermo wt = new WhereThermo(wStr);
106         if (wt.isProbe()) {
107             isTempSensor = true;
108         }
109         return wt;
110     }
111
112     @Override
113     protected String ownIdPrefix() {
114         return Who.THERMOREGULATION.value().toString();
115     }
116
117     private void handleSetFanSpeed(Command command) {
118         if (command instanceof StringType) {
119             Where w = deviceWhere;
120             if (w != null) {
121                 try {
122                     Thermoregulation.FanCoilSpeed speed = Thermoregulation.FanCoilSpeed.valueOf(command.toString());
123                     send(Thermoregulation.requestWriteFanCoilSpeed(w.value(), speed));
124                 } catch (OWNException e) {
125                     logger.warn("handleSetFanSpeed() {}", e.getMessage());
126                 } catch (IllegalArgumentException e) {
127                     logger.warn("handleSetFanSpeed() Unsupported command {} for thing {}", command,
128                             getThing().getUID());
129                     return;
130                 }
131             }
132         } else {
133             logger.warn("handleSetFanSpeed() Unsupported command {} for thing {}", command, getThing().getUID());
134         }
135     }
136
137     private void handleSetpoint(Command command) {
138         if (command instanceof QuantityType || command instanceof DecimalType) {
139             Where w = deviceWhere;
140             if (w != null) {
141                 double newTemp = 0;
142                 if (command instanceof QuantityType) {
143                     QuantityType<?> tempCelsius = ((QuantityType<?>) command).toUnit(SIUnits.CELSIUS);
144                     if (tempCelsius != null) {
145                         newTemp = tempCelsius.doubleValue();
146                     }
147                 } else {
148                     newTemp = ((DecimalType) command).doubleValue();
149                 }
150                 try {
151                     send(Thermoregulation.requestWriteSetpointTemperature(w.value(), newTemp, currentFunction));
152                 } catch (MalformedFrameException | OWNException e) {
153                     logger.warn("handleSetpoint() {}", e.getMessage());
154                 }
155             }
156         } else {
157             logger.warn("handleSetpoint() Unsupported command {} for thing {}", command, getThing().getUID());
158         }
159     }
160
161     private void handleMode(Command command) {
162         if (command instanceof StringType) {
163             Where w = deviceWhere;
164             if (w != null) {
165                 try {
166                     Thermoregulation.OperationMode mode = Thermoregulation.OperationMode.valueOf(command.toString());
167                     send(Thermoregulation.requestWriteMode(w.value(), mode, currentFunction, currentSetPointTemp));
168                 } catch (OWNException e) {
169                     logger.warn("handleMode() {}", e.getMessage());
170                 } catch (IllegalArgumentException e) {
171                     logger.warn("handleMode() Unsupported command {} for thing {}", command, getThing().getUID());
172                     return;
173                 }
174             }
175         } else {
176             logger.warn("handleMode() Unsupported command {} for thing {}", command, getThing().getUID());
177         }
178     }
179
180     private void handleFunction(Command command) {
181         if (command instanceof StringType) {
182             Where w = deviceWhere;
183             if (w != null) {
184                 try {
185                     Thermoregulation.Function function = Thermoregulation.Function.valueOf(command.toString());
186                     send(Thermoregulation.requestWriteFunction(w.value(), function));
187                 } catch (OWNException e) {
188                     logger.warn("handleFunction() {}", e.getMessage());
189                 } catch (IllegalArgumentException e) {
190                     logger.warn("handleFunction() Unsupported command {} for thing {}", command, getThing().getUID());
191                     return;
192                 }
193             }
194         } else {
195             logger.warn("handleFunction() Unsupported command {} for thing {}", command, getThing().getUID());
196         }
197     }
198
199     @Override
200     protected void handleMessage(BaseOpenMessage msg) {
201         super.handleMessage(msg);
202         if (msg.isCommand()) {
203             updateModeAndFunction((Thermoregulation) msg);
204         } else {
205             if (msg.getDim() == null) {
206                 return;
207             }
208             if (msg.getDim() == Thermoregulation.DimThermo.TEMPERATURE
209                     || msg.getDim() == Thermoregulation.DimThermo.PROBE_TEMPERATURE) {
210                 updateTemperature((Thermoregulation) msg);
211             } else if (msg.getDim() == Thermoregulation.DimThermo.TEMP_SETPOINT
212                     || msg.getDim() == Thermoregulation.DimThermo.COMPLETE_PROBE_STATUS) {
213                 updateSetpoint((Thermoregulation) msg);
214             } else if (msg.getDim() == Thermoregulation.DimThermo.VALVES_STATUS) {
215                 updateValveStatus((Thermoregulation) msg);
216             } else if (msg.getDim() == Thermoregulation.DimThermo.ACTUATOR_STATUS) {
217                 updateActuatorStatus((Thermoregulation) msg);
218             } else if (msg.getDim() == Thermoregulation.DimThermo.FAN_COIL_SPEED) {
219                 updateFanCoilSpeed((Thermoregulation) msg);
220             } else {
221                 logger.debug("handleMessage() Ignoring unsupported DIM {} for thing {}. Frame={}", msg.getDim(),
222                         getThing().getUID(), msg);
223             }
224         }
225     }
226
227     private void updateModeAndFunction(Thermoregulation tmsg) {
228         if (tmsg.getWhat() == null) {
229             logger.debug("updateModeAndFunction() Could not parse Mode or Function from {} (what is null)",
230                     tmsg.getFrameValue());
231             return;
232         }
233
234         Thermoregulation.WhatThermo w = Thermoregulation.WhatThermo.fromValue(tmsg.getWhat().value());
235
236         if (w.mode() == null) {
237             logger.debug("updateModeAndFunction() Could not parse Mode from: {}", tmsg.getFrameValue());
238             return;
239         }
240         if (w.function() == null) {
241             logger.debug("updateModeAndFunction() Could not parse Function from: {}", tmsg.getFrameValue());
242             return;
243         }
244
245         Thermoregulation.OperationMode mode = w.mode();
246         Thermoregulation.Function function = w.function();
247
248         if (w == Thermoregulation.WhatThermo.HEATING) {
249             function = Thermoregulation.Function.HEATING;
250         } else if (w == Thermoregulation.WhatThermo.CONDITIONING) {
251             function = Thermoregulation.Function.COOLING;
252         }
253
254         updateState(CHANNEL_MODE, new StringType(mode.toString()));
255         updateState(CHANNEL_FUNCTION, new StringType(function.toString()));
256
257         // store current function
258         currentFunction = function;
259     }
260
261     private void updateTemperature(Thermoregulation tmsg) {
262         try {
263             double temp = Thermoregulation.parseTemperature(tmsg);
264             updateState(CHANNEL_TEMPERATURE, getAsQuantityTypeOrNull(temp, SIUnits.CELSIUS));
265         } catch (FrameException e) {
266             logger.warn("updateTemperature() FrameException on frame {}: {}", tmsg, e.getMessage());
267             updateState(CHANNEL_TEMPERATURE, UnDefType.UNDEF);
268         }
269     }
270
271     private void updateSetpoint(Thermoregulation tmsg) {
272         try {
273             double temp = Thermoregulation.parseTemperature(tmsg);
274             updateState(CHANNEL_TEMP_SETPOINT, getAsQuantityTypeOrNull(temp, SIUnits.CELSIUS));
275             currentSetPointTemp = temp;
276         } catch (FrameException e) {
277             logger.warn("updateSetpoint() FrameException on frame {}: {}", tmsg, e.getMessage());
278             updateState(CHANNEL_TEMP_SETPOINT, UnDefType.UNDEF);
279         }
280     }
281
282     private void updateFanCoilSpeed(Thermoregulation tmsg) {
283         try {
284             Thermoregulation.FanCoilSpeed speed = Thermoregulation.parseFanCoilSpeed(tmsg);
285             updateState(CHANNEL_FAN_SPEED, new StringType(speed.toString()));
286         } catch (FrameException e) {
287             logger.warn("updateFanCoilSpeed() FrameException on frame {}: {}", tmsg, e.getMessage());
288             updateState(CHANNEL_FAN_SPEED, UnDefType.UNDEF);
289         }
290     }
291
292     private void updateValveStatus(Thermoregulation tmsg) {
293         try {
294             Thermoregulation.ValveOrActuatorStatus cv = Thermoregulation.parseValveStatus(tmsg,
295                     Thermoregulation.WhatThermo.CONDITIONING);
296             updateState(CHANNEL_CONDITIONING_VALVES, new StringType(cv.toString()));
297
298             Thermoregulation.ValveOrActuatorStatus hv = Thermoregulation.parseValveStatus(tmsg,
299                     Thermoregulation.WhatThermo.HEATING);
300             updateState(CHANNEL_HEATING_VALVES, new StringType(hv.toString()));
301         } catch (FrameException e) {
302             logger.warn("updateValveStatus() FrameException on frame {}: {}", tmsg, e.getMessage());
303             updateState(CHANNEL_CONDITIONING_VALVES, UnDefType.UNDEF);
304             updateState(CHANNEL_HEATING_VALVES, UnDefType.UNDEF);
305         }
306     }
307
308     private void updateActuatorStatus(Thermoregulation tmsg) {
309         try {
310             Thermoregulation.ValveOrActuatorStatus hv = Thermoregulation.parseActuatorStatus(tmsg);
311             updateState(CHANNEL_ACTUATORS, new StringType(hv.toString()));
312         } catch (FrameException e) {
313             logger.warn("updateActuatorStatus() FrameException on frame {}: {}", tmsg, e.getMessage());
314             updateState(CHANNEL_ACTUATORS, UnDefType.UNDEF);
315         }
316     }
317
318     @Override
319     protected void refreshDevice(boolean refreshAll) {
320         if (deviceWhere != null) {
321             String w = deviceWhere.value();
322             try {
323                 send(Thermoregulation.requestTemperature(w));
324                 if (!this.isTempSensor) {
325                     // for bus_thermo_zone request also other single channels updates
326                     send(Thermoregulation.requestSetPointTemperature(w));
327                     send(Thermoregulation.requestFanCoilSpeed(w));
328                     send(Thermoregulation.requestMode(w));
329                     send(Thermoregulation.requestValvesStatus(w));
330                     send(Thermoregulation.requestActuatorsStatus(w));
331                 }
332             } catch (OWNException e) {
333                 logger.warn("refreshDevice() where='{}' returned OWNException {}", w, e.getMessage());
334             }
335         }
336     }
337 }