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