Update to use homebridge types

This commit is contained in:
watsonb8
2020-12-11 21:59:29 -05:00
parent c28de00928
commit 38ffdec2db
15 changed files with 1101 additions and 1509 deletions

View File

@ -1,148 +1,111 @@
import { PlatformAccessory, Service } from "homebridge";
import HarmonyDataProvider from "../DataProviders/HarmonyDataProvider";
import { IDeviceButton } from "../Models/Config";
import { ICommand } from "../Models";
import { HarmonyDevice } from "../Models/HarmonyDevice";
import { Service, PlatformAccessory, AccessoryPlugin, API, Characteristic } from "homebridge";
import { Platform } from "../platform";
export interface IDeviceButtonProps {
dataProvider: HarmonyDataProvider,
buttonName: string,
displayName: string,
deviceInfo: IDeviceButton,
api: API,
log: any,
export class DeviceButton {
private _buttonState: boolean;
private _device!: HarmonyDevice;
private _switchService: Service;
constructor(
private readonly _platform: Platform,
private readonly _accessory: PlatformAccessory,
private _dataProvider: HarmonyDataProvider,
private _deviceInfo: IDeviceButton
) {
this._buttonState = false;
if (this._deviceInfo.NumberOfKeyPresses && this._deviceInfo.IsStateful) {
throw new Error(
"A button cannot be stateful and be pressed more than once"
);
}
this._accessory
.getService(this._platform.Service.AccessoryInformation)!
.setCharacteristic(
this._platform.Characteristic.Manufacturer,
"Brandon Watson"
)
.setCharacteristic(this._platform.Characteristic.Model, "Device Button")
.setCharacteristic(
this._platform.Characteristic.SerialNumber,
"123-456-789"
);
const switchUUID = this._platform.api.hap.uuid.generate(
`${this._accessory.displayName} Switch`
);
this._switchService =
this._accessory.getService(this._platform.Service.Switch) ||
this._accessory.addService(
this._platform.Service.Switch,
this._accessory.displayName,
switchUUID
);
this._switchService
.getCharacteristic(this._platform.Characteristic.On)
//@ts-ignore
.on("set", this.onSwitchSet)
.updateValue(this._buttonState)
.on("get", this.onSwitchGet);
}
/**
* Handler for switch set event
* @param callback The callback function to call when complete
*/
private onSwitchSet = async (
newState: boolean,
callback: (error?: Error | null | undefined) => void
) => {
if (!this._deviceInfo.IsStateful && newState === this._buttonState) {
return callback();
}
//Get device command if we don't have it
if (!this._device) {
this._device = this._dataProvider.getDeviceFromName(
this._deviceInfo.DeviceName
);
}
//Execute command
if (this._device) {
//change state if stateful
if (this._deviceInfo.IsStateful && this._buttonState != newState) {
this._buttonState = newState;
await this._device.sendCommand(this._deviceInfo.ButtonName);
} else if (!this._deviceInfo.IsStateful) {
//Send the number of configured key presses
for (let i = 0; i < this._deviceInfo.NumberOfKeyPresses; i++) {
await this._device.sendCommand(this._deviceInfo.ButtonName);
}
this._switchService
.getCharacteristic(this._platform.Characteristic.On)
.updateValue(false);
return callback(new Error("Normal Response"));
}
}
return callback();
};
/**
* Handler for switch get event
* @param callback The callback function to call when complete
*/
private onSwitchGet = (
callback: (error: Error | null, value: boolean) => void
) => {
//Only return state if button is stateful
if (this._deviceInfo.IsStateful) {
return callback(null, this._buttonState);
} else {
return callback(null, false);
}
};
}
export class DeviceButton implements AccessoryPlugin {
private _api: API;
private _homebridge: any;
private _log: any = {};
//Service fields
private _switchService: Service;
private _infoService: Service;
private _buttonInfo: IDeviceButton;
private _dataProvider: HarmonyDataProvider;
private _device!: HarmonyDevice;
private _buttonState: boolean;
constructor(props: IDeviceButtonProps) {
//Assign class variables
this._log = props.log;
this._api = props.api;
this.name = props.displayName;
this._buttonInfo = props.deviceInfo;
this._dataProvider = props.dataProvider;
this._buttonState = false;
if (this._buttonInfo.NumberOfKeyPresses && this._buttonInfo.IsStateful) {
throw new Error("A button cannot be stateful and be pressed more than once");
}
//Assign default number of key presses
if (!this._buttonInfo.NumberOfKeyPresses) {
this._buttonInfo.NumberOfKeyPresses = 1;
}
this.platformAccessory = new this._homebridge.platformAccessory(this.name, this.generateUUID(), this._homebridge.hap.Accessory.Categories.SWITCH);
//@ts-ignore
this._infoService = new Service.AccessoryInformation();
this._infoService.setCharacteristic(Characteristic.Manufacturer, "Brandon Watson")
this._infoService.setCharacteristic(Characteristic.Model, "Device Button")
this._infoService.setCharacteristic(Characteristic.SerialNumber, "123-456-789");
this._switchService = new Service.Switch(
this.name,
'switchService'
)
this._switchService.getCharacteristic(Characteristic.On)
//@ts-ignore
.on("set", this.onSwitchSet)
.updateValue(this._buttonState)
.on("get", this.onSwitchGet);
}
/**
* Required by homebridge.
*/
public name: string;
public platformAccessory: any;
/**
* Called by homebridge to gather services.
*/
public getServices = (): Array<Service> => {
return [this._infoService, this._switchService!];
}
/**
* Handler for switch set event
* @param callback The callback function to call when complete
*/
private onSwitchSet = async (newState: boolean, callback: (error?: Error | null | undefined) => void) => {
if (!this._buttonInfo.IsStateful && newState === this._buttonState) {
return callback();
}
//Get device command if we don't have it
if (!this._device) {
this._device = this._dataProvider.getDeviceFromName(this._buttonInfo.DeviceName);
}
//Execute command
if (this._device) {
//change state if stateful
if (this._buttonInfo.IsStateful && this._buttonState != newState) {
this._buttonState = newState
await this._device.sendCommand(this._buttonInfo.ButtonName);
} else if (!this._buttonInfo.IsStateful) {
//Send the number of configured key presses
for (let i = 0; i < this._buttonInfo.NumberOfKeyPresses; i++) {
await this._device.sendCommand(this._buttonInfo.ButtonName);
}
this._switchService.getCharacteristic(Characteristic.On).updateValue(false);
return callback(new Error("Normal Response"));
}
}
return callback();
}
/**
* Handler for switch get event
* @param callback The callback function to call when complete
*/
private onSwitchGet = (callback: (error: Error | null, value: boolean) => void) => {
//Only return state if button is stateful
if (this._buttonInfo.IsStateful) {
return callback(null, this._buttonState);
} else {
return callback(null, false)
}
}
/**
* Helper function to generate a UUID
*/
private generateUUID(): string { // Public Domain/MIT
var d = new Date().getTime();
if (typeof performance !== 'undefined' && typeof performance.now === 'function') {
d += performance.now(); //use high-precision timer if available
}
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = (d + Math.random() * 16) % 16 | 0;
d = Math.floor(d / 16);
return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
});
}
}