diff --git a/src/plugins/comps/CompsManager.js b/src/plugins/comps/CompsManager.js index 1d91c1b2fc..4b336a8fdd 100644 --- a/src/plugins/comps/CompsManager.js +++ b/src/plugins/comps/CompsManager.js @@ -11,6 +11,8 @@ export default class CompsManager extends EventEmitter { #loaded = false; #compositionLoaded = false; #telemetryProcessors = {}; + // make id random 4 digit number + #id = Math.floor(Math.random() * 9000) + 1000; constructor(openmct, domainObject) { super(); @@ -70,7 +72,7 @@ export default class CompsManager extends EventEmitter { testValue: 0, timeMetaData }); - this.emit('parametersUpdated', keyString); + this.emit('parameterAdded', this.#domainObject); } getParameters() { @@ -104,7 +106,7 @@ export default class CompsManager extends EventEmitter { (parameter) => parameter.keyString === keyString ); if (!parameterExists) { - this.#composition.remove(this.#telemetryObjects[keyString]); + this.emit('parameterRemoved', this.#domainObject); } } @@ -129,20 +131,25 @@ export default class CompsManager extends EventEmitter { } } - startListeningToUnderlyingTelemetry() { + async startListeningToUnderlyingTelemetry() { console.debug('🎉 CompsManager: startListeningToUnderlyingTelemetry'); + this.#loaded = false; Object.keys(this.#telemetryCollections).forEach((keyString) => { if (!this.#telemetryCollections[keyString].loaded) { - const specificTelemetryProcessor = this.#getTelemetryProcessor(keyString); - this.#telemetryCollections[keyString].on('add', specificTelemetryProcessor); + this.#telemetryCollections[keyString].on('add', this.#getTelemetryProcessor(keyString)); this.#telemetryCollections[keyString].on('clear', this.clearData); - this.#telemetryCollections[keyString].load(); + const telemetryLoadedPromise = this.#telemetryCollections[keyString].load(); + this.#telemetryLoadedPromises.push(telemetryLoadedPromise); } }); + await Promise.all(this.#telemetryLoadedPromises); + this.#telemetryLoadedPromises = []; + this.#loaded = true; } stopListeningToUnderlyingTelemetry() { console.debug('🔇 CompsManager: stopListeningToUnderlyingTelemetry'); + this.#loaded = false; Object.keys(this.#telemetryCollections).forEach((keyString) => { const specificTelemetryProcessor = this.#telemetryProcessors[keyString]; delete this.#telemetryProcessors[keyString]; @@ -209,11 +216,7 @@ export default class CompsManager extends EventEmitter { this.#telemetryCollections[keyString]?.destroy(); delete this.#telemetryCollections[keyString]; // remove all parameters that reference this telemetry object - this.#domainObject.configuration.comps.parameters = - this.#domainObject.configuration.comps.parameters.filter( - (parameter) => parameter.keyString !== keyString - ); - this.emit('parametersUpdated', keyString); + this.deleteParameter(keyString); }; requestUnderlyingTelemetry() { diff --git a/src/plugins/comps/CompsMathWorker.js b/src/plugins/comps/CompsMathWorker.js index 8ddea694dc..823e87c676 100644 --- a/src/plugins/comps/CompsMathWorker.js +++ b/src/plugins/comps/CompsMathWorker.js @@ -74,7 +74,7 @@ function calculate(dataFrame, parameters, expression) { otherParameters.forEach((parameter) => { const otherDataFrame = dataFrame[parameter.keyString]; const otherTelemetry = otherDataFrame.get(referenceTime); - if (!otherTelemetry) { + if (otherTelemetry === undefined && otherTelemetry === null) { missingData = true; return; } diff --git a/src/plugins/comps/CompsMetadataProvider.js b/src/plugins/comps/CompsMetadataProvider.js index 6d859ef723..b12fc34ef2 100644 --- a/src/plugins/comps/CompsMetadataProvider.js +++ b/src/plugins/comps/CompsMetadataProvider.js @@ -34,7 +34,7 @@ export default class CompsMetadataProvider { return domainObject.type === 'comps'; } - getDomains(domainObject) { + getDefaultDomains(domainObject) { return this.#openmct.time.getAllTimeSystems().map(function (ts, i) { return { key: ts.key, @@ -56,7 +56,7 @@ export default class CompsMetadataProvider { // if there are any parameters, grab the first one's timeMetaData const timeMetaData = specificCompsManager?.getParameters()[0]?.timeMetaData; const metaDataToReturn = { - values: this.getDomains().concat([ + values: [ { key: 'compsOutput', source: 'compsOutput', @@ -66,13 +66,13 @@ export default class CompsMetadataProvider { range: 1 } } - ]) + ] }; - if ( - timeMetaData && - metaDataToReturn.values.some((metaDatum) => metaDatum.key === timeMetaData.key) - ) { + if (timeMetaData) { metaDataToReturn.values.push(timeMetaData); + } else { + const defaultDomains = this.getDefaultDomains(domainObject); + metaDataToReturn.values.push(...defaultDomains); } return metaDataToReturn; } diff --git a/src/plugins/comps/CompsTelemetryProvider.js b/src/plugins/comps/CompsTelemetryProvider.js index 345f050885..a6c6fa684b 100644 --- a/src/plugins/comps/CompsTelemetryProvider.js +++ b/src/plugins/comps/CompsTelemetryProvider.js @@ -29,6 +29,8 @@ export default class CompsTelemetryProvider { #lastUniqueID = 1; #requestPromises = {}; #subscriptionCallbacks = {}; + // id is random 4 digit number + #id = Math.floor(Math.random() * 9000) + 1000; constructor(openmct, compsManagerPool) { this.#openmct = openmct; @@ -67,7 +69,11 @@ export default class CompsTelemetryProvider { const callbackID = this.#getCallbackID(); const telemetryForComps = specificCompsManager.requestUnderlyingTelemetry(); const expression = specificCompsManager.getExpression(); - const parameters = specificCompsManager.getParameters(); + const parameters = JSON.parse(JSON.stringify(specificCompsManager.getParameters())); + if (!expression || !parameters) { + resolve([]); + return; + } this.#requestPromises[callbackID] = { resolve, reject }; const payload = { type: 'calculateRequest', @@ -85,13 +91,16 @@ export default class CompsTelemetryProvider { }); } - #computeOnNewTelemetry(specificCompsManager, newTelemetry, callbackID) { + #computeOnNewTelemetry(specificCompsManager, callbackID, newTelemetry) { if (!specificCompsManager.isReady()) { return; } const expression = specificCompsManager.getExpression(); const telemetryForComps = specificCompsManager.getFullDataFrame(newTelemetry); const parameters = JSON.parse(JSON.stringify(specificCompsManager.getParameters())); + if (!expression || !parameters) { + return; + } const payload = { type: 'calculateSubscription', telemetryForComps, @@ -111,12 +120,19 @@ export default class CompsTelemetryProvider { ); const callbackID = this.#getCallbackID(); this.#subscriptionCallbacks[callbackID] = callback; - specificCompsManager.on('underlyingTelemetryUpdated', (newTelemetry) => { - this.#computeOnNewTelemetry(specificCompsManager, newTelemetry, callbackID); - }); + const boundComputeOnNewTelemetry = this.#computeOnNewTelemetry.bind( + this, + specificCompsManager, + callbackID + ); + specificCompsManager.on('underlyingTelemetryUpdated', boundComputeOnNewTelemetry); specificCompsManager.startListeningToUnderlyingTelemetry(); + console.debug( + `🧮 Comps Telemetry Provider: subscribed to comps. Now have ${Object.keys(this.#subscriptionCallbacks).length} listener`, + this.#subscriptionCallbacks + ); return () => { - specificCompsManager.off('underlyingTelemetryUpdated', callback); + specificCompsManager.off('underlyingTelemetryUpdated', boundComputeOnNewTelemetry); delete this.#subscriptionCallbacks[callbackID]; // if this is the last subscription, tell the comp manager to stop listening specificCompsManager.stopListeningToUnderlyingTelemetry(); diff --git a/src/plugins/comps/components/CompsView.vue b/src/plugins/comps/components/CompsView.vue index 4a3a52ec6d..46a842287c 100644 --- a/src/plugins/comps/components/CompsView.vue +++ b/src/plugins/comps/components/CompsView.vue @@ -26,10 +26,16 @@