From eda198ed0907b062032f14d128c39e7aa56c2066 Mon Sep 17 00:00:00 2001 From: Arne Blumentritt Date: Fri, 30 Apr 2021 19:51:04 +0200 Subject: [PATCH] WIP dynamic platform --- old_index.js | 1 - src/accessories/neatoVacuumRobot.ts | 68 ++++++++++++++++++++++++++--- src/homebridgeNeatoPlatform.ts | 19 +++++--- 3 files changed, 74 insertions(+), 14 deletions(-) diff --git a/old_index.js b/old_index.js index e3b1bf5..c20f2bb 100644 --- a/old_index.js +++ b/old_index.js @@ -207,7 +207,6 @@ NeatoVacuumRobotPlatform.prototype = { map.boundaries = result.boundaries; } loadedMaps++; - // Robot is completely requested if zones for all maps are loaded if (loadedMaps === robot.maps.length) { diff --git a/src/accessories/neatoVacuumRobot.ts b/src/accessories/neatoVacuumRobot.ts index 0e6fba6..af2651b 100644 --- a/src/accessories/neatoVacuumRobot.ts +++ b/src/accessories/neatoVacuumRobot.ts @@ -1,7 +1,8 @@ -import {CharacteristicValue, Logger, PlatformAccessory, Service} from 'homebridge'; +import {CharacteristicValue, Logger, PlatformAccessory, PlatformConfig, Service} from 'homebridge'; import {HomebridgeNeatoPlatform} from '../homebridgeNeatoPlatform'; const debug = require('debug')('my-app:my-module'); + /** * Platform Accessory * An instance of this class is created for each accessory your platform registers @@ -13,6 +14,7 @@ export class NeatoVacuumRobotAccessory private findMeService: Service; private robot: any; private log: Logger; + private readonly refresh: any; // private goToDockService: Service; // private dockStateService: Service; // private ecoService: Service; @@ -29,10 +31,12 @@ export class NeatoVacuumRobotAccessory constructor( private readonly platform: HomebridgeNeatoPlatform, private readonly accessory: PlatformAccessory, - private readonly isNew: Boolean) + private readonly isNew: Boolean, + private readonly config: PlatformConfig) { this.robot = accessory.context.robot; this.log = platform.log; + this.refresh = (this.config)['refresh']; // set accessory information this.accessory.getService(this.platform.Service.AccessoryInformation)! @@ -46,7 +50,7 @@ export class NeatoVacuumRobotAccessory this.cleanService = this.accessory.getService(cleanServiceName) || this.accessory.addService(this.platform.Service.Switch, cleanServiceName, "CLEAN"); let findMeServiceName = this.robot.name + " Find Me"; this.findMeService = this.accessory.getService(findMeServiceName) || this.accessory.addService(this.platform.Service.Switch, findMeServiceName, "FIND_ME"); - + this.cleanService.getCharacteristic(this.platform.Characteristic.On) .onSet(this.setClean.bind(this)) .onGet(this.getClean.bind(this)); @@ -154,7 +158,7 @@ export class NeatoVacuumRobotAccessory throw new this.platform.api.hap.HapStatusError(this.platform.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE); } } - + async getClean(): Promise { try @@ -195,7 +199,7 @@ export class NeatoVacuumRobotAccessory setTimeout(() => { this.findMeService.updateCharacteristic(this.platform.Characteristic.On, false); }, 1000); - + try { await this.robot.findMe(); @@ -230,7 +234,59 @@ export class NeatoVacuumRobotAccessory } } } - + + async clean(boundary, spot) + { + // Start automatic update while cleaning + if (this.refresh === 'auto') + { + setTimeout(() => { + this.platform.updateRobotTimer(this.robot._serial); + }, 60 * 1000); + } + + let eco = this.robotObject.mainAccessory.ecoService.getCharacteristic(Characteristic.On).value; + let extraCare = this.robotObject.mainAccessory.extraCareService.getCharacteristic(Characteristic.On).value; + let nogoLines = this.robotObject.mainAccessory.noGoLinesService.getCharacteristic(Characteristic.On).value; + let room = (this.boundary == null) ? '' : this.boundary.name; + debug(this.name + ": ## Start cleaning (" + (room !== '' ? room + " " : '') + "eco: " + eco + ", extraCare: " + extraCare + ", nogoLines: " + nogoLines + ", spot: " + JSON.stringify(spot) + + ")"); + + // Normal cleaning + if (this.boundary == null && (typeof spot === 'undefined')) + { + this.robot.startCleaning(eco, extraCare ? 2 : 1, nogoLines, (error, result) => { + if (error) + { + this.log.error("Cannot start cleaning. " + error + ": " + JSON.stringify(result)); + } + callback(error); + }); + } + // Room cleaning + else if (room !== '') + { + this.robot.startCleaningBoundary(eco, extraCare, this.boundary.id, (error, result) => { + if (error) + { + this.log.error("Cannot start room cleaning. " + error + ": " + JSON.stringify(result)); + } + callback(error); + }); + } + // Spot cleaning + else + { + this.robot.startSpotCleaning(eco, spot.width, spot.height, spot.repeat, extraCare ? 2 : 1, (error, result) => { + if (error) + { + this.log.error("Cannot start spot cleaning. " + error + ": " + JSON.stringify(result)); + } + callback(error); + }); + } + } + // /** // * Handle the "GET" requests from HomeKit diff --git a/src/homebridgeNeatoPlatform.ts b/src/homebridgeNeatoPlatform.ts index e2b600e..768c5e8 100644 --- a/src/homebridgeNeatoPlatform.ts +++ b/src/homebridgeNeatoPlatform.ts @@ -24,7 +24,7 @@ export class HomebridgeNeatoPlatform implements DynamicPlatformPlugin public readonly config: PlatformConfig, public readonly api: API) { - this.log.debug('Finished initializing platform:', this.config.name); + this.log.debug('Finished initializing platform:', this.config.platform); this.api.on('didFinishLaunching', () => { log.debug('Executed didFinishLaunching callback'); @@ -55,7 +55,10 @@ export class HomebridgeNeatoPlatform implements DynamicPlatformPlugin client.authorize((this.config)['email'], (this.config)['password'], false, (error) => { if (error) { - throw new this.api.hap.HapStatusError(this.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE); + this.log.warn("Cannot connect to neato server. No new robots will be found and existing robots will be unresponsive."); + this.log.warn(error); + // TODO retry after x min + return; } // Get all robots from account @@ -63,12 +66,14 @@ export class HomebridgeNeatoPlatform implements DynamicPlatformPlugin if (error) { this.log.error("Successful login but can't connect to your neato robot: " + error); - throw new this.api.hap.HapStatusError(this.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE); + // TODO retry after x min + return; } else if (robots.length === 0) { this.log.error("Successful login but no robots associated with your account."); - throw new this.api.hap.HapStatusError(this.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE); + // TODO retry after x min + return; } debug("Found " + robots.length + " robots"); @@ -84,7 +89,7 @@ export class HomebridgeNeatoPlatform implements DynamicPlatformPlugin if (error) { this.log.error("Error getting robot meta information: " + error + ": " + state); - throw new this.api.hap.HapStatusError(this.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE); + return; } try @@ -105,7 +110,7 @@ export class HomebridgeNeatoPlatform implements DynamicPlatformPlugin // create the accessory handler for the restored accessory // this is imported from `platformAccessory.ts` - new NeatoVacuumRobotAccessory(this, existingAccessory, false); + new NeatoVacuumRobotAccessory(this, existingAccessory, false, this.config); // it is possible to remove platform accessories at any time using `api.unregisterPlatformAccessories`, eg.: // remove platform accessories when no longer present @@ -118,7 +123,7 @@ export class HomebridgeNeatoPlatform implements DynamicPlatformPlugin const accessory = new this.api.platformAccessory(robot.name, uuid); accessory.context.robot = robot; - new NeatoVacuumRobotAccessory(this, accessory, true); + new NeatoVacuumRobotAccessory(this, accessory, true, this.config); // link the accessory to your platform this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);