Merge pull request #2704 from nasa/dave/provide-conditions-telemetry

[Conditions] Conditions to provide telemetry
This commit is contained in:
Shefali Joshi 2020-03-02 14:56:10 -08:00 committed by GitHub
commit ece6223b23
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 133 additions and 42 deletions

View File

@ -58,7 +58,7 @@ export default class ConditionClass extends EventEmitter {
this.id = this.openmct.objects.makeKeyString(conditionConfiguration.identifier);
this.criteria = [];
this.criteriaResults = {};
this.result = null;
this.result = undefined;
if (conditionConfiguration.configuration.criteria) {
this.createCriteria(conditionConfiguration.configuration.criteria);
}
@ -163,6 +163,7 @@ export default class ConditionClass extends EventEmitter {
if (found) {
let criterion = found.item;
criterion.destroy();
// TODO this is passing the wrong args
criterion.off('criterionUpdated', (result) => {
this.handleCriterionUpdated(id, result);
});
@ -180,6 +181,7 @@ export default class ConditionClass extends EventEmitter {
if (found) {
this.criteria[found.index] = criterion.data;
this.subscribe();
// TODO nothing is listening to this
this.emitEvent('conditionUpdated', {
trigger: this.trigger,
criteria: this.criteria
@ -188,27 +190,24 @@ export default class ConditionClass extends EventEmitter {
}
handleCriterionResult(eventData) {
let id = eventData.id;
let result = eventData.data.result;
let found = this.findCriterion(id);
if (found) {
this.criteriaResults[id] = result;
const id = eventData.id;
const conditionData = eventData.data;
if (this.findCriterion(id)) {
this.criteriaResults[id] = eventData.data.result;
}
this.handleConditionUpdated();
conditionData.result = computeCondition(this.criteriaResults, this.trigger === TRIGGER.ALL);
this.emitEvent('conditionResultUpdated', conditionData);
}
subscribe() {
// TODO it looks like on any single criterion update subscriptions fire for all criteria
this.criteria.forEach((criterion) => {
criterion.subscribe();
})
}
handleConditionUpdated() {
// trigger an updated event so that consumers can react accordingly
this.evaluate();
this.emitEvent('conditionResultUpdated', {result: this.result});
}
getCriteria() {
return this.criteria;
}
@ -222,10 +221,6 @@ export default class ConditionClass extends EventEmitter {
return success;
}
evaluate() {
this.result = computeCondition(this.criteriaResults, this.trigger === TRIGGER.ALL);
}
emitEvent(eventName, data) {
this.emit(eventName, {
id: this.id,

View File

@ -210,13 +210,12 @@ export default class ConditionManager extends EventEmitter {
if (resultObj) {
let idAsString = this.openmct.objects.makeKeyString(resultObj.id);
let found = this.findConditionById(idAsString);
if (found) {
if (this.findConditionById(idAsString)) {
this.conditionResults[idAsString] = resultObj.data.result;
}
}
for (let i = 0, ii = conditionCollection.length - 1; i < ii; i++) {
for (let i = 0; i < conditionCollection.length - 1; i++) {
let conditionIdAsString = this.openmct.objects.makeKeyString(conditionCollection[i]);
if (this.conditionResults[conditionIdAsString]) {
//first condition to be true wins
@ -226,11 +225,16 @@ export default class ConditionManager extends EventEmitter {
}
this.openmct.objects.get(currentConditionIdentifier).then((obj) => {
this.emit('conditionSetResultUpdated', {
id: this.domainObject.identifier,
output: obj.configuration.output,
conditionId: currentConditionIdentifier
})
this.emit('conditionSetResultUpdated',
Object.assign({},
resultObj ? resultObj.data : {},
{
output: obj.configuration.output,
id: this.domainObject.identifier,
conditionId: currentConditionIdentifier
}
)
)
});
}

View File

@ -0,0 +1,37 @@
export default class ConditionSetMetadataProvider {
constructor(openmct) {
this.openmct = openmct;
}
supportsMetadata(domainObject) {
return domainObject.type === 'conditionSet';
}
getDomains(domainObject) {
return this.openmct.time.getAllTimeSystems().map(function (ts, i) {
return {
key: ts.key,
name: ts.name,
format: ts.timeFormat,
hints: {
domain: i
}
};
});
}
getMetadata(domainObject) {
return {
values: this.getDomains().concat([
{
name: 'Output',
key: 'output',
format: 'string',
hints: {
range: 1
}
}
])
};
}
}

View File

@ -0,0 +1,29 @@
import ConditionManager from './ConditionManager'
export default class ConditionSetTelemetryProvider {
constructor(openmct) {
this.openmct = openmct;
}
isTelemetryObject(domainObject) {
return domainObject.type === 'conditionSet';
}
supportsRequest(domainObject, options) {
return false;
}
supportsSubscribe(domainObject) {
return domainObject.type === 'conditionSet';
}
subscribe(domainObject, callback) {
let conditionManager = new ConditionManager(domainObject, this.openmct);
conditionManager.on('conditionSetResultUpdated', callback);
return function unsubscribe() {
conditionManager.off('conditionSetResultUpdated');
conditionManager.destroy();
}
}
}

View File

@ -23,6 +23,8 @@
import ConditionSet from './components/ConditionSet.vue';
import Vue from 'vue';
const DEFAULT_VIEW_PRIORITY = 100;
export default class ConditionSetViewProvider {
constructor(openmct) {
this.openmct = openmct;
@ -71,4 +73,12 @@ export default class ConditionSetViewProvider {
}
};
}
priority(domainObject) {
if (domainObject.type === 'conditionSet') {
return Number.MAX_VALUE;
} else {
return DEFAULT_VIEW_PRIORITY;
}
}
}

View File

@ -110,7 +110,6 @@ export default {
this.composition.off('add', this.addTelemetryObject);
this.composition.off('remove', this.removeTelemetryObject);
if(this.conditionManager) {
this.conditionManager.off('conditionSetResultUpdated', this.handleOutputUpdated);
this.conditionManager.destroy();
}
if (typeof this.stopObservingForChanges === 'function') {
@ -124,7 +123,6 @@ export default {
this.composition.load();
this.conditionCollection = this.domainObject.configuration.conditionCollection;
this.conditionManager = new ConditionManager(this.domainObject, this.openmct);
this.conditionManager.on('conditionSetResultUpdated', this.handleOutputUpdated.bind(this));
this.observeForChanges();
},
methods: {
@ -179,9 +177,6 @@ export default {
dragLeave(e) {
e.target.classList.remove("dragging");
},
handleOutputUpdated(args) {
this.$emit('currentConditionSetOutputUpdated', args);
},
addTelemetryObject(domainObject) {
this.telemetryObjs.push(domainObject);
},

View File

@ -37,9 +37,7 @@
</div>
</section>
<TestData :is-editing="isEditing" />
<ConditionCollection :is-editing="isEditing"
@currentConditionSetOutputUpdated="updateCurrentOutput"
/>
<ConditionCollection :is-editing="isEditing" />
</div>
</div>
</template>
@ -64,12 +62,20 @@ export default {
},
mounted() {
this.conditionSetIdentifier = this.openmct.objects.makeKeyString(this.domainObject.identifier);
this.provideTelemetry();
},
beforeDestroy() {
if (this.stopProvidingTelemetry) {
this.stopProvidingTelemetry();
}
},
methods: {
updateCurrentOutput(currentConditionResult) {
if (this.openmct.objects.makeKeyString(currentConditionResult.id) === this.conditionSetIdentifier) {
this.currentConditionOutput = currentConditionResult.output;
}
this.currentConditionOutput = currentConditionResult.output;
},
provideTelemetry() {
this.stopProvidingTelemetry = this.openmct.telemetry
.subscribe(this.domainObject, output => { this.updateCurrentOutput(output); });
}
}
};

View File

@ -38,6 +38,7 @@ export default class TelemetryCriterion extends EventEmitter {
this.openmct = openmct;
this.objectAPI = this.openmct.objects;
this.telemetryAPI = this.openmct.telemetry;
this.timeAPI = this.openmct.time;
this.id = telemetryDomainObjectDefinition.id;
this.telemetry = telemetryDomainObjectDefinition.telemetry;
this.operation = telemetryDomainObjectDefinition.operation;
@ -55,11 +56,15 @@ export default class TelemetryCriterion extends EventEmitter {
}
handleSubscription(data) {
let result = this.computeResult(data);
this.emitEvent('criterionResultUpdated', {
result: result,
error: null
})
const datum = {};
const timeSystemKey = this.timeAPI.timeSystem().key;
datum.result = this.computeResult(data);
if (data && data[timeSystemKey]) {
datum[timeSystemKey] = data[timeSystemKey]
}
this.emitEvent('criterionResultUpdated', datum);
}
findOperation(operation) {

View File

@ -62,6 +62,12 @@ describe("The telemetry criterion", function () {
openmct.telemetry.subscribe.and.returnValue(function () {});
openmct.telemetry.getMetadata.and.returnValue(testTelemetryObject.telemetry.values);
openmct.time = jasmine.createSpyObj('timeAPI',
['timeSystem', 'bounds']
);
openmct.time.timeSystem.and.returnValue({key: 'system'});
openmct.time.bounds.and.returnValue({start: 0, end: 1});
testCriterionDefinition = {
id: 'test-criterion-id',
telemetry: openmct.objects.makeKeyString(testTelemetryObject.identifier)

View File

@ -21,6 +21,8 @@
*****************************************************************************/
import ConditionSetViewProvider from './ConditionSetViewProvider.js';
import ConditionSetCompositionPolicy from "./ConditionSetCompositionPolicy";
import ConditionSetMetadataProvider from './ConditionSetMetadataProvider';
import ConditionSetTelemetryProvider from './ConditionSetTelemetryProvider';
export default function ConditionPlugin() {
@ -46,11 +48,13 @@ export default function ConditionPlugin() {
conditionCollection: []
};
domainObject.composition = [];
domainObject.telemetry = {};
}
});
openmct.composition.addPolicy(new ConditionSetCompositionPolicy(openmct).allow);
openmct.telemetry.addProvider(new ConditionSetMetadataProvider(openmct));
openmct.telemetry.addProvider(new ConditionSetTelemetryProvider(openmct));
openmct.objectViews.addProvider(new ConditionSetViewProvider(openmct));
}