Compare commits
	
		
			4 Commits
		
	
	
		
			1.2.0
			...
			feature/ne
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | ed0b418b4d | ||
|  | 2475aea1c8 | ||
|  | 31c5c5b9e2 | ||
|  | a539287b9e | 
							
								
								
									
										16
									
								
								.vscode/launch.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								.vscode/launch.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | |||||||
|  | { | ||||||
|  |     // Use IntelliSense to learn about possible attributes. | ||||||
|  |     // Hover to view descriptions of existing attributes. | ||||||
|  |     // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 | ||||||
|  |     "version": "0.2.0", | ||||||
|  |     "configurations": [ | ||||||
|  |         { | ||||||
|  |             "type": "node", | ||||||
|  |             "request": "launch", | ||||||
|  |             "name": "Launch Program", | ||||||
|  |             "preLaunchTask": "build and install", | ||||||
|  |             "program": "/Users/brandonwatson/.npm-global/bin/homebridge", | ||||||
|  |             "sourceMaps": true, | ||||||
|  |         } | ||||||
|  |     ] | ||||||
|  | } | ||||||
							
								
								
									
										17
									
								
								.vscode/tasks.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								.vscode/tasks.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | |||||||
|  | { | ||||||
|  |     // See https://go.microsoft.com/fwlink/?LinkId=733558  | ||||||
|  |     // for the documentation about the tasks.json format | ||||||
|  |     "version": "2.0.0", | ||||||
|  |     "tasks": [ | ||||||
|  |         { | ||||||
|  |             "type": "npm", | ||||||
|  |             "script": "build", | ||||||
|  |             "problemMatcher": [] | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             "type": "shell", | ||||||
|  |             "label": "build and install", | ||||||
|  |             "command": "npm run build&&sudo npm install -g --unsafe-perm ." | ||||||
|  |         } | ||||||
|  |     ] | ||||||
|  | } | ||||||
							
								
								
									
										51
									
								
								config.json
									
									
									
									
									
								
							
							
						
						
									
										51
									
								
								config.json
									
									
									
									
									
								
							| @@ -13,8 +13,10 @@ | |||||||
|         }, |         }, | ||||||
|         { |         { | ||||||
|             "platform": "HarmonyHubMatrix", |             "platform": "HarmonyHubMatrix", | ||||||
|             "hubIp": "192.168.1.14", |             "harmonyHubIp": "192.168.1.14", | ||||||
|  |             "neeoHubIp": "192.168.1.24", | ||||||
|             "Matrix": { |             "Matrix": { | ||||||
|  |                 "Hub": "Harmony", | ||||||
|                 "DeviceName": "Gefen AV Switch", |                 "DeviceName": "Gefen AV Switch", | ||||||
|                 "Inputs": [ |                 "Inputs": [ | ||||||
|                     { |                     { | ||||||
| @@ -57,14 +59,17 @@ | |||||||
|                             "DisplayName": "Chromecast", |                             "DisplayName": "Chromecast", | ||||||
|                             "DeviceSetupList": [ |                             "DeviceSetupList": [ | ||||||
|                                 { |                                 { | ||||||
|  |                                     "Hub": "Harmony", | ||||||
|                                     "DeviceName": "LG TV", |                                     "DeviceName": "LG TV", | ||||||
|                                     "Input": "HDMI1" |                                     "Input": "HDMI1" | ||||||
|                                 }, |                                 }, | ||||||
|                                 { |                                 { | ||||||
|  |                                     "Hub": "Harmony", | ||||||
|                                     "DeviceName": "JVC AV Receiver", |                                     "DeviceName": "JVC AV Receiver", | ||||||
|                                     "Input": "DVD" |                                     "Input": "DVD" | ||||||
|                                 }, |                                 }, | ||||||
|                                 { |                                 { | ||||||
|  |                                     "Hub": "Harmony", | ||||||
|                                     "DeviceName": "Chromecast", |                                     "DeviceName": "Chromecast", | ||||||
|                                     "Input": [] |                                     "Input": [] | ||||||
|                                 } |                                 } | ||||||
| @@ -78,14 +83,17 @@ | |||||||
|                             "DisplayName": "Play Xbox One", |                             "DisplayName": "Play Xbox One", | ||||||
|                             "DeviceSetupList": [ |                             "DeviceSetupList": [ | ||||||
|                                 { |                                 { | ||||||
|  |                                     "Hub": "Harmony", | ||||||
|                                     "DeviceName": "Microsoft Xbox One", |                                     "DeviceName": "Microsoft Xbox One", | ||||||
|                                     "Input": [] |                                     "Input": [] | ||||||
|                                 }, |                                 }, | ||||||
|                                 { |                                 { | ||||||
|  |                                     "Hub": "Harmony", | ||||||
|                                     "DeviceName": "LG TV", |                                     "DeviceName": "LG TV", | ||||||
|                                     "Input": "HDMI1" |                                     "Input": "HDMI1" | ||||||
|                                 }, |                                 }, | ||||||
|                                 { |                                 { | ||||||
|  |                                     "Hub": "Harmony", | ||||||
|                                     "DeviceName": "JVC AV Receiver", |                                     "DeviceName": "JVC AV Receiver", | ||||||
|                                     "Input": "DVD" |                                     "Input": "DVD" | ||||||
|                                 } |                                 } | ||||||
| @@ -99,14 +107,17 @@ | |||||||
|                             "DisplayName": "Play PS4", |                             "DisplayName": "Play PS4", | ||||||
|                             "DeviceSetupList": [ |                             "DeviceSetupList": [ | ||||||
|                                 { |                                 { | ||||||
|  |                                     "Hub": "Harmony", | ||||||
|                                     "DeviceName": "Sony PS4", |                                     "DeviceName": "Sony PS4", | ||||||
|                                     "Input": [] |                                     "Input": [] | ||||||
|                                 }, |                                 }, | ||||||
|                                 { |                                 { | ||||||
|  |                                     "Hub": "Harmony", | ||||||
|                                     "DeviceName": "LG TV", |                                     "DeviceName": "LG TV", | ||||||
|                                     "Input": "HDMI1" |                                     "Input": "HDMI1" | ||||||
|                                 }, |                                 }, | ||||||
|                                 { |                                 { | ||||||
|  |                                     "Hub": "Harmony", | ||||||
|                                     "DeviceName": "JVC AV Receiver", |                                     "DeviceName": "JVC AV Receiver", | ||||||
|                                     "Input": "DVD" |                                     "Input": "DVD" | ||||||
|                                 } |                                 } | ||||||
| @@ -120,14 +131,17 @@ | |||||||
|                             "DisplayName": "Apple TV", |                             "DisplayName": "Apple TV", | ||||||
|                             "DeviceSetupList": [ |                             "DeviceSetupList": [ | ||||||
|                                 { |                                 { | ||||||
|  |                                     "Hub": "Harmony", | ||||||
|                                     "DeviceName": "Apple TV Gen 4", |                                     "DeviceName": "Apple TV Gen 4", | ||||||
|                                     "Input": [] |                                     "Input": [] | ||||||
|                                 }, |                                 }, | ||||||
|                                 { |                                 { | ||||||
|  |                                     "Hub": "Harmony", | ||||||
|                                     "DeviceName": "LG TV", |                                     "DeviceName": "LG TV", | ||||||
|                                     "Input": "HDMI1" |                                     "Input": "HDMI1" | ||||||
|                                 }, |                                 }, | ||||||
|                                 { |                                 { | ||||||
|  |                                     "Hub": "Harmony", | ||||||
|                                     "DeviceName": "JVC AV Receiver", |                                     "DeviceName": "JVC AV Receiver", | ||||||
|                                     "Input": "DVD" |                                     "Input": "DVD" | ||||||
|                                 } |                                 } | ||||||
| @@ -141,6 +155,7 @@ | |||||||
|                             "DisplayName": "Listen to Music", |                             "DisplayName": "Listen to Music", | ||||||
|                             "DeviceSetupList": [ |                             "DeviceSetupList": [ | ||||||
|                                 { |                                 { | ||||||
|  |                                     "Hub": "Harmony", | ||||||
|                                     "DeviceName": "JVC AV Receiver", |                                     "DeviceName": "JVC AV Receiver", | ||||||
|                                     "Input": "DVD" |                                     "Input": "DVD" | ||||||
|                                 } |                                 } | ||||||
| @@ -159,19 +174,22 @@ | |||||||
|                             "DisplayName": "Chromecast", |                             "DisplayName": "Chromecast", | ||||||
|                             "DeviceSetupList": [ |                             "DeviceSetupList": [ | ||||||
|                                 { |                                 { | ||||||
|  |                                     "Hub": "Neeo", | ||||||
|                                     "DeviceName": "Vizio TV", |                                     "DeviceName": "Vizio TV", | ||||||
|                                     "Input": "HDMI1" |                                     "Input": "HDMI1" | ||||||
|                                 }, |                                 }, | ||||||
|                                 { |                                 { | ||||||
|                                     "DeviceName": "Harman Kardon AV Receiver", |                                     "Hub": "Neeo", | ||||||
|  |                                     "DeviceName": "Harmon Kardon Receicer", | ||||||
|                                     "Input": "Game" |                                     "Input": "Game" | ||||||
|                                 }, |                                 }, | ||||||
|                                 { |                                 { | ||||||
|  |                                     "Hub": "Harmony", | ||||||
|                                     "DeviceName": "Chromecast", |                                     "DeviceName": "Chromecast", | ||||||
|                                     "Input": [] |                                     "Input": [] | ||||||
|                                 } |                                 } | ||||||
|                             ], |                             ], | ||||||
|                             "VolumeDevice": "Harman Kardon AV Receiver", |                             "VolumeDevice": "Harmon Kardon Receicer", | ||||||
|                             "ControlDevice": "Chromecast", |                             "ControlDevice": "Chromecast", | ||||||
|                             "OutputDevice": "Vizio TV", |                             "OutputDevice": "Vizio TV", | ||||||
|                             "UseMatrix": "true" |                             "UseMatrix": "true" | ||||||
| @@ -180,19 +198,22 @@ | |||||||
|                             "DisplayName": "Play Xbox One", |                             "DisplayName": "Play Xbox One", | ||||||
|                             "DeviceSetupList": [ |                             "DeviceSetupList": [ | ||||||
|                                 { |                                 { | ||||||
|  |                                     "Hub": "Harmony", | ||||||
|                                     "DeviceName": "Microsoft Xbox One", |                                     "DeviceName": "Microsoft Xbox One", | ||||||
|                                     "Input": [] |                                     "Input": [] | ||||||
|                                 }, |                                 }, | ||||||
|                                 { |                                 { | ||||||
|  |                                     "Hub": "Neeo", | ||||||
|                                     "DeviceName": "Vizio TV", |                                     "DeviceName": "Vizio TV", | ||||||
|                                     "Input": "HDMI1" |                                     "Input": "HDMI1" | ||||||
|                                 }, |                                 }, | ||||||
|                                 { |                                 { | ||||||
|                                     "DeviceName": "Harman Kardon AV Receiver", |                                     "Hub": "Neeo", | ||||||
|  |                                     "DeviceName": "Harmon Kardon Receicer", | ||||||
|                                     "Input": "Game" |                                     "Input": "Game" | ||||||
|                                 } |                                 } | ||||||
|                             ], |                             ], | ||||||
|                             "VolumeDevice": "Harman Kardon AV Receiver", |                             "VolumeDevice": "Harmon Kardon Receicer", | ||||||
|                             "ControlDevice": "Microsoft Xbox One", |                             "ControlDevice": "Microsoft Xbox One", | ||||||
|                             "OutputDevice": "Vizio TV", |                             "OutputDevice": "Vizio TV", | ||||||
|                             "UseMatrix": "true" |                             "UseMatrix": "true" | ||||||
| @@ -201,19 +222,22 @@ | |||||||
|                             "DisplayName": "Play PS4", |                             "DisplayName": "Play PS4", | ||||||
|                             "DeviceSetupList": [ |                             "DeviceSetupList": [ | ||||||
|                                 { |                                 { | ||||||
|  |                                     "Hub": "Harmony", | ||||||
|                                     "DeviceName": "Sony PS4", |                                     "DeviceName": "Sony PS4", | ||||||
|                                     "Input": [] |                                     "Input": [] | ||||||
|                                 }, |                                 }, | ||||||
|                                 { |                                 { | ||||||
|  |                                     "Hub": "Neeo", | ||||||
|                                     "DeviceName": "Vizio TV", |                                     "DeviceName": "Vizio TV", | ||||||
|                                     "Input": "HDMI1" |                                     "Input": "HDMI1" | ||||||
|                                 }, |                                 }, | ||||||
|                                 { |                                 { | ||||||
|                                     "DeviceName": "Harman Kardon AV Receiver", |                                     "Hub": "Neeo", | ||||||
|  |                                     "DeviceName": "Harmon Kardon Receicer", | ||||||
|                                     "Input": "DVD" |                                     "Input": "DVD" | ||||||
|                                 } |                                 } | ||||||
|                             ], |                             ], | ||||||
|                             "VolumeDevice": "Harman Kardon AV Receiver", |                             "VolumeDevice": "Harmon Kardon Receicer", | ||||||
|                             "ControlDevice": "Sony PS4", |                             "ControlDevice": "Sony PS4", | ||||||
|                             "OutputDevice": "LG TV", |                             "OutputDevice": "LG TV", | ||||||
|                             "UseMatrix": "true" |                             "UseMatrix": "true" | ||||||
| @@ -222,19 +246,22 @@ | |||||||
|                             "DisplayName": "Apple TV", |                             "DisplayName": "Apple TV", | ||||||
|                             "DeviceSetupList": [ |                             "DeviceSetupList": [ | ||||||
|                                 { |                                 { | ||||||
|  |                                     "Hub": "Harmony", | ||||||
|                                     "DeviceName": "Apple TV Gen 4", |                                     "DeviceName": "Apple TV Gen 4", | ||||||
|                                     "Input": [] |                                     "Input": [] | ||||||
|                                 }, |                                 }, | ||||||
|                                 { |                                 { | ||||||
|  |                                     "Hub": "Neeo", | ||||||
|                                     "DeviceName": "Vizio TV", |                                     "DeviceName": "Vizio TV", | ||||||
|                                     "Input": "HDMI1" |                                     "Input": "HDMI1" | ||||||
|                                 }, |                                 }, | ||||||
|                                 { |                                 { | ||||||
|                                     "DeviceName": "Harman Kardon AV Receiver", |                                     "Hub": "Neeo", | ||||||
|  |                                     "DeviceName": "Harmon Kardon Receicer", | ||||||
|                                     "Input": "Game" |                                     "Input": "Game" | ||||||
|                                 } |                                 } | ||||||
|                             ], |                             ], | ||||||
|                             "VolumeDevice": "Harman Kardon AV Receiver", |                             "VolumeDevice": "Harmon Kardon Receicer", | ||||||
|                             "ControlDevice": "Apple TV Gen 4", |                             "ControlDevice": "Apple TV Gen 4", | ||||||
|                             "OutputDevice": "Vizio TV", |                             "OutputDevice": "Vizio TV", | ||||||
|                             "UseMatrix": "true" |                             "UseMatrix": "true" | ||||||
| @@ -248,10 +275,12 @@ | |||||||
|                             "DisplayName": "Chromecast", |                             "DisplayName": "Chromecast", | ||||||
|                             "DeviceSetupList": [ |                             "DeviceSetupList": [ | ||||||
|                                 { |                                 { | ||||||
|  |                                     "Hub": "Harmony", | ||||||
|                                     "DeviceName": "Chromecast", |                                     "DeviceName": "Chromecast", | ||||||
|                                     "Input": [] |                                     "Input": [] | ||||||
|                                 }, |                                 }, | ||||||
|                                 { |                                 { | ||||||
|  |                                     "Hub": "Harmony", | ||||||
|                                     "DeviceName": "Westinghouse TV", |                                     "DeviceName": "Westinghouse TV", | ||||||
|                                     "Input": "HDMI1" |                                     "Input": "HDMI1" | ||||||
|                                 } |                                 } | ||||||
| @@ -265,10 +294,12 @@ | |||||||
|                             "DisplayName": "Watch Apple Tv", |                             "DisplayName": "Watch Apple Tv", | ||||||
|                             "DeviceSetupList": [ |                             "DeviceSetupList": [ | ||||||
|                                 { |                                 { | ||||||
|  |                                     "Hub": "Harmony", | ||||||
|                                     "DeviceName": "Apple TV Gen 4", |                                     "DeviceName": "Apple TV Gen 4", | ||||||
|                                     "Input": [] |                                     "Input": [] | ||||||
|                                 }, |                                 }, | ||||||
|                                 { |                                 { | ||||||
|  |                                     "Hub": "Harmony", | ||||||
|                                     "DeviceName": "Westinghouse TV", |                                     "DeviceName": "Westinghouse TV", | ||||||
|                                     "Input": "HDMI1" |                                     "Input": "HDMI1" | ||||||
|                                 } |                                 } | ||||||
| @@ -282,10 +313,12 @@ | |||||||
|                             "DisplayName": "Play Xbox One", |                             "DisplayName": "Play Xbox One", | ||||||
|                             "DeviceSetupList": [ |                             "DeviceSetupList": [ | ||||||
|                                 { |                                 { | ||||||
|  |                                     "Hub": "Harmony", | ||||||
|                                     "DeviceName": "Westinghouse TV", |                                     "DeviceName": "Westinghouse TV", | ||||||
|                                     "Input": "HDMI1" |                                     "Input": "HDMI1" | ||||||
|                                 }, |                                 }, | ||||||
|                                 { |                                 { | ||||||
|  |                                     "Hub": "Harmony", | ||||||
|                                     "DeviceName": "Microsoft Xbox One", |                                     "DeviceName": "Microsoft Xbox One", | ||||||
|                                     "Input": [] |                                     "Input": [] | ||||||
|                                 } |                                 } | ||||||
|   | |||||||
							
								
								
									
										13
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										13
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -748,6 +748,14 @@ | |||||||
|       "resolved": "https://registry.npmjs.org/@types/node/-/node-12.0.7.tgz", |       "resolved": "https://registry.npmjs.org/@types/node/-/node-12.0.7.tgz", | ||||||
|       "integrity": "sha512-1YKeT4JitGgE4SOzyB9eMwO0nGVNkNEsm9qlIt1Lqm/tG2QEiSMTD4kS3aO6L+w5SClLVxALmIBESK6Mk5wX0A==" |       "integrity": "sha512-1YKeT4JitGgE4SOzyB9eMwO0nGVNkNEsm9qlIt1Lqm/tG2QEiSMTD4kS3aO6L+w5SClLVxALmIBESK6Mk5wX0A==" | ||||||
|     }, |     }, | ||||||
|  |     "@types/node-fetch": { | ||||||
|  |       "version": "2.5.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.0.tgz", | ||||||
|  |       "integrity": "sha512-TLFRywthBgL68auWj+ziWu+vnmmcHCDFC/sqCOQf1xTz4hRq8cu79z8CtHU9lncExGBsB8fXA4TiLDLt6xvMzw==", | ||||||
|  |       "requires": { | ||||||
|  |         "@types/node": "*" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "ajv": { |     "ajv": { | ||||||
|       "version": "6.10.0", |       "version": "6.10.0", | ||||||
|       "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", |       "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", | ||||||
| @@ -1541,6 +1549,11 @@ | |||||||
|       "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", |       "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", | ||||||
|       "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" |       "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" | ||||||
|     }, |     }, | ||||||
|  |     "node-fetch": { | ||||||
|  |       "version": "2.6.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", | ||||||
|  |       "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" | ||||||
|  |     }, | ||||||
|     "node-persist": { |     "node-persist": { | ||||||
|       "version": "0.0.8", |       "version": "0.0.8", | ||||||
|       "resolved": "https://registry.npmjs.org/node-persist/-/node-persist-0.0.8.tgz", |       "resolved": "https://registry.npmjs.org/node-persist/-/node-persist-0.0.8.tgz", | ||||||
|   | |||||||
| @@ -35,8 +35,10 @@ | |||||||
|         "@babel/preset-env": "^7.4.5", |         "@babel/preset-env": "^7.4.5", | ||||||
|         "@babel/preset-typescript": "^7.3.3", |         "@babel/preset-typescript": "^7.3.3", | ||||||
|         "@types/node": "^12.0.7", |         "@types/node": "^12.0.7", | ||||||
|  |         "@types/node-fetch": "^2.5.0", | ||||||
|         "harmony-websocket": "^1.1.0", |         "harmony-websocket": "^1.1.0", | ||||||
|         "homebridge": "^0.4.50", |         "homebridge": "^0.4.50", | ||||||
|  |         "node-fetch": "^2.6.0", | ||||||
|         "request": "^2.88.0" |         "request": "^2.88.0" | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -2,7 +2,7 @@ import { Activity } from '../Models/Activity'; | |||||||
| import { Matrix } from '../Models/Matrix'; | import { Matrix } from '../Models/Matrix'; | ||||||
| import { IAccessory } from './IAccessory'; | import { IAccessory } from './IAccessory'; | ||||||
| import callbackify from '../Util/Callbackify'; | import callbackify from '../Util/Callbackify'; | ||||||
| import HarmonyDataProvider from '../DataProviders/HarmonyDataProvider'; | import HubDataProvider from '../DataProviders/HubDataProvider'; | ||||||
|  |  | ||||||
| let Service: HAPNodeJS.Service; | let Service: HAPNodeJS.Service; | ||||||
| let Characteristic: HAPNodeJS.Characteristic; | let Characteristic: HAPNodeJS.Characteristic; | ||||||
| @@ -29,7 +29,7 @@ export enum RemoteKey { | |||||||
| } | } | ||||||
|  |  | ||||||
| export interface IControlUnitProps { | export interface IControlUnitProps { | ||||||
|     dataProvider: HarmonyDataProvider, |     dataProvider: HubDataProvider, | ||||||
|     displayName: string, |     displayName: string, | ||||||
|     activities: Array<Activity>, |     activities: Array<Activity>, | ||||||
|     api: any, |     api: any, | ||||||
| @@ -58,7 +58,7 @@ export class ControlUnit implements IAccessory { | |||||||
|  |  | ||||||
|     //Harmony fields |     //Harmony fields | ||||||
|     private activities: Array<Activity> = []; |     private activities: Array<Activity> = []; | ||||||
|     private dataProvider: HarmonyDataProvider; |     private dataProvider: HubDataProvider; | ||||||
|  |  | ||||||
|     public platformAccessory: any; |     public platformAccessory: any; | ||||||
|  |  | ||||||
| @@ -173,14 +173,6 @@ export class ControlUnit implements IAccessory { | |||||||
|      */ |      */ | ||||||
|     private onSetRemoteKey = async (key: any) => { |     private onSetRemoteKey = async (key: any) => { | ||||||
|         if (this.isExternal) { |         if (this.isExternal) { | ||||||
|             //Set the active identifier with every key press |  | ||||||
|             // let currentActivity: Activity = this.dataProvider.getIsActive(this.name)!; |  | ||||||
|             // let identifier: number = 0; |  | ||||||
|             // if (currentActivity) { |  | ||||||
|             //     identifier = this.activities.findIndex(e => e.displayName === currentActivity.displayName); |  | ||||||
|             // } |  | ||||||
|             // this.televisionService!.setCharacteristic(Characteristic.ActiveIdentifier, identifier); |  | ||||||
|  |  | ||||||
|             this.dataProvider.sendKeyPress(this.name, key); |             this.dataProvider.sendKeyPress(this.name, key); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -1,58 +1,69 @@ | |||||||
| import { Activity } from "../Models/Activity"; | import { Activity } from "../Models/Activity"; | ||||||
| import { DeviceSetupItem } from "../Models/DeviceSetupItem"; | import { DeviceSetupItem } from "../Models/DeviceSetupItem"; | ||||||
| import { Input, Matrix, Output } from "../Models/Matrix"; | import { Input, Matrix, Output } from "../Models/Matrix"; | ||||||
|  | import { IDevice } from './IDevice'; | ||||||
| import { RemoteKey } from '../Accessories/ControlUnit'; | import { RemoteKey } from '../Accessories/ControlUnit'; | ||||||
| import { sleep } from '../Util/Sleep'; | import { sleep } from '../Util/Sleep'; | ||||||
|  | import { hub } from ".."; | ||||||
|  | import fetch from 'node-fetch'; | ||||||
| 
 | 
 | ||||||
| let Characteristic: HAPNodeJS.Characteristic; | let Characteristic: HAPNodeJS.Characteristic; | ||||||
| 
 | 
 | ||||||
| const Harmony = require("harmony-websocket"); | const Harmony = require("harmony-websocket"); | ||||||
| interface IDevice { |  | ||||||
|     id: string, |  | ||||||
|     name: string, |  | ||||||
|     supportsCommand(commandName: string): boolean, |  | ||||||
|     getCommand(commandName: string): string, |  | ||||||
|     commands: { [name: string]: string }; |  | ||||||
|     on: boolean; |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| interface IActivityState { | interface IActivityState { | ||||||
|     currentActivity: Activity |     currentActivity: Activity | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| interface IHarmonyDataProviderProps { | interface IHubDataProviderProps { | ||||||
|     hubAddress: string, |     harmonyHubAddress: string, | ||||||
|  |     neeoHubAddress: string, | ||||||
|     log: any, |     log: any, | ||||||
|     matrix: Matrix |     matrix: Matrix | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| class HarmonyDataProvider { | interface INeeoMacro { | ||||||
|     private harmony: any; |     roomKey: string, | ||||||
|  |     macroKey: string, | ||||||
|  |     deviceKey: string, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | class HubDataProvider { | ||||||
|  |     //Harmony Fields
 | ||||||
|  |     private harmonyHubAddress: string; | ||||||
|  |     private harmonyConnected: boolean = false; | ||||||
|  | 
 | ||||||
|  |     //Neeo Fields
 | ||||||
|  |     private neeoHubAddress: string; | ||||||
|  | 
 | ||||||
|  |     //Common Fields
 | ||||||
|     private log: any; |     private log: any; | ||||||
|     private hubAddress: string = ""; |  | ||||||
|     private connected: boolean = false; |  | ||||||
| 
 | 
 | ||||||
|     private devices: { [name: string]: IDevice; } = {}; |     private devices: { [name: string]: IDevice; } = {}; | ||||||
|     private states: { [controlUnitName: string]: (IActivityState | undefined) } = {}; |     private states: { [controlUnitName: string]: (IActivityState | undefined) } = {}; | ||||||
| 
 | 
 | ||||||
|     private matrix: Matrix; |     private matrix: Matrix; | ||||||
| 
 | 
 | ||||||
|     constructor(props: IHarmonyDataProviderProps) { |     constructor(props: IHubDataProviderProps) { | ||||||
|         this.log = props.log; |         this.log = props.log; | ||||||
|         this.hubAddress = props.hubAddress; |         this.harmonyHubAddress = props.harmonyHubAddress; | ||||||
|  |         this.neeoHubAddress = props.neeoHubAddress; | ||||||
|         this.matrix = props.matrix; |         this.matrix = props.matrix; | ||||||
| 
 | 
 | ||||||
|         this.harmony = new Harmony(); |         if (this.harmonyHubAddress) { | ||||||
| 
 |             try { | ||||||
|         //Listeners
 |                 Promise.resolve(this.connectHarmony(this.harmonyHubAddress)); | ||||||
|         this.harmony.on('open', () => { |             } catch (err) { | ||||||
|             this.connected = true; |                 this.log(`Error connecting to harmony hub at ${this.harmonyHubAddress}: ${err}`); | ||||||
|         }); |             } | ||||||
|         this.harmony.on('close', () => { |         } | ||||||
|             this.connected = false; |         if (this.neeoHubAddress) { | ||||||
|         }); |             try { | ||||||
| 
 |                 Promise.resolve(this.connectNeeo(this.neeoHubAddress)); | ||||||
|         this.connect(); |             } catch (err) { | ||||||
|  |                 this.log(`Error connecting to neeo hub at ${this.neeoHubAddress}: ${err}`) | ||||||
|  |             } | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
| @@ -76,16 +87,21 @@ class HarmonyDataProvider { | |||||||
|         //Build potential list of devices to turn off
 |         //Build potential list of devices to turn off
 | ||||||
|         let devicesToTurnOff: Array<IDevice> = this.states[controlUnitName]!.currentActivity.deviceSetupItems |         let devicesToTurnOff: Array<IDevice> = this.states[controlUnitName]!.currentActivity.deviceSetupItems | ||||||
|             .map((value: DeviceSetupItem): IDevice => { |             .map((value: DeviceSetupItem): IDevice => { | ||||||
|                 return this.getDeviceFromName(value.deviceName); |                 return this.getDeviceFromName(value.deviceName, value.hubType); | ||||||
|             }); |             }); | ||||||
| 
 | 
 | ||||||
|         //Resolve device conflicts with other controlUnits
 |         //Resolve device conflicts with other controlUnits
 | ||||||
|         devicesToTurnOff = this.sanitizeDeviceList(devicesToTurnOff, controlUnitName); |         devicesToTurnOff = this.sanitizeDeviceList(devicesToTurnOff, controlUnitName); | ||||||
| 
 | 
 | ||||||
|  |         await Promise.all( | ||||||
|             //Turn off devices
 |             //Turn off devices
 | ||||||
|         devicesToTurnOff.forEach((device: IDevice) => { |             devicesToTurnOff.map(async (device: IDevice) => { | ||||||
|             this.powerOffDevice(device); |                 if (device) { | ||||||
|         }); |                     await device.powerOff(); | ||||||
|  |                 } | ||||||
|  |             }) | ||||||
|  |         ); | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
|         this.states[controlUnitName] = undefined; |         this.states[controlUnitName] = undefined; | ||||||
|     } |     } | ||||||
| @@ -102,7 +118,7 @@ class HarmonyDataProvider { | |||||||
| 
 | 
 | ||||||
|         //Build potential list of devices to to turn on
 |         //Build potential list of devices to to turn on
 | ||||||
|         let devicesToTurnOn: Array<IDevice> = activity.deviceSetupItems.map((value: DeviceSetupItem): IDevice => { |         let devicesToTurnOn: Array<IDevice> = activity.deviceSetupItems.map((value: DeviceSetupItem): IDevice => { | ||||||
|             return this.getDeviceFromName(value.deviceName); |             return this.getDeviceFromName(value.deviceName, value.hubType); | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|         //Resolve device conflicts with other controlUnits
 |         //Resolve device conflicts with other controlUnits
 | ||||||
| @@ -110,10 +126,10 @@ class HarmonyDataProvider { | |||||||
| 
 | 
 | ||||||
|         //Turn on devices
 |         //Turn on devices
 | ||||||
|         await Promise.all(devicesToTurnOn.map(async (device: IDevice) => { |         await Promise.all(devicesToTurnOn.map(async (device: IDevice) => { | ||||||
|             if (device && device.name && this.devices[device.name]) { |             if (device && device.name) { | ||||||
|                 if (!device.on) { |                 if (!device.on) { | ||||||
|                     this.log(`Turning on device ${device.name}`) |                     this.log(`Turning on device ${device.name}`) | ||||||
|                     await this.powerOnDevice(device); |                     await device.powerOn(); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         })); |         })); | ||||||
| @@ -121,11 +137,11 @@ class HarmonyDataProvider { | |||||||
|         //Assign correct input
 |         //Assign correct input
 | ||||||
|         await Promise.all( |         await Promise.all( | ||||||
|             activity.deviceSetupItems.map(async (value: DeviceSetupItem) => { |             activity.deviceSetupItems.map(async (value: DeviceSetupItem) => { | ||||||
|                 let device: IDevice = this.getDeviceFromName(value.deviceName); |                 let device: IDevice = this.getDeviceFromName(value.deviceName, value.hubType); | ||||||
| 
 | 
 | ||||||
|                 if (device && device.supportsCommand(`Input ${value.input}`)) { |                 if (device && device.supportsCommand(`Input ${value.input}`)) { | ||||||
|                     let command: string = device.getCommand(`Input ${value.input}`); |                     let command: string = device.getCommand(`Input ${value.input}`); | ||||||
|                     await this.sendCommand(command); |                     await device.sendCommand(command); | ||||||
|                 } |                 } | ||||||
|             }) |             }) | ||||||
|         ); |         ); | ||||||
| @@ -138,19 +154,19 @@ class HarmonyDataProvider { | |||||||
|             let inputCommandName: string = `In ${input.inputNumber}`; |             let inputCommandName: string = `In ${input.inputNumber}`; | ||||||
|             let outputCommandName: string = `Out ${output.outputLetter}`; |             let outputCommandName: string = `Out ${output.outputLetter}`; | ||||||
| 
 | 
 | ||||||
|             let matrixDevice: IDevice = this.getDeviceFromName(this.matrix.deviceName); |             let matrixDevice: IDevice = this.getDeviceFromName(this.matrix.deviceName, this.matrix.hubType); | ||||||
| 
 | 
 | ||||||
|             //Route hdmi
 |             //Route hdmi
 | ||||||
|             if (matrixDevice.supportsCommand(inputCommandName) && matrixDevice.supportsCommand(outputCommandName)) { |             if (matrixDevice.supportsCommand(inputCommandName) && matrixDevice.supportsCommand(outputCommandName)) { | ||||||
|                 await this.sendCommand(matrixDevice.getCommand(inputCommandName)); |                 await matrixDevice.sendCommand(matrixDevice.getCommand(inputCommandName)); | ||||||
|                 await this.sendCommand(matrixDevice.getCommand(outputCommandName)); |                 await matrixDevice.sendCommand(matrixDevice.getCommand(outputCommandName)); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         //Build potential list of devices to turn off
 |         //Build potential list of devices to turn off
 | ||||||
|         if (lastActivity) { |         if (lastActivity) { | ||||||
|             let devicesToTurnOff: Array<IDevice> = lastActivity.deviceSetupItems.map((value: DeviceSetupItem): IDevice => { |             let devicesToTurnOff: Array<IDevice> = lastActivity.deviceSetupItems.map((value: DeviceSetupItem): IDevice => { | ||||||
|                 return this.getDeviceFromName(value.deviceName); |                 return this.getDeviceFromName(value.deviceName, value.hubType); | ||||||
|             }); |             }); | ||||||
| 
 | 
 | ||||||
|             //remove devices that will be used for next activity from list
 |             //remove devices that will be used for next activity from list
 | ||||||
| @@ -174,7 +190,7 @@ class HarmonyDataProvider { | |||||||
|                     if (device) { |                     if (device) { | ||||||
|                         if (device.on) { |                         if (device.on) { | ||||||
|                             this.log(`Turning off device ${device.name}`) |                             this.log(`Turning off device ${device.name}`) | ||||||
|                             await this.powerOffDevice(device); |                             await device.powerOff(); | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|                 }) |                 }) | ||||||
| @@ -191,10 +207,13 @@ class HarmonyDataProvider { | |||||||
|      */ |      */ | ||||||
|     public volumeUp = async (controlUnitName: string) => { |     public volumeUp = async (controlUnitName: string) => { | ||||||
|         let volumeUpCommand: string = "Volume Up" |         let volumeUpCommand: string = "Volume Up" | ||||||
|  |         let currentActivity: Activity = this.states[controlUnitName]!.currentActivity; | ||||||
|  |         let deviceSetupItem: DeviceSetupItem = currentActivity.deviceSetupItems.filter(e => e.deviceName == currentActivity.volumeDeviceId)[0]; | ||||||
|  | 
 | ||||||
|         if (this.states[controlUnitName]) { |         if (this.states[controlUnitName]) { | ||||||
|             let volumeDevice: IDevice = this.getDeviceFromName(this.states[controlUnitName]!.currentActivity.volumeDeviceId); |             let volumeDevice: IDevice = this.getDeviceFromName(currentActivity.volumeDeviceId, deviceSetupItem.hubType); | ||||||
|             if (volumeDevice.supportsCommand(volumeUpCommand)) { |             if (volumeDevice.supportsCommand(volumeUpCommand)) { | ||||||
|                 this.sendCommand(volumeDevice.getCommand(volumeUpCommand)); |                 volumeDevice.sendCommand(volumeDevice.getCommand(volumeUpCommand)); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @@ -204,14 +223,52 @@ class HarmonyDataProvider { | |||||||
|      */ |      */ | ||||||
|     public volumeDown = async (controlUnitName: string) => { |     public volumeDown = async (controlUnitName: string) => { | ||||||
|         let volumeDownCommand: string = "Volume Down" |         let volumeDownCommand: string = "Volume Down" | ||||||
|  |         let currentActivity: Activity = this.states[controlUnitName]!.currentActivity; | ||||||
|  |         let deviceSetupItem: DeviceSetupItem = currentActivity.deviceSetupItems.filter(e => e.deviceName == currentActivity.volumeDeviceId)[0]; | ||||||
|  | 
 | ||||||
|         if (this.states[controlUnitName]) { |         if (this.states[controlUnitName]) { | ||||||
|             let volumeDevice: IDevice = this.getDeviceFromName(this.states[controlUnitName]!.currentActivity.volumeDeviceId); |             let volumeDevice: IDevice = this.getDeviceFromName(currentActivity.volumeDeviceId, deviceSetupItem.hubType); | ||||||
|             if (volumeDevice.supportsCommand(volumeDownCommand)) { |             if (volumeDevice.supportsCommand(volumeDownCommand)) { | ||||||
|                 this.sendCommand(volumeDevice.getCommand(volumeDownCommand)); |                 volumeDevice.sendCommand(volumeDevice.getCommand(volumeDownCommand)); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * Return if a control unit is active | ||||||
|  |      * @param controlUnitName  | ||||||
|  |      */ | ||||||
|  |     public getIsActive(controlUnitName: string): Activity | undefined { | ||||||
|  |         return this.states[controlUnitName] ? this.states[controlUnitName]!.currentActivity : undefined; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Helper function to make sure no control unit depends on device list. | ||||||
|  |      * @param devicesToTurnOn The list of devices to modify. | ||||||
|  |      * @param controlUnitName The name of the control unit in question. | ||||||
|  |      */ | ||||||
|  |     private sanitizeDeviceList(devicesToTurnOn: Array<IDevice>, controlUnitName: string): Array<IDevice> { | ||||||
|  |         for (let controlUnitKey in this.states) { | ||||||
|  |             //Skip self
 | ||||||
|  |             if (controlUnitKey === controlUnitName) { | ||||||
|  |                 continue; | ||||||
|  |             } | ||||||
|  |             let currentOtherState: IActivityState = this.states[controlUnitKey]!; | ||||||
|  | 
 | ||||||
|  |             if (currentOtherState) { | ||||||
|  |                 currentOtherState.currentActivity.deviceSetupItems.forEach((value: DeviceSetupItem) => { | ||||||
|  |                     //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]; | ||||||
|  |                         delete devicesToTurnOn[devicesToTurnOn.indexOf(deviceToRemove)]; | ||||||
|  |                     } | ||||||
|  |                 }); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return devicesToTurnOn; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /** |     /** | ||||||
|      * Send key press for current activity. |      * Send key press for current activity. | ||||||
|      *  |      *  | ||||||
| @@ -222,7 +279,10 @@ class HarmonyDataProvider { | |||||||
|         if (this.states[controlUnitName]) { |         if (this.states[controlUnitName]) { | ||||||
|             let commandName: string = ""; |             let commandName: string = ""; | ||||||
| 
 | 
 | ||||||
|             let device: IDevice = this.getDeviceFromName(this.states[controlUnitName]!.currentActivity.controlDeviceId); |             let currentActivity: Activity = this.states[controlUnitName]!.currentActivity; | ||||||
|  |             let deviceSetupItem: DeviceSetupItem = currentActivity.deviceSetupItems.filter(e => e.deviceName == currentActivity.volumeDeviceId)[0]; | ||||||
|  | 
 | ||||||
|  |             let device: IDevice = this.getDeviceFromName(this.states[controlUnitName]!.currentActivity.controlDeviceId, deviceSetupItem.hubType); | ||||||
|             switch (key) { |             switch (key) { | ||||||
|                 case RemoteKey.ARROW_UP: { |                 case RemoteKey.ARROW_UP: { | ||||||
|                     commandName = "Direction Up"; |                     commandName = "Direction Up"; | ||||||
| @@ -263,43 +323,54 @@ class HarmonyDataProvider { | |||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             if (device && device.supportsCommand(commandName)) { |             if (device && device.supportsCommand(commandName)) { | ||||||
|                 this.sendCommand(device.getCommand(commandName)); |                 device.sendCommand(device.getCommand(commandName)); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Return if a control unit is active |      * Get the IDevice by name. | ||||||
|      * @param controlUnitName  |      * @param deviceName The device to retrieve. | ||||||
|      */ |      */ | ||||||
|     public getIsActive(controlUnitName: string): Activity | undefined { |     private getDeviceFromName(deviceName: string, hubType: hub): IDevice { | ||||||
|         return this.states[controlUnitName] ? this.states[controlUnitName]!.currentActivity : undefined; |         return this.devices[`${hubType}-${deviceName}`]; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Connect to harmony and receive device info |      * Connect to harmony hub and receive device info. | ||||||
|      */ |      */ | ||||||
|     private connect = async () => { |     private connectHarmony = async (address: string): Promise<void> => { | ||||||
|         await this.harmony.connect(this.hubAddress); |         let harmony: any = new Harmony(); | ||||||
|  |         //Listeners
 | ||||||
|  |         harmony.on('open', () => { | ||||||
|  |             this.harmonyConnected = true; | ||||||
|  |         }); | ||||||
|  |         harmony.on('close', () => { | ||||||
|  |             this.harmonyConnected = false; | ||||||
|  |         }); | ||||||
|  |         await harmony.connect(address); | ||||||
|         let self = this; |         let self = this; | ||||||
| 
 | 
 | ||||||
|         setTimeout(async function () { |         setTimeout(async function () { | ||||||
|             if (self.connected) { |             if (self.harmonyConnected) { | ||||||
|                 let devices: any = await self.harmony.getDevices(); |                 let devices: any = await harmony.getDevices(); | ||||||
|                 try { |                 try { | ||||||
|                     await Promise.all( |                     await Promise.all( | ||||||
|                         //Add each to dictionary
 |                         //Add each to dictionary
 | ||||||
|                         devices.map(async (dev: any) => { |                         devices.map(async (dev: any) => { | ||||||
|                             //get commands
 |                             //get commands
 | ||||||
|                             let commands: { [name: string]: string } = {}; |                             let commands: { [name: string]: string } = {}; | ||||||
|                             let deviceCommands: any = await self.harmony.getDeviceCommands(dev.id); |                             let deviceCommands: any = await harmony.getDeviceCommands(dev.id); | ||||||
|                             deviceCommands.forEach((command: any) => { |                             deviceCommands.forEach((command: any) => { | ||||||
|                                 commands[command.label] = command.action; |                                 commands[command.label] = command.action; | ||||||
|                             }); |                             }); | ||||||
|                             self.devices[dev.label] = { |                             self.devices[`Harmony-${dev.label}`] = { | ||||||
|                                 id: dev.id, |                                 id: dev.id, | ||||||
|                                 name: dev.label, |                                 name: dev.label, | ||||||
|                                 commands: commands, |                                 commands: commands, | ||||||
|  |                                 harmony: harmony, | ||||||
|  |                                 hubType: "Harmony", | ||||||
|  |                                 log: self.log, | ||||||
|                                 on: false, |                                 on: false, | ||||||
|                                 //Define device methods
 |                                 //Define device methods
 | ||||||
|                                 supportsCommand(commandName: string): boolean { |                                 supportsCommand(commandName: string): boolean { | ||||||
| @@ -308,6 +379,39 @@ class HarmonyDataProvider { | |||||||
|                                 }, |                                 }, | ||||||
|                                 getCommand(commandName: string): string { |                                 getCommand(commandName: string): string { | ||||||
|                                     return commands[commandName]; |                                     return commands[commandName]; | ||||||
|  |                                 }, | ||||||
|  |                                 async powerOn(): Promise<void> { | ||||||
|  |                                     let powerOnCommand: string = "Power On"; | ||||||
|  |                                     let powerToggleCommand: string = "Power Toggle"; | ||||||
|  |                                     if (this.supportsCommand(powerOnCommand)) { | ||||||
|  |                                         await this.sendCommand(this.getCommand(powerOnCommand)); | ||||||
|  |                                         this.on = true; | ||||||
|  |                                     } else if (this.supportsCommand(powerToggleCommand)) { | ||||||
|  |                                         await this.sendCommand(this.getCommand(powerToggleCommand)); | ||||||
|  |                                         this.on = true; | ||||||
|  |                                     } | ||||||
|  |                                 }, | ||||||
|  |                                 async powerOff(): Promise<void> { | ||||||
|  |                                     let powerOffCommand: string = "Power Off"; | ||||||
|  |                                     let powerToggleCommand: string = "Power Toggle"; | ||||||
|  |                                     if (this.supportsCommand(powerOffCommand)) { | ||||||
|  |                                         await this.sendCommand(this.getCommand(powerOffCommand)); | ||||||
|  |                                         this.on = false; | ||||||
|  |                                     } else if (this.supportsCommand(powerToggleCommand)) { | ||||||
|  |                                         await this.sendCommand(this.getCommand(powerToggleCommand)); | ||||||
|  |                                         this.on = false; | ||||||
|  |                                     } | ||||||
|  |                                 }, | ||||||
|  |                                 async sendCommand(command: string): Promise<void> { | ||||||
|  |                                     try { | ||||||
|  |                                         //Execute command
 | ||||||
|  |                                         let response = await this.harmony.sendCommand(JSON.stringify(command)); | ||||||
|  | 
 | ||||||
|  |                                         //Sleep
 | ||||||
|  |                                         await sleep(800); | ||||||
|  |                                     } catch (err) { | ||||||
|  |                                         this.log(`ERROR - error sending command to harmony: ${err}`); | ||||||
|  |                                     } | ||||||
|                                 } |                                 } | ||||||
|                             } |                             } | ||||||
|                         })); |                         })); | ||||||
| @@ -320,87 +424,85 @@ class HarmonyDataProvider { | |||||||
|         }, 1000); |         }, 1000); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     private connectNeeo = async (address: string): Promise<void> => { | ||||||
|      * Power off a device (Power toggle if no power off). | 
 | ||||||
|      */ |         let baseUrl = `http://${address}:3000/v1/projects/home`; | ||||||
|     private powerOffDevice = async (device: IDevice) => { | 
 | ||||||
|         let powerOffCommand: string = "Power Off"; |         let response: any = await fetch(`${baseUrl}/rooms`); | ||||||
|         let powerToggleCommand: string = "Power Toggle"; |         let rooms: { [key: string]: any } = await response.json(); | ||||||
|         if (device && device.supportsCommand(powerOffCommand)) { | 
 | ||||||
|             await this.sendCommand(device.getCommand(powerOffCommand)); |         function regularizeString(str: string) { | ||||||
|             device.on = false; |             str = str.toLowerCase(); | ||||||
|         } else if (device && device.supportsCommand(powerToggleCommand)) { |             return str.replace(/(?:^|\s)\S/g, function (a) { return a.toUpperCase(); }); | ||||||
|             await this.sendCommand(device.getCommand(powerToggleCommand)); |  | ||||||
|             device.on = false; |  | ||||||
|         } |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|     /** |         for (let key in rooms) { | ||||||
|      * Power on a device (Power toggle if no power on). |             let devices: { [key: string]: any } = rooms[key].devices; | ||||||
|      */ |             for (let deviceKey in devices) { | ||||||
|     private powerOnDevice = async (device: IDevice) => { |                 let device = devices[deviceKey]; | ||||||
|  | 
 | ||||||
|  |                 //shape commands from macros
 | ||||||
|  |                 let commands: { [item: string]: any } = {}; | ||||||
|  |                 for (let macroKey in device.macros) { | ||||||
|  |                     let macro: any = device.macros[macroKey]; | ||||||
|  |                     commands[regularizeString(macro.name)] = { | ||||||
|  |                         deviceKey: macro.deviceKey, | ||||||
|  |                         macroKey: macro.key, | ||||||
|  |                         roomKey: macro.roomKey, | ||||||
|  |                     }; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 this.devices[`Neeo-${deviceKey}`] = { | ||||||
|  |                     id: device.key, | ||||||
|  |                     name: device.name, | ||||||
|  |                     log: this.log, | ||||||
|  |                     hubType: "Neeo", | ||||||
|  |                     commands: commands, | ||||||
|  |                     on: false, | ||||||
|  |                     supportsCommand(commandName: string): boolean { | ||||||
|  |                         let command = this.commands[commandName]; | ||||||
|  |                         return (command) ? true : false; | ||||||
|  |                     }, | ||||||
|  | 
 | ||||||
|  |                     getCommand(commandName: string): string { | ||||||
|  |                         return this.commands[commandName]; | ||||||
|  |                     }, | ||||||
|  | 
 | ||||||
|  |                     async sendCommand(command: string): Promise<void> { | ||||||
|  |                         if (this.supportsCommand(command)) { | ||||||
|  |                             let macro: INeeoMacro = this.commands[command]; | ||||||
|  |                             let url: string = `${baseUrl}/rooms/${macro.roomKey}/devices/${macro.deviceKey}/macros/${macro.macroKey}/trigger`; | ||||||
|  |                             this.log(`Sending command ${url}`); | ||||||
|  |                             fetch(`${baseUrl}/rooms/${macro.roomKey}/devices/${macro.deviceKey}/macros/${macro.macroKey}/trigger`); | ||||||
|  |                         } | ||||||
|  |                     }, | ||||||
|  | 
 | ||||||
|  |                     async powerOn(): Promise<void> { | ||||||
|                         let powerOnCommand: string = "Power On"; |                         let powerOnCommand: string = "Power On"; | ||||||
|                         let powerToggleCommand: string = "Power Toggle"; |                         let powerToggleCommand: string = "Power Toggle"; | ||||||
|         if (device && device.supportsCommand(powerOnCommand)) { |                         if (this.supportsCommand(powerOnCommand)) { | ||||||
|             await this.sendCommand(device.getCommand(powerOnCommand)); |                             await this.sendCommand(powerOnCommand); | ||||||
|             device.on = true; |                             this.on = true; | ||||||
|         } else if (device && device.supportsCommand(powerToggleCommand)) { |                         } else if (this.supportsCommand(powerToggleCommand)) { | ||||||
|             await this.sendCommand(device.getCommand(powerToggleCommand)); |                             await this.sendCommand(powerToggleCommand); | ||||||
|             device.on = true; |                             this.on = true; | ||||||
|  |                         } | ||||||
|  |                     }, | ||||||
|  |                     async powerOff(): Promise<void> { | ||||||
|  |                         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; | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|     /** | export default HubDataProvider; | ||||||
|      * Get the IDevice by name. |  | ||||||
|      * @param deviceName The device to retrieve. |  | ||||||
|      */ |  | ||||||
|     private getDeviceFromName(deviceName: string): IDevice { |  | ||||||
|         return this.devices[deviceName]; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Helper function to make sure no control unit depends on device list. |  | ||||||
|      * @param devicesToTurnOn The list of devices to modify. |  | ||||||
|      * @param controlUnitName The name of the control unit in question. |  | ||||||
|      */ |  | ||||||
|     private sanitizeDeviceList(devicesToTurnOn: Array<IDevice>, controlUnitName: string): Array<IDevice> { |  | ||||||
|         for (let controlUnitKey in this.states) { |  | ||||||
|             //Skip self
 |  | ||||||
|             if (controlUnitKey === controlUnitName) { |  | ||||||
|                 continue; |  | ||||||
|             } |  | ||||||
|             let currentOtherState: IActivityState = this.states[controlUnitKey]!; |  | ||||||
| 
 |  | ||||||
|             if (currentOtherState) { |  | ||||||
|                 currentOtherState.currentActivity.deviceSetupItems.forEach((value: DeviceSetupItem) => { |  | ||||||
|                     //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]; |  | ||||||
|                         delete devicesToTurnOn[devicesToTurnOn.indexOf(deviceToRemove)]; |  | ||||||
|                     } |  | ||||||
|                 }); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return devicesToTurnOn; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Send a command to the harmony hub. |  | ||||||
|      * @param command The command to send. |  | ||||||
|      */ |  | ||||||
|     private sendCommand = async (command: string) => { |  | ||||||
|         try { |  | ||||||
|             //Execute command
 |  | ||||||
|             let response = await this.harmony.sendCommand(JSON.stringify(command)); |  | ||||||
| 
 |  | ||||||
|             //Sleep
 |  | ||||||
|             await sleep(800); |  | ||||||
|         } catch (err) { |  | ||||||
|             this.log(`ERROR - error sending command to harmony: ${err}`); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| export default HarmonyDataProvider; |  | ||||||
							
								
								
									
										16
									
								
								src/DataProviders/IDevice.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/DataProviders/IDevice.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | |||||||
|  | import { hub } from ".."; | ||||||
|  |  | ||||||
|  | export interface IDevice { | ||||||
|  |     id: string, | ||||||
|  |     name: string, | ||||||
|  |     harmony?: any, | ||||||
|  |     log: any, | ||||||
|  |     hubType: hub | ||||||
|  |     supportsCommand(commandName: string): boolean, | ||||||
|  |     getCommand(commandName: string): string, | ||||||
|  |     sendCommand(command: string): void, | ||||||
|  |     powerOn(): Promise<void>, | ||||||
|  |     powerOff(): Promise<void>, | ||||||
|  |     commands: { [name: string]: any }; | ||||||
|  |     on: boolean; | ||||||
|  | } | ||||||
| @@ -1,7 +1,9 @@ | |||||||
|  | import { hub } from ".."; | ||||||
|  |  | ||||||
| export interface IDeviceSetupItemProps { | export interface IDeviceSetupItemProps { | ||||||
|     deviceName: string, |     deviceName: string, | ||||||
|     input: string |     input: string, | ||||||
|  |     hub: hub | ||||||
| } | } | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @@ -10,9 +12,11 @@ export interface IDeviceSetupItemProps { | |||||||
| export class DeviceSetupItem { | export class DeviceSetupItem { | ||||||
|     private _deviceId: string = ""; |     private _deviceId: string = ""; | ||||||
|     private _input: string = ""; |     private _input: string = ""; | ||||||
|  |     private _hubType: hub; | ||||||
|     constructor(props: IDeviceSetupItemProps) { |     constructor(props: IDeviceSetupItemProps) { | ||||||
|         this._deviceId = props.deviceName; |         this._deviceId = props.deviceName; | ||||||
|         this._input = props.input; |         this._input = props.input; | ||||||
|  |         this._hubType = props.hub; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public get deviceName() { |     public get deviceName() { | ||||||
| @@ -22,4 +26,8 @@ export class DeviceSetupItem { | |||||||
|     public get input() { |     public get input() { | ||||||
|         return this._input; |         return this._input; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public get hubType() { | ||||||
|  |         return this._hubType; | ||||||
|  |     } | ||||||
| } | } | ||||||
| @@ -1,7 +1,10 @@ | |||||||
|  | import { hub } from ".."; | ||||||
|  |  | ||||||
| export interface IMatrixProps { | export interface IMatrixProps { | ||||||
|     inputs: Array<Input>, |     inputs: Array<Input>, | ||||||
|     outputs: Array<Output>, |     outputs: Array<Output>, | ||||||
|     deviceName: string, |     deviceName: string, | ||||||
|  |     hubType: hub | ||||||
| } | } | ||||||
|  |  | ||||||
| export interface Input { | export interface Input { | ||||||
| @@ -21,11 +24,13 @@ export class Matrix { | |||||||
|     private _inputs: Array<Input> = []; |     private _inputs: Array<Input> = []; | ||||||
|     private _outputs: Array<Output> = []; |     private _outputs: Array<Output> = []; | ||||||
|     private _deviceName: string; |     private _deviceName: string; | ||||||
|  |     private _hubType: hub = "Harmony"; | ||||||
|  |  | ||||||
|     constructor(props: IMatrixProps) { |     constructor(props: IMatrixProps) { | ||||||
|         this._inputs = props.inputs; |         this._inputs = props.inputs; | ||||||
|         this._outputs = props.outputs; |         this._outputs = props.outputs; | ||||||
|         this._deviceName = props.deviceName; |         this._deviceName = props.deviceName; | ||||||
|  |         this._hubType = props.hubType; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public get inputs(): Array<Input> { |     public get inputs(): Array<Input> { | ||||||
| @@ -39,4 +44,8 @@ export class Matrix { | |||||||
|     public get deviceName(): string { |     public get deviceName(): string { | ||||||
|         return this._deviceName; |         return this._deviceName; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public get hubType(): hub { | ||||||
|  |         return this._hubType; | ||||||
|  |     } | ||||||
| } | } | ||||||
							
								
								
									
										19
									
								
								src/index.ts
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								src/index.ts
									
									
									
									
									
								
							| @@ -2,11 +2,13 @@ import { ControlUnit } from "./Accessories/ControlUnit"; | |||||||
| import { Activity } from "./Models/Activity"; | import { Activity } from "./Models/Activity"; | ||||||
| import { DeviceSetupItem } from "./Models/DeviceSetupItem"; | import { DeviceSetupItem } from "./Models/DeviceSetupItem"; | ||||||
| import { Input, Output, Matrix } from "./Models/Matrix"; | import { Input, Output, Matrix } from "./Models/Matrix"; | ||||||
| import HarmonyDataProvider from "./DataProviders/HarmonyDataProvider"; | import HubDataProvider from './DataProviders/HubDataProvider'; | ||||||
|  |  | ||||||
| let Accessory: any; | let Accessory: any; | ||||||
| let Homebridge: any; | let Homebridge: any; | ||||||
|  |  | ||||||
|  | export type hub = "Harmony" | "Neeo"; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Main entry. |  * Main entry. | ||||||
|  * @param homebridge  |  * @param homebridge  | ||||||
| @@ -27,7 +29,7 @@ class HarmonyMatrixPlatform { | |||||||
|     config: any = {}; |     config: any = {}; | ||||||
|     api: any; |     api: any; | ||||||
|     externalAccessories: Array<any> = []; |     externalAccessories: Array<any> = []; | ||||||
|     dataProvider: HarmonyDataProvider | null; |     dataProvider: HubDataProvider | null; | ||||||
|  |  | ||||||
|     constructor(log: any, config: any, api: any) { |     constructor(log: any, config: any, api: any) { | ||||||
|         this.log = log; |         this.log = log; | ||||||
| @@ -60,12 +62,14 @@ class HarmonyMatrixPlatform { | |||||||
|      */ |      */ | ||||||
|     accessories(callback: (accessories: Array<ControlUnit>) => void) { |     accessories(callback: (accessories: Array<ControlUnit>) => void) { | ||||||
|         //Parse ip |         //Parse ip | ||||||
|         let hubIp: string = this.config["hubIp"]; |         let harmonyIp: string = this.config["harmonyHubIp"]; | ||||||
|  |         let neeoIp: string = this.config["neeoHubIp"]; | ||||||
|  |  | ||||||
|         //Parse matrix |         //Parse matrix | ||||||
|         let configInputs: any = this.config["Matrix"]["Inputs"]; |         let configInputs: any = this.config["Matrix"]["Inputs"]; | ||||||
|         let configOutputs: any = this.config["Matrix"]["Outputs"]; |         let configOutputs: any = this.config["Matrix"]["Outputs"]; | ||||||
|         let matrixName: string = this.config["Matrix"]["DeviceName"]; |         let matrixName: string = this.config["Matrix"]["DeviceName"]; | ||||||
|  |         let hub: hub = this.config["Matrix"]["Hub"]; | ||||||
|  |  | ||||||
|         let inputs: Array<Input> = []; |         let inputs: Array<Input> = []; | ||||||
|         let outputs: Array<Output> = []; |         let outputs: Array<Output> = []; | ||||||
| @@ -98,11 +102,13 @@ class HarmonyMatrixPlatform { | |||||||
|             inputs: inputs, |             inputs: inputs, | ||||||
|             outputs: outputs, |             outputs: outputs, | ||||||
|             deviceName: matrixName, |             deviceName: matrixName, | ||||||
|  |             hubType: hub | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|         //construct data provider |         //construct data provider | ||||||
|         this.dataProvider = new HarmonyDataProvider({ |         this.dataProvider = new HubDataProvider({ | ||||||
|             hubAddress: hubIp, |             harmonyHubAddress: harmonyIp, | ||||||
|  |             neeoHubAddress: neeoIp, | ||||||
|             matrix: matrix, |             matrix: matrix, | ||||||
|             log: this.log |             log: this.log | ||||||
|         }); |         }); | ||||||
| @@ -122,7 +128,8 @@ class HarmonyMatrixPlatform { | |||||||
|                     //Add device |                     //Add device | ||||||
|                     devices.push(new DeviceSetupItem({ |                     devices.push(new DeviceSetupItem({ | ||||||
|                         deviceName: configDevice["DeviceName"], |                         deviceName: configDevice["DeviceName"], | ||||||
|                         input: configDevice["Input"] |                         input: configDevice["Input"], | ||||||
|  |                         hub: configDevice["Hub"] | ||||||
|                     })); |                     })); | ||||||
|                     this.log(`INFO - Added device '${configDevice["DeviceName"]}' for activity '${configActivity["DisplayName"]}'`); |                     this.log(`INFO - Added device '${configDevice["DeviceName"]}' for activity '${configActivity["DisplayName"]}'`); | ||||||
|                 }); |                 }); | ||||||
|   | |||||||
| @@ -5,6 +5,7 @@ | |||||||
|         "declaration": true, |         "declaration": true, | ||||||
|         "outDir": "./bin", |         "outDir": "./bin", | ||||||
|         "strict": true, |         "strict": true, | ||||||
|  |         "sourceMap": true, | ||||||
|     }, |     }, | ||||||
|     "include": [ |     "include": [ | ||||||
|         "src" |         "src" | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user