From 80ac6423e57c070997556ae1f5b8fb3ef7edc23d Mon Sep 17 00:00:00 2001 From: watsonb8 Date: Wed, 1 Jan 2020 00:17:37 -0500 Subject: [PATCH] Simplified config parsing --- src/Accessories/ControlUnit.ts | 18 ++-- src/DataProviders/HarmonyDataProvider.ts | 72 +++++++-------- src/Models/Activity.ts | 74 ++-------------- src/Models/DeviceSetupItem.ts | 26 +----- src/Models/IConfig.ts | 13 +++ src/Models/Matrix.ts | 47 +++------- src/index.ts | 106 +++-------------------- 7 files changed, 91 insertions(+), 265 deletions(-) create mode 100644 src/Models/IConfig.ts diff --git a/src/Accessories/ControlUnit.ts b/src/Accessories/ControlUnit.ts index 7491bf2..d59ff9e 100644 --- a/src/Accessories/ControlUnit.ts +++ b/src/Accessories/ControlUnit.ts @@ -1,5 +1,5 @@ -import { Activity } from '../Models/Activity'; -import { Matrix } from '../Models/Matrix'; +import { IActivity } from '../Models/Activity'; +import { IMatrix } from '../Models/Matrix'; import { IAccessory } from './IAccessory'; import callbackify from '../Util/Callbackify'; import HarmonyDataProvider from '../DataProviders/HarmonyDataProvider'; @@ -31,7 +31,7 @@ export enum RemoteKey { export interface IControlUnitProps { dataProvider: HarmonyDataProvider, displayName: string, - activities: Array, + activities: Array, api: any, log: any, homebridge: any, @@ -55,7 +55,7 @@ export class ControlUnit implements IAccessory { private inputServices: Array = []; //Harmony fields - private activities: Array = []; + private activities: Array = []; private dataProvider: HarmonyDataProvider; public platformAccessory: any; @@ -180,10 +180,10 @@ export class ControlUnit implements IAccessory { * Event handler for GET active identifier characteristic */ private onGetActiveIdentifier = async () => { - let currentActivity: Activity = this.dataProvider.getIsActive(this.name)!; + let currentActivity: IActivity = this.dataProvider.getIsActive(this.name)!; let identifier: number = 0; if (currentActivity) { - identifier = this.activities.findIndex(e => e.displayName === currentActivity.displayName); + identifier = this.activities.findIndex(e => e.DisplayName === currentActivity.DisplayName); } return identifier; } @@ -240,13 +240,13 @@ export class ControlUnit implements IAccessory { */ private configureInputSourceService(): void { let inputs: Array = []; - this.activities.forEach((activity: Activity, index: number) => { - let inputService = new Service.InputSource(activity.displayName, 'activity' + activity.displayName); + this.activities.forEach((activity: IActivity, index: number) => { + let inputService = new Service.InputSource(activity.DisplayName, 'activity' + activity.DisplayName); inputService .setCharacteristic(Characteristic.Identifier, index) .setCharacteristic( Characteristic.ConfiguredName, - activity.displayName) + activity.DisplayName) .setCharacteristic( Characteristic.IsConfigured, //@ts-ignore diff --git a/src/DataProviders/HarmonyDataProvider.ts b/src/DataProviders/HarmonyDataProvider.ts index b50fed0..5075548 100644 --- a/src/DataProviders/HarmonyDataProvider.ts +++ b/src/DataProviders/HarmonyDataProvider.ts @@ -1,6 +1,6 @@ -import { Activity } from "../Models/Activity"; -import { DeviceSetupItem } from "../Models/DeviceSetupItem"; -import { Input, Matrix, Output } from "../Models/Matrix"; +import { IActivity } from "../Models/Activity"; +import { IDeviceSetupItem } from "../Models/DeviceSetupItem"; +import { IInput, IMatrix, IOutput } from "../Models/Matrix"; import { RemoteKey } from '../Accessories/ControlUnit'; import { sleep } from '../Util/Sleep'; @@ -17,13 +17,13 @@ interface IDevice { } interface IActivityState { - currentActivity: Activity + currentActivity: IActivity } interface IHarmonyDataProviderProps { hubAddress: string, log: any, - matrix: Matrix + matrix: IMatrix } class HarmonyDataProvider { @@ -35,7 +35,7 @@ class HarmonyDataProvider { private devices: { [name: string]: IDevice; } = {}; private states: { [controlUnitName: string]: (IActivityState | undefined) } = {}; - private matrix: Matrix; + private matrix: IMatrix; constructor(props: IHarmonyDataProviderProps) { this.log = props.log; @@ -58,7 +58,7 @@ class HarmonyDataProvider { /** * Power on all devices in an activity. */ - public powerOn = async (controlUnitName: string, activity: Activity) => { + public powerOn = async (controlUnitName: string, activity: IActivity) => { //Only power on if not alread on let currentActivity = this.states[controlUnitName] ? this.states[controlUnitName]!.currentActivity : undefined; if (!currentActivity) { @@ -74,9 +74,9 @@ class HarmonyDataProvider { return; } //Build potential list of devices to turn off - let devicesToTurnOff: Array = this.states[controlUnitName]!.currentActivity.deviceSetupItems - .map((value: DeviceSetupItem): IDevice => { - return this.getDeviceFromName(value.deviceName); + let devicesToTurnOff: Array = this.states[controlUnitName]!.currentActivity.DeviceSetupList + .map((value: IDeviceSetupItem): IDevice => { + return this.getDeviceFromName(value.DeviceName); }); //Resolve device conflicts with other controlUnits @@ -93,16 +93,16 @@ class HarmonyDataProvider { /** * Start an activity */ - public startActivity = async (controlUnitName: string, activity: Activity) => { - this.log(`Starting activity ${activity.displayName} for controlUnit: ${controlUnitName}`) - let lastActivity: Activity | undefined = undefined; + public startActivity = async (controlUnitName: string, activity: IActivity) => { + this.log(`Starting activity ${activity.DisplayName} for controlUnit: ${controlUnitName}`) + let lastActivity: IActivity | undefined = undefined; if (this.states[controlUnitName]) { lastActivity = this.states[controlUnitName]!.currentActivity; } //Build potential list of devices to to turn on - let devicesToTurnOn: Array = activity.deviceSetupItems.map((value: DeviceSetupItem): IDevice => { - return this.getDeviceFromName(value.deviceName); + let devicesToTurnOn: Array = activity.DeviceSetupList.map((value: IDeviceSetupItem): IDevice => { + return this.getDeviceFromName(value.DeviceName); }); //Resolve device conflicts with other controlUnits @@ -120,25 +120,25 @@ class HarmonyDataProvider { //Assign correct input await Promise.all( - activity.deviceSetupItems.map(async (value: DeviceSetupItem) => { - let device: IDevice = this.getDeviceFromName(value.deviceName); + activity.DeviceSetupList.map(async (value: IDeviceSetupItem) => { + let device: IDevice = this.getDeviceFromName(value.DeviceName); - if (device && device.supportsCommand(`Input${value.input}`)) { - let command: string = device.getCommand(`Input${value.input}`); + if (device && device.supportsCommand(`Input${value.Input}`)) { + let command: string = device.getCommand(`Input${value.Input}`); await this.sendCommand(command); } }) ); - if (activity.useMatrix) { + if (activity.UseMatrix) { //get input and output - let input: Input = this.matrix.inputs.filter(e => e.inputDevice === activity.controlDeviceId)[0]; - let output: Output = this.matrix.outputs.filter(e => e.outputDevice === activity.outputDeviceId)[0]; + let input: IInput = this.matrix.Inputs.filter(e => e.InputDevice === activity.ControlDevice)[0]; + let output: IOutput = this.matrix.Outputs.filter(e => e.OutputDevice === activity.OutputDevice)[0]; - let inputCommandName: string = `In ${input.inputNumber}`; - let outputCommandName: string = `Out ${output.outputLetter}`; + let inputCommandName: string = `In ${input.InputNumber}`; + let outputCommandName: string = `Out ${output.OutputLetter}`; - let matrixDevice: IDevice = this.getDeviceFromName(this.matrix.deviceName); + let matrixDevice: IDevice = this.getDeviceFromName(this.matrix.DeviceName); //Route hdmi if (matrixDevice.supportsCommand(inputCommandName) && matrixDevice.supportsCommand(outputCommandName)) { @@ -151,15 +151,15 @@ class HarmonyDataProvider { //Build potential list of devices to turn off if (lastActivity) { - let devicesToTurnOff: Array = lastActivity.deviceSetupItems.map((value: DeviceSetupItem): IDevice => { - return this.getDeviceFromName(value.deviceName); + let devicesToTurnOff: Array = lastActivity.DeviceSetupList.map((value: IDeviceSetupItem): IDevice => { + 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) => { - if (device && device.name && activity.deviceSetupItems.some(e => { - return (e && e.deviceName === device.name) + if (device && device.name && activity.DeviceSetupList.some(e => { + return (e && e.DeviceName === device.name) })) { delete devicesToTurnOff[index]; } @@ -194,7 +194,7 @@ class HarmonyDataProvider { public volumeUp = async (controlUnitName: string) => { let volumeUpCommand: string = "Volume Up" if (this.states[controlUnitName]) { - let volumeDevice: IDevice = this.getDeviceFromName(this.states[controlUnitName]!.currentActivity.volumeDeviceId); + let volumeDevice: IDevice = this.getDeviceFromName(this.states[controlUnitName]!.currentActivity.VolumeDevice); if (volumeDevice.supportsCommand(volumeUpCommand)) { this.sendCommand(volumeDevice.getCommand(volumeUpCommand)); } @@ -207,7 +207,7 @@ class HarmonyDataProvider { public volumeDown = async (controlUnitName: string) => { let volumeDownCommand: string = "Volume Down" if (this.states[controlUnitName]) { - let volumeDevice: IDevice = this.getDeviceFromName(this.states[controlUnitName]!.currentActivity.volumeDeviceId); + let volumeDevice: IDevice = this.getDeviceFromName(this.states[controlUnitName]!.currentActivity.VolumeDevice); if (volumeDevice.supportsCommand(volumeDownCommand)) { this.sendCommand(volumeDevice.getCommand(volumeDownCommand)); } @@ -224,7 +224,7 @@ class HarmonyDataProvider { if (this.states[controlUnitName]) { let commandName: string = ""; - let device: IDevice = this.getDeviceFromName(this.states[controlUnitName]!.currentActivity.controlDeviceId); + let device: IDevice = this.getDeviceFromName(this.states[controlUnitName]!.currentActivity.ControlDevice); switch (key) { case RemoteKey.ARROW_UP: { commandName = "Direction Up"; @@ -274,7 +274,7 @@ class HarmonyDataProvider { * Return if a control unit is active * @param controlUnitName */ - public getIsActive(controlUnitName: string): Activity | undefined { + public getIsActive(controlUnitName: string): IActivity | undefined { return this.states[controlUnitName] ? this.states[controlUnitName]!.currentActivity : undefined; } @@ -374,10 +374,10 @@ class HarmonyDataProvider { let currentOtherState: IActivityState = this.states[controlUnitKey]!; if (currentOtherState) { - currentOtherState.currentActivity.deviceSetupItems.forEach((value: DeviceSetupItem) => { + 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]; + if (devicesToTurnOn.some(e => e && e.name === value.DeviceName)) { + let deviceToRemove: IDevice = devicesToTurnOn.filter(i => i.name === value.DeviceName)[0]; delete devicesToTurnOn[devicesToTurnOn.indexOf(deviceToRemove)]; } }); diff --git a/src/Models/Activity.ts b/src/Models/Activity.ts index 14d9d4b..acbbb43 100644 --- a/src/Models/Activity.ts +++ b/src/Models/Activity.ts @@ -1,69 +1,11 @@ -import { DeviceSetupItem } from './DeviceSetupItem'; -/** - * Input properties. - */ -export interface IActivityProps { - deviceList: Array, - controlDeviceId: string, - volumeDeviceId: string, - outputDeviceId: string, - displayName: string - useMatrix: boolean, -} +import { IDeviceSetupItem } from './DeviceSetupItem'; -/** - * Data model class to hold activity related information. - */ -export class Activity { - private _volumeDeviceId: string = ""; - private _outputDeviceId: string = ""; - private _controlDeviceId: string = ""; - private _displayName: string = ""; - private _deviceSetupItems: Array; - private _useMatrix: boolean = false; +export interface IActivity { + OutputDevice: string; + VolumeDevice: string; + ControlDevice: string; + DisplayName: string; + DeviceSetupList: Array; + UseMatrix: boolean; - constructor(props: IActivityProps) { - this._controlDeviceId = props.controlDeviceId; - this._outputDeviceId = props.outputDeviceId; - this._volumeDeviceId = props.volumeDeviceId; - this._displayName = props.displayName; - this._deviceSetupItems = props.deviceList; - this._useMatrix = props.useMatrix - } - - /** - * The device associated with main control. - */ - public get controlDeviceId(): string { - return this._controlDeviceId; - }; - - /** - * The device associated with the volume control. - */ - public get volumeDeviceId(): string { - return this._volumeDeviceId - }; - - /** - * The device associated with output. - */ - public get outputDeviceId(): string { - return this._outputDeviceId; - }; - - /** - * The display name of the activity. - */ - public get displayName(): string { - return this._displayName; - } - - public get deviceSetupItems(): Array { - return this._deviceSetupItems - } - - public get useMatrix(): boolean { - return this._useMatrix; - } } \ No newline at end of file diff --git a/src/Models/DeviceSetupItem.ts b/src/Models/DeviceSetupItem.ts index e9e4f4e..c899502 100644 --- a/src/Models/DeviceSetupItem.ts +++ b/src/Models/DeviceSetupItem.ts @@ -1,25 +1,5 @@ -export interface IDeviceSetupItemProps { - deviceName: string, - input: string -} - -/** - * Data model to hold device setup items. - */ -export class DeviceSetupItem { - private _deviceId: string = ""; - private _input: string = ""; - constructor(props: IDeviceSetupItemProps) { - this._deviceId = props.deviceName; - this._input = props.input; - } - - public get deviceName() { - return this._deviceId; - } - - public get input() { - return this._input; - } +export interface IDeviceSetupItem { + DeviceName: string; + Input: string; } \ No newline at end of file diff --git a/src/Models/IConfig.ts b/src/Models/IConfig.ts new file mode 100644 index 0000000..08e34d8 --- /dev/null +++ b/src/Models/IConfig.ts @@ -0,0 +1,13 @@ +import { IMatrix } from "./Matrix"; +import { IActivity } from "./Activity"; + +export interface IControlUnit { + DisplayName: string; + Activities: Array; +} + +export interface IConfig { + hubIp: string; + Matrix: IMatrix + ControlUnits: Array +} \ No newline at end of file diff --git a/src/Models/Matrix.ts b/src/Models/Matrix.ts index d067976..90e10f8 100644 --- a/src/Models/Matrix.ts +++ b/src/Models/Matrix.ts @@ -1,42 +1,15 @@ -export interface IMatrixProps { - inputs: Array, - outputs: Array, - deviceName: string, +export interface IInput { + InputNumber: string, + InputDevice: string, } -export interface Input { - inputNumber: string, - inputDevice: string, +export interface IOutput { + OutputLetter: string, + OutputDevice: string, } -export interface Output { - outputLetter: string, - outputDevice: string, -} - -/** - * Data model to hold matrix information. - */ -export class Matrix { - private _inputs: Array = []; - private _outputs: Array = []; - private _deviceName: string; - - constructor(props: IMatrixProps) { - this._inputs = props.inputs; - this._outputs = props.outputs; - this._deviceName = props.deviceName; - } - - public get inputs(): Array { - return this._inputs - } - - public get outputs(): Array { - return this._outputs; - } - - public get deviceName(): string { - return this._deviceName; - } +export interface IMatrix { + Inputs: Array; + Outputs: Array; + DeviceName: string; } \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index acf90aa..b92022b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,8 +1,9 @@ import { ControlUnit } from "./Accessories/ControlUnit"; -import { Activity } from "./Models/Activity"; -import { DeviceSetupItem } from "./Models/DeviceSetupItem"; -import { Input, Output, Matrix } from "./Models/Matrix"; +import { IActivity } from "./Models/Activity"; +import { IDeviceSetupItem } from "./Models/DeviceSetupItem"; +import { IInput, IOutput, IMatrix } from "./Models/Matrix"; import HarmonyDataProvider from "./DataProviders/HarmonyDataProvider"; +import { IConfig, IControlUnit } from "./Models/IConfig"; let Accessory: any; let Homebridge: any; @@ -24,7 +25,7 @@ export default function (homebridge: any) { class HarmonyMatrixPlatform { log: any = {}; - config: any = {}; + config: IConfig; api: any; dataProvider: HarmonyDataProvider | null; controlUnits: Array = []; @@ -37,7 +38,6 @@ class HarmonyMatrixPlatform { this.api.on('didFinishLaunching', this.didFinishLaunching.bind(this)); this.dataProvider = null; - this.log("This is new"); } /** @@ -51,7 +51,6 @@ class HarmonyMatrixPlatform { this.controlUnits.forEach((accessory: ControlUnit) => { this.api.publishExternalAccessories("HarmonyMatrixPlatform", [accessory.platformAccessory]); }) - } /** @@ -59,103 +58,22 @@ class HarmonyMatrixPlatform { * @param callback */ accessories(callback: (accessories: Array) => void) { - //Parse ip - let hubIp: string = this.config["hubIp"]; - - //Parse matrix - let configInputs: any = this.config["Matrix"]["Inputs"]; - let configOutputs: any = this.config["Matrix"]["Outputs"]; - let matrixName: string = this.config["Matrix"]["DeviceName"]; - - let inputs: Array = []; - let outputs: Array = []; - - configInputs.forEach((configInput: any) => { - let inputDevice: string = configInput["InputDevice"]; - let inputNumber: string = configInput["InputNumber"]; - - this.log(`INFO - Added input to matrix '${inputDevice}'`); - - inputs.push({ - inputDevice: inputDevice, - inputNumber: inputNumber - }); - }); - configOutputs.forEach((configOutput: any) => { - let outputDevice: string = configOutput["OutputDevice"]; - let outputLetter: string = configOutput["OutputLetter"]; - - this.log(`INFO - Added output to matrix '${outputDevice}'`); - - outputs.push({ - outputDevice: outputDevice, - outputLetter: outputLetter - }); - - }); - - let matrix = new Matrix({ - inputs: inputs, - outputs: outputs, - deviceName: matrixName, - }); - //construct data provider this.dataProvider = new HarmonyDataProvider({ - hubAddress: hubIp, - matrix: matrix, + hubAddress: this.config.hubIp, + matrix: this.config.Matrix, log: this.log }); - //Parse control units - let configControlUnits: any = this.config["ControlUnits"]; - - configControlUnits.forEach((configControlUnit: any) => { - //Parse activities list - let configActivities: any = configControlUnit["Activities"]; - let activities: Array = []; - configActivities.forEach((configActivity: any) => { - //parse devices - let configDevices: any = configActivity["DeviceSetupList"]; - let devices: Array = []; - configDevices.forEach((configDevice: any) => { - //Add device - devices.push(new DeviceSetupItem({ - deviceName: configDevice["DeviceName"], - input: configDevice["Input"] - })); - this.log(`INFO - Added device '${configDevice["DeviceName"]}' for activity '${configActivity["DisplayName"]}'`); - }); - - //Add activity - activities.push(new Activity({ - volumeDeviceId: configActivity["VolumeDevice"], - controlDeviceId: configActivity["ControlDevice"], - outputDeviceId: configActivity["OutputDevice"], - displayName: configActivity["DisplayName"], - useMatrix: configActivity["UseMatrix"] === "true" ? true : false, - deviceList: devices - })); - this.log(`INFO - Added activity '${configActivity["DisplayName"]}'`); - }); - - let controlUnit: ControlUnit = new ControlUnit({ + this.config.ControlUnits.forEach((unit: IControlUnit) => { + this.controlUnits.push(new ControlUnit({ dataProvider: this.dataProvider!, - displayName: configControlUnit["DisplayName"], + displayName: unit.DisplayName, api: this.api, log: this.log, - activities: activities, + activities: unit.Activities, homebridge: Homebridge, - }); - - //@ts-ignore - let accessory = controlUnit as homebridge.platformAccessory; - //@ts-ignore - - //Add control unit - this.controlUnits.push(accessory); - - this.log(`INFO - Added ControlUnit`); + })); }); callback(this.controlUnits); }