From 7b70d8f0768b1b3c47d1ff14d41ad48743d10004 Mon Sep 17 00:00:00 2001 From: Nico Hartung Date: Thu, 3 Jan 2019 23:23:14 +0100 Subject: [PATCH] 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 +}