diff --git a/src/plugins/condition/Condition.js b/src/plugins/condition/Condition.js index c33297c092..8eb3e05cd7 100644 --- a/src/plugins/condition/Condition.js +++ b/src/plugins/condition/Condition.js @@ -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, diff --git a/src/plugins/condition/ConditionManager.js b/src/plugins/condition/ConditionManager.js index 9740ca9ba5..67d71405ed 100644 --- a/src/plugins/condition/ConditionManager.js +++ b/src/plugins/condition/ConditionManager.js @@ -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 + } + ) + ) }); } diff --git a/src/plugins/condition/ConditionSetMetadataProvider.js b/src/plugins/condition/ConditionSetMetadataProvider.js new file mode 100644 index 0000000000..0d81a692b1 --- /dev/null +++ b/src/plugins/condition/ConditionSetMetadataProvider.js @@ -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 + } + } + ]) + }; + } +} diff --git a/src/plugins/condition/ConditionSetTelemetryProvider.js b/src/plugins/condition/ConditionSetTelemetryProvider.js new file mode 100644 index 0000000000..cf721654ce --- /dev/null +++ b/src/plugins/condition/ConditionSetTelemetryProvider.js @@ -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(); + } + } +} diff --git a/src/plugins/condition/ConditionSetViewProvider.js b/src/plugins/condition/ConditionSetViewProvider.js index 91bd2f5409..43eb436f7e 100644 --- a/src/plugins/condition/ConditionSetViewProvider.js +++ b/src/plugins/condition/ConditionSetViewProvider.js @@ -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; + } + } } diff --git a/src/plugins/condition/components/ConditionCollection.vue b/src/plugins/condition/components/ConditionCollection.vue index 31dbdd0666..803f18e7b6 100644 --- a/src/plugins/condition/components/ConditionCollection.vue +++ b/src/plugins/condition/components/ConditionCollection.vue @@ -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); }, diff --git a/src/plugins/condition/components/ConditionSet.vue b/src/plugins/condition/components/ConditionSet.vue index 38c66deae1..b81fb29745 100644 --- a/src/plugins/condition/components/ConditionSet.vue +++ b/src/plugins/condition/components/ConditionSet.vue @@ -37,9 +37,7 @@ - + @@ -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); }); } } }; diff --git a/src/plugins/condition/criterion/TelemetryCriterion.js b/src/plugins/condition/criterion/TelemetryCriterion.js index 5fcb89389d..4c4958036a 100644 --- a/src/plugins/condition/criterion/TelemetryCriterion.js +++ b/src/plugins/condition/criterion/TelemetryCriterion.js @@ -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) { diff --git a/src/plugins/condition/criterion/TelemetryCriterionSpec.js b/src/plugins/condition/criterion/TelemetryCriterionSpec.js index 8c9cb67671..86ccbd6a68 100644 --- a/src/plugins/condition/criterion/TelemetryCriterionSpec.js +++ b/src/plugins/condition/criterion/TelemetryCriterionSpec.js @@ -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) diff --git a/src/plugins/condition/plugin.js b/src/plugins/condition/plugin.js index 4994904f43..dc485f4573 100644 --- a/src/plugins/condition/plugin.js +++ b/src/plugins/condition/plugin.js @@ -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)); }