mirror of
https://github.com/nasa/openmct.git
synced 2025-02-26 11:20:19 +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;
|
#loaded = false;
|
||||||
#compositionLoaded = false;
|
#compositionLoaded = false;
|
||||||
#telemetryProcessors = {};
|
#telemetryProcessors = {};
|
||||||
|
// make id random 4 digit number
|
||||||
|
#id = Math.floor(Math.random() * 9000) + 1000;
|
||||||
|
|
||||||
constructor(openmct, domainObject) {
|
constructor(openmct, domainObject) {
|
||||||
super();
|
super();
|
||||||
@ -70,7 +72,7 @@ export default class CompsManager extends EventEmitter {
|
|||||||
testValue: 0,
|
testValue: 0,
|
||||||
timeMetaData
|
timeMetaData
|
||||||
});
|
});
|
||||||
this.emit('parametersUpdated', keyString);
|
this.emit('parameterAdded', this.#domainObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
getParameters() {
|
getParameters() {
|
||||||
@ -104,7 +106,7 @@ export default class CompsManager extends EventEmitter {
|
|||||||
(parameter) => parameter.keyString === keyString
|
(parameter) => parameter.keyString === keyString
|
||||||
);
|
);
|
||||||
if (!parameterExists) {
|
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');
|
console.debug('🎉 CompsManager: startListeningToUnderlyingTelemetry');
|
||||||
|
this.#loaded = false;
|
||||||
Object.keys(this.#telemetryCollections).forEach((keyString) => {
|
Object.keys(this.#telemetryCollections).forEach((keyString) => {
|
||||||
if (!this.#telemetryCollections[keyString].loaded) {
|
if (!this.#telemetryCollections[keyString].loaded) {
|
||||||
const specificTelemetryProcessor = this.#getTelemetryProcessor(keyString);
|
this.#telemetryCollections[keyString].on('add', this.#getTelemetryProcessor(keyString));
|
||||||
this.#telemetryCollections[keyString].on('add', specificTelemetryProcessor);
|
|
||||||
this.#telemetryCollections[keyString].on('clear', this.clearData);
|
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() {
|
stopListeningToUnderlyingTelemetry() {
|
||||||
console.debug('🔇 CompsManager: stopListeningToUnderlyingTelemetry');
|
console.debug('🔇 CompsManager: stopListeningToUnderlyingTelemetry');
|
||||||
|
this.#loaded = false;
|
||||||
Object.keys(this.#telemetryCollections).forEach((keyString) => {
|
Object.keys(this.#telemetryCollections).forEach((keyString) => {
|
||||||
const specificTelemetryProcessor = this.#telemetryProcessors[keyString];
|
const specificTelemetryProcessor = this.#telemetryProcessors[keyString];
|
||||||
delete this.#telemetryProcessors[keyString];
|
delete this.#telemetryProcessors[keyString];
|
||||||
@ -209,11 +216,7 @@ export default class CompsManager extends EventEmitter {
|
|||||||
this.#telemetryCollections[keyString]?.destroy();
|
this.#telemetryCollections[keyString]?.destroy();
|
||||||
delete this.#telemetryCollections[keyString];
|
delete this.#telemetryCollections[keyString];
|
||||||
// remove all parameters that reference this telemetry object
|
// remove all parameters that reference this telemetry object
|
||||||
this.#domainObject.configuration.comps.parameters =
|
this.deleteParameter(keyString);
|
||||||
this.#domainObject.configuration.comps.parameters.filter(
|
|
||||||
(parameter) => parameter.keyString !== keyString
|
|
||||||
);
|
|
||||||
this.emit('parametersUpdated', keyString);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
requestUnderlyingTelemetry() {
|
requestUnderlyingTelemetry() {
|
||||||
|
@ -74,7 +74,7 @@ function calculate(dataFrame, parameters, expression) {
|
|||||||
otherParameters.forEach((parameter) => {
|
otherParameters.forEach((parameter) => {
|
||||||
const otherDataFrame = dataFrame[parameter.keyString];
|
const otherDataFrame = dataFrame[parameter.keyString];
|
||||||
const otherTelemetry = otherDataFrame.get(referenceTime);
|
const otherTelemetry = otherDataFrame.get(referenceTime);
|
||||||
if (!otherTelemetry) {
|
if (otherTelemetry === undefined && otherTelemetry === null) {
|
||||||
missingData = true;
|
missingData = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ export default class CompsMetadataProvider {
|
|||||||
return domainObject.type === 'comps';
|
return domainObject.type === 'comps';
|
||||||
}
|
}
|
||||||
|
|
||||||
getDomains(domainObject) {
|
getDefaultDomains(domainObject) {
|
||||||
return this.#openmct.time.getAllTimeSystems().map(function (ts, i) {
|
return this.#openmct.time.getAllTimeSystems().map(function (ts, i) {
|
||||||
return {
|
return {
|
||||||
key: ts.key,
|
key: ts.key,
|
||||||
@ -56,7 +56,7 @@ export default class CompsMetadataProvider {
|
|||||||
// if there are any parameters, grab the first one's timeMetaData
|
// if there are any parameters, grab the first one's timeMetaData
|
||||||
const timeMetaData = specificCompsManager?.getParameters()[0]?.timeMetaData;
|
const timeMetaData = specificCompsManager?.getParameters()[0]?.timeMetaData;
|
||||||
const metaDataToReturn = {
|
const metaDataToReturn = {
|
||||||
values: this.getDomains().concat([
|
values: [
|
||||||
{
|
{
|
||||||
key: 'compsOutput',
|
key: 'compsOutput',
|
||||||
source: 'compsOutput',
|
source: 'compsOutput',
|
||||||
@ -66,13 +66,13 @@ export default class CompsMetadataProvider {
|
|||||||
range: 1
|
range: 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
])
|
]
|
||||||
};
|
};
|
||||||
if (
|
if (timeMetaData) {
|
||||||
timeMetaData &&
|
|
||||||
metaDataToReturn.values.some((metaDatum) => metaDatum.key === timeMetaData.key)
|
|
||||||
) {
|
|
||||||
metaDataToReturn.values.push(timeMetaData);
|
metaDataToReturn.values.push(timeMetaData);
|
||||||
|
} else {
|
||||||
|
const defaultDomains = this.getDefaultDomains(domainObject);
|
||||||
|
metaDataToReturn.values.push(...defaultDomains);
|
||||||
}
|
}
|
||||||
return metaDataToReturn;
|
return metaDataToReturn;
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,8 @@ export default class CompsTelemetryProvider {
|
|||||||
#lastUniqueID = 1;
|
#lastUniqueID = 1;
|
||||||
#requestPromises = {};
|
#requestPromises = {};
|
||||||
#subscriptionCallbacks = {};
|
#subscriptionCallbacks = {};
|
||||||
|
// id is random 4 digit number
|
||||||
|
#id = Math.floor(Math.random() * 9000) + 1000;
|
||||||
|
|
||||||
constructor(openmct, compsManagerPool) {
|
constructor(openmct, compsManagerPool) {
|
||||||
this.#openmct = openmct;
|
this.#openmct = openmct;
|
||||||
@ -67,7 +69,11 @@ export default class CompsTelemetryProvider {
|
|||||||
const callbackID = this.#getCallbackID();
|
const callbackID = this.#getCallbackID();
|
||||||
const telemetryForComps = specificCompsManager.requestUnderlyingTelemetry();
|
const telemetryForComps = specificCompsManager.requestUnderlyingTelemetry();
|
||||||
const expression = specificCompsManager.getExpression();
|
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 };
|
this.#requestPromises[callbackID] = { resolve, reject };
|
||||||
const payload = {
|
const payload = {
|
||||||
type: 'calculateRequest',
|
type: 'calculateRequest',
|
||||||
@ -85,13 +91,16 @@ export default class CompsTelemetryProvider {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#computeOnNewTelemetry(specificCompsManager, newTelemetry, callbackID) {
|
#computeOnNewTelemetry(specificCompsManager, callbackID, newTelemetry) {
|
||||||
if (!specificCompsManager.isReady()) {
|
if (!specificCompsManager.isReady()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const expression = specificCompsManager.getExpression();
|
const expression = specificCompsManager.getExpression();
|
||||||
const telemetryForComps = specificCompsManager.getFullDataFrame(newTelemetry);
|
const telemetryForComps = specificCompsManager.getFullDataFrame(newTelemetry);
|
||||||
const parameters = JSON.parse(JSON.stringify(specificCompsManager.getParameters()));
|
const parameters = JSON.parse(JSON.stringify(specificCompsManager.getParameters()));
|
||||||
|
if (!expression || !parameters) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const payload = {
|
const payload = {
|
||||||
type: 'calculateSubscription',
|
type: 'calculateSubscription',
|
||||||
telemetryForComps,
|
telemetryForComps,
|
||||||
@ -111,12 +120,19 @@ export default class CompsTelemetryProvider {
|
|||||||
);
|
);
|
||||||
const callbackID = this.#getCallbackID();
|
const callbackID = this.#getCallbackID();
|
||||||
this.#subscriptionCallbacks[callbackID] = callback;
|
this.#subscriptionCallbacks[callbackID] = callback;
|
||||||
specificCompsManager.on('underlyingTelemetryUpdated', (newTelemetry) => {
|
const boundComputeOnNewTelemetry = this.#computeOnNewTelemetry.bind(
|
||||||
this.#computeOnNewTelemetry(specificCompsManager, newTelemetry, callbackID);
|
this,
|
||||||
});
|
specificCompsManager,
|
||||||
|
callbackID
|
||||||
|
);
|
||||||
|
specificCompsManager.on('underlyingTelemetryUpdated', boundComputeOnNewTelemetry);
|
||||||
specificCompsManager.startListeningToUnderlyingTelemetry();
|
specificCompsManager.startListeningToUnderlyingTelemetry();
|
||||||
|
console.debug(
|
||||||
|
`🧮 Comps Telemetry Provider: subscribed to comps. Now have ${Object.keys(this.#subscriptionCallbacks).length} listener`,
|
||||||
|
this.#subscriptionCallbacks
|
||||||
|
);
|
||||||
return () => {
|
return () => {
|
||||||
specificCompsManager.off('underlyingTelemetryUpdated', callback);
|
specificCompsManager.off('underlyingTelemetryUpdated', boundComputeOnNewTelemetry);
|
||||||
delete this.#subscriptionCallbacks[callbackID];
|
delete this.#subscriptionCallbacks[callbackID];
|
||||||
// if this is the last subscription, tell the comp manager to stop listening
|
// if this is the last subscription, tell the comp manager to stop listening
|
||||||
specificCompsManager.stopListeningToUnderlyingTelemetry();
|
specificCompsManager.stopListeningToUnderlyingTelemetry();
|
||||||
|
@ -26,10 +26,16 @@
|
|||||||
<div class="c-cs__content c-cs__current-output-value">
|
<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__label">Current Output</span>
|
||||||
<span class="c-cs__current-output-value__value" aria-label="Current Output Value">
|
<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 }}
|
{{ currentTestOutput }}
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="currentCompOutput && !testDataApplied">
|
<template
|
||||||
|
v-else-if="
|
||||||
|
!testDataApplied && currentCompOutput !== undefined && currentCompOutput !== null
|
||||||
|
"
|
||||||
|
>
|
||||||
{{ currentCompOutput }}
|
{{ currentCompOutput }}
|
||||||
</template>
|
</template>
|
||||||
<template v-else> --- </template>
|
<template v-else> --- </template>
|
||||||
@ -136,7 +142,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { evaluate } from 'mathjs';
|
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 ObjectPathString from '../../../ui/components/ObjectPathString.vue';
|
||||||
import CompsManager from '../CompsManager';
|
import CompsManager from '../CompsManager';
|
||||||
@ -155,7 +161,7 @@ const outputFormat = ref(null);
|
|||||||
|
|
||||||
let outputTelemetryCollection;
|
let outputTelemetryCollection;
|
||||||
|
|
||||||
defineProps({
|
const props = defineProps({
|
||||||
isEditing: {
|
isEditing: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: true
|
required: true
|
||||||
@ -167,11 +173,12 @@ onBeforeMount(async () => {
|
|||||||
outputTelemetryCollection = openmct.telemetry.requestCollection(domainObject);
|
outputTelemetryCollection = openmct.telemetry.requestCollection(domainObject);
|
||||||
outputTelemetryCollection.on('add', telemetryProcessor);
|
outputTelemetryCollection.on('add', telemetryProcessor);
|
||||||
outputTelemetryCollection.on('clear', clearData);
|
outputTelemetryCollection.on('clear', clearData);
|
||||||
|
compsManager.on('parameterAdded', reloadParameters);
|
||||||
|
compsManager.on('parameterRemoved', reloadParameters);
|
||||||
await compsManager.load();
|
await compsManager.load();
|
||||||
parameters.value = compsManager.getParameters();
|
parameters.value = compsManager.getParameters();
|
||||||
expression.value = compsManager.getExpression();
|
expression.value = compsManager.getExpression();
|
||||||
outputFormat.value = compsManager.getOutputFormat();
|
outputFormat.value = compsManager.getOutputFormat();
|
||||||
compsManager.on('parametersUpdated', reloadParameters);
|
|
||||||
outputTelemetryCollection.load();
|
outputTelemetryCollection.load();
|
||||||
applyTestData();
|
applyTestData();
|
||||||
});
|
});
|
||||||
@ -179,17 +186,35 @@ onBeforeMount(async () => {
|
|||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
outputTelemetryCollection.off('add', telemetryProcessor);
|
outputTelemetryCollection.off('add', telemetryProcessor);
|
||||||
outputTelemetryCollection.off('clear', clearData);
|
outputTelemetryCollection.off('clear', clearData);
|
||||||
|
compsManager.off('parameterAdded', reloadParameters);
|
||||||
|
compsManager.off('parameterRemoved', reloadParameters);
|
||||||
outputTelemetryCollection.destroy();
|
outputTelemetryCollection.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
function reloadParameters() {
|
watch(
|
||||||
parameters.value = compsManager.getParameters();
|
() => props.isEditing,
|
||||||
domainObject.configuration.comps.parameters = parameters.value;
|
(editMode) => {
|
||||||
compsManager.setDomainObject(domainObject);
|
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() {
|
function updateParameters() {
|
||||||
console.debug('🚀 CompsView: updateParameters', parameters.value);
|
|
||||||
openmct.objects.mutate(domainObject, `configuration.comps.parameters`, parameters.value);
|
openmct.objects.mutate(domainObject, `configuration.comps.parameters`, parameters.value);
|
||||||
compsManager.setDomainObject(domainObject);
|
compsManager.setDomainObject(domainObject);
|
||||||
applyTestData();
|
applyTestData();
|
||||||
@ -217,6 +242,9 @@ function getValueFormatter() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function applyTestData() {
|
function applyTestData() {
|
||||||
|
if (!expression.value || !parameters.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const scope = parameters.value.reduce((acc, parameter) => {
|
const scope = parameters.value.reduce((acc, parameter) => {
|
||||||
acc[parameter.name] = parameter.testValue;
|
acc[parameter.name] = parameter.testValue;
|
||||||
return acc;
|
return acc;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user