]> git.basschouten.com Git - openhab-addons.git/blob
dce7452407ab55fc66322891101c2baa1370e2f7
[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
14 package org.openhab.binding.souliss.internal.handler;
15
16 import javax.measure.quantity.Temperature;
17
18 import org.eclipse.jdt.annotation.NonNullByDefault;
19 import org.openhab.binding.souliss.internal.SoulissBindingConstants;
20 import org.openhab.binding.souliss.internal.SoulissProtocolConstants;
21 import org.openhab.binding.souliss.internal.protocol.HalfFloatUtils;
22 import org.openhab.core.library.types.OnOffType;
23 import org.openhab.core.library.types.QuantityType;
24 import org.openhab.core.library.types.StringType;
25 import org.openhab.core.library.unit.SIUnits;
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.types.Command;
30 import org.openhab.core.types.PrimitiveType;
31 import org.openhab.core.types.RefreshType;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
34
35 /**
36  * The {@link SoulissT31Handler} is responsible for handling commands, which are
37  * sent to one of the channels.
38  *
39  * @author Luca Remigio - Initial contribution
40  * @author Luca Calcaterra - Refactor for OH3
41  */
42 @NonNullByDefault
43 public class SoulissT31Handler extends SoulissGenericHandler {
44
45     private final Logger logger = LoggerFactory.getLogger(SoulissT31Handler.class);
46
47     QuantityType<Temperature> setMeasuredValue = new QuantityType<>("0");
48     QuantityType<Temperature> setPointValue = new QuantityType<>("0");
49     StringType fanStateValue = StringType.EMPTY;
50     StringType powerState = StringType.EMPTY;
51     StringType fireState = StringType.EMPTY;
52     StringType lastModeState = StringType.EMPTY;
53     StringType modeStateValue = StringType.EMPTY;
54
55     public SoulissT31Handler(Thing pThing) {
56         super(pThing);
57         thing = pThing;
58     }
59
60     // called on every status change or change request
61     @Override
62     public void handleCommand(ChannelUID channelUID, Command command) {
63         if (!(command instanceof RefreshType)) {
64             switch (channelUID.getId()) {
65                 // FAN
66                 case SoulissBindingConstants.T31_SYSTEM_CHANNEL:
67                     if (command.equals(OnOffType.OFF)) {
68                         commandSEND(SoulissProtocolConstants.SOULISS_T3N_SHUTDOWN);
69                     } else {
70                         if (modeStateValue.toString()
71                                 .equals(SoulissBindingConstants.T31_HEATINGMODE_MESSAGE_MODE_CHANNEL)) {
72                             commandSEND(SoulissProtocolConstants.SOULISS_T3N_HEATING);
73                         } else {
74                             commandSEND(SoulissProtocolConstants.SOULISS_T3N_COOLING);
75                         }
76                     }
77                     break;
78                 case SoulissBindingConstants.T31_MODE_CHANNEL:
79                     if (command.toString().equals(SoulissBindingConstants.T31_HEATINGMODE_MESSAGE_MODE_CHANNEL)) {
80                         commandSEND(SoulissProtocolConstants.SOULISS_T3N_HEATING);
81                     } else {
82                         commandSEND(SoulissProtocolConstants.SOULISS_T3N_COOLING);
83                     }
84                     break;
85                 case SoulissBindingConstants.T31_BUTTON_CHANNEL:
86                     if (command.equals(OnOffType.ON)) {
87                         commandSEND(SoulissProtocolConstants.SOULISS_T3N_AS_MEASURED);
88                     }
89                     break;
90                 case SoulissBindingConstants.T31_FAN_CHANNEL:
91                     switch (command.toString()) {
92                         case SoulissBindingConstants.T31_FANHIGH_MESSAGE_FAN_CHANNEL:
93                             commandSEND(SoulissProtocolConstants.SOULISS_T3N_FAN_MANUAL);
94                             commandSEND(SoulissProtocolConstants.SOULISS_T3N_FAN_HIGH);
95                             fanStateValue = StringType.valueOf(SoulissBindingConstants.T31_FANHIGH_MESSAGE_FAN_CHANNEL);
96                             break;
97                         case SoulissBindingConstants.T31_FANMEDIUM_MESSAGE_FAN_CHANNEL:
98                             commandSEND(SoulissProtocolConstants.SOULISS_T3N_FAN_MANUAL);
99                             commandSEND(SoulissProtocolConstants.SOULISS_T3N_FAN_MED);
100                             fanStateValue = StringType
101                                     .valueOf(SoulissBindingConstants.T31_FANMEDIUM_MESSAGE_FAN_CHANNEL);
102                             break;
103                         case SoulissBindingConstants.T31_FANLOW_MESSAGE_FAN_CHANNEL:
104                             commandSEND(SoulissProtocolConstants.SOULISS_T3N_FAN_MANUAL);
105                             commandSEND(SoulissProtocolConstants.SOULISS_T3N_FAN_LOW);
106                             fanStateValue = StringType.valueOf(SoulissBindingConstants.T31_FANLOW_MESSAGE_FAN_CHANNEL);
107                             break;
108                         case SoulissBindingConstants.T31_FANAUTO_MESSAGE_FAN_CHANNEL:
109                             commandSEND(SoulissProtocolConstants.SOULISS_T3N_FAN_AUTO);
110                             fanStateValue = StringType.valueOf(SoulissBindingConstants.T31_FANAUTO_MESSAGE_FAN_CHANNEL);
111                             break;
112                         case SoulissBindingConstants.T31_FANOFF_MESSAGE_FAN_CHANNEL:
113                             commandSEND(SoulissProtocolConstants.SOULISS_T3N_FAN_OFF);
114                             fanStateValue = StringType.valueOf(SoulissBindingConstants.T31_FANOFF_MESSAGE_FAN_CHANNEL);
115                             break;
116                         default:
117                             logger.debug("Fan Channel handle not recognized, skipping..");
118                             break;
119                     }
120                     break;
121                 case SoulissBindingConstants.T31_SETPOINT_CHANNEL:
122                     if (command instanceof QuantityType<?>) {
123                         int uu = HalfFloatUtils.fromFloat(((QuantityType<?>) command).floatValue());
124                         byte b2 = (byte) (uu >> 8);
125                         byte b1 = (byte) uu;
126                         // setpoint command
127                         commandSEND(SoulissProtocolConstants.SOULISS_T31_USE_OF_SLOT_SETPOINT_COMMAND, b1, b2);
128                     }
129                     break;
130
131                 default:
132                     logger.debug("state not recognized! skipping..");
133                     break;
134             }
135         }
136     }
137
138     @Override
139     public void initialize() {
140         super.initialize();
141
142         updateStatus(ThingStatus.UNKNOWN);
143
144         var configurationMap = getThing().getConfiguration();
145         if (configurationMap.get(SoulissBindingConstants.CONFIG_SECURE_SEND) != null) {
146             bSecureSend = ((Boolean) configurationMap.get(SoulissBindingConstants.CONFIG_SECURE_SEND)).booleanValue();
147         }
148     }
149
150     public void setState(PrimitiveType state) {
151         this.updateState(SoulissBindingConstants.T31_BUTTON_CHANNEL, OnOffType.OFF);
152
153         super.setLastStatusStored();
154         if (state instanceof StringType) {
155             switch (state.toString()) {
156                 case SoulissBindingConstants.T31_FANLOW_MESSAGE_FAN_CHANNEL:
157                 case SoulissBindingConstants.T31_FANMEDIUM_MESSAGE_FAN_CHANNEL:
158                 case SoulissBindingConstants.T31_FANHIGH_MESSAGE_FAN_CHANNEL:
159                 case SoulissBindingConstants.T31_FANAUTO_MESSAGE_FAN_CHANNEL:
160                 case SoulissBindingConstants.T31_FANOFF_MESSAGE_FAN_CHANNEL:
161                     if (!fanStateValue.equals(state)) {
162                         this.updateState(SoulissBindingConstants.T31_FAN_CHANNEL, (StringType) state);
163                         fanStateValue = (StringType) state;
164                     }
165                     break;
166
167                 case SoulissBindingConstants.T31_HEATINGMODE_MESSAGE_MODE_CHANNEL:
168                     if (!modeStateValue.equals(state)) {
169                         this.updateState(SoulissBindingConstants.T31_MODE_CHANNEL, (StringType) state);
170                         modeStateValue = (StringType) state;
171                     }
172                     break;
173
174                 case SoulissBindingConstants.T31_COOLINGMODE_MESSAGE_MODE_CHANNEL:
175                     if (!modeStateValue.equals(state)) {
176                         this.updateState(SoulissBindingConstants.T31_MODE_CHANNEL, (StringType) state);
177                         modeStateValue = (StringType) state;
178                     }
179                     break;
180
181                 case SoulissBindingConstants.T31_OFF_MESSAGE_SYSTEM_CHANNEL:
182                     if (!powerState.equals(state)) {
183                         this.updateState(SoulissBindingConstants.T31_SYSTEM_CHANNEL, OnOffType.OFF);
184                         powerState = (StringType) state;
185                     }
186                     break;
187                 case SoulissBindingConstants.T31_ON_MESSAGE_SYSTEM_CHANNEL:
188                     if (!powerState.equals(state)) {
189                         this.updateState(SoulissBindingConstants.T31_SYSTEM_CHANNEL, OnOffType.ON);
190                         powerState = (StringType) state;
191                     }
192                     break;
193
194                 case SoulissBindingConstants.T31_ON_MESSAGE_FIRE_CHANNEL:
195                     if (!fireState.equals(state)) {
196                         this.updateState(SoulissBindingConstants.T31_FIRE_CHANNEL, OnOffType.ON);
197                         fireState = (StringType) state;
198                     }
199                     break;
200                 case SoulissBindingConstants.T31_OFF_MESSAGE_FIRE_CHANNEL:
201                     if (!fireState.equals(state)) {
202                         this.updateState(SoulissBindingConstants.T31_FIRE_CHANNEL, OnOffType.OFF);
203                         fireState = (StringType) state;
204                     }
205                     break;
206
207                 default:
208             }
209
210         }
211     }
212
213     public void setMeasuredValue(QuantityType<Temperature> valueOf) {
214         if ((valueOf instanceof QuantityType<?>) && (!setMeasuredValue.equals(valueOf))) {
215             this.updateState(SoulissBindingConstants.T31_VALUE_CHANNEL, valueOf);
216             setMeasuredValue = valueOf;
217         }
218     }
219
220     public void setSetpointValue(QuantityType<Temperature> valueOf) {
221         if ((valueOf instanceof QuantityType<?>) && (!setPointValue.equals(valueOf))) {
222             this.updateState(SoulissBindingConstants.T31_SETPOINT_CHANNEL, valueOf);
223             setPointValue = valueOf;
224         }
225     }
226
227     public void setRawStateValues(byte rawStateByte0, float valTemp, float valSetPoint) {
228         var sMessage = "";
229         switch (getBitState(rawStateByte0, 0)) {
230             case 0:
231                 sMessage = SoulissBindingConstants.T31_OFF_MESSAGE_SYSTEM_CHANNEL;
232                 break;
233             case 1:
234                 sMessage = SoulissBindingConstants.T31_ON_MESSAGE_SYSTEM_CHANNEL;
235                 break;
236             default:
237                 logger.debug("System Channel on/off not recognized, skipping");
238                 break;
239         }
240         this.setState(StringType.valueOf(sMessage));
241
242         switch (getBitState(rawStateByte0, 7)) {
243             case 0:
244                 sMessage = SoulissBindingConstants.T31_HEATINGMODE_MESSAGE_MODE_CHANNEL;
245                 break;
246             case 1:
247                 sMessage = SoulissBindingConstants.T31_COOLINGMODE_MESSAGE_MODE_CHANNEL;
248                 break;
249             default:
250                 logger.debug("Mode not recognized, skipping");
251                 break;
252         }
253         this.setState(StringType.valueOf(sMessage));
254
255         // button indicating whether the system is running or not
256         switch (getBitState(rawStateByte0, 1) + getBitState(rawStateByte0, 2)) {
257             case 0:
258                 sMessage = SoulissBindingConstants.T31_OFF_MESSAGE_FIRE_CHANNEL;
259                 break;
260             case 1:
261                 sMessage = SoulissBindingConstants.T31_ON_MESSAGE_FIRE_CHANNEL;
262                 break;
263             default:
264                 logger.debug("Fire not recognized, skipping");
265                 break;
266         }
267         this.setState(StringType.valueOf(sMessage));
268
269         // FAN SPEED
270         switch (getBitState(rawStateByte0, 3) + getBitState(rawStateByte0, 4) + getBitState(rawStateByte0, 5)) {
271             case 0:
272                 sMessage = SoulissBindingConstants.T31_FANOFF_MESSAGE_FAN_CHANNEL;
273                 break;
274             case 1:
275                 sMessage = SoulissBindingConstants.T31_FANLOW_MESSAGE_FAN_CHANNEL;
276                 break;
277             case 2:
278                 sMessage = SoulissBindingConstants.T31_FANMEDIUM_MESSAGE_FAN_CHANNEL;
279                 break;
280             case 3:
281                 sMessage = SoulissBindingConstants.T31_FANHIGH_MESSAGE_FAN_CHANNEL;
282                 break;
283             default:
284                 logger.debug("Fan speed not recognized, skipping");
285                 break;
286         }
287
288         this.setState(StringType.valueOf(sMessage));
289
290         // SLOT 1-2: Temperature Value
291         if (!Float.isNaN(valTemp)) {
292             this.setMeasuredValue(QuantityType.valueOf(valTemp, SIUnits.CELSIUS));
293         }
294
295         // SLOT 3-4: Setpoint Value
296         if (!Float.isNaN(valSetPoint)) {
297             this.setSetpointValue(QuantityType.valueOf(valSetPoint, SIUnits.CELSIUS));
298         }
299     }
300
301     @Override
302     public byte getRawState() {
303         return 0;
304     }
305
306     @Override
307     public byte getExpectedRawState(byte bCommand) {
308         return 0;
309     }
310
311     public byte getBitState(byte vRaw, int iBit) {
312         final var maskBit1 = 0x1;
313
314         if (((vRaw >>> iBit) & maskBit1) == 0) {
315             return 0;
316         } else {
317             return 1;
318         }
319     }
320
321     @Override
322     public void setRawState(byte rawState) {
323         throw new UnsupportedOperationException("Not Implemented, yet.");
324     }
325 }