WIP dynamic platform

This commit is contained in:
Arne Blumentritt
2021-04-28 20:07:39 +02:00
parent 6f1f078ba4
commit 4a97891dfd
7 changed files with 318 additions and 314 deletions

View File

@@ -1,141 +1,187 @@
import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
import { HomebridgeNeatoPlatform } from '../homebridgeNeatoPlatform';
import {CharacteristicValue, PlatformAccessory, 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
* Each accessory may expose multiple services of different service types.
*/
export class NeatoVacuumRobotAccessory {
private service: Service;
export class NeatoVacuumRobotAccessory
{
private cleanService: Service;
private robot: any;
// private goToDockService: Service;
// private dockStateService: Service;
// private ecoService: Service;
// private noGoLinesService: Service;
// private extraCareService: Service;
// private scheduleService: Service;
// private findMeService: Service;
// private spotCleanService: Service;
/**
* These are just used to create a working example
* You should implement your own code to track the state of your accessory
*/
private exampleStates = {
On: false,
Brightness: 100,
};
/**
* These are just used to create a working example
* You should implement your own code to track the state of your accessory
*/
constructor(
private readonly platform: HomebridgeNeatoPlatform,
private readonly accessory: PlatformAccessory,
) {
constructor(
private readonly platform: HomebridgeNeatoPlatform,
private readonly accessory: PlatformAccessory,
private readonly isNew: Boolean)
{
this.robot = accessory.context.robot;
// set accessory information
this.accessory.getService(this.platform.Service.AccessoryInformation)!
.setCharacteristic(this.platform.Characteristic.Manufacturer, "Neato Robotics")
.setCharacteristic(this.platform.Characteristic.Model, this.robot.meta.modelName)
.setCharacteristic(this.platform.Characteristic.SerialNumber, this.robot._serial)
.setCharacteristic(this.platform.Characteristic.FirmwareRevision, this.robot.meta.firmware)
.setCharacteristic(this.platform.Characteristic.Name, this.robot.name);
// set accessory information
this.accessory.getService(this.platform.Service.AccessoryInformation)!
.setCharacteristic(this.platform.Characteristic.Manufacturer, 'Default-Manufacturer')
.setCharacteristic(this.platform.Characteristic.Model, 'Default-Model')
.setCharacteristic(this.platform.Characteristic.SerialNumber, 'Default-Serial');
// get the LightBulb service if it exists, otherwise create a new LightBulb service
// you can create multiple services for each accessory
this.service = this.accessory.getService(this.platform.Service.Lightbulb) || this.accessory.addService(this.platform.Service.Lightbulb);
let cleanServiceName = robot.name + " Clean";
this.cleanService = this.accessory.getService(cleanServiceName) || this.accessory.addService(this.platform.Service.Switch, cleanServiceName, "CLEAN");
this.cleanService.getCharacteristic(this.platform.Characteristic.On)
.onSet(this.setClean.bind(this))
.onGet(this.getClean.bind(this));
// set the service name, this is what is displayed as the default name on the Home app
// in this example we are using the name we stored in the `accessory.context` in the `discoverDevices` method.
this.service.setCharacteristic(this.platform.Characteristic.Name, accessory.context.device.exampleDisplayName);
// /**
// * Updating characteristics values asynchronously.
// *
// * Example showing how to update the state of a Characteristic asynchronously instead
// * of using the `on('get')` handlers.
// * Here we change update the motion sensor trigger states on and off every 10 seconds
// * the `updateCharacteristic` method.
// *
// */
// let motionDetected = false;
// setInterval(() => {
// // EXAMPLE - inverse the trigger
// motionDetected = !motionDetected;
//
// // push the new value to HomeKit
// motionSensorOneService.updateCharacteristic(this.platform.Characteristic.MotionDetected, motionDetected);
// motionSensorTwoService.updateCharacteristic(this.platform.Characteristic.MotionDetected, !motionDetected);
//
// this.platform.log.debug('Triggering motionSensorOneService:', motionDetected);
// this.platform.log.debug('Triggering motionSensorTwoService:', !motionDetected);
// }, 10000);
}
// each service must implement at-minimum the "required characteristics" for the given service type
// see https://developers.homebridge.io/#/service/Lightbulb
// register handlers for the On/Off Characteristic
this.service.getCharacteristic(this.platform.Characteristic.On)
.onSet(this.setOn.bind(this)) // SET - bind to the `setOn` method below
.onGet(this.getOn.bind(this)); // GET - bind to the `getOn` method below
async setClean(on: CharacteristicValue)
{
// TODO debug(this.robot.name + ": " + (on ? "Enabled ".brightGreen : "Disabled".red) + " Clean " + (this.boundary ? JSON.stringify(this.boundary) : ''));
this.platform.updateRobot(this.robot._serial, (error, result) =>
{
// Start
if (on)
{
// No room given or same room
if (this.boundary == null || this.robot.cleaningBoundaryId === this.boundary.id)
{
// Resume cleaning
if (this.robot.canResume)
{
debug(this.name + ": ## Resume cleaning");
this.robot.resumeCleaning((error) =>
{
callback(error);
});
}
// Start cleaning
else if (this.robot.canStart)
{
this.clean(callback);
}
// Cannot start
else
{
debug(this.name + ": Cannot start, maybe already cleaning (expected)");
callback();
}
}
// Different room given
else
{
// Return to dock
if (this.robot.canPause || this.robot.canResume)
{
debug(this.name + ": ## Returning to dock to start cleaning of new room");
this.setGoToDock(true, (error, result) =>
{
this.nextRoom = this.boundary.id;
callback();
});
}
// Start new cleaning of new room
else
{
debug(this.name + ": ## Start cleaning of new room");
this.clean(callback);
}
}
}
// Stop
else
{
if (this.robot.canPause)
{
debug(this.name + ": ## Pause cleaning");
this.robot.pauseCleaning((error) =>
{
callback(error);
});
}
else
{
debug(this.name + ": Already paused");
callback();
}
}
});
}
async getClean(): Promise<CharacteristicValue>
{
// implement your own code to check if the device is on
const isOn = this.exampleStates.On;
// register handlers for the Brightness Characteristic
this.service.getCharacteristic(this.platform.Characteristic.Brightness)
.onSet(this.setBrightness.bind(this)); // SET - bind to the 'setBrightness` method below
this.platform.log.debug('Get Characteristic On ->', isOn);
/**
* Creating multiple services of the same type.
*
* To avoid "Cannot add a Service with the same UUID another Service without also defining a unique 'subtype' property." error,
* when creating multiple services of the same type, you need to use the following syntax to specify a name and subtype id:
* this.accessory.getService('NAME') || this.accessory.addService(this.platform.Service.Lightbulb, 'NAME', 'USER_DEFINED_SUBTYPE_ID');
*
* The USER_DEFINED_SUBTYPE must be unique to the platform accessory (if you platform exposes multiple accessories, each accessory
* can use the same sub type id.)
*/
// if you need to return an error to show the device as "Not Responding" in the Home app:
// throw new this.platform.api.hap.HapStatusError(this.platform.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE);
// Example: add two "motion sensor" services to the accessory
const motionSensorOneService = this.accessory.getService('Motion Sensor One Name') ||
this.accessory.addService(this.platform.Service.MotionSensor, 'Motion Sensor One Name', 'YourUniqueIdentifier-1');
const motionSensorTwoService = this.accessory.getService('Motion Sensor Two Name') ||
this.accessory.addService(this.platform.Service.MotionSensor, 'Motion Sensor Two Name', 'YourUniqueIdentifier-2');
/**
* Updating characteristics values asynchronously.
*
* Example showing how to update the state of a Characteristic asynchronously instead
* of using the `on('get')` handlers.
* Here we change update the motion sensor trigger states on and off every 10 seconds
* the `updateCharacteristic` method.
*
*/
let motionDetected = false;
setInterval(() => {
// EXAMPLE - inverse the trigger
motionDetected = !motionDetected;
// push the new value to HomeKit
motionSensorOneService.updateCharacteristic(this.platform.Characteristic.MotionDetected, motionDetected);
motionSensorTwoService.updateCharacteristic(this.platform.Characteristic.MotionDetected, !motionDetected);
this.platform.log.debug('Triggering motionSensorOneService:', motionDetected);
this.platform.log.debug('Triggering motionSensorTwoService:', !motionDetected);
}, 10000);
}
/**
* Handle "SET" requests from HomeKit
* These are sent when the user changes the state of an accessory, for example, turning on a Light bulb.
*/
async setOn(value: CharacteristicValue) {
// implement your own code to turn your device on/off
this.exampleStates.On = value as boolean;
this.platform.log.debug('Set Characteristic On ->', value);
}
/**
* Handle the "GET" requests from HomeKit
* These are sent when HomeKit wants to know the current state of the accessory, for example, checking if a Light bulb is on.
*
* GET requests should return as fast as possbile. A long delay here will result in
* HomeKit being unresponsive and a bad user experience in general.
*
* If your device takes time to respond you should update the status of your device
* asynchronously instead using the `updateCharacteristic` method instead.
* @example
* this.service.updateCharacteristic(this.platform.Characteristic.On, true)
*/
async getOn(): Promise<CharacteristicValue> {
// implement your own code to check if the device is on
const isOn = this.exampleStates.On;
this.platform.log.debug('Get Characteristic On ->', isOn);
// if you need to return an error to show the device as "Not Responding" in the Home app:
// throw new this.platform.api.hap.HapStatusError(this.platform.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE);
return isOn;
}
/**
* Handle "SET" requests from HomeKit
* These are sent when the user changes the state of an accessory, for example, changing the Brightness
*/
async setBrightness(value: CharacteristicValue) {
// implement your own code to set the brightness
this.exampleStates.Brightness = value as number;
this.platform.log.debug('Set Characteristic Brightness -> ', value);
}
return isOn;
}
// /**
// * Handle the "GET" requests from HomeKit
// * These are sent when HomeKit wants to know the current state of the accessory, for example, checking if a Light bulb is on.
// *
// * GET requests should return as fast as possbile. A long delay here will result in
// * HomeKit being unresponsive and a bad user experience in general.
// *
// * If your device takes time to respond you should update the status of your device
// * asynchronously instead using the `updateCharacteristic` method instead.
//
// * @example
// * this.service.updateCharacteristic(this.platform.Characteristic.On, true)
// */
// async getOn(): Promise<CharacteristicValue>
// {
// // implement your own code to check if the device is on
// const isOn = this.exampleStates.On;
//
// this.platform.log.debug('Get Characteristic On ->', isOn);
//
// // if you need to return an error to show the device as "Not Responding" in the Home app:
// // throw new this.platform.api.hap.HapStatusError(this.platform.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE);
//
// return isOn;
// }
}