diff --git a/doc/example5.png b/doc/example5.png new file mode 100644 index 0000000..f6b0b62 Binary files /dev/null and b/doc/example5.png differ diff --git a/readme.md b/readme.md index 87674a8..62ccf0b 100644 --- a/readme.md +++ b/readme.md @@ -13,11 +13,13 @@ A Node-RED node to throttle down * [Install](#install) * [Usage](#usage) * [By Time](#by-time) + * [By Period](#by-period) * [By Count](#by-count) * [By Block Size](#by-block-size) * [By Reset](#by-reset) * [Example Flows](#example-flows) * [Example by Time](#example-by-time) + * [Example by Period](#example-by-period) * [Example by Count](#example-by-count) * [Example by Block Size](#example-by-block-size) * [Example by Reset](#example-by-reset) @@ -49,6 +51,12 @@ Limits the passed through messages by a given amount of time. **For example:** setting the node to `10 seconds` means, that only one message in ten seconds will be forwarded. +### By Period + +Limits the passed through messages by a given period of time. +**For example:** setting the node to `10 seconds` means, that all messages in the first ten seconds will be forwarded. + + ### By Count Limits the passed through messages by a given count. @@ -81,6 +89,15 @@ Simple examples showing how to use the throttle and it's output. ``` +### Example by Period + +![example5.png](./doc/example5.png) + +```JSON +[{"id":"8383dfd6.38029","type":"function","z":"6253524.ae0e9ac","name":"info msg","func":"msg.payload = \"injected\";\nreturn msg;","outputs":1,"noerr":0,"x":508.0994567871094,"y":194.09091186523438,"wires":[["dde88359.a1484"]]},{"id":"aa17d47e.ca3ae8","type":"throttle","z":"6253524.ae0e9ac","name":"","throttleType":"period","timeLimit":"10","timeLimitType":"seconds","periodLimit":"10","periodLimitType":"seconds","countLimit":"3","blockSize":"3","locked":false,"resend":false,"x":508.0994567871094,"y":234.09091186523438,"wires":[["dde88359.a1484"]]},{"id":"87dc94db.139918","type":"inject","z":"6253524.ae0e9ac","name":"inject","topic":"","payload":"!!! PASSED THROUGH !!!","payloadType":"str","repeat":"","crontab":"","once":false,"x":198.09945678710938,"y":214.09091186523438,"wires":[["aa17d47e.ca3ae8","8383dfd6.38029"]]},{"id":"8fbc58ea.3a7da8","type":"inject","z":"6253524.ae0e9ac","name":"reset","topic":"","payload":"reset","payloadType":"str","repeat":"","crontab":"","once":false,"x":198.09945678710938,"y":274.0909118652344,"wires":[["a3b2c4d0.c76688"]]},{"id":"a3b2c4d0.c76688","type":"function","z":"6253524.ae0e9ac","name":"reset msg","func":"msg.reset = true;\nreturn msg;","outputs":1,"noerr":0,"x":328.0994567871094,"y":274.0909118652344,"wires":[["aa17d47e.ca3ae8","dde88359.a1484"]]},{"id":"dde88359.a1484","type":"debug","z":"6253524.ae0e9ac","name":"output","active":true,"console":"false","complete":"payload","x":678.0994567871094,"y":274.0909118652344,"wires":[]}] +``` + + ### Example by Count ![example2.png](./doc/example2.png) @@ -121,4 +138,4 @@ _You like to support me?_ _You appreciate my work?_ _You use it in commercial projects?_ -Feel free to make a little [donation](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=FFL6VQJCUZMXC)! :wink: \ No newline at end of file +Feel free to make a little [donation](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=FFL6VQJCUZMXC)! :wink: diff --git a/throttle.html b/throttle.html index 39ea868..c007f65 100644 --- a/throttle.html +++ b/throttle.html @@ -7,6 +7,7 @@ + +
+ + + +
\ No newline at end of file diff --git a/throttle.js b/throttle.js index 6755323..91b2859 100644 --- a/throttle.js +++ b/throttle.js @@ -10,28 +10,50 @@ module.exports = function(RED) { this.throttleType = config.throttleType || "time"; this.timeLimitType = config.timeLimitType || "seconds"; this.timeLimit = Number(config.timeLimit || 0); + this.periodLimitType = config.periodLimitType || "seconds"; + this.periodLimit = Number(config.periodLimit || 0); this.countLimit = Number(config.countLimit || 0); this.blockSize = Number(config.blockSize || 0); this.locked = config.locked || false; - - // helpers - this.time = this.locked ? Math.floor(Date.now()) : 0; - this.count = this.locked ? 1 : 0; - this.block = this.locked ? this.blockSize + 1 : 0; - this.reset = !!this.locked; - - // calculate time limit in milliseconds - if( this.timeLimitType === "hours" ) { - this.timeLimit *= 60 * 60 * 1000; - } - else if( this.timeLimitType === "minutes" ) { - this.timeLimit *= 60 * 1000; + this.resend = config.resend || false; + + function initialize(locked, node) { + node.time = locked ? Math.floor(Date.now()) : 0; + node.period = locked ? 0 : Math.floor(Date.now()); + node.count = locked ? 1 : 0; + node.block = locked ? node.blockSize + 1 : 0; + node.reset = !!locked; } - else if( this.timeLimitType === "seconds" ) { - this.timeLimit *= 1000; + + // Initialize the current status, based on the 'locked' property + initialize(this.locked, this); + + // calculate limit in milliseconds + function getMilliSeconds(limitType, limit) { + if( limitType === "hours" ) { + return limit * 60 * 60 * 1000; + } + else if( limitType === "minutes" ) { + return limit * 60 * 1000; + } + else if( limitType === "seconds" ) { + return limit * 1000; + } } + + this.timeLimit = getMilliSeconds(this.timeLimitType, this.timeLimit); + this.periodLimit = getMilliSeconds(this.periodLimitType, this.periodLimit); this.on("input", function(msg) { + if( msg.reset) { + initialize(false, node); + + if( node.resend !== true) { + // When a 'reset' message shouldn't be resended (on the output port), just skip it ... + return; + } + } + // throttle by time if( node.throttleType === "time" ) { if( isNaN(node.timeLimit) || !isFinite(node.timeLimit) ) { @@ -45,6 +67,19 @@ module.exports = function(RED) { node.send(msg); } } + + // throttle by period + else if( node.throttleType === "period" ) { + if( isNaN(node.periodLimit) || !isFinite(node.periodLimit) ) { + return this.error("period limit is not numeric", msg); + } + + var now = Math.floor(Date.now()); + + if( node.period + node.periodLimit > now ) { + node.send(msg); + } + } // throttle by count else if( node.throttleType === "count" ) { @@ -74,9 +109,6 @@ module.exports = function(RED) { if( node.block <= node.blockSize ) { node.send(msg); } - else if( msg.reset ) { - node.block = 0; - } } // throttle by reset @@ -85,11 +117,7 @@ module.exports = function(RED) { node.reset = true; node.send(msg); } - else if( msg.reset ) { - node.reset = false; - } } - // unknown throttle type else { this.error("unknown throttle type '" + node.throttleType + "'", msg);