From bae1ed126044d04447e0e534c2ed5a0b62cf1686 Mon Sep 17 00:00:00 2001 From: Phillip Ivan Pietruschka Date: Sun, 22 Sep 2024 09:24:48 +1000 Subject: [PATCH 1/3] register new parameters from feedback subscribe, allow variables in feedback path option --- src/actions.ts | 6 +++++- src/feedback.ts | 27 ++++++++++++++++++++++----- src/index.ts | 43 +++++++++++++++++++++++++++++++++++-------- 3 files changed, 62 insertions(+), 14 deletions(-) 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..5d1d84b 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,13 @@ 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) => { + const path = await resolvePath(context, feedback.options['path']?.toString() ?? '') + await _self.registerNewParameter(path) }, }, [FeedbackId.String]: { @@ -65,6 +73,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 +85,16 @@ 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) => { + const path = await resolvePath(context, feedback.options['path']?.toString() ?? '') + await _self.registerNewParameter(path) }, }, [FeedbackId.Take]: { diff --git a/src/index.ts b/src/index.ts index 613b7d7..e7863f7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -16,13 +16,14 @@ 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 private emberQueue!: PQueue private reconnectTimer!: ReturnType | undefined private isRecordingActions!: boolean + public handleValueChange!: ReturnType // Override base types to make types stricter public checkFeedbacks(...feedbackTypes: string[]): void { @@ -46,7 +47,7 @@ class EmberPlusInstance extends InstanceBase { this.setupMatrices() this.setupMonitoredParams() - this.updateCompanionBits() + this.updateCompanionBits(true) } /** @@ -64,7 +65,7 @@ class EmberPlusInstance extends InstanceBase { this.setupEmberConnection() this.setupMatrices() this.setupMonitoredParams() - this.updateCompanionBits() + this.updateCompanionBits(true) } /** @@ -83,10 +84,11 @@ class EmberPlusInstance extends InstanceBase { this.emberClient.discard() } - private updateCompanionBits(): void { - this.setActionDefinitions(GetActionsList(this, this.client, this.config, this.state, this.emberQueue)) - this.setFeedbackDefinitions(GetFeedbacksList(this, this.client, this.config, this.state)) + public updateCompanionBits(updateAll: boolean): void { + this.setFeedbackDefinitions(GetFeedbacksList(this, this.client, this.config, this.state, this.emberQueue)) 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 +199,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.handleValueChange(path, node).catch((e: any) => 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() ?? '') From d4630942a98c678e1d4728489cbe3298276b5478 Mon Sep 17 00:00:00 2001 From: Phillip Ivan Pietruschka Date: Sun, 22 Sep 2024 09:28:48 +1000 Subject: [PATCH 2/3] minor fixes --- src/index.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/index.ts b/src/index.ts index e7863f7..f218f6d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -23,7 +23,6 @@ export class EmberPlusInstance extends InstanceBase { private emberQueue!: PQueue private reconnectTimer!: ReturnType | undefined private isRecordingActions!: boolean - public handleValueChange!: ReturnType // Override base types to make types stricter public checkFeedbacks(...feedbackTypes: string[]): void { @@ -84,8 +83,8 @@ export class EmberPlusInstance extends InstanceBase { this.emberClient.discard() } - public updateCompanionBits(updateAll: boolean): void { - this.setFeedbackDefinitions(GetFeedbacksList(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)) From 4caf9413f1a3600a1bb5b9c9e2327a4a30355de8 Mon Sep 17 00:00:00 2001 From: Phillip Ivan Pietruschka Date: Sun, 22 Sep 2024 09:32:18 +1000 Subject: [PATCH 3/3] minor fixes --- src/feedback.ts | 6 ++---- src/index.ts | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/feedback.ts b/src/feedback.ts index 5d1d84b..7f86dca 100644 --- a/src/feedback.ts +++ b/src/feedback.ts @@ -54,8 +54,7 @@ export function GetFeedbacksList( return state.parameters.get(path) == feedback.options['value']?.toString() }, subscribe: async (feedback, context) => { - const path = await resolvePath(context, feedback.options['path']?.toString() ?? '') - await _self.registerNewParameter(path) + await _self.registerNewParameter(await resolvePath(context, feedback.options['path']?.toString() ?? '')) }, }, [FeedbackId.String]: { @@ -93,8 +92,7 @@ export function GetFeedbacksList( return state.parameters.get(path) == value }, subscribe: async (feedback, context) => { - const path = await resolvePath(context, feedback.options['path']?.toString() ?? '') - await _self.registerNewParameter(path) + await _self.registerNewParameter(await resolvePath(context, feedback.options['path']?.toString() ?? '')) }, }, [FeedbackId.Take]: { diff --git a/src/index.ts b/src/index.ts index f218f6d..e7eabbc 100644 --- a/src/index.ts +++ b/src/index.ts @@ -205,7 +205,7 @@ export class EmberPlusInstance extends InstanceBase { .add(async () => { try { const initial_node = await this.emberClient.getElementByPath(path, (node) => { - this.handleValueChange(path, node).catch((e: any) => this.log('error', 'Error handling parameter ' + e)) + this.handleChangedValue(path, node).catch((e) => this.log('error', 'Error handling parameter ' + e)) }) if (initial_node) { this.log('debug', 'Registered for path "' + path + '"')