diff --git a/APPSTORE.md b/APPSTORE.md index 269b67c..981812d 100644 --- a/APPSTORE.md +++ b/APPSTORE.md @@ -27,8 +27,5 @@ For Homey to be able to communicate with devices over the miIO protocol a unique Xiaomi has recently released an update for its v1 vacuum that enabled it for the zoned cleaning and goto function that was previously only available to the v2 vacuum. Using the action cards that utilize these functions are a bit challenging. If you want to use these cards please read the instructions [here](https://github.com/jghaanstra/com.xiaomi-miio/blob/master/docs/mirobot_zonecleanup.md). ## Changelog -### 2018-11-28 - v2.9.3 -* FIX: fix for Xiaomi Philips Zhirui Downlights - -### 2018-11-28 - v2.9.2 -* NEW: added support for Xiaomi Philips Zhirui Candle Lights (PR from rdvanbuuren) and Xiaomi Philips Zhirui Downlights +### 2019-01-16 - v2.9.4 +* FIX: better error handling to avoid app crashes diff --git a/app.js b/app.js index c244504..0a9f6f1 100644 --- a/app.js +++ b/app.js @@ -58,28 +58,44 @@ class XiaomiMiioApp extends Homey.App { new Homey.FlowCardAction('findVacuum') .register() .registerRunListener((args, state) => { - return args.device.miio.find(); + if (args.device.miio) { + return args.device.miio.find(); + } else { + return Promise.reject(new Error('Device unreachable, please try again ...')); + } }) new Homey.FlowCardAction('fanPowerVacuum') .register() .registerRunListener((args, state) => { - return args.device.miio.changeFanSpeed(Number(args.fanspeed)).then(result => { - return args.device.setStoreValue('fanspeed', args.fanspeed); - }); + if (args.device.miio) { + return args.device.miio.changeFanSpeed(Number(args.fanspeed)).then(result => { + return args.device.setStoreValue('fanspeed', args.fanspeed); + }); + } else { + return Promise.reject(new Error('Device unreachable, please try again ...')); + } }) new Homey.FlowCardAction('goToTargetVacuum') .register() .registerRunListener((args, state) => { - return args.device.miio.goToTarget([args.xcoordinate, args.ycoordinate]); + if (args.device.miio) { + return args.device.miio.goToTarget([args.xcoordinate, args.ycoordinate]); + } else { + return Promise.reject(new Error('Device unreachable, please try again ...')); + } }) new Homey.FlowCardAction('cleanZoneVacuum') .register() .registerRunListener((args, state) => { - const zones = JSON.parse("[" + args.zones + "]"); - return args.device.miio.activateZoneClean(zones); + if (args.device.miio) { + const zones = JSON.parse("[" + args.zones + "]"); + return args.device.miio.activateZoneClean(zones); + } else { + return Promise.reject(new Error('Device unreachable, please try again ...')); + } }) // MI AIR PURIFIER: CONDITION AND ACTION FLOW CARDS @@ -92,31 +108,47 @@ class XiaomiMiioApp extends Homey.App { new Homey.FlowCardAction('modeAirpurifier') .register() .registerRunListener((args, state) => { - return args.device.miio.mode(args.mode).then(result => { - return args.device.setStoreValue('mode', args.mode); - }); + if (args.device.miio) { + return args.device.miio.mode(args.mode).then(result => { + return args.device.setStoreValue('mode', args.mode); + }); + } else { + return Promise.reject(new Error('Device unreachable, please try again ...')); + } }) new Homey.FlowCardAction('airpurifierSetFavorite') .register() .registerRunListener((args, state) => { - return args.device.miio.favoriteLevel(args.favorite); + if (args.device.miio) { + return args.device.miio.favoriteLevel(args.favorite); + } else { + return Promise.reject(new Error('Device unreachable, please try again ...')); + } }) new Homey.FlowCardAction('airpurifierOn') .register() .registerRunListener((args, state) => { - return args.device.miio.setPower(true).then(result => { - return args.device.setCapabilityValue('onoff', true); - }); + if (args.device.miio) { + return args.device.miio.setPower(true).then(result => { + return args.device.setCapabilityValue('onoff', true); + }); + } else { + return Promise.reject(new Error('Device unreachable, please try again ...')); + } }) new Homey.FlowCardAction('airpurifierOff') .register() .registerRunListener((args, state) => { - return args.device.miio.setPower(false).then(result => { - return args.device.setCapabilityValue('onoff', false); - }); + if (args.device.miio) { + return args.device.miio.setPower(false).then(result => { + return args.device.setCapabilityValue('onoff', false); + }); + } else { + return Promise.reject(new Error('Device unreachable, please try again ...')); + } }) // MI HUMDIFIER: CONDITION AND ACTION FLOW CARDS @@ -129,9 +161,13 @@ class XiaomiMiioApp extends Homey.App { new Homey.FlowCardAction('modeHumidifier') .register() .registerRunListener((args, state) => { - return args.device.miio.mode(args.mode).then(result => { - return args.device.setStoreValue('mode', args.mode); - }); + if (args.device.miio) { + return args.device.miio.mode(args.mode).then(result => { + return args.device.setStoreValue('mode', args.mode); + }); + } else { + return Promise.reject(new Error('Device unreachable, please try again ...')); + } }) new Homey.FlowCardAction('humidifierOn') @@ -145,37 +181,53 @@ class XiaomiMiioApp extends Homey.App { new Homey.FlowCardAction('humidifierOff') .register() .registerRunListener((args, state) => { - return args.device.miio.setPower(false).then(result => { - return args.device.setCapabilityValue('onoff', false); - }); + if (args.device.miio) { + return args.device.miio.setPower(false).then(result => { + return args.device.setCapabilityValue('onoff', false); + }); + } else { + return Promise.reject(new Error('Device unreachable, please try again ...')); + } }) // PHILIPS EYECARE LAMP: CONDITION AND ACTION FLOW CARDS new Homey.FlowCardAction('enableEyecare') .register() .registerRunListener((args, state) => { - const eyecare = args.eyecare == 'on' ? true : false; - return args.device.setEyeCare(eyecare).then(result => { - return args.device.setStoreValue('eyecare', eyecare); - }); + if (args.device.miio) { + const eyecare = args.eyecare == 'on' ? true : false; + return args.device.setEyeCare(eyecare).then(result => { + return args.device.setStoreValue('eyecare', eyecare); + }); + } else { + return Promise.reject(new Error('Device unreachable, please try again ...')); + } }) new Homey.FlowCardAction('modeEyecare') .register() .registerRunListener((args, state) => { - return args.device.mode(args.mode).then(result => { - return args.device.setStoreValue('mode', args.mode); - }); + if (args.device.miio) { + return args.device.mode(args.mode).then(result => { + return args.device.setStoreValue('mode', args.mode); + }); + } else { + return Promise.reject(new Error('Device unreachable, please try again ...')); + } }) // GATEWAY: CONDITION AND ACTION FLOW CARDS new Homey.FlowCardAction('armGateway') .register() .registerRunListener((args, state) => { - const alarm = args.alarm == 'armed' ? true : false; - return args.device.miio.setArming(alarm).then(result => { - return args.device.setCapabilityValue('homealarm_state', args.alarm); - }); + if (args.device.miio) { + const alarm = args.alarm == 'armed' ? true : false; + return args.device.miio.setArming(alarm).then(result => { + return args.device.setCapabilityValue('homealarm_state', args.alarm); + }); + } else { + return Promise.reject(new Error('Device unreachable, please try again ...')); + } }) } } diff --git a/app.json b/app.json index 875f579..ad209b5 100644 --- a/app.json +++ b/app.json @@ -10,7 +10,7 @@ "en": [ "Xiaomi", "Mi", "Mi Home", "miio", "vacuumcleaner", "robot", "yeelight", "yeelights", "purifier", "humidifier", "philips", "eyecare", "powerplug", "gateway" ], "nl": [ "Xiaomi", "Mi", "Mi home", "miio", "stofzuiger", "robot", "yeelight", "yeelights", "luchtreiniger", "luchtbevochtiger", "philips", "eyecare", "powerplug", "gateway" ] }, - "version": "2.9.3", + "version": "2.9.4", "compatibility": ">=1.5.12", "author": { "name": "Jelger Haanstra", diff --git a/drivers/air-monitor/device.js b/drivers/air-monitor/device.js index b6a7789..19fe0f0 100644 --- a/drivers/air-monitor/device.js +++ b/drivers/air-monitor/device.js @@ -7,22 +7,29 @@ class MiAirMonitorDevice extends Homey.Device { onInit() { this.createDevice(); + this.setUnavailable(Homey.__('unreachable')); this.registerCapabilityListener('onoff', this.onCapabilityOnoff.bind(this)); } onDeleted() { clearInterval(this.pollingInterval); - if (typeof this.miio !== "undefined") { + if (this.miio) { 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) }); + if (this.miio) { + this.miio.setPower(value) + .then(result => { callback(null, value) }) + .catch(error => { callback(error, false) }); + } else { + this.setUnavailable(Homey.__('unreachable')); + this.createDevice(); + callback('Device unreachable, please try again ...', false) + } } // HELPER FUNCTIONS diff --git a/drivers/gateway/device.js b/drivers/gateway/device.js index c10433a..1e28e47 100644 --- a/drivers/gateway/device.js +++ b/drivers/gateway/device.js @@ -11,6 +11,7 @@ class GatewayDevice extends Homey.Device { this.gatewayLuminanceTrigger = new Homey.FlowCardTriggerDevice('gatewayLuminance').register(); this.createDevice(); + this.setUnavailable(Homey.__('unreachable')); this.registerCapabilityListener('onoff', this.onCapabilityOnoff.bind(this)); this.registerCapabilityListener('dim', this.onCapabilityDim.bind(this)); @@ -20,45 +21,69 @@ class GatewayDevice extends Homey.Device { onDeleted() { clearInterval(this.pollingInterval); - if (typeof this.miio !== "undefined") { + if (this.miio) { this.miio.destroy(); } } // LISTENERS FOR UPDATING CAPABILITIES onCapabilityOnoff(value, opts) { - return this.miio.light.setPower(value) + if (this.miio) { + return this.miio.light.setPower(value) + } else { + this.setUnavailable(Homey.__('unreachable')); + this.createDevice(); + callback('Device unreachable, please try again ...', false) + } } onCapabilityDim(value, opts) { - const brightness = value * 100; - return this.miio.light.setBrightness(brightness) + if (this.miio) { + const brightness = value * 100; + return this.miio.light.setBrightness(brightness); + } else { + this.setUnavailable(Homey.__('unreachable')); + this.createDevice(); + callback('Device unreachable, please try again ...', false) + } } onCapabilityHueSaturation(valueObj, optsObj) { - if (valueObj.hasOwnProperty('light_hue')) { - var hue_value = valueObj.light_hue; - } else { - var hue_value = this.getCapabilityValue('light_hue'); - } + if (this.miio) { + if (valueObj.hasOwnProperty('light_hue')) { + var hue_value = valueObj.light_hue; + } else { + var hue_value = this.getCapabilityValue('light_hue'); + } - if (valueObj.hasOwnProperty('light_saturation')) { - var saturation_value = valueObj.light_saturation; - } else { - var saturation_value = this.getCapabilityValue('light_saturation'); - } + if (valueObj.hasOwnProperty('light_saturation')) { + var saturation_value = valueObj.light_saturation; + } else { + var saturation_value = this.getCapabilityValue('light_saturation'); + } - const hue = hue_value * 359; - const saturation = saturation_value * 100; - const dim = this.getCapabilityValue('dim') * 100 - const colorUpdate = tinycolor({ h: Math.round(hue), s: Math.round(saturation), v: dim }); + const hue = hue_value * 359; + const saturation = saturation_value * 100; + const dim = this.getCapabilityValue('dim') * 100 + const colorUpdate = tinycolor({ h: Math.round(hue), s: Math.round(saturation), v: dim }); - return this.miio.light.color(colorUpdate.toRgbString()); + return this.miio.light.color(colorUpdate.toRgbString()); + } else { + this.setUnavailable(Homey.__('unreachable')); + this.createDevice(); + callback('Device unreachable, please try again ...', false) + } } onCapabilityAlarm(value, opts) { - const state = value == 'armed' ? true : false; - return this.miio.setArming(state) + if (this.miio) { + const state = value == 'armed' ? true : false; + return this.miio.setArming(state); + } else { + this.setUnavailable(Homey.__('unreachable')); + this.createDevice(); + callback('Device unreachable, please try again ...', false) + } } // HELPER FUNCTIONS diff --git a/drivers/mi-airpurifier/device.js b/drivers/mi-airpurifier/device.js index 47b9fc3..04d3909 100644 --- a/drivers/mi-airpurifier/device.js +++ b/drivers/mi-airpurifier/device.js @@ -7,22 +7,29 @@ class MiAirPurifierDevice extends Homey.Device { onInit() { this.createDevice(); + this.setUnavailable(Homey.__('unreachable')); this.registerCapabilityListener('onoff', this.onCapabilityOnoff.bind(this)); } onDeleted() { clearInterval(this.pollingInterval); - if (typeof this.miio !== "undefined") { + if (this.miio) { 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) }); + if (this.miio) { + this.miio.setPower(value) + .then(result => { callback(null, value) }) + .catch(error => { callback(error, false) }); + } else { + this.setUnavailable(Homey.__('unreachable')); + this.createDevice(); + callback('Device unreachable, please try again ...', false) + } } // HELPER FUNCTIONS diff --git a/drivers/mi-humidifier/device.js b/drivers/mi-humidifier/device.js index e1a04cc..e70a41c 100644 --- a/drivers/mi-humidifier/device.js +++ b/drivers/mi-humidifier/device.js @@ -7,22 +7,29 @@ class MiHumidifierDevice extends Homey.Device { onInit() { this.createDevice(); + this.setUnavailable(Homey.__('unreachable')); this.registerCapabilityListener('onoff', this.onCapabilityOnoff.bind(this)); } onDeleted() { clearInterval(this.pollingInterval); - if (typeof this.miio !== "undefined") { + if (this.miio) { 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) }); + if (this.miio) { + this.miio.setPower(value) + .then(result => { callback(null, value) }) + .catch(error => { callback(error, false) }); + } else { + this.setUnavailable(Homey.__('unreachable')); + this.createDevice(); + callback('Device unreachable, please try again ...', false) + } } // HELPER FUNCTIONS diff --git a/drivers/mi-power-plug/device.js b/drivers/mi-power-plug/device.js index 751850e..8f333a9 100644 --- a/drivers/mi-power-plug/device.js +++ b/drivers/mi-power-plug/device.js @@ -7,22 +7,29 @@ class PowerPlugDevice extends Homey.Device { onInit() { this.createDevice(); + this.setUnavailable(Homey.__('unreachable')); this.registerCapabilityListener('onoff', this.onCapabilityOnoff.bind(this)); } onDeleted() { clearInterval(this.pollingInterval); - if (typeof this.miio !== "undefined") { + if (this.miio) { 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) }); + if (this.miio) { + this.miio.setPower(value) + .then(result => { callback(null, value) }) + .catch(error => { callback(error, false) }); + } else { + this.setUnavailable(Homey.__('unreachable')); + this.createDevice(); + callback('Device unreachable, please try again ...', false) + } } // HELPER FUNCTIONS diff --git a/drivers/mi-power-strip/device.js b/drivers/mi-power-strip/device.js index cc119f8..c85d232 100644 --- a/drivers/mi-power-strip/device.js +++ b/drivers/mi-power-strip/device.js @@ -7,22 +7,29 @@ class PowerStripDevice extends Homey.Device { onInit() { this.createDevice(); + this.setUnavailable(Homey.__('unreachable')); this.registerCapabilityListener('onoff', this.onCapabilityOnoff.bind(this)); } onDeleted() { clearInterval(this.pollingInterval); - if (typeof this.miio !== "undefined") { + if (this.miio) { 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) }); + if (this.miio) { + this.miio.setPower(value) + .then(result => { callback(null, value) }) + .catch(error => { callback(error, false) }); + } else { + this.setUnavailable(Homey.__('unreachable')); + this.createDevice(); + callback('Device unreachable, please try again ...', false) + } } // HELPER FUNCTIONS diff --git a/drivers/mi-robot/device.js b/drivers/mi-robot/device.js index f1fa88b..0fe249d 100644 --- a/drivers/mi-robot/device.js +++ b/drivers/mi-robot/device.js @@ -9,6 +9,7 @@ class MiRobotDevice extends Homey.Device { new Homey.FlowCardTriggerDevice('statusVacuum').register(); this.createDevice(); + this.setUnavailable(Homey.__('unreachable')); this.registerCapabilityListener('onoff', this.onCapabilityOnoff.bind(this)); this.registerCapabilityListener('vacuumcleaner_state', this.onCapabilityVacuumcleanerState.bind(this)); @@ -16,71 +17,83 @@ class MiRobotDevice extends Homey.Device { onDeleted() { clearInterval(this.pollingInterval); - if (typeof this.miio !== "undefined") { + if (this.miio) { this.miio.destroy(); } } // LISTENERS FOR UPDATING CAPABILITIES onCapabilityOnoff(value, opts, callback) { - if (value) { - this.miio.clean() - .then(result => { - this.setCapabilityValue('vacuumcleaner_state', 'cleaning'); - callback(null, value) - }) - .catch(error => { callback(error, false) }); - } else { - this.miio.stop() - .then(result => { - this.setCapabilityValue('vacuumcleaner_state', 'stopped'); - callback(null, value) - }) - .catch(error => { callback(error, false) }); - } - } - - onCapabilityVacuumcleanerState(value, opts, callback) { - switch (value) { - case "cleaning": - this.miio.activateCleaning() - .then(result => { - this.setCapabilityValue('onoff', true); - callback(null, value); - }) - .catch(error => { callback(error, false) }); - break; - case "spot_cleaning": - this.miio.activateSpotClean() + if (this.miio) { + if (value) { + this.miio.clean() .then(result => { - this.setCapabilityValue('onoff', true); - callback(null, value); + this.setCapabilityValue('vacuumcleaner_state', 'cleaning'); + callback(null, value) }) .catch(error => { callback(error, false) }); - break; - case "stopped": - this.miio.pause() + } else { + this.miio.stop() .then(result => { - this.setCapabilityValue('onoff', false); - callback(null, value); + this.setCapabilityValue('vacuumcleaner_state', 'stopped'); + callback(null, value) }) .catch(error => { callback(error, false) }); - break; - case "docked": - case "charging": - this.miio.pause() - .catch(error => { callback(error, false) }); - setTimeout(() => { - this.miio.activateCharging() + } + } else { + this.setUnavailable(Homey.__('unreachable')); + this.createDevice(); + callback('Device unreachable, please try again ...', false) + } + } + + onCapabilityVacuumcleanerState(value, opts, callback) { + if (this.miio) { + switch (value) { + case "cleaning": + this.miio.activateCleaning() + .then(result => { + this.setCapabilityValue('onoff', true); + callback(null, value); + }) + .catch(error => { callback(error, false) }); + break; + case "spot_cleaning": + this.miio.activateSpotClean() + .then(result => { + this.setCapabilityValue('onoff', true); + callback(null, value); + }) + .catch(error => { callback(error, false) }); + break; + case "stopped": + this.miio.pause() .then(result => { this.setCapabilityValue('onoff', false); callback(null, value); }) .catch(error => { callback(error, false) }); - }, 4000) - break; - default: - this.log("Not a valid vacuumcleaner_state"); + break; + case "docked": + case "charging": + this.miio.pause() + .catch(error => { callback(error, false) }); + setTimeout(() => { + this.miio.activateCharging() + .then(result => { + this.setCapabilityValue('onoff', false); + callback(null, value); + }) + .catch(error => { callback(error, false) }); + }, 4000) + break; + default: + this.log("Not a valid vacuumcleaner_state"); + } + } else { + this.setUnavailable(Homey.__('unreachable')); + this.createDevice(); + callback('Device unreachable, please try again ...', false) } } diff --git a/drivers/philips-bulb/device.js b/drivers/philips-bulb/device.js index 616c22f..b74ce72 100644 --- a/drivers/philips-bulb/device.js +++ b/drivers/philips-bulb/device.js @@ -8,6 +8,7 @@ class PhilipsBulbDevice extends Homey.Device { onInit() { this.createDevice(); + this.setUnavailable(Homey.__('unreachable')); this.registerCapabilityListener('onoff', this.onCapabilityOnoff.bind(this)); this.registerCapabilityListener('dim', this.onCapabilityDim.bind(this)); @@ -16,31 +17,49 @@ class PhilipsBulbDevice extends Homey.Device { onDeleted() { clearInterval(this.pollingInterval); - if (typeof this.miio !== "undefined") { + if (this.miio ) { 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) }); + if (this.miio) { + this.miio.setPower(value) + .then(result => { callback(null, value) }) + .catch(error => { callback(error, false) }); + } else { + this.setUnavailable(Homey.__('unreachable')); + this.createDevice(); + callback('Device unreachable, please try again ...', false) + } } onCapabilityDim(value, opts, callback) { - var brightness = value * 100; - this.miio.setBrightness(brightness) - .then(result => { callback(null, value) }) - .catch(error => { callback(error, false) }); + if (this.miio) { + var brightness = value * 100; + this.miio.setBrightness(brightness) + .then(result => { callback(null, value) }) + .catch(error => { callback(error, false) }); + } else { + this.setUnavailable(Homey.__('unreachable')); + this.createDevice(); + callback('Device unreachable, please try again ...', false) + } } onCapabilityLightTemperature(value, opts, callback) { - var colorvalue = util.denormalize(value, 3000, 5700); - var colortemp = ''+ colorvalue +'K'; - this.miio.color(colortemp) - .then(result => { callback(null, value) }) - .catch(error => { callback(error, false) }); + if (this.miio) { + var colorvalue = util.denormalize(value, 3000, 5700); + var colortemp = ''+ colorvalue +'K'; + this.miio.color(colortemp) + .then(result => { callback(null, value) }) + .catch(error => { callback(error, false) }); + } else { + this.setUnavailable(Homey.__('unreachable')); + this.createDevice(); + callback('Device unreachable, please try again ...', false) + } } // HELPER FUNCTIONS diff --git a/drivers/yeelights/device.js b/drivers/yeelights/device.js index e4b71f5..8fe26c1 100644 --- a/drivers/yeelights/device.js +++ b/drivers/yeelights/device.js @@ -181,7 +181,9 @@ class YeelightDevice extends Homey.Device { yeelights[id].socket.on('error', (error) => { this.log("Yeelight - error on socket: "+ error); - yeelights[id].socket.destroy(); + if (yeelights[id].socket) { + yeelights[id].socket.destroy(); + } if(error.code === 'ETIMEDOUT' || error.code === 'ECONNRESET' || error == 'Error: Error sending command') { this.log('Yeelight - trying to reconnect in 6 seconds.'); diff --git a/node_modules/miio/lib/models.js b/node_modules/miio/lib/models.js index cdb3b01..9b1f431 100644 --- a/node_modules/miio/lib/models.js +++ b/node_modules/miio/lib/models.js @@ -23,10 +23,13 @@ module.exports = { 'zhimi.airmonitor.v1': AirMonitor, // Air Purifier 1 (and Pro?) - 'zhimi.airpurifier.v1': AirPurifier, + 'zhimi.airpurifier.v1': AirPurifier, 'zhimi.airpurifier.v2': AirPurifier, 'zhimi.airpurifier.v3': AirPurifier, + 'zhimi.airpurifier.v4': AirPurifier, + 'zhimi.airpurifier.v5': AirPurifier, 'zhimi.airpurifier.v6': AirPurifier, + 'zhimi.airpurifier.v7': AirPurifier, // Air Purifier 2 'zhimi.airpurifier.m1': AirPurifier, diff --git a/node_modules/miio/lib/network.js b/node_modules/miio/lib/network.js index 982b81d..f4754ca 100644 --- a/node_modules/miio/lib/network.js +++ b/node_modules/miio/lib/network.js @@ -135,10 +135,14 @@ class Network extends EventEmitter { // Bind the socket and when it is ready mark it for broadcasting this._socket.bind(); this._socket.on('listening', () => { - this._socket.setBroadcast(true); - - const address = this._socket.address(); - this.debug('Network bound to port', address.port); + if (this._socket) { + this._socket.setBroadcast(true); + + const address = this._socket.address(); + this.debug('Network bound to port', address.port); + } else { + this.createSocket(); + } }); // On any incoming message, parse it, update the discovery @@ -290,7 +294,11 @@ class DeviceInfo { this.debug('Loading token from storage, device hides token and no token set via options'); this.autoToken = false; promise = tokens.get(this.id) - .then(token => this.token = Buffer.from(token, 'hex')); + .then(token => { + this.debug('Using stored token:', token); + this.packet.token = Buffer.from(token, 'hex'); + this.tokenChanged = true; + }); } else { if(this.tokenChanged) { this.autoToken = false; @@ -316,6 +324,7 @@ class DeviceInfo { if(err.code === 'missing-token') { // Rethrow some errors + err.device = this; throw err; } @@ -484,6 +493,7 @@ class DeviceInfo { if(retriesLeft-- > 0) { send(); } else { + this.debug('Reached maximum number of retries, giving up'); const err = new Error('Call to device timed out'); err.code = 'timeout'; promise.reject(err); diff --git a/package.json b/package.json index 4f63e7a..6cc0631 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "com.xiaomi-miio", - "version": "2.9.3", + "version": "2.9.4", "description": "Xiaomi Mi Home", "main": "app.js", "dependencies": {