mirror of
https://github.com/nasa/openmct.git
synced 2025-06-01 07:00:49 +00:00
Ensure a request for telemetry happens in Condition Sets (#7592)
* request telemetry when subscribing to data in case we have cached subscription * change back to >= * revert * update tests * fixing tests * add metadata * fix test * another mock required * one more function needed * attempt to fix some afterall errors * add fixme for e2e test * fail fast on request --------- Co-authored-by: Andrew Henry <akhenry@gmail.com>
This commit is contained in:
parent
fb396ac194
commit
e305b46d88
@ -457,4 +457,11 @@ test.describe('Basic Condition Set Use', () => {
|
|||||||
|
|
||||||
await page.goto(exampleTelemetry.url);
|
await page.goto(exampleTelemetry.url);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test.fixme('Ensure condition sets work with telemetry like operator status', ({ page }) => {
|
||||||
|
test.info().annotations.push({
|
||||||
|
type: 'issue',
|
||||||
|
description: 'https://github.com/nasa/openmct/issues/7484'
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -56,20 +56,38 @@ export default class ConditionManager extends EventEmitter {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
subscribeToTelemetry(endpoint) {
|
async requestLatestValue(endpoint) {
|
||||||
const id = this.openmct.objects.makeKeyString(endpoint.identifier);
|
const options = {
|
||||||
if (this.subscriptions[id]) {
|
size: 1,
|
||||||
console.log('subscription already exists');
|
strategy: 'latest'
|
||||||
|
};
|
||||||
|
const latestData = await this.openmct.telemetry.request(endpoint, options);
|
||||||
|
|
||||||
|
if (!latestData) {
|
||||||
|
throw new Error('Telemetry request failed by returning a falsy response');
|
||||||
|
}
|
||||||
|
if (latestData.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.telemetryReceived(endpoint, latestData[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
subscribeToTelemetry(endpoint) {
|
||||||
|
const telemetryKeyString = this.openmct.objects.makeKeyString(endpoint.identifier);
|
||||||
|
if (this.subscriptions[telemetryKeyString]) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const metadata = this.openmct.telemetry.getMetadata(endpoint);
|
const metadata = this.openmct.telemetry.getMetadata(endpoint);
|
||||||
|
|
||||||
this.telemetryObjects[id] = Object.assign({}, endpoint, {
|
this.telemetryObjects[telemetryKeyString] = Object.assign({}, endpoint, {
|
||||||
telemetryMetaData: metadata ? metadata.valueMetadatas : []
|
telemetryMetaData: metadata ? metadata.valueMetadatas : []
|
||||||
});
|
});
|
||||||
this.subscriptions[id] = this.openmct.telemetry.subscribe(
|
|
||||||
|
// get latest telemetry value (in case subscription is cached and no new data is coming in)
|
||||||
|
this.requestLatestValue(endpoint);
|
||||||
|
|
||||||
|
this.subscriptions[telemetryKeyString] = this.openmct.telemetry.subscribe(
|
||||||
endpoint,
|
endpoint,
|
||||||
this.telemetryReceived.bind(this, endpoint)
|
this.telemetryReceived.bind(this, endpoint)
|
||||||
);
|
);
|
||||||
@ -91,7 +109,7 @@ export default class ConditionManager extends EventEmitter {
|
|||||||
|
|
||||||
//force re-computation of condition set result as we might be in a state where
|
//force re-computation of condition set result as we might be in a state where
|
||||||
// there is no telemetry datum coming in for a while or at all.
|
// there is no telemetry datum coming in for a while or at all.
|
||||||
let latestTimestamp = getLatestTimestamp(
|
const latestTimestamp = getLatestTimestamp(
|
||||||
{},
|
{},
|
||||||
{},
|
{},
|
||||||
this.timeSystems,
|
this.timeSystems,
|
||||||
@ -334,57 +352,54 @@ export default class ConditionManager extends EventEmitter {
|
|||||||
return currentCondition;
|
return currentCondition;
|
||||||
}
|
}
|
||||||
|
|
||||||
requestLADConditionSetOutput(options) {
|
async requestLADConditionSetOutput(options) {
|
||||||
if (!this.conditions.length) {
|
if (!this.conditions.length) {
|
||||||
return Promise.resolve([]);
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.compositionLoad.then(() => {
|
await this.compositionLoad;
|
||||||
let latestTimestamp;
|
|
||||||
let conditionResults = {};
|
|
||||||
let nextLegOptions = { ...options };
|
|
||||||
delete nextLegOptions.onPartialResponse;
|
|
||||||
|
|
||||||
const conditionRequests = this.conditions.map((condition) =>
|
let latestTimestamp;
|
||||||
condition.requestLADConditionResult(nextLegOptions)
|
let conditionResults = {};
|
||||||
|
let nextLegOptions = { ...options };
|
||||||
|
delete nextLegOptions.onPartialResponse;
|
||||||
|
|
||||||
|
const results = Promise.all(
|
||||||
|
this.conditions.map((condition) => condition.requestLADConditionResult(nextLegOptions))
|
||||||
|
);
|
||||||
|
|
||||||
|
results.forEach((resultObj) => {
|
||||||
|
const {
|
||||||
|
id,
|
||||||
|
data,
|
||||||
|
data: { result }
|
||||||
|
} = resultObj;
|
||||||
|
|
||||||
|
if (this.findConditionById(id)) {
|
||||||
|
conditionResults[id] = Boolean(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
latestTimestamp = getLatestTimestamp(
|
||||||
|
latestTimestamp,
|
||||||
|
data,
|
||||||
|
this.timeSystems,
|
||||||
|
this.openmct.time.timeSystem()
|
||||||
);
|
);
|
||||||
|
|
||||||
return Promise.all(conditionRequests).then((results) => {
|
|
||||||
results.forEach((resultObj) => {
|
|
||||||
const {
|
|
||||||
id,
|
|
||||||
data,
|
|
||||||
data: { result }
|
|
||||||
} = resultObj;
|
|
||||||
if (this.findConditionById(id)) {
|
|
||||||
conditionResults[id] = Boolean(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
latestTimestamp = getLatestTimestamp(
|
|
||||||
latestTimestamp,
|
|
||||||
data,
|
|
||||||
this.timeSystems,
|
|
||||||
this.openmct.time.timeSystem()
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!Object.values(latestTimestamp).some((timeSystem) => timeSystem)) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
const currentCondition = this.getCurrentConditionLAD(conditionResults);
|
|
||||||
const currentOutput = Object.assign(
|
|
||||||
{
|
|
||||||
output: currentCondition.configuration.output,
|
|
||||||
id: this.conditionSetDomainObject.identifier,
|
|
||||||
conditionId: currentCondition.id
|
|
||||||
},
|
|
||||||
latestTimestamp
|
|
||||||
);
|
|
||||||
|
|
||||||
return [currentOutput];
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (!Object.values(latestTimestamp).some((timeSystem) => timeSystem)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentCondition = this.getCurrentConditionLAD(conditionResults);
|
||||||
|
const currentOutput = {
|
||||||
|
output: currentCondition.configuration.output,
|
||||||
|
id: this.conditionSetDomainObject.identifier,
|
||||||
|
conditionId: currentCondition.id,
|
||||||
|
...latestTimestamp
|
||||||
|
};
|
||||||
|
|
||||||
|
return [currentOutput];
|
||||||
}
|
}
|
||||||
|
|
||||||
isTelemetryUsed(endpoint) {
|
isTelemetryUsed(endpoint) {
|
||||||
@ -409,7 +424,7 @@ export default class ConditionManager extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const normalizedDatum = this.createNormalizedDatum(datum, endpoint);
|
const normalizedDatum = this.createNormalizedDatum(datum, endpoint);
|
||||||
const timeSystemKey = this.openmct.time.timeSystem().key;
|
const timeSystemKey = this.openmct.time.getTimeSystem().key;
|
||||||
let timestamp = {};
|
let timestamp = {};
|
||||||
const currentTimestamp = normalizedDatum[timeSystemKey];
|
const currentTimestamp = normalizedDatum[timeSystemKey];
|
||||||
timestamp[timeSystemKey] = currentTimestamp;
|
timestamp[timeSystemKey] = currentTimestamp;
|
||||||
|
@ -40,12 +40,10 @@ export default class ConditionSetTelemetryProvider {
|
|||||||
return domainObject.type === 'conditionSet';
|
return domainObject.type === 'conditionSet';
|
||||||
}
|
}
|
||||||
|
|
||||||
request(domainObject, options) {
|
async request(domainObject, options) {
|
||||||
let conditionManager = this.getConditionManager(domainObject);
|
let conditionManager = this.getConditionManager(domainObject);
|
||||||
|
let latestOutput = await conditionManager.requestLADConditionSetOutput(options);
|
||||||
return conditionManager.requestLADConditionSetOutput(options).then((latestOutput) => {
|
return latestOutput;
|
||||||
return latestOutput;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
subscribe(domainObject, callback) {
|
subscribe(domainObject, callback) {
|
||||||
|
@ -66,7 +66,8 @@ describe('the plugin', function () {
|
|||||||
format: 'utc',
|
format: 'utc',
|
||||||
hints: {
|
hints: {
|
||||||
domain: 1
|
domain: 1
|
||||||
}
|
},
|
||||||
|
source: 'utc'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'testSource',
|
key: 'testSource',
|
||||||
@ -720,6 +721,23 @@ describe('the plugin', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should evaluate as old when telemetry is not received in the allotted time', (done) => {
|
it('should evaluate as old when telemetry is not received in the allotted time', (done) => {
|
||||||
|
openmct.telemetry = jasmine.createSpyObj('telemetry', [
|
||||||
|
'subscribe',
|
||||||
|
'getMetadata',
|
||||||
|
'request',
|
||||||
|
'getValueFormatter',
|
||||||
|
'abortAllRequests'
|
||||||
|
]);
|
||||||
|
openmct.telemetry.getMetadata.and.returnValue({
|
||||||
|
...testTelemetryObject.telemetry,
|
||||||
|
valueMetadatas: []
|
||||||
|
});
|
||||||
|
openmct.telemetry.request.and.returnValue(Promise.resolve([]));
|
||||||
|
openmct.telemetry.getValueFormatter.and.returnValue({
|
||||||
|
parse: function (value) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
});
|
||||||
let conditionMgr = new ConditionManager(conditionSetDomainObject, openmct);
|
let conditionMgr = new ConditionManager(conditionSetDomainObject, openmct);
|
||||||
conditionMgr.on('conditionSetResultUpdated', mockListener);
|
conditionMgr.on('conditionSetResultUpdated', mockListener);
|
||||||
conditionMgr.telemetryObjects = {
|
conditionMgr.telemetryObjects = {
|
||||||
@ -741,6 +759,20 @@ describe('the plugin', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should not evaluate as old when telemetry is received in the allotted time', (done) => {
|
it('should not evaluate as old when telemetry is received in the allotted time', (done) => {
|
||||||
|
openmct.telemetry.getMetadata = jasmine.createSpy('getMetadata');
|
||||||
|
openmct.telemetry.getMetadata.and.returnValue({
|
||||||
|
...testTelemetryObject.telemetry,
|
||||||
|
valueMetadatas: testTelemetryObject.telemetry.values
|
||||||
|
});
|
||||||
|
const testDatum = {
|
||||||
|
'some-key2': '',
|
||||||
|
utc: 1,
|
||||||
|
testSource: '',
|
||||||
|
'some-key': null,
|
||||||
|
id: 'test-object'
|
||||||
|
};
|
||||||
|
openmct.telemetry.request = jasmine.createSpy('request');
|
||||||
|
openmct.telemetry.request.and.returnValue(Promise.resolve([testDatum]));
|
||||||
const date = 1;
|
const date = 1;
|
||||||
conditionSetDomainObject.configuration.conditionCollection[0].configuration.criteria[0].input =
|
conditionSetDomainObject.configuration.conditionCollection[0].configuration.criteria[0].input =
|
||||||
['0.4'];
|
['0.4'];
|
||||||
@ -750,9 +782,7 @@ describe('the plugin', function () {
|
|||||||
'test-object': testTelemetryObject
|
'test-object': testTelemetryObject
|
||||||
};
|
};
|
||||||
conditionMgr.updateConditionTelemetryObjects();
|
conditionMgr.updateConditionTelemetryObjects();
|
||||||
conditionMgr.telemetryReceived(testTelemetryObject, {
|
conditionMgr.telemetryReceived(testTelemetryObject, testDatum);
|
||||||
utc: date
|
|
||||||
});
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
expect(mockListener).toHaveBeenCalledWith({
|
expect(mockListener).toHaveBeenCalledWith({
|
||||||
output: 'Default',
|
output: 'Default',
|
||||||
@ -868,6 +898,12 @@ describe('the plugin', function () {
|
|||||||
it('should stop evaluating conditions when a condition evaluates to true', () => {
|
it('should stop evaluating conditions when a condition evaluates to true', () => {
|
||||||
const date = Date.now();
|
const date = Date.now();
|
||||||
let conditionMgr = new ConditionManager(conditionSetDomainObject, openmct);
|
let conditionMgr = new ConditionManager(conditionSetDomainObject, openmct);
|
||||||
|
|
||||||
|
openmct.telemetry.getMetadata = jasmine.createSpy('getMetadata');
|
||||||
|
openmct.telemetry.getMetadata.and.returnValue({
|
||||||
|
...testTelemetryObject.telemetry,
|
||||||
|
valueMetadatas: []
|
||||||
|
});
|
||||||
conditionMgr.on('conditionSetResultUpdated', mockListener);
|
conditionMgr.on('conditionSetResultUpdated', mockListener);
|
||||||
conditionMgr.telemetryObjects = {
|
conditionMgr.telemetryObjects = {
|
||||||
'test-object': testTelemetryObject
|
'test-object': testTelemetryObject
|
||||||
|
@ -169,6 +169,8 @@ describe('Notebook plugin:', () => {
|
|||||||
|
|
||||||
openmct.editor = {};
|
openmct.editor = {};
|
||||||
openmct.editor.isEditing = () => false;
|
openmct.editor.isEditing = () => false;
|
||||||
|
openmct.editor.on = () => {};
|
||||||
|
openmct.editor.off = () => {};
|
||||||
|
|
||||||
const applicableViews = openmct.objectViews.get(notebookViewObject, [notebookViewObject]);
|
const applicableViews = openmct.objectViews.get(notebookViewObject, [notebookViewObject]);
|
||||||
notebookViewProvider = applicableViews.find(
|
notebookViewProvider = applicableViews.find(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user