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:
parent
51fe428809
commit
1f20c937d5
3 changed files with 92 additions and 73 deletions
|
@ -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]]);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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.
|
||||||
|
};
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
Loading…
Add table
Reference in a new issue