151 lines
4.7 KiB
TypeScript
151 lines
4.7 KiB
TypeScript
import HarmonyDataProvider from "../DataProviders/HarmonyDataProvider";
|
|
import { IDeviceButton } from "../Models/Config/IDeviceButton";
|
|
import { IAccessory } from "./IAccessory";
|
|
import { sleep } from "../Util/Sleep";
|
|
import { ICommand } from "../Models/IDevice";
|
|
|
|
let Service: HAPNodeJS.Service;
|
|
let Characteristic: HAPNodeJS.Characteristic;
|
|
|
|
export interface IDeviceButtonProps {
|
|
dataProvider: HarmonyDataProvider,
|
|
buttonName: string,
|
|
displayName: string,
|
|
deviceInfo: IDeviceButton,
|
|
api: any,
|
|
log: any,
|
|
homebridge: any,
|
|
}
|
|
|
|
export class DeviceButton implements IAccessory {
|
|
private _api: any;
|
|
private _homebridge: any;
|
|
private _log: any = {};
|
|
|
|
//Service fields
|
|
private _switchService: HAPNodeJS.Service;
|
|
private _infoService: HAPNodeJS.Service;
|
|
|
|
private _buttonInfo: IDeviceButton;
|
|
|
|
private _dataProvider: HarmonyDataProvider;
|
|
|
|
private _deviceCommand?: ICommand;
|
|
|
|
private _buttonState: boolean;
|
|
|
|
private _buttonName: string;
|
|
|
|
|
|
constructor(props: IDeviceButtonProps) {
|
|
//Assign class variables
|
|
this._log = props.log;
|
|
this._api = props.api;
|
|
Service = props.api.hap.Service;
|
|
Characteristic = props.api.hap.Characteristic;
|
|
this._buttonName = props.buttonName;
|
|
this.name = props.displayName;
|
|
this._homebridge = props.homebridge;
|
|
|
|
this._buttonInfo = props.deviceInfo;
|
|
|
|
this._dataProvider = props.dataProvider;
|
|
|
|
this._buttonState = false;
|
|
|
|
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, "The Watson Project")
|
|
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<HAPNodeJS.Service> => {
|
|
return [this._infoService, this._switchService!];
|
|
}
|
|
|
|
/**
|
|
* Handler for switch set event
|
|
* @param callback The callback function to call when complete
|
|
*/
|
|
private onSwitchSet = async (activeState: boolean, callback: (error?: Error | null | undefined) => void) => {
|
|
if (!this._buttonInfo.IsStateful && activeState === this._buttonState) {
|
|
return callback();
|
|
}
|
|
|
|
//Get device command if we don't have it
|
|
if (!this._deviceCommand) {
|
|
let cmd = this._dataProvider.getCommand(this._buttonInfo.ButtonName, this._buttonInfo.DeviceName);
|
|
if (cmd) {
|
|
this._deviceCommand = cmd;
|
|
}
|
|
}
|
|
|
|
//Execute command
|
|
if (this._deviceCommand) {
|
|
await this._dataProvider.sendCommand(this._deviceCommand);
|
|
|
|
//change state if stateful
|
|
if (this._buttonInfo.IsStateful) {
|
|
this._buttonState != this._buttonState
|
|
} else {
|
|
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);
|
|
});
|
|
}
|
|
} |