Compare commits

..

2 Commits

Author SHA1 Message Date
d3825fc554 rescope objects 2023-08-18 14:52:46 -07:00
d42b2dd023 mappin 2023-08-17 11:23:42 -07:00
11 changed files with 939 additions and 933 deletions

View File

@ -23,5 +23,5 @@ module.exports = merge(common, {
__OPENMCT_ROOT_RELATIVE__: '""'
})
],
devtool: "source-map"
devtool: "eval-source-map"
});

View File

@ -1,32 +1,37 @@
define(['lodash'], function (_) {
define([
'lodash'
], function (
_
) {
var METADATA_BY_TYPE = {
generator: {
'generator': {
values: [
{
key: 'name',
name: 'Name',
format: 'string'
key: "name",
name: "Name",
format: "string"
},
{
key: 'utc',
name: 'Time',
format: 'utc',
key: "utc",
name: "Time",
format: "utc",
hints: {
domain: 1
}
},
{
key: 'yesterday',
name: 'Yesterday',
format: 'utc',
key: "yesterday",
name: "Yesterday",
format: "utc",
hints: {
domain: 2
}
},
{
key: 'wavelengths',
name: 'Wavelength',
unit: 'nm',
key: "wavelengths",
name: "Wavelength",
unit: "nm",
format: 'string[]',
hints: {
range: 4
@ -43,26 +48,26 @@ define(['lodash'], function (_) {
// }
// },
{
key: 'sin',
name: 'Sine',
unit: 'Hz',
key: "sin",
name: "Sine",
unit: "Hz",
formatString: '%0.2f',
hints: {
range: 1
}
},
{
key: 'cos',
name: 'Cosine',
unit: 'deg',
key: "cos",
name: "Cosine",
unit: "deg",
formatString: '%0.2f',
hints: {
range: 2
}
},
{
key: 'intensities',
name: 'Intensities',
key: "intensities",
name: "Intensities",
format: 'number[]',
hints: {
range: 3
@ -73,40 +78,40 @@ define(['lodash'], function (_) {
'example.state-generator': {
values: [
{
key: 'name',
name: 'Name',
format: 'string'
key: "name",
name: "Name",
format: "string"
},
{
key: 'utc',
name: 'Time',
format: 'utc',
key: "utc",
name: "Time",
format: "utc",
hints: {
domain: 1
}
},
{
key: 'local',
name: 'Time',
format: 'utc',
source: 'utc',
key: "local",
name: "Time",
format: "utc",
source: "utc",
hints: {
domain: 2
}
},
{
key: 'state',
source: 'value',
name: 'State',
format: 'enum',
key: "state",
source: "value",
name: "State",
format: "enum",
enumerations: [
{
value: 0,
string: 'OFF'
string: "OFF"
},
{
value: 1,
string: 'ON'
string: "ON"
}
],
hints: {
@ -114,8 +119,8 @@ define(['lodash'], function (_) {
}
},
{
key: 'value',
name: 'Value',
key: "value",
name: "Value",
hints: {
range: 2
}
@ -124,15 +129,22 @@ define(['lodash'], function (_) {
}
};
function GeneratorMetadataProvider() {}
function GeneratorMetadataProvider() {
}
GeneratorMetadataProvider.prototype.supportsMetadata = function (domainObject) {
return Object.prototype.hasOwnProperty.call(METADATA_BY_TYPE, domainObject.type);
};
GeneratorMetadataProvider.prototype.getMetadata = function (domainObject) {
return Object.assign({}, domainObject.telemetry, METADATA_BY_TYPE[domainObject.type]);
return Object.assign(
{},
domainObject.telemetry,
METADATA_BY_TYPE[domainObject.type]
);
};
return GeneratorMetadataProvider;
});

View File

@ -20,7 +20,12 @@
* at runtime from the About dialog for additional information.
*****************************************************************************/
define(['./WorkerInterface'], function (WorkerInterface) {
define([
'./WorkerInterface'
], function (
WorkerInterface
) {
var REQUEST_DEFAULTS = {
amplitude: 1,
period: 10,
@ -29,8 +34,7 @@ define(['./WorkerInterface'], function (WorkerInterface) {
randomness: 0,
phase: 0,
loadDelay: 0,
infinityValues: false,
veryLargeValues: false
infinityValues: false
};
function GeneratorProvider(openmct, StalenessProvider) {
@ -42,7 +46,8 @@ define(['./WorkerInterface'], function (WorkerInterface) {
return domainObject.type === 'generator';
};
GeneratorProvider.prototype.supportsRequest = GeneratorProvider.prototype.supportsSubscribe =
GeneratorProvider.prototype.supportsRequest =
GeneratorProvider.prototype.supportsSubscribe =
GeneratorProvider.prototype.canProvideTelemetry;
GeneratorProvider.prototype.makeWorkerRequest = function (domainObject, request) {
@ -54,8 +59,7 @@ define(['./WorkerInterface'], function (WorkerInterface) {
'randomness',
'phase',
'loadDelay',
'infinityValues',
'veryLargeValues'
'infinityValues'
];
request = request || {};
@ -63,10 +67,7 @@ define(['./WorkerInterface'], function (WorkerInterface) {
var workerRequest = {};
props.forEach(function (prop) {
if (
domainObject.telemetry &&
Object.prototype.hasOwnProperty.call(domainObject.telemetry, prop)
) {
if (domainObject.telemetry && Object.prototype.hasOwnProperty.call(domainObject.telemetry, prop)) {
workerRequest[prop] = domainObject.telemetry[prop];
}

View File

@ -20,7 +20,12 @@
* at runtime from the About dialog for additional information.
*****************************************************************************/
define([], function () {
define([
], function (
) {
var PURPLE = {
sin: 2.2,
cos: 2.2
@ -43,32 +48,34 @@ define([], function () {
},
LIMITS = {
rh: {
cssClass: 'is-limit--upr is-limit--red',
cssClass: "is-limit--upr is-limit--red",
low: RED,
high: Number.POSITIVE_INFINITY,
name: 'Red High'
name: "Red High"
},
rl: {
cssClass: 'is-limit--lwr is-limit--red',
cssClass: "is-limit--lwr is-limit--red",
high: -RED,
low: Number.NEGATIVE_INFINITY,
name: 'Red Low'
name: "Red Low"
},
yh: {
cssClass: 'is-limit--upr is-limit--yellow',
cssClass: "is-limit--upr is-limit--yellow",
low: YELLOW,
high: RED,
name: 'Yellow High'
name: "Yellow High"
},
yl: {
cssClass: 'is-limit--lwr is-limit--yellow',
cssClass: "is-limit--lwr is-limit--yellow",
low: -RED,
high: -YELLOW,
name: 'Yellow Low'
name: "Yellow Low"
}
};
function SinewaveLimitProvider() {}
function SinewaveLimitProvider() {
}
SinewaveLimitProvider.prototype.supportsLimits = function (domainObject) {
return domainObject.type === 'generator';
@ -99,61 +106,62 @@ define([], function () {
};
SinewaveLimitProvider.prototype.getLimits = function (domainObject) {
return {
limits: function () {
return Promise.resolve({
WATCH: {
low: {
color: 'cyan',
color: "cyan",
sin: -CYAN.sin,
cos: -CYAN.cos
},
high: {
color: 'cyan',
color: "cyan",
...CYAN
}
},
WARNING: {
low: {
color: 'yellow',
color: "yellow",
sin: -YELLOW.sin,
cos: -YELLOW.cos
},
high: {
color: 'yellow',
color: "yellow",
...YELLOW
}
},
DISTRESS: {
low: {
color: 'orange',
color: "orange",
sin: -ORANGE.sin,
cos: -ORANGE.cos
},
high: {
color: 'orange',
color: "orange",
...ORANGE
}
},
CRITICAL: {
low: {
color: 'red',
color: "red",
sin: -RED.sin,
cos: -RED.cos
},
high: {
color: 'red',
color: "red",
...RED
}
},
SEVERE: {
low: {
color: 'purple',
color: "purple",
sin: -PURPLE.sin,
cos: -PURPLE.cos
},
high: {
color: 'purple',
color: "purple",
...PURPLE
}
}

View File

@ -62,7 +62,7 @@ export default class SinewaveLimitProvider extends EventEmitter {
const id = this.#getObjectKeyString(domainObject);
if (this.#isRealTime === undefined) {
this.#updateRealTime(this.#openmct.time.getMode());
this.#updateRealTime(this.#openmct.time.clock());
}
this.#handleClockUpdate();
@ -92,15 +92,15 @@ export default class SinewaveLimitProvider extends EventEmitter {
if (observers && !this.#watchingTheClock) {
this.#watchingTheClock = true;
this.#openmct.time.on('modeChanged', this.#updateRealTime, this);
this.#openmct.time.on('clock', this.#updateRealTime, this);
} else if (!observers && this.#watchingTheClock) {
this.#watchingTheClock = false;
this.#openmct.time.off('modeChanged', this.#updateRealTime, this);
this.#openmct.time.off('clock', this.#updateRealTime, this);
}
}
#updateRealTime(mode) {
this.#isRealTime = mode !== 'fixed';
#updateRealTime(clock) {
this.#isRealTime = clock !== undefined;
if (!this.#isRealTime) {
Object.keys(this.#observingStaleness).forEach((id) => {

View File

@ -20,8 +20,15 @@
* at runtime from the About dialog for additional information.
*****************************************************************************/
define([], function () {
function StateGeneratorProvider() {}
define([
], function (
) {
function StateGeneratorProvider() {
}
function pointForTimestamp(timestamp, duration, name) {
return {
@ -72,4 +79,5 @@ define([], function () {
};
return StateGeneratorProvider;
});

View File

@ -20,7 +20,11 @@
* at runtime from the About dialog for additional information.
*****************************************************************************/
define(['uuid'], function ({ v4: uuid }) {
define([
'uuid'
], function (
{ v4: uuid }
) {
function WorkerInterface(openmct, StalenessProvider) {
// eslint-disable-next-line no-undef
const workerUrl = `${openmct.getAssetPath()}${__OPENMCT_ROOT_RELATIVE__}generatorWorker.js`;
@ -34,7 +38,7 @@ define(['uuid'], function ({ v4: uuid }) {
}
WorkerInterface.prototype.watchStaleness = function () {
this.StalenessProvider.on('stalenessEvent', ({ id, isStale }) => {
this.StalenessProvider.on('stalenessEvent', ({ id, isStale}) => {
this.staleTelemetryIds[id] = isStale;
});
};
@ -80,6 +84,7 @@ define(['uuid'], function ({ v4: uuid }) {
}
delete self.callbacks[messageId];
}
messageId = this.dispatch('request', request, callback.bind(this));
@ -88,10 +93,10 @@ define(['uuid'], function ({ v4: uuid }) {
};
WorkerInterface.prototype.subscribe = function (request, cb) {
const { id, loadDelay } = request;
const id = request.id;
const messageId = this.dispatch('subscribe', request, (message) => {
if (!this.staleTelemetryIds[id]) {
setTimeout(() => cb(message.data), Math.max(loadDelay, 0));
cb(message.data);
}
});

View File

@ -21,6 +21,7 @@
*****************************************************************************/
(function () {
var FIFTEEN_MINUTES = 15 * 60 * 1000;
var handlers = {
@ -33,12 +34,9 @@
function workSubscriptions(timestamp) {
var now = Date.now();
var nextWork = Math.min.apply(
Math,
Object.values(subscriptions).map(function (subscription) {
var nextWork = Math.min.apply(Math, Object.values(subscriptions).map(function (subscription) {
return subscription(now);
})
);
}));
var wait = nextWork - now;
if (wait < 0) {
wait = 0;
@ -61,7 +59,7 @@
work = function (now) {
while (nextStep < now) {
const messageCopy = Object.create(message);
message.data.start = nextStep - 60 * 1000;
message.data.start = nextStep - (60 * 1000);
message.data.end = nextStep;
onRequest(messageCopy);
nextStep += step;
@ -78,28 +76,10 @@
name: data.name,
utc: nextStep,
yesterday: nextStep - 60 * 60 * 24 * 1000,
sin: sin(
nextStep,
data.period,
data.amplitude,
data.offset,
data.phase,
data.randomness,
data.infinityValues,
data.veryLargeValues
),
sin: sin(nextStep, data.period, data.amplitude, data.offset, data.phase, data.randomness, data.infinityValues),
wavelengths: wavelengths(),
intensities: intensities(),
cos: cos(
nextStep,
data.period,
data.amplitude,
data.offset,
data.phase,
data.randomness,
data.infinityValues,
data.veryLargeValues
)
cos: cos(nextStep, data.period, data.amplitude, data.offset, data.phase, data.randomness, data.infinityValues)
}
});
nextStep += step;
@ -138,7 +118,6 @@
var randomness = request.randomness;
var loadDelay = Math.max(request.loadDelay, 0);
var infinityValues = request.infinityValues;
var veryLargeValues = request.veryLargeValues;
var step = 1000 / dataRateInHz;
var nextStep = start - (start % step) + step;
@ -149,10 +128,10 @@
data.push({
utc: nextStep,
yesterday: nextStep - 60 * 60 * 24 * 1000,
sin: sin(nextStep, period, amplitude, offset, phase, randomness, infinityValues, veryLargeValues),
sin: sin(nextStep, period, amplitude, offset, phase, randomness, infinityValues),
wavelengths: wavelengths(),
intensities: intensities(),
cos: cos(nextStep, period, amplitude, offset, phase, randomness, infinityValues, veryLargeValues)
cos: cos(nextStep, period, amplitude, offset, phase, randomness, infinityValues)
});
}
@ -166,63 +145,33 @@
function postOnRequest(message, request, data) {
self.postMessage({
id: message.id,
data: request.spectra
? {
data: request.spectra ? {
wavelength: data.map((item) => {
return item.wavelength;
}),
cos: data.map((item) => {
return item.cos;
})
}
: data
} : data
});
}
function cos(timestamp, period, amplitude, offset, phase, randomness, infinityValues, veryLargeValues) {
const randomValue = Math.random();
if (infinityValues && veryLargeValues) {
if (randomValue < 0.33) return Number.POSITIVE_INFINITY;
if (randomValue < 0.66) return (randomValue > 0.5 ? -1 : 1) * 1e+177;
// if neither condition is met, it just proceeds to the normal return value
} else {
if (infinityValues && randomValue > 0.5) {
function cos(timestamp, period, amplitude, offset, phase, randomness, infinityValues) {
if (infinityValues && Math.random() > 0.5) {
return Number.POSITIVE_INFINITY;
}
if (veryLargeValues && randomValue > 0.5) {
return (randomValue > 0.5 ? -1 : 1) * 1e+177;
}
return amplitude
* Math.cos(phase + (timestamp / period / 1000 * Math.PI * 2)) + (amplitude * Math.random() * randomness) + offset;
}
return (
amplitude * Math.cos(phase + (timestamp / period / 1000) * Math.PI * 2) +
amplitude * Math.random() * randomness +
offset
);
}
function sin(timestamp, period, amplitude, offset, phase, randomness, infinityValues, veryLargeValues) {
const randomValue = Math.random();
if (infinityValues && veryLargeValues) {
if (randomValue < 0.33) return Number.POSITIVE_INFINITY;
if (randomValue < 0.66) return (randomValue > 0.5 ? -1 : 1) * 1e+177;
// if neither condition is met, it just proceeds to the normal return value
} else {
if (infinityValues && randomValue > 0.5) {
function sin(timestamp, period, amplitude, offset, phase, randomness, infinityValues) {
if (infinityValues && Math.random() > 0.5) {
return Number.POSITIVE_INFINITY;
}
if (veryLargeValues && randomValue > 0.5) {
return (randomValue > 0.5 ? -1 : 1) * 1e+177;
}
}
return (
amplitude * Math.sin(phase + (timestamp / period / 1000) * Math.PI * 2) +
amplitude * Math.random() * randomness +
offset
);
return amplitude
* Math.sin(phase + (timestamp / period / 1000 * Math.PI * 2)) + (amplitude * Math.random() * randomness) + offset;
}
function wavelengths() {
@ -271,4 +220,5 @@
}
}
};
})();
}());

View File

@ -20,27 +20,30 @@
* at runtime from the About dialog for additional information.
*****************************************************************************/
import GeneratorMetadataProvider from './GeneratorMetadataProvider';
import GeneratorProvider from './GeneratorProvider';
import SinewaveLimitProvider from './SinewaveLimitProvider';
import SinewaveStalenessProvider from './SinewaveStalenessProvider';
import StateGeneratorProvider from './StateGeneratorProvider';
import GeneratorProvider from "./GeneratorProvider";
import SinewaveLimitProvider from "./SinewaveLimitProvider";
import SinewaveStalenessProvider from "./SinewaveStalenessProvider";
import StateGeneratorProvider from "./StateGeneratorProvider";
import GeneratorMetadataProvider from "./GeneratorMetadataProvider";
export default function (openmct) {
openmct.types.addType('example.state-generator', {
name: 'State Generator',
description:
'For development use. Generates example enumerated telemetry by cycling through a given set of states.',
cssClass: 'icon-generator-telemetry',
openmct.types.addType("example.state-generator", {
name: "State Generator",
description: "For development use. Generates example enumerated telemetry by cycling through a given set of states.",
cssClass: "icon-generator-telemetry",
creatable: true,
form: [
{
name: 'State Duration (seconds)',
control: 'numberfield',
cssClass: 'l-input-sm l-numeric',
key: 'duration',
name: "State Duration (seconds)",
control: "numberfield",
cssClass: "l-input-sm l-numeric",
key: "duration",
required: true,
property: ['telemetry', 'duration']
property: [
"telemetry",
"duration"
]
}
],
initialize: function (object) {
@ -52,89 +55,108 @@ export default function (openmct) {
openmct.telemetry.addProvider(new StateGeneratorProvider());
openmct.types.addType('generator', {
name: 'Sine Wave Generator',
description:
'For development use. Generates example streaming telemetry data using a simple sine wave algorithm.',
cssClass: 'icon-generator-telemetry',
openmct.types.addType("generator", {
name: "Sine Wave Generator",
description: "For development use. Generates example streaming telemetry data using a simple sine wave algorithm.",
cssClass: "icon-generator-telemetry",
creatable: true,
form: [
{
name: 'Period',
control: 'numberfield',
cssClass: 'l-input-sm l-numeric',
key: 'period',
name: "Period",
control: "numberfield",
cssClass: "l-input-sm l-numeric",
key: "period",
required: true,
property: ['telemetry', 'period']
property: [
"telemetry",
"period"
]
},
{
name: 'Amplitude',
control: 'numberfield',
cssClass: 'l-numeric',
key: 'amplitude',
name: "Amplitude",
control: "numberfield",
cssClass: "l-numeric",
key: "amplitude",
required: true,
property: ['telemetry', 'amplitude']
property: [
"telemetry",
"amplitude"
]
},
{
name: 'Offset',
control: 'numberfield',
cssClass: 'l-numeric',
key: 'offset',
name: "Offset",
control: "numberfield",
cssClass: "l-numeric",
key: "offset",
required: true,
property: ['telemetry', 'offset']
property: [
"telemetry",
"offset"
]
},
{
name: 'Data Rate (hz)',
control: 'numberfield',
cssClass: 'l-input-sm l-numeric',
key: 'dataRateInHz',
name: "Data Rate (hz)",
control: "numberfield",
cssClass: "l-input-sm l-numeric",
key: "dataRateInHz",
required: true,
property: ['telemetry', 'dataRateInHz']
property: [
"telemetry",
"dataRateInHz"
]
},
{
name: 'Phase (radians)',
control: 'numberfield',
cssClass: 'l-input-sm l-numeric',
key: 'phase',
name: "Phase (radians)",
control: "numberfield",
cssClass: "l-input-sm l-numeric",
key: "phase",
required: true,
property: ['telemetry', 'phase']
property: [
"telemetry",
"phase"
]
},
{
name: 'Randomness',
control: 'numberfield',
cssClass: 'l-input-sm l-numeric',
key: 'randomness',
name: "Randomness",
control: "numberfield",
cssClass: "l-input-sm l-numeric",
key: "randomness",
required: true,
property: ['telemetry', 'randomness']
property: [
"telemetry",
"randomness"
]
},
{
name: 'Loading Delay (ms)',
control: 'numberfield',
cssClass: 'l-input-sm l-numeric',
key: 'loadDelay',
name: "Loading Delay (ms)",
control: "numberfield",
cssClass: "l-input-sm l-numeric",
key: "loadDelay",
required: true,
property: ['telemetry', 'loadDelay']
property: [
"telemetry",
"loadDelay"
]
},
{
name: 'Include Infinity Values',
control: 'toggleSwitch',
cssClass: 'l-input',
key: 'infinityValues',
property: ['telemetry', 'infinityValues']
name: "Include Infinity Values",
control: "toggleSwitch",
cssClass: "l-input",
key: "infinityValues",
property: [
"telemetry",
"infinityValues"
]
},
{
name: 'Include Very Large Values',
control: 'toggleSwitch',
cssClass: 'l-input',
key: 'veryLargeValues',
property: ['telemetry', 'veryLargeValues']
},
{
name: 'Provide Staleness Updates',
control: 'toggleSwitch',
cssClass: 'l-input',
key: 'staleness',
property: ['telemetry', 'staleness']
name: "Provide Staleness Updates",
control: "toggleSwitch",
cssClass: "l-input",
key: "staleness",
property: [
"telemetry",
"staleness"
]
}
],
initialize: function (object) {
@ -147,7 +169,6 @@ export default function (openmct) {
randomness: 0,
loadDelay: 0,
infinityValues: false,
veryLargeValues: false,
staleness: false
};
}

View File

@ -57,9 +57,7 @@ define([
if (isIdentifier(keyString)) {
// TODO REMOVE FOR OMM-RELEASE-5.0
if (!keyString.namespace && keyString.key.includes(':')) {
console.warn(`smushed key: ${keyString.key}`);
return parseKeyString(keyString.key);
console.error(`smushed key: ${keyString.key}`);
}
return keyString;

View File

@ -35,34 +35,34 @@ export default class DuplicateAction {
}
invoke(objectPath) {
this.object = objectPath[0];
this.parent = objectPath[1];
const object = objectPath[0];
const parent = objectPath[1];
this.showForm(this.object, this.parent);
this.showForm(object, parent);
}
inNavigationPath() {
inNavigationPath(object) {
return this.openmct.router.path
.some(objectInPath => this.openmct.objects.areIdsEqual(objectInPath.identifier, this.object.identifier));
.some(objectInPath => this.openmct.objects.areIdsEqual(objectInPath.identifier, object.identifier));
}
async onSave(changes) {
async onSave(object, parent, changes) {
this.startTransaction();
let inNavigationPath = this.inNavigationPath();
let inNavigationPath = this.inNavigationPath(object);
if (inNavigationPath && this.openmct.editor.isEditing()) {
this.openmct.editor.save();
}
let duplicationTask = new DuplicateTask(this.openmct);
if (changes.name && (changes.name !== this.object.name)) {
if (changes.name && (changes.name !== object.name)) {
duplicationTask.changeName(changes.name);
}
const parentDomainObjectpath = changes.location || [this.parent];
const parent = parentDomainObjectpath[0];
const parentDomainObjectpath = changes.location || [parent];
const parentObject = parentDomainObjectpath[0];
await duplicationTask.duplicate(this.object, parent);
await duplicationTask.duplicate(object, parentObject);
return this.saveTransaction();
}
@ -88,7 +88,7 @@ export default class DuplicateAction {
control: "locator",
required: true,
parent: parentDomainObject,
validate: this.validate(parentDomainObject),
validate: this.validate(domainObject, parentDomainObject),
key: 'location'
}
]
@ -97,16 +97,19 @@ export default class DuplicateAction {
};
this.openmct.forms.showForm(formStructure)
.then(this.onSave.bind(this));
.then(changes => {
let onSave = this.onSave.bind(this);
onSave(domainObject, parentDomainObject, changes);
});
}
validate(currentParent) {
validate(domainObject, currentParent) {
return (data) => {
const parentCandidate = data.value[0];
let currentParentKeystring = this.openmct.objects.makeKeyString(currentParent.identifier);
let parentCandidateKeystring = this.openmct.objects.makeKeyString(parentCandidate.identifier);
let objectKeystring = this.openmct.objects.makeKeyString(this.object.identifier);
let objectKeystring = this.openmct.objects.makeKeyString(domainObject.identifier);
if (!this.openmct.objects.isPersistable(parentCandidate.identifier)) {
return false;
@ -125,7 +128,7 @@ export default class DuplicateAction {
return false;
}
return parentCandidate && this.openmct.composition.checkPolicy(parentCandidate, this.object);
return parentCandidate && this.openmct.composition.checkPolicy(parentCandidate, domainObject);
};
}