From 06fb2009bc728ce4b50216afba8f7e9d2e630d49 Mon Sep 17 00:00:00 2001 From: watsonb8 Date: Sun, 16 Jun 2019 12:55:19 -0400 Subject: [PATCH] Correctly working activities :) --- config.json | 120 +++++++++++------------ src/Accessories/ControlUnit.ts | 23 ++++- src/DataProviders/HarmonyDataProvider.ts | 57 ++++++----- 3 files changed, 113 insertions(+), 87 deletions(-) diff --git a/config.json b/config.json index 735d802..c5b6c4b 100644 --- a/config.json +++ b/config.json @@ -53,6 +53,27 @@ { "DisplayName": "Living Room", "Activities": [ + { + "DisplayName": "Chromecast", + "DeviceSetupList": [ + { + "DeviceName": "LG TV", + "Input": "HDMI1" + }, + { + "DeviceName": "JVC AV Receiver", + "Input": "DVD" + }, + { + "DeviceName": "Chromecast", + "Input": [] + } + ], + "VolumeDevice": "JVC AV Receiver", + "ControlDevice": "Chromecast", + "OutputDevice": "LG TV", + "UseMatrix": "true" + }, { "DisplayName": "Play Xbox One", "DeviceSetupList": [ @@ -81,23 +102,6 @@ "DeviceName": "Sony PS4", "Input": [] }, - { - "DeviceName": [], - "Input": "HDMI1" - }, - { - "DeviceName": [], - "Input": "DVD" - } - ], - "VolumeDevice": "JVC AV Receiver", - "ControlDevice": "Sony PS4", - "OutputDevice": "LG TV", - "UseMatrix": "true" - }, - { - "DisplayName": "Chromecast", - "DeviceSetupList": [ { "DeviceName": "LG TV", "Input": "HDMI1" @@ -105,14 +109,10 @@ { "DeviceName": "JVC AV Receiver", "Input": "DVD" - }, - { - "DeviceName": "Chromecast", - "Input": [] } ], "VolumeDevice": "JVC AV Receiver", - "ControlDevice": "Chromecast", + "ControlDevice": "Sony PS4", "OutputDevice": "LG TV", "UseMatrix": "true" }, @@ -155,6 +155,27 @@ { "DisplayName": "Bedroom", "Activities": [ + { + "DisplayName": "Chromecast", + "DeviceSetupList": [ + { + "DeviceName": "Vizio TV", + "Input": "HDMI1" + }, + { + "DeviceName": "Harman Kardon AV Receiver", + "Input": "Game" + }, + { + "DeviceName": "Chromecast", + "Input": [] + } + ], + "VolumeDevice": "Harman Kardon AV Receiver", + "ControlDevice": "Chromecast", + "OutputDevice": "Vizio TV", + "UseMatrix": "true" + }, { "DisplayName": "Play Xbox One", "DeviceSetupList": [ @@ -197,27 +218,6 @@ "OutputDevice": "LG TV", "UseMatrix": "true" }, - { - "DisplayName": "Chromecast", - "DeviceSetupList": [ - { - "DeviceName": "Vizio TV", - "Input": "HDMI1" - }, - { - "DeviceName": "Harman Kardon AV Receiver", - "Input": "Game" - }, - { - "DeviceName": "Chromecast", - "Input": [] - } - ], - "VolumeDevice": "Harman Kardon AV Receiver", - "ControlDevice": "Chromecast", - "OutputDevice": "Vizio TV", - "UseMatrix": "true" - }, { "DisplayName": "Apple TV", "DeviceSetupList": [ @@ -244,6 +244,23 @@ { "DisplayName": "Kitchen", "Activities": [ + { + "DisplayName": "Chromecast", + "DeviceSetupList": [ + { + "DeviceName": "Chromecast", + "Input": [] + }, + { + "DeviceName": "Westinghouse TV", + "Input": "HDMI1" + } + ], + "VolumeDevice": "Westinghouse TV", + "ControlDevice": "Chromecast", + "OutputDevice": "Westinghouse TV", + "UseMatrix": "true" + }, { "DisplayName": "Watch Apple Tv", "DeviceSetupList": [ @@ -277,23 +294,6 @@ "ControlDevice": "Microsoft Xbox One", "OutputDevice": "Westinghouse TV", "UseMatrix": "true" - }, - { - "DisplayName": "Chromecast", - "DeviceSetupList": [ - { - "DeviceName": "Chromecast", - "Input": [] - }, - { - "DeviceName": "Westinghouse TV", - "Input": "HDMI1" - } - ], - "VolumeDevice": "Westinghouse TV", - "ControlDevice": "Chromecast", - "OutputDevice": "Westinghouse TV", - "UseMatrix": "true" } ] } diff --git a/src/Accessories/ControlUnit.ts b/src/Accessories/ControlUnit.ts index d61bd99..92c015a 100644 --- a/src/Accessories/ControlUnit.ts +++ b/src/Accessories/ControlUnit.ts @@ -99,7 +99,9 @@ export class ControlUnit implements IAccessory { .on("get", callbackify(this.onGetActiveIdentifier)); } - //TODO + /** + * Event handler for SET active characteristic + */ private onSetAccessoryActive = async (value: any) => { this.log(`set active + ${value}`); switch (value) { @@ -108,13 +110,14 @@ export class ControlUnit implements IAccessory { } } - //TODO + /** + * Event handler for GET active characteristic + */ private onGetAccessoryActive = async () => { this.log(`get active`) //@ts-ignore return this.dataProvider.getIsActive ? Characteristic.Active.Active : Characteristic.Active.Inactive - // return Characteristic.Active.Active; } //TODO @@ -122,13 +125,25 @@ export class ControlUnit implements IAccessory { this.log(`set remote key + ${key}`); } + /** + * Event handler for SET active identifier characteristic + */ private onSetActiveIdentifier = async (identifier: any) => { this.log(`set active identifier + ${identifier}`); + this.dataProvider.startActivity(this.name, this.activities[identifier]); } + /** + * Event handler for GET active identifier characteristic + */ private onGetActiveIdentifier = async () => { this.log(`get active identifier`); - return 1; + let currentActivity: Activity = this.dataProvider.getIsActive(this.name)!; + let identifier: number = 0; + if (currentActivity) { + identifier = this.activities.findIndex(e => e.displayName === currentActivity.displayName); + } + return identifier; } /****************** diff --git a/src/DataProviders/HarmonyDataProvider.ts b/src/DataProviders/HarmonyDataProvider.ts index 915dd5c..d353d62 100644 --- a/src/DataProviders/HarmonyDataProvider.ts +++ b/src/DataProviders/HarmonyDataProvider.ts @@ -43,11 +43,9 @@ class HarmonyDataProvider { //Listeners this.harmony.on('open', () => { - this.log('Hub open'); this.connected = true; }); this.harmony.on('close', () => { - this.log('Hub closed'); this.connected = false; }); @@ -85,22 +83,22 @@ class HarmonyDataProvider { lastActivity = this.states[controlUnitName]!.currentActivity; } - // this.log(`asdf: ${JSON.stringify(this.devices)}`); //Build potential list of devices to to turn on let devicesToTurnOn: Array = activity.deviceSetupItems.map((value: DeviceSetupItem): IDevice => { return this.getDeviceFromName(value.deviceName); }); - // this.log(`Devices to turn on: ${JSON.stringify(devicesToTurnOn)}`); - //Resolve device conflicts with other controlUnits devicesToTurnOn = this.sanitizeDeviceList(devicesToTurnOn, controlUnitName); - // this.log(`Sanatized devices to turn on: ${JSON.stringify(devicesToTurnOn)}`) //Turn on devices await Promise.all(devicesToTurnOn.map(async (device: IDevice) => { - this.log(`Turning on device ${device.name}`) - await this.powerOnDevice(device); + if (device && device.name && this.devices[device.name]) { + if (!device.on) { + this.log(`Turning on device ${device.name}`) + await this.powerOnDevice(device); + } + } })); //Assign correct input @@ -108,14 +106,13 @@ class HarmonyDataProvider { activity.deviceSetupItems.map(async (value: DeviceSetupItem) => { let device: IDevice = this.getDeviceFromName(value.deviceName); - if (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) { //get input and output let input: Input = this.matrix.inputs.filter(e => e.inputDevice === activity.controlDeviceId)[0]; @@ -124,11 +121,9 @@ class HarmonyDataProvider { let inputCommandName: string = `In ${input.inputNumber}`; let outputCommandName: string = `Out ${output.outputLetter}`; - // this.log(`Matrix input command: ${inputCommandName} Matrix output command: ${outputCommandName}`); - let matrixDevice: IDevice = this.getDeviceFromName(this.matrix.deviceName); - //Rout hdmi + //Route hdmi if (matrixDevice.supportsCommand(inputCommandName) && matrixDevice.supportsCommand(outputCommandName)) { await this.sendCommand(matrixDevice.getCommand(inputCommandName)); await this.sendCommand(matrixDevice.getCommand(outputCommandName)); @@ -141,17 +136,30 @@ class HarmonyDataProvider { return this.getDeviceFromName(value.deviceName); }); - this.log(`Devices to turn off: ${JSON.stringify(devicesToTurnOff)}`); + //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) + })) { + delete devicesToTurnOff[index]; + } + }) //Resolve device conflicts with other controlUnits devicesToTurnOff = this.sanitizeDeviceList(devicesToTurnOff, controlUnitName); - this.log(`Sanatized devices to turn off: ${JSON.stringify(devicesToTurnOff)}`); + this.log(`Sanatized devices to turn off: ${JSON.stringify(devicesToTurnOff.map(e => e ? e.name : ""))}`); await Promise.all( //Turn off devices devicesToTurnOff.map(async (device: IDevice) => { - await this.powerOffDevice(device); + if (device) { + if (device.on) { + this.log(`Turning off device ${device.name}`) + await this.powerOffDevice(device); + } + } }) ); @@ -173,8 +181,8 @@ class HarmonyDataProvider { } - public getIsActive(controlUnitName: string): boolean { - return this.states[controlUnitName] ? true : false + public getIsActive(controlUnitName: string): Activity | undefined { + return this.states[controlUnitName] ? this.states[controlUnitName]!.currentActivity : undefined; } /** @@ -213,6 +221,7 @@ class HarmonyDataProvider { } } })); + self.log(`Harmony data provider ready`); } catch (err) { self.log(`ERROR - error connecting to harmony: ${err}`); @@ -223,15 +232,17 @@ class HarmonyDataProvider { private powerOffDevice = async (device: IDevice) => { let powerOffCommand: string = "Power Off"; - if (device.supportsCommand(powerOffCommand)) { + if (device && device.supportsCommand(powerOffCommand)) { await this.sendCommand(device.getCommand(powerOffCommand)); + device.on = false; } } private powerOnDevice = async (device: IDevice) => { let powerOnCommand: string = "Power On"; - if (device.supportsCommand(powerOnCommand)) { + if (device && device.supportsCommand(powerOnCommand)) { await this.sendCommand(device.getCommand(powerOnCommand)); + device.on = true; } } @@ -250,7 +261,7 @@ class HarmonyDataProvider { if (currentOtherState) { currentOtherState.currentActivity.deviceSetupItems.forEach((value: DeviceSetupItem) => { //there are devices to remove - if (devicesToTurnOn.some(e => e.name === value.deviceName)) { + 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)]; } @@ -264,7 +275,7 @@ class HarmonyDataProvider { private sendCommand = async (command: string) => { try { let response = await this.harmony.sendCommand(JSON.stringify(command)); - this.log(`Sent command: ${JSON.stringify(command)} response: ${JSON.stringify(response)}`); + // this.log(`Sent command: ${JSON.stringify(command)} response: ${JSON.stringify(response)}`); } catch (err) { this.log(`ERROR - error sending command to harmony: ${err}`); }