Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds limits subscription to the Telemetry API #6735

Merged
merged 12 commits into from
Jul 15, 2023
3 changes: 2 additions & 1 deletion e2e/baseFixtures.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand Down Expand Up @@ -179,4 +179,5 @@ exports.test = base.test.extend({
});

exports.expect = expect;
exports.request = request;
exports.waitForAnimations = waitForAnimations;
3 changes: 2 additions & 1 deletion e2e/pluginFixtures.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');

Expand Down Expand Up @@ -147,6 +147,7 @@ exports.test = test.extend({
}
});
exports.expect = expect;
exports.request = request;

/**
* Takes a readable stream and returns a string.
Expand Down
110 changes: 96 additions & 14 deletions src/api/telemetry/TelemetryAPI.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down Expand Up @@ -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#
*/
Expand Down Expand Up @@ -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#
*/
Expand Down Expand Up @@ -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
*/

Expand All @@ -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
*/

/**
Expand Down
22 changes: 21 additions & 1 deletion src/plugins/plot/configuration/PlotSeries.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,10 @@ export default class PlotSeries extends Model {
this.unsubscribe();
}

if (this.unsubscribeLimits) {
this.unsubscribeLimits();
}

if (this.removeMutationListener) {
this.removeMutationListener();
}
Expand Down Expand Up @@ -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);
Expand Down