| Mi Multifunction Air Monitor | miio:basic | [cgllc.airmonitor.b1](#cgllc-airmonitor-b1) | Yes | |
| Qingping Air Monitor | miio:basic | [cgllc.airmonitor.s1](#cgllc-airmonitor-s1) | Yes | |
| Mi Universal Remote | miio:unsupported | chuangmi.ir.v2 | No | |
-| Mi Smart Power Plug 2 (Wi-Fi and Bluetooth Gateway) | miio:basic | [chuangmi.plug.212a01](#chuangmi-plug-212a01) | Yes | Experimental support. Please report back if all channels are functional. Preferably share the debug log of property refresh and command responses |
+| Mi Smart Power Plug 2 (Wi-Fi and Bluetooth Gateway) | miio:basic | [chuangmi.plug.212a01](#chuangmi-plug-212a01) | Yes | |
| Mi Smart Plug WiFi | miio:basic | [chuangmi.plug.hmi205](#chuangmi-plug-hmi205) | Yes | |
| Mi Smart Plug (WiFi) | miio:basic | [chuangmi.plug.hmi206](#chuangmi-plug-hmi206) | Yes | |
| Mi Smart Wi-Fi Plug (Bluetooth Gateway) | miio:basic | [chuangmi.plug.hmi208](#chuangmi-plug-hmi208) | Yes | |
| countdown | Number:Time | Imilab Timer - Countdown | |
| task-switch | Switch | Imilab Timer - Task Switch | |
| countdown-info | Switch | Imilab Timer - Countdown Info | |
+| bt-gw | String | BT Gateway | Value mapping `["disable"="Disable","enable"="Enable"]` |
### Mi Smart Plug WiFi (<a name="chuangmi-plug-hmi205">chuangmi.plug.hmi205</a>) Channels
Number:Time countdown "Imilab Timer - Countdown" (G_plug) {channel="miio:basic:plug:countdown"}
Switch task_switch "Imilab Timer - Task Switch" (G_plug) {channel="miio:basic:plug:task-switch"}
Switch countdown_info "Imilab Timer - Countdown Info" (G_plug) {channel="miio:basic:plug:countdown-info"}
+String bt_gw "BT Gateway" (G_plug) {channel="miio:basic:plug:bt-gw"}
```
### Mi Smart Plug WiFi (chuangmi.plug.hmi205) item file lines
import org.slf4j.LoggerFactory;
import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParseException;
+import com.google.gson.JsonParser;
import com.google.gson.JsonPrimitive;
/**
}
}
+ public static JsonElement getJsonElement(String element, JsonElement responseValue) {
+ try {
+ if (responseValue.isJsonPrimitive() || responseValue.isJsonObject()) {
+ JsonElement jsonElement = responseValue.isJsonObject() ? responseValue
+ : JsonParser.parseString(responseValue.getAsString());
+ if (jsonElement.isJsonObject()) {
+ JsonObject value = jsonElement.getAsJsonObject();
+ if (value.has(element)) {
+ return value.get(element);
+ }
+ }
+ }
+ } catch (JsonParseException e) {
+ // ignore
+ }
+ LOGGER.debug("JsonElement '{}' not found in '{}'", element, responseValue);
+ return responseValue;
+ }
+
public static JsonElement execute(String transformation, JsonElement value,
@Nullable Map<String, Object> deviceVariables) {
try {
+ if (transformation.toUpperCase().startsWith("GETJSONELEMENT")) {
+ if (transformation.length() > 15) {
+ return getJsonElement(transformation.substring(15), value);
+ } else {
+ LOGGER.info("Transformation {} missing element. Returning '{}'", transformation, value.toString());
+ }
+ }
switch (transformation.toUpperCase()) {
case "YEELIGHTSCENEID":
return yeelightSceneConversion(value);
--- /dev/null
+/**
+ * Copyright (c) 2010-2021 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.miio.internal;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.util.Collections;
+import java.util.Map;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.junit.jupiter.api.Test;
+import org.openhab.binding.miio.internal.basic.Conversions;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonParser;
+import com.google.gson.JsonPrimitive;
+
+/**
+ * Test case for {@link ConversionsTest}
+ *
+ * @author Marcel Verpaalen - Initial contribution
+ *
+ */
+@NonNullByDefault
+public class ConversionsTest {
+
+ @Test
+ public void getJsonElementTest() {
+
+ Map<String, Object> deviceVariables = Collections.emptyMap();
+
+ // test invalid missing element
+ String transformation = "getJsonElement";
+ JsonElement value = new JsonPrimitive("");
+ JsonElement resp = Conversions.execute(transformation, value, deviceVariables);
+ assertNotNull(resp);
+ assertEquals(value, resp);
+
+ // test invalid missing element
+ value = new JsonPrimitive("{\"test\": \"testresponse\"}");
+ resp = Conversions.execute(transformation, value, deviceVariables);
+ assertNotNull(resp);
+ assertEquals(value, resp);
+
+ transformation = "getJsonElement-test";
+
+ // test without deviceVariables
+ resp = Conversions.execute(transformation, value, null);
+ assertNotNull(resp);
+ assertEquals(new JsonPrimitive("testresponse"), resp);
+
+ // test non json
+ value = new JsonPrimitive("some non json value");
+ resp = Conversions.execute(transformation, value, deviceVariables);
+ assertNotNull(resp);
+ assertEquals(value, resp);
+
+ // test non json empty string
+ value = new JsonPrimitive("");
+ resp = Conversions.execute(transformation, value, deviceVariables);
+ assertNotNull(resp);
+ assertEquals(value, resp);
+
+ // test input as jsonString
+ value = new JsonPrimitive("{\"test\": \"testresponse\"}");
+ resp = Conversions.execute(transformation, value, deviceVariables);
+ assertNotNull(resp);
+ assertEquals(new JsonPrimitive("testresponse"), resp);
+
+ // test input as jsonObject
+ value = JsonParser.parseString("{\"test\": \"testresponse\"}");
+ resp = Conversions.execute(transformation, value, deviceVariables);
+ assertNotNull(resp);
+ assertEquals(new JsonPrimitive("testresponse"), resp);
+
+ // test input as jsonString for a number
+ value = new JsonPrimitive("{\"test\": 3}");
+ resp = Conversions.execute(transformation, value, deviceVariables);
+ assertNotNull(resp);
+ assertEquals(new JsonPrimitive(3), resp);
+
+ // test input as jsonString for a array
+ value = new JsonPrimitive("{\"test\": []}");
+ resp = Conversions.execute(transformation, value, deviceVariables);
+ assertNotNull(resp);
+ assertEquals(new JsonArray(), resp);
+
+ // test input as jsonString for a boolean
+ value = new JsonPrimitive("{\"test\": false}");
+ resp = Conversions.execute(transformation, value, deviceVariables);
+ assertNotNull(resp);
+ assertEquals(new JsonPrimitive(false), resp);
+
+ // test input as jsonObject for a number
+ value = JsonParser.parseString("{\"test\": 3}");
+ resp = Conversions.execute(transformation, value, deviceVariables);
+ assertNotNull(resp);
+ assertEquals(new JsonPrimitive(3), resp);
+
+ // test input as jsonString for non-existing element
+ value = new JsonPrimitive("{\"nottest\": \"testresponse\"}");
+ resp = Conversions.execute(transformation, value, deviceVariables);
+ assertNotNull(resp);
+ assertEquals(value, resp);
+
+ // test input as jsonString for non-existing element
+ value = JsonParser.parseString("{\"nottest\": \"testresponse\"}");
+ resp = Conversions.execute(transformation, value, deviceVariables);
+ assertNotNull(resp);
+ assertEquals(value, resp);
+ }
+}