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.asuswrt.internal.helpers;
15 import java.util.regex.Pattern;
17 import javax.measure.Unit;
18 import javax.measure.quantity.Energy;
19 import javax.measure.quantity.Power;
20 import javax.measure.quantity.Time;
22 import org.eclipse.jdt.annotation.NonNullByDefault;
23 import org.eclipse.jdt.annotation.Nullable;
24 import org.openhab.core.library.types.DecimalType;
25 import org.openhab.core.library.types.HSBType;
26 import org.openhab.core.library.types.OnOffType;
27 import org.openhab.core.library.types.PercentType;
28 import org.openhab.core.library.types.QuantityType;
29 import org.openhab.core.library.types.StringType;
30 import org.openhab.core.types.State;
32 import com.google.gson.Gson;
33 import com.google.gson.JsonObject;
34 import com.google.gson.JsonPrimitive;
37 * The {@link AsuswrtUtils} contains utility helper functions.
39 * @author Christian Wild - Initial Initial contribution
42 public class AsuswrtUtils {
43 private static final Pattern PATTERN_MAC_PAIRS = Pattern.compile("^([a-fA-F0-9]{2}[:\\.-]?){5}[a-fA-F0-9]{2}$");
44 private static final Pattern PATTERN_MAC_TRIPLES = Pattern.compile("^([a-fA-F0-9]{3}[:\\.-]?){3}[a-fA-F0-9]{3}$");
47 * Calculation utility methods
51 * Limits a value between limits.
53 * @param value the value that should be limited
54 * @param lowerLimit will be returned if value is below
55 * @param upperLimit will be returned if value is higher
57 public static int limitVal(@Nullable Integer value, int lowerLimit, int upperLimit) {
58 if (value == null || value < lowerLimit) {
60 } else if (value > upperLimit) {
67 * Formatting utility methods
71 * Returns a value or default value when the value is <code>null</code>.
73 * @param <T> Type of value
74 * @param value the value which should be checked
75 * @param defaultValue the default value that will be returned when <code>value</code> is <code>null</code>
77 public static <T> T getValueOrDefault(@Nullable T value, T defaultValue) {
78 return value == null ? defaultValue : value;
82 * Formats a MAC address by replacing old separator characters and adding new ones.
84 * @param mac unformatted MAC address
85 * @param newSeparatorChar new separator characters (e.g. ":","-" )
87 public static String formatMac(String mac, char newSeparatorChar) {
88 String unformatedMac = unformatMac(mac);
89 String formatedMac = "";
91 formatedMac = unformatedMac.replaceAll("(.{2})", "$1" + newSeparatorChar).substring(0, 17);
93 } catch (Exception e) {
99 * Unformats a MAC address. Removes all separator characters.
101 public static String unformatMac(String rawMac) {
103 mac = mac.replace("-", "");
104 mac = mac.replace(":", "");
105 mac = mac.replace(".", "");
106 mac = mac.replace(" ", "");
111 * Checks if a MAC address is valid.
113 public static boolean isValidMacAddress(String mac) {
114 // MAC-Addresses usually are 6 * 2 hex nibbles separated by colons,
115 // but apparently it is legal to have 4 * 3 hex nibbles as well,
116 // and the separators can be any of : or - or . or nothing.
117 return (PATTERN_MAC_PAIRS.matcher(mac).find() || PATTERN_MAC_TRIPLES.matcher(mac).find());
121 * Converts a hexadecimal String to a byte array.
123 public static byte[] hexStringToByteArray(String s) {
124 int len = s.length();
125 byte[] data = new byte[len / 2];
127 for (int i = 0; i < len; i += 2) {
128 data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i + 1), 16));
130 } catch (Exception e) {
136 * Converts a {@link String} to a <code>boolean</code>.
138 * @param s the string to be converted ('0', '1', '-1', 'true', 'false')
139 * @param defVal default value if no match was found
141 public static boolean stringToBool(@Nullable String s, boolean defVal) {
144 } else if ("1".equals(s) || "-1".equals(s)) {
146 } else if ("0".equals(s)) {
150 return Boolean.parseBoolean(s);
151 } catch (Exception e) {
158 * Converts a {@link String} to an <code>int</code>.
160 * @param s the string to be converted
161 * @param defVal the default value if the string is not a number
163 public static int stringToInteger(@Nullable String s, int defVal) {
168 return Integer.parseInt(s);
169 } catch (Exception e) {
175 * Returns the provided string if it is not <code>null</code>, empty or blank. Otherwise the default value is
178 * @param s the string to check
179 * @param defVal the default value
180 * @return the string or the default value
182 public static String stringOrDefault(@Nullable String s, String defVal) {
183 if (s == null || s.isEmpty() || s.isBlank()) {
194 * Checks if a String is valid JSON.
196 public static boolean isValidJson(String json) {
198 Gson gson = new Gson();
199 JsonObject jsnObject = gson.fromJson(json, JsonObject.class);
200 return jsnObject != null;
201 } catch (Exception e) {
207 * Gets a {@link String} value from a {@link JsonObject}.
209 * @param jsonObject the object that will be searched for the key
210 * @param name the name of the key containing the value
211 * @param defVal the default value if the key does not exist
213 public static String jsonObjectToString(@Nullable JsonObject jsonObject, String name, String defVal) {
214 if (jsonObject != null && jsonObject.has(name)) {
215 return jsonObject.get(name).getAsString();
222 * Gets a {@link String} value from a {@link JsonObject} using an empty String as default value.
224 * @param jsonObject the object that will be searched for the key
225 * @param name the name of the key containing the value
227 public static String jsonObjectToString(@Nullable JsonObject jsonObject, String name) {
228 return jsonObjectToString(jsonObject, name, "");
232 * Gets a <code>boolean</code> value from a {@link JsonObject}.
234 * @param jsonObject the object that will be searched for the key
235 * @param name the name of the key containing the value
236 * @param defVal the default value if the key does not exist
238 public static boolean jsonObjectToBool(@Nullable JsonObject jsonObject, String name, boolean defVal) {
239 if (jsonObject != null && jsonObject.has(name)) {
240 JsonPrimitive o = jsonObject.getAsJsonPrimitive(name);
242 return jsonObject.get(name).getAsBoolean();
243 } else if (o.isNumber()) {
244 Integer iVal = jsonObject.get(name).getAsInt();
245 return (iVal.equals(1) || iVal.equals(-1));
246 } else if (o.isString()) {
247 String val = jsonObject.get(name).getAsString();
248 return stringToBool(val, defVal);
255 * Gets a <code>boolean</code> value from a {@link JsonObject} using <code>false</code> as default value.
257 * @param jsonObject the object that will be searched for the key
258 * @param name the name of the key containing the value
260 public static boolean jsonObjectToBool(@Nullable JsonObject jsonObject, String name) {
261 return jsonObjectToBool(jsonObject, name, false);
265 * Gets an <code>int</code> value from a {@link JsonObject}.
267 * @param jsonObject the object that will be searched for the key
268 * @param name the name of the key containing the value
269 * @param defVal the default value if the key does not exist
271 public static int jsonObjectToInt(@Nullable JsonObject jsonObject, String name, int defVal) {
272 if (jsonObject != null && jsonObject.has(name)) {
273 JsonPrimitive o = jsonObject.getAsJsonPrimitive(name);
275 return jsonObject.get(name).getAsInt();
276 } else if (o.isString()) {
277 String val = jsonObject.get(name).getAsString();
278 return stringToInteger(val, defVal);
285 * Gets an <code>int</code> value from a {@link JsonObject} using <code>0</code> as default value.
287 * @param jsonObject the object that will be searched for the key
288 * @param name the name of the key containing the value
290 public static int jsonObjectToInt(@Nullable JsonObject jsonObject, String name) {
291 return jsonObjectToInt(jsonObject, name, 0);
295 * Gets a {@link Number} value from a {@link JsonObject}.
297 * @param jsonObject the object that will be searched for the key
298 * @param name the name of the key containing the value
299 * @param defVal the default value if the key does not exist
301 public static Number jsonObjectToNumber(@Nullable JsonObject jsonObject, String name, Number defVal) {
302 if (jsonObject != null && jsonObject.has(name)) {
303 return jsonObject.get(name).getAsNumber();
310 * Gets a {@link Number} value from a {@link JsonObject} using <code>0</code> as default value.
312 * @param jsonObject the object that will be searched for the key
313 * @param name the name of the key containing the value
315 public static Number jsonObjectToNumber(@Nullable JsonObject jsonObject, String name) {
316 return jsonObjectToNumber(jsonObject, name, 0);
320 * Type utility methods
324 * Returns an {@link OnOffType} from a {@link Boolean}.
326 public static OnOffType getOnOffType(@Nullable Boolean boolVal) {
327 return (boolVal != null ? boolVal ? OnOffType.ON : OnOffType.OFF : OnOffType.OFF);
331 * Returns an {@link OnOffType} from an {@link Integer}.
333 public static OnOffType getOnOffType(Integer intVal) {
334 return intVal == 0 ? OnOffType.OFF : OnOffType.ON;
338 * Returns a {@link StringType} from a {@link String}.
340 public static StringType getStringType(@Nullable String strVal) {
341 return new StringType(strVal != null ? strVal : "");
345 * Returns a {@link DecimalType} from a {@link Double}.
347 public static DecimalType getDecimalType(@Nullable Double numVal) {
348 return new DecimalType((numVal != null ? numVal : 0));
352 * Returns a {@link DecimalType} from an {@link Integer}.
354 public static DecimalType getDecimalType(@Nullable Integer numVal) {
355 return new DecimalType((numVal != null ? numVal : 0));
359 * Returns a {@link DecimalType} from a {@link Long}.
361 public static DecimalType getDecimalType(@Nullable Long numVal) {
362 return new DecimalType((numVal != null ? numVal : 0));
366 * Returns a {@link PercentType} from an {@link Integer}.
368 public static PercentType getPercentType(@Nullable Integer numVal) {
369 Integer val = limitVal(numVal, 0, 100);
370 return new PercentType(val);
374 * Returns a {@link HSBType} from {@link Integer}s.
376 * @param hue the hue color
377 * @param saturation the saturation (0-100)
378 * @param brightness the brightness (0-100)
380 public static HSBType getHSBType(Integer hue, Integer saturation, Integer brightness) {
381 DecimalType h = new DecimalType(hue);
382 PercentType s = new PercentType(saturation);
383 PercentType b = new PercentType(brightness);
384 return new HSBType(h, s, b);
388 * Returns a {@link QuantityType} with the {@link Time} unit.
390 public static QuantityType<Time> getTimeType(@Nullable Number numVal, Unit<Time> unit) {
391 return new QuantityType<>((numVal != null ? numVal : 0), unit);
395 * Returns a {@link QuantityType} with the {@link Power} unit.
397 public static QuantityType<Power> getPowerType(@Nullable Number numVal, Unit<Power> unit) {
398 return new QuantityType<>((numVal != null ? numVal : 0), unit);
402 * Returns a {@link QuantityType} with the {@link Energy} unit.
404 public static QuantityType<Energy> getEnergyType(@Nullable Number numVal, Unit<Energy> unit) {
405 return new QuantityType<>((numVal != null ? numVal : 0), unit);
409 * Returns a {@link QuantityType} with the provided unit.
411 public static State getQuantityType(@Nullable Number numVal, Unit<?> unit) {
412 return new QuantityType<>((numVal != null ? numVal : 0), unit);