diff --git a/src/Accessories/ControlUnit.ts b/src/Accessories/ControlUnit.ts index 92c015a..3e99062 100644 --- a/src/Accessories/ControlUnit.ts +++ b/src/Accessories/ControlUnit.ts @@ -7,6 +7,7 @@ import HarmonyDataProvider from '../DataProviders/HarmonyDataProvider'; let Service: HAPNodeJS.Service; let Characteristic: HAPNodeJS.Characteristic; let Api: any; +let homebridge: any; export interface IControlUnitProps { dataProvider: HarmonyDataProvider, @@ -14,6 +15,7 @@ export interface IControlUnitProps { activities: Array, api: any, log: any, + homebridge: any, } /** @@ -37,6 +39,8 @@ export class ControlUnit implements IAccessory { private activities: Array = []; private dataProvider: HarmonyDataProvider; + public platformAccessory: any; + /** * Constructor * @param props Input properties @@ -53,12 +57,28 @@ export class ControlUnit implements IAccessory { this.activities = props.activities; this.dataProvider = props.dataProvider; + homebridge = props.homebridge; + + this.platformAccessory = new homebridge.platformAccessory(this.name, this.generateUUID(), homebridge.hap.Accessory.Categories.TELEVISION); //Configure services this.configureTvService(); this.configureTvSpeakerService(); // this.configureAccessoryInformation(); this.configureInputSourceService(); + + //Configure external services + this.getServices().forEach(service => { + try { + this.platformAccessory.addService(service); + } catch (error) { } + + //@ts-ignore + if (service.linked) { + //@ts-ignore + this.televisionService!.addLinkedService(service); + } + }); } /************* * @@ -106,6 +126,7 @@ export class ControlUnit implements IAccessory { this.log(`set active + ${value}`); switch (value) { case 0: this.dataProvider.powerOff(this.name); break; + //Turn on with first activity case 1: this.dataProvider.powerOn(this.name, this.activities[0]); break; } } @@ -162,9 +183,9 @@ export class ControlUnit implements IAccessory { ); this.televisionSpeakerService.setCharacteristic(Characteristic.Name, this.displayName); //@ts-ignore - this.televisionSpeakerService.setCharacteristic(Characteristic.Active, Characteristic.Active.Active); + this.televisionSpeakerService.setCharacteristic(Characteristic.Active, Characteristic.Active.ACTIVE); //@ts-ignore - this.televisionSpeakerService.setCharacteristic(Characteristic.VolumeControlType, Characteristic.VolumeControlType.Absolute); + this.televisionSpeakerService.setCharacteristic(Characteristic.VolumeControlType, Characteristic.VolumeControlType.ABSOLUTE); this.televisionSpeakerService.subtype = this.displayName + "Volume"; if (this.televisionService) { //@ts-ignore @@ -232,6 +253,18 @@ export class ControlUnit implements IAccessory { this.inputServices = inputs; } + private generateUUID(): string { // Public Domain/MIT + var d = new Date().getTime(); + if (typeof performance !== 'undefined' && typeof performance.now === 'function') { + d += performance.now(); //use high-precision timer if available + } + return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { + var r = (d + Math.random() * 16) % 16 | 0; + d = Math.floor(d / 16); + return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16); + }); + } + /** diff --git a/src/index.ts b/src/index.ts index 302332b..7986564 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,7 +4,12 @@ import { DeviceSetupItem } from "./Models/DeviceSetupItem"; import { Input, Output, Matrix } from "./Models/Matrix"; import HarmonyDataProvider from "./DataProviders/HarmonyDataProvider"; +let Accessory: any; +let Homebridge: any; + export default function (homebridge: any) { + Homebridge = homebridge; + Accessory = homebridge.platformAccessory; homebridge.registerPlatform( 'homebridge-harmony-watson', 'HarmonyHubMatrix', @@ -17,12 +22,23 @@ class HarmonyMatrixPlatform { log: any = {}; config: any = {}; api: any; + externalAccessories: Array = []; constructor(log: any, config: any, api: any) { this.log = log; this.config = config; this.api = api; this.log('INFO - Registering Harmony Matrix Platform'); + this.api.on('didFinishLaunching', this.didFinishLaunching.bind(this)); + } + + didFinishLaunching() { + this.log(`Publishing external accessories`); + + this.externalAccessories.forEach((accessory: ControlUnit) => { + this.api.publishExternalAccessories("HarmonyMatrixPlatform", [accessory.platformAccessory]); + }) + } /** @@ -75,7 +91,7 @@ class HarmonyMatrixPlatform { let dataProvider = new HarmonyDataProvider({ hubAddress: hubIp, matrix: matrix, - log: this.log, + log: this.log }); //Parse control units @@ -110,16 +126,27 @@ class HarmonyMatrixPlatform { this.log(`INFO - Added activity '${configActivity["DisplayName"]}'`); }); - //Add control unit - controlUnits.push(new ControlUnit({ + // let accessory = new Accessory(configControlUnit["DisplayName"], + // Homebridge.hap.uuid.generate(configControlUnit["DisplayName"], Homebridge.hap.Accessory.Categories.TELEVISION)); + + let controlUnit: ControlUnit = new ControlUnit({ dataProvider: dataProvider, displayName: configControlUnit["DisplayName"], api: this.api, log: this.log, activities: activities, - })); + homebridge: Homebridge + }); + + //@ts-ignore + let accessory = controlUnit as homebridge.platformAccessory; + + //Add control unit + controlUnits.push(accessory); + this.log(`INFO - Added ControlUnit`); }); + this.externalAccessories = controlUnits; callback(controlUnits); } } \ No newline at end of file