]> git.basschouten.com Git - openhab-addons.git/blob
e04a79946cbb84ac469302dc8d5de15bf5d5dd88
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2022 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.miio.internal.basic;
14
15 import java.awt.Color;
16 import java.util.Map;
17
18 import org.eclipse.jdt.annotation.NonNullByDefault;
19 import org.eclipse.jdt.annotation.Nullable;
20 import org.openhab.core.library.types.HSBType;
21 import org.openhab.core.library.types.PercentType;
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
24
25 import com.google.gson.JsonElement;
26 import com.google.gson.JsonObject;
27 import com.google.gson.JsonParseException;
28 import com.google.gson.JsonParser;
29 import com.google.gson.JsonPrimitive;
30
31 /**
32  * Conversion for values
33  *
34  * @author Marcel Verpaalen - Initial contribution
35  */
36 @NonNullByDefault
37 public class Conversions {
38     private static final Logger LOGGER = LoggerFactory.getLogger(Conversions.class);
39
40     /**
41      * Converts a RGB+brightness input to a HSV value.
42      * *
43      *
44      * @param RGB + brightness value (note brightness in the first byte)
45      * @return HSV
46      */
47     private static JsonElement bRGBtoHSV(JsonElement bRGB) throws ClassCastException {
48         if (bRGB.isJsonPrimitive() && bRGB.getAsJsonPrimitive().isNumber()) {
49             Color rgb = new Color(bRGB.getAsInt());
50             HSBType hsb = HSBType.fromRGB(rgb.getRed(), rgb.getGreen(), rgb.getBlue());
51             hsb = new HSBType(hsb.getHue(), hsb.getSaturation(), new PercentType(bRGB.getAsInt() >>> 24));
52             return new JsonPrimitive(hsb.toFullString());
53         }
54         return bRGB;
55     }
56
57     /**
58      * Adds the brightness info (from separate channel) to a HSV value.
59      * *
60      *
61      * @param RGB
62      * @param map with device variables containing the brightness info
63      * @return HSV
64      */
65     private static JsonElement addBrightToHSV(JsonElement rgbValue, @Nullable Map<String, Object> deviceVariables)
66             throws ClassCastException, IllegalStateException {
67         int bright = 100;
68         if (deviceVariables != null) {
69             JsonElement lastBright = (JsonElement) deviceVariables.getOrDefault("bright", new JsonPrimitive(100));
70             bright = lastBright.getAsInt();
71         }
72         if (rgbValue.isJsonPrimitive()
73                 && (rgbValue.getAsJsonPrimitive().isNumber() || rgbValue.getAsString().matches("^[0-9]+$"))) {
74             Color rgb = new Color(rgbValue.getAsInt());
75             HSBType hsb = HSBType.fromRGB(rgb.getRed(), rgb.getGreen(), rgb.getBlue());
76             hsb = new HSBType(hsb.getHue(), hsb.getSaturation(), new PercentType(bright));
77             return new JsonPrimitive(hsb.toFullString());
78         }
79         return rgbValue;
80     }
81
82     private static JsonElement secondsToHours(JsonElement seconds) throws ClassCastException {
83         double value = seconds.getAsDouble() / 3600;
84         return new JsonPrimitive(value);
85     }
86
87     private static JsonElement yeelightSceneConversion(JsonElement intValue)
88             throws ClassCastException, IllegalStateException {
89         switch (intValue.getAsInt()) {
90             case 1:
91                 return new JsonPrimitive("color");
92             case 2:
93                 return new JsonPrimitive("hsv");
94             case 3:
95                 return new JsonPrimitive("ct");
96             case 4:
97                 return new JsonPrimitive("nightlight");
98             case 5: // don't know the number for colorflow...
99                 return new JsonPrimitive("cf");
100             case 6: // don't know the number for auto_delay_off, or if it is even in the properties visible...
101                 return new JsonPrimitive("auto_delay_off");
102             default:
103                 return new JsonPrimitive("unknown");
104         }
105     }
106
107     private static JsonElement divideTen(JsonElement value10) throws ClassCastException, IllegalStateException {
108         double value = value10.getAsDouble() / 10.0;
109         return new JsonPrimitive(value);
110     }
111
112     private static JsonElement divideHundred(JsonElement value10) throws ClassCastException, IllegalStateException {
113         double value = value10.getAsDouble() / 100.0;
114         return new JsonPrimitive(value);
115     }
116
117     private static JsonElement tankLevel(JsonElement value12) throws ClassCastException, IllegalStateException {
118         // 127 without water tank. 120 = 100% water
119         if (value12.getAsInt() == 127) {
120             return new JsonPrimitive(-1);
121         } else {
122             double value = value12.getAsDouble();
123             return new JsonPrimitive(value / 1.2);
124         }
125     }
126
127     /**
128      * Returns the deviceId element value from the Json response. If not found, returns the input
129      *
130      * @param responseValue
131      * @param deviceVariables containing the deviceId
132      * @return
133      */
134     private static JsonElement getDidElement(JsonElement responseValue, Map<String, Object> deviceVariables) {
135         String did = (String) deviceVariables.get("deviceId");
136         if (did != null) {
137             return getJsonElement(did, responseValue);
138         }
139         LOGGER.debug("deviceId not Found, no conversion");
140         return responseValue;
141     }
142
143     /**
144      * Returns the element from the Json response. If not found, returns the input
145      *
146      * @param element to be found
147      * @param responseValue
148      * @return
149      */
150     private static JsonElement getJsonElement(String element, JsonElement responseValue) {
151         try {
152             if (responseValue.isJsonPrimitive() || responseValue.isJsonObject()) {
153                 JsonElement jsonElement = responseValue.isJsonObject() ? responseValue
154                         : JsonParser.parseString(responseValue.getAsString());
155                 if (jsonElement.isJsonObject()) {
156                     JsonObject value = jsonElement.getAsJsonObject();
157                     if (value.has(element)) {
158                         return value.get(element);
159                     }
160                 }
161             }
162         } catch (JsonParseException e) {
163             // ignore
164         }
165         LOGGER.debug("JsonElement '{}' not found in '{}'", element, responseValue);
166         return responseValue;
167     }
168
169     public static JsonElement execute(String transformation, JsonElement value, Map<String, Object> deviceVariables) {
170         try {
171             if (transformation.toUpperCase().startsWith("GETJSONELEMENT")) {
172                 if (transformation.length() > 15) {
173                     return getJsonElement(transformation.substring(15), value);
174                 } else {
175                     LOGGER.info("Transformation {} missing element. Returning '{}'", transformation, value.toString());
176                 }
177             }
178             switch (transformation.toUpperCase()) {
179                 case "YEELIGHTSCENEID":
180                     return yeelightSceneConversion(value);
181                 case "SECONDSTOHOURS":
182                     return secondsToHours(value);
183                 case "/10":
184                     return divideTen(value);
185                 case "/100":
186                     return divideHundred(value);
187                 case "TANKLEVEL":
188                     return tankLevel(value);
189                 case "ADDBRIGHTTOHSV":
190                     return addBrightToHSV(value, deviceVariables);
191                 case "BRGBTOHSV":
192                     return bRGBtoHSV(value);
193                 case "GETDIDELEMENT":
194                     return getDidElement(value, deviceVariables);
195                 default:
196                     LOGGER.debug("Transformation {} not found. Returning '{}'", transformation, value.toString());
197                     return value;
198             }
199         } catch (ClassCastException | IllegalStateException e) {
200             LOGGER.debug("Transformation {} failed. Returning '{}'", transformation, value.toString());
201             return value;
202         }
203     }
204 }