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