[Demo] Updated demo telemetry source

This commit is contained in:
Henry 2016-04-26 14:47:03 -07:00
parent 509e1970de
commit 37c5a11ece
5 changed files with 298 additions and 68 deletions

View File

@ -56,12 +56,6 @@ define([
"provides": "conductorService",
"type": "decorator"
},
{
"implementation": DemoTelemetryDecorator,
"provides": "telemetryService",
"type": "decorator",
"priority": "mandatory"
},
{
"implementation": DemoTelemetryProvider,
"type": "provider",
@ -147,7 +141,15 @@ define([
{
"stylesheetUrl": "css/tour.css"
}
]
],
"constants": [
{
"key": "PLOT_FIXED_DURATION",
"value": 60000,
"comment": "1 minute."
}
],
}
});
});

View File

@ -97,26 +97,9 @@ define(
target: document.querySelector(".create-btn"),
placement: "bottom"
},
/*
{
title: "Composing objects",
content: "Objects can be composed by dragging" +
" them from the tree...",
target: document.querySelector("mct-tree" +
" ul.tree"),
placement: "right"
},
{
title: "Composing objects (cont.)",
content: "...into the current view",
target: document.querySelector(".object-holder-main"),
placement: "top",
yOffset: "100px;"
}*/
]
};
hopscotch.endTour(true);
// Start the tour!
hopscotch.startTour(tour);
}, 3000);

View File

@ -21,68 +21,142 @@
*****************************************************************************/
/*global define,Promise*/
/**
* Module defining SinewaveTelemetryProvider.
* Created by vwoeltje on 11/12/14.
*
* @memberof example/generator
*/
define(
["../../../example/generator/src/SinewaveTelemetryProvider"],
function (SinewaveTelemetryProvider) {
["./DemoTelemetrySeries"],
function (DemoTelemetrySeries) {
"use strict";
var SOURCE = 'demo-telemetry';
var SOURCE = 'demo-telemetry',
series = {};
/**
* A telemetry provider that generates sine wave data for testing
* and telemetry purposes.
* @constructor
*/
function DemoTelemetryProvider($q, $timeout) {
SinewaveTelemetryProvider.call(this, $q, $timeout);
}
DemoTelemetryProvider.prototype = Object.create(SinewaveTelemetryProvider.prototype);
DemoTelemetryProvider.prototype.doPackage = function (results) {
var packaged = {};
results.forEach(function (result) {
packaged[result.key] = result.telemetry;
});
// Format as expected (sources -> keys -> telemetry)
return { "demo-telemetry": packaged };
this.$q = $q;
this.$timeout = $timeout;
this.subscriptions = [];
this.generating = false;
}
DemoTelemetryProvider.prototype.matchesSource = function (request) {
return request.source === SOURCE;
};
DemoTelemetryProvider.prototype.doPackage = function (results) {
var packaged = {},
result = {};
results.forEach(function (result) {
packaged[result.key] = result.telemetry;
});
result[SOURCE] = packaged;
// Format as expected (sources -> keys -> telemetry)
return result;
}
DemoTelemetryProvider.prototype.subscribe = function (callback, requests) {
var offsets = {};
/**
* Produce some data to be passed to registered subscription callbacks
* @param request
* @returns {{key: string, telemetry: DemoTelemetrySeries}}
*/
DemoTelemetryProvider.prototype.generateData = function (request) {
if (!series[request.id]){
series[request.id] = {
phaseShift: Math.random() * 2 * Math.PI,
rangeOffset: 1 + Math.random()
};
}
return {
key: request.key,
telemetry: new DemoTelemetrySeries(request, series[request.id])
};
};
function wrapSeries(telemetrySeries, offset) {
return {
getDomainValue: function (index, domain) {
return telemetrySeries.getDomainValue(index, domain);
},
getRangeValue: function (index, range) {
// Sine wave 'carrier' signal, with random phase shift
return telemetrySeries.getRangeValue(index, range)
// Introduce some random variability so that line is
// not straight or perfectly curved
+ Math.random(1)/50
//Add a random range offset so that lines
// are not all bunched together
+ offset;
},
getPointCount: function () {
return telemetrySeries.getPointCount();
}
/**
* Invoke callbacks on all registered subscriptions when data is
* available.
*/
DemoTelemetryProvider.prototype.handleSubscriptions = function () {
var self = this;
self.subscriptions.forEach(function (subscription) {
var requests = subscription.requests;
subscription.callback(self.doPackage(
requests.filter(self.matchesSource).map(self.generateData)
));
});
};
/**
* Will start producing telemetry @ 1hz
*/
DemoTelemetryProvider.prototype.startGenerating = function () {
var self = this;
self.generating = true;
self.$timeout(function () {
self.handleSubscriptions();
if (self.generating && self.subscriptions.length > 0) {
self.startGenerating();
} else {
self.generating = false;
}
}
}, 1000);
};
function randomize(telemetry){
Object.keys(telemetry[SOURCE]).forEach(function(key) {
if (!offsets[key])
offsets[key] = 1 + Math.random(10);
telemetry[SOURCE][key] = wrapSeries(telemetry[SOURCE][key], offsets[key]);
/**
* Request historical telemetry from this source.
* @param requests
* @returns {object} an object with the request key as the key, and
* a SinewaveTelemetrySeries as its value
*/
DemoTelemetryProvider.prototype.requestTelemetry = function (requests) {
var self = this;
return this.$timeout(function () {
return self.doPackage(requests.filter(self.matchesSource).map(self.generateData));
}, 0);
};
/**
* Subscribe to realtime telemetry
* @param callback a function to call when data is available
* @param requests all current telemetry requests (will be tested to
* see if they match this source)
* @returns {function} a function to call to unsubscribe from this
* telemetry source
*/
DemoTelemetryProvider.prototype.subscribe = function (callback, requests) {
var self = this,
subscription = {
callback: callback,
requests: requests
};
function unsubscribe() {
self.subscriptions = self.subscriptions.filter(function (s) {
return s !== subscription;
});
//Also delete series object
subscription.requests.forEach(function (request) {
delete series[request.id];
});
callback(telemetry);
}
return SinewaveTelemetryProvider.prototype.subscribe.call(this, randomize, requests);
self.subscriptions.push(subscription);
if (!this.generating) {
this.startGenerating();
}
return unsubscribe;
};
return DemoTelemetryProvider;
}
);
);

View File

@ -0,0 +1,88 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT Web includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define,Promise*/
define(
["../../../example/generator/src/SinewaveTelemetryProvider"],
function (SinewaveTelemetryProvider) {
"use strict";
var SOURCE = 'demo-telemetry';
function DemoTelemetryProvider($q, $timeout) {
SinewaveTelemetryProvider.call(this, $q, $timeout);
}
DemoTelemetryProvider.prototype = Object.create(SinewaveTelemetryProvider.prototype);
DemoTelemetryProvider.prototype.doPackage = function (results) {
var packaged = {};
results.forEach(function (result) {
packaged[result.key] = result.telemetry;
});
// Format as expected (sources -> keys -> telemetry)
return { "demo-telemetry": packaged };
}
DemoTelemetryProvider.prototype.matchesSource = function (request) {
return request.source === SOURCE;
}
DemoTelemetryProvider.prototype.subscribe = function (callback, requests) {
var offsets = {};
function wrapSeries(telemetrySeries, offset) {
return {
getDomainValue: function (index, domain) {
return telemetrySeries.getDomainValue(index, domain);
},
getRangeValue: function (index, range) {
// Sine wave 'carrier' signal, with random phase shift
return telemetrySeries.getRangeValue(index, range)
// Introduce some random variability so that line is
// not straight or perfectly curved
+ Math.random(1)/50
//Add a random range offset so that lines
// are not all bunched together
+ offset;
},
getPointCount: function () {
return telemetrySeries.getPointCount();
}
}
}
function randomize(telemetry){
Object.keys(telemetry[SOURCE]).forEach(function(key) {
if (!offsets[key])
offsets[key] = 1 + Math.random();
telemetry[SOURCE][key] = wrapSeries(telemetry[SOURCE][key], offsets[key]);
});
callback(telemetry);
}
return SinewaveTelemetryProvider.prototype.subscribe.call(this, randomize, requests);
};
return DemoTelemetryProvider;
}
);

View File

@ -0,0 +1,83 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT Web includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define,Promise*/
/**
* Module defining SinewaveTelemetry. Created by vwoeltje on 11/12/14.
*/
define(
[],
function () {
"use strict";
var ONE_DAY = 60 * 60 * 24,
START_TIME = Date.now() - 24 * 60 * 60 * 1000, // Now minus a day.
firstObservedTime = Math.floor(START_TIME / 1000);
/**
*
* @constructor
*/
function DemoTelemetrySeries(request, options) {
var timeOffset = (request.domain === 'yesterday') ? ONE_DAY : 0,
latestTime = Math.floor(Date.now() / 1000) - timeOffset,
firstTime = firstObservedTime - timeOffset,
endTime = (request.end !== undefined) ?
Math.floor(request.end / 1000) : latestTime,
count = Math.min(endTime, latestTime) - firstTime,
period = +request.period || 30,
generatorData = {},
requestStart = (request.start === undefined) ? firstTime :
Math.max(Math.floor(request.start / 1000), firstTime),
offset = requestStart - firstTime;
if (request.size !== undefined) {
offset = Math.max(offset, count - request.size);
}
generatorData.getPointCount = function () {
return count - offset;
};
generatorData.getDomainValue = function (i, domain) {
// delta uses the same numeric values as the default domain,
// so it's not checked for here, just formatted for display
// differently.
return (i + offset) * 1000 + firstTime * 1000 -
(domain === 'yesterday' ? (ONE_DAY * 1000) : 0);
};
generatorData.getRangeValue = function (i, range) {
var rangeValue = Math[range || "sin"]((i + offset) * options.phaseShift / period),
damper = 0.05,
noise = Math.random() * damper;
rangeValue += options.rangeOffset;
rangeValue += noise;
return rangeValue;
};
return generatorData;
}
return DemoTelemetrySeries;
}
);