Successfully added tsyringe to project
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
@ -7,6 +7,9 @@ import { IHub } from "../Models/Config/IHub";
|
||||
import { IDeviceConfig } from "../Models/Config/IDeviceConfig";
|
||||
import { HarmonyDevice } from "../Models/HarmonyDevice";
|
||||
import { HarmonyHub } from "../Models/HarmonyHub";
|
||||
import { IConfig } from "../Models/Config";
|
||||
import { inject, injectable } from "tsyringe";
|
||||
import { Logger, Logging } from "homebridge";
|
||||
|
||||
const Harmony = require("harmony-websocket");
|
||||
|
||||
@ -21,8 +24,8 @@ interface IHarmonyDataProviderProps {
|
||||
matrix: IMatrix;
|
||||
}
|
||||
|
||||
@injectable()
|
||||
class HarmonyDataProvider extends EventEmitter {
|
||||
private _log: any;
|
||||
private _hubsByDevice: { [deviceName: string]: string } = {};
|
||||
private _hubs: { [hubName: string]: HarmonyHub } = {};
|
||||
// private _devicesByHub: { [hubName: string]: { [deviceName: string]: HarmonyDevice } } = {};
|
||||
@ -32,16 +35,18 @@ class HarmonyDataProvider extends EventEmitter {
|
||||
|
||||
private _matrix: IMatrix;
|
||||
|
||||
constructor(props: IHarmonyDataProviderProps) {
|
||||
constructor(
|
||||
@inject("IConfig") private _config: IConfig,
|
||||
@inject("log") private _log: Logging
|
||||
) {
|
||||
super();
|
||||
this._log = props.log;
|
||||
this._matrix = props.matrix;
|
||||
props.deviceConfigs.forEach((deviceConfig: IDeviceConfig) => {
|
||||
this._matrix = _config.Matrix;
|
||||
_config.Devices.forEach((deviceConfig: IDeviceConfig) => {
|
||||
this._hubsByDevice[deviceConfig.Name] = deviceConfig.Hub;
|
||||
});
|
||||
// this._deviceConfigs = props.deviceConfigs;
|
||||
|
||||
this.connect(props.hubs);
|
||||
this.connect(_config.Hubs);
|
||||
}
|
||||
|
||||
// public get devicesByHub(): { [hubName: string]: { [deviceName: string]: HarmonyDevice } } {
|
||||
@ -104,7 +109,7 @@ class HarmonyDataProvider extends EventEmitter {
|
||||
controlUnitName: string,
|
||||
activity: IActivity
|
||||
) => {
|
||||
this._log(
|
||||
this._log.info(
|
||||
`Starting activity ${activity.DisplayName} for controlUnit: ${controlUnitName}`
|
||||
);
|
||||
let lastActivity: IActivity | undefined = undefined;
|
||||
@ -127,7 +132,7 @@ class HarmonyDataProvider extends EventEmitter {
|
||||
devicesToTurnOn.map(async (device: HarmonyDevice) => {
|
||||
if (device && device.name) {
|
||||
if (!device.on) {
|
||||
this._log(`Turning on device ${device.name}`);
|
||||
this._log.info(`Turning on device ${device.name}`);
|
||||
await device.powerOn();
|
||||
}
|
||||
}
|
||||
@ -175,11 +180,12 @@ class HarmonyDataProvider extends EventEmitter {
|
||||
|
||||
//Build potential list of devices to turn off
|
||||
if (lastActivity) {
|
||||
let devicesToTurnOff: Array<HarmonyDevice> = lastActivity.DeviceSetupList.map(
|
||||
(value: IDeviceSetupItem): HarmonyDevice => {
|
||||
return this.getDeviceFromName(value.DeviceName);
|
||||
}
|
||||
);
|
||||
let devicesToTurnOff: Array<HarmonyDevice> =
|
||||
lastActivity.DeviceSetupList.map(
|
||||
(value: IDeviceSetupItem): HarmonyDevice => {
|
||||
return this.getDeviceFromName(value.DeviceName);
|
||||
}
|
||||
);
|
||||
|
||||
//remove devices that will be used for next activity from list
|
||||
//delete array[index] is stupid because it just nulls out the index. But now i have to deal with nulls
|
||||
@ -201,7 +207,7 @@ class HarmonyDataProvider extends EventEmitter {
|
||||
controlUnitName
|
||||
);
|
||||
|
||||
this._log(
|
||||
this._log.info(
|
||||
`Sanatized devices to turn off: ${JSON.stringify(
|
||||
devicesToTurnOff.map((e) => (e ? e.name : ""))
|
||||
)}`
|
||||
@ -212,7 +218,7 @@ class HarmonyDataProvider extends EventEmitter {
|
||||
devicesToTurnOff.map(async (device: HarmonyDevice) => {
|
||||
if (device) {
|
||||
if (device.on) {
|
||||
this._log(`Turning off device ${device.name}`);
|
||||
this._log.info(`Turning off device ${device.name}`);
|
||||
await device.powerOff();
|
||||
}
|
||||
}
|
||||
@ -323,11 +329,10 @@ class HarmonyDataProvider extends EventEmitter {
|
||||
public getDeviceFromName(deviceName: string): HarmonyDevice {
|
||||
let device: HarmonyDevice | undefined;
|
||||
try {
|
||||
device = this._hubs[this._hubsByDevice[deviceName]].getDeviceByName(
|
||||
deviceName
|
||||
);
|
||||
device =
|
||||
this._hubs[this._hubsByDevice[deviceName]].getDeviceByName(deviceName);
|
||||
} catch (err) {
|
||||
this._log(`Error retrieving device from hub: ${err}`);
|
||||
this._log.info(`Error retrieving device from hub: ${err}`);
|
||||
}
|
||||
|
||||
return device!;
|
||||
@ -350,19 +355,17 @@ class HarmonyDataProvider extends EventEmitter {
|
||||
private connect = async (hubs: Array<IHub>) => {
|
||||
let readyCount = 0;
|
||||
await Promise.all(
|
||||
hubs.map(
|
||||
async (hub: IHub): Promise<void> => {
|
||||
const newHarmonyHub = new HarmonyHub(hub.Name, hub.Ip, this._log);
|
||||
this._hubs[hub.Name] = newHarmonyHub;
|
||||
newHarmonyHub.on("Ready", () => {
|
||||
readyCount++;
|
||||
if (readyCount === Object.keys(this._hubs).length) {
|
||||
this.emit("Ready");
|
||||
}
|
||||
});
|
||||
await newHarmonyHub.initialize();
|
||||
}
|
||||
)
|
||||
hubs.map(async (hub: IHub): Promise<void> => {
|
||||
const newHarmonyHub = new HarmonyHub(hub.Name, hub.Ip, this._log.info);
|
||||
this._hubs[hub.Name] = newHarmonyHub;
|
||||
newHarmonyHub.on("Ready", () => {
|
||||
readyCount++;
|
||||
if (readyCount === Object.keys(this._hubs).length) {
|
||||
this.emit("Ready");
|
||||
}
|
||||
});
|
||||
await newHarmonyHub.initialize();
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
|
141
src/platform.ts
141
src/platform.ts
@ -1,3 +1,4 @@
|
||||
import "reflect-metadata";
|
||||
import {
|
||||
API,
|
||||
Characteristic,
|
||||
@ -12,9 +13,8 @@ import { Sequence } from "./Accessories/Sequence";
|
||||
import HarmonyDataProvider from "./DataProviders/HarmonyDataProvider";
|
||||
import { IConfig, IControlUnit, IDeviceButton } from "./Models/Config";
|
||||
import { ISequence } from "./Models/Config/ISequence";
|
||||
import { HarmonyDevice } from "./Models/HarmonyDevice";
|
||||
import { HarmonyHub } from "./Models/HarmonyHub";
|
||||
import { PLATFORM_NAME, PLUGIN_NAME } from "./settings";
|
||||
import { container } from "tsyringe";
|
||||
|
||||
export class Platform implements DynamicPlatformPlugin {
|
||||
constructor(
|
||||
@ -23,57 +23,58 @@ export class Platform implements DynamicPlatformPlugin {
|
||||
public readonly api: API
|
||||
) {
|
||||
this.log.debug("Finished initializing platform:", config.name);
|
||||
|
||||
this.config = config as unknown as IConfig;
|
||||
this.register();
|
||||
|
||||
//construct data provider
|
||||
const dataProvider = new HarmonyDataProvider({
|
||||
hubs: this.config.Hubs,
|
||||
deviceConfigs: this.config.Devices,
|
||||
matrix: this.config.Matrix,
|
||||
log: this.log,
|
||||
});
|
||||
// const dataProvider = new HarmonyDataProvider({
|
||||
// hubs: this.config.Hubs,
|
||||
// deviceConfigs: this.config.Devices,
|
||||
// matrix: this.config.Matrix,
|
||||
// log: this.log,
|
||||
// });
|
||||
|
||||
let didFinishLaunching = false;
|
||||
this.api.on("didFinishLaunching", async () => {
|
||||
log.debug("Executed didFinishLaunching callback");
|
||||
this.discoverControlUnitAccessories();
|
||||
this.discoverDeviceButtonAccessories();
|
||||
this.discoverSequenceAccessories();
|
||||
this.pruneAccessories();
|
||||
didFinishLaunching = true;
|
||||
});
|
||||
|
||||
this.dataProvider = null;
|
||||
// this.dataProvider = null;
|
||||
|
||||
if (this.config) {
|
||||
//construct data provider
|
||||
this.dataProvider = new HarmonyDataProvider({
|
||||
hubs: this.config.Hubs,
|
||||
deviceConfigs: this.config.Devices,
|
||||
matrix: this.config.Matrix,
|
||||
log: this.log,
|
||||
});
|
||||
|
||||
// this.dataProvider = new HarmonyDataProvider({
|
||||
// hubs: this.config.Hubs,
|
||||
// deviceConfigs: this.config.Devices,
|
||||
// matrix: this.config.Matrix,
|
||||
// log: this.log,
|
||||
// });
|
||||
//Emit devices if requested
|
||||
|
||||
this.dataProvider.on("Ready", () => {
|
||||
this.log.info("All hubs connected");
|
||||
this.discoverControlUnitAccessories(dataProvider);
|
||||
this.discoverDeviceButtonAccessories(dataProvider);
|
||||
this.discoverSequenceAccessories(dataProvider);
|
||||
this.pruneAccessories();
|
||||
|
||||
if (this.config.EmitDevicesOnStartup) {
|
||||
const hubs = this.dataProvider!.hubs;
|
||||
Object.values(hubs).forEach((hub: HarmonyHub) => {
|
||||
const deviceDictionary = hub.devices;
|
||||
this.log.info(`${hub.hubName}`);
|
||||
|
||||
Object.values(deviceDictionary).forEach((device: HarmonyDevice) => {
|
||||
this.log.info(` ${device.name} : ${device.id}`);
|
||||
Object.keys(device.commands).forEach((command: string) => {
|
||||
this.log.info(` ${command}`);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
// this.dataProvider.on("Ready", () => {
|
||||
// this.log.info("All hubs connected");
|
||||
// this.discoverControlUnitAccessories(dataProvider);
|
||||
// this.discoverDeviceButtonAccessories(dataProvider);
|
||||
// this.discoverSequenceAccessories(dataProvider);
|
||||
// this.pruneAccessories();
|
||||
// if (this.config.EmitDevicesOnStartup) {
|
||||
// const hubs = this.dataProvider!.hubs;
|
||||
// Object.values(hubs).forEach((hub: HarmonyHub) => {
|
||||
// const deviceDictionary = hub.devices;
|
||||
// this.log.info(`${hub.hubName}`);
|
||||
// Object.values(deviceDictionary).forEach((device: HarmonyDevice) => {
|
||||
// this.log.info(` ${device.name} : ${device.id}`);
|
||||
// Object.keys(device.commands).forEach((command: string) => {
|
||||
// this.log.info(` ${command}`);
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// }
|
||||
// });
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,15 +85,12 @@ export class Platform implements DynamicPlatformPlugin {
|
||||
// this is used to track restored cached accessories
|
||||
public readonly accessories: PlatformAccessory[] = [];
|
||||
public config: IConfig;
|
||||
public dataProvider: HarmonyDataProvider | null;
|
||||
|
||||
/**
|
||||
* Discover new control unit accessories
|
||||
* @param dataProvider
|
||||
*/
|
||||
private discoverControlUnitAccessories(
|
||||
dataProvider: HarmonyDataProvider
|
||||
): void {
|
||||
private discoverControlUnitAccessories(): void {
|
||||
this.config.ControlUnits.forEach((unit: IControlUnit) => {
|
||||
const uuid = this.api.hap.uuid.generate(unit.DisplayName);
|
||||
const existingAccessory = this.accessories.find((e) => e.UUID === uuid);
|
||||
@ -103,7 +101,12 @@ export class Platform implements DynamicPlatformPlugin {
|
||||
existingAccessory.displayName
|
||||
);
|
||||
|
||||
new ControlUnit(this, existingAccessory, dataProvider, unit.Activities);
|
||||
new ControlUnit(
|
||||
this,
|
||||
existingAccessory,
|
||||
container.resolve(HarmonyDataProvider),
|
||||
unit.Activities
|
||||
);
|
||||
|
||||
this.api.publishExternalAccessories(PLUGIN_NAME, [existingAccessory]);
|
||||
console.log("Publishing external accessory: " + uuid);
|
||||
@ -116,7 +119,12 @@ export class Platform implements DynamicPlatformPlugin {
|
||||
accessory.context["DeviceName"] = unit.DisplayName;
|
||||
accessory.context["Type"] = typeof ControlUnit.name;
|
||||
|
||||
new ControlUnit(this, accessory, dataProvider, unit.Activities);
|
||||
new ControlUnit(
|
||||
this,
|
||||
accessory,
|
||||
container.resolve(HarmonyDataProvider),
|
||||
unit.Activities
|
||||
);
|
||||
|
||||
this.api.publishExternalAccessories(PLUGIN_NAME, [accessory]);
|
||||
console.log("Publishing external accessory: " + uuid);
|
||||
@ -128,9 +136,7 @@ export class Platform implements DynamicPlatformPlugin {
|
||||
* Discover new device button accessories
|
||||
* @param dataProvider
|
||||
*/
|
||||
private discoverDeviceButtonAccessories(
|
||||
dataProvider: HarmonyDataProvider
|
||||
): void {
|
||||
private discoverDeviceButtonAccessories(): void {
|
||||
this.config.DeviceButtons.forEach((button: IDeviceButton) => {
|
||||
const uuid = this.api.hap.uuid.generate(button.DisplayName);
|
||||
const existingAccessory = this.accessories.find((e) => e.UUID === uuid);
|
||||
@ -140,7 +146,12 @@ export class Platform implements DynamicPlatformPlugin {
|
||||
existingAccessory.displayName
|
||||
);
|
||||
|
||||
new DeviceButton(this, existingAccessory, dataProvider, button);
|
||||
new DeviceButton(
|
||||
this,
|
||||
existingAccessory,
|
||||
container.resolve(HarmonyDataProvider),
|
||||
button
|
||||
);
|
||||
this.api.updatePlatformAccessories([existingAccessory]);
|
||||
} else {
|
||||
this.log.info("Adding new accessory: " + button.DisplayName);
|
||||
@ -151,7 +162,12 @@ export class Platform implements DynamicPlatformPlugin {
|
||||
accessory.context["DeviceName"] = button.DisplayName;
|
||||
accessory.context["Type"] = typeof DeviceButton;
|
||||
|
||||
new DeviceButton(this, accessory, dataProvider, button);
|
||||
new DeviceButton(
|
||||
this,
|
||||
accessory,
|
||||
container.resolve(HarmonyDataProvider),
|
||||
button
|
||||
);
|
||||
|
||||
this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [
|
||||
accessory,
|
||||
@ -165,7 +181,7 @@ export class Platform implements DynamicPlatformPlugin {
|
||||
* Discover new sequence accessories
|
||||
* @param dataProvider
|
||||
*/
|
||||
private discoverSequenceAccessories(dataProvider: HarmonyDataProvider): void {
|
||||
private discoverSequenceAccessories(): void {
|
||||
this.config.Sequences.forEach((sequence: ISequence) => {
|
||||
const uuid = this.api.hap.uuid.generate(sequence.DisplayName);
|
||||
const existingAccessory = this.accessories.find((e) => e.UUID === uuid);
|
||||
@ -175,7 +191,12 @@ export class Platform implements DynamicPlatformPlugin {
|
||||
existingAccessory.displayName
|
||||
);
|
||||
|
||||
new Sequence(this, existingAccessory, dataProvider, sequence);
|
||||
new Sequence(
|
||||
this,
|
||||
existingAccessory,
|
||||
container.resolve(HarmonyDataProvider),
|
||||
sequence
|
||||
);
|
||||
this.api.updatePlatformAccessories([existingAccessory]);
|
||||
} else {
|
||||
this.log.info("Adding new accessory: " + sequence.DisplayName);
|
||||
@ -186,7 +207,12 @@ export class Platform implements DynamicPlatformPlugin {
|
||||
accessory.context["DeviceName"] = sequence.DisplayName;
|
||||
accessory.context["Type"] = typeof "Sequence";
|
||||
|
||||
new Sequence(this, accessory, dataProvider, sequence);
|
||||
new Sequence(
|
||||
this,
|
||||
accessory,
|
||||
container.resolve(HarmonyDataProvider),
|
||||
sequence
|
||||
);
|
||||
|
||||
this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [
|
||||
accessory,
|
||||
@ -222,4 +248,11 @@ export class Platform implements DynamicPlatformPlugin {
|
||||
// add the restored accessory to the accessories cache so we can track if it has already been registered
|
||||
this.accessories.push(accessory);
|
||||
}
|
||||
|
||||
private register(): void {
|
||||
container.register<Platform>(Platform, { useValue: this });
|
||||
container.register<IConfig>("IConfig", { useValue: this.config });
|
||||
container.register<Logger>("log", { useValue: this.log });
|
||||
container.registerSingleton<HarmonyDataProvider>(HarmonyDataProvider);
|
||||
}
|
||||
}
|
||||
|
@ -6,4 +6,4 @@ export const PLATFORM_NAME = "HarmonyHubMatrix";
|
||||
/**
|
||||
* This must match the name of your plugin as defined the package.json
|
||||
*/
|
||||
export const PLUGIN_NAME = "homebridge-harmony-control";
|
||||
export const PLUGIN_NAME = "@watsonb8/homebridge-harmony-control";
|
||||
|
Reference in New Issue
Block a user