From 7b70d8f0768b1b3c47d1ff14d41ad48743d10004 Mon Sep 17 00:00:00 2001 From: Nico Hartung Date: Thu, 3 Jan 2019 23:23:14 +0100 Subject: [PATCH 1/2] Added support for spot cleaning, added repeat and 4x4 mode for spot cleaning Repeat and 4x4 mode are not persistent - node-botvac api not supported. After a reboot of homebridge set it to off/false - use it for spot cleaning in compination with homekit scenes or automations. --- index.js | 127 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 126 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 5ea07a4..ff8d24d 100644 --- a/index.js +++ b/index.js @@ -93,6 +93,9 @@ function NeatoVacuumRobotAccessory(robot, platform) { this.name = robot.name; this.lastUpdate = null; + this.tempSpot4x4 = false; + this.tempSpotRepeat = false; + this.vacuumRobotCleanService = new Service.Switch(this.name + " Clean", "clean"); this.vacuumRobotGoToDockService = new Service.Switch(this.name + " Go to Dock", "goToDock"); this.vacuumRobotDockStateService = new Service.OccupancySensor(this.name + " Dock", "dockState"); @@ -102,6 +105,10 @@ function NeatoVacuumRobotAccessory(robot, platform) { this.vacuumRobotScheduleService = new Service.Switch(this.name + " Schedule", "schedule"); this.vacuumRobotBatteryService = new Service.BatteryService("Battery", "battery"); + this.vacuumRobotSpotCleanService = new Service.Switch(this.name + " Spot Clean", "spotClean"); + this.vacuumRobotSpotRepeatService = new Service.Switch(this.name + " Spot Repeat", "spotRepeat"); + this.vacuumRobotSpot4x4Service = new Service.Switch(this.name + " Spot Clean 4x4", "spotClean4x4"); + this.updateRobotTimer(); } @@ -153,6 +160,18 @@ NeatoVacuumRobotAccessory.prototype = { this.vacuumRobotBatteryService.getCharacteristic(Characteristic.BatteryLevel).on('get', this.getBatteryLevel.bind(this)); this.vacuumRobotBatteryService.getCharacteristic(Characteristic.ChargingState).on('get', this.getBatteryChargingState.bind(this)); + this.vacuumRobotSpotCleanService.getCharacteristic(Characteristic.On).on('set', this.setSpotClean.bind(this)); + this.vacuumRobotSpotCleanService.getCharacteristic(Characteristic.On).on('get', this.getSpotClean.bind(this)); + + this.vacuumRobotSpotCleanService.getCharacteristic(Characteristic.On).on('set', this.setSpotClean.bind(this)); + this.vacuumRobotSpotCleanService.getCharacteristic(Characteristic.On).on('get', this.getSpotClean.bind(this)); + + this.vacuumRobotSpot4x4Service.getCharacteristic(Characteristic.On).on('set', this.setSpot4x4.bind(this)); + this.vacuumRobotSpot4x4Service.getCharacteristic(Characteristic.On).on('get', this.getSpot4x4.bind(this)); + + this.vacuumRobotSpotRepeatService.getCharacteristic(Characteristic.On).on('set', this.setSpotRepeat.bind(this)); + this.vacuumRobotSpotRepeatService.getCharacteristic(Characteristic.On).on('get', this.getSpotRepeat.bind(this)); + this.services = [this.informationService, this.vacuumRobotCleanService, this.vacuumRobotBatteryService]; if (this.hiddenServices.indexOf('dock') === -1) this.services.push(this.vacuumRobotGoToDockService); @@ -166,6 +185,11 @@ NeatoVacuumRobotAccessory.prototype = { this.services.push(this.vacuumRobotExtraCareService); if (this.hiddenServices.indexOf('schedule') === -1) this.services.push(this.vacuumRobotScheduleService); + if (this.hiddenServices.indexOf('spot') === -1) { + this.services.push(this.vacuumRobotSpotCleanService); + this.services.push(this.vacuumRobotSpot4x4Service); + this.services.push(this.vacuumRobotSpotRepeatService); + }; return this.services; }, @@ -226,6 +250,71 @@ NeatoVacuumRobotAccessory.prototype = { }); }, + setSpotClean: function (on, callback) { + let that = this; + this.updateRobot(function (error, result) { + if (on) { + if (that.robot.canResume || that.robot.canStart) { + + // start extra update robot timer if refresh is set to "auto" + if (that.refresh === 'auto') { + setTimeout(function () { + clearTimeout(that.timer); + that.updateRobotTimer(); + }, 60 * 1000); + } + + if (that.robot.canResume) { + debug(that.name + ": Resume spot cleaning"); + that.robot.resumeCleaning(callback); + } + else { + let eco = that.vacuumRobotEcoService.getCharacteristic(Characteristic.On).value; + if (!that.vacuumRobotSpot4x4Service.getCharacteristic(Characteristic.On).value) { + var width = 200; + var height = 200; + } else { + var width = 400; + var height = 400; + } + let repeat = that.vacuumRobotSpotRepeatService.getCharacteristic(Characteristic.On).value; + let extraCare = false; + debug(that.name + ": Start spot cleaning (eco: " + eco + ", width: " + width + ", height: " + height + ", repeat: " + repeat + ")"); + that.robot.startSpotCleaning( + eco, + width, + height, + repeat ? 2 : 1, + extraCare ? 2 : 1, + function (error, result) { + if (error) { + that.log.error(error + ": " + result); + callback(true); + } + else { + callback(); + } + }); + } + } + else { + debug(that.name + ": Cant start, maybe already cleaning"); + callback(); + } + } + else { + if (that.robot.canPause) { + debug(that.name + ": Pause spot cleaning"); + that.robot.pauseCleaning(callback); + } + else { + debug(that.name + ": Already stopped"); + callback(); + } + } + }); + }, + setGoToDock: function (on, callback) { let that = this; this.updateRobot(function (error, result) { @@ -285,6 +374,28 @@ NeatoVacuumRobotAccessory.prototype = { }); }, + setSpotRepeat: function (on, callback) { + debug(this.name + ": " + (on ? "Enable spot cleaning repeat mode (2x)" : "Disable spot cleaning repeat mode (2x)")); + if (on) { + this.tempSpotRepeat = true; + } + else { + this.tempSpotRepeat = false; + } + callback(); + }, + + setSpot4x4: function (on, callback) { + debug(this.name + ": " + (on ? "Enable spot cleaning 4x4 mode" : "Disable spot cleaning 4x4 mode")); + if (on) { + this.tempSpot4x4 = true; + } + else { + this.tempSpot4x4 = false; + } + callback(); + }, + getClean: function (callback) { let that = this; this.updateRobot(function (error, result) { @@ -337,6 +448,17 @@ NeatoVacuumRobotAccessory.prototype = { }); }, + getSpotRepeat: function (callback) { + let that = this; + debug(that.name + ": Is spot cleaning repeat: " + that.tempSpotRepeat); + callback(false, that.tempSpotRepeat); + }, + + getSpot4x4: function (callback) { + let that = this; + debug(that.name + ": Is spot cleaning 4x4: " + that.tempSpot4x4); + callback(false, that.tempSpot4x4); + }, getBatteryLevel: function (callback) { let that = this; @@ -379,6 +501,9 @@ NeatoVacuumRobotAccessory.prototype = { if (that.vacuumRobotCleanService.getCharacteristic(Characteristic.On).value !== that.robot.canPause) { that.vacuumRobotCleanService.setCharacteristic(Characteristic.On, that.robot.canPause); } + if (that.vacuumRobotSpotCleanService.getCharacteristic(Characteristic.On).value !== that.robot.canPause) { + that.vacuumRobotSpotCleanService.setCharacteristic(Characteristic.On, that.robot.canPause); + } // dock switch is on (dock not seen before) and dock has just been seen -> turn switch off if (that.vacuumRobotGoToDockService.getCharacteristic(Characteristic.On).value == true && that.robot.dockHasBeenSeen) { @@ -413,4 +538,4 @@ NeatoVacuumRobotAccessory.prototype = { } }); }, -} \ No newline at end of file +} From 769712405a6c3bd917bf12b46a327b7cadd6d535 Mon Sep 17 00:00:00 2001 From: Nico Hartung Date: Thu, 3 Jan 2019 23:25:38 +0100 Subject: [PATCH 2/2] Update README.md for new spot cleaning --- README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0024ba0..94b0fa2 100644 --- a/README.md +++ b/README.md @@ -10,11 +10,14 @@ Feel free to leave any feedback [here](https://github.com/naofireblade/homebridg ## Features - Start and pause cleaning +- Start and pause spot cleaning - Return to dock - Toggle schedule - Toggle eco mode - Toggle extra care navigation - Toggle nogo lines +- Toggle 4x4 mode (spot) +- Toggle repeat mode (spot) - Get battery info - Get dock info - Periodic refresh of robot state @@ -49,7 +52,7 @@ The following config contains advanced optional settings. The parameter **refresh** sets an interval in seconds that is used to update the robot state in the background. This is only required for automations based on the robot state. The default value is `auto` which means that the update is automatically enabled while cleaning and disabled while not cleaning. You can set a value in seconds e.g. `120` to enable background updates even when the robot is not cleaning. You can also disable background updates completely by setting the value `0`. This might be required if you experience timeouts in the app because you have other home automation apps that are connected to your robot. -The parameter **disabled** accepts a list of switches/sensors that can be disabled in the neato homekit plugin (e.g. dock, dockstate, eco, schedule). +The parameter **disabled** accepts a list of switches/sensors that can be disabled in the neato homekit plugin (e.g. dock, dockstate, eco, schedule, spot). ```json "platforms": [ @@ -58,7 +61,7 @@ The parameter **disabled** accepts a list of switches/sensors that can be disabl "email": "YourEmail", "password": "YourPassword", "refresh": "120", - "disabled": ["dock", "dockstate", "eco", "nogolines", "extracare", "schedule"] + "disabled": ["dock", "dockstate", "eco", "nogolines", "extracare", "schedule", "spot"] } ] ```