restructure robot for localization
This commit is contained in:
parent
109ebbf162
commit
2d35e8b814
@ -1,10 +1,13 @@
|
|||||||
import {CharacteristicValue, Logger, PlatformAccessory, PlatformAccessoryEvent, PlatformConfig, Service} from 'homebridge';
|
import {CharacteristicValue, Logger, PlatformAccessory, PlatformAccessoryEvent, PlatformConfig, Service, WithUUID, CharacteristicGetHandler, CharacteristicSetHandler, Characteristic} from 'homebridge';
|
||||||
import {HomebridgeNeatoPlatform} from '../homebridgeNeatoPlatform';
|
import {HomebridgeNeatoPlatform} from '../homebridgeNeatoPlatform';
|
||||||
import spotRepeat from '../characteristics/spotRepeat';
|
import spotRepeat from '../characteristics/spotRepeat';
|
||||||
import spotWidth from '../characteristics/spotWidth';
|
import spotWidth from '../characteristics/spotWidth';
|
||||||
import spotHeight from '../characteristics/spotHeight';
|
import spotHeight from '../characteristics/spotHeight';
|
||||||
import {Options} from '../models/options';
|
import {Options} from '../models/options';
|
||||||
import {CharacteristicGetHandler, CharacteristicSetHandler} from "hap-nodejs/dist/lib/Characteristic";
|
import { RobotService, CleanType } from '../models/services';
|
||||||
|
import { ALL_SERVICES, BACKGROUND_INTERVAL, LOCALE, PREFIX } from '../defaults';
|
||||||
|
import { availableLocales, localize } from '../localization';
|
||||||
|
import { CharacteristicHandler } from '../characteristics/characteristicHandler';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Platform Accessory
|
* Platform Accessory
|
||||||
@ -15,17 +18,17 @@ export class NeatoVacuumRobotAccessory
|
|||||||
{
|
{
|
||||||
// Homebridge
|
// Homebridge
|
||||||
private log: Logger;
|
private log: Logger;
|
||||||
private batteryService: Service;
|
private readonly batteryService?: Service;
|
||||||
private readonly cleanService: Service | null;
|
private readonly cleanService?: Service;
|
||||||
private readonly findMeService: Service | null;
|
private readonly findMeService?: Service;
|
||||||
private readonly goToDockService: Service | null;
|
private readonly goToDockService?: Service;
|
||||||
private readonly dockStateService: Service | null;
|
private readonly dockStateService?: Service;
|
||||||
private readonly binFullService: Service | null;
|
private readonly binFullService?: Service;
|
||||||
private readonly ecoService: Service | null;
|
private readonly ecoService?: Service;
|
||||||
private readonly noGoLinesService: Service | null;
|
private readonly noGoLinesService?: Service;
|
||||||
private readonly extraCareService: Service | null;
|
private readonly extraCareService?: Service;
|
||||||
private readonly scheduleService: Service | null;
|
private readonly scheduleService?: Service;
|
||||||
private readonly spotCleanService: Service | null;
|
private readonly spotCleanService?: Service;
|
||||||
private spotPlusFeatures: boolean;
|
private spotPlusFeatures: boolean;
|
||||||
|
|
||||||
// Context
|
// Context
|
||||||
@ -34,8 +37,9 @@ export class NeatoVacuumRobotAccessory
|
|||||||
|
|
||||||
// Config
|
// Config
|
||||||
private readonly backgroundUpdateInterval: number;
|
private readonly backgroundUpdateInterval: number;
|
||||||
|
private readonly locale: availableLocales;
|
||||||
private readonly prefix: boolean;
|
private readonly prefix: boolean;
|
||||||
private readonly availableServices: string[];
|
private readonly availableServices: Set<RobotService>;
|
||||||
|
|
||||||
// Transient
|
// Transient
|
||||||
private isSpotCleaning: boolean;
|
private isSpotCleaning: boolean;
|
||||||
@ -59,7 +63,8 @@ export class NeatoVacuumRobotAccessory
|
|||||||
|
|
||||||
this.backgroundUpdateInterval = NeatoVacuumRobotAccessory.parseBackgroundUpdateInterval(this.config['backgroundUpdate']);
|
this.backgroundUpdateInterval = NeatoVacuumRobotAccessory.parseBackgroundUpdateInterval(this.config['backgroundUpdate']);
|
||||||
this.prefix = this.config['prefix'] || PREFIX;
|
this.prefix = this.config['prefix'] || PREFIX;
|
||||||
this.availableServices = this.config['services'] || SERVICES;
|
this.locale = this.config['language'] || LOCALE;
|
||||||
|
this.availableServices = new Set(this.config['services']) || ALL_SERVICES;
|
||||||
|
|
||||||
this.isSpotCleaning = false;
|
this.isSpotCleaning = false;
|
||||||
|
|
||||||
@ -87,18 +92,77 @@ export class NeatoVacuumRobotAccessory
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
[
|
||||||
|
this.getClean,
|
||||||
|
this.setClean,
|
||||||
|
this.getSpotClean,
|
||||||
|
this.setSpotClean,
|
||||||
|
this.getGoToDock,
|
||||||
|
this.setGoToDock,
|
||||||
|
this.getDocked,
|
||||||
|
this.getBinFull,
|
||||||
|
this.getFindMe,
|
||||||
|
this.setFindMe,
|
||||||
|
this.getSchedule,
|
||||||
|
this.setSchedule,
|
||||||
|
this.getEco,
|
||||||
|
this.setEco,
|
||||||
|
this.getNoGoLines,
|
||||||
|
this.setNoGoLines,
|
||||||
|
this.getExtraCare,
|
||||||
|
this.setExtraCare
|
||||||
|
].forEach((f)=>f.bind(this))
|
||||||
|
|
||||||
// Services
|
// Services
|
||||||
this.cleanService = this.getSwitchService(RobotService.CLEAN_HOUSE, this.getCleanHouse.bind(this), this.setCleanHouse.bind(this));
|
this.cleanService = this.registerService(RobotService.CLEAN, this.platform.Service.Switch, [{
|
||||||
this.spotCleanService = this.getSwitchService(RobotService.CLEAN_SPOT, this.getSpotClean.bind(this), this.setSpotClean.bind(this));
|
characteristic: this.platform.Characteristic.On,
|
||||||
this.goToDockService = this.getSwitchService(RobotService.GO_TO_DOCK, this.getGoToDock.bind(this), this.setGoToDock.bind(this));
|
getCharacteristicHandler: this.getClean,
|
||||||
this.dockStateService = this.getOccupancyService(RobotService.DOCKED, this.getDocked.bind(this))
|
setCharacteristicHandler: this.setClean
|
||||||
this.binFullService = this.getOccupancyService(RobotService.BIN_FULL, this.getBinFull.bind(this))
|
}]);
|
||||||
this.findMeService = this.getSwitchService(RobotService.FIND_ME, this.getFindMe.bind(this), this.setFindMe.bind(this));
|
this.spotCleanService = this.registerService(RobotService.CLEAN_SPOT, this.platform.Service.Switch, [{
|
||||||
this.scheduleService = this.getSwitchService(RobotService.SCHEDULE, this.getSchedule.bind(this), this.setSchedule.bind(this));
|
characteristic: this.platform.Characteristic.On,
|
||||||
this.ecoService = this.getSwitchService(RobotService.ECO, this.getEco.bind(this), this.setEco.bind(this));
|
getCharacteristicHandler: this.getSpotClean,
|
||||||
this.noGoLinesService = this.getSwitchService(RobotService.NOGO_LINES, this.getNoGoLines.bind(this), this.setNoGoLines.bind(this));
|
setCharacteristicHandler: this.setSpotClean
|
||||||
this.extraCareService = this.getSwitchService(RobotService.EXTRA_CARE, this.getExtraCare.bind(this), this.setExtraCare.bind(this));
|
}]);
|
||||||
this.batteryService = this.accessory.getService(this.platform.Service.Battery) || this.accessory.addService(this.platform.Service.Battery)
|
this.goToDockService = this.registerService(RobotService.GO_TO_DOCK, this.platform.Service.Switch, [{
|
||||||
|
characteristic: this.platform.Characteristic.On,
|
||||||
|
getCharacteristicHandler: this.getGoToDock,
|
||||||
|
setCharacteristicHandler: this.setGoToDock
|
||||||
|
}]);
|
||||||
|
this.dockStateService = this.registerService(RobotService.DOCKED, this.platform.Service.OccupancySensor, [{
|
||||||
|
characteristic: this.platform.Characteristic.OccupancyDetected.OccupancyDetected,
|
||||||
|
getCharacteristicHandler: this.getDocked,
|
||||||
|
}]);
|
||||||
|
this.binFullService = this.registerService(RobotService.BIN_FULL, this.platform.Service.OccupancySensor, [{
|
||||||
|
characteristic: this.platform.Characteristic.OccupancyDetected.OccupancyDetected,
|
||||||
|
getCharacteristicHandler: this.getBinFull,
|
||||||
|
}]);
|
||||||
|
this.findMeService = this.registerService(RobotService.FIND_ME, this.platform.Service.Switch, [{
|
||||||
|
characteristic: this.platform.Characteristic.On,
|
||||||
|
getCharacteristicHandler: this.getFindMe,
|
||||||
|
setCharacteristicHandler: this.setFindMe
|
||||||
|
}]);
|
||||||
|
this.scheduleService = this.registerService(RobotService.SCHEDULE, this.platform.Service.Switch, [{
|
||||||
|
characteristic: this.platform.Characteristic.On,
|
||||||
|
getCharacteristicHandler: this.getSchedule,
|
||||||
|
setCharacteristicHandler: this.setSchedule
|
||||||
|
}]);
|
||||||
|
this.ecoService = this.registerService(RobotService.ECO, this.platform.Service.Switch, [{
|
||||||
|
characteristic: this.platform.Characteristic.On,
|
||||||
|
getCharacteristicHandler: this.getEco,
|
||||||
|
setCharacteristicHandler: this.setEco
|
||||||
|
}]);
|
||||||
|
this.noGoLinesService = this.registerService(RobotService.NOGO_LINES, this.platform.Service.Switch, [{
|
||||||
|
characteristic: this.platform.Characteristic.On,
|
||||||
|
getCharacteristicHandler: this.getNoGoLines,
|
||||||
|
setCharacteristicHandler: this.setNoGoLines
|
||||||
|
}]);
|
||||||
|
this.extraCareService = this.registerService(RobotService.EXTRA_CARE, this.platform.Service.Switch, [{
|
||||||
|
characteristic: this.platform.Characteristic.On,
|
||||||
|
getCharacteristicHandler: this.getExtraCare,
|
||||||
|
setCharacteristicHandler: this.setExtraCare
|
||||||
|
}]);
|
||||||
|
this.batteryService = this.registerService(RobotService.BATTERY, this.platform.Service.Battery);
|
||||||
|
|
||||||
// This should be the main switch if the accessory is grouped in homekit
|
// This should be the main switch if the accessory is grouped in homekit
|
||||||
if (this.cleanService)
|
if (this.cleanService)
|
||||||
@ -155,45 +219,39 @@ export class NeatoVacuumRobotAccessory
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private getSwitchService(serviceName: string, getHandler: CharacteristicGetHandler, setHandler: CharacteristicSetHandler)
|
private registerService(
|
||||||
|
serviceName: RobotService,
|
||||||
|
serviceType: WithUUID<typeof Service>,
|
||||||
|
characteristicHandlers: CharacteristicHandler[] = []
|
||||||
|
) : Service | undefined
|
||||||
{
|
{
|
||||||
let displayName = this.prefix ? this.robot.name + serviceName : serviceName;
|
const displayName = (this.prefix ? (this.robot.name + " ") : "") + localize(serviceName, this.locale);
|
||||||
if (this.availableServices.includes(serviceName))
|
|
||||||
{
|
// query existing service by type and subtype
|
||||||
let service = this.accessory.getService(displayName) || this.accessory.addService(this.platform.Service.Switch, displayName, serviceName);
|
const existingService = this.accessory.getServiceById(serviceType, serviceName)
|
||||||
service.getCharacteristic(this.platform.Characteristic.On)
|
|
||||||
.onGet(getHandler)
|
if (this.availableServices.has(serviceName))
|
||||||
.onSet(setHandler);
|
{
|
||||||
return service;
|
var service : Service
|
||||||
|
if (existingService && existingService.displayName === displayName) {
|
||||||
|
service = existingService
|
||||||
|
} else {
|
||||||
|
if (existingService) {this.accessory.removeService(existingService);} // delete to reset display name in case of locale or prefix change
|
||||||
|
service = this.accessory.addService(serviceType, displayName, serviceName);
|
||||||
|
}
|
||||||
|
characteristicHandlers.forEach(ch => {
|
||||||
|
var char = service.getCharacteristic(ch.characteristic)
|
||||||
|
if (ch.getCharacteristicHandler) {char.onGet(ch.getCharacteristicHandler)}
|
||||||
|
if (ch.setCharacteristicHandler) {char.onSet(ch.setCharacteristicHandler)}
|
||||||
|
});
|
||||||
|
return service
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (this.accessory.getService(displayName))
|
if (existingService)
|
||||||
{
|
{
|
||||||
this.accessory.removeService(<Service>this.accessory.getService(displayName));
|
this.accessory.removeService(existingService);
|
||||||
}
|
}
|
||||||
return null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private getOccupancyService(serviceName: string, getHandler: CharacteristicGetHandler)
|
|
||||||
{
|
|
||||||
let displayName = this.prefix ? this.robot.name + serviceName : serviceName;
|
|
||||||
|
|
||||||
if (this.availableServices.includes(serviceName))
|
|
||||||
{
|
|
||||||
let service = this.accessory.getService(displayName) || this.accessory.addService(this.platform.Service.OccupancySensor, displayName, serviceName);
|
|
||||||
service.getCharacteristic(this.platform.Characteristic.OccupancyDetected.OccupancyDetected)
|
|
||||||
.onGet(getHandler);
|
|
||||||
return service;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (this.accessory.getService(displayName))
|
|
||||||
{
|
|
||||||
this.accessory.removeService(<Service>this.accessory.getService(displayName));
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,7 +266,7 @@ export class NeatoVacuumRobotAccessory
|
|||||||
return backgroundUpdateInterval;
|
return backgroundUpdateInterval;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getCleanHouse(): Promise<CharacteristicValue>
|
async getClean(): Promise<CharacteristicValue>
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -222,7 +280,7 @@ export class NeatoVacuumRobotAccessory
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async setCleanHouse(on: CharacteristicValue)
|
async setClean(on: CharacteristicValue)
|
||||||
{
|
{
|
||||||
this.debug(DebugType.STATUS, "Set CLEAN HOUSE: " + on);
|
this.debug(DebugType.STATUS, "Set CLEAN HOUSE: " + on);
|
||||||
try
|
try
|
||||||
@ -552,8 +610,8 @@ export class NeatoVacuumRobotAccessory
|
|||||||
this.isSpotCleaning = result != null && result.action == 2;
|
this.isSpotCleaning = result != null && result.action == 2;
|
||||||
|
|
||||||
// Battery
|
// Battery
|
||||||
this.batteryService.updateCharacteristic(this.platform.Characteristic.BatteryLevel, this.robot.charge);
|
this.batteryService?.updateCharacteristic(this.platform.Characteristic.BatteryLevel, this.robot.charge);
|
||||||
this.batteryService.updateCharacteristic(this.platform.Characteristic.ChargingState, this.robot.isCharging);
|
this.batteryService?.updateCharacteristic(this.platform.Characteristic.ChargingState, this.robot.isCharging);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
catch (error)
|
catch (error)
|
||||||
@ -599,7 +657,7 @@ export class NeatoVacuumRobotAccessory
|
|||||||
{
|
{
|
||||||
if (this.cleanService)
|
if (this.cleanService)
|
||||||
{
|
{
|
||||||
this.cleanService.updateCharacteristic(this.platform.Characteristic.On, await this.getCleanHouse());
|
this.cleanService.updateCharacteristic(this.platform.Characteristic.On, await this.getClean());
|
||||||
}
|
}
|
||||||
if (this.spotCleanService)
|
if (this.spotCleanService)
|
||||||
{
|
{
|
||||||
@ -640,33 +698,10 @@ export class NeatoVacuumRobotAccessory
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum CleanType
|
|
||||||
{
|
|
||||||
ALL,
|
|
||||||
SPOT
|
|
||||||
}
|
|
||||||
|
|
||||||
enum DebugType
|
enum DebugType
|
||||||
{
|
{
|
||||||
ACTION,
|
ACTION,
|
||||||
STATUS,
|
STATUS,
|
||||||
INFO
|
INFO
|
||||||
}
|
}
|
||||||
|
|
||||||
enum RobotService
|
|
||||||
{
|
|
||||||
CLEAN_HOUSE = "Clean house",
|
|
||||||
CLEAN_SPOT = "Clean spot",
|
|
||||||
GO_TO_DOCK = "Go to dock",
|
|
||||||
DOCKED = "Docked sensor",
|
|
||||||
BIN_FULL = "Bin full sensor",
|
|
||||||
FIND_ME = "Find me",
|
|
||||||
SCHEDULE = "Schedule",
|
|
||||||
ECO = "Eco",
|
|
||||||
NOGO_LINES = "Nogo lines",
|
|
||||||
EXTRA_CARE = "Extra care"
|
|
||||||
}
|
|
||||||
|
|
||||||
const BACKGROUND_INTERVAL = 30;
|
|
||||||
const PREFIX = false;
|
|
||||||
const SERVICES = Object.values(RobotService);
|
|
Loading…
Reference in New Issue
Block a user