]> git.basschouten.com Git - openhab-addons.git/blob
acc31076d29308c6657c0d6178d0f59df85d0ae2
[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.types.Command;
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.JsonPrimitive;
29
30 /**
31  * Conditional Execution of rules
32  *
33  * @author Marcel Verpaalen - Initial contribution
34  */
35 @NonNullByDefault
36 public class ActionConditions {
37     private static final Logger LOGGER = LoggerFactory.getLogger(ActionConditions.class);
38
39     /**
40      * Check if it matches the firmware version.
41      *
42      * @param condition
43      * @param deviceVariables
44      * @param value
45      * @return value in case firmware is matching, return null if not
46      */
47     private static @Nullable JsonElement firmwareCheck(MiIoDeviceActionCondition condition,
48             @Nullable Map<String, Object> deviceVariables, @Nullable JsonElement value) {
49         // TODO: placeholder for firmware version check to allow for firmware dependent actions
50         return value;
51     }
52
53     /**
54      * Check if the value is a valid brightness for operating power On/Off switch.
55      * If brightness <1 returns Off, if >=1 returns On
56      *
57      * @param value
58      * @return
59      */
60     private static @Nullable JsonElement brightness(@Nullable JsonElement value) {
61         if (value != null && value.isJsonPrimitive() && value.getAsJsonPrimitive().isNumber()) {
62             if (value.getAsInt() < 1) {
63                 return new JsonPrimitive("off");
64             } else {
65                 return new JsonPrimitive("on");
66             }
67         } else {
68             LOGGER.debug("Could not parse brightness. Value '{}' is not an int", value);
69         }
70         return value;
71     }
72
73     /**
74      * Convert HSV value to RGB+Brightness
75      *
76      * @param value
77      * @return RGB value + brightness as first byte
78      */
79     private static @Nullable JsonElement hsvToBRGB(@Nullable Command command, @Nullable JsonElement value) {
80         if (command instanceof HSBType) {
81             HSBType hsb = (HSBType) command;
82             Color color = Color.getHSBColor(hsb.getHue().floatValue() / 360, hsb.getSaturation().floatValue() / 100,
83                     hsb.getBrightness().floatValue() / 100);
84             return new JsonPrimitive((hsb.getBrightness().byteValue() << 24) + (color.getRed() << 16)
85                     + (color.getGreen() << 8) + color.getBlue());
86         }
87         return null;
88     }
89
90     /**
91      * Check if the value is a valid brightness between 1-100 which can be send to brightness channel.
92      * If not returns a null
93      *
94      * @param value
95      * @return
96      */
97     private static @Nullable JsonElement brightnessExists(@Nullable JsonElement value) {
98         if (value != null && value.isJsonPrimitive() && value.getAsJsonPrimitive().isNumber()) {
99             int intVal = value.getAsInt();
100             if (intVal > 0 && intVal <= 100) {
101                 return value;
102             } else if (intVal > 100) {
103                 return new JsonPrimitive(100);
104             }
105             return null;
106         } else {
107             LOGGER.debug("Could not parse brightness. Value '{}' is not an int", value);
108         }
109         return value;
110     }
111
112     /**
113      * Check if the value is a color which can be send to Color channel.
114      * If not returns a null
115      *
116      * @param command
117      *
118      * @param value
119      * @return
120      */
121     private static @Nullable JsonElement hsbOnly(@Nullable Command command, @Nullable JsonElement value) {
122         if (command instanceof HSBType) {
123             return value;
124         }
125         return null;
126     }
127
128     /**
129      * Check if the command value matches the condition value.
130      * The condition parameter element should be a Json array, containing Json objects with a matchValue element.
131      * Optionally it can contain a 'returnValue'element which will be returned in case of match.
132      * If no match this function will return a null
133      *
134      * @param condition.
135      * @param command
136      * @param value
137      * @return returnValue or value in case matching, return null if no match
138      */
139     private static @Nullable JsonElement matchValue(MiIoDeviceActionCondition condition, @Nullable Command command,
140             @Nullable JsonElement value) {
141         if (condition.getParameters().isJsonArray() && command != null) {
142             JsonArray conditionArray = condition.getParameters().getAsJsonArray();
143             for (int i = 0; i < conditionArray.size(); i++) {
144                 if (conditionArray.get(i).isJsonObject() && conditionArray.get(i).getAsJsonObject().has("matchValue")) {
145                     JsonObject matchCondition = conditionArray.get(i).getAsJsonObject();
146                     String matchvalue = matchCondition.get("matchValue").getAsString();
147                     boolean matching = command.toString().matches(matchvalue);
148                     LOGGER.trace("Matching '{}' with '{}': {}", matchvalue, command, matching);
149                     if (matching) {
150                         if (matchCondition.has("returnValue")) {
151                             return matchCondition.get("returnValue");
152                         } else {
153                             return value;
154                         }
155                     }
156                 } else {
157                     LOGGER.debug("Json DB condition is missing matchValue element in match parameter array.");
158                 }
159             }
160         } else {
161             LOGGER.debug("Json DB condition is missing match parameter array.");
162         }
163         return null;
164     }
165
166     public static @Nullable JsonElement executeAction(MiIoDeviceActionCondition condition,
167             @Nullable Map<String, Object> deviceVariables, @Nullable JsonElement value, @Nullable Command command) {
168         switch (condition.getName().toUpperCase()) {
169             case "FIRMWARE":
170                 return firmwareCheck(condition, deviceVariables, value);
171             case "BRIGHTNESSEXISTING":
172                 return brightnessExists(value);
173             case "HSVTOBRGB":
174                 return hsvToBRGB(command, value);
175             case "BRIGHTNESSONOFF":
176                 return brightness(value);
177             case "HSBONLY":
178                 return hsbOnly(command, value);
179             case "MATCHVALUE":
180                 return matchValue(condition, command, value);
181             default:
182                 LOGGER.debug("Condition {} not found. Returning '{}'", condition,
183                         value != null ? value.toString() : "");
184                 return value;
185         }
186     }
187 }