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 {
58 String groupId = requireNonNull(channelUID.getGroupId());
59 System system = data.getSystem();
60 Unit<Temperature> unit = "F".equals(system.getUnit()) ? ImperialUnits.FAHRENHEIT : SIUnits.CELSIUS;
62 List<Channel> channelList = data.getChannel();
63 if (SYSTEM.equals(groupId)) {
64 switch (channelUID.getIdWithoutGroup()) {
66 if (system.getSoc() != null) {
67 return new DecimalType(system.getSoc());
69 return UnDefType.UNDEF;
72 if (system.getCharge() != null) {
73 return OnOffType.from(system.getCharge());
75 return UnDefType.UNDEF;
77 case SYSTEM_RSSI_SIGNALSTRENGTH:
78 int dbm = system.getRssi();
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;
86 return SIGNAL_STRENGTH_1;
89 return new QuantityType<>(system.getRssi(), Units.DECIBEL_MILLIWATTS);
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()) {
97 return new StringType(channel.getName());
99 return new StringType(settings.getSensors().get(channel.getTyp()).getName());
101 return channel.getTemp() == 999.0 ? UnDefType.UNDEF
102 : new QuantityType<>(channel.getTemp(), unit);
104 return new QuantityType<>(channel.getMin(), unit);
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()) {
115 return OnOffType.OFF;
117 case CHANNEL_ALARM_OPENHAB_LOW:
118 if (channel.getTemp() != 999 && channel.getTemp() < channel.getMin()) {
121 return OnOffType.OFF;
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());
129 return UnDefType.UNDEF;
131 case CHANNEL_COLOR_NAME:
132 String colorHex = channel.getColor();
133 if (colorHex != null && !colorHex.isEmpty()) {
134 return new StringType(WlanThermoEsp32Util.toColorName(colorHex));
136 return UnDefType.UNDEF;
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());
158 return UnDefType.UNDEF;
161 throw new WlanThermoUnknownChannelException(channelUID);
164 public static boolean setState(ChannelUID channelUID, Command command, Data data, Settings settings) {
167 groupId = requireNonNull(channelUID.getGroupId());
168 } catch (WlanThermoInputException ignore) {
172 List<Channel> channelList = data.getChannel();
173 System system = data.getSystem();
174 Unit<Temperature> unit = "F".equals(system.getUnit()) ? ImperialUnits.FAHRENHEIT : SIUnits.CELSIUS;
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()) {
182 if (command instanceof StringType) {
183 channel.setName(command.toFullString());
188 if (command instanceof QuantityType quantityCommand) {
190 channel.setMin(requireNonNull(quantityCommand.toUnit(unit)).doubleValue());
192 } catch (WlanThermoInputException ignore) {
198 if (command instanceof QuantityType quantityCommand) {
200 channel.setMax(requireNonNull(quantityCommand.toUnit(unit)).doubleValue());
202 } catch (WlanThermoInputException ignore) {
207 case CHANNEL_ALARM_DEVICE:
208 if (command instanceof OnOffType) {
210 if (command == OnOffType.ON) {
211 value = BigInteger.valueOf(channel.getAlarm()).setBit(1);
213 value = BigInteger.valueOf(channel.getAlarm()).clearBit(1);
215 channel.setAlarm(value.intValue());
219 case CHANNEL_ALARM_PUSH:
220 if (command instanceof OnOffType) {
222 if (command == OnOffType.ON) {
223 value = BigInteger.valueOf(channel.getAlarm()).setBit(0);
225 value = BigInteger.valueOf(channel.getAlarm()).clearBit(0);
227 channel.setAlarm(value.intValue());
231 case CHANNEL_COLOR_NAME:
232 if (command instanceof StringType stringCommand) {
233 channel.setColor(WlanThermoEsp32Util.toHex(stringCommand.toString()));
238 if (command instanceof HSBType hsbCommand) {
239 channel.setColor(WlanThermoUtil.toHex(hsbCommand));
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());
254 case CHANNEL_PITMASTER_PIDPROFILE:
255 pm.setPid(((DecimalType) command).intValue());
257 case CHANNEL_PITMASTER_SETPOINT:
259 pm.setSet(requireNonNull(((QuantityType<?>) command).toUnit(unit)).doubleValue());
261 } catch (WlanThermoInputException ignore) {
264 case CHANNEL_PITMASTER_STATE:
265 String state = ((StringType) command).toString();
266 if ("off".equalsIgnoreCase(state) || "manual".equalsIgnoreCase(state)
267 || "auto".equalsIgnoreCase(state)) {
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();
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;
300 throw new WlanThermoUnknownChannelException(channelUID);