mirror of
https://github.com/node-red/node-red-nodes.git
synced 2023-10-10 13:36:58 +02:00
add greater and greater or equal modes to RBE bandgap mode
This commit is contained in:
parent
fc249b6792
commit
774bc50589
@ -11,8 +11,10 @@
|
|||||||
},
|
},
|
||||||
"opts": {
|
"opts": {
|
||||||
"rbe": "block unless value changes",
|
"rbe": "block unless value changes",
|
||||||
"deadband": "block unless value changes by more than",
|
"deadband": "block unless value change is greater than",
|
||||||
"narrowband": "block if value changes by more than",
|
"deadbandEq": "block unless value change is greater or equal to",
|
||||||
|
"narrowband": "block if value change is greater than",
|
||||||
|
"narrowbandEq": "block if value change is greater or equal to",
|
||||||
"in": "compared to last input value",
|
"in": "compared to last input value",
|
||||||
"out": "compared to last valid output value"
|
"out": "compared to last valid output value"
|
||||||
},
|
},
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name" : "node-red-node-rbe",
|
"name" : "node-red-node-rbe",
|
||||||
"version" : "0.1.6",
|
"version" : "0.1.8",
|
||||||
"description" : "A Node-RED node that provides report-by-exception (RBE) and deadband capability.",
|
"description" : "A Node-RED node that provides report-by-exception (RBE) and deadband capability.",
|
||||||
"dependencies" : {
|
"dependencies" : {
|
||||||
},
|
},
|
||||||
|
@ -4,14 +4,16 @@
|
|||||||
<label for="node-input-func"><i class="fa fa-wrench"></i> <span data-i18n="rbe.label.func"></span></label>
|
<label for="node-input-func"><i class="fa fa-wrench"></i> <span data-i18n="rbe.label.func"></span></label>
|
||||||
<select type="text" id="node-input-func" style="width:74%;">
|
<select type="text" id="node-input-func" style="width:74%;">
|
||||||
<option value="rbe" data-i18n="rbe.opts.rbe"></option>
|
<option value="rbe" data-i18n="rbe.opts.rbe"></option>
|
||||||
|
<option value="deadbandEq" data-i18n="rbe.opts.deadbandEq"></option>
|
||||||
<option value="deadband" data-i18n="rbe.opts.deadband"></option>
|
<option value="deadband" data-i18n="rbe.opts.deadband"></option>
|
||||||
|
<option value="narrowbandEq" data-i18n="rbe.opts.narrowbandEq"></option>
|
||||||
<option value="narrowband" data-i18n="rbe.opts.narrowband"></option>
|
<option value="narrowband" data-i18n="rbe.opts.narrowband"></option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row" id="node-bandgap">
|
<div class="form-row" id="node-bandgap">
|
||||||
<label for="node-input-gap"> </label>
|
<label for="node-input-gap"> </label>
|
||||||
<input type="text" id="node-input-gap" data-i18n="[placeholder]rbe.placeholder.bandgap" style="width:70px;">
|
<input type="text" id="node-input-gap" data-i18n="[placeholder]rbe.placeholder.bandgap" style="width:95px;">
|
||||||
<select type="text" id="node-input-inout" style="width:55%;">
|
<select type="text" id="node-input-inout" style="width:54%;">
|
||||||
<option value="out" data-i18n="rbe.opts.out"></option>
|
<option value="out" data-i18n="rbe.opts.out"></option>
|
||||||
<option value="in" data-i18n="rbe.opts.in"></option>
|
<option value="in" data-i18n="rbe.opts.in"></option>
|
||||||
</select>
|
</select>
|
||||||
@ -27,21 +29,38 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script type="text/x-red" data-help-name="rbe">
|
<script type="text/x-red" data-help-name="rbe">
|
||||||
<p>Report by Exception node - only passes on data if it has changed.</p>
|
<p>Report by Exception node - only passes on data if the payload has changed.</p>
|
||||||
<p>The node can either block until the <code>msg.payload</code> is
|
<p>It can also block until the value changes by a specified amount - deadband modes.</p>
|
||||||
different to the previous one - <b>rbe</b> mode. This works on numbers, strings, and simple objects.</p>
|
<h3>Inputs</h3>
|
||||||
<p>Or it can block until the value changes by a specified amount - <b>deadband</b> mode.</p>
|
<dl class="message-properties">
|
||||||
<p>In deadband mode the incoming payload must contain a parseable <i>number</i> and is
|
<dt>payload
|
||||||
output only if greater than + or - the <i>band gap</i> away from a previous value.</p>
|
<span class="property-type">number | string | (object)</span>
|
||||||
|
</dt>
|
||||||
|
<dd>RBE mode will accept numbers, strings, and simple objects. Other modes must provide a parseable number.</dd>
|
||||||
|
<dt class="optional">topic <span class="property-type">string</span>
|
||||||
|
</dt>
|
||||||
|
<dd>if specified the function will work on a per topic basis.</dd>
|
||||||
|
</dl>
|
||||||
|
<h3>Outputs</h3>
|
||||||
|
<dl class="message-properties">
|
||||||
|
<dt>payload
|
||||||
|
<span class="property-type">as per input</span>
|
||||||
|
</dt>
|
||||||
|
<dd>If triggered the output will be the same as the input.</dd>
|
||||||
|
</dl>
|
||||||
|
<h3>Details</h3>
|
||||||
|
<p>In RBE mode this node will block until the <code>msg.payload</code> is
|
||||||
|
different to the previous one. </p>
|
||||||
|
<p>In Deadband modes the incoming payload must contain a parseable number and is
|
||||||
|
output only if greater than + or - the band gap 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>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
|
||||||
<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>
|
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
|
<p>Both Deadband and Narrowband allow comparison against either the previous valid output value, thus
|
||||||
ignoring any values out of range; or the <i>previous input value</i>, which resets the set point, thus allowing
|
ignoring any values out of range; or the previous input value, which resets the set point, thus allowing
|
||||||
gradual drift (deadband), or a step change (narrowband).</p>
|
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
|
<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>
|
handle multiple different topics at the same time.</p>
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
@ -59,7 +78,8 @@
|
|||||||
outputs:1,
|
outputs:1,
|
||||||
icon: "rbe.png",
|
icon: "rbe.png",
|
||||||
label: function() {
|
label: function() {
|
||||||
return this.name||this.func||"rbe";
|
var ll = (this.func||"").replace("Eq","")||"rbe";
|
||||||
|
return this.name||ll||"rbe";
|
||||||
},
|
},
|
||||||
labelStyle: function() {
|
labelStyle: function() {
|
||||||
return this.name?"node_label_italic":"";
|
return this.name?"node_label_italic":"";
|
||||||
|
@ -42,15 +42,23 @@ module.exports = function(RED) {
|
|||||||
else { node.previous[t] = node.start; }
|
else { node.previous[t] = node.start; }
|
||||||
}
|
}
|
||||||
if (node.pc) { node.gap = (node.previous[t] * node.g / 100) || 0; }
|
if (node.pc) { node.gap = (node.previous[t] * node.g / 100) || 0; }
|
||||||
if (!node.previous.hasOwnProperty(t)) { node.previous[t] = n - node.gap; }
|
else { node.gap = Number(node.gap); }
|
||||||
if (Math.abs(n - node.previous[t]) >= node.gap) {
|
if ((node.previous[t] === undefined) && (node.func === "narrowbandEq")) { node.previous[t] = n; }
|
||||||
|
if (node.previous[t] === undefined) { node.previous[t] = n - node.gap; }
|
||||||
|
if (Math.abs(n - node.previous[t]) === node.gap) {
|
||||||
|
if (this.func === "deadbandEq") {
|
||||||
|
if (node.inout === "out") { node.previous[t] = n; }
|
||||||
|
node.send(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (Math.abs(n - node.previous[t]) > node.gap) {
|
||||||
if (this.func === "deadband") {
|
if (this.func === "deadband") {
|
||||||
if (node.inout === "out") { node.previous[t] = n; }
|
if (node.inout === "out") { node.previous[t] = n; }
|
||||||
node.send(msg);
|
node.send(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else if (Math.abs(n - node.previous[t]) < node.gap) {
|
||||||
if (this.func === "narrowband") {
|
if ((this.func === "narrowband")||(this.func === "narrowbandEq")) {
|
||||||
if (node.inout === "out") { node.previous[t] = n; }
|
if (node.inout === "out") { node.previous[t] = n; }
|
||||||
node.send(msg);
|
node.send(msg);
|
||||||
}
|
}
|
||||||
|
@ -62,6 +62,37 @@ describe('rbe node', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should only send output if x away from original value (deadbandEq)', function(done) {
|
||||||
|
var flow = [{"id":"n1", "type":"rbe", func:"deadbandEq", gap:"10", inout:"out", 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) {
|
||||||
|
c = c + 1;
|
||||||
|
if (c === 1) {
|
||||||
|
msg.should.have.a.property("payload", 0);
|
||||||
|
}
|
||||||
|
else if (c === 2) {
|
||||||
|
msg.should.have.a.property("payload", 10);
|
||||||
|
}
|
||||||
|
else if (c == 3) {
|
||||||
|
msg.should.have.a.property("payload", 20);
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
n1.emit("input", {payload:0});
|
||||||
|
n1.emit("input", {payload:2});
|
||||||
|
n1.emit("input", {payload:4});
|
||||||
|
n1.emit("input", {payload:6});
|
||||||
|
n1.emit("input", {payload:8});
|
||||||
|
n1.emit("input", {payload:10});
|
||||||
|
n1.emit("input", {payload:15});
|
||||||
|
n1.emit("input", {payload:20});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should only send output if more than x away from original value (deadband)', function(done) {
|
it('should only send output if more than x away from original value (deadband)', function(done) {
|
||||||
var flow = [{"id":"n1", "type":"rbe", func:"deadband", gap:"10", wires:[["n2"]] },
|
var flow = [{"id":"n1", "type":"rbe", func:"deadband", gap:"10", wires:[["n2"]] },
|
||||||
{id:"n2", type:"helper"} ];
|
{id:"n2", type:"helper"} ];
|
||||||
@ -70,17 +101,18 @@ describe('rbe node', function() {
|
|||||||
var n2 = helper.getNode("n2");
|
var n2 = helper.getNode("n2");
|
||||||
var c = 0;
|
var c = 0;
|
||||||
n2.on("input", function(msg) {
|
n2.on("input", function(msg) {
|
||||||
if (c === 0) {
|
c = c + 1;
|
||||||
|
//console.log(c,msg);
|
||||||
|
if (c === 1) {
|
||||||
msg.should.have.a.property("payload", 0);
|
msg.should.have.a.property("payload", 0);
|
||||||
}
|
}
|
||||||
else if (c === 1) {
|
else if (c === 2) {
|
||||||
msg.should.have.a.property("payload", 20);
|
msg.should.have.a.property("payload", 20);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
msg.should.have.a.property("payload", "5 deg");
|
msg.should.have.a.property("payload", "5 deg");
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
c += 1;
|
|
||||||
});
|
});
|
||||||
n1.emit("input", {payload:0});
|
n1.emit("input", {payload:0});
|
||||||
n1.emit("input", {payload:2});
|
n1.emit("input", {payload:2});
|
||||||
@ -101,24 +133,21 @@ describe('rbe node', function() {
|
|||||||
var n2 = helper.getNode("n2");
|
var n2 = helper.getNode("n2");
|
||||||
var c = 0;
|
var c = 0;
|
||||||
n2.on("input", function(msg) {
|
n2.on("input", function(msg) {
|
||||||
if (c === 0) {
|
c = c + 1;
|
||||||
msg.should.have.a.property("payload", 100);
|
if (c === 1) {
|
||||||
}
|
|
||||||
else if (c === 1) {
|
|
||||||
msg.should.have.a.property("payload", 120);
|
msg.should.have.a.property("payload", 120);
|
||||||
}
|
}
|
||||||
else {
|
else if (c === 2) {
|
||||||
msg.should.have.a.property("payload", 132);
|
msg.should.have.a.property("payload", 135);
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
c += 1;
|
|
||||||
});
|
});
|
||||||
n1.emit("input", {payload:100});
|
n1.emit("input", {payload:100});
|
||||||
n1.emit("input", {payload:95});
|
n1.emit("input", {payload:95});
|
||||||
n1.emit("input", {payload:105});
|
n1.emit("input", {payload:105});
|
||||||
n1.emit("input", {payload:120});
|
n1.emit("input", {payload:120});
|
||||||
n1.emit("input", {payload:130});
|
n1.emit("input", {payload:130});
|
||||||
n1.emit("input", {payload:132});
|
n1.emit("input", {payload:135});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -150,6 +179,36 @@ describe('rbe node', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should not send output if x away or greater from original value (narrowbandEq)', function(done) {
|
||||||
|
var flow = [{"id":"n1", "type":"rbe", func:"narrowbandEq", gap:"10", inout:"out", 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) {
|
||||||
|
c = c + 1;
|
||||||
|
//console.log(c,msg);
|
||||||
|
if (c === 1) {
|
||||||
|
msg.should.have.a.property("payload", 0);
|
||||||
|
}
|
||||||
|
else if (c === 2) {
|
||||||
|
msg.should.have.a.property("payload", 5);
|
||||||
|
}
|
||||||
|
else if (c === 3) {
|
||||||
|
msg.should.have.a.property("payload", 10);
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
n1.emit("input", {payload:0});
|
||||||
|
n1.emit("input", {payload:10});
|
||||||
|
n1.emit("input", {payload:5});
|
||||||
|
n1.emit("input", {payload:15});
|
||||||
|
n1.emit("input", {payload:10});
|
||||||
|
n1.emit("input", {payload:20});
|
||||||
|
n1.emit("input", {payload:25});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should not send output if more than x away from original value (narrowband)', function(done) {
|
it('should not send output if more than x away from original value (narrowband)', function(done) {
|
||||||
var flow = [{"id":"n1", "type":"rbe", func:"narrowband", gap:"10", wires:[["n2"]] },
|
var flow = [{"id":"n1", "type":"rbe", func:"narrowband", gap:"10", wires:[["n2"]] },
|
||||||
@ -205,5 +264,4 @@ describe('rbe node', function() {
|
|||||||
n1.emit("input", {payload:205});
|
n1.emit("input", {payload:205});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user