From ba1a1685ae4b420383acd945c3f1f91ad38fce77 Mon Sep 17 00:00:00 2001 From: watsonb8 Date: Thu, 23 Jan 2020 09:01:14 -0500 Subject: [PATCH] Using harmony device Still need to look up devices specific to hubs (In the case of the same device on multiple hubs) --- src/DataProviders/HarmonyDataProvider.ts | 92 ++++++------------------ src/Models/HarmonyDevice.ts | 4 ++ src/index.ts | 3 +- 3 files changed, 29 insertions(+), 70 deletions(-) diff --git a/src/DataProviders/HarmonyDataProvider.ts b/src/DataProviders/HarmonyDataProvider.ts index 7386be3..5d4b7da 100644 --- a/src/DataProviders/HarmonyDataProvider.ts +++ b/src/DataProviders/HarmonyDataProvider.ts @@ -7,6 +7,7 @@ import { EventEmitter } from "events"; import { IDevice, ICommand } from '../Models/IDevice'; import { IHub } from "../Models/Config/IHub"; import { IDeviceConfig } from "../Models/Config/IDeviceConfig"; +import { HarmonyDevice } from "../Models/HarmonyDevice"; let Characteristic: HAPNodeJS.Characteristic; @@ -28,7 +29,7 @@ class HarmonyDataProvider extends EventEmitter { private _deviceConfigs: Array; private _hubs: { [hubName: string]: IHub } = {}; - private _devices: { [name: string]: IDevice; } = {}; + private _devices: { [name: string]: HarmonyDevice; } = {}; private _states: { [controlUnitName: string]: (IActivityState | undefined) } = {}; private _matrix: IMatrix; @@ -47,7 +48,7 @@ class HarmonyDataProvider extends EventEmitter { this.connect(); } - public get devices(): { [name: string]: IDevice; } { + public get devices(): { [name: string]: HarmonyDevice; } { return this._devices; } @@ -70,8 +71,8 @@ class HarmonyDataProvider extends EventEmitter { return; } //Build potential list of devices to turn off - let devicesToTurnOff: Array = this._states[controlUnitName]!.currentActivity.DeviceSetupList - .map((value: IDeviceSetupItem): IDevice => { + let devicesToTurnOff: Array = this._states[controlUnitName]!.currentActivity.DeviceSetupList + .map((value: IDeviceSetupItem): HarmonyDevice => { return this.getDeviceFromName(value.DeviceName); }); @@ -79,7 +80,7 @@ class HarmonyDataProvider extends EventEmitter { devicesToTurnOff = this.sanitizeDeviceList(devicesToTurnOff, controlUnitName); //Turn off devices - devicesToTurnOff.forEach(async (device: IDevice) => { + devicesToTurnOff.forEach(async (device: HarmonyDevice) => { await device.powerOff(); }); @@ -97,7 +98,7 @@ class HarmonyDataProvider extends EventEmitter { } //Build potential list of devices to to turn on - let devicesToTurnOn: Array = activity.DeviceSetupList.map((value: IDeviceSetupItem): IDevice => { + let devicesToTurnOn: Array = activity.DeviceSetupList.map((value: IDeviceSetupItem): HarmonyDevice => { return this.getDeviceFromName(value.DeviceName); }); @@ -105,7 +106,7 @@ class HarmonyDataProvider extends EventEmitter { devicesToTurnOn = this.sanitizeDeviceList(devicesToTurnOn, controlUnitName); //Turn on devices - await Promise.all(devicesToTurnOn.map(async (device: IDevice) => { + await Promise.all(devicesToTurnOn.map(async (device: HarmonyDevice) => { if (device && device.name && this._devices[device.name]) { if (!device.on) { this._log(`Turning on device ${device.name}`) @@ -117,7 +118,7 @@ class HarmonyDataProvider extends EventEmitter { //Assign correct input await Promise.all( activity.DeviceSetupList.map(async (value: IDeviceSetupItem) => { - let device: IDevice = this.getDeviceFromName(value.DeviceName); + let device: HarmonyDevice = this.getDeviceFromName(value.DeviceName); if (device && device.supportsCommand(`Input${value.Input}`)) { await device.sendCommand(`Input${value.Input}`) @@ -133,7 +134,7 @@ class HarmonyDataProvider extends EventEmitter { let inputCommandName: string = `In ${input.InputNumber}`; let outputCommandName: string = `Out ${output.OutputLetter}`; - let matrixDevice: IDevice = this.getDeviceFromName(this._matrix.DeviceName); + let matrixDevice: HarmonyDevice = this.getDeviceFromName(this._matrix.DeviceName); //Route hdmi if (matrixDevice.supportsCommand(inputCommandName) && matrixDevice.supportsCommand(outputCommandName)) { @@ -146,13 +147,13 @@ class HarmonyDataProvider extends EventEmitter { //Build potential list of devices to turn off if (lastActivity) { - let devicesToTurnOff: Array = lastActivity.DeviceSetupList.map((value: IDeviceSetupItem): IDevice => { + let devicesToTurnOff: Array = lastActivity.DeviceSetupList.map((value: IDeviceSetupItem): HarmonyDevice => { return this.getDeviceFromName(value.DeviceName); }); //remove devices that will be used for next activity from list //delete array[index] is stupid because it just nulls out the index. But now i have to deal with nulls - devicesToTurnOff.forEach((device: IDevice, index: number) => { + devicesToTurnOff.forEach((device: HarmonyDevice, index: number) => { if (device && device.name && activity.DeviceSetupList.some(e => { return (e && e.DeviceName === device.name) })) { @@ -167,7 +168,7 @@ class HarmonyDataProvider extends EventEmitter { await Promise.all( //Turn off devices - devicesToTurnOff.map(async (device: IDevice) => { + devicesToTurnOff.map(async (device: HarmonyDevice) => { if (device) { if (device.on) { this._log(`Turning off device ${device.name}`) @@ -189,7 +190,7 @@ class HarmonyDataProvider extends EventEmitter { public volumeUp = async (controlUnitName: string) => { let volumeUpCommand: string = "Volume Up" if (this._states[controlUnitName]) { - let volumeDevice: IDevice = this.getDeviceFromName(this._states[controlUnitName]!.currentActivity.VolumeDevice); + let volumeDevice: HarmonyDevice = this.getDeviceFromName(this._states[controlUnitName]!.currentActivity.VolumeDevice); await volumeDevice.sendCommand(volumeUpCommand); } } @@ -200,7 +201,7 @@ class HarmonyDataProvider extends EventEmitter { public volumeDown = async (controlUnitName: string) => { let volumeDownCommand: string = "Volume Down" if (this._states[controlUnitName]) { - let volumeDevice: IDevice = this.getDeviceFromName(this._states[controlUnitName]!.currentActivity.VolumeDevice); + let volumeDevice: HarmonyDevice = this.getDeviceFromName(this._states[controlUnitName]!.currentActivity.VolumeDevice); await volumeDevice.sendCommand(volumeDownCommand); } } @@ -215,7 +216,7 @@ class HarmonyDataProvider extends EventEmitter { if (this._states[controlUnitName]) { let commandName: string = ""; - let device: IDevice = this.getDeviceFromName(this._states[controlUnitName]!.currentActivity.ControlDevice); + let device: HarmonyDevice = this.getDeviceFromName(this._states[controlUnitName]!.currentActivity.ControlDevice); switch (key) { case RemoteKey.ARROW_UP: { commandName = "Direction Up"; @@ -273,7 +274,7 @@ class HarmonyDataProvider extends EventEmitter { * @param deviceName The device name */ public getCommand(deviceCommandName: string, deviceName: string): ICommand | undefined { - const device: IDevice = this.getDeviceFromName(deviceName); + const device: HarmonyDevice = this.getDeviceFromName(deviceName); if (device && device.supportsCommand(deviceCommandName)) { return device.getCommand(deviceCommandName); } else { @@ -306,60 +307,13 @@ class HarmonyDataProvider extends EventEmitter { deviceCommands.forEach((command: any) => { commands[command.label] = command.action; }); - self._devices[dev.label] = { + self._devices[dev.label] = new HarmonyDevice({ id: dev.id, name: dev.label, commands: commands, - on: false, - harmony: hub.Harmony, log: self._log, - //Define device methods - supportsCommand(commandName: string): boolean { - let command = commands[commandName]; - return (command) ? true : false; - }, - getCommand(commandName: string): ICommand { - return commands[commandName]; - }, - async powerOn(): Promise { - let powerOnCommand: string = "Power On"; - let powerToggleCommand: string = "Power Toggle"; - if (this.supportsCommand(powerOnCommand)) { - await this.sendCommand(powerOnCommand); - this.on = true; - } else if (this.supportsCommand(powerToggleCommand)) { - await this.sendCommand(powerToggleCommand); - this.on = true; - } - }, - async powerOff(): Promise { - let powerOffCommand: string = "Power Off"; - let powerToggleCommand: string = "Power Toggle"; - if (this.supportsCommand(powerOffCommand)) { - await this.sendCommand(powerOffCommand); - this.on = false; - } else if (this.supportsCommand(powerToggleCommand)) { - await this.sendCommand(powerToggleCommand); - this.on = false; - } - }, - async sendCommand(commandName: string): Promise { - let command!: ICommand; - if (this.supportsCommand(commandName)) { - command = this.getCommand(commandName); - } - - try { - //Execute command - await this.harmony.sendCommand(JSON.stringify(command)); - - //Sleep - await sleep(800); - } catch (err) { - this.log(`ERROR - error sending command to harmony: ${err}`); - } - } - } + harmony: hub.Harmony + }); })); self._log(`Harmony data provider ready`); self.emit("Ready"); @@ -378,7 +332,7 @@ class HarmonyDataProvider extends EventEmitter { * Get the IDevice by name. * @param deviceName The device to retrieve. */ - private getDeviceFromName(deviceName: string): IDevice { + private getDeviceFromName(deviceName: string): HarmonyDevice { return this._devices[deviceName]; } @@ -387,7 +341,7 @@ class HarmonyDataProvider extends EventEmitter { * @param devicesToTurnOn The list of devices to modify. * @param controlUnitName The name of the control unit in question. */ - private sanitizeDeviceList(devicesToTurnOn: Array, controlUnitName: string): Array { + private sanitizeDeviceList(devicesToTurnOn: Array, controlUnitName: string): Array { for (let controlUnitKey in this._states) { //Skip self if (controlUnitKey === controlUnitName) { @@ -399,7 +353,7 @@ class HarmonyDataProvider extends EventEmitter { currentOtherState.currentActivity.DeviceSetupList.forEach((value: IDeviceSetupItem) => { //there are devices to remove if (devicesToTurnOn.some(e => e && e.name === value.DeviceName)) { - let deviceToRemove: IDevice = devicesToTurnOn.filter(i => i.name === value.DeviceName)[0]; + let deviceToRemove: HarmonyDevice = devicesToTurnOn.filter(i => i.name === value.DeviceName)[0]; delete devicesToTurnOn[devicesToTurnOn.indexOf(deviceToRemove)]; } }); diff --git a/src/Models/HarmonyDevice.ts b/src/Models/HarmonyDevice.ts index 01e586f..614c414 100644 --- a/src/Models/HarmonyDevice.ts +++ b/src/Models/HarmonyDevice.ts @@ -26,6 +26,10 @@ export class HarmonyDevice { public id: string; public name: string; + public get on(): boolean { + return this._on; + } + //Define device methods public supportsCommand(commandName: string): boolean { let command = this._commands[commandName]; diff --git a/src/index.ts b/src/index.ts index 2526c17..9021fc2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -40,7 +40,8 @@ class HarmonyMatrixPlatform { if (this.config) { //construct data provider this.dataProvider = new HarmonyDataProvider({ - hubAddress: this.config.hubIp, + hubs: this.config.Hubs, + deviceConfigs: this.config.Devices, matrix: this.config.Matrix, log: this.log });