import { PlatformAccessory, Service } from "homebridge"; import { HarmonyDataProvider } from "../dataProviders/harmonyDataProvider"; import { IDeviceButton } from "../models/config"; import { HarmonyDevice } from "../models/harmonyDevice"; import { Platform } from "../platform"; 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) { return callback(); } //change state if stateful if (this._deviceInfo.IsStateful && this._buttonState != newState) { this._buttonState = newState; await this._device.sendCommand(this._deviceInfo.ButtonName); return callback(); } 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); this._buttonState = false; 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); } }; }