40 Commits

Author SHA1 Message Date
Arne
6c6bb1c204 Updated readme and changelog 2018-11-14 18:22:27 +01:00
Arne
577e62ea32 Improved refresh interval 2018-11-13 21:47:39 +01:00
Arne
fbec31602f NoGo Lines and options sync
ADDED
- NoGo lines button
- Extra care navigation button
- Syncing cleaning options from last run

CHANGED
- Goto dock button is now always off
- Better error handling
- More detailed debug messages
- Updated node-botvac dependency to 0.1.6

REMOVED
- Extra care navigation option parameter (is now a button)
2018-11-11 15:53:50 +01:00
naofireblade
42fa0399f8 Version 0.4.7
* Fixed an exception when no robot is associated with the account
2018-03-26 19:14:54 +02:00
Arne
0de549dd41 Merge pull request #12 from ghulands/fix_no_robots
Set an empty array if there are no robots on the account
2018-03-25 22:01:32 +02:00
Greg Hulands
7fef07df0a Set an empty array if there are no robots on the account 2018-03-24 22:54:12 -07:00
Arne
9e9dd80547 Added badges 2018-02-08 12:14:48 +01:00
Arne
b7ec93953e Updated list of supported robots 2018-01-11 08:01:18 +01:00
naofireblade
ad41c1679d Version 0.4.6
* Added error log while refreshing robot state
* Fixed a rare bug where the robot stops after some seconds of cleaning
2017-12-10 13:14:12 +01:00
naofireblade
89f6f233a5 Added errorlog while refreshing robot state 2017-10-15 19:34:02 +02:00
naofireblade
88f217e2b1 Version 0.4.5
* Fixed compatibility with homebridge 0.4.23 (occupancy sensor not
working)
2017-09-04 00:13:44 +02:00
naofireblade
2fec762498 Version 0.4.4
* Fixed config parameter to disable switches/sensors not optional
2017-07-25 08:54:52 +02:00
naofireblade
857af55e99 Version 0.4.3
* Fixed config parameter to disable switches/sensors not optional
2017-07-25 08:52:17 +02:00
naofireblade
20e0a9b909 Version 0.4.2
* Added config parameter to disable switches/sensors
2017-07-24 19:52:32 +02:00
Arne
afdff765b0 Wording 2017-06-07 10:51:14 +02:00
Arne
dcef6653ff Wording 2017-06-07 10:50:44 +02:00
Arne
82bf19c548 Wording 2017-06-07 10:48:46 +02:00
Arne
1084bff0ee Wording 2017-06-07 10:48:11 +02:00
Arne
5aa66835dd Wording 2017-06-07 10:47:01 +02:00
naofireblade
08ef90f7b0 Version 0.4.1
* Added config parameter for extraCareNavigation
2017-06-06 17:25:02 +02:00
naofireblade
bfb03b5d5d Version 0.4.0
* Added support for multiple robots
* Added log output when user requests accessory identify
* Changed plugin to platform instead of single accessory
* Removed parameter name from config
2017-06-05 16:46:45 +02:00
naofireblade
56e85c92e0 Wording and Bugfixes
* Fixed a bug that refresh is not disabled when set to 0
2017-05-20 19:41:25 +02:00
naofireblade
d6dd94979b Offical support for D5 Connected 2017-05-20 13:34:21 +02:00
naofireblade
6deca89d27 Updated dependencies 2017-05-18 19:14:59 +02:00
naofireblade
5eb5b9934d Support for basic-2 services 2017-05-18 18:59:14 +02:00
naofireblade
9a5c3f942c Error Handling 2017-05-13 21:17:46 +02:00
naofireblade
8f6f3dc72d Wording 2017-05-13 21:15:13 +02:00
naofireblade
0f8fb1dedf Wording 2017-05-07 17:20:54 +02:00
naofireblade
e01fb8df28 Bugfixes and changes in periodic refresh
* periodic refresh is now optional (minimum 60s)
* refresh while cleaning is now 30s
* fixed a bug where the robot starts to drive home after some minutes of
cleaning
2017-05-07 16:31:41 +02:00
naofireblade
8cb6ecf8a5 Improved refresh parameter 2017-05-06 23:57:36 +02:00
naofireblade
36e8496108 Version 0.3.0
* Added periodic refresh of robot state
* Improved go to dock switch to be enabled as soon as possible without
manual refresh
* Improved switches to indicate the time an action lasts
* Improved eco mode to not be overwritten by robot state
2017-05-06 23:51:58 +02:00
naofireblade
b2ddecc827 Improved go to dock command 2017-05-04 19:24:38 +02:00
naofireblade
5dbdb18c58 Set theme jekyll-theme-cayman 2017-04-30 18:07:17 +02:00
naofireblade
d49cab1e97 Set theme jekyll-theme-cayman 2017-04-30 18:06:45 +02:00
naofireblade
92eabfe5cd Wording 2017-04-30 14:35:23 +02:00
naofireblade
67b930653f Wording 2017-04-30 14:17:21 +02:00
naofireblade
579bd32a93 Readme 2017-04-28 18:12:22 +02:00
naofireblade
a606d4c632 Version 0.2.0
* Added dock info
* Changed logging to debug library
2017-04-22 22:57:09 +02:00
naofireblade
3a4327f7e9 spelling 2017-04-18 02:59:07 +02:00
naofireblade
cbfbb26b14 spelling 2017-04-18 02:51:59 +02:00
7 changed files with 463 additions and 221 deletions

17
.gitattributes vendored
View File

@@ -1,17 +0,0 @@
# Auto detect text files and perform LF normalization
* text=auto
# Custom for Visual Studio
*.cs diff=csharp
# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain

47
.gitignore vendored
View File

@@ -1,47 +0,0 @@
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msm
*.msp
# Windows shortcuts
*.lnk
# =========================
# Operating System Files
# =========================
# OSX
# =========================
.DS_Store
.AppleDouble
.LSOverride
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk

View File

@@ -4,4 +4,74 @@
* Added return to base
* Added enable and disable schedule
* Added enable and disable eco mode
* Added battery info
* Added battery info
## 0.2.0
* Added dock info
* Improved logging to use a debug library
## 0.2.1
* Improved the go to dock command
## 0.3.0
* Added periodic refresh of robot state while cleaning
* Added optional periodic refresh of robot state while not cleaning
* Added error messages when cant login or get robot
* Improved go to dock switch to be enabled as soon as possible without manual refresh
* Improved switches to indicate the time an action needs to complete
* Improved eco mode to not be overwritten by robot state update
## 0.3.1
* Added support for Neato BotVac D5 Connected
## 0.3.2
* Fixed a bug that refresh is not disabled when set to 0
## 0.4.0
* Added support for multiple robots
* Added log output when user requests accessory identify
* Changed plugin to platform instead of single accessory
* Removed parameter name from config
## 0.4.1
* Added config parameter for extraCareNavigation
## 0.4.2
* Added config parameter to disable switches/sensors
## 0.4.4
* Fixed config parameter to disable switches/sensors not optional
## 0.4.5
* Fixed compatibility with homebridge 0.4.23 (occupancy sensor not working)
## 0.4.6
* Added error log while refreshing robot state
* Fixed a rare bug where the robot stops after some seconds of cleaning
## 0.4.7
* Fixed an exception when no robot is associated with the account
## 0.5.0
* Added noGo lines button
* Added extra care navigation button
* Added syncing cleaning options from last run
* Added option to disable background state update completely
* Changed goto dock button is now always off
* Changed error handling
* Changed debug messages
* Updated node-botvac dependency to 0.1.6
* Removed extra care navigation option parameter (is now a button)

View File

@@ -1,40 +1,79 @@
# homebridge-neato
[![npm](https://img.shields.io/npm/v/homebridge-neato.svg?style=flat-square)](https://www.npmjs.com/package/homebridge-neato)
[![npm](https://img.shields.io/npm/dt/homebridge-neato.svg?style=flat-square)](https://www.npmjs.com/package/homebridge-neato)
[![GitHub last commit](https://img.shields.io/github/last-commit/naofireblade/homebridge-neato.svg?style=flat-square)](https://github.com/naofireblade/homebridge-neato)
This is a plugin to control your [Neato](https://www.neatorobotics.com/) vacuum robot.
This is a plugin for [homebridge](https://github.com/nfarina/homebridge) to control your [Neato](https://www.neatorobotics.com/) vacuum robot. You can download it via [npm](https://www.npmjs.com/package/homebridge-neato).
# Installation
Feel free to leave any feedback [here](https://github.com/naofireblade/homebridge-neato/issues).
1. Install homebridge using: npm install -g homebridge
2. Install this plugin using: npm install -g homebridge-neato
3. Update your configuration file. See the sample below.
If you update from a previous version 0.3.x you have to adapt your config (plugin is now a platform).
# Configuration
## Features
Configuration sample:
- Start and pause cleaning
- Return to dock
- Toggle schedule
- Toggle eco mode
- Toggle extra care navigation
- toggle nogo lines
- Get battery info
- Get dock info
- Periodic refresh of robot state
- Support for multiple robots
Add the following information to your config file. Change the values for name, email and password.
## Installation
1. Install homebridge using: `npm install -g homebridge`
2. Install this plugin using: `npm install -g homebridge-neato`
3. If you don't have a Neato account yet create one [here](https://www.neatorobotics.com/create-account/).
4. Update your configuration file. See the sample below.
## Configuration
Add the following information to your config file. Change the values for email and password.
### Simple
```json
"accessories": [
{
"accessory": "NeatoVacuumRobot",
"name": "YourRobot",
"email": "YourEmail",
"password": "YourPassword"
}
]
"platforms": [
{
"platform": "NeatoVacuumRobot",
"email": "YourEmail",
"password": "YourPassword"
}
]
```
# Features
### Advanced
- Atart and pause cleaning
- Return to base
- Enable and disable schedule
- Enable and disable eco mode
- Get battery info
The following config contains advanced optional settings.
# Tested robots
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.
- BotVac Connected Firmware 2.2.0
The parameter **disabled** accepts a list of switches/sensors that can be disabled in the neato homekit plugin (e.g. dock, dockstate, eco, schedule).
if you have another connected neato robot, please [tell me](https://github.com/naofireblade/homebridge-neato/issues/new) your experience with this plugin.
```json
"platforms": [
{
"platform": "NeatoVacuumRobot",
"email": "YourEmail",
"password": "YourPassword",
"refresh": "120",
"disabled": ["dock", "dockstate", "eco", "nogolines", "extracare", "schedule"]
}
]
```
## Tested robots
- BotVac Connected (Firmware 2.2.0)
- BotVac D3 Connected
- BotVac D5 Connected (Firmware 4.0.0, Firmware 4.3.0)
- BotVac D7 Connected
The plugin should work with D4 and D6 as well. If you have connected neato robot, please [tell me](https://github.com/naofireblade/homebridge-neato/issues) about your experience with this plugin.
## Contributors
Many thanks go to
- [ghulands](https://github.com/ghulands) for finding and fixing a bug when no robot is associated with the neato account

1
_config.yml Normal file
View File

@@ -0,0 +1 @@
theme: jekyll-theme-cayman

447
index.js
View File

@@ -1,223 +1,416 @@
"use strict";
var inherits = require('util').inherits;
var botvac = require('node-botvac');
var inherits = require('util').inherits,
debug = require('debug')('homebridge-neato'),
botvac = require('node-botvac'),
var Service, Characteristic;
Service,
Characteristic
module.exports = function (homebridge) {
Service = homebridge.hap.Service;
Characteristic = homebridge.hap.Characteristic;
homebridge.registerAccessory("homebridge-neato", "NeatoVacuumRobot", NeatoVacuumRobot);
homebridge.registerPlatform("homebridge-neato", "NeatoVacuumRobot", NeatoVacuumRobotPlatform);
}
function NeatoVacuumRobot(log, config) {
function NeatoVacuumRobotPlatform(log, config) {
this.log = log;
this.name = config['name'];
this.serial = "1-3-3-7";
this.email = config['email'];
this.password = config['password'];
this.hiddenServices = ('disabled' in config ? config['disabled'] : '');
this.lastUpdate = null;
this.robot = null;
if ('refresh' in config && config['refresh'] !== 'auto') {
// parse config parameter
this.refresh = parseInt(config['refresh']);
// must be integer and positive
this.refresh = (typeof this.refresh !== 'number' || (this.refresh % 1) !== 0 || this.refresh < 0) ? 60 : this.refresh;
// minimum 60s to save some load on the neato servers
this.refresh = (this.refresh > 0 && this.refresh < 60) ? 60 : this.refresh;
}
// default auto
else {
this.refresh = 'auto';
}
debug("Refresh is set to: " + this.refresh);
}
NeatoVacuumRobot.prototype = {
NeatoVacuumRobotPlatform.prototype = {
accessories: function (callback) {
this.accessories = [];
let that = this;
this.robots = this.getRobots(function () {
for (var i = 0; i < that.robots.length; i++) {
that.log("Found robot #" + (i + 1) + " named \"" + that.robots[i].name + "\" with serial \"" + that.robots[i]._serial + "\"");
var robotAccessory = new NeatoVacuumRobotAccessory(that.robots[i], that);
that.accessories.push(robotAccessory);
}
callback(that.accessories);
});
},
getRobots: function (callback) {
debug("Loading your robots");
let client = new botvac.Client();
let that = this;
client.authorize(this.email, this.password, false, function (error) {
if (error) {
that.log(error);
that.log.error("Can't log on to neato cloud. Please check your credentials.");
callback();
}
else {
client.getRobots(function (error, robots) {
if (error) {
that.log(error);
that.log.error("Successful login but can't connect to your neato robot.");
callback();
}
else {
if (robots.length === 0) {
that.log.error("Successful login but no robots associated with your account.");
that.robots = [];
callback();
}
else {
debug("Found " + robots.length + " robots");
that.robots = robots;
callback();
}
}
});
}
});
}
}
function NeatoVacuumRobotAccessory(robot, platform) {
this.platform = platform;
this.log = platform.log;
this.refresh = platform.refresh;
this.hiddenServices = platform.hiddenServices;
this.robot = robot;
this.name = robot.name;
this.lastUpdate = null;
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");
this.vacuumRobotEcoService = new Service.Switch(this.name + " Eco Mode", "eco");
this.vacuumRobotNoGoLinesService = new Service.Switch(this.name + " NoGo Lines", "noGoLines");
this.vacuumRobotExtraCareService = new Service.Switch(this.name + " Extra Care", "extraCare");
this.vacuumRobotScheduleService = new Service.Switch(this.name + " Schedule", "schedule");
this.vacuumRobotBatteryService = new Service.BatteryService("Battery", "battery");
this.updateRobotTimer();
}
NeatoVacuumRobotAccessory.prototype = {
identify: function (callback) {
this.log("Identify requested");
callback();
let that = this;
this.updateRobot(function () {
// hide serial and secret in log
let _serial = that.robot._serial;
let _secret = that.robot._secret;
that.robot._serial = "*****";
that.robot._secret = "*****";
that.log(that.robot);
that.robot._serial = _serial;
that.robot._secret = _secret;
callback();
});
},
getServices: function () {
this.informationService = new Service.AccessoryInformation();
this.informationService
.setCharacteristic(Characteristic.Manufacturer, "Neato Robotics")
.setCharacteristic(Characteristic.Model, this.name)
.setCharacteristic(Characteristic.SerialNumber, this.serial);
.setCharacteristic(Characteristic.Name, this.robot.name)
.setCharacteristic(Characteristic.Manufacturer, "Neato Robotics")
.setCharacteristic(Characteristic.Model, "Coming soon")
.setCharacteristic(Characteristic.SerialNumber, this.robot._serial);
this.vacuumRobotCleanService = new Service.Switch(this.name + " Clean", "clean");
this.vacuumRobotCleanService.getCharacteristic(Characteristic.On).on('set', this.clean.bind(this));
this.vacuumRobotCleanService.getCharacteristic(Characteristic.On).on('set', this.setClean.bind(this));
this.vacuumRobotCleanService.getCharacteristic(Characteristic.On).on('get', this.getClean.bind(this));
this.vacuumRobotDockService = new Service.Switch(this.name + " Dock", "dock");
this.vacuumRobotDockService.getCharacteristic(Characteristic.On).on('set', this.dock.bind(this));
this.vacuumRobotDockService.getCharacteristic(Characteristic.On).on('get', this.getDock.bind(this));
this.vacuumRobotGoToDockService.getCharacteristic(Characteristic.On).on('set', this.setGoToDock.bind(this));
this.vacuumRobotGoToDockService.getCharacteristic(Characteristic.On).on('get', this.getGoToDock.bind(this));
this.vacuumRobotEcoService = new Service.Switch(this.name + " Eco Mode", "eco");
this.vacuumRobotEcoService.getCharacteristic(Characteristic.On).on('set', this.eco.bind(this));
this.vacuumRobotDockStateService.getCharacteristic(Characteristic.OccupancyDetected).on('get', this.getDock.bind(this));
this.vacuumRobotEcoService.getCharacteristic(Characteristic.On).on('set', this.setEco.bind(this));
this.vacuumRobotEcoService.getCharacteristic(Characteristic.On).on('get', this.getEco.bind(this));
this.vacuumRobotScheduleService = new Service.Switch(this.name + " Schedule", "schedule");
this.vacuumRobotScheduleService.getCharacteristic(Characteristic.On).on('set', this.schedule.bind(this));
this.vacuumRobotNoGoLinesService.getCharacteristic(Characteristic.On).on('set', this.setNoGoLines.bind(this));
this.vacuumRobotNoGoLinesService.getCharacteristic(Characteristic.On).on('get', this.getNoGoLines.bind(this));
this.vacuumRobotExtraCareService.getCharacteristic(Characteristic.On).on('set', this.setExtraCare.bind(this));
this.vacuumRobotExtraCareService.getCharacteristic(Characteristic.On).on('get', this.getExtraCare.bind(this));
this.vacuumRobotScheduleService.getCharacteristic(Characteristic.On).on('set', this.setSchedule.bind(this));
this.vacuumRobotScheduleService.getCharacteristic(Characteristic.On).on('get', this.getSchedule.bind(this));
this.vacuumRobotBatteryService = new Service.BatteryService("Battery", "battery");
this.vacuumRobotBatteryService.getCharacteristic(Characteristic.BatteryLevel).on('get', this.getBatteryLevel.bind(this));
this.vacuumRobotBatteryService.getCharacteristic(Characteristic.ChargingState).on('get', this.getBatteryChargingState.bind(this));
return [this.informationService, this.vacuumRobotCleanService, this.vacuumRobotDockService, this.vacuumRobotEcoService,
this.vacuumRobotScheduleService, this.vacuumRobotBatteryService];
this.services = [this.informationService, this.vacuumRobotCleanService, this.vacuumRobotBatteryService];
if (this.hiddenServices.indexOf('dock') === -1)
this.services.push(this.vacuumRobotGoToDockService);
if (this.hiddenServices.indexOf('dockstate') === -1)
this.services.push(this.vacuumRobotDockStateService);
if (this.hiddenServices.indexOf('eco') === -1)
this.services.push(this.vacuumRobotEcoService);
if (this.hiddenServices.indexOf('nogolines') === -1)
this.services.push(this.vacuumRobotNoGoLinesService);
if (this.hiddenServices.indexOf('extracare') === -1)
this.services.push(this.vacuumRobotExtraCareService);
if (this.hiddenServices.indexOf('schedule') === -1)
this.services.push(this.vacuumRobotScheduleService);
return this.services;
},
clean: function (on, callback) {
setClean: function (on, callback) {
let that = this;
if (on) {
this.getState(function (error, result) {
that.log(that.robot);
if (that.robot.canResume === true) {
that.log("Resume cleaning");
that.robot.resumeCleaning(function (error, result) {
that.log(result);
});
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 cleaning");
that.robot.resumeCleaning(callback);
}
else {
let eco = that.vacuumRobotEcoService.getCharacteristic(Characteristic.On).value;
let extraCare = that.vacuumRobotExtraCareService.getCharacteristic(Characteristic.On).value;
let nogoLines = that.vacuumRobotNoGoLinesService.getCharacteristic(Characteristic.On).value;
debug(that.name + ": Start cleaning (eco: " + eco + ", extraCare: " + extraCare + ", nogoLines: " + nogoLines + ")");
that.robot.startCleaning(
eco,
extraCare ? 2 : 1,
nogoLines,
function (error, result) {
if (error) {
that.log.error(error + ": " + result);
callback(true);
}
else {
callback();
}
});
}
}
else {
that.log("Start cleaning");
that.robot.startCleaning(that.robot.eco, function (error, result) {
that.log(result);
debug(that.name + ": Cant start, maybe already cleaning");
callback();
}
}
else {
if (that.robot.canPause) {
debug(that.name + ": Pause cleaning");
that.robot.pauseCleaning(callback);
}
else {
debug(that.name + ": Already stopped");
callback();
}
}
});
},
setGoToDock: function (on, callback) {
let that = this;
this.updateRobot(function (error, result) {
if (on) {
if (that.robot.canPause) {
debug(that.name + ": Pause cleaning to go to dock");
that.robot.pauseCleaning(function (error, result) {
setTimeout(function () {
debug("Go to dock");
that.robot.sendToBase(callback);
}, 1000);
});
}
});
}
else {
this.log("Pause cleaning");
this.robot.pauseCleaning(false, function (error, result) {
that.log(result);
});
}
callback();
else if (that.robot.canGoToBase) {
debug(that.name + ": Go to dock");
that.robot.sendToBase(callback);
}
else {
that.log.warn(that.name + ": Can't go to dock at the moment");
callback();
}
} else {
callback();
}
});
},
dock: function (on, callback) {
let that = this;
that.log(that.robot);
if (on) {
that.log("Send to dock");
that.robot.sendToBase(false, function (error, result) {
that.log(result);
});
}
callback();
},
eco: function (on, callback) {
this.log(on ? "Enable eco mode" : "Disable eco mode");
setEco: function (on, callback) {
debug(this.name + ": " + (on ? "Enable eco mode" : "Disable eco mode"));
this.robot.eco = on;
callback();
},
schedule: function (on, callback) {
if (on) {
this.log("Enable schedule");
this.robot.enableSchedule(false, function (error, result) {
onsole.log(result);
});
}
else {
this.log("Disable schedule");
this.robot.disableSchedule(false, function (error, result) {
onsole.log(result);
});
}
setNoGoLines: function (on, callback) {
debug(this.name + ": " + (on ? "Enable nogo lines" : "Disable nogo lines"));
this.robot.noGoLines = on;
callback();
},
getClean: function(callback) {
setExtraCare: function (on, callback) {
debug(this.name + ": " + (on ? "Enable extra care navigation" : "Disable extra care navigation"));
this.robot.navigationMode = on ? 2 : 1;
callback();
},
setSchedule: function (on, callback) {
let that = this;
this.getState(function (error, result) {
that.log("Is cleaning: " + that.robot.canPause);
this.updateRobot(function (error, result) {
if (on) {
debug(that.name + ": Enable schedule");
that.robot.enableSchedule(callback);
}
else {
debug(that.name + ": Disable schedule");
that.robot.disableSchedule(callback);
}
});
},
getClean: function (callback) {
let that = this;
this.updateRobot(function (error, result) {
debug(that.name + ": Is cleaning: " + that.robot.canPause);
callback(false, that.robot.canPause);
});
},
getDock: function(callback) {
getGoToDock: function (callback) {
callback(false, false);
},
getDock: function (callback) {
let that = this;
this.getState(function (error, result) {
that.log("Can go to dock: " + that.robot.canGoToBase);
that.log("Is docked: " + that.robot.isDocked);
callback(false, that.robot.isDocked);
this.updateRobot(function () {
debug(that.name + ": Is docked: " + that.robot.isDocked);
callback(false, that.robot.isDocked ? 1 : 0);
});
},
getEco: function(callback) {
getEco: function (callback) {
let that = this;
this.getState(function (error, result) {
that.log("Eco mode: " + that.robot.eco);
this.updateRobot(function () {
debug(that.name + ": Is eco: " + that.robot.eco);
callback(false, that.robot.eco);
});
},
getSchedule: function(callback) {
getNoGoLines: function (callback) {
let that = this;
this.getState(function (error, result) {
that.log("Schedule: " + that.robot.isScheduleEnabled);
this.updateRobot(function () {
debug(that.name + ": Is nogo lines: " + that.robot.noGoLines);
callback(false, that.robot.noGoLines ? 1 : 0);
});
},
getExtraCare: function (callback) {
let that = this;
this.updateRobot(function () {
debug(that.name + ": Is extra care navigation: " + (that.robot.navigationMode == 2 ? true : false));
callback(false, that.robot.navigationMode == 2 ? 1 : 0);
});
},
getSchedule: function (callback) {
let that = this;
this.updateRobot(function () {
debug(that.name + ": Is schedule: " + that.robot.isScheduleEnabled);
callback(false, that.robot.isScheduleEnabled);
});
},
getBatteryLevel: function(callback) {
getBatteryLevel: function (callback) {
let that = this;
this.getState(function (error, result) {
that.log("Battery: " + that.robot.charge);
this.updateRobot(function () {
debug(that.name + ": Battery: " + that.robot.charge + "%");
callback(false, that.robot.charge);
});
},
getBatteryChargingState: function(callback) {
getBatteryChargingState: function (callback) {
let that = this;
this.getState(function (error, result) {
that.log("Is charging: " + that.robot.isCharging);
this.updateRobot(function () {
debug(that.name + ": Is charging: " + that.robot.isCharging);
callback(false, that.robot.isCharging);
});
},
getState: function(callback) {
updateRobot: function (callback) {
let that = this;
if (this.robot === null)
{
this.getRobot(function (error, result) {
that._getState(callback);
});
}
else {
that._getState(callback);
}
},
_getState: function(callback) {
if (this.lastUpdate !== null && new Date() - this.lastUpdate < 2000) {
//this.log("Get state (cached)");
callback();
}
else {
//this.log("Get state (new)");
let that = this;
debug(this.name + ": Updating robot state");
this.robot.getState(function (error, result) {
if (error) {
that.log.error(error + ": " + result);
}
that.lastUpdate = new Date();
callback();
});
}
},
getRobot: function(callback) {
//this.log("Get robot");
let client = new botvac.Client();
updateRobotTimer: function () {
let that = this;
client.authorize(this.email, this.password, false, function (error) {
if (error) {
that.log(error);
this.updateRobot(function (error, result) {
// only update these values if the state is different from the current one, otherwise we might accidentally start an action
if (that.vacuumRobotCleanService.getCharacteristic(Characteristic.On).value !== that.robot.canPause) {
that.vacuumRobotCleanService.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) {
that.vacuumRobotGoToDockService.setCharacteristic(Characteristic.On, false);
}
if (that.vacuumRobotScheduleService.getCharacteristic(Characteristic.On).value !== that.robot.isScheduleEnabled) {
that.vacuumRobotScheduleService.setCharacteristic(Characteristic.On, that.robot.isScheduleEnabled);
}
// no commands here, values can be updated without problems
that.vacuumRobotDockStateService.setCharacteristic(Characteristic.OccupancyDetected, that.robot.isDocked ? 1 : 0);
that.vacuumRobotEcoService.setCharacteristic(Characteristic.On, that.robot.eco);
that.vacuumRobotNoGoLinesService.setCharacteristic(Characteristic.On, that.robot.noGoLines);
that.vacuumRobotExtraCareService.setCharacteristic(Characteristic.On, that.robot.navigationMode == 2 ? true : false);
that.vacuumRobotBatteryService.setCharacteristic(Characteristic.BatteryLevel, that.robot.charge);
that.vacuumRobotBatteryService.setCharacteristic(Characteristic.ChargingState, that.robot.isCharging);
// robot is currently cleaning, update if refresh is set to auto or a specific interval
if (that.robot.canPause && that.refresh !== 0) {
let refreshTime = that.refresh === 'auto' ? 60 : that.refresh
debug("Updating state in background every " + refreshTime + " seconds while cleaning");
that.timer = setTimeout(that.updateRobotTimer.bind(that), refreshTime * 1000);
}
// robot is not cleaning, but a specific refresh interval is set
else if (that.refresh !== 'auto' && that.refresh !== 0) {
debug("Updating state in background every " + that.refresh + " seconds (user setting)");
that.timer = setTimeout(that.updateRobotTimer.bind(that), that.refresh * 1000);
}
else {
client.getRobots(function (error, robots) {
if (error) {
that.log(error);
}
else {
that.robot = robots[0];
that.log("Found robot: " + that.robot.name);
callback();
}
});
debug("Updating state in background disabled");
}
});
}
},
}

View File

@@ -1,10 +1,12 @@
{
"name": "homebridge-neato",
"version": "0.1.0",
"description": "control your neato vacuum robot",
"version": "0.5.0",
"description": "A Neato vacuum robot plugin for homebridge.",
"license": "MIT",
"keywords": [
"homebridge-plugin"
"homebridge-plugin",
"neato",
"botvac"
],
"engines": {
"node": ">=0.12.0",
@@ -18,6 +20,7 @@
"url": "git://github.com/naofireblade/homebridge-neato.git"
},
"dependencies": {
"node-botvac": ">=0.1.4"
"node-botvac": ">=0.1.6",
"debug": "^2.2.0"
}
}