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