Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
bartbutenaers committed Feb 27, 2017
1 parent d5d6b45 commit 9e29030
Show file tree
Hide file tree
Showing 4 changed files with 170 additions and 0 deletions.
Binary file added icons/speed.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
41 changes: 41 additions & 0 deletions msg_speed.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<script type="text/x-red" data-template-name="msg-speed">
<div class="form-row">
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
<input type="text" id="node-input-name" placeholder="Name">
</div>
<div class="form-row">
<label for="node-input-frequency"><i class="fa fa-random"></i> Frequency</label>
<select id="node-input-frequency">
<option value="sec">Second</option>
<option value="min">Minute</option>
<option value="min">Hour</option>
<option value="min">Day</option>
</select>
</div>
</script>

<script type="text/x-red" data-help-name="msg-speed">
<p>A node to measure the flow message speed.</p>
<p>The speed will be measured at the specified frequency.</p>
<p>E.g. frequency 'hour' means that (every second) the average speed of the previous hour will be calculated.</p>
</script>

<script type="text/javascript">
RED.nodes.registerType("msg-speed", {
category: "performance",
defaults: {
name: {value:""},
frequency: {value:"sec"},
},
color:"#e2d96e",
inputs: 1,
outputs: 1,
icon: "speed.png",
label: function() {
return this.name || "msg-speed";
},
labelStyle: function() {
return this.name ? "node_label_italic" : "";
},
});
</script>
102 changes: 102 additions & 0 deletions msg_speed.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
module.exports = function(RED) {
"use strict";
var CircularBuffer = require("circular-buffer");
var Math = require("mathjs");

function speed(config) {
RED.nodes.createNode(this, config);

// The buffer size depends on the frequency
switch(config.frequency) {
case 'sec':
this.bufferSize = 1;
break;
case 'min':
this.bufferSize = 60;
break;
case 'hour':
this.bufferSize = 60 * 60;
break;
case 'day':
this.bufferSize = 24 * 60 * 60;
break;
default:
this.bufferSize = 1; // Default 'sec'
}

this.circularBuffer = new CircularBuffer(this.bufferSize);

// Fill the buffer with zeros
for (var i = 0; i < this.bufferSize; i++) {
this.circularBuffer.enq(0);
}

this.frequency = config.frequency || 'sec';
this.msgCount = 0;
this.prevTotalMsgCount = 0;
this.totalMsgCount = 0;
this.startTime = null;
this.timer = null;

var analyse = function() {
var currentTime = new Date().getTime();

if (node.startTime == null) {
node.startTime = currentTime;
}

// Store the message count (of the previous second) in the circular buffer. However the timer can be
// delayed, so make sure this is done for EVERY second since the last time we got here ...
var seconds = Math.round((currentTime - node.startTime) / 1000);
for(var i = 0; i < seconds; i++) {
// The total msg count is the sum of all message counts in the circular buffer. Instead of summing
// those continiously, we will update the sum together with the buffer content.
// Sum = previous sum + message count of last second (which is going to be added to the buffer)
// - message count of the first second (which is going to be removed from the buffer).
node.totalMsgCount += node.msgCount;
node.totalMsgCount -= node.circularBuffer.get(node.bufferSize-1);

node.circularBuffer.enq(node.msgCount);

// Update the status with the last message count (only if it has changed)
if (node.prevTotalMsgCount != node.totalMsgCount) {
node.status({fill:"green",shape:"dot",text:" " + node.totalMsgCount + "/" + node.frequency });
node.send({ payload: node.totalMsgCount, frequency: node.frequency });
node.prevTotalMsgCount = node.totalMsgCount;
}

if (RED.settings.verbose) {
console.log(new Date().toISOString() + " " + node.totalMsgCount);
}

// Start counting all over again (for the next seconds)
node.msgCount = 0;
node.startTime = currentTime;
}
}

var node = this;

// Initially display a 0 count
node.status({fill:"green",shape:"dot",text:" " + node.msgCount + "/" + node.frequency });

this.on("input", function(msg) {
if (node.timer) {
// An msg has arrived during the specified (timeout) interval, so remove the (timeout) timer.
clearInterval(node.timer);
}

node.msgCount += 1;

analyse();

// Register a new timer (with a timeout interval of 1 second), in case no msg should arrive during the next second.
node.timer = setInterval(function() {
// Seems no msg has arrived during the last second, so register a zero count
analyse();
}, 1000);
});
}

RED.nodes.registerType("msg-speed", speed);
};
27 changes: 27 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name" : "node-red-contrib-msg-speed",
"version" : "0.0.1",
"description" : "A Node Red node to measure the flow message speed",
"dependencies": {
"circular-buffer": "1.0.2",
"mathjs": "3.9.3"
},
"author": {
"name": "Bart Butenaers"
},
"license": "Apache-2.0",
"keywords": [ "node-red", "speed", "rate", "count" ],
"bugs": {
"url": "https://github.com/bartbutenaers/node-red-contrib-msg-speed/issues"
},
"homepage": "https://github.com/bartbutenaers/node-red-contrib-msg-speed",
"repository": {
"type": "git",
"url": "https://github.com/bartbutenaers/node-red-contrib-msg-speed.git"
},
"node-red" : {
"nodes": {
"msg-speed": "msg_speed.js"
}
}
}

0 comments on commit 9e29030

Please sign in to comment.