mirror of
https://github.com/nasa/openmct.git
synced 2024-12-21 22:17:49 +00:00
works
This commit is contained in:
parent
d859322a47
commit
395436a361
@ -93,9 +93,6 @@ export default class TelemetryCollection extends EventEmitter {
|
||||
if (this.options.end) {
|
||||
this.lastBounds.end = this.options.end;
|
||||
}
|
||||
console.debug(
|
||||
`🫙 Bounds for collection are start ${new Date(this.lastBounds.start).toISOString()} and end ${new Date(this.lastBounds.end).toISOString()}`
|
||||
);
|
||||
this._watchBounds();
|
||||
this._watchTimeSystem();
|
||||
this._watchTimeModeChange();
|
||||
@ -140,9 +137,6 @@ export default class TelemetryCollection extends EventEmitter {
|
||||
* @private
|
||||
*/
|
||||
async _requestHistoricalTelemetry() {
|
||||
console.debug(
|
||||
`🫙 Requesting historical telemetry with start ${new Date(this.lastBounds.start).toISOString()} and end ${new Date(this.lastBounds.end).toISOString()}}`
|
||||
);
|
||||
let options = this.openmct.telemetry.standardizeRequestOptions({ ...this.options });
|
||||
const historicalProvider = this.openmct.telemetry.findRequestProvider(
|
||||
this.domainObject,
|
||||
@ -243,19 +237,6 @@ export default class TelemetryCollection extends EventEmitter {
|
||||
beforeStartOfBounds = parsedValue < boundsToUse.start;
|
||||
afterEndOfBounds = parsedValue > boundsToUse.end;
|
||||
|
||||
if (beforeStartOfBounds) {
|
||||
console.debug(
|
||||
`🫙 Datum is BEFORE start of bounds: ${new Date(parsedValue).toISOString()} < ${new Date(this.lastBounds.start).toISOString()}`,
|
||||
this.options
|
||||
);
|
||||
}
|
||||
if (afterEndOfBounds) {
|
||||
console.debug(
|
||||
`🫙 Datum is AFTER start of bounds: ${new Date(parsedValue).toISOString()} < ${new Date(this.lastBounds.start).toISOString()}`,
|
||||
this.options
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
!afterEndOfBounds &&
|
||||
(!beforeStartOfBounds || (this.isStrategyLatest && this.openmct.telemetry.greedyLAD()))
|
||||
|
@ -59,7 +59,8 @@ export default class CompsManager extends EventEmitter {
|
||||
name: `${this.#getNextAlphabeticalParameterName()}`,
|
||||
valueToUse,
|
||||
testValue: 0,
|
||||
timeMetaData
|
||||
timeMetaData,
|
||||
accumulateValues: false
|
||||
});
|
||||
this.emit('parameterAdded', this.#domainObject);
|
||||
}
|
||||
@ -173,27 +174,45 @@ export default class CompsManager extends EventEmitter {
|
||||
}
|
||||
}
|
||||
|
||||
getFullDataFrame(newTelemetry) {
|
||||
const dataFrame = {};
|
||||
// can assume on data item
|
||||
const newTelemetryKey = Object.keys(newTelemetry)[0];
|
||||
const newTelemetryData = newTelemetry[newTelemetryKey];
|
||||
const otherTelemetryKeys = Object.keys(this.#telemetryCollections).filter(
|
||||
(keyString) => keyString !== newTelemetryKey
|
||||
#getParameterForKeyString(keyString) {
|
||||
return this.#domainObject.configuration.comps.parameters.find(
|
||||
(parameter) => parameter.keyString === keyString
|
||||
);
|
||||
// initialize the data frame with the new telemetry data
|
||||
dataFrame[newTelemetryKey] = newTelemetryData;
|
||||
// initialize the other telemetry data
|
||||
}
|
||||
|
||||
getTelemetryForComps(newTelemetry) {
|
||||
const telemetryForComps = {};
|
||||
const newTelemetryKey = Object.keys(newTelemetry)[0];
|
||||
const newTelemetryParameter = this.#getParameterForKeyString(newTelemetryKey);
|
||||
const newTelemetryData = newTelemetry[newTelemetryKey];
|
||||
const otherTelemetryKeys = Object.keys(this.#telemetryCollections).slice(0);
|
||||
if (newTelemetryParameter.accumulateValues) {
|
||||
telemetryForComps[newTelemetryKey] = this.#telemetryCollections[newTelemetryKey].getAll();
|
||||
} else {
|
||||
telemetryForComps[newTelemetryKey] = newTelemetryData;
|
||||
}
|
||||
otherTelemetryKeys.forEach((keyString) => {
|
||||
dataFrame[keyString] = [];
|
||||
telemetryForComps[keyString] = [];
|
||||
});
|
||||
|
||||
// march through the new telemetry data and add data to the frame from the other telemetry objects
|
||||
// using LOCF
|
||||
const otherTelemetryKeysNotAccumulating = otherTelemetryKeys.filter(
|
||||
(keyString) => !this.#getParameterForKeyString(keyString).accumulateValues
|
||||
);
|
||||
const otherTelemetryKeysAccumulating = otherTelemetryKeys.filter(
|
||||
(keyString) => this.#getParameterForKeyString(keyString).accumulateValues
|
||||
);
|
||||
|
||||
// if we're accumulating, just add all the data
|
||||
otherTelemetryKeysAccumulating.forEach((keyString) => {
|
||||
telemetryForComps[keyString] = this.#telemetryCollections[keyString].getAll();
|
||||
});
|
||||
|
||||
// for the others, march through the new telemetry data and add data to the frame from the other telemetry objects
|
||||
// using LOCF
|
||||
newTelemetryData.forEach((newDatum) => {
|
||||
otherTelemetryKeys.forEach((otherKeyString) => {
|
||||
otherTelemetryKeysNotAccumulating.forEach((otherKeyString) => {
|
||||
const otherCollection = this.#telemetryCollections[otherKeyString];
|
||||
// otherwise we need to find the closest datum to the new datum
|
||||
let insertionPointForNewData = otherCollection._sortedIndex(newDatum);
|
||||
const otherCollectionData = otherCollection.getAll();
|
||||
if (insertionPointForNewData && insertionPointForNewData >= otherCollectionData.length) {
|
||||
@ -202,11 +221,11 @@ export default class CompsManager extends EventEmitter {
|
||||
// get the closest datum to the new datum
|
||||
const closestDatum = otherCollectionData[insertionPointForNewData];
|
||||
if (closestDatum) {
|
||||
dataFrame[otherKeyString].push(closestDatum);
|
||||
telemetryForComps[otherKeyString].push(closestDatum);
|
||||
}
|
||||
});
|
||||
});
|
||||
return dataFrame;
|
||||
return telemetryForComps;
|
||||
}
|
||||
|
||||
#removeTelemetryObject = (telemetryObjectIdentifier) => {
|
||||
|
@ -5,7 +5,8 @@ onconnect = function (e) {
|
||||
const port = e.ports[0];
|
||||
|
||||
port.onmessage = function (event) {
|
||||
const { type, callbackID, telemetryForComps, expression, parameters } = event.data;
|
||||
const { type, callbackID, telemetryForComps, expression, parameters, newTelemetry } =
|
||||
event.data;
|
||||
let responseType = 'unknown';
|
||||
let error = null;
|
||||
let result = [];
|
||||
@ -15,7 +16,7 @@ onconnect = function (e) {
|
||||
result = calculateRequest(telemetryForComps, parameters, expression);
|
||||
} else if (type === 'calculateSubscription') {
|
||||
responseType = 'calculationSubscriptionResult';
|
||||
result = calculateSubscription(telemetryForComps, parameters, expression);
|
||||
result = calculateSubscription(telemetryForComps, newTelemetry, parameters, expression);
|
||||
} else if (type === 'init') {
|
||||
port.postMessage({ type: 'ready' });
|
||||
return;
|
||||
@ -40,9 +41,16 @@ function getFullDataFrame(telemetryForComps, parameters) {
|
||||
return dataFrame;
|
||||
}
|
||||
|
||||
function calculateSubscription(telemetryForComps, parameters, expression) {
|
||||
function calculateSubscription(telemetryForComps, newTelemetry, parameters, expression) {
|
||||
const dataFrame = getFullDataFrame(telemetryForComps, parameters);
|
||||
return calculate(dataFrame, parameters, expression);
|
||||
const calculation = calculate(dataFrame, parameters, expression);
|
||||
const newTelemetryKey = Object.keys(newTelemetry)[0];
|
||||
const newTelemetrySize = newTelemetry[newTelemetryKey].length;
|
||||
let trimmedCalculation = calculation;
|
||||
if (calculation.length > newTelemetrySize) {
|
||||
trimmedCalculation = calculation.slice(calculation.length - newTelemetrySize);
|
||||
}
|
||||
return trimmedCalculation;
|
||||
}
|
||||
|
||||
function calculateRequest(telemetryForComps, parameters, expression) {
|
||||
@ -56,14 +64,28 @@ function calculate(dataFrame, parameters, expression) {
|
||||
if (!expression) {
|
||||
return sumResults;
|
||||
}
|
||||
// set up accumulated data structure
|
||||
const accumulatedData = {};
|
||||
parameters.forEach((parameter) => {
|
||||
if (parameter.accumulateValues) {
|
||||
accumulatedData[parameter.name] = [];
|
||||
}
|
||||
});
|
||||
|
||||
// take the first parameter keyString as the reference
|
||||
const referenceParameter = parameters[0];
|
||||
const otherParameters = parameters.slice(1);
|
||||
// iterate over the reference telemetry data
|
||||
const referenceTelemetry = dataFrame[referenceParameter.keyString];
|
||||
referenceTelemetry?.forEach((referenceTelemetryItem) => {
|
||||
let referenceValue = referenceTelemetryItem[referenceParameter.valueToUse];
|
||||
if (referenceParameter.accumulateValues) {
|
||||
accumulatedData[referenceParameter.name].push(referenceValue);
|
||||
referenceValue = accumulatedData[referenceParameter.name];
|
||||
}
|
||||
|
||||
const scope = {
|
||||
[referenceParameter.name]: referenceTelemetryItem[referenceParameter.valueToUse]
|
||||
[referenceParameter.name]: referenceValue
|
||||
};
|
||||
const referenceTime = referenceTelemetryItem[referenceParameter.timeKey];
|
||||
// iterate over the other parameters to set the scope
|
||||
@ -75,7 +97,12 @@ function calculate(dataFrame, parameters, expression) {
|
||||
missingData = true;
|
||||
return;
|
||||
}
|
||||
scope[parameter.name] = otherTelemetry[parameter.valueToUse];
|
||||
let otherValue = otherTelemetry[parameter.valueToUse];
|
||||
if (parameter.accumulateValues) {
|
||||
accumulatedData[parameter.name].push(referenceValue);
|
||||
otherValue = accumulatedData[referenceParameter.name];
|
||||
}
|
||||
scope[parameter.name] = otherValue;
|
||||
});
|
||||
if (missingData) {
|
||||
return;
|
||||
|
@ -61,6 +61,7 @@ export default class CompsMetadataProvider {
|
||||
key: 'compsOutput',
|
||||
source: 'compsOutput',
|
||||
name: 'Output',
|
||||
derived: true,
|
||||
formatString: specificCompsManager.getOutputFormat(),
|
||||
hints: {
|
||||
range: 1
|
||||
|
@ -95,7 +95,7 @@ export default class CompsTelemetryProvider {
|
||||
return;
|
||||
}
|
||||
const expression = specificCompsManager.getExpression();
|
||||
const telemetryForComps = specificCompsManager.getFullDataFrame(newTelemetry);
|
||||
const telemetryForComps = specificCompsManager.getTelemetryForComps(newTelemetry);
|
||||
const parameters = JSON.parse(JSON.stringify(specificCompsManager.getParameters()));
|
||||
if (!expression || !parameters) {
|
||||
return;
|
||||
@ -103,6 +103,7 @@ export default class CompsTelemetryProvider {
|
||||
const payload = {
|
||||
type: 'calculateSubscription',
|
||||
telemetryForComps,
|
||||
newTelemetry,
|
||||
expression,
|
||||
parameters,
|
||||
callbackID
|
||||
@ -134,10 +135,6 @@ export default class CompsTelemetryProvider {
|
||||
);
|
||||
return () => {
|
||||
delete this.#subscriptionCallbacks[callbackID];
|
||||
console.debug(
|
||||
`🛑 Stopping subscription for ${domainObject.name} with callback ID ${callbackID}. We now have ${Object.keys(this.#subscriptionCallbacks).length} subscribers`,
|
||||
this.#subscriptionCallbacks
|
||||
);
|
||||
specificCompsManager.stopListeningToUnderlyingTelemetry();
|
||||
specificCompsManager.off('underlyingTelemetryUpdated', boundComputeOnNewTelemetry);
|
||||
};
|
||||
|
@ -95,6 +95,25 @@
|
||||
</option>
|
||||
</select>
|
||||
<div v-else>{{ parameter.valueToUse }}</div>
|
||||
<div
|
||||
:class="[
|
||||
'c-comps__refs-controls c-cdef__controls',
|
||||
{ disabled: !parameters?.length }
|
||||
]"
|
||||
>
|
||||
<label v-if="isEditing" class="c-toggle-switch">
|
||||
<input
|
||||
v-model="parameter.accumulateValues"
|
||||
type="checkbox"
|
||||
@change="updateAccumulateValues(parameter)"
|
||||
/>
|
||||
<span
|
||||
class="c-toggle-switch__slider"
|
||||
aria-label="Toggle Parameter Accumulation"
|
||||
></span>
|
||||
<span class="c-toggle-switch__label">Accumulate Values</span>
|
||||
</label>
|
||||
</div>
|
||||
</span>
|
||||
|
||||
<span v-if="isEditing" class="c-test-datum__string">Test value</span>
|
||||
@ -235,6 +254,15 @@ function updateParameters() {
|
||||
applyTestData();
|
||||
}
|
||||
|
||||
function updateAccumulateValues(parameter) {
|
||||
if (parameter.accumulateValues) {
|
||||
parameter.testValue = [''];
|
||||
} else {
|
||||
parameter.testValue = '';
|
||||
}
|
||||
updateParameters();
|
||||
}
|
||||
|
||||
function toggleTestData() {
|
||||
testDataApplied.value = !testDataApplied.value;
|
||||
if (testDataApplied.value) {
|
||||
@ -270,6 +298,20 @@ function applyTestData() {
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
// see which parameters are misconfigured as non-arrays
|
||||
const misconfiguredParameterNames = parameters.value
|
||||
.filter((parameter) => {
|
||||
return parameter.accumulateValues && !Array.isArray(scope[parameter.name]);
|
||||
})
|
||||
.map((parameter) => parameter.name);
|
||||
if (misconfiguredParameterNames.length) {
|
||||
const misconfiguredParameterNamesString = misconfiguredParameterNames.join(', ');
|
||||
currentTestOutput.value = null;
|
||||
expressionOutput.value = `Reference "${misconfiguredParameterNamesString}" set to accumulating, but test values aren't arrays.`;
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const testOutput = evaluate(expression.value, scope);
|
||||
const formattedData = getValueFormatter().format(testOutput);
|
||||
|
@ -225,7 +225,13 @@ export default class PlotSeries extends Model {
|
||||
|
||||
try {
|
||||
const points = await this.openmct.telemetry.request(this.domainObject, options);
|
||||
const data = this.getSeriesData();
|
||||
// if derived, we can't use the old data
|
||||
let data = this.getSeriesData();
|
||||
|
||||
if (this.metadata.value(this.get('yKey')).derived) {
|
||||
data = [];
|
||||
}
|
||||
|
||||
// eslint-disable-next-line you-dont-need-lodash-underscore/concat
|
||||
const newPoints = _(data)
|
||||
.concat(points)
|
||||
|
Loading…
Reference in New Issue
Block a user