1
0
mirror of https://github.com/node-red/node-red-nodes.git synced 2023-10-10 13:36:58 +02:00

Let rbe node compare to previous input OR output

closes #192 and #193
Also update info and test.
This commit is contained in:
Dave Conway-Jones 2016-03-21 00:01:50 +00:00
parent 2ed8e5a306
commit c3a8a4088d
6 changed files with 52 additions and 8 deletions

View File

@ -36,7 +36,12 @@ same value. Saves bandwidth, etc...
In deadband mode the incoming payload should contain a parseable *number* and is
output only if greater than + or - the *band gap* away from the previous output.
It can also be set to block values more than a certain distance away from the present value.
This can be used to remove outliers or unexpected readings.
This can be used to remove outliers or unexpected readings.
You can specify compare with *previous valid output value* or *previous input value*.
The former ignores any values outside the valid range, whereas the latter allows
two "bad" readings in a row to reset the range based on those values.
For example a valid step change.
The deadband value can be specified as a fixed number, or a percentage. E.g. 10
or 5% . If % mode is used then the output will only get sent if the input payload

View File

@ -12,7 +12,9 @@
"opts": {
"rbe": "block unless value changes",
"deadband": "block unless value changes by more than",
"narrowband": "block if value changes by more than"
"narrowband": "block if value changes by more than",
"in": "compared to last input value",
"out": "compared to last valid output value"
},
"warn": {
"nonumber": "no number found in payload"

View File

@ -1,6 +1,6 @@
{
"name" : "node-red-node-rbe",
"version" : "0.1.4",
"version" : "0.1.5",
"description" : "A Node-RED node that provides report-by-exception (RBE) and deadband capability.",
"dependencies" : {
},

View File

@ -25,7 +25,11 @@
</div>
<div class="form-row" id="node-bandgap">
<label for="node-input-gap">&nbsp;</label>
<input type="text" id="node-input-gap" data-i18n="[placeholder]rbe.placeholder.bandgap" style="width:71%;">
<input type="text" id="node-input-gap" data-i18n="[placeholder]rbe.placeholder.bandgap" style="width:70px;">
<select type="text" id="node-input-inout" style="width:55%;">
<option value="out" data-i18n="rbe.opts.out"></option>
<option value="in" data-i18n="rbe.opts.in"></option>
</select>
</div>
<div class="form-row" id="node-startvalue">
<label for="node-input-start"><i class="fa fa-thumb-tack"/> <span data-i18n="rbe.label.start"></span></label>
@ -43,11 +47,14 @@
different to the previous one - <b>rbe</b> mode. This works on numbers, strings, and simple objects.</p>
<p>Or it can block until the value changes by a specified amount - <b>deadband</b> mode.</p>
<p>In deadband mode the incoming payload must contain a parseable <i>number</i> and is
output only if greater than + or - the <i>band gap</i> away from the previous output.</p>
output only if greater than + or - the <i>band gap</i> away from a previous value.</p>
<p>Deadband also supports % - only sends if the input differs by more than x% of the original value.</p>
<p>It can also ignore outlier values - <b>narrowband</b> mode.</p>
<p>In narrowband mode the incoming payload is blocked if it is more than + or - the band gap
away from the previous value. Useful for ignoring outliers from a faulty sensor for example.</p>
<p>Both Deadband and Narrowband allow comparison against either the <i>previous valid output value</i>, thus
ignoring any values out of range; or the <i>previous input value</i>, which resets the set point, thus allowing
gradual drift (deadband), or a step change (narrowband).</p>
<p><b>Note:</b> This works on a per <code>msg.topic</code> basis. This means that a single rbe node can
handle multiple topics at the same time.</p>
</script>
@ -60,7 +67,8 @@
name: {value:""},
func: {value:"rbe"},
gap: {value:"",validate:RED.validators.regex(/^(\d*[.]*\d*|)(%|)$/)},
start: {value:""}
start: {value:""},
inout: {value:"out"}
},
inputs:1,
outputs:1,
@ -73,6 +81,9 @@
},
oneditprepare: function() {
//$( "#node-input-gap" ).spinner({min:0});
if ($("#node-input-inout").val() === null) {
$("#node-input-inout").val("out");
}
$("#node-input-func").on("change",function() {
if ($("#node-input-func").val() === "rbe") {
$("#node-bandgap").hide();

View File

@ -21,6 +21,7 @@ module.exports = function(RED) {
this.func = n.func || "rbe";
this.gap = n.gap || "0";
this.start = n.start || '';
this.inout = n.inout || "out";
this.pc = false;
if (this.gap.substr(-1) === "%") {
this.pc = true;
@ -59,16 +60,17 @@ module.exports = function(RED) {
if (!node.previous.hasOwnProperty(t)) { node.previous[t] = n - node.gap; }
if (Math.abs(n - node.previous[t]) >= node.gap) {
if (this.func === "deadband") {
node.previous[t] = n;
if (node.inout === "out") { node.previous[t] = n; }
node.send(msg);
}
}
else {
if (this.func === "narrowband") {
node.previous[t] = n;
if (node.inout === "out") { node.previous[t] = n; }
node.send(msg);
}
}
if (node.inout === "in") { node.previous[t] = n; }
}
else {
node.warn(RED._("rbe.warn.nonumber"));

View File

@ -197,4 +197,28 @@ describe('rbe node', function() {
});
});
it('should not send output if more than x away from original value (narrowband in step mode)', function(done) {
var flow = [{"id":"n1", "type":"rbe", func:"narrowband", gap:"10", inout:"in", start:"500", wires:[["n2"]] },
{id:"n2", type:"helper"} ];
helper.load(testNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
var c = 0;
n2.on("input", function(msg) {
if (c === 0) {
msg.should.have.a.property("payload", 55);
}
else if (c === 1) {
msg.should.have.a.property("payload", 205);
done();
}
c += 1;
});
n1.emit("input", {payload:50});
n1.emit("input", {payload:55});
n1.emit("input", {payload:200});
n1.emit("input", {payload:205});
});
});
});