diff --git a/addons/binding/org.openhab.binding.mihome/.classpath b/addons/binding/org.openhab.binding.mihome/.classpath new file mode 100644 index 0000000000000..05a265fda90be --- /dev/null +++ b/addons/binding/org.openhab.binding.mihome/.classpath @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/addons/binding/org.openhab.binding.mihome/.project b/addons/binding/org.openhab.binding.mihome/.project new file mode 100644 index 0000000000000..1a06f1f323720 --- /dev/null +++ b/addons/binding/org.openhab.binding.mihome/.project @@ -0,0 +1,33 @@ + + + org.openhab.binding.mihome + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + org.eclipse.pde.ds.core.builder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/addons/binding/org.openhab.binding.mihome/ESH-INF/binding/binding.xml b/addons/binding/org.openhab.binding.mihome/ESH-INF/binding/binding.xml index dc163fe13974d..b26c34817013e 100644 --- a/addons/binding/org.openhab.binding.mihome/ESH-INF/binding/binding.xml +++ b/addons/binding/org.openhab.binding.mihome/ESH-INF/binding/binding.xml @@ -5,7 +5,8 @@ xsi:schemaLocation="http://eclipse.org/smarthome/schemas/binding/v1.0.0 http://eclipse.org/smarthome/schemas/binding-1.0.0.xsd"> Xiaomi Mi Smart Home Binding - This is the binding for Xiaomi Mi Smart Home. + Connects to Xiaomi Smart Gateway v2 and allows to communicate with Xiaomi Mi Smart Home suite (also called Xiaomi Aqara). + The Gateway connects with a range of Xiaomi Zigbee sensors such as Wireless Switch, Wall Plug or Temperature Sensor. Patrick Boos diff --git a/addons/binding/org.openhab.binding.mihome/ESH-INF/thing/bridge.xml b/addons/binding/org.openhab.binding.mihome/ESH-INF/thing/bridge.xml index 3402c6c78ad7e..8e6a7bc5250f6 100644 --- a/addons/binding/org.openhab.binding.mihome/ESH-INF/thing/bridge.xml +++ b/addons/binding/org.openhab.binding.mihome/ESH-INF/thing/bridge.xml @@ -7,7 +7,9 @@ - The Xiaomi Mi Smart Home Bride. + Multifunctional Gateway - a bridge for the sensors. One button click turns on/off the device. Two clicks toggle "home security" feature. + Three button clicks allow you to link the Xiaomi Zigbee devices with the Gateway. After you press the button 3 times, the light will flash blue; + After that you'll be able to add new sensors by pressing their hole button for 3 seconds. Xiaomi @@ -16,22 +18,25 @@ - Serial number of the xiaomi bridge. + Serial number of the Xiaomi bridge. true + network_address - Network address of the xiaomi bridge. + Network address of the Xiaomi bridge. true + network_address - Port of the xiaomi bridge. + Port of the Xiaomi bridge. true 9898 + password @@ -40,6 +45,7 @@ false + Seconds between fetching values from the Bridge. diff --git a/addons/binding/org.openhab.binding.mihome/ESH-INF/thing/gateway.xml b/addons/binding/org.openhab.binding.mihome/ESH-INF/thing/gateway.xml index 43d6d4d2fa86c..07ab1393bfbb7 100644 --- a/addons/binding/org.openhab.binding.mihome/ESH-INF/thing/gateway.xml +++ b/addons/binding/org.openhab.binding.mihome/ESH-INF/thing/gateway.xml @@ -9,8 +9,11 @@ - - Gateway + + Multifunctional Gateway. One button click turns on/off the device. Two clicks toggle "home security" feature. + Three button clicks allow you to link the Xiaomi Zigbee devices with the Gateway. After you press the button 3 times, the light will flash blue; + After that you'll be able to add new sensors by pressing their hole button for 3 seconds. + @@ -39,22 +42,25 @@ Lighting + Color - The color channel allows to control the color of a light. + Control the color of light. ColorLight Lighting + Dimmer - - The CT channel allows to control the CT of a light. + + Allows to control the color temperature of light. DimmableCT ColorTemperature + diff --git a/addons/binding/org.openhab.binding.mihome/ESH-INF/thing/sensor_cube.xml b/addons/binding/org.openhab.binding.mihome/ESH-INF/thing/sensor_cube.xml index 932224f98a269..f37dafbbee007 100644 --- a/addons/binding/org.openhab.binding.mihome/ESH-INF/thing/sensor_cube.xml +++ b/addons/binding/org.openhab.binding.mihome/ESH-INF/thing/sensor_cube.xml @@ -9,8 +9,8 @@ - - Magic Controller (Cube) + + Multifunctional controller equipped with an accelerometer and a gyroscope. Triggers the following actions: move, rotate, rotate, flip 90, flip 180, tap twice, shake air, free fall, alert. @@ -25,7 +25,7 @@ - + trigger diff --git a/addons/binding/org.openhab.binding.mihome/ESH-INF/thing/sensor_ht.xml b/addons/binding/org.openhab.binding.mihome/ESH-INF/thing/sensor_ht.xml index bede12d5f5060..d80640a0301e6 100644 --- a/addons/binding/org.openhab.binding.mihome/ESH-INF/thing/sensor_ht.xml +++ b/addons/binding/org.openhab.binding.mihome/ESH-INF/thing/sensor_ht.xml @@ -1,49 +1,72 @@ - - - - - - - - - Temperature & Humidity Sensor - - - - - - - - - - An identifier for the item connected. - true - - - - - - Number - - Temperature - - weather - - - - - - Number - - Humidity - - weather - - - - + + + + + + + + + Reports temperature and humidity. Operating temperature: −20°C to 60°C. Operating humidity: 0 to 100%. + Sensor reports the temperature when there's a difference around 0.5°C. If there is no significant temperature change, sensor reports temperature once a 50 minutes.\ + + + + + + + + + + + + + An identifier for the item connected. + true + + + + + + Number + + Temperature + + weather + + + + + + + Number + + Humidity + + weather + + + + + + + Number + + Battery Voltage + + + + + trigger + + Triggers LOW event when voltage is below 2800 mv + + + + + + + diff --git a/addons/binding/org.openhab.binding.mihome/ESH-INF/thing/sensor_magnet.xml b/addons/binding/org.openhab.binding.mihome/ESH-INF/thing/sensor_magnet.xml index 7483085294ead..9c8af8428e72f 100644 --- a/addons/binding/org.openhab.binding.mihome/ESH-INF/thing/sensor_magnet.xml +++ b/addons/binding/org.openhab.binding.mihome/ESH-INF/thing/sensor_magnet.xml @@ -1,34 +1,54 @@ - - - - - - - - - Sensor for Door/Window to detect open/closed state. - - - - - - - - - An identifier for the item connected. - true - - - - - - Contact - - Contact - - + + + + + + + + + Contact sensor mounted on doors or windows. Detects states: open and closed. + + + + + + + + + + + An identifier for the item connected. + true + + + + + + Contact + + Contact + + + + + Number + + Battery Voltage + + + + + trigger + + Triggers LOW event when voltage is below 2800 mv + + + + + + + diff --git a/addons/binding/org.openhab.binding.mihome/ESH-INF/thing/sensor_motion.xml b/addons/binding/org.openhab.binding.mihome/ESH-INF/thing/sensor_motion.xml index 23ebdd89167b0..dce6879c514ce 100644 --- a/addons/binding/org.openhab.binding.mihome/ESH-INF/thing/sensor_motion.xml +++ b/addons/binding/org.openhab.binding.mihome/ESH-INF/thing/sensor_motion.xml @@ -1,41 +1,62 @@ - - - - - - - - - Sensor that detects movement. - - - - - - - - - - An identifier for the item connected. - true - - - - - - Switch - - Motion - - - - DateTime - - Date/time when last motion was detected - - + + + + + + + + + Sensor that detects movement. Also called Occupancy Sensor or Human Body Sensor. After it detects motion, it goes to sleep for 1 minute. + + + + + + + + + + + + An identifier for the item connected. + true + + + + + + Switch + + Motion + + + + + DateTime + + Date/time when last motion was detected + + + + + Number + + Battery Voltage + + + + + trigger + + Triggers LOW event when voltage is below 2800 mv + + + + + + + diff --git a/addons/binding/org.openhab.binding.mihome/ESH-INF/thing/sensor_plug.xml b/addons/binding/org.openhab.binding.mihome/ESH-INF/thing/sensor_plug.xml index b1e9a1d1d739e..c96d97c8fad6b 100644 --- a/addons/binding/org.openhab.binding.mihome/ESH-INF/thing/sensor_plug.xml +++ b/addons/binding/org.openhab.binding.mihome/ESH-INF/thing/sensor_plug.xml @@ -1,51 +1,54 @@ - + - - - - + + + + - - Power plug. + + Allows you to enable or disable the socket, read voltage, current and power consumption. - - - - - - + + + + + + - - - - An identifier for the item connected. - true - - - + + + + An identifier for the item connected. + true + + + - - Switch - - PowerOutlet - - - Number - - - - - Number - - - - - Number - - - + + Switch + + PowerOutlet + + + + Number + + + + + + Number + + + + + + Number + + + + diff --git a/addons/binding/org.openhab.binding.mihome/ESH-INF/thing/sensor_switch.xml b/addons/binding/org.openhab.binding.mihome/ESH-INF/thing/sensor_switch.xml index ea80ad974fc45..9a246c58f9747 100644 --- a/addons/binding/org.openhab.binding.mihome/ESH-INF/thing/sensor_switch.xml +++ b/addons/binding/org.openhab.binding.mihome/ESH-INF/thing/sensor_switch.xml @@ -1,40 +1,60 @@ - - - - - - - - - Button sensor. - - - - - - - - - An identifier for the item connected. - true - - - - - - trigger - - - - - - - - - - + + + + + + + + + Round-shaped mini wireless switch that allows to trigger three types of event: single click, double click and long click. + + + + + + + + + + + An identifier for the item connected. + true + + + + + + trigger + + + + + + + + + + + + + Number + + Battery Voltage + + + + + trigger + + Triggers LOW event when voltage is below 2800 mv + + + + + + + diff --git a/addons/binding/org.openhab.binding.mihome/README.md b/addons/binding/org.openhab.binding.mihome/README.md index d0a69cb2a97a3..7448a0450bb6a 100644 --- a/addons/binding/org.openhab.binding.mihome/README.md +++ b/addons/binding/org.openhab.binding.mihome/README.md @@ -12,8 +12,9 @@ In order to connect the Gateway, you need to install MiHome app from the [Google Play](https://play.google.com/store/apps/details?id=com.xiaomi.smarthome) or [AppStore](https://itunes.apple.com/app/mi-home-xiaomi-for-your-smarthome/id957323480). ## How to set up + 1. Install the binding -2. Setup gateway to be discoverable +2. Setup Gateway to be discoverable 1. Add Gateway 2 to your WiFi Network 2. Install Mi Home app from [Google Play](https://play.google.com/store/apps/details?id=com.xiaomi.smarthome) or [AppStore](https://itunes.apple.com/app/mi-home-xiaomi-for-your-smarthome/id957323480) 3. Set your region to Mainland China under Settings -> Locale (seems to be required) @@ -32,18 +33,23 @@ from the [Google Play](https://play.google.com/store/apps/details?id=com.xiaomi. 6. Your sensors should be getting discovered by openHAB as you add and use them. ## Connecting sub-devices (sensors) to the Gateway + There are two ways of connecting Xiaomi devices to the gateway: + 1. Online - within the MiHome App 2. Offline - manual + * Click 3 times on the Gateway's button * Gateway will flash in blue and you will hear female voice in Chinese * Place the needle into the sensor and hold it for at least 3 seconds * You'll hear confirmation message in Chinese ## Important information -This requires port 9898 to not be used by any other service on the system. + +The binding requires port `9898` to not be used by any other service on the system. ## Full Example + xiaomi.items: ``` TODO @@ -79,18 +85,18 @@ when Channel 'mihome:sensor_cube::action' triggered then if (receivedEvent.event == "SHAKE_AIR") { - if (YeelightColorLEDBulb_Brightness.state == 0) { - sendCommand(YeelightColorLEDBulb_Brightness, ON) - sendCommand(YeelightColorLEDBulb_ColorTemperature, 50) + if (LEDBulb_Brightness.state == 0) { + sendCommand(LEDBulb_Brightness, ON) + sendCommand(LEDBulb_ColorTemperature, 50) } else { - sendCommand(YeelightColorLEDBulb_Brightness, OFF) + sendCommand(LEDBulb_Brightness, OFF) } } else if (receivedEvent.event == "FLIP90") { - sendCommand(YeelightColorLEDBulb_Brightness, ON) - sendCommand(YeelightColorLEDBulb_ColorTemperature, 10) + sendCommand(LEDBulb_Brightness, ON) + sendCommand(LEDBulb_ColorTemperature, 10) } else if (receivedEvent.event == "FLIP180") { - sendCommand(YeelightColorLEDBulb_Brightness, ON) - sendCommand(YeelightColorLEDBulb_Color, new HSBType(new DecimalType(90),new PercentType(100),new PercentType(100))) + sendCommand(LEDBulb_Brightness, ON) + sendCommand(LEDBulb_Color, new HSBType(new DecimalType(90),new PercentType(100),new PercentType(100))) } end diff --git a/addons/binding/org.openhab.binding.mihome/about.html b/addons/binding/org.openhab.binding.mihome/about.html new file mode 100644 index 0000000000000..3516f9f208725 --- /dev/null +++ b/addons/binding/org.openhab.binding.mihome/about.html @@ -0,0 +1,28 @@ + + + + +About + + +

About This Content

+ +

February 17, 2017

+

License

+ +

The openHAB community makes available all content in this plug-in ("Content"). Unless otherwise +indicated below, the Content is provided to you under the terms and conditions of the +Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available +at http://www.eclipse.org/legal/epl-v10.html. +For purposes of the EPL, "Program" will mean the Content.

+ +

If you did not receive this Content directly from the openHAB community, the Content is +being redistributed by another party ("Redistributor") and different terms and conditions may +apply to your use of any object code in the Content. Check the Redistributor's license that was +provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise +indicated below, the terms and conditions of the EPL still apply to any source code in the Content +and such source code may be obtained at openhab.org.

+ + + \ No newline at end of file diff --git a/addons/binding/org.openhab.binding.mihome/pom.xml b/addons/binding/org.openhab.binding.mihome/pom.xml index 9dd03bf0eaefd..7d9019a57806c 100644 --- a/addons/binding/org.openhab.binding.mihome/pom.xml +++ b/addons/binding/org.openhab.binding.mihome/pom.xml @@ -9,7 +9,9 @@ 2.1.0-SNAPSHOT + org.openhab.binding org.openhab.binding.mihome + 2.1.0-SNAPSHOT Xiaomi Mi Smart Home Binding eclipse-plugin diff --git a/addons/binding/org.openhab.binding.mihome/src/main/java/org/openhab/binding/mihome/XiaomiGatewayBindingConstants.java b/addons/binding/org.openhab.binding.mihome/src/main/java/org/openhab/binding/mihome/XiaomiGatewayBindingConstants.java index 5b54411ec2112..e0864b974bc40 100644 --- a/addons/binding/org.openhab.binding.mihome/src/main/java/org/openhab/binding/mihome/XiaomiGatewayBindingConstants.java +++ b/addons/binding/org.openhab.binding.mihome/src/main/java/org/openhab/binding/mihome/XiaomiGatewayBindingConstants.java @@ -30,6 +30,7 @@ public class XiaomiGatewayBindingConstants { // List of all Channel ids public static final String CHANNEL_TEMPERATURE = "temperature"; + public static final String CHANNEL_VOLTAGE = "voltage"; public static final String CHANNEL_HUMIDITY = "humidity"; public static final String CHANNEL_MOTION = "motion"; public static final String CHANNEL_LAST_MOTION = "lastMotion"; diff --git a/addons/binding/org.openhab.binding.mihome/src/main/java/org/openhab/binding/mihome/handler/XiaomiBridgeHandler.java b/addons/binding/org.openhab.binding.mihome/src/main/java/org/openhab/binding/mihome/handler/XiaomiBridgeHandler.java index 91beb80bae960..080c14831cf30 100644 --- a/addons/binding/org.openhab.binding.mihome/src/main/java/org/openhab/binding/mihome/handler/XiaomiBridgeHandler.java +++ b/addons/binding/org.openhab.binding.mihome/src/main/java/org/openhab/binding/mihome/handler/XiaomiBridgeHandler.java @@ -7,10 +7,22 @@ */ package org.openhab.binding.mihome.handler; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; +import static org.openhab.binding.mihome.XiaomiGatewayBindingConstants.*; +import static org.openhab.binding.mihome.internal.ModelMapper.getThingTypeForModel; + +import java.math.BigDecimal; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.TimeUnit; + import org.eclipse.smarthome.config.core.Configuration; import org.eclipse.smarthome.config.core.status.ConfigStatusMessage; import org.eclipse.smarthome.core.thing.Bridge; @@ -27,24 +39,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.math.BigDecimal; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.TimeUnit; - -import static org.openhab.binding.mihome.XiaomiGatewayBindingConstants.HOST; -import static org.openhab.binding.mihome.XiaomiGatewayBindingConstants.PORT; -import static org.openhab.binding.mihome.XiaomiGatewayBindingConstants.SERIAL_NUMBER; -import static org.openhab.binding.mihome.XiaomiGatewayBindingConstants.THING_TYPE_BRIDGE; -import static org.openhab.binding.mihome.internal.ModelMapper.getThingTypeForModel; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; /** * The {@link XiaomiBridgeHandler} is responsible for handling commands, which are @@ -101,7 +99,7 @@ public void dispose() { @Override public void handleCommand(ChannelUID channelUID, Command command) { - logger.warn("Gateway doesn't handle command: " + command); + logger.debug("Gateway doesn't handle command: {}", command); } @Override @@ -145,7 +143,7 @@ public void onDataReceived(String command, JsonObject message) { private ThingUID getThingUID(String model, String sid) { ThingTypeUID thingType = getThingTypeForModel(model); if (thingType == null) { - logger.error("Unknown discovered model: " + model); + logger.error("Unknown discovered model: {}", model); return null; } @@ -199,7 +197,7 @@ private void sendMessageToBridge(String message) { String host = (String) config.get(HOST); int port = getConfigInteger(config, PORT); XiaomiSocket.sendMessage(message, InetAddress.getByName(host), port); - logger.debug("Sent to bridge:" + message); + logger.debug("Sent to bridge: {}", message); } catch (UnknownHostException e) { logger.error("Could not send message to bridge", e); } @@ -227,7 +225,7 @@ private void sendCommandToBridge(String cmd, String sid, String[] keys, Object[] for (int i = 0; i < keys.length; i++) { message.append(",").append("\"").append(keys[i]).append("\"").append(": "); - //write value + // write value message.append(toJsonValue(values[i])); } } @@ -237,15 +235,13 @@ private void sendCommandToBridge(String cmd, String sid, String[] keys, Object[] } void writeToDevice(String itemId, String[] keys, Object[] values) { - sendCommandToBridge("write", - new String[]{"sid", "data"}, - new Object[]{itemId, createDataJsonString(keys, values)}); + sendCommandToBridge("write", new String[] { "sid", "data" }, + new Object[] { itemId, createDataJsonString(keys, values) }); } void writeToBridge(String[] keys, Object[] values) { - sendCommandToBridge("write", - new String[]{"model", "sid", "short_id", "data"}, - new Object[]{"gateway", getGatewaySid(), "0", createDataJsonString(keys, values)}); + sendCommandToBridge("write", new String[] { "model", "sid", "short_id", "data" }, + new Object[] { "gateway", getGatewaySid(), "0", createDataJsonString(keys, values) }); } private String createDataJsonString(String[] keys, Object[] values) { @@ -270,18 +266,19 @@ private String getEncryptedKey() { private String createDataString(String[] keys, Object[] values) { StringBuilder builder = new StringBuilder(); - if (keys.length != values.length) + if (keys.length != values.length) { return ""; + } for (int i = 0; i < keys.length; i++) { if (i > 0) { builder.append(","); } - //write key + // write key builder.append("\\\"").append(keys[i]).append("\\\"").append(": "); - //write value + // write value builder.append(escapeQuotes(toJsonValue(values[i]))); } return builder.toString(); @@ -290,8 +287,9 @@ private String createDataString(String[] keys, Object[] values) { private String toJsonValue(Object o) { if (o instanceof String) { return "\"" + o + "\""; - } else + } else { return o.toString(); + } } private String escapeQuotes(String string) { diff --git a/addons/binding/org.openhab.binding.mihome/src/main/java/org/openhab/binding/mihome/handler/XiaomiItemHandler.java b/addons/binding/org.openhab.binding.mihome/src/main/java/org/openhab/binding/mihome/handler/XiaomiItemHandler.java index db552a2c406f0..827b04a410991 100644 --- a/addons/binding/org.openhab.binding.mihome/src/main/java/org/openhab/binding/mihome/handler/XiaomiItemHandler.java +++ b/addons/binding/org.openhab.binding.mihome/src/main/java/org/openhab/binding/mihome/handler/XiaomiItemHandler.java @@ -7,8 +7,14 @@ */ package org.openhab.binding.mihome.handler; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; +import static org.openhab.binding.mihome.XiaomiGatewayBindingConstants.*; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; +import java.util.concurrent.TimeUnit; + import org.eclipse.smarthome.core.items.Item; import org.eclipse.smarthome.core.library.types.DateTimeType; import org.eclipse.smarthome.core.library.types.DecimalType; @@ -31,42 +37,21 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; -import java.util.concurrent.TimeUnit; - -import static org.openhab.binding.mihome.XiaomiGatewayBindingConstants.CHANNEL_BRIGHTNESS; -import static org.openhab.binding.mihome.XiaomiGatewayBindingConstants.CHANNEL_COLOR; -import static org.openhab.binding.mihome.XiaomiGatewayBindingConstants.CHANNEL_COLOR_TEMPERATURE; -import static org.openhab.binding.mihome.XiaomiGatewayBindingConstants.CHANNEL_HUMIDITY; -import static org.openhab.binding.mihome.XiaomiGatewayBindingConstants.CHANNEL_IS_OPEN; -import static org.openhab.binding.mihome.XiaomiGatewayBindingConstants.CHANNEL_LAST_MOTION; -import static org.openhab.binding.mihome.XiaomiGatewayBindingConstants.CHANNEL_LOAD_POWER; -import static org.openhab.binding.mihome.XiaomiGatewayBindingConstants.CHANNEL_LOAD_VOLTAGE; -import static org.openhab.binding.mihome.XiaomiGatewayBindingConstants.CHANNEL_MOTION; -import static org.openhab.binding.mihome.XiaomiGatewayBindingConstants.CHANNEL_POWER_CONSUMED; -import static org.openhab.binding.mihome.XiaomiGatewayBindingConstants.CHANNEL_POWER_ON; -import static org.openhab.binding.mihome.XiaomiGatewayBindingConstants.CHANNEL_TEMPERATURE; -import static org.openhab.binding.mihome.XiaomiGatewayBindingConstants.ITEM_ID; -import static org.openhab.binding.mihome.XiaomiGatewayBindingConstants.THING_TYPE_GATEWAY; -import static org.openhab.binding.mihome.XiaomiGatewayBindingConstants.THING_TYPE_SENSOR_CUBE; -import static org.openhab.binding.mihome.XiaomiGatewayBindingConstants.THING_TYPE_SENSOR_HT; -import static org.openhab.binding.mihome.XiaomiGatewayBindingConstants.THING_TYPE_SENSOR_MAGNET; -import static org.openhab.binding.mihome.XiaomiGatewayBindingConstants.THING_TYPE_SENSOR_MOTION; -import static org.openhab.binding.mihome.XiaomiGatewayBindingConstants.THING_TYPE_SENSOR_PLUG; -import static org.openhab.binding.mihome.XiaomiGatewayBindingConstants.THING_TYPE_SENSOR_SWITCH; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; /** * The {@link XiaomiItemHandler} is responsible for handling commands, which are * sent to one of the channels. * * @author Patrick Boos - Initial contribution + * @author Kuba Wolanin - Added voltage and low battery report */ public class XiaomiItemHandler extends BaseThingHandler implements XiaomiItemUpdateListener { - public final static Set SUPPORTED_THING_TYPES = new HashSet<>(Arrays.asList(THING_TYPE_GATEWAY, THING_TYPE_SENSOR_HT, THING_TYPE_SENSOR_MOTION, THING_TYPE_SENSOR_SWITCH, THING_TYPE_SENSOR_MAGNET, THING_TYPE_SENSOR_PLUG, THING_TYPE_SENSOR_CUBE)); + public final static Set SUPPORTED_THING_TYPES = new HashSet<>( + Arrays.asList(THING_TYPE_GATEWAY, THING_TYPE_SENSOR_HT, THING_TYPE_SENSOR_MOTION, THING_TYPE_SENSOR_SWITCH, + THING_TYPE_SENSOR_MAGNET, THING_TYPE_SENSOR_PLUG, THING_TYPE_SENSOR_CUBE)); private static final long ONLINE_TIMEOUT = 24 * 60 * 60 * 1000; @@ -116,11 +101,12 @@ public void dispose() { @Override public void handleCommand(ChannelUID channelUID, Command command) { - // TODO somehow it seems that this is called as well with LAST KNOWN STATE when openhab gets started. Can this be turned off somehow? + // TODO somehow it seems that this is called as well with LAST KNOWN STATE when openhab gets started. Can this + // be turned off somehow? switch (channelUID.getId()) { case CHANNEL_POWER_ON: String status = command.toString().toLowerCase(); - getXiaomiBridgeHandler().writeToDevice(itemId, new String[]{"status"}, new Object[]{status}); + getXiaomiBridgeHandler().writeToDevice(itemId, new String[] { "status" }, new Object[] { status }); break; case CHANNEL_BRIGHTNESS: if (command instanceof PercentType) { @@ -142,14 +128,15 @@ public void handleCommand(ChannelUID channelUID, Command command) { int kelvin = 48 * colorTemperature.intValue() + 1700; int color = ColorUtil.getRGBFromK(kelvin); writeBridgeLightColor(color, getGatewayLightBrightness()); - updateState(CHANNEL_COLOR, HSBType.fromRGB((color / 256 / 256) & 0xff, (color / 256) & 0xff, color & 0xff)); + updateState(CHANNEL_COLOR, + HSBType.fromRGB((color / 256 / 256) & 0xff, (color / 256) & 0xff, color & 0xff)); } else { - logger.error("Can't handle command " + command); + logger.error("Can't handle command {}", command); } break; default: - logger.error("Can't handle command " + command); + logger.error("Can't handle command {}", command); break; } } @@ -191,7 +178,7 @@ private float getGatewayLightBrightness() { public void onItemUpdate(String sid, String command, JsonObject message) { if (itemId != null && itemId.equals(sid)) { updateItemStatus(); - logger.debug("Item got update: " + message.toString()); + logger.debug("Item got update: {}", message.toString()); JsonObject data = parser.parse(message.get("data").getAsString()).getAsJsonObject(); String model = message.get("model").getAsString(); @@ -205,6 +192,10 @@ public void onItemUpdate(String sid, String command, JsonObject message) { float temperature = data.get("temperature").getAsFloat() / 100; updateState(CHANNEL_TEMPERATURE, new DecimalType(temperature)); } + if (data.get("voltage") != null) { + Integer voltage = data.get("voltage").getAsInt(); + updateState(CHANNEL_VOLTAGE, new DecimalType(voltage)); + } break; case "motion": boolean hasMotion = data.has("status") && data.get("status").getAsString().equals("motion"); @@ -236,18 +227,21 @@ public void onItemUpdate(String sid, String command, JsonObject message) { updateState(CHANNEL_LOAD_POWER, new DecimalType(data.get("load_power").getAsBigDecimal())); } if (data.has("power_consumed")) { - updateState(CHANNEL_POWER_CONSUMED, new DecimalType(data.get("power_consumed").getAsBigDecimal())); + updateState(CHANNEL_POWER_CONSUMED, + new DecimalType(data.get("power_consumed").getAsBigDecimal())); } break; case "gateway": if (data.has("rgb")) { long rgb = data.get("rgb").getAsLong(); - updateState(CHANNEL_BRIGHTNESS, new PercentType((int) (((rgb / 256 / 256 / 256) & 0xff) / 2.55))); - updateState(CHANNEL_COLOR, HSBType.fromRGB((int) (rgb / 256 / 256) & 0xff, (int) (rgb / 256) & 0xff, (int) rgb & 0xff)); + updateState(CHANNEL_BRIGHTNESS, + new PercentType((int) (((rgb / 256 / 256 / 256) & 0xff) / 2.55))); + updateState(CHANNEL_COLOR, HSBType.fromRGB((int) (rgb / 256 / 256) & 0xff, + (int) (rgb / 256) & 0xff, (int) rgb & 0xff)); } break; case "cube": - System.out.println("Cube data:" + data); + logger.debug("Cube data: {}", data); if (data.has("status")) { triggerChannel("action", data.get("status").getAsString().toUpperCase()); } else if (data.has("rotate")) { @@ -256,6 +250,15 @@ public void onItemUpdate(String sid, String command, JsonObject message) { } break; } + + if (data.get("voltage") != null) { + Integer voltage = data.get("voltage").getAsInt(); + updateState(CHANNEL_VOLTAGE, new DecimalType(voltage)); + + if (voltage < 2800) { + triggerChannel("batteryLevel", "LOW"); + } + } } } @@ -270,7 +273,26 @@ private void writeBridgeLightColor(int color, float brightness) { } private void writeBridgeLightColor(long color) { - getXiaomiBridgeHandler().writeToBridge(new String[]{"rgb"}, new Object[]{color}); + getXiaomiBridgeHandler().writeToBridge(new String[] { "rgb" }, new Object[] { color }); + } + + /** + * Play ringtone on Xiaomi Gateway + * 0 - 8, 10 - 13, 20 - 29 -- ringtones that come with the system) + * > 10001 -- user-defined ringtones + * + * @param ringtoneId + */ + private void writeBridgeRingtone(int ringtoneId) { + getXiaomiBridgeHandler().writeToBridge(new String[] { "mid" }, new Object[] { ringtoneId }); + } + + /** + * Stop playing ringtone on Xiaomi Gateway + * by setting "mid" parameter to 10000 + */ + private void stopRingtone() { + getXiaomiBridgeHandler().writeToBridge(new String[] { "mid" }, new Object[] { 10000 }); } private synchronized XiaomiBridgeHandler getXiaomiBridgeHandler() { diff --git a/addons/binding/org.openhab.binding.mihome/src/main/java/org/openhab/binding/mihome/internal/ModelMapper.java b/addons/binding/org.openhab.binding.mihome/src/main/java/org/openhab/binding/mihome/internal/ModelMapper.java index bef009cc3c4c3..fde2754dc8098 100644 --- a/addons/binding/org.openhab.binding.mihome/src/main/java/org/openhab/binding/mihome/internal/ModelMapper.java +++ b/addons/binding/org.openhab.binding.mihome/src/main/java/org/openhab/binding/mihome/internal/ModelMapper.java @@ -7,20 +7,15 @@ */ package org.openhab.binding.mihome.internal; -import org.eclipse.smarthome.core.thing.ThingTypeUID; +import static org.openhab.binding.mihome.XiaomiGatewayBindingConstants.*; -import static org.openhab.binding.mihome.XiaomiGatewayBindingConstants.THING_TYPE_GATEWAY; -import static org.openhab.binding.mihome.XiaomiGatewayBindingConstants.THING_TYPE_SENSOR_CUBE; -import static org.openhab.binding.mihome.XiaomiGatewayBindingConstants.THING_TYPE_SENSOR_HT; -import static org.openhab.binding.mihome.XiaomiGatewayBindingConstants.THING_TYPE_SENSOR_MAGNET; -import static org.openhab.binding.mihome.XiaomiGatewayBindingConstants.THING_TYPE_SENSOR_MOTION; -import static org.openhab.binding.mihome.XiaomiGatewayBindingConstants.THING_TYPE_SENSOR_PLUG; -import static org.openhab.binding.mihome.XiaomiGatewayBindingConstants.THING_TYPE_SENSOR_SWITCH; +import org.eclipse.smarthome.core.thing.ThingTypeUID; /** - * Maps the model (provided from xiaomi) to thing. + * Maps the model (provided from Xiaomi) to thing. * * @author Patrick Boos - Initial contribution + * @author Kuba Wolanin - Renamed labels */ public class ModelMapper { @@ -47,19 +42,19 @@ public static ThingTypeUID getThingTypeForModel(String model) { public static String getLabelForModel(String model) { switch (model) { case "gateway": - return "Gateway"; + return "Xiaomi Mi Smart Home Gateway"; case "sensor_ht": - return "Temperature & Humidity Sensor"; + return "Xiaomi Mi Temperature & Humidity Sensor"; case "motion": - return "Motion Sensor"; + return "Xiaomi Mi Motion Sensor"; case "magnet": - return "Open/close Sensor"; + return "Xiaomi Door/Window Sensor"; case "switch": - return "Button"; + return "Xiaomi Mi Wireless Switch"; case "plug": - return "Plug"; + return "Xiaomi Mi Smart Socket Plug"; case "cube": - return "Magic Controller (Cube)"; + return "Xiaomi Mi Smart Cube"; } return null; } diff --git a/addons/binding/org.openhab.binding.mihome/src/main/java/org/openhab/binding/mihome/internal/discovery/XiaomiBridgeDiscoveryService.java b/addons/binding/org.openhab.binding.mihome/src/main/java/org/openhab/binding/mihome/internal/discovery/XiaomiBridgeDiscoveryService.java index 2b90b58b429cd..218824004a9f9 100644 --- a/addons/binding/org.openhab.binding.mihome/src/main/java/org/openhab/binding/mihome/internal/discovery/XiaomiBridgeDiscoveryService.java +++ b/addons/binding/org.openhab.binding.mihome/src/main/java/org/openhab/binding/mihome/internal/discovery/XiaomiBridgeDiscoveryService.java @@ -7,7 +7,15 @@ */ package org.openhab.binding.mihome.internal.discovery; -import com.google.gson.JsonObject; +import static org.openhab.binding.mihome.XiaomiGatewayBindingConstants.*; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.Semaphore; +import java.util.concurrent.TimeUnit; + import org.eclipse.smarthome.config.discovery.AbstractDiscoveryService; import org.eclipse.smarthome.config.discovery.DiscoveryResultBuilder; import org.eclipse.smarthome.core.thing.ThingTypeUID; @@ -17,22 +25,13 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.Semaphore; -import java.util.concurrent.TimeUnit; - -import static org.openhab.binding.mihome.XiaomiGatewayBindingConstants.HOST; -import static org.openhab.binding.mihome.XiaomiGatewayBindingConstants.PORT; -import static org.openhab.binding.mihome.XiaomiGatewayBindingConstants.SERIAL_NUMBER; -import static org.openhab.binding.mihome.XiaomiGatewayBindingConstants.THING_TYPE_BRIDGE; +import com.google.gson.JsonObject; /** - * Discovery service for the xiaomi bridge. + * Discovery service for the Xiaomi bridge. * * @author Patrick Boos - Initial contribution + * @author Kuba Wolanin - logger fixes */ public class XiaomiBridgeDiscoveryService extends AbstractDiscoveryService implements XiaomiSocketListener { @@ -98,19 +97,16 @@ private void getGatewayInfo(JsonObject jobject) { properties.put(HOST, ipAddress); properties.put(PORT, port); - logger.debug("Discovered Xiaomi Gateway - sid: " + serialNumber + " ip: " + ipAddress + " port: " + port); + logger.debug("Discovered Xiaomi Gateway - sid: {} ip: {} port: {}", serialNumber, ipAddress, port); ThingUID thingUID = new ThingUID(THING_TYPE_BRIDGE, serialNumber); - thingDiscovered(DiscoveryResultBuilder.create(thingUID) - .withThingType(THING_TYPE_BRIDGE) - .withProperties(properties) - .withLabel("Xiaomi Gateway") - .withRepresentationProperty(SERIAL_NUMBER) - .build()); - -// DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(thingUID).withThingType(thingTypeUID) -// .withProperties(properties).withBridge(bridgeUID).withLabel(light.getName()).build(); -// thingDiscovered(discoveryResult); -// return new ThingUID(thingTypeUID, bridgeUID, light.getId()); + thingDiscovered( + DiscoveryResultBuilder.create(thingUID).withThingType(THING_TYPE_BRIDGE).withProperties(properties) + .withLabel("Xiaomi Gateway").withRepresentationProperty(SERIAL_NUMBER).build()); + + // DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(thingUID).withThingType(thingTypeUID) + // .withProperties(properties).withBridge(bridgeUID).withLabel(light.getName()).build(); + // thingDiscovered(discoveryResult); + // return new ThingUID(thingTypeUID, bridgeUID, light.getId()); } } diff --git a/addons/binding/org.openhab.binding.mihome/src/main/java/org/openhab/binding/mihome/internal/discovery/XiaomiItemDiscoveryService.java b/addons/binding/org.openhab.binding.mihome/src/main/java/org/openhab/binding/mihome/internal/discovery/XiaomiItemDiscoveryService.java index b4e132eab38cb..6519372bd1579 100644 --- a/addons/binding/org.openhab.binding.mihome/src/main/java/org/openhab/binding/mihome/internal/discovery/XiaomiItemDiscoveryService.java +++ b/addons/binding/org.openhab.binding.mihome/src/main/java/org/openhab/binding/mihome/internal/discovery/XiaomiItemDiscoveryService.java @@ -7,7 +7,15 @@ */ package org.openhab.binding.mihome.internal.discovery; -import com.google.gson.JsonObject; +import static org.openhab.binding.mihome.XiaomiGatewayBindingConstants.ITEM_ID; +import static org.openhab.binding.mihome.internal.ModelMapper.*; + +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.Semaphore; +import java.util.concurrent.TimeUnit; + import org.eclipse.smarthome.config.discovery.AbstractDiscoveryService; import org.eclipse.smarthome.config.discovery.DiscoveryResultBuilder; import org.eclipse.smarthome.core.thing.ThingTypeUID; @@ -17,15 +25,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.Semaphore; -import java.util.concurrent.TimeUnit; - -import static org.openhab.binding.mihome.XiaomiGatewayBindingConstants.ITEM_ID; -import static org.openhab.binding.mihome.internal.ModelMapper.getLabelForModel; -import static org.openhab.binding.mihome.internal.ModelMapper.getThingTypeForModel; +import com.google.gson.JsonObject; /** * Discovery service for items/sensors. @@ -93,11 +93,11 @@ public void run() { public void onItemUpdate(String sid, String command, JsonObject data) { if (command.equals("read_ack") || command.equals("report")) { String model = data.get("model").getAsString(); - logger.debug("Detected Xiaomi smart device - sid: " + sid + " model: " + model); + logger.debug("Detected Xiaomi smart device - sid: {} model: {}", sid, model); ThingTypeUID thingType = getThingTypeForModel(model); if (thingType == null) { - logger.error("Unknown discovered model: " + model); + logger.error("Unknown discovered model: {}", model); return; } @@ -105,13 +105,9 @@ public void onItemUpdate(String sid, String command, JsonObject data) { properties.put(ITEM_ID, sid); ThingUID thingUID = new ThingUID(thingType, sid); - thingDiscovered(DiscoveryResultBuilder.create(thingUID) - .withThingType(thingType) - .withProperties(properties) - .withRepresentationProperty(ITEM_ID) - .withLabel(getLabelForModel(model)) - .withBridge(xiaomiBridgeHandler.getThing().getUID()) - .build()); + thingDiscovered(DiscoveryResultBuilder.create(thingUID).withThingType(thingType).withProperties(properties) + .withRepresentationProperty(ITEM_ID).withLabel(getLabelForModel(model)) + .withBridge(xiaomiBridgeHandler.getThing().getUID()).build()); } } } diff --git a/addons/binding/org.openhab.binding.mihome/src/main/java/org/openhab/binding/mihome/internal/socket/XiaomiSocket.java b/addons/binding/org.openhab.binding.mihome/src/main/java/org/openhab/binding/mihome/internal/socket/XiaomiSocket.java index 75198e0d4082f..718b5de30dd12 100644 --- a/addons/binding/org.openhab.binding.mihome/src/main/java/org/openhab/binding/mihome/internal/socket/XiaomiSocket.java +++ b/addons/binding/org.openhab.binding.mihome/src/main/java/org/openhab/binding/mihome/internal/socket/XiaomiSocket.java @@ -7,11 +7,6 @@ */ package org.openhab.binding.mihome.internal.socket; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.io.IOException; import java.net.DatagramPacket; import java.net.InetAddress; @@ -20,6 +15,12 @@ import java.util.ArrayList; import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; + /** * Takes care of the communication with the bridge. * @@ -27,7 +28,7 @@ */ public class XiaomiSocket { private static final int BUFFER_LENGTH = 1024; - //private final int DEST_PORT = 9898; + // private final int DEST_PORT = 9898; private static final String MCAST_ADDR = "224.0.0.50"; private static final int MCAST_PORT = 4321; private static final int DEFAULT_PORT = 9898; @@ -63,10 +64,11 @@ private static void setupSocket() { synchronized (XiaomiSocket.class) { try { logger.debug("Setup socket"); - // TODO check if this can be any port. if yes, than we can have a socket for each discovery, and each bridge + // TODO check if this can be any port. if yes, than we can have a socket for each discovery, and each + // bridge socket = new MulticastSocket(DEFAULT_PORT); // must bind receive side socket.joinGroup(InetAddress.getByName(MCAST_ADDR)); - logger.debug("network interface: " + socket.getNetworkInterface().getName()); + logger.debug("network interface: {}", socket.getNetworkInterface().getName()); } catch (IOException e) { logger.error("Setup socket error", e); } @@ -102,13 +104,14 @@ public static void sendMessage(String message, InetAddress address, int port) { byte[] sendData = message.getBytes("UTF-8"); DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, address, port); socket.send(sendPacket); - logger.debug("Sent message: " + message); + logger.debug("Sent message: {}", message); } catch (IOException e) { logger.error("Sending error", e); } } private static class ReceiverThread extends Thread { + @Override public void run() { receiveData(socket, datagramPacket); }