UNPKG

node-kobold

Version:

Vorwerk Kobold API for VR200 and VR300

333 lines (309 loc) 12.7 kB
var api = require(__dirname + '/api'); var crypto = require('crypto'); function Robot(name, serial, secret) { this._baseUrl = 'https://nucleo.ksecosys.com/vendors/vorwerk/robots/'; this.name = name; this._serial = serial; this._secret = secret; this.eco = null; this.noGoLines = null; this.navigationMode = null; this.spotWidth = null; this.spotHeight = null; this.spotRepeat = null; //updated when getState() is called this.isCharging = null; this.isDocked = null; this.isScheduleEnabled = null; this.dockHasBeenSeen = null; this.charge = null; this.canStart = null; this.canStop = null; this.canPause = null; this.canResume = null; this.canGoToBase = null; } Robot.prototype.getState = function getState(callback) { doAction(this, 'getRobotState', null, (function (error, result) { if (typeof callback === 'function') { if (result === undefined) { if (!error) { error = 'no result'; } callback(error, null); }else if (result && 'message' in result) { callback(result.message, result); } else { this.isCharging = result.details.isCharging; this.isDocked = result.details.isDocked; this.isScheduleEnabled = result.details.isScheduleEnabled; this.dockHasBeenSeen = result.details.dockHasBeenSeen; this.charge = result.details.charge; this.canStart = result.availableCommands.start; this.canStop = result.availableCommands.stop; this.canPause = result.availableCommands.pause; this.canResume = result.availableCommands.resume; this.canGoToBase = result.availableCommands.goToBase; // Read cleaning parameters from last run this.eco = result.cleaning.mode == 1 ? true : false; // 4: house cleaning with noGoLines if (result.cleaning.category == 4) { this.noGoLines = true; } // 2: house cleaning without noGoLines else if (result.cleaning.category == 2) { this.noGoLines = false; } // 1+3: spot+manual cleaning. Set nogolines to default = false only if not set already else if (this.noGoLines === null) { this.noGoLines = false; } this.navigationMode = result.cleaning.navigationMode; this.spotWidth = result.cleaning.spotWidth; this.spotHeight = result.cleaning.spotHeight; this.spotRepeat = result.cleaning.modifier == 2 ? true : false; //console.log(result); callback(error, result); } } }).bind(this)); }; Robot.prototype.getSchedule = function getSchedule(callback) { doAction(this, 'getSchedule', null, function (error, result) { if (typeof callback === 'function') { if (error) { callback(error, result); } else if (result && 'data' in result && 'enabled' in result.data) { callback(null, result.data.enabled); } else { callback(result && 'message' in result ? result.message: 'failed', result); } } }); }; Robot.prototype.enableSchedule = function enableSchedule(callback) { doAction(this, 'enableSchedule', null, function (error, result) { if (typeof callback === 'function') { if (error) { callback(error, result); } else if (result && 'result' in result && result.result == 'ok') { callback(null, result.result); } else { callback(result && 'message' in result ? result.message: 'failed', result && 'result' in result ? result.result : result); } } }); }; Robot.prototype.disableSchedule = function disableSchedule(callback) { doAction(this, 'disableSchedule', null, function (error, result) { if (typeof callback === 'function') { if (error) { callback(error, result); } else if (result && 'result' in result && result.result == 'ok') { callback(null, result.result); } else { callback(result && 'message' in result ? result.message: 'failed', result && 'result' in result ? result.result : result); } } }); }; Robot.prototype.sendToBase = function sendToBase(callback) { doAction(this, 'sendToBase', null, function (error, result) { if (typeof callback === 'function') { if (error) { callback(error, result); } else if (result && 'result' in result && result.result == 'ok') { callback(null, result.result); } else { callback(result && 'message' in result ? result.message: 'failed', result && 'result' in result ? result.result : result); } } }); }; Robot.prototype.stopCleaning = function stopCleaning(callback) { doAction(this, 'stopCleaning', null, function (error, result) { if (typeof callback === 'function') { if (error) { callback(error, result); } else if (result && 'result' in result && result.result == 'ok') { callback(null, result.result); } else { callback(result && 'message' in result ? result.message: 'failed', result && 'result' in result ? result.result : result); } } }); }; Robot.prototype.pauseCleaning = function pauseCleaning(callback) { doAction(this, 'pauseCleaning', null, function (error, result) { if (typeof callback === 'function') { if (error) { callback(error, result); } else if (result && 'result' in result && result.result == 'ok') { callback(null, result.result); } else { callback(result && 'message' in result ? result.message: 'failed', result && 'result' in result ? result.result : result); } } }); }; Robot.prototype.resumeCleaning = function resumeCleaning(callback) { doAction(this, 'resumeCleaning', null, function (error, result) { if (typeof callback === 'function') { if (error) { callback(error, result); } else if (result && 'result' in result && result.result == 'ok') { callback(null, result.result); } else { callback(result && 'message' in result ? result.message: 'failed', result && 'result' in result ? result.result : result); } } }); }; Robot.prototype.startSpotCleaning = function startSpotCleaning(eco, width, height, repeat, navigationMode, callback) { if (typeof eco === 'function') { callback = eco; eco = this.eco; width = this.spotWidth; height = this.spotHeight; repeat = this.spotRepeat; navigationMode = this.navigationMode; } else if (typeof width === 'function') { callback = width; width = this.spotWidth; height = this.spotHeight; repeat = this.spotRepeat; navigationMode = this.navigationMode; } else if (typeof height === 'function') { callback = height; height = this.spotHeight; repeat = this.spotRepeat; navigationMode = this.navigationMode; } else if (typeof repeat === 'function') { callback = repeat; repeat = this.spotRepeat; navigationMode = this.navigationMode; } else if (typeof navigationMode === 'function') { callback = navigationMode; navigationMode = this.navigationMode; } if (typeof width !== 'number' || width < 100) { width = this.width; } if (typeof height !== 'number' || height < 100) { height = this.height; } if (typeof navigationMode !== 'number' || navigationMode < 1 || navigationMode > 2) { navigationMode = this.navigationMode; } var params = { category: 3, //1: manual, 2: house, 3: spot, 4: house with enabled nogolines mode: eco ? 1 : 2, //1: eco, 2: turbo modifier: repeat ? 2 : 1, //spot: clean spot 1 or 2 times navigationMode: navigationMode, //1: normal, 2: extra care spotWidth: width, spotHeight: height }; doAction(this, 'startCleaning', params, function (error, result) { if (typeof callback === 'function') { if (error) { callback(error, result); } else if (result && 'result' in result && result.result == 'ok') { callback(null, result.result); } else { callback(result && 'message' in result ? result.message: 'failed', result && 'result' in result ? result.result : result); } } }); }; Robot.prototype.startManualCleaning = function startSpotCleaning(eco, navigationMode, callback) { if (typeof eco === 'function') { callback = eco; eco = this.eco; navigationMode = this.navigationMode; } else if (typeof navigationMode === 'function') { callback = navigationMode; navigationMode = this.navigationMode; } var params = { category: 1, //1: manual, 2: house, 3: spot, 4: house with enabled nogolines mode: eco ? 1 : 2, //1: eco, 2: turbo modifier: 1, //spot: clean spot 1 or 2 times navigationMode: navigationMode //1: normal, 2: extra care }; doAction(this, 'startCleaning', params, function (error, result) { if (typeof callback === 'function') { if (error) { callback(error, result); } else if (result && 'result' in result && result.result == 'ok') { callback(null, result.result); } else { callback(result && 'message' in result ? result.message: 'failed', result && 'result' in result ? result.result : result); } } }); }; Robot.prototype.startCleaning = function startSpotCleaning(eco, navigationMode, noGoLines, callback) { if (typeof eco === 'function') { callback = eco; eco = this.eco; navigationMode = this.navigationMode; noGoLines = this.noGoLines; } else if (typeof navigationMode === 'function') { callback = navigationMode; navigationMode = this.navigationMode; noGoLines = this.noGoLines; } else if (typeof noGoLines === 'function') { callback = noGoLines; noGoLines = this.noGoLines; } var params = { category: noGoLines ? 4 : 2, //1: manual, 2: house, 3: spot, 4: house with enabled nogolines mode: eco ? 1 : 2, //1: eco, 2: turbo modifier: 1, //spot: clean spot 1 or 2 times navigationMode: navigationMode //1: normal, 2: extra care }; doAction(this, 'startCleaning', params, function (error, result) { if (typeof callback === 'function') { if (error) { callback(error, result); } else if (result && 'result' in result && result.result == 'ok') { callback(null, result.result); } else { callback(result && 'message' in result ? result.message: 'failed', result && 'result' in result ? result.result : result); } } }); }; function doAction(robot, command, params, callback) { if (robot._serial && robot._secret) { var payload = { reqId: '1', cmd: command }; if (params) { payload.params = params; } payload = JSON.stringify(payload); var date = new Date().toUTCString(); var data = [robot._serial.toLowerCase(), date, payload].join("\n"); var hmac = crypto.createHmac('sha256', robot._secret).update(data).digest('hex'); var headers = { Date: date, Authorization: 'NEATOAPP ' + hmac }; cert = __dirname + '/cert/neatocloud.com.crt'; api.request(robot._baseUrl + robot._serial + '/messages', payload, 'POST', headers, cert, function (error, body) { if (typeof callback === 'function') { callback(error, body); } }); } else { if (typeof callback === 'function') { callback('no serial or secret'); } } } module.exports = Robot;