2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
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
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.wlanthermo.internal.api.esp32;
15 import static org.openhab.binding.wlanthermo.internal.WlanThermoBindingConstants.*;
16 import static org.openhab.binding.wlanthermo.internal.WlanThermoUtil.requireNonNull;
18 import java.awt.Color;
19 import java.math.BigInteger;
20 import java.util.List;
22 import javax.measure.Unit;
23 import javax.measure.quantity.Temperature;
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;
48 * The {@link WlanThermoEsp32CommandHandler} is responsible for mapping the Commands to the respective data fields
51 * @author Christian Schlipp - Initial contribution
54 public class WlanThermoEsp32CommandHandler {
56 public static State getState(ChannelUID channelUID, Data data, Settings settings)
57 throws WlanThermoUnknownChannelException, WlanThermoInputException {
59 String groupId = requireNonNull(channelUID.getGroupId());
60 System system = data.getSystem();
61 Unit<Temperature> unit = "F".equals(system.getUnit()) ? ImperialUnits.FAHRENHEIT : SIUnits.CELSIUS;
63 List<Channel> channelList = data.getChannel();
64 if (SYSTEM.equals(groupId)) {
65 switch (channelUID.getIdWithoutGroup()) {
67 if (system.getSoc() != null) {
68 return new DecimalType(system.getSoc());
70 return UnDefType.UNDEF;
73 if (system.getCharge() != null) {
74 return OnOffType.from(system.getCharge());
76 return UnDefType.UNDEF;
78 case SYSTEM_RSSI_SIGNALSTRENGTH:
79 int dbm = system.getRssi();
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;
87 return SIGNAL_STRENGTH_1;
90 return new QuantityType<>(system.getRssi(), Units.DECIBEL_MILLIWATTS);
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()) {
98 return new StringType(channel.getName());
100 return new StringType(settings.getSensors().get(channel.getTyp()).getName());
102 return channel.getTemp() == 999.0 ? UnDefType.UNDEF
103 : new QuantityType<>(channel.getTemp(), unit);
105 return new QuantityType<>(channel.getMin(), unit);
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()) {
116 return OnOffType.OFF;
118 case CHANNEL_ALARM_OPENHAB_LOW:
119 if (channel.getTemp() != 999 && channel.getTemp() < channel.getMin()) {
122 return OnOffType.OFF;
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());
130 return UnDefType.UNDEF;
132 case CHANNEL_COLOR_NAME:
133 String colorHex = channel.getColor();
134 if (colorHex != null && !colorHex.isEmpty()) {
135 return new StringType(WlanThermoEsp32Util.toColorName(colorHex));
137 return UnDefType.UNDEF;
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());
159 return UnDefType.UNDEF;
162 throw new WlanThermoUnknownChannelException(channelUID);
165 public static boolean setState(ChannelUID channelUID, Command command, Data data, Settings settings) {
168 groupId = requireNonNull(channelUID.getGroupId());
169 } catch (WlanThermoInputException ignore) {
173 List<Channel> channelList = data.getChannel();
174 System system = data.getSystem();
175 Unit<Temperature> unit = "F".equals(system.getUnit()) ? ImperialUnits.FAHRENHEIT : SIUnits.CELSIUS;
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()) {
183 if (command instanceof StringType) {
184 channel.setName(command.toFullString());
189 if (command instanceof QuantityType) {
191 channel.setMin(requireNonNull(((QuantityType<?>) command).toUnit(unit)).doubleValue());
193 } catch (WlanThermoInputException ignore) {
199 if (command instanceof QuantityType) {
201 channel.setMax(requireNonNull(((QuantityType<?>) command).toUnit(unit)).doubleValue());
203 } catch (WlanThermoInputException ignore) {
208 case CHANNEL_ALARM_DEVICE:
209 if (command instanceof OnOffType) {
211 if (command == OnOffType.ON) {
212 value = BigInteger.valueOf(channel.getAlarm()).setBit(1);
214 value = BigInteger.valueOf(channel.getAlarm()).clearBit(1);
216 channel.setAlarm(value.intValue());
220 case CHANNEL_ALARM_PUSH:
221 if (command instanceof OnOffType) {
223 if (command == OnOffType.ON) {
224 value = BigInteger.valueOf(channel.getAlarm()).setBit(0);
226 value = BigInteger.valueOf(channel.getAlarm()).clearBit(0);
228 channel.setAlarm(value.intValue());
232 case CHANNEL_COLOR_NAME:
233 if (command instanceof StringType) {
234 channel.setColor(WlanThermoEsp32Util.toHex(((StringType) command).toString()));
239 if (command instanceof HSBType) {
240 channel.setColor(WlanThermoUtil.toHex((HSBType) command));
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());
255 case CHANNEL_PITMASTER_PIDPROFILE:
256 pm.setPid(((DecimalType) command).intValue());
258 case CHANNEL_PITMASTER_SETPOINT:
260 pm.setSet(requireNonNull(((QuantityType<?>) command).toUnit(unit)).doubleValue());
262 } catch (WlanThermoInputException ignore) {
265 case CHANNEL_PITMASTER_STATE:
266 String state = ((StringType) command).toString();
267 if (state.equalsIgnoreCase("off") || state.equalsIgnoreCase("manual")
268 || state.equalsIgnoreCase("auto")) {
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();
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;
301 throw new WlanThermoUnknownChannelException(channelUID);