]> git.basschouten.com Git - openhab-addons.git/blob
dd74d6d29a665d5400588124641144ee9aba10e8
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2021 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.shelly.internal.util;
14
15 import static org.openhab.binding.shelly.internal.ShellyBindingConstants.*;
16
17 import java.io.UnsupportedEncodingException;
18 import java.math.BigDecimal;
19 import java.net.URLEncoder;
20 import java.nio.charset.StandardCharsets;
21 import java.time.DateTimeException;
22 import java.time.Instant;
23 import java.time.LocalDateTime;
24 import java.time.ZoneId;
25 import java.time.ZonedDateTime;
26
27 import javax.measure.Unit;
28
29 import org.eclipse.jdt.annotation.NonNullByDefault;
30 import org.eclipse.jdt.annotation.Nullable;
31 import org.openhab.binding.shelly.internal.api.ShellyApiException;
32 import org.openhab.binding.shelly.internal.api.ShellyDeviceProfile;
33 import org.openhab.core.library.types.DateTimeType;
34 import org.openhab.core.library.types.DecimalType;
35 import org.openhab.core.library.types.OnOffType;
36 import org.openhab.core.library.types.PercentType;
37 import org.openhab.core.library.types.QuantityType;
38 import org.openhab.core.library.types.StringType;
39 import org.openhab.core.types.Command;
40 import org.openhab.core.types.State;
41 import org.openhab.core.types.UnDefType;
42
43 /**
44  * {@link ShellyUtils} provides general utility functions
45  *
46  * @author Markus Michels - Initial contribution
47  */
48 @NonNullByDefault
49 public class ShellyUtils {
50     public static String mkChannelId(String group, String channel) {
51         return group + "#" + channel;
52     }
53
54     public static String getString(@Nullable String value) {
55         return value != null ? value : "";
56     }
57
58     public static String substringBefore(@Nullable String string, String pattern) {
59         if (string != null) {
60             int pos = string.indexOf(pattern);
61             if (pos > 0) {
62                 return string.substring(0, pos);
63             }
64         }
65         return "";
66     }
67
68     public static String substringBeforeLast(@Nullable String string, String pattern) {
69         if (string != null) {
70             int pos = string.lastIndexOf(pattern);
71             if (pos > 0) {
72                 return string.substring(0, pos);
73             }
74         }
75         return "";
76     }
77
78     public static String substringAfter(@Nullable String string, String pattern) {
79         if (string != null) {
80             int pos = string.indexOf(pattern);
81             if (pos != -1) {
82                 return string.substring(pos + pattern.length());
83             }
84         }
85         return "";
86     }
87
88     public static String substringAfterLast(@Nullable String string, String pattern) {
89         if (string != null) {
90             int pos = string.lastIndexOf(pattern);
91             if (pos != -1) {
92                 return string.substring(pos + pattern.length());
93             }
94         }
95         return "";
96     }
97
98     public static String substringBetween(@Nullable String string, String begin, String end) {
99         if (string != null) {
100             int s = string.indexOf(begin);
101             if (s != -1) {
102                 // The end tag might be included before the start tag, e.g.
103                 // when using "http://" and ":" to get the IP from http://192.168.1.1:8081/xxx
104                 // therefore make it 2 steps
105                 String result = string.substring(s + begin.length());
106                 return substringBefore(result, end);
107             }
108         }
109         return "";
110     }
111
112     public static String getMessage(Exception e) {
113         String message = e.getMessage();
114         return message != null ? message : "";
115     }
116
117     public static Integer getInteger(@Nullable Integer value) {
118         return (value != null ? (Integer) value : 0);
119     }
120
121     public static Long getLong(@Nullable Long value) {
122         return (value != null ? (Long) value : 0);
123     }
124
125     public static Double getDouble(@Nullable Double value) {
126         return (value != null ? (Double) value : 0);
127     }
128
129     public static Boolean getBool(@Nullable Boolean value) {
130         return (value != null ? (Boolean) value : false);
131     }
132
133     // as State
134
135     public static StringType getStringType(@Nullable String value) {
136         return new StringType(value != null ? value : "");
137     }
138
139     public static DecimalType getDecimal(@Nullable Double value) {
140         return new DecimalType((value != null ? value : 0));
141     }
142
143     public static DecimalType getDecimal(@Nullable Integer value) {
144         return new DecimalType((value != null ? value : 0));
145     }
146
147     public static DecimalType getDecimal(@Nullable Long value) {
148         return new DecimalType((value != null ? value : 0));
149     }
150
151     public static Double getNumber(Command command) throws IllegalArgumentException {
152         if (command instanceof DecimalType) {
153             return ((DecimalType) command).doubleValue();
154         }
155         if (command instanceof QuantityType) {
156             return ((QuantityType<?>) command).doubleValue();
157         }
158         throw new IllegalArgumentException("Unable to convert number");
159     }
160
161     public static OnOffType getOnOff(@Nullable Boolean value) {
162         return (value != null ? value ? OnOffType.ON : OnOffType.OFF : OnOffType.OFF);
163     }
164
165     public static OnOffType getOnOff(int value) {
166         return value == 0 ? OnOffType.OFF : OnOffType.ON;
167     }
168
169     public static State toQuantityType(@Nullable Double value, int digits, Unit<?> unit) {
170         if (value == null) {
171             return UnDefType.NULL;
172         }
173         BigDecimal bd = new BigDecimal(value.doubleValue());
174         return toQuantityType(bd.setScale(digits, BigDecimal.ROUND_HALF_UP), unit);
175     }
176
177     public static State toQuantityType(@Nullable Number value, Unit<?> unit) {
178         return value == null ? UnDefType.NULL : new QuantityType<>(value, unit);
179     }
180
181     public static State toQuantityType(@Nullable PercentType value, Unit<?> unit) {
182         return value == null ? UnDefType.NULL : toQuantityType(value.toBigDecimal(), unit);
183     }
184
185     public static void validateRange(String name, Integer value, int min, int max) {
186         if ((value < min) || (value > max)) {
187             throw new IllegalArgumentException("Value " + name + " is out of range (" + min + "-" + max + ")");
188         }
189     }
190
191     public static String urlEncode(String input) throws ShellyApiException {
192         try {
193             return URLEncoder.encode(input, StandardCharsets.UTF_8.toString());
194         } catch (UnsupportedEncodingException e) {
195             throw new ShellyApiException(
196                     "Unsupported encoding format: " + StandardCharsets.UTF_8.toString() + ", input=" + input, e);
197         }
198     }
199
200     public static Long now() {
201         return System.currentTimeMillis() / 1000L;
202     }
203
204     public static DateTimeType getTimestamp() {
205         return new DateTimeType(ZonedDateTime.ofInstant(Instant.ofEpochSecond(now()), ZoneId.systemDefault()));
206     }
207
208     public static DateTimeType getTimestamp(String zone, long timestamp) {
209         try {
210             if (timestamp == 0) {
211                 return getTimestamp();
212             }
213             ZoneId zoneId = !zone.isEmpty() ? ZoneId.of(zone) : ZoneId.systemDefault();
214             ZonedDateTime zdt = LocalDateTime.now().atZone(zoneId);
215             int delta = zdt.getOffset().getTotalSeconds();
216             return new DateTimeType(ZonedDateTime.ofInstant(Instant.ofEpochSecond(timestamp - delta), zoneId));
217         } catch (DateTimeException e) {
218             // Unable to convert device's timezone, use system one
219             return getTimestamp();
220         }
221     }
222
223     public static Integer getLightIdFromGroup(String groupName) {
224         if (groupName.startsWith(CHANNEL_GROUP_LIGHT_CHANNEL)) {
225             return Integer.parseInt(substringAfter(groupName, CHANNEL_GROUP_LIGHT_CHANNEL)) - 1;
226         }
227         return 0; // only 1 light, e.g. bulb or rgbw2 in color mode
228     }
229
230     public static String buildControlGroupName(ShellyDeviceProfile profile, Integer channelId) {
231         return profile.isBulb || profile.isDuo || profile.inColor ? CHANNEL_GROUP_LIGHT_CONTROL
232                 : CHANNEL_GROUP_LIGHT_CHANNEL + channelId.toString();
233     }
234
235     public static String buildWhiteGroupName(ShellyDeviceProfile profile, Integer channelId) {
236         return profile.isBulb || profile.isDuo && !profile.inColor ? CHANNEL_GROUP_WHITE_CONTROL
237                 : CHANNEL_GROUP_LIGHT_CHANNEL + channelId.toString();
238     }
239
240     public static DecimalType mapSignalStrength(int dbm) {
241         int strength = -1;
242         if (dbm > -60) {
243             strength = 4;
244         } else if (dbm > -70) {
245             strength = 3;
246         } else if (dbm > -80) {
247             strength = 2;
248         } else if (dbm > -90) {
249             strength = 1;
250         } else {
251             strength = 0;
252         }
253         return new DecimalType(strength);
254     }
255 }