From 3be63775b5c063b934eb41a67b4a20e9f5f89660 Mon Sep 17 00:00:00 2001 From: jghaanstra Date: Sun, 18 Feb 2018 22:30:43 +0100 Subject: [PATCH] Release 2.6.0 --- APPSTORE.md | 14 +- app.json | 172 +++++++++++++++++- drivers/air-monitor/assets/icon.svg | 50 +++++ drivers/air-monitor/assets/images/large.jpg | Bin 0 -> 26010 bytes drivers/air-monitor/assets/images/small.jpg | Bin 0 -> 2118 bytes drivers/air-monitor/device.js | 73 ++++++++ drivers/air-monitor/driver.js | 40 ++++ drivers/air-monitor/pair/start.html | 147 +++++++++++++++ drivers/mi-airpurifier/driver.js | 2 +- drivers/mi-humidifier/driver.js | 2 +- drivers/mi-power-plug/pair/start.html | 2 +- drivers/mi-power-strip/assets/icon.svg | 109 +++++++++++ .../mi-power-strip/assets/images/large.jpg | Bin 0 -> 10541 bytes .../mi-power-strip/assets/images/small.jpg | Bin 0 -> 1074 bytes drivers/mi-power-strip/device.js | 74 ++++++++ drivers/mi-power-strip/driver.js | 41 +++++ drivers/mi-power-strip/pair/start.html | 145 +++++++++++++++ drivers/mi-robot/pair/start.html | 2 +- locales/en.json | 2 + locales/nl.json | 2 + package.json | 2 +- 21 files changed, 857 insertions(+), 22 deletions(-) create mode 100644 drivers/air-monitor/assets/icon.svg create mode 100644 drivers/air-monitor/assets/images/large.jpg create mode 100644 drivers/air-monitor/assets/images/small.jpg create mode 100644 drivers/air-monitor/device.js create mode 100644 drivers/air-monitor/driver.js create mode 100644 drivers/air-monitor/pair/start.html create mode 100644 drivers/mi-power-strip/assets/icon.svg create mode 100644 drivers/mi-power-strip/assets/images/large.jpg create mode 100644 drivers/mi-power-strip/assets/images/small.jpg create mode 100644 drivers/mi-power-strip/device.js create mode 100644 drivers/mi-power-strip/driver.js create mode 100644 drivers/mi-power-strip/pair/start.html 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 0000000000000000000000000000000000000000..838674bc6555313d6bef8de126d0ffcd7b1975b2 GIT binary patch literal 26010 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 WATu*w2jIUo^-JS_TO#^7_kRGiGN1bZ literal 0 HcmV?d00001 diff --git a/drivers/air-monitor/assets/images/small.jpg b/drivers/air-monitor/assets/images/small.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9841390f598fbb484969d13782c7535c87121c0f GIT binary patch literal 2118 zcmaJ?cTm&W8vTWIYC?d}n}7jV4IrTiA`lP(F+`Ro9b6(9iWptRMao-RXn`Pz;D&0D z;ws7_EGWG!s1QUGhyqfShz&snLSEcAZ}$1mJ9p;JeD{2F&Y5q%nJaoGngLKQPKTWU z5C{Y~iw_{00vrH|?*N8?B_zNQDC8TUFzDZa!QgNN91cSwB_)wa>F@DP1Ox_yp%5q% z21Ck7A*E#GWW|t^`@Zr2RiXy~8UeThu3!)vkU)dLXppEE&;$Sw7%EQt4`6Uf5Ez0$ zLM6n!BMJbZ;=E9p6jU$jOX~TV3NEuaIsP zQ+o%`(6H0-w3J_G#WKob2k`%zh;79>VnzooroPSR9~vZq1{=#`bdnV+ZZSkWKw3DSJRpuclagV-=#psFqLA{R#RafG2%4=T@NXFZo*&3San&s~Vd+ zU)gdwAA*cu+}0{hnT=*QU!utQI=rwG+|7@C19;e$PlJb3t&&(c3}z3+)5LM`4S)lF z&NF5mv@1u-n=ap6&4PGSZB^eaGqS{+hyS;*&!yk$Sx%gP~J}2M4Jhf z!`*||hj3hNZ5TdOy+^QWpQ>Xqq>Ua)cr5qn(OVYDsfa@cDLI~9983ll~m6<(wVnP9FJ9yTQIkx~{an;B5Md z@%px-k}1Kp&cwmcG^tiDdZ9@9)UV$~8>dA3hW(jCd9#_fI4`J{e)L9ET@Glkk>>)xx+dbm$-CM&i=FRzbQi*!}uUNF| z{If$EKdzduw_Dy<%^$hASGb(?sX55~hre99i#u1&(}%Vz73Zr8?lQgbp~1XPKVwr< z$gsXI?=M1t+s%8r%(~)wjeb?>^BKF%IQuWpG)JqEgM8jq2IN(2<>zS-E17-<&J4kw zT_$A$t4ov04`3LywxL5k=_q&aYE_{Yi*(B{vYVlV;fH={WS?lB$)58M^@!#xJ@od+ z27s#za?hs|59 zR50{7Tkx>h0Lx=!g%32y)PhWx%bq1%8!xy#LG`5B>X$TnYYq+tEQ&^bRbF}v$O7;v=#bet)I<@nQKguFxQ3szLkIBC3O32&q(~quY%1eEgnR_`kp!fQPR~S<% z){7sR1jB=}bz1pzC)1re={1MOq}6_Q3Dr#XCl72)m)-CAwho0v>4@SS$S#ZFgU91s zn+y@b_DiuLBH#)lraz~3Bg#xw-6Bc^%&^xz=*RK$ltamGPfl=#`+Q`7Uu*A`c_fuV z?SJlwPs;Ep?^<-_A09G4lj4CRC{}kLhUSJEh4*40>xea?zyvCtx%y~Fc1gEx9P{x; zHD$9;t;Kz``K?KnCgo#SCnZRK1ry^B#leR`x3zbaMSvV8o%o#B0p{wB53=`B|74c_ zO8R|l;Tcz^+K^D|4+A%s?#&)EC)Pxa8BCLBCHbBXn#YXy#BS)R|7X$Ti2y6DSPR{x z`=#S4#9#Z2b>#`Hb8@O$VL)L#vuiVbA9a93!aXJ_K;bMt1FPd60bE|;4#L2iHmrAR zB=12<14}!e1uiLCeRZKM&2%`$w;ao$6Ju$$Lk(Fq*jmQVB^hCH*u+`;s}uToMB=jL z?UlzH+N5~z?Cspmqgg7%80Ra6JgmUe`nTEeLZh14d_+l|g>&~ol4KZyd5+mPm_}>` z3<4~3mnw?=Ii3qtw$ka>@RG`$r#k7c3@7AT=$pF`7gWC_eF~h!ZwxN+9k@ZZgWO*1 zN)7#u)z%%GBGRix~PwF{x#~E((}u>)5-1Wk>}qVC%mGUH?46AXY`XJyM5PR5|w)n-aS$U hW9MVsGOI~CE@XJD_%nsGa1}ou6i*EF-%Crx{Wp=3e;oh- literal 0 HcmV?d00001 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.

+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+
+
+ +
+

Connection test successfull, you can now connect the device.

+

Mi Home device added succesfully.

+

+
diff --git a/drivers/mi-airpurifier/driver.js b/drivers/mi-airpurifier/driver.js index 11f6dcd..61791fd 100644 --- a/drivers/mi-airpurifier/driver.js +++ b/drivers/mi-airpurifier/driver.js @@ -14,7 +14,7 @@ class MiAirPurifierDriver extends Homey.Driver { const getData = async () => { try { const power = await device.power(); - const temp = await device.temperature() + const temp = await device.temperature(); const rh = await device.relativeHumidity(); const aqi = await device.pm2_5(); const mode = await device.mode(); diff --git a/drivers/mi-humidifier/driver.js b/drivers/mi-humidifier/driver.js index dffc70d..d58c21c 100644 --- a/drivers/mi-humidifier/driver.js +++ b/drivers/mi-humidifier/driver.js @@ -14,7 +14,7 @@ class MiHumidifierDriver extends Homey.Driver { const getData = async () => { try { const power = await device.power(); - const temp = await device.temperature() + const temp = await device.temperature(); const rh = await device.relativeHumidity(); const mode = await device.mode(); diff --git a/drivers/mi-power-plug/pair/start.html b/drivers/mi-power-plug/pair/start.html index d2ded15..79a778a 100644 --- a/drivers/mi-power-plug/pair/start.html +++ b/drivers/mi-power-plug/pair/start.html @@ -126,7 +126,7 @@
- +
diff --git a/drivers/mi-power-strip/assets/icon.svg b/drivers/mi-power-strip/assets/icon.svg new file mode 100644 index 0000000..99ee87f --- /dev/null +++ b/drivers/mi-power-strip/assets/icon.svg @@ -0,0 +1,109 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/drivers/mi-power-strip/assets/images/large.jpg b/drivers/mi-power-strip/assets/images/large.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2b5dc36902b5ed859568ffe04b07f20b3653c868 GIT binary patch literal 10541 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 literal 0 HcmV?d00001 diff --git a/drivers/mi-power-strip/assets/images/small.jpg b/drivers/mi-power-strip/assets/images/small.jpg new file mode 100644 index 0000000000000000000000000000000000000000..20c384849a6dcef1cb7d9a7424754fa48df9e36b GIT binary patch literal 1074 zcmex=?R8@78Ot2xarUbpgs|x_t5}IR1j1276T8^awb7$K?Zw<-#;4g zf#xP>$3in+aaFc0hR;v1^rYx?J`Ra`Uu)a4;KZG{h4-};Z0GLZ#r1i%Qm)Nbw>una zFFx&WH9LR%<<__Rts_}(ZrrK)Xi{agaB}CadCoC!+b8FFahyGKwq#0S!-YRidZwz6 zC!NdPnpbIZd&9eCUAF|2WsJtjY|Fw9bMREJdtS6}_U(58if3#pUuE7nCYf=E)tNi) z{_FxrYm3?mIU%37Efe#(+q|>yk(q|^f=@ozf6OV6$dWMHW*?~TW@M!9XdRPZxSdO~ zJ-v#1kNqc;`jhG391U5cH?EOga5&)Gago;d zIrW^I=j7P0;#XdBs^|>_}A9@Yn!+`KIWLN-7;gY@Z9@H zGyhHqlX05etMhBqcaN7!5?Mc*{xTlzuPk`J?$NFMB!}`z+@6LtCdU=}1rHx-UEUV= zA$ryAEQU|JxL)bF^{G3=z2WNdWtSIza7v~syIIPa?|MddUGmNw3X`L|F4}1vwG9&v z@VVI4kv@STL2t`0zyAyZd5`y9d%KHo%Z_D|J|`EK`U!e_Gq*(46zs|MmzKKr>fPH7 zGOZKxW>#&Rw4Sf^%2xy56??BGH}Bjr@g(anzIDlQCVSUbyiPal0bgQn JXlVX_6952|ke~nn literal 0 HcmV?d00001 diff --git a/drivers/mi-power-strip/device.js b/drivers/mi-power-strip/device.js new file mode 100644 index 0000000..d1a888c --- /dev/null +++ b/drivers/mi-power-strip/device.js @@ -0,0 +1,74 @@ +'use strict'; + +const Homey = require('homey'); +const miio = require('miio'); + +class PowerStripDevice extends Homey.Device { + + onInit() { + this.createDevice(); + + this.registerCapabilityListener('onoff', this.onCapabilityOnoff.bind(this)); + } + + onDeleted() { + clearInterval(this.pollingInterval); + } + + // 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') || 30; + this.pollDevice(interval); + }).catch(function (error) { + return reject(error); + }); + } + + pollDevice(interval) { + clearInterval(this.pollingInterval); + + this.pollingInterval = setInterval(() => { + const getData = async () => { + try { + // TODO: implement measure_power and meter_power capability + const power = await this.miio.power(); + const powerload = 0; + const powerconsumed = 0; + + if (this.getCapabilityValue('onoff') != power) { + this.setCapabilityValue('onoff', power); + } + if (this.getCapabilityValue('measure_power') != powerload) { + this.setCapabilityValue('measure_power', powerload); + } + if (this.getCapabilityValue('meter_power') != powerconsumed) { + this.setCapabilityValue('meter_power', powerconsumed); + } + if (!this.getAvailable()) { + this.setAvailable(); + } + } catch (error) { + this.setUnavailable(Homey.__('unreachable')); + this.log(error); + } + } + getData(); + }, 1000 * interval); + } + +} + +module.exports = PowerStripDevice; diff --git a/drivers/mi-power-strip/driver.js b/drivers/mi-power-strip/driver.js new file mode 100644 index 0000000..142f2ce --- /dev/null +++ b/drivers/mi-power-strip/driver.js @@ -0,0 +1,41 @@ +"use strict"; + +const Homey = require('homey'); +const miio = require('miio'); + +class PowerStripDriver 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 { + // TODO: implement measure_power and meter_power capability + const power = await device.power(); + const powerload = 0; + const powerconsumed = 0; + + let result = { + onoff: power, + powerload: powerload, + powerconsumed: powerconsumed + } + + callback(null, result); + } catch (error) { + callback(error, null); + } + } + getData(); + }).catch(function (error) { + callback(error, null); + }); + }); + } + +} + +module.exports = PowerStripDriver; diff --git a/drivers/mi-power-strip/pair/start.html b/drivers/mi-power-strip/pair/start.html new file mode 100644 index 0000000..c3ea72a --- /dev/null +++ b/drivers/mi-power-strip/pair/start.html @@ -0,0 +1,145 @@ + + + + +

Enter the details of your Mi Home device.

+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+
+
+ +
+

Connection test successfull, you can now connect the device.

+

Mi Home device added succesfully.

+

+
diff --git a/drivers/mi-robot/pair/start.html b/drivers/mi-robot/pair/start.html index 8cfe137..fc62200 100644 --- a/drivers/mi-robot/pair/start.html +++ b/drivers/mi-robot/pair/start.html @@ -134,7 +134,7 @@
- +
diff --git a/locales/en.json b/locales/en.json index d4a966b..80d7af7 100644 --- a/locales/en.json +++ b/locales/en.json @@ -7,7 +7,9 @@ "humidifier": "Humidifier", "philipsbulb": "Philips Light Bulb", "philipseyecare": "Philips Eyecare Lamp", + "airmonitor": "PM2.5 Air Monitor", "powerplug": "Mi Power Plug", + "powerstrip": "Mi Power Strip", "powered": "Powered:", "mode": "Mode:", "dim": "Dim Level:", diff --git a/locales/nl.json b/locales/nl.json index 9fb8780..3ad9986 100644 --- a/locales/nl.json +++ b/locales/nl.json @@ -7,7 +7,9 @@ "humidifier": "Luchtbevochtiger", "philipsbulb": "Philips Light Bulb", "philipseyecare": "Philips Eyecare Lamp", + "airmonitor": "PM2.5 Air Monitor", "powerplug": "Mi Power Plug", + "powerstrip": "Mi Power Strip", "powered": "Aangezet:", "mode": "Modus:", "dim": "Dim niveau:", diff --git a/package.json b/package.json index 1bb0623..72b00ad 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "com.xiaomi-miio", - "version": "2.5.3", + "version": "2.6.0", "description": "Xiaomi Mi Home", "main": "app.js", "dependencies": {