forked from bartbutenaers/node-red-contrib-msg-speed
-
Notifications
You must be signed in to change notification settings - Fork 0
/
msg_speed.js
119 lines (98 loc) · 4.77 KB
/
msg_speed.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/**
* Copyright 2017 Bart Butenaers
*
* 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:https://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.
**/
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;
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.floor((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);
//console.log("node.msgCount = " + node.msgCount + " and node.totalMsgCount = " + node.totalMsgCount );
node.circularBuffer.enq(node.msgCount);
// Update the status in the editor 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.prevTotalMsgCount = node.totalMsgCount;
}
node.send({ payload: node.totalMsgCount, frequency: node.frequency });
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;
//console.log("New msg arrived. node.msgCount = " + node.msgCount );
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() {
//console.log("Timer called. node.msgCount = " + node.msgCount );
// Seems no msg has arrived during the last second, so register a zero count
analyse();
}, 1000);
});
}
RED.nodes.registerType("msg-speed", speed);
};