Adds limits subscription to the Telemetry API (#6735)

* Add subscription for limits for domain objects
---------

Co-authored-by: John Hill <john.c.hill@nasa.gov>
Co-authored-by: Andrew Henry <akhenry@gmail.com>
This commit is contained in:
Shefali Joshi 2023-07-14 17:09:05 -07:00 committed by GitHub
parent 662d14354c
commit 5b1298f221
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 121 additions and 17 deletions

View File

@ -29,7 +29,7 @@
*/
const base = require('@playwright/test');
const { expect } = base;
const { expect, request } = base;
const fs = require('fs');
const path = require('path');
const { v4: uuid } = require('uuid');
@ -179,4 +179,5 @@ exports.test = base.test.extend({
});
exports.expect = expect;
exports.request = request;
exports.waitForAnimations = waitForAnimations;

View File

@ -26,7 +26,7 @@
* and appActions. These fixtures should be generalized across all plugins.
*/
const { test, expect } = require('./baseFixtures');
const { test, expect, request } = require('./baseFixtures');
// const { createDomainObjectWithDefaults } = require('./appActions');
const path = require('path');
@ -147,6 +147,7 @@ exports.test = test.extend({
}
});
exports.expect = expect;
exports.request = request;
/**
* Takes a readable stream and returns a string.

View File

@ -489,6 +489,62 @@ export default class TelemetryAPI {
}.bind(this);
}
/**
* Subscribe to run-time changes in configured telemetry limits for a specific domain object.
* The callback will be called whenever data is received from a
* limit provider.
*
* @method subscribeToLimits
* @memberof module:openmct.TelemetryAPI~TelemetryProvider#
* @param {module:openmct.DomainObject} domainObject the object
* which has associated limits
* @param {Function} callback the callback to invoke with new data, as
* it becomes available
* @returns {Function} a function which may be called to terminate
* the subscription
*/
subscribeToLimits(domainObject, callback) {
if (domainObject.type === 'unknown') {
return () => {};
}
const provider = this.#findLimitEvaluator(domainObject);
if (!this.limitsSubscribeCache) {
this.limitsSubscribeCache = {};
}
const keyString = objectUtils.makeKeyString(domainObject.identifier);
let subscriber = this.limitsSubscribeCache[keyString];
if (!subscriber) {
subscriber = this.limitsSubscribeCache[keyString] = {
callbacks: [callback]
};
if (provider && provider.subscribeToLimits) {
subscriber.unsubscribe = provider.subscribeToLimits(domainObject, function (value) {
subscriber.callbacks.forEach(function (cb) {
cb(value);
});
});
} else {
subscriber.unsubscribe = function () {};
}
} else {
subscriber.callbacks.push(callback);
}
return function unsubscribe() {
subscriber.callbacks = subscriber.callbacks.filter(function (cb) {
return cb !== callback;
});
if (subscriber.callbacks.length === 0) {
subscriber.unsubscribe();
delete this.limitsSubscribeCache[keyString];
}
}.bind(this);
}
/**
* Request telemetry staleness for a domain object.
*
@ -676,7 +732,7 @@ export default class TelemetryAPI {
*
* @param {module:openmct.DomainObject} domainObject the domain
* object for which to get limits
* @returns {module:openmct.TelemetryAPI~LimitEvaluator}
* @returns {LimitsResponseObject}
* @method limits
* @memberof module:openmct.TelemetryAPI~TelemetryProvider#
*/
@ -723,18 +779,8 @@ export default class TelemetryAPI {
*
* @param {module:openmct.DomainObject} domainObject the domain
* object for which to display limits
* @returns {module:openmct.TelemetryAPI~LimitEvaluator}
* @method limits returns a limits object of
* type {
* level1: {
* low: { key1: value1, key2: value2, color: <supportedColor> },
* high: { key1: value1, key2: value2, color: <supportedColor> }
* },
* level2: {
* low: { key1: value1, key2: value2 },
* high: { key1: value1, key2: value2 }
* }
* }
* @returns {LimitsResponseObject}
* @method limits returns a limits object of type {LimitsResponseObject}
* supported colors are purple, red, orange, yellow and cyan
* @memberof module:openmct.TelemetryAPI~TelemetryProvider#
*/
@ -766,7 +812,7 @@ export default class TelemetryAPI {
* @param {*} datum the telemetry datum to evaluate
* @param {TelemetryProperty} the property to check for limit violations
* @memberof module:openmct.TelemetryAPI~LimitEvaluator
* @returns {module:openmct.TelemetryAPI~LimitViolation} metadata about
* @returns {LimitViolation} metadata about
* the limit violation, or undefined if a value is within limits
*/
@ -777,6 +823,42 @@ export default class TelemetryAPI {
* @property {string} cssClass the class (or space-separated classes) to
* apply to display elements for values which violate this limit
* @property {string} name the human-readable name for the limit violation
* @property {number} low a lower limit for violation
* @property {number} high a higher limit violation
*/
/**
* @typedef {object} LimitsResponseObject
* @memberof {module:openmct.TelemetryAPI~}
* @property {LimitDefinition} limitLevel the level name and it's limit definition
* @example {
* [limitLevel]: {
* low: {
* color: lowColor,
* value: lowValue
* },
* high: {
* color: highColor,
* value: highValue
* }
* }
* }
*/
/**
* Limit defined for a telemetry property.
* @typedef LimitDefinition
* @memberof {module:openmct.TelemetryAPI~}
* @property {LimitDefinitionValue} low a lower limit
* @property {LimitDefinitionValue} high a higher limit
*/
/**
* Limit definition for a Limit of a telemetry property.
* @typedef LimitDefinitionValue
* @memberof {module:openmct.TelemetryAPI~}
* @property {string} color color to represent this limit
* @property {Number} value the limit value
*/
/**

View File

@ -141,6 +141,10 @@ export default class PlotSeries extends Model {
this.unsubscribe();
}
if (this.unsubscribeLimits) {
this.unsubscribeLimits();
}
if (this.removeMutationListener) {
this.removeMutationListener();
}
@ -320,10 +324,26 @@ export default class PlotSeries extends Model {
async load(options) {
await this.fetch(options);
this.emit('load');
this.loadLimits();
}
async loadLimits() {
const limitsResponse = await this.limitDefinition.limits();
this.limits = [];
this.limits = {};
if (!this.unsubscribeLimits) {
this.unsubscribeLimits = this.openmct.telemetry.subscribeToLimits(
this.domainObject,
this.limitsUpdated.bind(this)
);
}
this.limitsUpdated(limitsResponse);
}
limitsUpdated(limitsResponse) {
if (limitsResponse) {
this.limits = limitsResponse;
} else {
this.limits = {};
}
this.emit('limits', this);