mirror of
https://github.com/nasa/openmct.git
synced 2025-02-25 19:11:35 +00:00
Merge branch 'telemetry-comps' of github.com:nasa/openmct into telemetry-comps
This commit is contained in:
commit
fdcece8e0e
@ -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() {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -26,10 +26,16 @@
|
||||
<div class="c-cs__content c-cs__current-output-value">
|
||||
<span class="c-cs__current-output-value__label">Current Output</span>
|
||||
<span class="c-cs__current-output-value__value" aria-label="Current Output Value">
|
||||
<template v-if="testDataApplied && currentTestOutput">
|
||||
<template
|
||||
v-if="testDataApplied && currentTestOutput !== undefined && currentTestOutput !== null"
|
||||
>
|
||||
{{ currentTestOutput }}
|
||||
</template>
|
||||
<template v-else-if="currentCompOutput && !testDataApplied">
|
||||
<template
|
||||
v-else-if="
|
||||
!testDataApplied && currentCompOutput !== undefined && currentCompOutput !== null
|
||||
"
|
||||
>
|
||||
{{ currentCompOutput }}
|
||||
</template>
|
||||
<template v-else> --- </template>
|
||||
@ -136,7 +142,7 @@
|
||||
|
||||
<script setup>
|
||||
import { evaluate } from 'mathjs';
|
||||
import { inject, onBeforeMount, onBeforeUnmount, ref } from 'vue';
|
||||
import { inject, onBeforeMount, onBeforeUnmount, ref, watch } from 'vue';
|
||||
|
||||
import ObjectPathString from '../../../ui/components/ObjectPathString.vue';
|
||||
import CompsManager from '../CompsManager';
|
||||
@ -155,7 +161,7 @@ const outputFormat = ref(null);
|
||||
|
||||
let outputTelemetryCollection;
|
||||
|
||||
defineProps({
|
||||
const props = defineProps({
|
||||
isEditing: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
@ -167,11 +173,12 @@ onBeforeMount(async () => {
|
||||
outputTelemetryCollection = openmct.telemetry.requestCollection(domainObject);
|
||||
outputTelemetryCollection.on('add', telemetryProcessor);
|
||||
outputTelemetryCollection.on('clear', clearData);
|
||||
compsManager.on('parameterAdded', reloadParameters);
|
||||
compsManager.on('parameterRemoved', reloadParameters);
|
||||
await compsManager.load();
|
||||
parameters.value = compsManager.getParameters();
|
||||
expression.value = compsManager.getExpression();
|
||||
outputFormat.value = compsManager.getOutputFormat();
|
||||
compsManager.on('parametersUpdated', reloadParameters);
|
||||
outputTelemetryCollection.load();
|
||||
applyTestData();
|
||||
});
|
||||
@ -179,17 +186,35 @@ onBeforeMount(async () => {
|
||||
onBeforeUnmount(() => {
|
||||
outputTelemetryCollection.off('add', telemetryProcessor);
|
||||
outputTelemetryCollection.off('clear', clearData);
|
||||
compsManager.off('parameterAdded', reloadParameters);
|
||||
compsManager.off('parameterRemoved', reloadParameters);
|
||||
outputTelemetryCollection.destroy();
|
||||
});
|
||||
|
||||
function reloadParameters() {
|
||||
parameters.value = compsManager.getParameters();
|
||||
domainObject.configuration.comps.parameters = parameters.value;
|
||||
compsManager.setDomainObject(domainObject);
|
||||
watch(
|
||||
() => props.isEditing,
|
||||
(editMode) => {
|
||||
if (!editMode) {
|
||||
testDataApplied.value = false;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
function reloadParameters(passedDomainObject) {
|
||||
// Because this is triggered by a composition change, we have
|
||||
// to defer mutation of our domain object, otherwise we might
|
||||
// mutate an outdated version of the domain object.
|
||||
setTimeout(function () {
|
||||
console.debug('🚀 CompsView: parameter added', passedDomainObject);
|
||||
domainObject.configuration.comps.parameters = passedDomainObject.configuration.comps.parameters;
|
||||
parameters.value = domainObject.configuration.comps.parameters;
|
||||
openmct.objects.mutate(domainObject, `configuration.comps.parameters`, parameters.value);
|
||||
compsManager.setDomainObject(domainObject);
|
||||
applyTestData();
|
||||
});
|
||||
}
|
||||
|
||||
function updateParameters() {
|
||||
console.debug('🚀 CompsView: updateParameters', parameters.value);
|
||||
openmct.objects.mutate(domainObject, `configuration.comps.parameters`, parameters.value);
|
||||
compsManager.setDomainObject(domainObject);
|
||||
applyTestData();
|
||||
@ -217,6 +242,9 @@ function getValueFormatter() {
|
||||
}
|
||||
|
||||
function applyTestData() {
|
||||
if (!expression.value || !parameters.value) {
|
||||
return;
|
||||
}
|
||||
const scope = parameters.value.reduce((acc, parameter) => {
|
||||
acc[parameter.name] = parameter.testValue;
|
||||
return acc;
|
||||
|
Loading…
x
Reference in New Issue
Block a user