WIP dynamic platform
This commit is contained in:
parent
e0bd97ee5d
commit
b13885bea7
@ -62,8 +62,14 @@
|
||||
"ts-node": "^9.1.1",
|
||||
"typescript": "^4.2.2"
|
||||
},
|
||||
"funding": {
|
||||
"funding": [
|
||||
{
|
||||
"type": "buymeacoffee",
|
||||
"url": "https://buymeacoffee.com/naofireblade"
|
||||
},
|
||||
{
|
||||
"type": "paypal",
|
||||
"url": "https://paypal.me/ArneBlumentritt"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
import {CharacteristicValue, Logger, PlatformAccessory, PlatformConfig, Service} from 'homebridge';
|
||||
import {CharacteristicValue, Logger, PlatformAccessory, PlatformAccessoryEvent, PlatformConfig, Service} from 'homebridge';
|
||||
import {HomebridgeNeatoPlatform} from '../homebridgeNeatoPlatform';
|
||||
|
||||
const debug = require('debug')('my-app:my-module');
|
||||
import {Options} from '../models/options';
|
||||
|
||||
/**
|
||||
* Platform Accessory
|
||||
@ -13,15 +12,16 @@ export class NeatoVacuumRobotAccessory
|
||||
private robot: any;
|
||||
private log: Logger;
|
||||
private readonly refresh: any;
|
||||
private spotClean: boolean;
|
||||
|
||||
private options: any;
|
||||
private isSpotCleaning: boolean;
|
||||
private readonly options: Options;
|
||||
private timer: any;
|
||||
|
||||
private batteryService: Service;
|
||||
private cleanService: Service;
|
||||
private findMeService: Service;
|
||||
private goToDockService: Service;
|
||||
private dockStateService: Service;
|
||||
private binFullService: Service;
|
||||
private ecoService: Service;
|
||||
private noGoLinesService: Service;
|
||||
private extraCareService: Service;
|
||||
@ -39,8 +39,9 @@ export class NeatoVacuumRobotAccessory
|
||||
private readonly isNew: Boolean,
|
||||
private readonly config: PlatformConfig)
|
||||
{
|
||||
this.robot = accessory.context.robot;
|
||||
this.log = platform.log;
|
||||
this.robot = accessory.context.robot;
|
||||
this.options = accessory.context.options || new Options();
|
||||
|
||||
if ('refresh' in this.config && this.config['refresh'] !== 'auto')
|
||||
{
|
||||
@ -59,10 +60,9 @@ export class NeatoVacuumRobotAccessory
|
||||
{
|
||||
this.refresh = 'auto';
|
||||
}
|
||||
this.log.debug(this.robot.name + " ## Refresh set to: " + this.refresh);
|
||||
this.debug(DebugType.STATUS, "Background update interval is: " + this.refresh);
|
||||
|
||||
this.spotClean = false;
|
||||
this.options = {};
|
||||
this.isSpotCleaning = false;
|
||||
|
||||
// set accessory information
|
||||
this.accessory.getService(this.platform.Service.AccessoryInformation)!
|
||||
@ -72,61 +72,102 @@ export class NeatoVacuumRobotAccessory
|
||||
.setCharacteristic(this.platform.Characteristic.FirmwareRevision, this.robot.meta.firmware)
|
||||
.setCharacteristic(this.platform.Characteristic.Name, this.robot.name);
|
||||
|
||||
this.accessory.on(PlatformAccessoryEvent.IDENTIFY, () => {
|
||||
this.robot.getState((error, result) => {
|
||||
this.log.info(this.robot.name + " Identified");
|
||||
if (error)
|
||||
{
|
||||
this.debug(DebugType.INFO, JSON.stringify("Error: " + error));
|
||||
}
|
||||
this.debug(DebugType.INFO, "Status: " + JSON.stringify(result));
|
||||
});
|
||||
});
|
||||
|
||||
this.batteryService = this.accessory.getService(this.platform.Service.Battery) || this.accessory.addService(this.platform.Service.Battery)
|
||||
|
||||
this.cleanService = this.getSwitchService(this.robot.name + " Clean");
|
||||
this.findMeService = this.getSwitchService(this.robot.name + " Find Me");
|
||||
this.cleanService = this.getSwitchService(this.robot.name + " Clean House");
|
||||
this.spotCleanService = this.getSwitchService(this.robot.name + " Clean Spot");
|
||||
this.goToDockService = this.getSwitchService(this.robot.name + " Go to Dock");
|
||||
this.dockStateService = this.getOccupancyService(this.robot.name + " Docked")
|
||||
this.ecoService = this.getSwitchService(this.robot.name + " Eco Mode");
|
||||
this.noGoLinesService = this.getSwitchService(this.robot.name + " NoGo Lines");
|
||||
this.extraCareService = this.getSwitchService(this.robot.name + " Extra Care");
|
||||
this.scheduleService = this.getSwitchService(this.robot.name + " Schedule");
|
||||
this.spotCleanService = this.getSwitchService(this.robot.name + " Clean Spot");
|
||||
this.binFullService = this.getOccupancyService(this.robot.name + " Bin Full")
|
||||
this.findMeService = this.getSwitchService(this.robot.name + " Find Me");
|
||||
this.scheduleService = this.getSwitchService(this.robot.name + " Option: Schedule");
|
||||
this.ecoService = this.getSwitchService(this.robot.name + " Option: Eco Mode");
|
||||
this.noGoLinesService = this.getSwitchService(this.robot.name + " Option: NoGo Lines");
|
||||
this.extraCareService = this.getSwitchService(this.robot.name + " Option: Extra Care");
|
||||
|
||||
this.cleanService.getCharacteristic(this.platform.Characteristic.On)
|
||||
.onSet(this.setClean.bind(this))
|
||||
.onGet(this.getClean.bind(this));
|
||||
this.findMeService.getCharacteristic(this.platform.Characteristic.On)
|
||||
.onSet(this.setFindMe.bind(this))
|
||||
.onGet(this.getFindMe.bind(this));
|
||||
.onSet(this.setCleanHouse.bind(this))
|
||||
.onGet(this.getCleanHouse.bind(this));
|
||||
this.spotCleanService.getCharacteristic(this.platform.Characteristic.On)
|
||||
.onSet(this.setSpotClean.bind(this))
|
||||
.onGet(this.getSpotClean.bind(this));
|
||||
this.goToDockService.getCharacteristic(this.platform.Characteristic.On)
|
||||
.onSet(this.setGoToDock.bind(this))
|
||||
.onGet(this.getGoToDock.bind(this));
|
||||
this.dockStateService.getCharacteristic(this.platform.Characteristic.On)
|
||||
this.dockStateService.getCharacteristic(this.platform.Characteristic.OccupancyDetected)
|
||||
.onGet(this.getDocked.bind(this));
|
||||
this.dockStateService.getCharacteristic(this.platform.Characteristic.OccupancyDetected)
|
||||
.onGet(this.getBinFull.bind(this));
|
||||
this.findMeService.getCharacteristic(this.platform.Characteristic.On)
|
||||
.onSet(this.setFindMe.bind(this))
|
||||
.onGet(this.getFindMe.bind(this));
|
||||
this.scheduleService.getCharacteristic(this.platform.Characteristic.On)
|
||||
.onSet(this.setSchedule.bind(this))
|
||||
.onGet(this.getSchedule.bind(this));
|
||||
this.ecoService.getCharacteristic(this.platform.Characteristic.On)
|
||||
.onSet(this.setEco.bind(this))
|
||||
.onGet(this.getEco.bind(this));
|
||||
this.noGoLinesService.getCharacteristic(this.platform.Characteristic.On)
|
||||
.onSet(this.setFindMe.bind(this))
|
||||
.onGet(this.getFindMe.bind(this));
|
||||
.onSet(this.setNoGoLines.bind(this))
|
||||
.onGet(this.getNoGoLines.bind(this));
|
||||
this.extraCareService.getCharacteristic(this.platform.Characteristic.On)
|
||||
.onSet(this.setFindMe.bind(this))
|
||||
.onGet(this.getFindMe.bind(this));
|
||||
this.scheduleService.getCharacteristic(this.platform.Characteristic.On)
|
||||
.onSet(this.setFindMe.bind(this))
|
||||
.onGet(this.getFindMe.bind(this));
|
||||
this.spotCleanService.getCharacteristic(this.platform.Characteristic.On)
|
||||
.onSet(this.setSpotClean.bind(this))
|
||||
.onGet(this.getSpotClean.bind(this));
|
||||
.onSet(this.setExtraCare.bind(this))
|
||||
.onGet(this.getExtraCare.bind(this));
|
||||
|
||||
this.updateRobotPeriodically().then(r => this.log.debug(this.robot.name + " ## Periodic update started with interval: " + this.refresh));
|
||||
this.updateRobotPeriodically().then(() => {
|
||||
if (!accessory.context.options)
|
||||
{
|
||||
this.options.eco = this.robot.eco;
|
||||
this.options.noGoLines = this.robot.noGoLines;
|
||||
this.options.extraCare = this.robot.navigationMode == 2;
|
||||
this.debug(DebugType.INFO, "Options initially set to eco: " + this.options.eco + ", noGoLines: " + this.options.noGoLines + ", extraCare: " + this.options.extraCare);
|
||||
accessory.context.options = this.options;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.debug(DebugType.INFO, "Options loaded from cache eco: " + this.options.eco + ", noGoLines: " + this.options.noGoLines + ", extraCare: " + this.options.extraCare);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
getSwitchService(servicename: string)
|
||||
private getSwitchService(servicename: string)
|
||||
{
|
||||
return this.accessory.getService(servicename) || this.accessory.addService(this.platform.Service.Switch, servicename, servicename)
|
||||
}
|
||||
|
||||
getOccupancyService(servicename: string)
|
||||
private getOccupancyService(servicename: string)
|
||||
{
|
||||
return this.accessory.getService(servicename) || this.accessory.addService(this.platform.Service.OccupancySensor, servicename, servicename)
|
||||
}
|
||||
|
||||
async setClean(on: CharacteristicValue)
|
||||
async getCleanHouse(): Promise<CharacteristicValue>
|
||||
{
|
||||
// TODO debug(this.robot.name + ": " + (on ? "Enabled ".brightGreen : "Disabled".red) + " Clean " + (this.boundary ? JSON.stringify(this.boundary) : ''));
|
||||
try
|
||||
{
|
||||
await this.updateRobot();
|
||||
return this.robot.canPause && !this.isSpotCleaning;
|
||||
}
|
||||
catch (error)
|
||||
{
|
||||
this.log.error("Cannot get cleaning status: " + error);
|
||||
throw new this.platform.api.hap.HapStatusError(this.platform.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
async setCleanHouse(on: CharacteristicValue)
|
||||
{
|
||||
this.debug(DebugType.STATUS, "Set CLEAN HOUSE: " + on);
|
||||
try
|
||||
{
|
||||
await this.updateRobot();
|
||||
@ -137,20 +178,18 @@ export class NeatoVacuumRobotAccessory
|
||||
// Resume cleaning
|
||||
if (this.robot.canResume)
|
||||
{
|
||||
debug(this.robot.name + " => Resume cleaning");
|
||||
this.debug(DebugType.ACTION, "Resume cleaning");
|
||||
await this.robot.resumeCleaning();
|
||||
return;
|
||||
}
|
||||
// Start cleaning
|
||||
else if (this.robot.canStart)
|
||||
{
|
||||
await this.clean(CleanType.ALL)
|
||||
await this.clean(CleanType.HOUSE)
|
||||
}
|
||||
// Cannot start
|
||||
else
|
||||
{
|
||||
this.log.debug(this.robot.name + ": Cannot start, maybe already cleaning (expected)");
|
||||
return;
|
||||
this.debug(DebugType.INFO, "Cannot start, maybe already cleaning (expected)");
|
||||
}
|
||||
}
|
||||
// Stop
|
||||
@ -158,12 +197,12 @@ export class NeatoVacuumRobotAccessory
|
||||
{
|
||||
if (this.robot.canPause)
|
||||
{
|
||||
this.log.debug(this.robot.name + " => Pause cleaning");
|
||||
this.debug(DebugType.ACTION, "Pause cleaning");
|
||||
await this.robot.pauseCleaning();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.log.debug(this.robot.name + ": Already paused");
|
||||
this.debug(DebugType.INFO, "Already paused");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -174,34 +213,40 @@ export class NeatoVacuumRobotAccessory
|
||||
}
|
||||
}
|
||||
|
||||
async getClean(): Promise<CharacteristicValue>
|
||||
async getSpotClean(): Promise<CharacteristicValue>
|
||||
{
|
||||
try
|
||||
{
|
||||
await this.updateRobot();
|
||||
let on = this.robot.canPause && !this.spotClean;
|
||||
this.log.debug(this.robot.name + " ## Clean is: " + on);
|
||||
return on;
|
||||
return this.robot.canPause && this.isSpotCleaning;
|
||||
}
|
||||
catch (error)
|
||||
{
|
||||
this.log.warn("Cannot get cleaning status: " + error);
|
||||
this.log.error("Cannot get spot cleaning status: " + error);
|
||||
throw new this.platform.api.hap.HapStatusError(this.platform.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
async getSpotClean(): Promise<CharacteristicValue>
|
||||
{
|
||||
await this.updateRobot();
|
||||
let on = this.robot.canPause && this.spotClean;
|
||||
this.log.debug(this.robot.name + " ## Spot Clean is: " + on);
|
||||
return on;
|
||||
}
|
||||
|
||||
async setSpotClean(on: CharacteristicValue)
|
||||
{
|
||||
this.debug(DebugType.STATUS, "Set SPOT CLEAN: " + on);
|
||||
try
|
||||
{
|
||||
if (on)
|
||||
{
|
||||
await this.clean(CleanType.SPOT)
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO stop/pause
|
||||
}
|
||||
}
|
||||
catch (error)
|
||||
{
|
||||
this.log.error("Error setting spot cleaning to: " + on + ". " + error);
|
||||
throw new this.platform.api.hap.HapStatusError(this.platform.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
getGoToDock()
|
||||
{
|
||||
@ -210,6 +255,7 @@ export class NeatoVacuumRobotAccessory
|
||||
|
||||
async setGoToDock(on: CharacteristicValue)
|
||||
{
|
||||
this.debug(DebugType.STATUS, "Set GO TO DOCK: " + on);
|
||||
if (on)
|
||||
{
|
||||
await this.updateRobot();
|
||||
@ -222,7 +268,7 @@ export class NeatoVacuumRobotAccessory
|
||||
{
|
||||
if (this.robot.canPause)
|
||||
{
|
||||
this.log.debug(this.robot.name + " => Pause cleaning to go to dock");
|
||||
this.debug(DebugType.ACTION, "Pause cleaning to go to dock");
|
||||
await this.robot.pauseCleaning();
|
||||
setTimeout(async () => {
|
||||
await this.robot.sendToBase();
|
||||
@ -230,7 +276,7 @@ export class NeatoVacuumRobotAccessory
|
||||
}
|
||||
else if (this.robot.canGoToBase)
|
||||
{
|
||||
this.log.debug(this.robot.name + " => Go to dock");
|
||||
this.debug(DebugType.ACTION, "Going to dock");
|
||||
await this.robot.sendToBase();
|
||||
}
|
||||
else
|
||||
@ -240,23 +286,106 @@ export class NeatoVacuumRobotAccessory
|
||||
}
|
||||
catch (error)
|
||||
{
|
||||
this.log.warn("Error setting go to dock to: " + on + ". " + error);
|
||||
this.log.error("Error setting go to dock to: " + on + ". " + error);
|
||||
throw new this.platform.api.hap.HapStatusError(this.platform.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async getDocked(): Promise<CharacteristicValue>
|
||||
{
|
||||
try
|
||||
{
|
||||
await this.updateRobot();
|
||||
return this.robot.isDocked;
|
||||
}
|
||||
catch (error)
|
||||
{
|
||||
this.log.error("Cannot get docked status: " + error);
|
||||
throw new this.platform.api.hap.HapStatusError(this.platform.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
async getBinFull(): Promise<CharacteristicValue>
|
||||
{
|
||||
try
|
||||
{
|
||||
await this.updateRobot();
|
||||
return this.robot.isBinFull;
|
||||
}
|
||||
catch (error)
|
||||
{
|
||||
this.log.error("Cannot get bin full status: " + error);
|
||||
throw new this.platform.api.hap.HapStatusError(this.platform.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
async getSchedule(): Promise<CharacteristicValue>
|
||||
{
|
||||
try
|
||||
{
|
||||
await this.updateRobot();
|
||||
return this.robot.isScheduleEnabled;
|
||||
}
|
||||
catch (error)
|
||||
{
|
||||
this.log.error("Cannot get schedule status: " + error);
|
||||
throw new this.platform.api.hap.HapStatusError(this.platform.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
async setSchedule(on: CharacteristicValue)
|
||||
{
|
||||
this.debug(DebugType.STATUS, "Set SCHEDULE: " + on);
|
||||
try
|
||||
{
|
||||
if (on)
|
||||
{
|
||||
await this.robot.enableSchedule();
|
||||
}
|
||||
else
|
||||
{
|
||||
await this.robot.disableSchedule();
|
||||
}
|
||||
}
|
||||
catch (error)
|
||||
{
|
||||
this.log.error("Error setting schedule to: " + on + ". " + error);
|
||||
throw new this.platform.api.hap.HapStatusError(this.platform.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
getEco()
|
||||
{
|
||||
let on = this.options.eco;
|
||||
this.log.debug(this.robot.name + " ## Eco is: " + on);
|
||||
return on;
|
||||
return this.options.eco;
|
||||
}
|
||||
|
||||
setEco(on: CharacteristicValue)
|
||||
{
|
||||
this.options.eco = on;
|
||||
this.log.debug(this.robot.name + " ## Option eco set to: " + on);
|
||||
this.debug(DebugType.STATUS, "Set ECO: " + on);
|
||||
this.options.eco = <boolean>on;
|
||||
}
|
||||
|
||||
getExtraCare()
|
||||
{
|
||||
return this.options.extraCare;
|
||||
}
|
||||
|
||||
setExtraCare(on: CharacteristicValue)
|
||||
{
|
||||
this.debug(DebugType.STATUS, "Set EXTRA CARE: " + on);
|
||||
this.options.extraCare = <boolean>on;
|
||||
}
|
||||
|
||||
getNoGoLines()
|
||||
{
|
||||
return this.options.noGoLines;
|
||||
}
|
||||
|
||||
setNoGoLines(on: CharacteristicValue)
|
||||
{
|
||||
this.debug(DebugType.STATUS, "Set NOGO LINES: " + on);
|
||||
this.options.noGoLines = <boolean>on;
|
||||
}
|
||||
|
||||
getFindMe()
|
||||
@ -266,9 +395,10 @@ export class NeatoVacuumRobotAccessory
|
||||
|
||||
async setFindMe(on: CharacteristicValue)
|
||||
{
|
||||
this.debug(DebugType.STATUS, "Set FIND ME: " + on);
|
||||
if (on)
|
||||
{
|
||||
this.log.debug(this.robot.name + " => Find me")
|
||||
this.debug(DebugType.ACTION, "Find me");
|
||||
setTimeout(() => {
|
||||
this.findMeService.updateCharacteristic(this.platform.Characteristic.On, false);
|
||||
}, 1000);
|
||||
@ -279,7 +409,7 @@ export class NeatoVacuumRobotAccessory
|
||||
}
|
||||
catch (error)
|
||||
{
|
||||
this.log.warn(this.robot.name + " ## Cannot start find me. " + error);
|
||||
this.log.error(this.robot.name + " ## Cannot start find me. " + error);
|
||||
throw new this.platform.api.hap.HapStatusError(this.platform.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE);
|
||||
}
|
||||
}
|
||||
@ -287,27 +417,22 @@ export class NeatoVacuumRobotAccessory
|
||||
|
||||
async clean(cleanType: CleanType)
|
||||
{
|
||||
// Start automatic update while cleaning
|
||||
if (this.refresh === 'auto')
|
||||
{
|
||||
// Enable shorter background update while cleaning
|
||||
setTimeout(() => {
|
||||
this.updateRobotPeriodically();
|
||||
}, 60 * 1000);
|
||||
}
|
||||
|
||||
this.log.info("Start cleaning with options type: " + cleanType + ", eco: " + this.options.eco + ", noGoLines: " + this.options.noGoLines + ", extraCare: " + this.options.extraCare);
|
||||
this.log.info("[" + this.robot.name + "] > Start cleaning with options type: " + CleanType[cleanType] + ", eco: " + this.options.eco + ", noGoLines: " + this.options.noGoLines + ", extraCare: " + this.options.extraCare);
|
||||
|
||||
try
|
||||
{
|
||||
switch (cleanType)
|
||||
{
|
||||
case CleanType.ALL:
|
||||
case CleanType.HOUSE:
|
||||
await this.robot.startCleaning(this.options.eco, this.options.extraCare ? 2 : 1, this.options.noGoLines);
|
||||
this.spotClean = false;
|
||||
break;
|
||||
case CleanType.SPOT:
|
||||
await this.robot.startSpotCleaning(this.options.eco, this.options.spot.width, this.options.spot.height, this.options.spot.repeat, this.options.extraCare ? 2 : 1);
|
||||
this.spotClean = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -322,20 +447,16 @@ export class NeatoVacuumRobotAccessory
|
||||
// Data is outdated
|
||||
if (typeof (this.robot.lastUpdate) === 'undefined' || new Date().getTime() - this.robot.lastUpdate > 2000)
|
||||
{
|
||||
debug(this.robot.name + ": ++ Updating robot state");
|
||||
this.robot.lastUpdate = new Date().getTime();
|
||||
try
|
||||
{
|
||||
await this.robot.getState();
|
||||
this.robot.getState((error, result) => {
|
||||
this.isSpotCleaning = result != null && result.action == 2;
|
||||
|
||||
// Set options initially by api
|
||||
if (typeof this.options.eco == 'undefined')
|
||||
{
|
||||
this.options.eco = this.robot.eco;
|
||||
this.options.noGoLines = this.robot.noGoLines;
|
||||
this.options.extraCare = this.robot.navigationMode == 2;
|
||||
this.log.debug("Options initially set to eco: " + this.options.eco + ", noGoLines: " + this.options.noGoLines + ", extraCare: " + this.options.extraCare);
|
||||
}
|
||||
// Battery
|
||||
this.batteryService.updateCharacteristic(this.platform.Characteristic.BatteryLevel, this.robot.charge);
|
||||
this.batteryService.updateCharacteristic(this.platform.Characteristic.ChargingState, this.robot.isCharging);
|
||||
});
|
||||
}
|
||||
catch (error)
|
||||
{
|
||||
@ -347,11 +468,13 @@ export class NeatoVacuumRobotAccessory
|
||||
|
||||
async updateRobotPeriodically()
|
||||
{
|
||||
this.debug(DebugType.INFO, "Performing background update")
|
||||
|
||||
await this.updateRobot()
|
||||
await this.updateCharacteristics();
|
||||
|
||||
// Clear any other overlapping timers for this robot
|
||||
clearTimeout(this.robot.timer);
|
||||
clearTimeout(this.timer);
|
||||
|
||||
// Tell all accessories of this robot (mainAccessory and roomAccessories) that updated robot data is available
|
||||
// this.robot.mainAccessory.updated();
|
||||
@ -360,35 +483,25 @@ export class NeatoVacuumRobotAccessory
|
||||
// });
|
||||
|
||||
// Periodic refresh interval set in config
|
||||
if (this.refresh !== 'auto' && this.refresh !== 0)
|
||||
let interval;
|
||||
if (this.robot.canPause)
|
||||
{
|
||||
this.log.debug(this.robot.name + " ## Next background update in " + this.refresh + " seconds");
|
||||
this.robot.timer = setTimeout(this.updateRobotPeriodically.bind(this), this.refresh * 1000);
|
||||
interval = 1;
|
||||
}
|
||||
// Auto refresh set in config (cleaning)
|
||||
else if (this.refresh === 'auto' && !this.robot.canPause)
|
||||
{
|
||||
this.log.debug(this.robot.name + " ## Next background update in 30 minutes (auto mode)");
|
||||
this.robot.timer = setTimeout(this.updateRobotPeriodically.bind(this), 30 * 60 * 1000);
|
||||
}
|
||||
// Auto refresh set in config (cleaning)
|
||||
else if (this.refresh === 'auto' && this.robot.canPause)
|
||||
{
|
||||
this.log.debug(this.robot.name + " ## Next background update in 60 seconds while cleaning (auto mode)");
|
||||
this.robot.timer = setTimeout(this.updateRobotPeriodically.bind(this), 60 * 1000);
|
||||
}
|
||||
// No refresh
|
||||
else
|
||||
{
|
||||
debug(this.robot.name + " ## Stopped background updates");
|
||||
interval = this.refresh == "auto" ? 30 : this.refresh;
|
||||
}
|
||||
|
||||
this.debug(DebugType.INFO, "Background update done. Next update in " + interval + " minute(s)" + ((this.robot.canPause) ? ", robot is currently cleaning" : ""));
|
||||
this.timer = setTimeout(this.updateRobotPeriodically.bind(this), interval * 60 * 1000);
|
||||
}
|
||||
|
||||
async updateCharacteristics()
|
||||
{
|
||||
// Update Switches
|
||||
// Clean
|
||||
this.cleanService.updateCharacteristic(this.platform.Characteristic.On, await this.getClean());
|
||||
this.cleanService.updateCharacteristic(this.platform.Characteristic.On, await this.getCleanHouse());
|
||||
|
||||
// Spot Clean
|
||||
this.spotCleanService.updateCharacteristic(this.platform.Characteristic.On, await this.getSpotClean());
|
||||
@ -396,17 +509,51 @@ export class NeatoVacuumRobotAccessory
|
||||
// Go To Dock
|
||||
this.goToDockService.updateCharacteristic(this.platform.Characteristic.On, await this.getGoToDock());
|
||||
|
||||
// // Schedule
|
||||
// this.scheduleService.updateCharacteristic(this.platform.Characteristic.On, await this.getSchedule());
|
||||
// Docked
|
||||
this.dockStateService.updateCharacteristic(this.platform.Characteristic.OccupancyDetected, await this.getDocked());
|
||||
|
||||
// Battery
|
||||
this.batteryService.updateCharacteristic(this.platform.Characteristic.BatteryLevel, this.robot.charge);
|
||||
this.batteryService.updateCharacteristic(this.platform.Characteristic.ChargingState, this.robot.isCharging);
|
||||
// Bin full
|
||||
this.binFullService.updateCharacteristic(this.platform.Characteristic.OccupancyDetected, await this.getBinFull());
|
||||
|
||||
// Schedule
|
||||
this.scheduleService.updateCharacteristic(this.platform.Characteristic.On, await this.getSchedule());
|
||||
|
||||
// Eco
|
||||
this.ecoService.updateCharacteristic(this.platform.Characteristic.On, await this.getEco());
|
||||
|
||||
// Extra Care
|
||||
this.extraCareService.updateCharacteristic(this.platform.Characteristic.On, await this.getExtraCare());
|
||||
|
||||
// NoGo Lines
|
||||
this.noGoLinesService.updateCharacteristic(this.platform.Characteristic.On, await this.getNoGoLines());
|
||||
}
|
||||
|
||||
debug(debugType: DebugType, message: String)
|
||||
{
|
||||
switch (debugType)
|
||||
{
|
||||
case DebugType.ACTION:
|
||||
this.log.debug("[" + this.robot.name + "] > " + message);
|
||||
break;
|
||||
case DebugType.STATUS:
|
||||
this.log.debug("[" + this.robot.name + "] " + message);
|
||||
break;
|
||||
case DebugType.INFO:
|
||||
this.log.debug("[" + this.robot.name + "] " + message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum CleanType
|
||||
{
|
||||
ALL,
|
||||
HOUSE,
|
||||
SPOT
|
||||
}
|
||||
|
||||
enum DebugType
|
||||
{
|
||||
ACTION,
|
||||
STATUS,
|
||||
INFO
|
||||
}
|
@ -1,11 +1,8 @@
|
||||
import {API, Characteristic, DynamicPlatformPlugin, Logger, PlatformAccessory, PlatformConfig, Service} from 'homebridge';
|
||||
import Debug from "debug";
|
||||
import NeatoApi from "node-botvac";
|
||||
import {PLATFORM_NAME, PLUGIN_NAME} from './settings';
|
||||
import {NeatoVacuumRobotAccessory} from './accessories/NeatoVacuumRobot';
|
||||
|
||||
const debug = Debug("homebridge-neato");
|
||||
|
||||
/**
|
||||
* HomebridgePlatform
|
||||
* This class is the main constructor for your plugin, this is where you should
|
||||
@ -24,10 +21,7 @@ export class HomebridgeNeatoPlatform implements DynamicPlatformPlugin
|
||||
public readonly config: PlatformConfig,
|
||||
public readonly api: API)
|
||||
{
|
||||
this.log.debug('Finished initializing platform:', this.config.platform);
|
||||
|
||||
this.api.on('didFinishLaunching', () => {
|
||||
log.debug('Executed didFinishLaunching callback');
|
||||
this.discoverRobots();
|
||||
});
|
||||
}
|
||||
@ -38,15 +32,12 @@ export class HomebridgeNeatoPlatform implements DynamicPlatformPlugin
|
||||
*/
|
||||
configureAccessory(accessory: PlatformAccessory)
|
||||
{
|
||||
this.log.info('Loading accessory from cache:', accessory.displayName);
|
||||
|
||||
// add the restored accessory to the accessories cache so we can track if it has already been registered
|
||||
this.robotAccessories.push(accessory);
|
||||
}
|
||||
|
||||
discoverRobots()
|
||||
{
|
||||
debug("Discovering new robots");
|
||||
let client = new NeatoApi.Client();
|
||||
|
||||
try
|
||||
@ -76,16 +67,12 @@ export class HomebridgeNeatoPlatform implements DynamicPlatformPlugin
|
||||
return;
|
||||
}
|
||||
|
||||
debug("Found " + robots.length + " robots");
|
||||
let loadedRobots = 0;
|
||||
this.log.debug("Neato account has " + robots.length + " robot " + (robots.length == 1 ? "" : "s"));
|
||||
|
||||
for (let robot of robots)
|
||||
{
|
||||
// Get additional information for the robot
|
||||
robot.getState((error, state) => {
|
||||
this.log.debug("Got state for robot: " + robot.name);
|
||||
robot.meta = state.meta;
|
||||
|
||||
if (error)
|
||||
{
|
||||
this.log.error("Error getting robot meta information: " + error + ": " + state);
|
||||
@ -94,32 +81,25 @@ export class HomebridgeNeatoPlatform implements DynamicPlatformPlugin
|
||||
|
||||
try
|
||||
{
|
||||
robot.meta = state.meta;
|
||||
|
||||
const uuid = this.api.hap.uuid.generate(robot._serial);
|
||||
const existingAccessory = this.robotAccessories.find(accessory => accessory.UUID === uuid);
|
||||
|
||||
// the accessory already exists
|
||||
if (existingAccessory)
|
||||
{
|
||||
// the accessory already exists
|
||||
this.log.info('Restoring existing accessory from cache:', existingAccessory.displayName);
|
||||
existingAccessory.context.robot = robot;
|
||||
this.log.info("[" + robot.name + "] Robot loaded from cache");
|
||||
// TODO update maps
|
||||
|
||||
// if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
|
||||
// existingAccessory.context.device = device;
|
||||
// this.api.updatePlatformAccessories([existingAccessory]);
|
||||
existingAccessory.context.robot = robot;
|
||||
this.api.updatePlatformAccessories([existingAccessory]);
|
||||
|
||||
// create the accessory handler for the restored accessory
|
||||
// this is imported from `platformAccessory.ts`
|
||||
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
|
||||
// this.api.unregisterPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [existingAccessory]);
|
||||
// this.log.info('Removing existing accessory from cache:', existingAccessory.displayName);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.log.info('Adding new accessory: ', robot.name);
|
||||
this.log.info("[" + robot.name + "] Robot created");
|
||||
const accessory = new this.api.platformAccessory(robot.name, uuid);
|
||||
|
||||
accessory.context.robot = robot;
|
||||
|
18
src/models/options.ts
Normal file
18
src/models/options.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import {HomebridgeNeatoPlatform} from "../homebridgeNeatoPlatform";
|
||||
import {PlatformAccessory, PlatformConfig} from "homebridge";
|
||||
|
||||
export class Options
|
||||
{
|
||||
public eco: boolean;
|
||||
public extraCare: boolean;
|
||||
public noGoLines: boolean;
|
||||
public spot: any;
|
||||
|
||||
constructor()
|
||||
{
|
||||
this.eco = false;
|
||||
this.extraCare = false;
|
||||
this.noGoLines = false;
|
||||
this.spot = {};
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user