Fixed launch error with multiple robots
This commit is contained in:
		| @@ -17,6 +17,9 @@ module.exports = function (_Service, _Characteristic) | |||||||
| { | { | ||||||
| 	Service = _Service; | 	Service = _Service; | ||||||
| 	Characteristic = _Characteristic; | 	Characteristic = _Characteristic; | ||||||
|  | 	SpotWidthCharacteristic = require('../characteristics/spotWidth')(Characteristic, CustomUUID); | ||||||
|  | 	SpotHeightCharacteristic = require('../characteristics/spotHeight')(Characteristic, CustomUUID); | ||||||
|  | 	SpotRepeatCharacteristic = require('../characteristics/spotRepeat')(Characteristic, CustomUUID); | ||||||
|  |  | ||||||
| 	return NeatoVacuumRobotAccessory; | 	return NeatoVacuumRobotAccessory; | ||||||
| }; | }; | ||||||
| @@ -32,7 +35,7 @@ function NeatoVacuumRobotAccessory(platform, robotObject) | |||||||
| 	this.robotObject = robotObject; | 	this.robotObject = robotObject; | ||||||
| 	this.robot = robotObject.device; | 	this.robot = robotObject.device; | ||||||
| 	this.meta = robotObject.meta; | 	this.meta = robotObject.meta; | ||||||
| 	this.availableServices = robotObject.availableServices; | 	this.spotPlusFeatures = ((typeof robotObject.availableServices.spotCleaning !== 'undefined') && robotObject.availableServices.spotCleaning.includes("basic")); | ||||||
| 	this.boundary = (typeof robotObject.boundary === 'undefined') ? null : robotObject.boundary; | 	this.boundary = (typeof robotObject.boundary === 'undefined') ? null : robotObject.boundary; | ||||||
|  |  | ||||||
| 	if (this.boundary == null) | 	if (this.boundary == null) | ||||||
| @@ -74,23 +77,12 @@ function NeatoVacuumRobotAccessory(platform, robotObject) | |||||||
| 		this.scheduleService = new Service.Switch(this.name + " Schedule", "schedule"); | 		this.scheduleService = new Service.Switch(this.name + " Schedule", "schedule"); | ||||||
| 		this.findMeService = new Service.Switch(this.name + " Find Me", "findMe"); | 		this.findMeService = new Service.Switch(this.name + " Find Me", "findMe"); | ||||||
|  |  | ||||||
| 		SpotWidthCharacteristic = require('../characteristics/spotWidth')(Characteristic, CustomUUID); | 		this.spotCleanService = new Service.Switch(this.name + " Clean Spot", "cleanSpot"); | ||||||
| 		SpotHeightCharacteristic = require('../characteristics/spotHeight')(Characteristic, CustomUUID); | 		this.spotCleanService.addCharacteristic(SpotRepeatCharacteristic); | ||||||
| 		SpotRepeatCharacteristic = require('../characteristics/spotRepeat')(Characteristic, CustomUUID); | 		if (this.spotPlusFeatures) | ||||||
|  |  | ||||||
| 		// Spot cleaning with advanced options |  | ||||||
| 		if ((typeof this.availableServices.spotCleaning !== 'undefined') && this.availableServices.spotCleaning.includes("basic")) |  | ||||||
| 		{ | 		{ | ||||||
| 			this.spotCleanAdvancedService = new Service.Switch(this.name + " Clean Spot", "cleanSpot"); | 			this.spotCleanService.addCharacteristic(SpotWidthCharacteristic); | ||||||
| 			this.spotCleanAdvancedService.addCharacteristic(SpotRepeatCharacteristic); | 			this.spotCleanService.addCharacteristic(SpotHeightCharacteristic); | ||||||
| 			this.spotCleanAdvancedService.addCharacteristic(SpotWidthCharacteristic); |  | ||||||
| 			this.spotCleanAdvancedService.addCharacteristic(SpotHeightCharacteristic); |  | ||||||
| 		} |  | ||||||
| 		// Spot cleaning without advanced options |  | ||||||
| 		else |  | ||||||
| 		{ |  | ||||||
| 			this.spotCleanSimpleService = new Service.Switch(this.name + " Clean Spot", "cleanSpot"); |  | ||||||
| 			this.spotCleanSimpleService.addCharacteristic(SpotRepeatCharacteristic); |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| @@ -166,29 +158,22 @@ NeatoVacuumRobotAccessory.prototype = { | |||||||
| 			this.findMeService.getCharacteristic(Characteristic.On).on('set', this.setFindMe.bind(this)); | 			this.findMeService.getCharacteristic(Characteristic.On).on('set', this.setFindMe.bind(this)); | ||||||
| 			this.findMeService.getCharacteristic(Characteristic.On).on('get', this.getFindMe.bind(this)); | 			this.findMeService.getCharacteristic(Characteristic.On).on('get', this.getFindMe.bind(this)); | ||||||
|  |  | ||||||
| 			if (typeof this.spotCleanAdvancedService !== 'undefined') | 			this.spotCleanService.getCharacteristic(Characteristic.On).on('set', this.setSpotClean.bind(this)); | ||||||
| 			{ | 			this.spotCleanService.getCharacteristic(Characteristic.On).on('get', this.getSpotClean.bind(this)); | ||||||
| 				this.spotCleanAdvancedService.getCharacteristic(Characteristic.On).on('set', this.setSpotClean.bind(this)); | 			this.spotCleanService.getCharacteristic(SpotRepeatCharacteristic).on('set', this.setSpotRepeat.bind(this)); | ||||||
| 				this.spotCleanAdvancedService.getCharacteristic(Characteristic.On).on('get', this.getSpotClean.bind(this)); | 			this.spotCleanService.getCharacteristic(SpotRepeatCharacteristic).on('get', this.getSpotRepeat.bind(this)); | ||||||
| 				this.spotCleanAdvancedService.getCharacteristic(SpotRepeatCharacteristic).on('set', this.setSpotRepeat.bind(this)); |  | ||||||
| 				this.spotCleanAdvancedService.getCharacteristic(SpotRepeatCharacteristic).on('get', this.getSpotRepeat.bind(this)); |  | ||||||
| 				this.spotCleanAdvancedService.getCharacteristic(SpotWidthCharacteristic).on('set', this.setSpotWidth.bind(this)); |  | ||||||
| 				this.spotCleanAdvancedService.getCharacteristic(SpotWidthCharacteristic).on('get', this.getSpotWidth.bind(this)); |  | ||||||
| 				this.spotCleanAdvancedService.getCharacteristic(SpotHeightCharacteristic).on('set', this.setSpotHeight.bind(this)); |  | ||||||
| 				this.spotCleanAdvancedService.getCharacteristic(SpotHeightCharacteristic).on('get', this.getSpotHeight.bind(this)); |  | ||||||
|  |  | ||||||
| 				if (this.hiddenServices.indexOf('spot') === -1) | 			if (this.spotPlusFeatures) | ||||||
| 					this.services.push(this.spotCleanAdvancedService); | 			{ | ||||||
|  | 				this.spotCleanService.getCharacteristic(SpotWidthCharacteristic).on('set', this.setSpotWidth.bind(this)); | ||||||
|  | 				this.spotCleanService.getCharacteristic(SpotWidthCharacteristic).on('get', this.getSpotWidth.bind(this)); | ||||||
|  | 				this.spotCleanService.getCharacteristic(SpotHeightCharacteristic).on('set', this.setSpotHeight.bind(this)); | ||||||
|  | 				this.spotCleanService.getCharacteristic(SpotHeightCharacteristic).on('get', this.getSpotHeight.bind(this)); | ||||||
| 			} | 			} | ||||||
| 			else |  | ||||||
| 			{ |  | ||||||
| 				this.spotCleanSimpleService.getCharacteristic(Characteristic.On).on('set', this.setSpotClean.bind(this)); |  | ||||||
| 				this.spotCleanSimpleService.getCharacteristic(Characteristic.On).on('get', this.getSpotClean.bind(this)); |  | ||||||
| 				this.spotCleanSimpleService.getCharacteristic(SpotRepeatCharacteristic).on('set', this.setSpotRepeat.bind(this)); |  | ||||||
| 				this.spotCleanSimpleService.getCharacteristic(SpotRepeatCharacteristic).on('get', this.getSpotRepeat.bind(this)); |  | ||||||
|  |  | ||||||
| 			if (this.hiddenServices.indexOf('spot') === -1) | 			if (this.hiddenServices.indexOf('spot') === -1) | ||||||
| 					this.services.push(this.spotCleanSimpleService); | 			{ | ||||||
|  | 				this.services.push(this.spotCleanService); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			// Add optional services | 			// Add optional services | ||||||
| @@ -507,12 +492,10 @@ NeatoVacuumRobotAccessory.prototype = { | |||||||
|  |  | ||||||
| 	setSpotClean: function (on, callback) | 	setSpotClean: function (on, callback) | ||||||
| 	{ | 	{ | ||||||
| 		let spotCleanService = (typeof this.spotCleanAdvancedService !== 'undefined') ? this.spotCleanAdvancedService : this.spotCleanSimpleService; |  | ||||||
|  |  | ||||||
| 		let spot = { | 		let spot = { | ||||||
| 			width:  spotCleanService.getCharacteristic(SpotWidthCharacteristic).value, | 			width: this.spotPlusFeatures ? this.spotCleanService.getCharacteristic(SpotWidthCharacteristic).value : null, | ||||||
| 			height: spotCleanService.getCharacteristic(SpotHeightCharacteristic).value, | 			height: this.spotPlusFeatures ? this.spotCleanService.getCharacteristic(SpotHeightCharacteristic).value : null, | ||||||
| 			repeat: spotCleanService.getCharacteristic(SpotRepeatCharacteristic).value | 			repeat: this.spotCleanService.getCharacteristic(SpotRepeatCharacteristic).value | ||||||
| 		}; | 		}; | ||||||
|  |  | ||||||
| 		this.platform.updateRobot(this.robot._serial, (error, result) => | 		this.platform.updateRobot(this.robot._serial, (error, result) => | ||||||
| @@ -658,15 +641,12 @@ NeatoVacuumRobotAccessory.prototype = { | |||||||
| 			this.noGoLinesService.setCharacteristic(Characteristic.On, this.robot.noGoLines); | 			this.noGoLinesService.setCharacteristic(Characteristic.On, this.robot.noGoLines); | ||||||
| 			this.extraCareService.setCharacteristic(Characteristic.On, this.robot.navigationMode == 2 ? true : false); | 			this.extraCareService.setCharacteristic(Characteristic.On, this.robot.navigationMode == 2 ? true : false); | ||||||
|  |  | ||||||
| 			if (typeof this.spotCleanAdvancedService !== 'undefined') | 			this.spotCleanService.setCharacteristic(SpotRepeatCharacteristic, this.robot.spotRepeat); | ||||||
|  |  | ||||||
|  | 			if (this.spotPlusFeatures) | ||||||
| 			{ | 			{ | ||||||
| 				this.spotCleanAdvancedService.setCharacteristic(SpotWidthCharacteristic, this.robot.spotWidth); | 					this.spotCleanService.setCharacteristic(SpotWidthCharacteristic, this.robot.spotWidth); | ||||||
| 				this.spotCleanAdvancedService.setCharacteristic(SpotHeightCharacteristic, this.robot.spotHeight); | 					this.spotCleanService.setCharacteristic(SpotHeightCharacteristic, this.robot.spotHeight); | ||||||
| 				this.spotCleanAdvancedService.setCharacteristic(SpotRepeatCharacteristic, this.robot.spotRepeat); |  | ||||||
| 			} |  | ||||||
| 			else |  | ||||||
| 			{ |  | ||||||
| 				this.spotCleanSimpleService.setCharacteristic(SpotRepeatCharacteristic, this.robot.spotRepeat); |  | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										97
									
								
								index.js
									
									
									
									
									
								
							
							
						
						
									
										97
									
								
								index.js
									
									
									
									
									
								
							| @@ -4,12 +4,14 @@ let inherits = require('util').inherits, | |||||||
| 	botvac = require('node-botvac'), | 	botvac = require('node-botvac'), | ||||||
|  |  | ||||||
| 	Service, | 	Service, | ||||||
| 	Characteristic; | 	Characteristic, | ||||||
|  | 	NeatoVacuumRobotAccessory; | ||||||
|  |  | ||||||
| module.exports = function (homebridge) | module.exports = function (homebridge) | ||||||
| { | { | ||||||
| 	Service = homebridge.hap.Service; | 	Service = homebridge.hap.Service; | ||||||
| 	Characteristic = homebridge.hap.Characteristic; | 	Characteristic = homebridge.hap.Characteristic; | ||||||
|  | 	NeatoVacuumRobotAccessory = require('./accessories/neatoVacuumRobot')(Service, Characteristic); | ||||||
| 	homebridge.registerPlatform("homebridge-neato", "NeatoVacuumRobot", NeatoVacuumRobotPlatform); | 	homebridge.registerPlatform("homebridge-neato", "NeatoVacuumRobot", NeatoVacuumRobotPlatform); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @@ -54,27 +56,41 @@ NeatoVacuumRobotPlatform.prototype = { | |||||||
| 		debug("Get robots"); | 		debug("Get robots"); | ||||||
| 		let accessories = []; | 		let accessories = []; | ||||||
| 		this.boundaryNames = []; | 		this.boundaryNames = []; | ||||||
|  |  | ||||||
| 		this.getRobots(() => | 		this.getRobots(() => | ||||||
| 		{ | 		{ | ||||||
|  | 			// // MOCK MULTIPLE ROBOTS START | ||||||
|  | 			// let client = new botvac.Client(); | ||||||
|  | 			// client.authorize(this.email, this.password, false, (error) => | ||||||
|  | 			// { | ||||||
|  | 			// 	client.getRobots((error, robs) => | ||||||
|  | 			// 	{ | ||||||
|  | 			// 		let testRobot = robs[0]; | ||||||
|  | 			// 		testRobot.getState((error, result) => | ||||||
|  | 			// 		{ | ||||||
|  | 			// 			testRobot.name = "Testrobot"; | ||||||
|  | 			// 			this.robots.push({device: testRobot, meta: result.meta, availableServices: result.availableServices}); | ||||||
|  | 			// 			// MOCK MULTIPLE ROBOTS END | ||||||
|  |  | ||||||
| 						this.robots.forEach((robot, i) => | 						this.robots.forEach((robot, i) => | ||||||
| 						{ | 						{ | ||||||
| 				this.log("Found robot #" + (i + 1) + " named \"" + robot.device.name + "\" with serial \"" + robot.device._serial.substring(0,9) + "XXXXXXXXXXXX\""); | 							this.log("Found robot #" + (i + 1) + " named \"" + robot.device.name + "\" with serial \"" + robot.device._serial.substring(0, 9) + "XXXXXXXXXXXX\""); | ||||||
|  |  | ||||||
| 				// Start Update Intervall |  | ||||||
| 				this.updateRobotTimer(robot.device._serial); |  | ||||||
|  |  | ||||||
| 				let NeatoVacuumRobotAccessory = require('./accessories/neatoVacuumRobot')(Service, Characteristic); |  | ||||||
| 							let mainAccessory = new NeatoVacuumRobotAccessory(this, robot); | 							let mainAccessory = new NeatoVacuumRobotAccessory(this, robot); | ||||||
| 							accessories.push(mainAccessory); | 							accessories.push(mainAccessory); | ||||||
|  |  | ||||||
| 							robot.mainAccessory = mainAccessory; | 							robot.mainAccessory = mainAccessory; | ||||||
| 							robot.roomAccessories = []; | 							robot.roomAccessories = []; | ||||||
|  |  | ||||||
| 				// For testing purposes only | 							// Start Update Intervall | ||||||
|  | 							this.updateRobotTimer(robot.device._serial); | ||||||
|  |  | ||||||
|  | 							// // MOCK ZONE CLEANING START | ||||||
| 							// robot.boundary = {name: "Testroom", id: "1"}; | 							// robot.boundary = {name: "Testroom", id: "1"}; | ||||||
| 							// let roomAccessory = new NeatoVacuumRobotAccessory(this, robot); | 							// let roomAccessory = new NeatoVacuumRobotAccessory(this, robot); | ||||||
| 							// accessories.push(roomAccessory); | 							// accessories.push(roomAccessory); | ||||||
| 							// robot.roomAccessories.push(roomAccessory); | 							// robot.roomAccessories.push(roomAccessory); | ||||||
|  | 							// // MOCK ZONE CLEANING END | ||||||
|  |  | ||||||
| 							if (robot.device.maps) | 							if (robot.device.maps) | ||||||
| 							{ | 							{ | ||||||
| @@ -98,6 +114,12 @@ NeatoVacuumRobotPlatform.prototype = { | |||||||
| 							} | 							} | ||||||
| 						}); | 						}); | ||||||
| 						callback(accessories); | 						callback(accessories); | ||||||
|  |  | ||||||
|  | 			// 			// MOCK MULTIPLE ROBOTS START | ||||||
|  | 			// 		}); | ||||||
|  | 			// 	}); | ||||||
|  | 			// }); | ||||||
|  | 			// // MOCK MULTIPLE ROBOTS END | ||||||
| 		}); | 		}); | ||||||
| 	}, | 	}, | ||||||
|  |  | ||||||
| @@ -137,24 +159,39 @@ NeatoVacuumRobotPlatform.prototype = { | |||||||
|  |  | ||||||
| 						robots.forEach((robot) => | 						robots.forEach((robot) => | ||||||
| 						{ | 						{ | ||||||
| 							// Get all maps for each robot | 							// Get additional information for the robot | ||||||
| 							robot.getPersistentMaps((error, result) => | 							robot.getState((error, state) => | ||||||
| 							{ | 							{ | ||||||
| 								if (error) | 								if (error) | ||||||
| 								{ | 								{ | ||||||
| 									this.log.error("Error updating persistent maps: " + error + ": " + result); | 									this.log.error("Error getting robot meta information: " + error + ": " + state); | ||||||
|  | 									callback(); | ||||||
|  | 								} | ||||||
|  | 								else | ||||||
|  | 								{ | ||||||
|  | 									// Get all maps for each robot | ||||||
|  | 									robot.getPersistentMaps((error, maps) => | ||||||
|  | 									{ | ||||||
|  | 										if (error) | ||||||
|  | 										{ | ||||||
|  | 											this.log.error("Error updating persistent maps: " + error + ": " + maps); | ||||||
| 											callback(); | 											callback(); | ||||||
| 										} | 										} | ||||||
| 										// Robot has no maps | 										// Robot has no maps | ||||||
| 								else if (result.length === 0) | 										else if (maps.length === 0) | ||||||
| 										{ | 										{ | ||||||
| 											robot.maps = []; | 											robot.maps = []; | ||||||
| 									this.saveRobot(robot, loadedRobots, robots.length, callback); | 											this.robots.push({device: robot, meta: state.meta, availableServices: state.availableServices}); | ||||||
|  | 											loadedRobots++; | ||||||
|  | 											if (loadedRobots === robots.length) | ||||||
|  | 											{ | ||||||
|  | 												callback(); | ||||||
|  | 											} | ||||||
| 										} | 										} | ||||||
| 										// Robot has maps | 										// Robot has maps | ||||||
| 										else | 										else | ||||||
| 										{ | 										{ | ||||||
| 									robot.maps = result; | 											robot.maps = maps; | ||||||
| 											let loadedMaps = 0; | 											let loadedMaps = 0; | ||||||
| 											robot.maps.forEach((map) => | 											robot.maps.forEach((map) => | ||||||
| 											{ | 											{ | ||||||
| @@ -174,12 +211,19 @@ NeatoVacuumRobotPlatform.prototype = { | |||||||
| 													// Robot is completely requested if zones for all maps are loaded | 													// Robot is completely requested if zones for all maps are loaded | ||||||
| 													if (loadedMaps === robot.maps.length) | 													if (loadedMaps === robot.maps.length) | ||||||
| 													{ | 													{ | ||||||
| 												this.saveRobot(robot, loadedRobots, robots.length, callback); | 														this.robots.push({device: robot, meta: state.meta, availableServices: state.availableServices}); | ||||||
|  | 														loadedRobots++; | ||||||
|  | 														if (loadedRobots === robots.length) | ||||||
|  | 														{ | ||||||
|  | 															callback(); | ||||||
|  | 														} | ||||||
| 													} | 													} | ||||||
| 												}) | 												}) | ||||||
| 											}); | 											}); | ||||||
| 										} | 										} | ||||||
| 									}); | 									}); | ||||||
|  | 								} | ||||||
|  | 							}); | ||||||
| 						}); | 						}); | ||||||
| 					} | 					} | ||||||
| 				}); | 				}); | ||||||
| @@ -187,31 +231,6 @@ NeatoVacuumRobotPlatform.prototype = { | |||||||
| 		}); | 		}); | ||||||
| 	}, | 	}, | ||||||
|  |  | ||||||
| 	saveRobot: function (robot, loadedRobots, size, callback) |  | ||||||
| 	{ |  | ||||||
| 		// Get additional information for the robot |  | ||||||
| 		robot.getState((error, result) => |  | ||||||
| 		{ |  | ||||||
| 			if (error) |  | ||||||
| 			{ |  | ||||||
| 				this.log.error("Error getting robot meta information: " + error + ": " + result); |  | ||||||
| 				callback(); |  | ||||||
| 			} |  | ||||||
| 			else |  | ||||||
| 			{ |  | ||||||
| 				// Store the robot with his information, maps and zones |  | ||||||
| 				this.robots.push({device: robot, meta: result.meta, availableServices: result.availableServices}); |  | ||||||
| 				loadedRobots++; |  | ||||||
|  |  | ||||||
| 				// Initial request is complete if all robots are loaded. |  | ||||||
| 				if (loadedRobots === size) |  | ||||||
| 				{ |  | ||||||
| 					callback(); |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 		}); |  | ||||||
| 	}, |  | ||||||
|  |  | ||||||
| 	updateRobot: function (serial, callback) | 	updateRobot: function (serial, callback) | ||||||
| 	{ | 	{ | ||||||
| 		let robot = this.getRobot(serial); | 		let robot = this.getRobot(serial); | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| { | { | ||||||
|   "name": "homebridge-neato", |   "name": "homebridge-neato", | ||||||
|   "version": "0.7.1", |   "version": "0.7.2-beta.1", | ||||||
|   "description": "A Neato vacuum robot plugin for homebridge.", |   "description": "A Neato vacuum robot plugin for homebridge.", | ||||||
|   "license": "MIT", |   "license": "MIT", | ||||||
|   "keywords": [ |   "keywords": [ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user