diff --git a/src/actions.ts b/src/actions.ts index fea6f0e..9c0e6e9 100644 --- a/src/actions.ts +++ b/src/actions.ts @@ -1,6 +1,7 @@ import type { CompanionActionDefinition, CompanionActionDefinitions, + CompanionFeedbackContext, CompanionActionEvent, CompanionInputFieldNumber, CompanionInputFieldTextInput, @@ -56,7 +57,10 @@ const matrixInputs: Array, path: string): Promise { +export async function resolvePath( + self: InstanceBase | CompanionFeedbackContext, + path: string, +): Promise { const pathString: string = await self.parseVariablesInString(path) if (pathString.includes('[') && pathString.includes(']')) { return pathString.substring(pathString.indexOf('[') + 1, pathString.indexOf(']')) diff --git a/src/feedback.ts b/src/feedback.ts index 3085728..7f86dca 100644 --- a/src/feedback.ts +++ b/src/feedback.ts @@ -1,6 +1,8 @@ -import { combineRgb, InstanceBase } from '@companion-module/base' +import { combineRgb /*InstanceBase*/ } from '@companion-module/base' import type { CompanionFeedbackDefinition, CompanionFeedbackDefinitions, DropdownChoice } from '@companion-module/base' +import type { EmberPlusInstance } from './index' import { EmberClient } from 'emberplus-connection' +import { resolvePath } from './actions' import type { EmberPlusConfig } from './config' import { EmberPlusState } from './state' @@ -14,7 +16,7 @@ export enum FeedbackId { } export function GetFeedbacksList( - _self: InstanceBase, + _self: EmberPlusInstance, //InstanceBase, _emberClient: EmberClient, config: EmberPlusConfig, state: EmberPlusState, @@ -35,6 +37,7 @@ export function GetFeedbacksList( id: 'path', choices: config.monitoredParameters?.map((item) => { id: item, label: item }) ?? [], default: config.monitoredParameters?.find(() => true) ?? 'No paths configured!', + allowCustom: true, }, { type: 'number', @@ -46,8 +49,12 @@ export function GetFeedbacksList( default: 0, }, ], - callback: (feedback) => { - return state.parameters.get(feedback.options['path']?.toString() ?? '') == feedback.options['value']?.toString() + callback: async (feedback, context) => { + const path = await resolvePath(context, feedback.options['path']?.toString() ?? '') + return state.parameters.get(path) == feedback.options['value']?.toString() + }, + subscribe: async (feedback, context) => { + await _self.registerNewParameter(await resolvePath(context, feedback.options['path']?.toString() ?? '')) }, }, [FeedbackId.String]: { @@ -65,6 +72,7 @@ export function GetFeedbacksList( id: 'path', choices: config.monitoredParameters?.map((item) => { id: item, label: item }) ?? [], default: config.monitoredParameters?.find(() => true) ?? 'No paths configured!', + allowCustom: true, }, { type: 'textinput', @@ -76,8 +84,15 @@ export function GetFeedbacksList( }, ], callback: async (feedback, context) => { + const path = await resolvePath( + _self, + await context.parseVariablesInString(feedback.options['path']?.toString() ?? ''), + ) const value: string = await context.parseVariablesInString(feedback.options['value']?.toString() ?? '') - return state.parameters.get(feedback.options['path']?.toString() ?? '') == value + return state.parameters.get(path) == value + }, + subscribe: async (feedback, context) => { + await _self.registerNewParameter(await resolvePath(context, feedback.options['path']?.toString() ?? '')) }, }, [FeedbackId.Take]: { diff --git a/src/index.ts b/src/index.ts index 613b7d7..e7eabbc 100644 --- a/src/index.ts +++ b/src/index.ts @@ -16,7 +16,7 @@ const reconnectInterval: number = 300000 //emberplus-connection destroys socket /** * Companion instance class for generic EmBER+ Devices */ -class EmberPlusInstance extends InstanceBase { +export class EmberPlusInstance extends InstanceBase { private emberClient!: EmberClient private config!: EmberPlusConfig private state!: EmberPlusState @@ -46,7 +46,7 @@ class EmberPlusInstance extends InstanceBase { this.setupMatrices() this.setupMonitoredParams() - this.updateCompanionBits() + this.updateCompanionBits(true) } /** @@ -64,7 +64,7 @@ class EmberPlusInstance extends InstanceBase { this.setupEmberConnection() this.setupMatrices() this.setupMonitoredParams() - this.updateCompanionBits() + this.updateCompanionBits(true) } /** @@ -83,10 +83,11 @@ class EmberPlusInstance extends InstanceBase { this.emberClient.discard() } - private updateCompanionBits(): void { - this.setActionDefinitions(GetActionsList(this, this.client, this.config, this.state, this.emberQueue)) + private updateCompanionBits(updateAll: boolean): void { this.setFeedbackDefinitions(GetFeedbacksList(this, this.client, this.config, this.state)) this.setVariableDefinitions(GetVariablesList(this.config)) + if (!updateAll) return + this.setActionDefinitions(GetActionsList(this, this.client, this.config, this.state, this.emberQueue)) this.setPresetDefinitions(GetPresetsList()) } @@ -197,11 +198,36 @@ class EmberPlusInstance extends InstanceBase { }) } } + + public async registerNewParameter(path: string): Promise { + if (this.config.monitoredParameters?.includes(path) === true) return + this.emberQueue + .add(async () => { + try { + const initial_node = await this.emberClient.getElementByPath(path, (node) => { + this.handleChangedValue(path, node).catch((e) => this.log('error', 'Error handling parameter ' + e)) + }) + if (initial_node) { + this.log('debug', 'Registered for path "' + path + '"') + if (this.config.monitoredParameters) { + this.config.monitoredParameters.push(path) + this.updateCompanionBits(false) + } + await this.handleChangedValue(path, initial_node) + } + } catch (e) { + this.log('error', 'Failed to subscribe to path "' + path + '": ' + e) + } + }) + .catch((e) => { + this.log('debug', `Failed to register parameter: ${e.toString()}`) + }) + } // Track whether actions are being recorded - public handleStartStopRecordActions(isRecording: boolean) { + public handleStartStopRecordActions(isRecording: boolean): void { this.isRecordingActions = isRecording } - private async handleChangedValue(path: string, node: TreeElement) { + public async handleChangedValue(path: string, node: TreeElement): Promise { if (node.contents.type == ElementType.Parameter) { this.log('debug', 'Got parameter value for ' + path + ': ' + (node.contents.value?.toString() ?? '')) this.state.parameters.set(path, node.contents.value?.toString() ?? '')