From 128bb933bdae42c9fc3e20b30363b67d2ac3597c Mon Sep 17 00:00:00 2001 From: Brandon Watson Date: Tue, 28 Dec 2021 22:08:59 -0500 Subject: [PATCH] Fixing bug where volume would restart the first activity. ControlUnit now starts with last used activity --- package-lock.json | 2 +- package.json | 2 +- src/accessories/controlUnit.ts | 10 +++++++--- src/dataProviders/stateDataProvider.ts | 18 ++++++++++++++--- src/models/activityState.ts | 3 ++- src/services/activityService.ts | 27 +++++++++++++++++++++----- src/services/commandService.ts | 2 +- src/services/volumeService.ts | 16 +++++++++------ 8 files changed, 59 insertions(+), 21 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3a8bfcc..5252635 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "@watsonb8/homebridge-harmony-control", - "version": "1.2.0", + "version": "1.2.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 224ea06..36b0578 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@watsonb8/homebridge-harmony-control", - "version": "1.2.0", + "version": "1.2.1", "description": "Homebridge platform to control smart home equipment by room.", "main": "bin/index.js", "publishConfig": { diff --git a/src/accessories/controlUnit.ts b/src/accessories/controlUnit.ts index f6def08..06d409f 100644 --- a/src/accessories/controlUnit.ts +++ b/src/accessories/controlUnit.ts @@ -137,7 +137,10 @@ export class ControlUnit { break; //Turn on with first activity case 1: - this._activityService.startActivity( + if (this._activityService.getIsActive(this._accessory.displayName)) { + break; + } + this._activityService.startLastOrDefaultActivity( this._accessory.displayName, this._activities[0] ); @@ -150,7 +153,8 @@ export class ControlUnit { */ private onGetAccessoryActive = async () => { //@ts-ignore - return this._activityService.getIsActive(this._accessory.displayName) + return this._activityService.getCurrentActivity(this._accessory.displayName) + ?.DisplayName ? this._platform.Characteristic.Active.ACTIVE : this._platform.Characteristic.Active.INACTIVE; }; @@ -176,7 +180,7 @@ export class ControlUnit { * Event handler for GET active identifier characteristic */ private onGetActiveIdentifier = async () => { - let currentActivity: IActivity = this._activityService.getIsActive( + let currentActivity: IActivity = this._activityService.getCurrentActivity( this._accessory.displayName )!; let identifier: number = 0; diff --git a/src/dataProviders/stateDataProvider.ts b/src/dataProviders/stateDataProvider.ts index f4d89b8..9dc9f71 100644 --- a/src/dataProviders/stateDataProvider.ts +++ b/src/dataProviders/stateDataProvider.ts @@ -9,18 +9,30 @@ export class StateDataProvider { } = {}; public updateState(activity: IActivity, controlUnitName: string): void { - this._states[controlUnitName] = { currentActivity: activity }; + const oldState = this._states[controlUnitName]; + this._states[controlUnitName] = { + currentActivity: activity, + lastActivity: oldState?.lastActivity, + }; + } + + public deactivateState(controlUnitName: string): void { + const oldState = this._states[controlUnitName]; + this._states[controlUnitName] = { + currentActivity: undefined, + lastActivity: oldState?.currentActivity, + }; } public removeState(controlUnitName: string): void { this._states[controlUnitName] = undefined; } - public getState(controlUnitName: string) { + public getState(controlUnitName: string): IActivityState | undefined { if (!this._states[controlUnitName]) { return undefined; } - return this._states[controlUnitName]!.currentActivity; + return this._states[controlUnitName]; } public get states(): { diff --git a/src/models/activityState.ts b/src/models/activityState.ts index 96db22e..144e06f 100644 --- a/src/models/activityState.ts +++ b/src/models/activityState.ts @@ -1,5 +1,6 @@ import { IActivity } from "./config"; export interface IActivityState { - currentActivity: IActivity; + currentActivity?: IActivity; + lastActivity?: IActivity; } diff --git a/src/services/activityService.ts b/src/services/activityService.ts index 8549684..9c06fa8 100644 --- a/src/services/activityService.ts +++ b/src/services/activityService.ts @@ -22,6 +22,18 @@ export class ActivityService { @inject("log") private _log: Logging ) {} + public startLastOrDefaultActivity = async ( + controlUnitName: string, + defaultActivity: IActivity + ) => { + const lastActivity = this.getLastActivity(controlUnitName); + if (!lastActivity) { + return this.startActivity(controlUnitName, defaultActivity); + } + + return this.startActivity(controlUnitName, lastActivity); + }; + public startActivity = async ( controlUnitName: string, activity: IActivity @@ -68,19 +80,24 @@ export class ActivityService { ); await this._harmonyDataProvider.powerOffDevices(devicesToTurnOff); - this._stateDataProvider.removeState(controlUnitName); + this._stateDataProvider.deactivateState(controlUnitName); }; public getCurrentActivity(controlUnitName: string): IActivity | undefined { - return this._stateDataProvider.getState(controlUnitName); + return this._stateDataProvider.getState(controlUnitName)?.currentActivity; + } + + public getLastActivity(controlUnitName: string): IActivity | undefined { + return this._stateDataProvider.getState(controlUnitName)?.lastActivity; } /** * Return if a control unit is active * @param controlUnitName */ - public getIsActive(controlUnitName: string): IActivity | undefined { - return this._stateDataProvider.getState(controlUnitName); + public getIsActive(controlUnitName: string): boolean { + const state = this._stateDataProvider.getState(controlUnitName); + return state != undefined && state.currentActivity != undefined; } /** @@ -104,7 +121,7 @@ export class ActivityService { return devicesToTurnOn; } - currentOtherState.currentActivity.DeviceSetupList.forEach( + currentOtherState.currentActivity!.DeviceSetupList.forEach( (value: IDeviceSetupItem) => { //there are devices to remove if (devicesToTurnOn.some((e) => e && e.name === value.DeviceName)) { diff --git a/src/services/commandService.ts b/src/services/commandService.ts index be4e841..3d8fe3a 100644 --- a/src/services/commandService.ts +++ b/src/services/commandService.ts @@ -24,7 +24,7 @@ export class CommandService { let commandName: string = ""; let device: HarmonyDevice = this._harmonyDataProvider.getDeviceByName( - currentActivity.ControlDevice + currentActivity.currentActivity!.ControlDevice ); switch (key) { case RemoteKey.ARROW_UP: { diff --git a/src/services/volumeService.ts b/src/services/volumeService.ts index 5a48961..ac262e5 100644 --- a/src/services/volumeService.ts +++ b/src/services/volumeService.ts @@ -16,10 +16,12 @@ export class VolumeService { */ public volumeUp = async (controlUnitName: string) => { let volumeUpCommand: string = "Volume Up"; - let currentActivity = this._stateDataProvider.getState(controlUnitName); - if (currentActivity) { + let currentState = this._stateDataProvider.getState(controlUnitName); + if (currentState) { let volumeDevice: HarmonyDevice = - this._harmonyDataProvider.getDeviceByName(currentActivity.VolumeDevice); + this._harmonyDataProvider.getDeviceByName( + currentState.currentActivity!.VolumeDevice + ); await this._harmonyDataProvider.sendCommand( volumeUpCommand, volumeDevice @@ -32,10 +34,12 @@ export class VolumeService { */ public volumeDown = async (controlUnitName: string) => { let volumeDownCommand: string = "Volume Down"; - let currentActivity = this._stateDataProvider.getState(controlUnitName); - if (currentActivity) { + let currentState = this._stateDataProvider.getState(controlUnitName); + if (currentState) { let volumeDevice: HarmonyDevice = - this._harmonyDataProvider.getDeviceByName(currentActivity.VolumeDevice); + this._harmonyDataProvider.getDeviceByName( + currentState.currentActivity!.VolumeDevice + ); await this._harmonyDataProvider.sendCommand( volumeDownCommand, volumeDevice