1
0
Fork 0
mirror of https://git.rwth-aachen.de/acs/public/villas/node/ synced 2025-03-30 00:00:11 +01:00

added new JS code for binary WebSocket protocol

This commit is contained in:
Steffen Vogel 2016-02-04 16:28:31 +01:00
parent 51fe428809
commit 1f20c937d5
3 changed files with 92 additions and 73 deletions

View file

@ -3,9 +3,8 @@ var connection;
var seq = 0; var seq = 0;
var node = getParameterByName("node") || "ws"; var currentNode;
var url = wsUrl(node); var nodes = [ ];
var protocol = ['live'];
var updateRate = 1.0 / 25; var updateRate = 1.0 / 25;
var plotData = []; var plotData = [];
@ -18,28 +17,32 @@ var plotOptions = {
} }
}; };
var msg = new Msg();
var xPast = 10*1000; var xPast = 10*1000;
var xFuture = 5*1000; var xFuture = 5*1000;
$(document).on('ready', function() { $(document).on('ready', function() {
$.getJSON('/nodes.json', function(data) { $.getJSON('/nodes.json', function(data) {
$(data).each(function(index, n) { nodes = data;
var title = n.description ? n.description : n.name;
for (var i = 0; i < nodes.length; i++)
if (n.unit) if (nodes[i].name == getParameterByName("node"))
title += " [" + n.unit + "]"; currentNode = nodes[i];
if (currentNode === undefined)
currentNode = nodes[0];
nodes.forEach(function(node, index) {
$(".node-selector").append( $(".node-selector").append(
$("<li>").append( $("<li>").append(
$("<a>", { $("<a>", {
text: title, text: node.description ? node.description : node.name,
title: n.name, title: node.name,
href: "?node=" + n.name href: "?node=" + node.name
}) })
).addClass(n.name == node ? 'active' : '') ).addClass(node.name == currentNode.name ? 'active' : '')
); );
wsConnect(wsUrl(currentNode.name), ["live"]);
}); });
}); });
@ -53,8 +56,6 @@ $(document).on('ready', function() {
$(button).addClass('on'); $(button).addClass('on');
}); });
wsConnect();
setInterval(plotUpdate, updateRate); setInterval(plotUpdate, updateRate);
}); });
@ -66,8 +67,10 @@ function plotUpdate() {
// add data to arrays // add data to arrays
for (var i = 0; i < plotData.length; i++) { for (var i = 0; i < plotData.length; i++) {
// remove old values // remove old values
//while (plotData[i].length > 0 && plotData[i][0][0] < (Date.now() - xDelta)) while (plotData[i].length > 0 && plotData[i][0][0] < (Date.now() - xPast))
// plotData[i].shift() plotData[i].shift()
var seriesOptions = nodes
data[i] = { data[i] = {
data : plotData[i], data : plotData[i],
@ -77,6 +80,9 @@ function plotUpdate() {
lineWidth: 2 lineWidth: 2
} }
} }
if (currentNode.series !== undefined && currentNode.series[i] !== undefined)
$.extend(true, data[i], currentNode.series[i]);
} }
var options = { var options = {
@ -105,8 +111,10 @@ function wsDisconnect() {
plotData = []; plotData = [];
} }
function wsConnect() { function wsConnect(url, protocol) {
connection = new WebSocket(url, protocol); connection = new WebSocket(url, protocol);
connection.binaryType = 'arraybuffer';
connection.onopen = function() { connection.onopen = function() {
$('#connectionStatus') $('#connectionStatus')
@ -127,17 +135,21 @@ function wsConnect() {
}; };
connection.onmessage = function(e) { connection.onmessage = function(e) {
var msg = new Msg(); var msgs = Msg.fromArrayBufferVector(e.data);
msg.parse(e.data);
// add empty arrays for data for (var j = 0; j < msgs.length; j++) {
while (plotData.length < msg.values.length) var msg = msgs[j];
plotData.push([]);
// add data to arrays // add empty arrays for data
for (var i = 0; i < msg.values.length; i++) while (plotData.length < msg.values)
plotData[i].push([msg.ts, msg.values[i]]); plotData.push([]);
// add data to arrays
for (var i = 0; i < msg.values; i++) {
plotData[i].push([msg.timestamp, msg.data[i]]);
console.log([msg.timestamp, msg.data[i]]);
}
}
}; };
}; };

View file

@ -11,6 +11,7 @@
<script src="jquery-ui/jquery-ui.js"></script> <script src="jquery-ui/jquery-ui.js"></script>
<script src="flot/jquery.flot.js"></script> <script src="flot/jquery.flot.js"></script>
<script src="flot/jquery.flot.time.js"></script> <script src="flot/jquery.flot.time.js"></script>
<script src="msg.js"></script>
<script src="app.js"></script> <script src="app.js"></script>
</head> </head>
<body> <body>

View file

@ -12,23 +12,7 @@
* @{ * @{
**********************************************************************************/ **********************************************************************************/
var S2SS = S2SS || {}; //var S2SS = S2SS || {};
/* Some constants for the binary protocol */
const Msg.VERSION = 1;
const Msg.TYPE_DATA = 0; /**< Message contains float values */
const Msg.TYPE_START = 1; /**< Message marks the beginning of a new simulation case */
const Msg.TYPE_STOP = 2; /**< Message marks the end of a simulation case */
const Msg.TYPE_EMPTY = 3; /**< Message does not carry useful data */
const Msg.ENDIAN_LITTLE = 0; /**< Message values are in little endian format (float too!) */
const Msg.ENDIAN_BIG = 1; /**< Message values are in bit endian format */
/* Some offsets in the binary message */
const Msg.OFFSET_ENDIAN = 1;
const Msg.OFFSET_TYPE = 2;
const Msg.OFFSET_VERSION = 4;
/* Class for parsing and printing a message / sample */ /* Class for parsing and printing a message / sample */
function Msg(members) { function Msg(members) {
@ -36,57 +20,73 @@ function Msg(members) {
this[k] = members[k]; this[k] = members[k];
} }
Msg.prototype.length = function() { /* Some constants for the binary protocol */
return this.length * 4 + 16; Msg.prototype.VERSION = 1;
Msg.prototype.TYPE_DATA = 0; /**< Message contains float values */
Msg.prototype.TYPE_START = 1; /**< Message marks the beginning of a new simulation case */
Msg.prototype.TYPE_STOP = 2; /**< Message marks the end of a simulation case */
Msg.prototype.ENDIAN_LITTLE = 0; /**< Message values are in little endian format (float too!) */
Msg.prototype.ENDIAN_BIG = 1; /**< Message values are in bit endian format */
/* Some offsets in the binary message */
Msg.prototype.OFFSET_ENDIAN = 1;
Msg.prototype.OFFSET_TYPE = 2;
Msg.prototype.OFFSET_VERSION = 4;
Msg.prototype.values = function() {
return this.values * 4 + 16;
} }
Msg.prototype.toArrayBuffer = function() { Msg.prototype.toArrayBuffer = function() {
var blob = new ArrayBuffer(this.length()); var blob = new ArrayBuffer(this.values());
return blob; return blob;
} }
Msg.prototype.fromArrayBuffer = function(blob) { Msg.fromArrayBuffer = function(data) {
var hdr = new UInt32Array(blob, 0, 16); var bits = data.getUint8(0);
var hdr16 = new UInt16Array(blob, 0, 16); var endian = (bits >> Msg.OFFSET_ENDIAN) & 0x1 ? 0 : 1;
var msg = new Msg({ var msg = new Msg({
endian: (hdr[0] >> MSG_OFFSET_ENDIAN) & 0x1, endian: (bits >> Msg.OFFSET_ENDIAN) & 0x1,
version: (hdr[0] >> MSG_OFFSET_VERSION) & 0xF, version: (bits >> Msg.OFFSET_VERSION) & 0xF,
type: (hdr[0] >> MSG_OFFSET_TYPE) & 0x3, type: (bits >> Msg.OFFSET_TYPE) & 0x3,
length: hdr16[1], values: data.getUint16(0x02, endian),
sequence: hdr[1], sequence: data.getUint32(0x04, endian),
timestamp: 1e3 * (hdr[2] + hdr[3]), // in milliseconds timestamp: data.getUint32(0x08, endian) * 1e3 +
blob : blob data.getUint32(0x0C, endian) * 1e-6,
}); });
msg.blob = new DataView( data.buffer, data.byteOffset + 0x00, (msg.values + 4) * 4);
msg.data = new Float32Array(data.buffer, data.byteOffset + 0x10, msg.values);
if (msg.endian == MSG_ENDIAN_BIG) { if (msg.endian != host_endianess()) {
console.warn("Unsupported endianness. Skipping message!"); console.warn("Message is not given in host endianess!");
continue;
/* @todo not working yet var data = new Uint32Array(msg.blob, 0x10);
hdr = hdr.map(swap32); for (var i = 0; i < data.length; i++)
values = values.map(swap32); data[i] = swap32(data[i]);
*/
} }
return msg;
msg.values = new Float32Array(msg, offset + 16, length * 4); // values reinterpreted as floats with 16byte offset in msg
} }
Msg.prototype.fromArrayBufferVector = function(blob) { Msg.fromArrayBufferVector = function(blob) {
/* some local variables for parsing */ /* some local variables for parsing */
var offset = 0; var offset = 0;
var msgs = []; var msgs = [];
/* for every msg in vector */ /* for every msg in vector */
while (offset < msg.byteLength) { while (offset < blob.byteLength) {
var msg = Msg.fromArrayBuffer(ArrayBuffer(blob, offset)); var msg = Msg.fromArrayBuffer(new DataView(blob, offset));
if (msg != undefined) if (msg != undefined) {
msgs.push(msg); msgs.push(msg);
offset += msg.blobLength; offset += msg.blob.byteLength;
}
} }
return msgs; return msgs;
@ -105,4 +105,10 @@ function swap32(val) {
| ((val >> 24) & 0xFF); | ((val >> 24) & 0xFF);
} }
function host_endianess() {
var buffer = new ArrayBuffer(2);
new DataView(buffer).setInt16(0, 256, true /* littleEndian */);
return new Int16Array(buffer)[0] === 256 ? 0 : 1; // Int16Array uses the platform's endianness.
};
/** @} */ /** @} */