[miio] add support for BT Gateway switch on chuangmi.plug.212a01 (#11657)
* [miio] add support for BT Gateway switch on chuangmi.plug.212a01 Signed-off-by: Marcel Verpaalen <marcel@verpaalen.com> * [miio] improve conversion & add test for it Signed-off-by: Marcel Verpaalen <marcel@verpaalen.com> * [miio] add one empty string test Signed-off-by: Marcel Verpaalen <marcel@verpaalen.com> * [miio] remove unnessesary exceptions Signed-off-by: Marcel Verpaalen <marcel@verpaalen.com> * [miio] add one more test for different inputs Signed-off-by: Marcel Verpaalen <marcel@verpaalen.com> * [miio] typo Signed-off-by: Marcel Verpaalen <marcel@verpaalen.com>
This commit is contained in:
parent
f8d8f9a9fe
commit
c6798ea4fa
|
@ -187,7 +187,7 @@ Currently the miio binding supports more than 300 different models.
|
||||||
| Mi Multifunction Air Monitor | miio:basic | [cgllc.airmonitor.b1](#cgllc-airmonitor-b1) | Yes | |
|
| 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 | |
|
| Qingping Air Monitor | miio:basic | [cgllc.airmonitor.s1](#cgllc-airmonitor-s1) | Yes | |
|
||||||
| Mi Universal Remote | miio:unsupported | chuangmi.ir.v2 | No | |
|
| 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.hmi205](#chuangmi-plug-hmi205) | Yes | |
|
||||||
| Mi Smart Plug (WiFi) | miio:basic | [chuangmi.plug.hmi206](#chuangmi-plug-hmi206) | 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 | |
|
| Mi Smart Wi-Fi Plug (Bluetooth Gateway) | miio:basic | [chuangmi.plug.hmi208](#chuangmi-plug-hmi208) | Yes | |
|
||||||
|
@ -694,6 +694,7 @@ Note, not all the values need to be in the json file, e.g. a subset of the param
|
||||||
| countdown | Number:Time | Imilab Timer - Countdown | |
|
| countdown | Number:Time | Imilab Timer - Countdown | |
|
||||||
| task-switch | Switch | Imilab Timer - Task Switch | |
|
| task-switch | Switch | Imilab Timer - Task Switch | |
|
||||||
| countdown-info | Switch | Imilab Timer - Countdown Info | |
|
| 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
|
### Mi Smart Plug WiFi (<a name="chuangmi-plug-hmi205">chuangmi.plug.hmi205</a>) Channels
|
||||||
|
|
||||||
|
@ -5488,6 +5489,7 @@ Number:Time off_duration "Imilab Timer - Off Duration" (G_plug) {channel="miio:b
|
||||||
Number:Time countdown "Imilab Timer - Countdown" (G_plug) {channel="miio:basic:plug:countdown"}
|
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 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"}
|
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
|
### Mi Smart Plug WiFi (chuangmi.plug.hmi205) item file lines
|
||||||
|
|
|
@ -23,6 +23,9 @@ import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import com.google.gson.JsonElement;
|
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;
|
import com.google.gson.JsonPrimitive;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -121,9 +124,35 @@ public class Conversions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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,
|
public static JsonElement execute(String transformation, JsonElement value,
|
||||||
@Nullable Map<String, Object> deviceVariables) {
|
@Nullable Map<String, Object> deviceVariables) {
|
||||||
try {
|
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()) {
|
switch (transformation.toUpperCase()) {
|
||||||
case "YEELIGHTSCENEID":
|
case "YEELIGHTSCENEID":
|
||||||
return yeelightSceneConversion(value);
|
return yeelightSceneConversion(value);
|
||||||
|
|
|
@ -274,8 +274,57 @@
|
||||||
},
|
},
|
||||||
"refresh": true,
|
"refresh": true,
|
||||||
"actions": []
|
"actions": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"property": "",
|
||||||
|
"friendlyName": "BT Gateway",
|
||||||
|
"channel": "bt-gw",
|
||||||
|
"type": "String",
|
||||||
|
"stateDescription": {
|
||||||
|
"readOnly": false,
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"value": "disable",
|
||||||
|
"label": "Disable"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value": "enable",
|
||||||
|
"label": "Enable"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"refresh": true,
|
||||||
|
"customRefreshCommand": "bt_gateway_status",
|
||||||
|
"transformation": "getJsonElement-gateway_status",
|
||||||
|
"actions": [
|
||||||
|
{
|
||||||
|
"command": "bt_gateway_enable",
|
||||||
|
"parameterType": "EMPTY",
|
||||||
|
"condition": {
|
||||||
|
"name": "matchValue",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"matchValue": "enable"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "bt_gateway_disable",
|
||||||
|
"parameterType": "EMPTY",
|
||||||
|
"condition": {
|
||||||
|
"name": "matchValue",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"matchValue": "disable"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"readmeComment": "Value mapping `[\"disable\"\u003d\"Disable\",\"enable\"\u003d\"Enable\"]`"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"experimental": true
|
"experimental": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,123 @@
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue