mirror of
https://github.com/nasa/openmct.git
synced 2025-04-19 08:36:24 +00:00
Add realtime output of telemetry data in conditionals and add support for historical conditional telemetry queries to allow for plotting
This commit is contained in:
parent
73489cd78d
commit
23cf829fdc
@ -24,6 +24,7 @@ import { EventEmitter } from 'eventemitter3';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
|
||||
import Condition from './Condition.js';
|
||||
import HistoricalTelemetryProvider from './historicalTelemetryProvider.js';
|
||||
import { getLatestTimestamp } from './utils/time.js';
|
||||
|
||||
export default class ConditionManager extends EventEmitter {
|
||||
@ -46,6 +47,8 @@ export default class ConditionManager extends EventEmitter {
|
||||
applied: false
|
||||
};
|
||||
this.initialize();
|
||||
this.telemetryBuffer = [];
|
||||
this.isProcessing = false;
|
||||
}
|
||||
|
||||
subscribeToTelemetry(telemetryObject) {
|
||||
@ -320,6 +323,17 @@ export default class ConditionManager extends EventEmitter {
|
||||
return currentCondition;
|
||||
}
|
||||
|
||||
getHistoricalData() {
|
||||
const historicalTelemetry = new HistoricalTelemetryProvider(
|
||||
this.openmct,
|
||||
this.telemetryObjects,
|
||||
this.compositionLoad,
|
||||
this.conditions,
|
||||
this.conditionSetDomainObject
|
||||
);
|
||||
return historicalTelemetry.getHistoricalData();
|
||||
}
|
||||
|
||||
getCurrentConditionLAD(conditionResults) {
|
||||
const conditionCollection = this.conditionSetDomainObject.configuration.conditionCollection;
|
||||
let currentCondition = conditionCollection[conditionCollection.length - 1];
|
||||
@ -375,8 +389,26 @@ export default class ConditionManager extends EventEmitter {
|
||||
}
|
||||
|
||||
const currentCondition = this.getCurrentConditionLAD(conditionResults);
|
||||
let output = currentCondition?.configuration?.output;
|
||||
if (output === 'telemetry value') {
|
||||
const { outputTelemetry, outputMetadata } = currentCondition.configuration;
|
||||
const outputTelemetryObject = await this.openmct.objects.get(outputTelemetry);
|
||||
const telemetryOptions = {
|
||||
size: 1,
|
||||
strategy: 'latest',
|
||||
timeContext: this.openmct.time.getContextForView([])
|
||||
};
|
||||
const latestData = await this.openmct.telemetry.request(
|
||||
outputTelemetryObject,
|
||||
telemetryOptions
|
||||
);
|
||||
if (latestData?.[0]?.[outputMetadata]) {
|
||||
output = latestData?.[0]?.[outputMetadata];
|
||||
}
|
||||
}
|
||||
|
||||
const currentOutput = {
|
||||
output: currentCondition.configuration.output,
|
||||
output: output,
|
||||
id: this.conditionSetDomainObject.identifier,
|
||||
conditionId: currentCondition.id,
|
||||
...latestTimestamp
|
||||
@ -394,6 +426,18 @@ export default class ConditionManager extends EventEmitter {
|
||||
}
|
||||
}
|
||||
|
||||
const conditionTelemetries = [];
|
||||
const conditions = this.conditionSetDomainObject.configuration.conditionCollection;
|
||||
conditions.forEach((condition) => {
|
||||
if (condition?.configuration?.outputTelemetry) {
|
||||
conditionTelemetries.push(condition?.configuration?.outputTelemetry);
|
||||
}
|
||||
});
|
||||
|
||||
if (conditionTelemetries.includes(id)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -415,7 +459,7 @@ export default class ConditionManager extends EventEmitter {
|
||||
timestamp[timeSystemKey] = currentTimestamp;
|
||||
if (this.shouldEvaluateNewTelemetry(currentTimestamp)) {
|
||||
this.updateConditionResults(normalizedDatum);
|
||||
this.updateCurrentCondition(timestamp);
|
||||
this.updateCurrentCondition(timestamp, endpoint, datum);
|
||||
}
|
||||
}
|
||||
|
||||
@ -428,14 +472,12 @@ export default class ConditionManager extends EventEmitter {
|
||||
});
|
||||
}
|
||||
|
||||
updateCurrentCondition(timestamp) {
|
||||
const currentCondition = this.getCurrentCondition();
|
||||
|
||||
emitConditionSetResult(currentCondition, timestamp, outputValue) {
|
||||
this.emit(
|
||||
'conditionSetResultUpdated',
|
||||
Object.assign(
|
||||
{
|
||||
output: currentCondition.configuration.output,
|
||||
output: outputValue,
|
||||
id: this.conditionSetDomainObject.identifier,
|
||||
conditionId: currentCondition.id
|
||||
},
|
||||
@ -444,6 +486,60 @@ export default class ConditionManager extends EventEmitter {
|
||||
);
|
||||
}
|
||||
|
||||
updateCurrentCondition(timestamp, telemetryObject, telemetryData) {
|
||||
this.telemetryBuffer.push({ timestamp, telemetryObject, telemetryData });
|
||||
|
||||
if (!this.isProcessing) {
|
||||
this.processBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
async processBuffer() {
|
||||
this.isProcessing = true;
|
||||
|
||||
while (this.telemetryBuffer.length > 0) {
|
||||
const { timestamp, telemetryObject, telemetryData } = this.telemetryBuffer.shift();
|
||||
await this.processCondition(timestamp, telemetryObject, telemetryData);
|
||||
}
|
||||
|
||||
this.isProcessing = false;
|
||||
}
|
||||
|
||||
async processCondition(timestamp, telemetryObject, telemetryData) {
|
||||
const currentCondition = this.getCurrentCondition();
|
||||
let telemetryValue = currentCondition.configuration.output;
|
||||
if (currentCondition?.configuration?.outputTelemetry) {
|
||||
const selectedOutputIdentifier = currentCondition?.configuration?.outputTelemetry;
|
||||
const outputMetadata = currentCondition?.configuration?.outputMetadata;
|
||||
const telemetryKeystring = this.openmct.objects.makeKeyString(telemetryObject.identifier);
|
||||
|
||||
if (selectedOutputIdentifier === telemetryKeystring) {
|
||||
telemetryValue = telemetryData[outputMetadata];
|
||||
} else {
|
||||
const outputTelemetryObject = await this.openmct.objects.get(selectedOutputIdentifier);
|
||||
const telemetryOptions = {
|
||||
size: 1,
|
||||
strategy: 'latest',
|
||||
start: timestamp?.utc - 1000,
|
||||
end: timestamp?.utc + 1000
|
||||
};
|
||||
const outputTelemetryData = await this.openmct.telemetry.request(
|
||||
outputTelemetryObject,
|
||||
telemetryOptions
|
||||
);
|
||||
const outputTelemetryValue =
|
||||
outputTelemetryData?.length > 0 ? outputTelemetryData.slice(-1)[0] : null;
|
||||
if (outputTelemetryData.length && outputTelemetryValue?.[outputMetadata]) {
|
||||
telemetryValue = outputTelemetryValue?.[outputMetadata];
|
||||
} else {
|
||||
telemetryValue = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.emitConditionSetResult(currentCondition, timestamp, telemetryValue);
|
||||
}
|
||||
|
||||
getTestData(metadatum) {
|
||||
let data = undefined;
|
||||
if (this.testData.applied) {
|
||||
|
@ -42,8 +42,9 @@ export default class ConditionSetTelemetryProvider {
|
||||
|
||||
async request(domainObject, options) {
|
||||
let conditionManager = this.getConditionManager(domainObject);
|
||||
const formattedHistoricalData = await conditionManager.getHistoricalData();
|
||||
let latestOutput = await conditionManager.requestLADConditionSetOutput(options);
|
||||
return latestOutput;
|
||||
return [...formattedHistoricalData, ...latestOutput];
|
||||
}
|
||||
|
||||
subscribe(domainObject, callback) {
|
||||
|
@ -235,10 +235,11 @@ export default {
|
||||
|
||||
return arr;
|
||||
},
|
||||
addTelemetryObject(domainObject) {
|
||||
async addTelemetryObject(domainObject) {
|
||||
const keyString = this.openmct.objects.makeKeyString(domainObject.identifier);
|
||||
const telemetryPath = await this.getFullTelemetryPath(domainObject);
|
||||
|
||||
this.telemetryObjs.push(domainObject);
|
||||
this.telemetryObjs.push({ ...domainObject, path: telemetryPath });
|
||||
this.$emit('telemetry-updated', this.telemetryObjs);
|
||||
|
||||
this.subscribeToStaleness(domainObject, (stalenessResponse) => {
|
||||
@ -248,6 +249,19 @@ export default {
|
||||
});
|
||||
});
|
||||
},
|
||||
async getFullTelemetryPath(telemetry) {
|
||||
const keyString = this.openmct.objects.makeKeyString(telemetry.identifier);
|
||||
const originalPathObjects = await this.openmct.objects.getOriginalPath(keyString, []);
|
||||
|
||||
const telemetryPath = originalPathObjects.reverse().map((pathObject) => {
|
||||
if (pathObject.type !== 'root') {
|
||||
return pathObject.name;
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
|
||||
return telemetryPath.join('/');
|
||||
},
|
||||
removeTelemetryObject(identifier) {
|
||||
const keyString = this.openmct.objects.makeKeyString(identifier);
|
||||
const index = this.telemetryObjs.findIndex((obj) => {
|
||||
|
@ -99,13 +99,13 @@
|
||||
@change="setOutputValue"
|
||||
>
|
||||
<option v-for="option in outputOptions" :key="option" :value="option">
|
||||
{{ initCap(option) }}
|
||||
{{ option }}
|
||||
</option>
|
||||
</select>
|
||||
</span>
|
||||
<span class="c-cdef__control">
|
||||
<input
|
||||
v-if="selectedOutputSelection === outputOptions[2]"
|
||||
v-if="selectedOutputSelection === outputOptions[3]"
|
||||
v-model="condition.configuration.output"
|
||||
aria-label="Condition Output String"
|
||||
class="t-condition-name-input"
|
||||
@ -113,8 +113,41 @@
|
||||
@change="persist"
|
||||
/>
|
||||
</span>
|
||||
<span v-if="selectedOutputSelection === 'telemetry value'" class="c-cdef__control">
|
||||
<select
|
||||
v-model="condition.configuration.outputTelemetry"
|
||||
aria-label="Output Telemetry Selection"
|
||||
@change="persist"
|
||||
>
|
||||
<option value="">- Select Telemetry -</option>
|
||||
<option
|
||||
v-for="telemetryOption in telemetry"
|
||||
:key="openmct.objects.makeKeyString(telemetryOption.identifier)"
|
||||
:value="openmct.objects.makeKeyString(telemetryOption.identifier)"
|
||||
>
|
||||
{{ telemetryOption.path }}
|
||||
</option>
|
||||
</select>
|
||||
</span>
|
||||
<span v-if="condition.configuration.outputTelemetry" class="c-cdef__control">
|
||||
<select
|
||||
v-model="condition.configuration.outputMetadata"
|
||||
aria-label="Output Telemetry Metadata Selection"
|
||||
@change="persist"
|
||||
>
|
||||
<option value="">- Select Field -</option>
|
||||
<option
|
||||
v-for="(option, index) in telemetryMetadataOptions[
|
||||
condition.configuration.outputTelemetry
|
||||
]"
|
||||
:key="index"
|
||||
:value="option.key"
|
||||
>
|
||||
{{ option.name }}
|
||||
</option>
|
||||
</select>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<div v-if="!condition.isDefault" class="c-cdef__match-and-criteria">
|
||||
<span class="c-cdef__separator c-row-separator"></span>
|
||||
<span class="c-cdef__label">Match</span>
|
||||
@ -181,7 +214,12 @@
|
||||
<span class="c-condition__name">
|
||||
{{ condition.configuration.name }}
|
||||
</span>
|
||||
<span class="c-condition__output"> Output: {{ condition.configuration.output }} </span>
|
||||
<span class="c-condition__output">
|
||||
Output:
|
||||
{{
|
||||
condition.configuration.output === undefined ? 'none' : condition.configuration.output
|
||||
}}
|
||||
</span>
|
||||
</div>
|
||||
<div class="c-condition__summary">
|
||||
<ConditionDescription :show-label="false" :condition="condition" />
|
||||
@ -250,10 +288,11 @@ export default {
|
||||
expanded: true,
|
||||
trigger: 'all',
|
||||
selectedOutputSelection: '',
|
||||
outputOptions: ['false', 'true', 'string'],
|
||||
outputOptions: ['none', 'false', 'true', 'string', 'telemetry value'],
|
||||
criterionIndex: 0,
|
||||
draggingOver: false,
|
||||
isDefault: this.condition.isDefault
|
||||
isDefault: this.condition.isDefault,
|
||||
telemetryMetadataOptions: {}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@ -287,26 +326,51 @@ export default {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
condition: {
|
||||
handler() {
|
||||
if (this.condition.configuration.output !== 'telemetry value') {
|
||||
this.condition.configuration.outputTelemetry = null;
|
||||
this.condition.configuration.outputMetadata = null;
|
||||
}
|
||||
},
|
||||
deep: true
|
||||
},
|
||||
isEditing(newValue, oldValue) {
|
||||
if (newValue === true) {
|
||||
this.initializeMetadata();
|
||||
}
|
||||
}
|
||||
},
|
||||
unmounted() {
|
||||
this.destroy();
|
||||
},
|
||||
mounted() {
|
||||
this.setOutputSelection();
|
||||
this.initializeMetadata();
|
||||
},
|
||||
methods: {
|
||||
setOutputSelection() {
|
||||
let conditionOutput = this.condition.configuration.output;
|
||||
if (conditionOutput) {
|
||||
if (conditionOutput !== 'false' && conditionOutput !== 'true') {
|
||||
if (
|
||||
conditionOutput !== 'false' &&
|
||||
conditionOutput !== 'true' &&
|
||||
conditionOutput !== 'telemetry value'
|
||||
) {
|
||||
this.selectedOutputSelection = 'string';
|
||||
} else {
|
||||
this.selectedOutputSelection = conditionOutput;
|
||||
}
|
||||
} else if (conditionOutput === undefined) {
|
||||
this.selectedOutputSelection = 'none';
|
||||
}
|
||||
},
|
||||
setOutputValue() {
|
||||
if (this.selectedOutputSelection === 'string') {
|
||||
this.condition.configuration.output = '';
|
||||
} else if (this.selectedOutputSelection === 'none') {
|
||||
this.condition.configuration.output = undefined;
|
||||
} else {
|
||||
this.condition.configuration.output = this.selectedOutputSelection;
|
||||
}
|
||||
@ -401,6 +465,24 @@ export default {
|
||||
},
|
||||
initCap(str) {
|
||||
return str.charAt(0).toUpperCase() + str.slice(1);
|
||||
},
|
||||
initializeMetadata() {
|
||||
this.telemetry.forEach((telemetryObject) => {
|
||||
const id = this.openmct.objects.makeKeyString(telemetryObject.identifier);
|
||||
let telemetryMetadata = this.openmct.telemetry.getMetadata(telemetryObject);
|
||||
if (telemetryMetadata) {
|
||||
this.telemetryMetadataOptions[id] = telemetryMetadata.values().slice();
|
||||
} else {
|
||||
this.telemetryMetadataOptions[id] = [];
|
||||
}
|
||||
});
|
||||
},
|
||||
getId(identifier) {
|
||||
if (identifier) {
|
||||
return this.openmct.objects.makeKeyString(identifier);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -40,7 +40,7 @@
|
||||
:key="telemetryOption.identifier.key"
|
||||
:value="telemetryOption.identifier"
|
||||
>
|
||||
{{ telemetryOption.name }}
|
||||
{{ telemetryOption.path }}
|
||||
</option>
|
||||
</select>
|
||||
</span>
|
||||
|
@ -63,7 +63,7 @@
|
||||
:key="index"
|
||||
:value="telemetryOption.identifier"
|
||||
>
|
||||
{{ telemetryOption.name }}
|
||||
{{ telemetryPaths[index] || telemetryOption.name }}
|
||||
</option>
|
||||
</select>
|
||||
</span>
|
||||
@ -147,7 +147,8 @@ export default {
|
||||
expanded: true,
|
||||
isApplied: false,
|
||||
testInputs: [],
|
||||
telemetryMetadataOptions: {}
|
||||
telemetryMetadataOptions: {},
|
||||
telemetryPaths: []
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
@ -200,6 +201,10 @@ export default {
|
||||
this.telemetryMetadataOptions[id] = [];
|
||||
}
|
||||
});
|
||||
this.telemetry.forEach(async (telemetryOption, index) => {
|
||||
const telemetryPath = await this.getFullTelemetryPath(telemetryOption);
|
||||
this.telemetryPaths[index] = telemetryPath;
|
||||
});
|
||||
},
|
||||
addTestInput(testInput) {
|
||||
this.testInputs.push(
|
||||
@ -244,6 +249,22 @@ export default {
|
||||
applied: this.isApplied,
|
||||
conditionTestInputs: this.testInputs
|
||||
});
|
||||
},
|
||||
async getFullTelemetryPath(telemetry) {
|
||||
const keyStringForObject = this.openmct.objects.makeKeyString(telemetry.identifier);
|
||||
const originalPathObjects = await this.openmct.objects.getOriginalPath(
|
||||
keyStringForObject,
|
||||
[]
|
||||
);
|
||||
|
||||
const telemetryPath = originalPathObjects.reverse().map((pathObject) => {
|
||||
if (pathObject.type !== 'root') {
|
||||
return pathObject.name;
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
|
||||
return telemetryPath.join('/');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
274
src/plugins/condition/historicalTelemetryProvider.js
Normal file
274
src/plugins/condition/historicalTelemetryProvider.js
Normal file
@ -0,0 +1,274 @@
|
||||
export default class HistoricalTelemetryProvider {
|
||||
constructor(openmct, telemetryObjects, compositionLoad, conditions, conditionSetDomainObject) {
|
||||
this.openmct = openmct;
|
||||
this.telemetryObjects = telemetryObjects;
|
||||
this.compositionLoad = compositionLoad;
|
||||
this.bounds = { start: null, end: null };
|
||||
this.telemetryList = [];
|
||||
this.conditions = conditions;
|
||||
this.conditionSetDomainObject = conditionSetDomainObject;
|
||||
this.historicalTelemetryPoolMap = new Map();
|
||||
this.historicalTelemetryDateMap = new Map();
|
||||
this.index = 0;
|
||||
}
|
||||
|
||||
setTimeBounds(bounds) {
|
||||
this.bounds = bounds;
|
||||
}
|
||||
|
||||
refreshAllHistoricalTelemetries() {
|
||||
const refreshPromises = [];
|
||||
for (const [, value] of Object.entries(this.telemetryObjects)) {
|
||||
refreshPromises.push(this.refreshHistoricalTelemetry(value));
|
||||
}
|
||||
return Promise.all(refreshPromises);
|
||||
}
|
||||
|
||||
async refreshHistoricalTelemetry(domainObject, identifier) {
|
||||
console.log('refreshHistoricalTelemetry');
|
||||
if (!domainObject && identifier) {
|
||||
domainObject = await this.openmct.objects.get(identifier);
|
||||
}
|
||||
const id = this.openmct.objects.makeKeyString(domainObject.identifier);
|
||||
const telemetryOptions = { ...this.bounds };
|
||||
const historicalTelemetry = await this.openmct.telemetry.request(
|
||||
domainObject,
|
||||
telemetryOptions
|
||||
);
|
||||
this.historicalTelemetryPoolMap.set(id, { domainObject, historicalTelemetry });
|
||||
return { domainObject, historicalTelemetry };
|
||||
}
|
||||
|
||||
evaluateTrueCondition(historicalDateMap, timestamp, condition, conditionCollectionMap) {
|
||||
const telemetryData = historicalDateMap.get(timestamp);
|
||||
const conditionConfiguration = conditionCollectionMap.get(condition.id)?.configuration;
|
||||
const { outputTelemetry, outputMetadata } = conditionConfiguration;
|
||||
let output = {};
|
||||
if (outputTelemetry) {
|
||||
const outputTelemetryID = this.openmct.objects.makeKeyString(outputTelemetry);
|
||||
const outputTelemetryData = telemetryData.get(outputTelemetryID);
|
||||
output.telemetry = outputTelemetryData;
|
||||
output.value = outputTelemetryData[outputMetadata];
|
||||
output.condition = condition;
|
||||
} else if (conditionConfiguration?.output) {
|
||||
output.telemetry = null;
|
||||
output.value = conditionConfiguration?.output;
|
||||
output.condition = condition;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
async getAllTelemetries(conditionCollection) {
|
||||
const conditionCollectionMap = new Map();
|
||||
const inputTelemetries = [];
|
||||
const outputTelemetries = [];
|
||||
const historicalTelemetryPoolPromises = [];
|
||||
|
||||
conditionCollection.forEach((condition, index) => {
|
||||
console.log('-------------------------');
|
||||
console.log(condition);
|
||||
const { id } = condition;
|
||||
const { criteria, output, outputTelemetry, outputMetadata } = condition.configuration;
|
||||
const inputTelemetry = criteria?.[0]?.telemetry;
|
||||
console.log(id);
|
||||
console.log(criteria);
|
||||
console.log(output);
|
||||
console.log(outputMetadata);
|
||||
console.log('inputTelemetry', inputTelemetry);
|
||||
console.log('outputTelemetry', outputTelemetry);
|
||||
conditionCollectionMap.set(condition?.id, condition);
|
||||
if (inputTelemetry) {
|
||||
const inputTelemetryId = this.openmct.objects.makeKeyString(inputTelemetry);
|
||||
if (![...inputTelemetries, ...outputTelemetries].includes(inputTelemetryId)) {
|
||||
historicalTelemetryPoolPromises.push(
|
||||
this.refreshHistoricalTelemetry(null, inputTelemetry)
|
||||
);
|
||||
}
|
||||
inputTelemetries.push(inputTelemetryId);
|
||||
} else {
|
||||
inputTelemetries.push(null);
|
||||
}
|
||||
if (outputTelemetry) {
|
||||
if (![...inputTelemetries, ...outputTelemetries].includes(outputTelemetry)) {
|
||||
historicalTelemetryPoolPromises.push(
|
||||
this.refreshHistoricalTelemetry(null, outputTelemetry)
|
||||
);
|
||||
}
|
||||
outputTelemetries.push(outputTelemetry);
|
||||
} else {
|
||||
outputTelemetries.push(null);
|
||||
}
|
||||
});
|
||||
|
||||
const historicalTelemetriesPool = await Promise.all(historicalTelemetryPoolPromises);
|
||||
return {
|
||||
historicalTelemetriesPool,
|
||||
inputTelemetries,
|
||||
outputTelemetries,
|
||||
conditionCollectionMap
|
||||
};
|
||||
}
|
||||
|
||||
sortTelemetriesByDate(historicalTelemetriesPool) {
|
||||
const historicalTelemetryDateMap = new Map();
|
||||
historicalTelemetriesPool.forEach((historicalTelemetryList) => {
|
||||
const { historicalTelemetry, domainObject } = historicalTelemetryList;
|
||||
const { identifier } = domainObject;
|
||||
const telemetryIdentifier = this.openmct.objects.makeKeyString(identifier);
|
||||
historicalTelemetry.forEach((historicalTelemetryItem) => {
|
||||
if (!historicalTelemetryDateMap.get(historicalTelemetryItem.utc)) {
|
||||
const telemetryMap = new Map();
|
||||
telemetryMap.set(telemetryIdentifier, historicalTelemetryItem);
|
||||
historicalTelemetryDateMap.set(historicalTelemetryItem.utc, telemetryMap);
|
||||
} else {
|
||||
const telemetryMap = historicalTelemetryDateMap.get(historicalTelemetryItem.utc);
|
||||
telemetryMap.set(telemetryIdentifier, historicalTelemetryItem);
|
||||
historicalTelemetryDateMap.set(historicalTelemetryItem.utc, telemetryMap);
|
||||
}
|
||||
});
|
||||
});
|
||||
return historicalTelemetryDateMap;
|
||||
}
|
||||
|
||||
evaluateConditionsByDate(historicalTelemetryDateMap, conditionCollectionMap) {
|
||||
const outputTelemetryDateMap = new Map();
|
||||
historicalTelemetryDateMap.forEach((historicalTelemetryMap, timestamp) => {
|
||||
let isConditionValid = false;
|
||||
const evaluatedConditions = [];
|
||||
this.conditions.forEach((condition) => {
|
||||
if (isConditionValid) {
|
||||
return;
|
||||
}
|
||||
const { id } = condition;
|
||||
const conditionMetadata = { condition };
|
||||
const conditionCriteria = condition.criteria[0];
|
||||
let result;
|
||||
if (conditionCriteria?.telemetry) {
|
||||
const conditionInputTelemetryId = this.openmct.objects.makeKeyString(
|
||||
conditionCriteria.telemetry
|
||||
);
|
||||
const inputTelemetry = historicalTelemetryMap.get(conditionInputTelemetryId);
|
||||
conditionMetadata.inputTelemetry = inputTelemetry;
|
||||
result = conditionCriteria.computeResult({
|
||||
id,
|
||||
...inputTelemetry
|
||||
});
|
||||
} else if (!conditionCriteria) {
|
||||
const conditionDetails = conditionCollectionMap.get(id);
|
||||
const { isDefault } = conditionDetails;
|
||||
const conditionConfiguration = conditionDetails?.configuration;
|
||||
const { outputTelemetry, outputMetadata, output } = conditionConfiguration;
|
||||
if (isDefault) {
|
||||
const conditionOutput = {
|
||||
telemetry: null,
|
||||
value: output,
|
||||
condition
|
||||
};
|
||||
outputTelemetryDateMap.set(timestamp, conditionOutput);
|
||||
}
|
||||
}
|
||||
conditionMetadata.result = result;
|
||||
evaluatedConditions.push(conditionMetadata);
|
||||
if (result === true) {
|
||||
isConditionValid = true;
|
||||
const conditionOutput = this.evaluateTrueCondition(
|
||||
historicalTelemetryDateMap,
|
||||
timestamp,
|
||||
condition,
|
||||
conditionCollectionMap
|
||||
);
|
||||
console.log(conditionOutput.value);
|
||||
outputTelemetryDateMap.set(timestamp, conditionOutput);
|
||||
}
|
||||
});
|
||||
});
|
||||
return outputTelemetryDateMap;
|
||||
}
|
||||
|
||||
async getHistoricalInputsByDate() {
|
||||
console.log('getHistoricalInputsByDate');
|
||||
console.log(this.conditions);
|
||||
const conditionCollection = this.conditionSetDomainObject.configuration.conditionCollection;
|
||||
|
||||
const {
|
||||
historicalTelemetriesPool,
|
||||
inputTelemetries,
|
||||
outputTelemetries,
|
||||
conditionCollectionMap
|
||||
} = await this.getAllTelemetries(conditionCollection);
|
||||
|
||||
const historicalTelemetryDateMap = this.sortTelemetriesByDate(historicalTelemetriesPool);
|
||||
const outputTelemetryDateMap = this.evaluateConditionsByDate(
|
||||
historicalTelemetryDateMap,
|
||||
conditionCollectionMap
|
||||
);
|
||||
|
||||
console.log('*️⃣*️⃣*️⃣*️⃣*️⃣*️⃣*️⃣*️⃣*️⃣*️⃣*️⃣*️⃣*️⃣*️⃣');
|
||||
console.log(historicalTelemetriesPool);
|
||||
console.log(this.historicalTelemetryPoolMap);
|
||||
console.log(inputTelemetries);
|
||||
console.log(outputTelemetries);
|
||||
console.log(historicalTelemetryDateMap);
|
||||
console.log(outputTelemetryDateMap);
|
||||
|
||||
return outputTelemetryDateMap;
|
||||
}
|
||||
|
||||
addItemToHistoricalTelemetryMap(telemetryMap, item, type, index) {
|
||||
if (type === 'input') {
|
||||
telemetryMap.set();
|
||||
}
|
||||
}
|
||||
|
||||
async getHistoricalData() {
|
||||
console.log('getHistoricalData');
|
||||
await this.compositionLoad;
|
||||
this.setTimeBounds(this.openmct.time.getBounds());
|
||||
const outputTelemetryMap = await this.getHistoricalInputsByDate();
|
||||
const formattedOutputTelemetry = this.formatOutputData(outputTelemetryMap);
|
||||
// const firstObjectKey = this.historicalTelemetryPoolMap.keys().next().value;
|
||||
// const firstObjectValue = this.historicalTelemetryPoolMap.values().next().value;
|
||||
// const formattedHistoricalData = this.formatHistoricalData(firstObjectKey, firstObjectValue);
|
||||
console.log(formattedOutputTelemetry);
|
||||
// console.log(formattedHistoricalData);
|
||||
return formattedOutputTelemetry;
|
||||
}
|
||||
|
||||
formatOutputData(outputTelemetryMap) {
|
||||
const outputTelemetryList = [];
|
||||
const domainObject = this.conditionSetDomainObject;
|
||||
outputTelemetryMap.forEach((outputMetadata, timestamp) => {
|
||||
const { condition, telemetry, value } = outputMetadata;
|
||||
outputTelemetryList.push({
|
||||
conditionId: condition.id,
|
||||
id: domainObject.identifier,
|
||||
output: value,
|
||||
utc: timestamp
|
||||
});
|
||||
});
|
||||
return outputTelemetryList;
|
||||
}
|
||||
|
||||
simpleTelemetryList(outputTelemetryMap) {
|
||||
const outputTelemetryList = [];
|
||||
outputTelemetryMap.forEach((outputMetadata, timestamp) => {
|
||||
const { value } = outputMetadata;
|
||||
outputTelemetryList.push(value);
|
||||
});
|
||||
return outputTelemetryList;
|
||||
}
|
||||
|
||||
formatHistoricalData(historicalDataKey, telemetryDetails) {
|
||||
const formattedData = [];
|
||||
const { domainObject, historicalTelemetry } = telemetryDetails;
|
||||
historicalTelemetry.forEach((value) => {
|
||||
formattedData.push({
|
||||
id: domainObject.identifier,
|
||||
output: value.sin,
|
||||
conditionId: historicalDataKey,
|
||||
utc: value.utc
|
||||
});
|
||||
});
|
||||
return formattedData;
|
||||
}
|
||||
}
|
@ -243,6 +243,7 @@ export default {
|
||||
domainObject: {
|
||||
...this.childObject,
|
||||
configuration: {
|
||||
...this.childObject.configuration,
|
||||
series: [
|
||||
{
|
||||
identifier: this.childObject.identifier,
|
||||
|
@ -94,7 +94,7 @@ export function ticks(start, stop, count) {
|
||||
}
|
||||
|
||||
export function commonPrefix(a, b) {
|
||||
const maxLen = Math.min(a.length, b.length);
|
||||
const maxLen = Math.min(a.length, b?.length);
|
||||
let breakpoint = 0;
|
||||
for (let i = 0; i < maxLen; i++) {
|
||||
if (a[i] !== b[i]) {
|
||||
@ -110,7 +110,7 @@ export function commonPrefix(a, b) {
|
||||
}
|
||||
|
||||
export function commonSuffix(a, b) {
|
||||
const maxLen = Math.min(a.length, b.length);
|
||||
const maxLen = Math.min(a.length, b?.length);
|
||||
let breakpoint = 0;
|
||||
for (let i = 0; i <= maxLen; i++) {
|
||||
if (a[a.length - i] !== b[b.length - i]) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user