1
0
Fork 0
mirror of https://git.rwth-aachen.de/acs/public/villas/node/ synced 2025-03-16 00:00:02 +01:00
VILLASnode/web/socket/app.js

286 lines
5.3 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// global variables
var api;
var connection;
var timer;
var nodes = [];
var currentNode;
var paused = false;
var sequence = 0;
var plotData = [];
var plotOptions = {
xaxis: {
mode: 'time'
},
legend: {
show: true
}
};
var updateRate = 25;
var redrawPlot = true;
var xDelta = 5000;
var xPast = xDelta * 0.9;
var xFuture = xDelta * 0.1;
$(document).ready(function() {
api = new Api('v1', apiConnected);
$('#play').click(function(e, ui) {
connection = wsConnect(currentNode);
paused = false;
});
$('#pause').click(function(e, ui) {
connection.close();
paused = true;
});
$('#timespan').slider({
min : 1000,
max : 10000,
value : xDelta,
slide : function(e, ui) {
updatePlotWindow(ui.value);
}
});
$('#updaterate').slider({
min : 1,
max : 50,
value : updateRate,
slide : function(e, ui) {
clearInterval(timer);
timer = setInterval(updatePlot, 1000.0 / updateRate);
updateRate = ui.value;
}
});
$('.inputs #slider').slider({
min : 0,
max : 100,
slide : sendData
});
$('.inputs-checkboxes input').checkboxradio()
.each(function(idx, elm) {
$(elm).change(sendData);
});
timer = setInterval(updatePlot, 1000.0 / updateRate);
});
$(window).on('beforeunload', function() {
connection.close();
api.close();
});
function sendData()
{
var slider = $('.inputs #slider');
var checkboxes = $('.inputs-checkboxes input');
var data = [ $(slider).slider('value'), 0 ];
for (var i = 0; i < checkboxes.length; i++)
data[1] += (checkboxes[i].checked ? 1 : 0) << i;
var msg = new Msg({
timestamp : Date.now(),
sequence : sequence++,
id : currentNode.id,
data : data
});
console.log('Sending message', msg);
connection.send(msg.toArrayBuffer());
}
function apiConnected()
{
api.request('nodes', {},
function(response) {
nodes = response;
console.log("Found " + nodes.length + " nodes:", nodes);
for (var i = 0; i < nodes.length; i++)
if (nodes[i].name == getParameterByName('node'))
currentNode = nodes[i];
if (currentNode === undefined)
currentNode = nodes[0];
if (currentNode !== undefined) {
updateNodeList();
connection = wsConnect(currentNode);
}
}
);
}
function updateNodeList()
{
$('.node-selector').empty();
nodes.forEach(function(node, index) {
if (node.type == 'websocket') {
$('.node-selector').append(
$('<button>')
.addClass(node.name == currentNode.name ? 'ui-state-active' : '')
.text(node.description ? node.description : node.name)
.click(function() {
var url = node.name;
window.location = '?node=' + node.name;
})
);
}
});
$('.node-selector').buttonset();
}
function updatePlotWindow(delta)
{
xDelta = delta
xPast = xDelta * 0.9;
xFuture = xDelta * 0.1;
}
function updatePlot()
{
var data = [];
if (!redrawPlot)
return;
// add data to arrays
for (var i = 0; i < plotData.length; i++) {
var seriesOptions = nodes
data[i] = {
data : plotData[i],
shadowSize : 0,
label : 'Index ' + String(i),
lines : {
lineWidth: 2
}
}
if (currentNode.series !== undefined && currentNode.series[i] !== undefined)
$.extend(true, data[i], currentNode.series[i]);
}
var options = {
xaxis: {
min: Date.now() - xPast,
max: Date.now() + xFuture
},
grid: {
markings: [
{ xaxis: { from: Date.now(), to: Date.now() }, color: '#ff0000' }
]
}
}
/* update plot */
$.plot('.plot-container div', data, $.extend(true, options, plotOptions));
redrawPlot = false;
}
function wsConnect(node)
{
var url = wsUrl('');
var conn = new WebSocket(url, 'live');
conn.binaryType = 'arraybuffer';
conn.onopen = function() {
$('#status')
.text('Connected')
.css('color', 'green');
console.log('WebSocket connection established');
};
conn.onclose = function(error) {
console.log('WebSocket connection closed', error);
$('#status')
.text('Disconnected (' + error.reason + ')')
.css('color', 'red');
/* Try connect if close reason was CLOSE_NORMAL */
if (error.code == 1000 || error.code == 1001) {
setTimeout(function() {
wsConnect(currentNode);
}, 1000);
}
};
conn.onerror = function(error) {
console.log('WebSocket connection error', error);
$('#status').text('Status: Error: ' + error.message);
};
conn.onmessage = function(e) {
var msgs = Msg.fromArrayBufferVector(e.data);
console.log('Received ' + msgs.length + ' messages with ' + msgs[0].data.length + ' values from id ' + msgs[0].id + ' with timestamp ' + msgs[0].timestamp);
for (var j = 0; j < plotData.length; j++) {
// remove old
while (plotData[j].length > 0 && plotData[j][0][0] < (Date.now() - xPast))
plotData[j].shift()
}
for (var j = 0; j < msgs.length; j++) {
var msg = msgs[j];
if (msg.id != currentNode.id)
continue;
// add empty arrays for data series
while (plotData.length < msg.length)
plotData.push([]);
// add data to arrays
for (var i = 0; i < msg.length; i++)
plotData[i].push([msg.timestamp, msg.data[i]]);
}
redrawPlot = true;
};
return conn;
};
/* Helpers */
function wsUrl(endpoint)
{
var l = window.location;
var url = '';
if (l.protocol === 'https:')
url += 'wss://';
else
url += 'ws://';
url += l.hostname;
if ((l.port) && (l.port != 80) && (l.port != 443))
url += ':'+ l.port;
url += '/' + endpoint;
return url;
}
/* Some helpers */