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