Skip to content

Commit

Permalink
[miio] add support for BT Gateway switch on chuangmi.plug.212a01 (ope…
Browse files Browse the repository at this point in the history
…nhab#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>
  • Loading branch information
marcelrv authored and andan67 committed Nov 5, 2022
1 parent 4ef628d commit c853e68
Show file tree
Hide file tree
Showing 4 changed files with 205 additions and 2 deletions.
4 changes: 3 additions & 1 deletion bundles/org.openhab.binding.miio/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 | |
| 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 | |
Expand Down Expand Up @@ -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 | |
| 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

Expand Down Expand Up @@ -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"}
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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
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;

/**
Expand Down Expand Up @@ -121,9 +124,35 @@ public static JsonElement tankLevel(JsonElement value12) throws ClassCastExcepti
}
}

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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,8 +274,57 @@
},
"refresh": true,
"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
}
}
Original file line number Diff line number Diff line change
@@ -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);
}
}

0 comments on commit c853e68

Please sign in to comment.