diff --git a/APPSTORE.md b/APPSTORE.md index d7616ad..ac3ea0f 100644 --- a/APPSTORE.md +++ b/APPSTORE.md @@ -10,7 +10,8 @@ Below is a list of supported devices and devices. Post a comment in the [support * Xiaomi Robot Vacuum Cleaner (tested) * Xiaomi Air Purifiers 2, 2S and Pro (tested) * Xiamomi Humidifier (tested) -* Xiaomi Single Power Plug WiFi version (untested) +* Xiaomi Single Power Plug and Power Strip WiFi version (tested) +* Xiaomi PM2.5 Air Monitor (tested) ## Support topic For support please use the official support topic on the forum [here](https://forum.athom.com/discussion/3295/). @@ -45,17 +46,12 @@ For Homey to be able to communicate with devices over the miIO protocol a unique * Default flow cards for on/off, measure power and meter power capabilities class ## Changelog -### 2018-02-17 -- v2.5.3 +### 2018-02-18 -- v2.6.0 +* NEW: add support for PM2.5 sensor +* NEW: add basic support for WiFi power strips (power load and power consumed are not available for now) * UPDATE: update miio library to 0.15.6 which fixes: * Power and color temperature setting fixed for Philips Light Bulbs * Refreshing of vacuumcleaner state after starting and stopping cleaning * FIX: update vacuumcleaner state directly when using onoff capability * FIX: fix flow cards not showing (un)succesful execution status * FIX: possible fix for showing temperature for purifiers and humidifiers - -### 2018-02-07 -- v2.5.2 -* FIX: removed powerLoad and powerConsumed capability in WiFi plug driver as these capabilities are not available for this device - -### 2018-02-04 -- v2.5.1 -* UPDATE: updated the miio library to 0.15.5 and rewritten all device drivers -* UPDATE: reintroduced support for the Mi Robot Vacuum Cleaner (needs re-pairing the device if coming from an older version) diff --git a/app.json b/app.json index c377c61..06349ef 100644 --- a/app.json +++ b/app.json @@ -9,7 +9,7 @@ "en": [ "Xiaomi", "Mi", "Mi Home", "miio", "vacuumcleaner", "robot", "yeelight", "yeelights", "purifier", "humidifier", "philips", "eyecare", "powerplug" ], "nl": [ "Xiaomi", "Mi", "Mi home", "miio", "stofzuiger", "robot", "yeelight", "yeelights", "luchtreiniger", "luchtbevochtiger", "philips", "eyecare", "powerplug" ] }, - "version": "2.5.3", + "version": "2.6.0", "compatibility": "1.x >=1.5.0", "author": { "name": "Jelger Haanstra", @@ -234,6 +234,10 @@ { "id": "picker", "capabilities": [ "vacuumcleaner_state" ] + }, + { + "id": "toggle", + "capabilities": [ "onoff" ] } ] }, @@ -271,7 +275,11 @@ { "id": "polling", "type": "number", - "value": 60, + "value": 30, + "attr": { + "min": 30, + "max": 3600 + }, "label": { "en": "Mi Robot Polling", "nl": "Mi Robot Polling" @@ -308,12 +316,13 @@ "id": "sensor", "capabilities": [ "measure_temperature", - "measure_humidity" + "measure_humidity", + "measure_pm25" ] }, { - "id": "sensor", - "capabilities": [ "measure_pm25" ] + "id": "toggle", + "capabilities": [ "onoff" ] } ] }, @@ -389,11 +398,14 @@ }, { "id": "sensor", - "capabilities": [ "measure_temperature" ] + "capabilities": [ + "measure_temperature", + "measure_humidity" + ] }, { - "id": "sensor", - "capabilities": [ "measure_humidity" ] + "id": "toggle", + "capabilities": [ "onoff" ] } ] }, @@ -445,6 +457,86 @@ } ] }, + { + "id": "air-monitor", + "name": { + "en": "PM2.5 Air Monitor", + "nl": "PM2.5 Air Monitor" + }, + "images": { + "large": "drivers/air-monitor/assets/images/large.jpg", + "small": "drivers/air-monitor/assets/images/small.jpg" + }, + "class": "sensor", + "capabilities": [ + "onoff", + "measure_battery", + "measure_pm25" + ], + "mobile": { + "components": [ + { + "id": "icon", + "capabilities": [ "onoff" ] + }, + { + "id": "sensor", + "capabilities": [ "measure_pm25" ] + }, + { + "id": "toggle", + "capabilities": [ "onoff" ] + } + ] + }, + "pair": [ + { + "id": "start" + } + ], + "settings": [ + { + "type": "group", + "label": { + "en": "PM2.5 Air Monitor Settings", + "nl": "PM2.5 Air Monitor Instellingen" + }, + "children": [ + { + "id": "address", + "type": "text", + "value": "0.0.0.0", + "label": { + "en": "IP Address", + "nl": "IP Adres" + } + }, + { + "id": "token", + "type": "text", + "value": "", + "label": { + "en": "PM2.5 Air Monitor Token", + "nl": "PM2.5 Air Monitor Token" + } + }, + { + "id": "polling", + "type": "number", + "value": 60, + "attr": { + "min": 5, + "max": 3600 + }, + "label": { + "en": "PM2.5 Air Monitor Polling", + "nl": "PM2.5 Air Monitor Polling" + } + } + ] + } + ] + }, { "id": "mi-power-plug", "name": { @@ -506,6 +598,70 @@ ] } ] + }, + { + "id": "mi-power-strip", + "name": { + "en": "Mi Power Strip", + "nl": "Mi Power Strip" + }, + "images": { + "large": "drivers/mi-power-strip/assets/images/large.jpg", + "small": "drivers/mi-power-strip/assets/images/small.jpg" + }, + "class": "sensor", + "capabilities": [ + "onoff", + "measure_power", + "meter_power" + ], + "pair": [ + { + "id": "start" + } + ], + "settings": [ + { + "type": "group", + "label": { + "en": "Mi Power Strip Settings", + "nl": "Mi Power Strip Instellingen" + }, + "children": [ + { + "id": "address", + "type": "text", + "value": "0.0.0.0", + "label": { + "en": "IP Address", + "nl": "IP Adres" + } + }, + { + "id": "token", + "type": "text", + "value": "", + "label": { + "en": "Mi Power Strip Token", + "nl": "Mi Power Strip Token" + } + }, + { + "id": "polling", + "type": "number", + "value": 30, + "attr": { + "min": 5, + "max": 3600 + }, + "label": { + "en": "Mi Power Strip Polling", + "nl": "Mi Power Strip Polling" + } + } + ] + } + ] } ], "flow": { diff --git a/drivers/air-monitor/assets/icon.svg b/drivers/air-monitor/assets/icon.svg new file mode 100644 index 0000000..4423cb9 --- /dev/null +++ b/drivers/air-monitor/assets/icon.svg @@ -0,0 +1,50 @@ + + + diff --git a/drivers/air-monitor/assets/images/large.jpg b/drivers/air-monitor/assets/images/large.jpg new file mode 100644 index 0000000..838674b Binary files /dev/null and b/drivers/air-monitor/assets/images/large.jpg differ diff --git a/drivers/air-monitor/assets/images/small.jpg b/drivers/air-monitor/assets/images/small.jpg new file mode 100644 index 0000000..9841390 Binary files /dev/null and b/drivers/air-monitor/assets/images/small.jpg differ diff --git a/drivers/air-monitor/device.js b/drivers/air-monitor/device.js new file mode 100644 index 0000000..c52f0b9 --- /dev/null +++ b/drivers/air-monitor/device.js @@ -0,0 +1,73 @@ +'use strict'; + +const Homey = require('homey'); +const miio = require('miio'); + +class MiAirMonitorDevice extends Homey.Device { + + onInit() { + this.createDevice(); + + this.registerCapabilityListener('onoff', this.onCapabilityOnoff.bind(this)); + } + + onDeleted() { + clearInterval(this.pollingInterval); + this.miio.destroy(); + } + + // LISTENERS FOR UPDATING CAPABILITIES + onCapabilityOnoff(value, opts, callback) { + this.miio.setPower(value) + .then(result => { callback(null, value) }) + .catch(error => { callback(error, false) }); + } + + // HELPER FUNCTIONS + createDevice() { + miio.device({ + address: this.getSetting('address'), + token: this.getSetting('token') + }).then(miiodevice => { + this.miio = miiodevice; + + var interval = this.getSetting('polling') || 60; + this.pollDevice(interval); + }).catch(function (error) { + return reject(error); + }); + } + + pollDevice(interval) { + clearInterval(this.pollingInterval); + + this.pollingInterval = setInterval(() => { + const getData = async () => { + try { + const power = await this.miio.power(); + const battery = await this.miio.batteryLevel(); + const aqi = await this.miio.pm2_5(); + + if (this.getCapabilityValue('onoff') != power) { + this.setCapabilityValue('onoff', power); + } + if (this.getCapabilityValue('measure_battery') != battery) { + this.setCapabilityValue('measure_battery', battery); + } + if (this.getCapabilityValue('measure_pm25') != aqi) { + this.setCapabilityValue('measure_pm25', aqi); + } + if (!this.getAvailable()) { + this.setAvailable(); + } + } catch (error) { + this.setUnavailable(Homey.__('unreachable')); + this.log(error); + } + } + getData(); + }, 1000 * interval); + } +} + +module.exports = MiAirMonitorDevice; diff --git a/drivers/air-monitor/driver.js b/drivers/air-monitor/driver.js new file mode 100644 index 0000000..91ccecd --- /dev/null +++ b/drivers/air-monitor/driver.js @@ -0,0 +1,40 @@ +"use strict"; + +const Homey = require('homey'); +const miio = require('miio'); + +class MiAirMonitorDriver extends Homey.Driver { + + onPair(socket) { + socket.on('testConnection', function(data, callback) { + miio.device({ + address: data.address, + token: data.token + }).then(device => { + const getData = async () => { + try { + const power = await device.power(); + const battery = await device.batteryLevel(); + const aqi = await device.pm2_5(); + + let result = { + onoff: power, + battery: battery, + aqi: aqi + } + + callback(null, result); + } catch (error) { + callback(error, null); + } + } + getData(); + }).catch(function (error) { + callback(error, null); + }); + }); + } + +} + +module.exports = MiAirMonitorDriver; diff --git a/drivers/air-monitor/pair/start.html b/drivers/air-monitor/pair/start.html new file mode 100644 index 0000000..d00b032 --- /dev/null +++ b/drivers/air-monitor/pair/start.html @@ -0,0 +1,147 @@ + + + + +
Enter the details of your Mi Home device.
+