]> git.basschouten.com Git - openhab-addons.git/blob
b370a33389d47d6cc08b4fbb83945201438c1cef
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 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.wlanthermo.internal.api.esp32;
14
15 import static org.openhab.binding.wlanthermo.internal.WlanThermoBindingConstants.*;
16 import static org.openhab.binding.wlanthermo.internal.WlanThermoUtil.requireNonNull;
17
18 import java.awt.Color;
19 import java.math.BigInteger;
20 import java.util.List;
21
22 import javax.measure.Unit;
23 import javax.measure.quantity.Temperature;
24
25 import org.eclipse.jdt.annotation.NonNullByDefault;
26 import org.openhab.binding.wlanthermo.internal.WlanThermoInputException;
27 import org.openhab.binding.wlanthermo.internal.WlanThermoUnknownChannelException;
28 import org.openhab.binding.wlanthermo.internal.WlanThermoUtil;
29 import org.openhab.binding.wlanthermo.internal.api.esp32.dto.data.Channel;
30 import org.openhab.binding.wlanthermo.internal.api.esp32.dto.data.Data;
31 import org.openhab.binding.wlanthermo.internal.api.esp32.dto.data.Pm;
32 import org.openhab.binding.wlanthermo.internal.api.esp32.dto.data.System;
33 import org.openhab.binding.wlanthermo.internal.api.esp32.dto.settings.Settings;
34 import org.openhab.core.library.types.DecimalType;
35 import org.openhab.core.library.types.HSBType;
36 import org.openhab.core.library.types.OnOffType;
37 import org.openhab.core.library.types.QuantityType;
38 import org.openhab.core.library.types.StringType;
39 import org.openhab.core.library.unit.ImperialUnits;
40 import org.openhab.core.library.unit.SIUnits;
41 import org.openhab.core.library.unit.Units;
42 import org.openhab.core.thing.ChannelUID;
43 import org.openhab.core.types.Command;
44 import org.openhab.core.types.State;
45 import org.openhab.core.types.UnDefType;
46
47 /**
48  * The {@link WlanThermoEsp32CommandHandler} is responsible for mapping the Commands to the respective data fields
49  * of the API.
50  *
51  * @author Christian Schlipp - Initial contribution
52  */
53 @NonNullByDefault
54 public class WlanThermoEsp32CommandHandler {
55
56     public static State getState(ChannelUID channelUID, Data data, Settings settings)
57             throws WlanThermoUnknownChannelException, WlanThermoInputException {
58
59         String groupId = requireNonNull(channelUID.getGroupId());
60         System system = data.getSystem();
61         Unit<Temperature> unit = "F".equals(system.getUnit()) ? ImperialUnits.FAHRENHEIT : SIUnits.CELSIUS;
62
63         List<Channel> channelList = data.getChannel();
64         if (SYSTEM.equals(groupId)) {
65             switch (channelUID.getIdWithoutGroup()) {
66                 case SYSTEM_SOC:
67                     if (system.getSoc() != null) {
68                         return new DecimalType(system.getSoc());
69                     } else {
70                         return UnDefType.UNDEF;
71                     }
72                 case SYSTEM_CHARGE:
73                     if (system.getCharge() != null) {
74                         return OnOffType.from(system.getCharge());
75                     } else {
76                         return UnDefType.UNDEF;
77                     }
78                 case SYSTEM_RSSI_SIGNALSTRENGTH:
79                     int dbm = system.getRssi();
80                     if (dbm >= -80) {
81                         return SIGNAL_STRENGTH_4;
82                     } else if (dbm >= -95) {
83                         return SIGNAL_STRENGTH_3;
84                     } else if (dbm >= -105) {
85                         return SIGNAL_STRENGTH_2;
86                     } else {
87                         return SIGNAL_STRENGTH_1;
88                     }
89                 case SYSTEM_RSSI:
90                     return new QuantityType<>(system.getRssi(), Units.DECIBEL_MILLIWATTS);
91             }
92         } else if (channelUID.getId().startsWith(CHANNEL_PREFIX)) {
93             int channelId = Integer.parseInt(groupId.substring(CHANNEL_PREFIX.length())) - 1;
94             if (channelList != null && !channelList.isEmpty() && channelId < channelList.size()) {
95                 Channel channel = channelList.get(channelId);
96                 switch (channelUID.getIdWithoutGroup()) {
97                     case CHANNEL_NAME:
98                         return new StringType(channel.getName());
99                     case CHANNEL_TYP:
100                         return new StringType(settings.getSensors().get(channel.getTyp()).getName());
101                     case CHANNEL_TEMP:
102                         return channel.getTemp() == 999.0 ? UnDefType.UNDEF
103                                 : new QuantityType<>(channel.getTemp(), unit);
104                     case CHANNEL_MIN:
105                         return new QuantityType<>(channel.getMin(), unit);
106                     case CHANNEL_MAX:
107                         return new QuantityType<>(channel.getMax(), unit);
108                     case CHANNEL_ALARM_DEVICE:
109                         return OnOffType.from(BigInteger.valueOf(channel.getAlarm()).testBit(1));
110                     case CHANNEL_ALARM_PUSH:
111                         return OnOffType.from(BigInteger.valueOf(channel.getAlarm()).testBit(0));
112                     case CHANNEL_ALARM_OPENHAB_HIGH:
113                         if (channel.getTemp() != 999 && channel.getTemp() > channel.getMax()) {
114                             return OnOffType.ON;
115                         } else {
116                             return OnOffType.OFF;
117                         }
118                     case CHANNEL_ALARM_OPENHAB_LOW:
119                         if (channel.getTemp() != 999 && channel.getTemp() < channel.getMin()) {
120                             return OnOffType.ON;
121                         } else {
122                             return OnOffType.OFF;
123                         }
124                     case CHANNEL_COLOR:
125                         String color = channel.getColor();
126                         if (color != null && !color.isEmpty()) {
127                             Color c = Color.decode(color);
128                             return HSBType.fromRGB(c.getRed(), c.getGreen(), c.getBlue());
129                         } else {
130                             return UnDefType.UNDEF;
131                         }
132                     case CHANNEL_COLOR_NAME:
133                         String colorHex = channel.getColor();
134                         if (colorHex != null && !colorHex.isEmpty()) {
135                             return new StringType(WlanThermoEsp32Util.toColorName(colorHex));
136                         } else {
137                             return UnDefType.UNDEF;
138                         }
139                 }
140             }
141         } else if (channelUID.getId().startsWith(CHANNEL_PITMASTER_PREFIX)) {
142             int channelId = Integer.parseInt(groupId.substring(CHANNEL_PITMASTER_PREFIX.length())) - 1;
143             if (settings.getFeatures().getPitmaster() && data.getPitmaster() != null
144                     && data.getPitmaster().getPm() != null && data.getPitmaster().getPm().size() > channelId) {
145                 Pm pm = data.getPitmaster().getPm().get(channelId);
146                 switch (channelUID.getIdWithoutGroup()) {
147                     case CHANNEL_PITMASTER_CHANNEL_ID:
148                         return new DecimalType(pm.getChannel());
149                     case CHANNEL_PITMASTER_PIDPROFILE:
150                         return new DecimalType(pm.getPid());
151                     case CHANNEL_PITMASTER_DUTY_CYCLE:
152                         return new DecimalType(pm.getValue());
153                     case CHANNEL_PITMASTER_SETPOINT:
154                         return new QuantityType<>(pm.getSet(), unit);
155                     case CHANNEL_PITMASTER_STATE:
156                         return new StringType(pm.getTyp());
157                 }
158             } else {
159                 return UnDefType.UNDEF;
160             }
161         }
162         throw new WlanThermoUnknownChannelException(channelUID);
163     }
164
165     public static boolean setState(ChannelUID channelUID, Command command, Data data, Settings settings) {
166         String groupId;
167         try {
168             groupId = requireNonNull(channelUID.getGroupId());
169         } catch (WlanThermoInputException ignore) {
170             return false;
171         }
172
173         List<Channel> channelList = data.getChannel();
174         System system = data.getSystem();
175         Unit<Temperature> unit = "F".equals(system.getUnit()) ? ImperialUnits.FAHRENHEIT : SIUnits.CELSIUS;
176
177         if (channelUID.getId().startsWith(CHANNEL_PREFIX)) {
178             int channelId = Integer.parseInt(groupId.substring(CHANNEL_PREFIX.length())) - 1;
179             if (!channelList.isEmpty() && channelId < channelList.size()) {
180                 Channel channel = channelList.get(channelId);
181                 switch (channelUID.getIdWithoutGroup()) {
182                     case CHANNEL_NAME:
183                         if (command instanceof StringType) {
184                             channel.setName(command.toFullString());
185                             return true;
186                         }
187                         return false;
188                     case CHANNEL_MIN:
189                         if (command instanceof QuantityType) {
190                             try {
191                                 channel.setMin(requireNonNull(((QuantityType<?>) command).toUnit(unit)).doubleValue());
192                                 return true;
193                             } catch (WlanThermoInputException ignore) {
194                                 return false;
195                             }
196                         }
197                         return false;
198                     case CHANNEL_MAX:
199                         if (command instanceof QuantityType) {
200                             try {
201                                 channel.setMax(requireNonNull(((QuantityType<?>) command).toUnit(unit)).doubleValue());
202                                 return true;
203                             } catch (WlanThermoInputException ignore) {
204                                 return false;
205                             }
206                         }
207                         return false;
208                     case CHANNEL_ALARM_DEVICE:
209                         if (command instanceof OnOffType) {
210                             BigInteger value;
211                             if (command == OnOffType.ON) {
212                                 value = BigInteger.valueOf(channel.getAlarm()).setBit(1);
213                             } else {
214                                 value = BigInteger.valueOf(channel.getAlarm()).clearBit(1);
215                             }
216                             channel.setAlarm(value.intValue());
217                             return true;
218                         }
219                         return false;
220                     case CHANNEL_ALARM_PUSH:
221                         if (command instanceof OnOffType) {
222                             BigInteger value;
223                             if (command == OnOffType.ON) {
224                                 value = BigInteger.valueOf(channel.getAlarm()).setBit(0);
225                             } else {
226                                 value = BigInteger.valueOf(channel.getAlarm()).clearBit(0);
227                             }
228                             channel.setAlarm(value.intValue());
229                             return true;
230                         }
231                         return false;
232                     case CHANNEL_COLOR_NAME:
233                         if (command instanceof StringType) {
234                             channel.setColor(WlanThermoEsp32Util.toHex(((StringType) command).toString()));
235                             return true;
236                         }
237                         return false;
238                     case CHANNEL_COLOR:
239                         if (command instanceof HSBType) {
240                             channel.setColor(WlanThermoUtil.toHex((HSBType) command));
241                             return true;
242                         }
243                         return false;
244                 }
245             }
246         } else if (channelUID.getId().startsWith(CHANNEL_PITMASTER_PREFIX)) {
247             int channelId = Integer.parseInt(groupId.substring(CHANNEL_PITMASTER_PREFIX.length())) - 1;
248             if (settings.getFeatures().getPitmaster() && data.getPitmaster() != null
249                     && data.getPitmaster().getPm() != null && data.getPitmaster().getPm().size() > channelId) {
250                 Pm pm = data.getPitmaster().getPm().get(channelId);
251                 switch (channelUID.getIdWithoutGroup()) {
252                     case CHANNEL_PITMASTER_CHANNEL_ID:
253                         pm.setChannel(((DecimalType) command).intValue());
254                         return true;
255                     case CHANNEL_PITMASTER_PIDPROFILE:
256                         pm.setPid(((DecimalType) command).intValue());
257                         return true;
258                     case CHANNEL_PITMASTER_SETPOINT:
259                         try {
260                             pm.setSet(requireNonNull(((QuantityType<?>) command).toUnit(unit)).doubleValue());
261                             return true;
262                         } catch (WlanThermoInputException ignore) {
263                             return false;
264                         }
265                     case CHANNEL_PITMASTER_STATE:
266                         String state = ((StringType) command).toString();
267                         if (state.equalsIgnoreCase("off") || state.equalsIgnoreCase("manual")
268                                 || state.equalsIgnoreCase("auto")) {
269                             pm.setTyp(state);
270                             return true;
271                         }
272                         return false;
273                 }
274             }
275         }
276         return false;
277     }
278
279     public static String getTrigger(ChannelUID channelUID, Data data)
280             throws WlanThermoUnknownChannelException, WlanThermoInputException {
281         String groupId = requireNonNull(channelUID.getGroupId());
282         List<Channel> channelList = data.getChannel();
283
284         if (channelUID.getId().startsWith(CHANNEL_PREFIX)) {
285             int channelId = Integer.parseInt(groupId.substring(CHANNEL_PREFIX.length())) - 1;
286             if (!channelList.isEmpty() && channelId < channelList.size()) {
287                 Channel channel = channelList.get(channelId);
288                 if (CHANNEL_ALARM_OPENHAB.equals(channelUID.getIdWithoutGroup())) {
289                     if (channel.getTemp() != 999) {
290                         if (channel.getTemp() > channel.getMax()) {
291                             return TRIGGER_ALARM_MAX;
292                         } else if (channel.getTemp() < channel.getMin()) {
293                             return TRIGGER_ALARM_MIN;
294                         } else {
295                             return TRIGGER_NONE;
296                         }
297                     }
298                 }
299             }
300         }
301         throw new WlanThermoUnknownChannelException(channelUID);
302     }
303 }