Merge pull request #2784 from nasa/fix-conditionals

Fixes error while getting metadata when telemetry is not yet available for a criterion
This commit is contained in:
David Tsay 2020-03-25 21:39:45 -07:00 committed by GitHub
commit 311ff003c0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 51 additions and 44 deletions

View File

@ -92,6 +92,7 @@ export default class ConditionClass extends EventEmitter {
return { return {
id: uuid(), id: uuid(),
telemetry: criterionConfiguration.telemetry || '', telemetry: criterionConfiguration.telemetry || '',
telemetryObject: this.conditionManager.telemetryObjects[this.openmct.objects.makeKeyString(criterionConfiguration.telemetry)],
operation: criterionConfiguration.operation || '', operation: criterionConfiguration.operation || '',
input: criterionConfiguration.input === undefined ? [] : criterionConfiguration.input, input: criterionConfiguration.input === undefined ? [] : criterionConfiguration.input,
metadata: criterionConfiguration.metadata || '' metadata: criterionConfiguration.metadata || ''
@ -109,6 +110,12 @@ export default class ConditionClass extends EventEmitter {
this.createCriteria(criterionConfigurations); this.createCriteria(criterionConfigurations);
} }
updateTelemetry() {
this.criteria.forEach((criterion) => {
criterion.updateTelemetry(this.conditionManager.telemetryObjects);
});
}
/** /**
* adds criterion to the condition. * adds criterion to the condition.
*/ */
@ -209,7 +216,7 @@ export default class ConditionClass extends EventEmitter {
requestLADConditionResult() { requestLADConditionResult() {
const criteriaResults = this.criteria const criteriaResults = this.criteria
.map(criterion => criterion.requestLAD()); .map(criterion => criterion.requestLAD({telemetryObjects: this.conditionManager.telemetryObjects}));
return Promise.all(criteriaResults) return Promise.all(criteriaResults)
.then(results => { .then(results => {

View File

@ -36,6 +36,7 @@ export default class ConditionManager extends EventEmitter {
this.composition.on('remove', this.unsubscribeFromTelemetry, this); this.composition.on('remove', this.unsubscribeFromTelemetry, this);
this.compositionLoad = this.composition.load(); this.compositionLoad = this.composition.load();
this.subscriptions = {}; this.subscriptions = {};
this.telemetryObjects = {};
this.initialize(); this.initialize();
this.stopObservingForChanges = this.openmct.objects.observe(this.conditionSetDomainObject, '*', (newDomainObject) => { this.stopObservingForChanges = this.openmct.objects.observe(this.conditionSetDomainObject, '*', (newDomainObject) => {
@ -49,11 +50,12 @@ export default class ConditionManager extends EventEmitter {
console.log('subscription already exists'); console.log('subscription already exists');
return; return;
} }
this.telemetryObjects[id] = Object.assign({}, endpoint, {telemetryMetaData: this.openmct.telemetry.getMetadata(endpoint).valueMetadatas});
this.subscriptions[id] = this.openmct.telemetry.subscribe( this.subscriptions[id] = this.openmct.telemetry.subscribe(
endpoint, endpoint,
this.broadcastTelemetry.bind(this, id) this.broadcastTelemetry.bind(this, id)
); );
this.updateConditionTelemetry();
} }
unsubscribeFromTelemetry(endpointIdentifier) { unsubscribeFromTelemetry(endpointIdentifier) {
@ -65,6 +67,7 @@ export default class ConditionManager extends EventEmitter {
this.subscriptions[id](); this.subscriptions[id]();
delete this.subscriptions[id]; delete this.subscriptions[id];
delete this.telemetryObjects[id];
} }
initialize() { initialize() {
@ -77,6 +80,10 @@ export default class ConditionManager extends EventEmitter {
} }
} }
updateConditionTelemetry() {
this.conditionClassCollection.forEach((condition) => condition.updateTelemetry());
}
updateCondition(conditionConfiguration, index) { updateCondition(conditionConfiguration, index) {
let condition = this.conditionClassCollection[index]; let condition = this.conditionClassCollection[index];
condition.update(conditionConfiguration); condition.update(conditionConfiguration);
@ -255,7 +262,15 @@ export default class ConditionManager extends EventEmitter {
} }
broadcastTelemetry(id, datum) { broadcastTelemetry(id, datum) {
this.emit(`broadcastTelemetry`, Object.assign({}, datum, {id: id})); this.emit(`broadcastTelemetry`, Object.assign({}, this.createNormalizedDatum(datum, id), {id: id}));
}
createNormalizedDatum(telemetryDatum, id) {
return Object.values(this.telemetryObjects[id].telemetryMetaData).reduce((normalizedDatum, metadatum) => {
const formatter = this.openmct.telemetry.getValueFormatter(metadatum);
normalizedDatum[metadatum.key] = formatter.parse(telemetryDatum[metadatum.source]);
return normalizedDatum;
}, {});
} }
persistConditions() { persistConditions() {

View File

@ -62,6 +62,9 @@ describe("The condition", function () {
}] }]
} }
}; };
conditionManager.telemetryObjects = {
"test-object": testTelemetryObject
};
openmct.objects = jasmine.createSpyObj('objects', ['get', 'makeKeyString']); openmct.objects = jasmine.createSpyObj('objects', ['get', 'makeKeyString']);
openmct.objects.get.and.returnValue(new Promise(function (resolve, reject) { openmct.objects.get.and.returnValue(new Promise(function (resolve, reject) {
resolve(testTelemetryObject); resolve(testTelemetryObject);

View File

@ -44,28 +44,25 @@ export default class TelemetryCriterion extends EventEmitter {
this.operation = telemetryDomainObjectDefinition.operation; this.operation = telemetryDomainObjectDefinition.operation;
this.input = telemetryDomainObjectDefinition.input; this.input = telemetryDomainObjectDefinition.input;
this.metadata = telemetryDomainObjectDefinition.metadata; this.metadata = telemetryDomainObjectDefinition.metadata;
this.telemetryObjectIdAsString = undefined; this.telemetryObject = telemetryDomainObjectDefinition.telemetryObject;
this.objectAPI.get(this.objectAPI.makeKeyString(this.telemetry)).then((obj) => this.initialize(obj)); this.telemetryObjectIdAsString = this.objectAPI.makeKeyString(telemetryDomainObjectDefinition.telemetry);
}
initialize(obj) {
this.telemetryObject = obj;
this.telemetryMetaData = this.openmct.telemetry.getMetadata(obj).valueMetadatas;
this.telemetryObjectIdAsString = this.objectAPI.makeKeyString(this.telemetry);
this.on(`subscription:${this.telemetryObjectIdAsString}`, this.handleSubscription); this.on(`subscription:${this.telemetryObjectIdAsString}`, this.handleSubscription);
this.emitEvent('criterionUpdated', this); this.emitEvent('criterionUpdated', this);
} }
formatData(data) { updateTelemetry(telemetryObjects) {
const normalizedDatum = this.createNormalizedDatum(data); this.telemetryObject = telemetryObjects[this.telemetryObjectIdAsString];
const datum = { }
result: this.computeResult(normalizedDatum)
}
if (normalizedDatum) { formatData(data) {
const datum = {
result: this.computeResult(data)
};
if (data) {
// TODO check back to see if we should format times here // TODO check back to see if we should format times here
this.timeAPI.getAllTimeSystems().forEach(timeSystem => { this.timeAPI.getAllTimeSystems().forEach(timeSystem => {
datum[timeSystem.key] = normalizedDatum[timeSystem.key] datum[timeSystem.key] = data[timeSystem.key]
}); });
} }
return datum; return datum;
@ -77,13 +74,6 @@ export default class TelemetryCriterion extends EventEmitter {
} }
} }
createNormalizedDatum(telemetryDatum) {
return Object.values(this.telemetryMetaData).reduce((normalizedDatum, metadatum) => {
normalizedDatum[metadatum.key] = telemetryDatum[metadatum.source];
return normalizedDatum;
}, {});
}
findOperation(operation) { findOperation(operation) {
for (let i=0, ii=OPERATIONS.length; i < ii; i++) { for (let i=0, ii=OPERATIONS.length; i < ii; i++) {
if (operation === OPERATIONS[i].name) { if (operation === OPERATIONS[i].name) {

View File

@ -24,7 +24,6 @@ import TelemetryCriterion from "./TelemetryCriterion";
let openmct = {}, let openmct = {},
mockListener, mockListener,
mockListener2,
testCriterionDefinition, testCriterionDefinition,
testTelemetryObject, testTelemetryObject,
telemetryCriterion; telemetryCriterion;
@ -60,9 +59,6 @@ describe("The telemetry criterion", function () {
} }
}; };
openmct.objects = jasmine.createSpyObj('objects', ['get', 'makeKeyString']); openmct.objects = jasmine.createSpyObj('objects', ['get', 'makeKeyString']);
openmct.objects.get.and.returnValue(new Promise(function (resolve, reject) {
resolve(testTelemetryObject);
}));
openmct.objects.makeKeyString.and.returnValue(testTelemetryObject.identifier.key); openmct.objects.makeKeyString.and.returnValue(testTelemetryObject.identifier.key);
openmct.telemetry = jasmine.createSpyObj('telemetry', ['isTelemetryObject', "subscribe", "getMetadata"]); openmct.telemetry = jasmine.createSpyObj('telemetry', ['isTelemetryObject', "subscribe", "getMetadata"]);
openmct.telemetry.isTelemetryObject.and.returnValue(true); openmct.telemetry.isTelemetryObject.and.returnValue(true);
@ -80,13 +76,11 @@ describe("The telemetry criterion", function () {
id: 'test-criterion-id', id: 'test-criterion-id',
telemetry: openmct.objects.makeKeyString(testTelemetryObject.identifier), telemetry: openmct.objects.makeKeyString(testTelemetryObject.identifier),
operation: 'lessThan', operation: 'lessThan',
metadata: 'sin' metadata: 'sin',
telemetryObject: testTelemetryObject
}; };
mockListener = jasmine.createSpy('listener'); mockListener = jasmine.createSpy('listener');
mockListener2 = jasmine.createSpy('updatedListener', (data) => {
console.log(data);
});
telemetryCriterion = new TelemetryCriterion( telemetryCriterion = new TelemetryCriterion(
testCriterionDefinition, testCriterionDefinition,
@ -94,18 +88,14 @@ describe("The telemetry criterion", function () {
); );
telemetryCriterion.on('criterionResultUpdated', mockListener); telemetryCriterion.on('criterionResultUpdated', mockListener);
telemetryCriterion.on('criterionUpdated', mockListener2);
}); });
it("initializes with a telemetry objectId as string", function () { it("initializes with a telemetry objectId as string", function () {
telemetryCriterion.initialize(testTelemetryObject);
expect(telemetryCriterion.telemetryObjectIdAsString).toEqual(testTelemetryObject.identifier.key); expect(telemetryCriterion.telemetryObjectIdAsString).toEqual(testTelemetryObject.identifier.key);
expect(mockListener2).toHaveBeenCalled();
}); });
it("updates and emits event on new data from telemetry providers", function () { it("updates and emits event on new data from telemetry providers", function () {
telemetryCriterion.initialize(testTelemetryObject);
spyOn(telemetryCriterion, 'emitEvent').and.callThrough(); spyOn(telemetryCriterion, 'emitEvent').and.callThrough();
telemetryCriterion.handleSubscription({ telemetryCriterion.handleSubscription({
value: 'Hello', value: 'Hello',

View File

@ -268,15 +268,17 @@ export default {
this.openmct.contextMenu._showContextMenuForObjectPath(this.currentObjectPath, event.x, event.y, CONTEXT_MENU_ACTIONS); this.openmct.contextMenu._showContextMenuForObjectPath(this.currentObjectPath, event.x, event.y, CONTEXT_MENU_ACTIONS);
}, },
initObjectStyles() { initObjectStyles() {
this.styleRuleManager = new StyleRuleManager(this.domainObject.configuration.objectStyles, this.openmct, this.updateStyle.bind(this)); if (this.domainObject.configuration) {
this.styleRuleManager = new StyleRuleManager(this.domainObject.configuration.objectStyles, this.openmct, this.updateStyle.bind(this));
if (this.unlistenStyles) { if (this.unlistenStyles) {
this.unlistenStyles(); this.unlistenStyles();
}
this.unlistenStyles = this.openmct.objects.observe(this.domainObject, 'configuration.objectStyles', (newObjectStyle) => {
//Updating object styles in the inspector view will trigger this so that the changes are reflected immediately
this.styleRuleManager.updateObjectStyleConfig(newObjectStyle);
});
} }
this.unlistenStyles = this.openmct.objects.observe(this.domainObject, 'configuration.objectStyles', (newObjectStyle) => {
//Updating object styles in the inspector view will trigger this so that the changes are reflected immediately
this.styleRuleManager.updateObjectStyleConfig(newObjectStyle);
});
}, },
updateStyle(styleObj) { updateStyle(styleObj) {
let keys = Object.keys(styleObj); let keys = Object.keys(styleObj);