167 lines
5.1 KiB
TypeScript
167 lines
5.1 KiB
TypeScript
import { Logging } from "homebridge";
|
|
import { inject, injectable } from "tsyringe";
|
|
import { ICommand } from "../models";
|
|
import { IConfig } from "../models/config";
|
|
import { IDeviceConfig } from "../models/config/deviceConfig";
|
|
import { IHub } from "../models/config/hub";
|
|
import { HarmonyDevice } from "../models/harmonyDevice";
|
|
import { HarmonyHub } from "../models/harmonyHub";
|
|
|
|
@injectable()
|
|
export class HarmonyDataProvider {
|
|
private _hubs: { [hubName: string]: HarmonyHub } = {};
|
|
private _deviceConfigByName: { [deviceName: string]: IDeviceConfig } = {};
|
|
|
|
constructor(
|
|
@inject("IConfig") private _config: IConfig,
|
|
@inject("log") private _log: Logging
|
|
) {
|
|
_config.Devices.forEach((deviceConfig: IDeviceConfig) => {
|
|
this._deviceConfigByName[deviceConfig.Name] = deviceConfig;
|
|
});
|
|
|
|
this.connect(_config.Hubs);
|
|
this.emitInfo();
|
|
}
|
|
|
|
public async powerOnDevices(devices: Array<HarmonyDevice>): Promise<void> {
|
|
await Promise.all(
|
|
devices.map(async (device: HarmonyDevice) => {
|
|
if (device && device.name) {
|
|
if (!device.on) {
|
|
this._log.info(`Turning on device ${device.name}`);
|
|
await this.powerOnDevice(device);
|
|
}
|
|
}
|
|
})
|
|
);
|
|
}
|
|
|
|
public async powerOffDevices(devices: Array<HarmonyDevice>) {
|
|
await Promise.all(
|
|
//Turn off devices
|
|
devices.map(async (device: HarmonyDevice) => {
|
|
if (device) {
|
|
if (device.on) {
|
|
this._log.info(`Turning off device ${device.name}`);
|
|
await this.powerOffDevice(device);
|
|
}
|
|
}
|
|
})
|
|
);
|
|
}
|
|
|
|
public async sendCommand(
|
|
commandName: string,
|
|
harmonyDevice: HarmonyDevice
|
|
): Promise<void> {
|
|
let command!: ICommand;
|
|
|
|
commandName = this.getOverrideCommand(commandName, harmonyDevice);
|
|
|
|
if (harmonyDevice.supportsCommand(commandName)) {
|
|
command = harmonyDevice.getCommand(commandName);
|
|
}
|
|
const hub = this.getHubByDevice(harmonyDevice);
|
|
await hub.sendCommand(command);
|
|
}
|
|
|
|
/**
|
|
* Get the IDevice by name.
|
|
* @param deviceName The device to retrieve.
|
|
*/
|
|
public getDeviceByName(deviceName: string): HarmonyDevice {
|
|
let device: HarmonyDevice | undefined;
|
|
try {
|
|
device =
|
|
this._hubs[this._deviceConfigByName[deviceName].Hub].getDeviceByName(
|
|
deviceName
|
|
);
|
|
} catch (err) {
|
|
this._log.info(`Error retrieving device from hub: ${err}`);
|
|
}
|
|
|
|
return device!;
|
|
}
|
|
|
|
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.info);
|
|
this._hubs[hub.Name] = newHarmonyHub;
|
|
newHarmonyHub.on("Ready", () => {
|
|
readyCount++;
|
|
if (readyCount === Object.keys(this._hubs).length) {
|
|
// this.emit("Ready");
|
|
}
|
|
});
|
|
await newHarmonyHub.initialize();
|
|
})
|
|
);
|
|
};
|
|
|
|
private emitInfo(): void {
|
|
//Emit devices if requested
|
|
this._log.info("All hubs connected");
|
|
if (this._config.EmitDevicesOnStartup) {
|
|
const hubs = this._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}`);
|
|
});
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
private getHubByDevice(device: HarmonyDevice) {
|
|
return this._hubs[this._deviceConfigByName[device.name].Hub];
|
|
}
|
|
|
|
private async powerOnDevice(harmonyDevice: HarmonyDevice): Promise<void> {
|
|
let powerOnCommand: string = "Power On";
|
|
let powerToggleCommand: string = "Power Toggle";
|
|
if (harmonyDevice.supportsCommand(powerOnCommand)) {
|
|
await this.sendCommand(powerOnCommand, harmonyDevice);
|
|
harmonyDevice.on = true;
|
|
} else if (harmonyDevice.supportsCommand(powerToggleCommand)) {
|
|
await this.sendCommand(powerToggleCommand, harmonyDevice);
|
|
harmonyDevice.on = true;
|
|
} else {
|
|
await this.sendCommand(powerOnCommand, harmonyDevice);
|
|
}
|
|
}
|
|
|
|
private async powerOffDevice(harmonyDevice: HarmonyDevice): Promise<void> {
|
|
let powerOffCommand: string = "Power Off";
|
|
let powerToggleCommand: string = "Power Toggle";
|
|
if (harmonyDevice.supportsCommand(powerOffCommand)) {
|
|
await this.sendCommand(powerOffCommand, harmonyDevice);
|
|
harmonyDevice.on = false;
|
|
} else if (harmonyDevice.supportsCommand(powerToggleCommand)) {
|
|
await this.sendCommand(powerToggleCommand, harmonyDevice);
|
|
harmonyDevice.on = false;
|
|
}
|
|
}
|
|
|
|
private getOverrideCommand(
|
|
commandName: string,
|
|
harmonyDevice: HarmonyDevice
|
|
) {
|
|
const deviceConfig: IDeviceConfig =
|
|
this._deviceConfigByName[harmonyDevice.name];
|
|
if (!deviceConfig.Overrides) {
|
|
return commandName;
|
|
}
|
|
const overrideCommand = deviceConfig.Overrides.find(
|
|
(e) => e.Command == commandName
|
|
);
|
|
return overrideCommand ? overrideCommand.Override : commandName;
|
|
}
|
|
}
|