mirror of
https://github.com/nasa/openmct.git
synced 2025-01-02 19:36:41 +00:00
Merge branch 'condition-ui' of https://github.com/nasa/openmct into condition-clone
This commit is contained in:
commit
a5a3e41d21
@ -24,6 +24,7 @@ import * as EventEmitter from 'eventemitter3';
|
|||||||
import uuid from 'uuid';
|
import uuid from 'uuid';
|
||||||
import TelemetryCriterion from "@/plugins/condition/criterion/TelemetryCriterion";
|
import TelemetryCriterion from "@/plugins/condition/criterion/TelemetryCriterion";
|
||||||
import { TRIGGER } from "@/plugins/condition/utils/constants";
|
import { TRIGGER } from "@/plugins/condition/utils/constants";
|
||||||
|
import {computeConditionForAll, computeConditionForAny} from "@/plugins/condition/utils/evaluator";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* conditionDefinition = {
|
* conditionDefinition = {
|
||||||
@ -56,6 +57,7 @@ export default class ConditionClass extends EventEmitter {
|
|||||||
this.openmct = openmct;
|
this.openmct = openmct;
|
||||||
this.id = this.openmct.objects.makeKeyString(conditionDefinition.identifier);
|
this.id = this.openmct.objects.makeKeyString(conditionDefinition.identifier);
|
||||||
this.criteria = [];
|
this.criteria = [];
|
||||||
|
this.criteriaResults = {};
|
||||||
if (conditionDefinition.definition.criteria) {
|
if (conditionDefinition.definition.criteria) {
|
||||||
this.createCriteria(conditionDefinition.definition.criteria);
|
this.createCriteria(conditionDefinition.definition.criteria);
|
||||||
}
|
}
|
||||||
@ -71,12 +73,11 @@ export default class ConditionClass extends EventEmitter {
|
|||||||
update(newDomainObject) {
|
update(newDomainObject) {
|
||||||
this.updateTrigger(newDomainObject.definition.trigger);
|
this.updateTrigger(newDomainObject.definition.trigger);
|
||||||
this.updateCriteria(newDomainObject.definition.criteria);
|
this.updateCriteria(newDomainObject.definition.criteria);
|
||||||
this.handleConditionUpdated();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
updateTrigger(conditionDefinition) {
|
updateTrigger(trigger) {
|
||||||
if (this.trigger !== conditionDefinition.trigger) {
|
if (this.trigger !== trigger) {
|
||||||
this.trigger = conditionDefinition.trigger;
|
this.trigger = trigger;
|
||||||
this.handleConditionUpdated();
|
this.handleConditionUpdated();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -109,6 +110,7 @@ export default class ConditionClass extends EventEmitter {
|
|||||||
let criterionDefinitionWithId = this.generateCriterion(criterionDefinition || null);
|
let criterionDefinitionWithId = this.generateCriterion(criterionDefinition || null);
|
||||||
let criterion = new TelemetryCriterion(criterionDefinitionWithId, this.openmct);
|
let criterion = new TelemetryCriterion(criterionDefinitionWithId, this.openmct);
|
||||||
criterion.on('criterionUpdated', (obj) => this.handleCriterionUpdated(obj));
|
criterion.on('criterionUpdated', (obj) => this.handleCriterionUpdated(obj));
|
||||||
|
criterion.on('criterionResultUpdated', (obj) => this.handleCriterionResult(obj));
|
||||||
if (!this.criteria) {
|
if (!this.criteria) {
|
||||||
this.criteria = [];
|
this.criteria = [];
|
||||||
}
|
}
|
||||||
@ -138,12 +140,17 @@ export default class ConditionClass extends EventEmitter {
|
|||||||
if (found) {
|
if (found) {
|
||||||
const newCriterionDefinition = this.generateCriterion(criterionDefinition);
|
const newCriterionDefinition = this.generateCriterion(criterionDefinition);
|
||||||
let newCriterion = new TelemetryCriterion(newCriterionDefinition, this.openmct);
|
let newCriterion = new TelemetryCriterion(newCriterionDefinition, this.openmct);
|
||||||
|
newCriterion.on('criterionUpdated', (obj) => this.handleCriterionUpdated(obj));
|
||||||
|
newCriterion.on('criterionResultUpdated', (obj) => this.handleCriterionResult(obj));
|
||||||
|
|
||||||
let criterion = found.item;
|
let criterion = found.item;
|
||||||
criterion.unsubscribe();
|
criterion.unsubscribe();
|
||||||
criterion.off('criterionUpdated', (result) => {
|
criterion.off('criterionUpdated', (obj) => this.handleCriterionUpdated(obj));
|
||||||
this.handleCriterionUpdated(id, result);
|
criterion.off('criterionResultUpdated', (obj) => this.handleCriterionResult(obj));
|
||||||
});
|
|
||||||
this.criteria.splice(found.index, 1, newCriterion);
|
this.criteria.splice(found.index, 1, newCriterion);
|
||||||
|
if (this.criteriaResults[criterion.id] !== undefined) {
|
||||||
|
delete this.criteriaResults[criterion.id];
|
||||||
|
}
|
||||||
this.handleConditionUpdated();
|
this.handleConditionUpdated();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -163,6 +170,9 @@ export default class ConditionClass extends EventEmitter {
|
|||||||
this.handleCriterionUpdated(id, result);
|
this.handleCriterionUpdated(id, result);
|
||||||
});
|
});
|
||||||
this.criteria.splice(found.index, 1);
|
this.criteria.splice(found.index, 1);
|
||||||
|
if (this.criteriaResults[criterion.id] !== undefined) {
|
||||||
|
delete this.criteriaResults[criterion.id];
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -173,14 +183,30 @@ export default class ConditionClass extends EventEmitter {
|
|||||||
if (found) {
|
if (found) {
|
||||||
this.criteria[found.index] = criterion.data;
|
this.criteria[found.index] = criterion.data;
|
||||||
//Most likely don't need this.
|
//Most likely don't need this.
|
||||||
|
this.subscribe();
|
||||||
this.emitEvent('conditionUpdated', {
|
this.emitEvent('conditionUpdated', {
|
||||||
trigger: this.trigger,
|
trigger: this.trigger,
|
||||||
criteria: this.criteria
|
criteria: this.criteria
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleCriterionResult(eventData) {
|
||||||
|
let id = eventData.id;
|
||||||
|
let result = eventData.data.result;
|
||||||
|
let found = this.findCriterion(id);
|
||||||
|
if (found) {
|
||||||
|
this.criteriaResults[id] = result;
|
||||||
|
}
|
||||||
this.handleConditionUpdated();
|
this.handleConditionUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
subscribe() {
|
||||||
|
this.criteria.forEach((criterion) => {
|
||||||
|
criterion.subscribe();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
handleConditionUpdated() {
|
handleConditionUpdated() {
|
||||||
// trigger an updated event so that consumers can react accordingly
|
// trigger an updated event so that consumers can react accordingly
|
||||||
this.evaluate();
|
this.evaluate();
|
||||||
@ -203,9 +229,9 @@ export default class ConditionClass extends EventEmitter {
|
|||||||
//TODO: implement as part of the evaluator class task.
|
//TODO: implement as part of the evaluator class task.
|
||||||
evaluate() {
|
evaluate() {
|
||||||
if (this.trigger === TRIGGER.ANY) {
|
if (this.trigger === TRIGGER.ANY) {
|
||||||
this.result = true;
|
this.result = computeConditionForAny(this.criteriaResults);
|
||||||
} else if (this.trigger === TRIGGER.ALL) {
|
} else if (this.trigger === TRIGGER.ALL) {
|
||||||
this.result = false;
|
this.result = computeConditionForAll(this.criteriaResults);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,6 +64,7 @@ describe("The condition", function () {
|
|||||||
openmct.telemetry.getMetadata.and.returnValue(testTelemetryObject.telemetry.values);
|
openmct.telemetry.getMetadata.and.returnValue(testTelemetryObject.telemetry.values);
|
||||||
|
|
||||||
testConditionDefinition = {
|
testConditionDefinition = {
|
||||||
|
definition: {
|
||||||
trigger: TRIGGER.ANY,
|
trigger: TRIGGER.ANY,
|
||||||
criteria: [
|
criteria: [
|
||||||
{
|
{
|
||||||
@ -73,6 +74,7 @@ describe("The condition", function () {
|
|||||||
key: testTelemetryObject.identifier
|
key: testTelemetryObject.identifier
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
conditionObj = new Condition(
|
conditionObj = new Condition(
|
||||||
@ -85,7 +87,7 @@ describe("The condition", function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("generates criteria with an id", function () {
|
it("generates criteria with an id", function () {
|
||||||
const testCriterion = testConditionDefinition.criteria[0];
|
const testCriterion = testConditionDefinition.definition.criteria[0];
|
||||||
let criterion = conditionObj.generateCriterion(testCriterion);
|
let criterion = conditionObj.generateCriterion(testCriterion);
|
||||||
expect(criterion.id).toBeDefined();
|
expect(criterion.id).toBeDefined();
|
||||||
expect(criterion.operation).toEqual(testCriterion.operation);
|
expect(criterion.operation).toEqual(testCriterion.operation);
|
||||||
@ -101,15 +103,15 @@ describe("The condition", function () {
|
|||||||
it("initializes with criteria from the condition definition", function () {
|
it("initializes with criteria from the condition definition", function () {
|
||||||
expect(conditionObj.criteria.length).toEqual(1);
|
expect(conditionObj.criteria.length).toEqual(1);
|
||||||
let criterion = conditionObj.criteria[0];
|
let criterion = conditionObj.criteria[0];
|
||||||
|
console.log(criterion);
|
||||||
expect(criterion instanceof TelemetryCriterion).toBeTrue();
|
expect(criterion instanceof TelemetryCriterion).toBeTrue();
|
||||||
expect(criterion.operator).toEqual(testConditionDefinition.operator);
|
expect(criterion.operator).toEqual(testConditionDefinition.definition.criteria[0].operator);
|
||||||
expect(criterion.input).toEqual(testConditionDefinition.input);
|
expect(criterion.input).toEqual(testConditionDefinition.definition.criteria[0].input);
|
||||||
expect(criterion.metaDataKey).toEqual(testConditionDefinition.metaDataKey);
|
expect(criterion.metaDataKey).toEqual(testConditionDefinition.definition.criteria[0].metaDataKey);
|
||||||
expect(criterion.key).toEqual(testConditionDefinition.key);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("initializes with the trigger from the condition definition", function () {
|
it("initializes with the trigger from the condition definition", function () {
|
||||||
expect(conditionObj.trigger).toEqual(testConditionDefinition.trigger);
|
expect(conditionObj.trigger).toEqual(testConditionDefinition.definition.trigger);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("destroys all criteria for a condition", function () {
|
it("destroys all criteria for a condition", function () {
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
import * as EventEmitter from 'eventemitter3';
|
import * as EventEmitter from 'eventemitter3';
|
||||||
|
import {OPERATIONS} from '../utils/operations';
|
||||||
|
|
||||||
export default class TelemetryCriterion extends EventEmitter {
|
export default class TelemetryCriterion extends EventEmitter {
|
||||||
|
|
||||||
@ -38,6 +39,9 @@ export default class TelemetryCriterion extends EventEmitter {
|
|||||||
this.objectAPI = this.openmct.objects;
|
this.objectAPI = this.openmct.objects;
|
||||||
this.telemetryAPI = this.openmct.telemetry;
|
this.telemetryAPI = this.openmct.telemetry;
|
||||||
this.id = telemetryDomainObjectDefinition.id;
|
this.id = telemetryDomainObjectDefinition.id;
|
||||||
|
this.operation = telemetryDomainObjectDefinition.operation;
|
||||||
|
this.input = telemetryDomainObjectDefinition.input;
|
||||||
|
this.metaDataKey = telemetryDomainObjectDefinition.metaDataKey;
|
||||||
this.subscription = null;
|
this.subscription = null;
|
||||||
this.telemetryMetadata = null;
|
this.telemetryMetadata = null;
|
||||||
this.telemetryObjectIdAsString = null;
|
this.telemetryObjectIdAsString = null;
|
||||||
@ -51,19 +55,36 @@ export default class TelemetryCriterion extends EventEmitter {
|
|||||||
this.emitEvent('criterionUpdated', this);
|
this.emitEvent('criterionUpdated', this);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleSubscription(datum) {
|
handleSubscription(data) {
|
||||||
let data = this.normalizeData(datum);
|
let result = this.computeResult(data);
|
||||||
this.emitEvent('criterionResultUpdated', {
|
this.emitEvent('criterionResultUpdated', {
|
||||||
result: data,
|
result: result,
|
||||||
error: null
|
error: null
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
normalizeData(datum) {
|
findOperation(operation) {
|
||||||
return {
|
for (let i=0, ii=OPERATIONS.length; i < ii; i++) {
|
||||||
[datum.key]: datum[datum.source]
|
if (operation === OPERATIONS[i].name) {
|
||||||
|
return OPERATIONS[i].operation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
computeResult(data) {
|
||||||
|
let comparator = this.findOperation(this.operation);
|
||||||
|
let params = [];
|
||||||
|
let result = false;
|
||||||
|
params.push(data[this.metaDataKey]);
|
||||||
|
if (this.input instanceof Array && this.input.length) {
|
||||||
|
params.push(this.input[0]);
|
||||||
|
}
|
||||||
|
if (typeof comparator === 'function') {
|
||||||
|
result = comparator(params);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
emitEvent(eventName, data) {
|
emitEvent(eventName, data) {
|
||||||
this.emit(eventName, {
|
this.emit(eventName, {
|
||||||
@ -76,6 +97,7 @@ export default class TelemetryCriterion extends EventEmitter {
|
|||||||
* Subscribes to the telemetry object and returns an unsubscribe function
|
* Subscribes to the telemetry object and returns an unsubscribe function
|
||||||
*/
|
*/
|
||||||
subscribe() {
|
subscribe() {
|
||||||
|
this.unsubscribe();
|
||||||
this.subscription = this.telemetryAPI.subscribe(this.telemetryObject, (datum) => {
|
this.subscription = this.telemetryAPI.subscribe(this.telemetryObject, (datum) => {
|
||||||
this.handleSubscription(datum);
|
this.handleSubscription(datum);
|
||||||
});
|
});
|
||||||
|
@ -94,17 +94,6 @@ describe("The telemetry criterion", function () {
|
|||||||
expect(telemetryCriterion.subscription).toBeDefined();
|
expect(telemetryCriterion.subscription).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("normalizes telemetry data", function () {
|
|
||||||
let result = telemetryCriterion.normalizeData({
|
|
||||||
key: 'some-key',
|
|
||||||
source: 'testSource',
|
|
||||||
testSource: 'Hello'
|
|
||||||
});
|
|
||||||
expect(result).toEqual({
|
|
||||||
'some-key': 'Hello'
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
it("emits update event on new data from telemetry providers", function () {
|
it("emits update event on new data from telemetry providers", function () {
|
||||||
spyOn(telemetryCriterion, 'emitEvent').and.callThrough();
|
spyOn(telemetryCriterion, 'emitEvent').and.callThrough();
|
||||||
telemetryCriterion.handleSubscription({
|
telemetryCriterion.handleSubscription({
|
||||||
|
@ -1,7 +1,31 @@
|
|||||||
export const computeConditionForAny = (args) => {
|
/**
|
||||||
return false;
|
* Returns true only if at least one of the results is true
|
||||||
|
**/
|
||||||
|
export const computeConditionForAny = (resultMap) => {
|
||||||
|
let result = false;
|
||||||
|
for (let key in resultMap) {
|
||||||
|
if (resultMap.hasOwnProperty(key)) {
|
||||||
|
result = resultMap[key];
|
||||||
|
if (result) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const computeConditionForAll = (args) => {
|
/**
|
||||||
return false;
|
* Returns true only if all the results are true
|
||||||
|
**/
|
||||||
|
export const computeConditionForAll = (resultMap) => {
|
||||||
|
let result = false;
|
||||||
|
for (let key in resultMap) {
|
||||||
|
if (resultMap.hasOwnProperty(key)) {
|
||||||
|
result = resultMap[key];
|
||||||
|
if (!result) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user