mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
Merge pull request #2944 from node-red/Pull-in-RBE-and-push-out-tail
v2: Pull in RBE node and push out tail
This commit is contained in:
commit
68fef169f3
@ -60,9 +60,6 @@
|
|||||||
"multer": "1.4.2",
|
"multer": "1.4.2",
|
||||||
"mustache": "4.2.0",
|
"mustache": "4.2.0",
|
||||||
"node-red-admin": "^0.2.6",
|
"node-red-admin": "^0.2.6",
|
||||||
"node-red-node-rbe": "^0.5.0",
|
|
||||||
"node-red-node-sentiment": "^0.1.6",
|
|
||||||
"node-red-node-tail": "^0.3.0",
|
|
||||||
"nopt": "5.0.0",
|
"nopt": "5.0.0",
|
||||||
"oauth2orize": "1.11.0",
|
"oauth2orize": "1.11.0",
|
||||||
"on-headers": "1.0.2",
|
"on-headers": "1.0.2",
|
||||||
|
@ -233,7 +233,7 @@ RED.sidebar.help = (function() {
|
|||||||
var div = $('<div>',{class:"red-ui-info-outline-item"});
|
var div = $('<div>',{class:"red-ui-info-outline-item"});
|
||||||
RED.utils.createNodeIcon(n).appendTo(div);
|
RED.utils.createNodeIcon(n).appendTo(div);
|
||||||
var contentDiv = $('<div>',{class:"red-ui-search-result-description"}).appendTo(div);
|
var contentDiv = $('<div>',{class:"red-ui-search-result-description"}).appendTo(div);
|
||||||
$('<div>',{class:"red-ui-search-result-node-label red-ui-info-outline-item-label"}).text(n.name||n.type).appendTo(contentDiv);
|
$('<div>',{class:"red-ui-search-result-node-label red-ui-info-outline-item-label"}).text(n.name||n._def.paletteLabel||n.type).appendTo(contentDiv);
|
||||||
return div;
|
return div;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,7 +248,8 @@ RED.sidebar.help = (function() {
|
|||||||
title = subflowNode.name || nodeType;
|
title = subflowNode.name || nodeType;
|
||||||
} else {
|
} else {
|
||||||
helpText = RED.nodes.getNodeHelp(nodeType)||('<span class="red-ui-help-info-none">'+RED._("sidebar.info.none")+'</span>');
|
helpText = RED.nodes.getNodeHelp(nodeType)||('<span class="red-ui-help-info-none">'+RED._("sidebar.info.none")+'</span>');
|
||||||
title = nodeType;
|
var _def = RED.nodes.registry.getNodeType(nodeType);
|
||||||
|
title = (_def && _def.paletteLabel)?_def.paletteLabel:nodeType;
|
||||||
}
|
}
|
||||||
setInfoText(title, helpText, helpSection);
|
setInfoText(title, helpText, helpSection);
|
||||||
|
|
||||||
|
93
packages/node_modules/@node-red/nodes/core/function/rbe.html
vendored
Normal file
93
packages/node_modules/@node-red/nodes/core/function/rbe.html
vendored
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
|
||||||
|
<script type="text/html" data-template-name="rbe">
|
||||||
|
<div class="form-row">
|
||||||
|
<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:70%;">
|
||||||
|
<option value="rbe" data-i18n="rbe.opts.rbe"></option>
|
||||||
|
<option value="rbei" data-i18n="rbe.opts.rbei"></option>
|
||||||
|
<option value="deadbandEq" data-i18n="rbe.opts.deadbandEq"></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>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="form-row" id="node-bandgap">
|
||||||
|
<label for="node-input-gap"> </label>
|
||||||
|
<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:54%;">
|
||||||
|
<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"></i> <span data-i18n="rbe.label.start"></span></label>
|
||||||
|
<input type="text" id="node-input-start" data-i18n="[placeholder]rbe.placeholder.start" style="width:70%;">
|
||||||
|
</div>
|
||||||
|
<div class="form-row">
|
||||||
|
<label for="node-input-property"><i class="fa fa-ellipsis-h"></i> <span data-i18n="node-red:common.label.property"></span></label>
|
||||||
|
<input type="text" id="node-input-property" style="width:70%;"/>
|
||||||
|
</div>
|
||||||
|
<div class="form-row">
|
||||||
|
<label> </label>
|
||||||
|
<input type="checkbox" id="node-input-septopics" style="display:inline-block; width:20px; vertical-align:baseline;">
|
||||||
|
<span data-i18n="rbe.label.septopics"></span> <input type="text" id="node-input-topi" style="width:27%;"/>
|
||||||
|
</div>
|
||||||
|
<div class="form-row">
|
||||||
|
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="rbe.label.name"></span></label>
|
||||||
|
<input type="text" id="node-input-name" data-i18n="[placeholder]rbe.label.name" style="width:70%;">
|
||||||
|
</div>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
RED.nodes.registerType("rbe", {
|
||||||
|
color:"#E2D96E",
|
||||||
|
category: 'function',
|
||||||
|
defaults: {
|
||||||
|
name: {value:""},
|
||||||
|
func: {value:"rbe"},
|
||||||
|
gap: {value:"",validate:RED.validators.regex(/^(\d*[.]*\d*|)(%|)$/)},
|
||||||
|
start: {value:""},
|
||||||
|
inout: {value:"out"},
|
||||||
|
septopics: {value:true},
|
||||||
|
property: {value:"payload",required:true},
|
||||||
|
topi: {value:"topic",required:true}
|
||||||
|
},
|
||||||
|
inputs:1,
|
||||||
|
outputs:1,
|
||||||
|
icon: "rbe.png",
|
||||||
|
paletteLabel: "filter",
|
||||||
|
label: function() {
|
||||||
|
var ll = (this.func||"").replace("Eq","").replace("rbei",this._("rbe.rbe")).replace("rbe",this._("rbe.rbe"))||this._("rbe.rbe");
|
||||||
|
return this.name||ll||this._("rbe.rbe");
|
||||||
|
},
|
||||||
|
labelStyle: function() {
|
||||||
|
return this.name?"node_label_italic":"";
|
||||||
|
},
|
||||||
|
oneditprepare: function() {
|
||||||
|
if (this.property === undefined) {
|
||||||
|
$("#node-input-property").val("payload");
|
||||||
|
}
|
||||||
|
if (this.septopics === undefined) {
|
||||||
|
$("#node-input-septopics").prop('checked', true);
|
||||||
|
}
|
||||||
|
$("#node-input-property").typedInput({default:'msg',types:['msg']});
|
||||||
|
$("#node-input-topi").typedInput({default:'msg',types:['msg']});
|
||||||
|
//$( "#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-input-func").val() === "rbei")) {
|
||||||
|
$("#node-bandgap").hide();
|
||||||
|
} else {
|
||||||
|
$("#node-bandgap").show();
|
||||||
|
}
|
||||||
|
if (($("#node-input-func").val() === "narrowband")||($("#node-input-func").val() === "narrowbandEq")) {
|
||||||
|
$("#node-startvalue").show();
|
||||||
|
} else {
|
||||||
|
$("#node-startvalue").hide();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
97
packages/node_modules/@node-red/nodes/core/function/rbe.js
vendored
Normal file
97
packages/node_modules/@node-red/nodes/core/function/rbe.js
vendored
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
|
||||||
|
module.exports = function(RED) {
|
||||||
|
"use strict";
|
||||||
|
function RbeNode(n) {
|
||||||
|
RED.nodes.createNode(this,n);
|
||||||
|
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;
|
||||||
|
this.gap = parseFloat(this.gap);
|
||||||
|
}
|
||||||
|
this.g = this.gap;
|
||||||
|
this.property = n.property || "payload";
|
||||||
|
this.topi = n.topi || "topic";
|
||||||
|
this.septopics = true;
|
||||||
|
if (n.septopics !== undefined && n.septopics === false) {
|
||||||
|
this.septopics = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var node = this;
|
||||||
|
|
||||||
|
node.previous = {};
|
||||||
|
this.on("input",function(msg) {
|
||||||
|
var topic;
|
||||||
|
try {
|
||||||
|
topic = RED.util.getMessageProperty(msg,node.topi);
|
||||||
|
}
|
||||||
|
catch(e) { }
|
||||||
|
if (msg.hasOwnProperty("reset")) {
|
||||||
|
if (node.septopics && topic && (typeof topic === "string") && (topic !== "")) {
|
||||||
|
delete node.previous[msg.topic];
|
||||||
|
}
|
||||||
|
else { node.previous = {}; }
|
||||||
|
}
|
||||||
|
var value = RED.util.getMessageProperty(msg,node.property);
|
||||||
|
if (value !== undefined) {
|
||||||
|
var t = "_no_topic";
|
||||||
|
if (node.septopics) { t = topic || t; }
|
||||||
|
if ((this.func === "rbe") || (this.func === "rbei")) {
|
||||||
|
var doSend = (this.func !== "rbei") || (node.previous.hasOwnProperty(t)) || false;
|
||||||
|
if (typeof(value) === "object") {
|
||||||
|
if (typeof(node.previous[t]) !== "object") { node.previous[t] = {}; }
|
||||||
|
if (!RED.util.compareObjects(value, node.previous[t])) {
|
||||||
|
node.previous[t] = RED.util.cloneMessage(value);
|
||||||
|
if (doSend) { node.send(msg); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (value !== node.previous[t]) {
|
||||||
|
node.previous[t] = RED.util.cloneMessage(value);
|
||||||
|
if (doSend) { node.send(msg); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var n = parseFloat(value);
|
||||||
|
if (!isNaN(n)) {
|
||||||
|
if ((typeof node.previous[t] === 'undefined') && (this.func === "narrowband")) {
|
||||||
|
if (node.start === '') { node.previous[t] = n; }
|
||||||
|
else { node.previous[t] = node.start; }
|
||||||
|
}
|
||||||
|
if (node.pc) { node.gap = Math.abs(node.previous[t] * node.g / 100) || 0; }
|
||||||
|
else { node.gap = Number(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 - 1; }
|
||||||
|
if (Math.abs(n - node.previous[t]) === node.gap) {
|
||||||
|
if ((this.func === "deadbandEq")||(this.func === "narrowband")) {
|
||||||
|
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" || 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 === "narrowband")||(this.func === "narrowbandEq")) {
|
||||||
|
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"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // ignore msg with no payload property.
|
||||||
|
});
|
||||||
|
}
|
||||||
|
RED.nodes.registerType("rbe",RbeNode);
|
||||||
|
}
|
BIN
packages/node_modules/@node-red/nodes/icons/rbe.png
vendored
Normal file
BIN
packages/node_modules/@node-red/nodes/icons/rbe.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 252 B |
40
packages/node_modules/@node-red/nodes/locales/de/function/rbe.html
vendored
Normal file
40
packages/node_modules/@node-red/nodes/locales/de/function/rbe.html
vendored
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<script type="text/html" data-help-name="rbe">
|
||||||
|
<p>Report by Exception (RBE) - Daten-Weiterleitung nur bei Änderung der Nutzdaten (Payload).
|
||||||
|
Der Node kann auch blockieren oder weiterleiten, wenn die Wertänderung eine Grenze überschreitet (Totband- und Nahband-Modus).</p>
|
||||||
|
<h3>Eingangsdaten</h3>
|
||||||
|
<dl class="message-properties">
|
||||||
|
<dt>payload
|
||||||
|
<span class="property-type">number | string | (object)</span>
|
||||||
|
</dt>
|
||||||
|
<dd>Der RBE-Modus mit Prüfung auf Wertänderung akzeptiert Zahlen (numbers), Zeichenfolgen (string) und einfache Objekte (object).
|
||||||
|
Bei den anderen wertvergleichenden Modies müssen analysierbare (parseable) Zahlenwerte übergeben werden.</dd>
|
||||||
|
<dt class="optional">topic <span class="property-type">string</span>
|
||||||
|
</dt>
|
||||||
|
<dd>Wenn vorgegeben erfolgt die Auswertung separat für jedes Topic</dd>
|
||||||
|
<dt class="optional">reset<span class="property-type">any</span></dt>
|
||||||
|
<dd>Wenn gesetzt wird/werden der/die gespeicherte(n) Wert(e) rückgesetzt</dd>
|
||||||
|
</dl>
|
||||||
|
<h3>Ausgangsdaten</h3>
|
||||||
|
<dl class="message-properties">
|
||||||
|
<dt>payload
|
||||||
|
<span class="property-type">wie Eingangsdaten</span>
|
||||||
|
</dt>
|
||||||
|
<dd>Wenn Bedingung erfüllt, sind die Ausgangsdaten gleich den Eingangsdaten</dd>
|
||||||
|
</dl>
|
||||||
|
<h3>Details</h3>
|
||||||
|
<p>Im <i>RBE</i>-Modus mit Prüfung auf Wertänderung blockiert dieser Node die Datenweitergabe bis
|
||||||
|
<code>msg.payload</code> (oder die eingestellte Eigenschaft) verändert ist gegenüber dessen vorherigen Wert.
|
||||||
|
Wenn benötigt, wird der Anfangswert ignoriert, sodass beim Start nichts gesendet wird.</p>
|
||||||
|
<p>In den <i>Totband</i>-Modies werden die Eingangswerte geblockt,
|
||||||
|
<i>bis</i> die Wertänderung größer oder größer-gleich ist als ± des Bandes um den voherigen Wert.</p>
|
||||||
|
<p>In den <i>Nahband</i>-Modies werden die Eingangswerte geblockt,
|
||||||
|
<i>wenn</i> die Wertänderung größer oder größer-gleich ist als ± des Bandes um den voherigen Wert.
|
||||||
|
Dies ist beispielsweise nützlich, um Ausreißer eines fehlerhaften Sensors zu ignorieren.</p>
|
||||||
|
<p>In den Totband und Nahband-Modies müssen die Eingangswerte analysierbare (parseable) Zahlenwerte sein und
|
||||||
|
beide unterstützen auch % (prozentuale Angabe), d.h. der Node sendet nur, wenn der Eingangswert mehr als x% vom vorherigen Wert abweicht.</p>
|
||||||
|
<p>Die Totband- und Nahband-Modies erlauben den Vergleich entweder gegen den letzten gültigen Ausgangswert,
|
||||||
|
dieses zum Ignorieren von Werten außerhalb des gültigen Bereichs, oder gegen den des vorherigen Eingangswertes,
|
||||||
|
welches den Sollwert rücksetzt, was einen allmähligen Drift (Totband) oder einen eine schrittweise Veränderung (Nahband) ermöglicht.</p>
|
||||||
|
<p><b>Hinweis</b>: Dieser Node arbeitet auf per-<code>msg.topic</code>-Basis.
|
||||||
|
Dies bedeutet, dass ein einzelner rbe-Node mehrere verschiedene Topics parallel bearbeiten kann.</p>
|
||||||
|
</script>
|
@ -1000,5 +1000,32 @@
|
|||||||
"too-many": "Zu viele anstehende Nachrichten im <span style=\"background-color:Gainsboro\">batch</span>-Node",
|
"too-many": "Zu viele anstehende Nachrichten im <span style=\"background-color:Gainsboro\">batch</span>-Node",
|
||||||
"unexpected": "Unerwarteter Modus",
|
"unexpected": "Unerwarteter Modus",
|
||||||
"no-parts": "Keine parts-Eigenschaft in Nachricht"
|
"no-parts": "Keine parts-Eigenschaft in Nachricht"
|
||||||
|
},
|
||||||
|
"rbe": {
|
||||||
|
"rbe": "filter",
|
||||||
|
"label": {
|
||||||
|
"func": "Modus",
|
||||||
|
"init": "Sende Anfangswert",
|
||||||
|
"start": "Startwert",
|
||||||
|
"name": "Name",
|
||||||
|
"septopics": "Modus für jedes msg.topic separat anwenden"
|
||||||
|
},
|
||||||
|
"placeholder":{
|
||||||
|
"bandgap": "z.B. 10 oder 5%",
|
||||||
|
"start": "Leer lassen, um erste empfangenen Daten zu nutzen"
|
||||||
|
},
|
||||||
|
"opts": {
|
||||||
|
"rbe": "Blockieren bis Wertänderung",
|
||||||
|
"rbei": "Blockieren bis Wertänderung (Anfangswert ignorieren)",
|
||||||
|
"deadband": "Blockieren bis Wertänderung ist größer als",
|
||||||
|
"deadbandEq": "Blockieren bis Wertänderung ist größer-gleich",
|
||||||
|
"narrowband": "Blockieren wenn Wertänderung ist größer als",
|
||||||
|
"narrowbandEq": "Blockieren wenn Wertänderung ist größer-gleich",
|
||||||
|
"in": "verglichen mit letzten Eingangswert",
|
||||||
|
"out": "verglichen mit letzten gültigen Ausgangswert"
|
||||||
|
},
|
||||||
|
"warn": {
|
||||||
|
"nonumber": "Keine Zahl gefunden in den Nutzdaten (Payload)"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
41
packages/node_modules/@node-red/nodes/locales/en-US/function/rbe.html
vendored
Normal file
41
packages/node_modules/@node-red/nodes/locales/en-US/function/rbe.html
vendored
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<script type="text/html" data-help-name="rbe">
|
||||||
|
<p>Report by Exception (RBE) node - only passes on data if the payload has changed.
|
||||||
|
It can also block unless, or ignore if the value changes by a specified amount (Dead- and Narrowband mode).</p>
|
||||||
|
<h3>Inputs</h3>
|
||||||
|
<dl class="message-properties">
|
||||||
|
<dt>payload
|
||||||
|
<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. This property can be set by configuration.</dd>
|
||||||
|
<dt class="optional">reset<span class="property-type">any</span></dt>
|
||||||
|
<dd>if set clears the stored value for the specified msg.topic, or
|
||||||
|
all topics if msg.topic is not specified.</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>,
|
||||||
|
(or selected property) value is different to the previous one.
|
||||||
|
If required it can ignore the intial value, so as not to send anything at start.</p>
|
||||||
|
<p>The <a href="https://en.wikipedia.org/wiki/Deadband" target="_blank">Deadband</a> modes will block the incoming value
|
||||||
|
<i>unless</i> its change is greater or greater-equal than ± the band gap away from a previous value.</p>
|
||||||
|
<p>The Narrowband modes will block the incoming value,
|
||||||
|
<i>if</i> its change is greater or greater-equal than ± the band gap away from the previous value.
|
||||||
|
It is useful for ignoring outliers from a faulty sensor for example.</p>
|
||||||
|
<p>Both in Deadband and Narrowband modes the incoming value must contain a parseable number and
|
||||||
|
both also supports % - only sends if/unless the input differs by more than x% of the original value.</p>
|
||||||
|
<p>Both Deadband and Narrowband allow comparison against either the previous valid output value, thus
|
||||||
|
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>
|
||||||
|
<p><b>Note:</b> This works on a per <code>msg.topic</code> basis, though this can be changed to another property if desired.
|
||||||
|
This means that a single rbe node can handle multiple different topics at the same time.</p>
|
||||||
|
</script>
|
@ -1001,5 +1001,32 @@
|
|||||||
"too-many" : "too many pending messages in batch node",
|
"too-many" : "too many pending messages in batch node",
|
||||||
"unexpected" : "unexpected mode",
|
"unexpected" : "unexpected mode",
|
||||||
"no-parts" : "no parts property in message"
|
"no-parts" : "no parts property in message"
|
||||||
|
},
|
||||||
|
"rbe": {
|
||||||
|
"rbe": "filter",
|
||||||
|
"label": {
|
||||||
|
"func": "Mode",
|
||||||
|
"init": "Send initial value",
|
||||||
|
"start": "Start value",
|
||||||
|
"name": "Name",
|
||||||
|
"septopics": "Apply mode separately for each "
|
||||||
|
},
|
||||||
|
"placeholder":{
|
||||||
|
"bandgap": "e.g. 10 or 5%",
|
||||||
|
"start": "leave blank to use first data received"
|
||||||
|
},
|
||||||
|
"opts": {
|
||||||
|
"rbe": "block unless value changes",
|
||||||
|
"rbei": "block unless value changes (ignore initial value)",
|
||||||
|
"deadband": "block unless value change is greater 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",
|
||||||
|
"out": "compared to last valid output value"
|
||||||
|
},
|
||||||
|
"warn": {
|
||||||
|
"nonumber": "no number found in payload"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
31
packages/node_modules/@node-red/nodes/locales/ja/function/rbe.html
vendored
Normal file
31
packages/node_modules/@node-red/nodes/locales/ja/function/rbe.html
vendored
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<!-- Source revision: https://github.com/node-red/node-red-nodes/commit/467907776088422882076f46d85e25601449564d -->
|
||||||
|
|
||||||
|
<script type="text/html" data-help-name="rbe">
|
||||||
|
<p>Report by Exception(例外データの報告)ノード - ペイロードの値が変化した場合だけデータを送信。</p>
|
||||||
|
<p>値が指定した量変化するまでブロックすることもできます- 不感帯(deadband)モード。</p>
|
||||||
|
<h3>入力</h3> <dl class="message-properties">
|
||||||
|
<dt>payload
|
||||||
|
<span class="property-type">数値 | 文字列 | (オブジェクト)</span>
|
||||||
|
</dt>
|
||||||
|
<dd>RBEモードでは数値、文字列、シンプルなオブジェクトを受け付けます。他のモードではパース可能な数値を指定します。</dd>
|
||||||
|
<dt class="optional">topic <span class="property-type">文字列</span>
|
||||||
|
</dt>
|
||||||
|
<dd>指定すると、トピックごとに動作します。</dd>
|
||||||
|
<dt class="optional">reset<span class="property-type">任意</span></dt>
|
||||||
|
<dd>値を設定すると、保存した値をクリアします。msg.topicを指定した場合は対応する値、指定しなければ全てのトピックが対象となります。</dd>
|
||||||
|
</dl>
|
||||||
|
<h3>出力</h3>
|
||||||
|
<dl class="message-properties">
|
||||||
|
<dt>payload
|
||||||
|
<span class="property-type">入力と同じ</span>
|
||||||
|
</dt>
|
||||||
|
<dd>トリガー条件を満たした場合、入力を出力として送信。</dd>
|
||||||
|
</dl>
|
||||||
|
<h3>詳細</h3>
|
||||||
|
<p>RBEモードでは、<code>msg.payload</code>が前の値から変化するまでブロックします。</p>
|
||||||
|
<p>不感帯モードでは、入力データはパース可能な数値でなければなりません。以前の入力値に対する差分が指定値より大きな場合にのみメッセージを出力します。</p>
|
||||||
|
<p>不感帯モードでは%による指定もサポートしています。入力と前の値の差分がX%より大きな場合に出力を行います。</p>
|
||||||
|
<p>狭帯域(narrowband)モードでは、前の値に対する差分が一定値より大きな場合に入力ペイロードをブロックします。このモードは、故障したセンサから発生する外れ値を無視する時などに有用です。</p>
|
||||||
|
<p>不感帯モードと狭帯域モードでは、以前の有効出力値、もしくは、以前の入力値との比較ができます。有効出力値を用いると範囲外の値を無視することが、入力値を用いると設定点がリセットされるため漸次的変化(不感帯モード)もしくは段階的変化(狭帯域モード)が可能です。</p>
|
||||||
|
<p><b>注:</b> このノードは<code>msg.topic</code>毎に動作します。そのため、ひとつのrbeノードで複数の異なるトピックを同時に扱うことができます。</p>
|
||||||
|
</script>
|
@ -999,5 +999,30 @@
|
|||||||
"too-many": "batchノード内で保持しているメッセージが多すぎます",
|
"too-many": "batchノード内で保持しているメッセージが多すぎます",
|
||||||
"unexpected": "想定外のモード",
|
"unexpected": "想定外のモード",
|
||||||
"no-parts": "メッセージにpartsプロパティがありません"
|
"no-parts": "メッセージにpartsプロパティがありません"
|
||||||
|
},
|
||||||
|
"rbe": {
|
||||||
|
"label": {
|
||||||
|
"func": "動作",
|
||||||
|
"init": "初期値を送付",
|
||||||
|
"start": "初期値",
|
||||||
|
"name": "名前"
|
||||||
|
},
|
||||||
|
"placeholder": {
|
||||||
|
"bandgap": "例:10、5%",
|
||||||
|
"start": "最初に受け取った値を用いる場合は空欄"
|
||||||
|
},
|
||||||
|
"opts": {
|
||||||
|
"rbe": "値が変化した時のみメッセージを中継",
|
||||||
|
"rbei": "値が変化した時のみメッセージを中継(初期値を無視)",
|
||||||
|
"deadband": "値が指定した変化量を超える時のみメッセージを中継",
|
||||||
|
"deadbandEq": "値が指定した変化量以上の時のみメッセージを中継",
|
||||||
|
"narrowband": "値が指定した変化量を超えない時のみメッセージを中継",
|
||||||
|
"narrowbandEq": "値が指定した変化量以上でない時のみメッセージを中継",
|
||||||
|
"in": "最後の入力値と比較",
|
||||||
|
"out": "最後の出力値と比較"
|
||||||
|
},
|
||||||
|
"warn": {
|
||||||
|
"nonumber": "ペイロードに数値が含まれていません"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
2
packages/node_modules/node-red/package.json
vendored
2
packages/node_modules/node-red/package.json
vendored
@ -40,8 +40,6 @@
|
|||||||
"express": "4.17.1",
|
"express": "4.17.1",
|
||||||
"fs-extra": "9.1.0",
|
"fs-extra": "9.1.0",
|
||||||
"node-red-admin": "^0.2.6",
|
"node-red-admin": "^0.2.6",
|
||||||
"node-red-node-rbe": "^0.5.0",
|
|
||||||
"node-red-node-tail": "^0.3.0",
|
|
||||||
"nopt": "5.0.0",
|
"nopt": "5.0.0",
|
||||||
"semver": "7.3.5"
|
"semver": "7.3.5"
|
||||||
},
|
},
|
||||||
|
538
test/nodes/core/function/rbe_spec.js
Normal file
538
test/nodes/core/function/rbe_spec.js
Normal file
@ -0,0 +1,538 @@
|
|||||||
|
|
||||||
|
var should = require("should");
|
||||||
|
var helper = require("node-red-node-test-helper");
|
||||||
|
|
||||||
|
var testNode = require("nr-test-utils").require("@node-red/nodes/core/function/rbe.js");
|
||||||
|
|
||||||
|
describe('rbe node', function() {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
beforeEach(function(done) {
|
||||||
|
helper.startServer(done);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(function(done) {
|
||||||
|
helper.unload().then(function() {
|
||||||
|
helper.stopServer(done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should be loaded with correct defaults", function(done) {
|
||||||
|
var flow = [{"id":"n1", "type":"rbe", "name":"rbe1", "wires":[[]]}];
|
||||||
|
helper.load(testNode, flow, function() {
|
||||||
|
var n1 = helper.getNode("n1");
|
||||||
|
n1.should.have.property("name", "rbe1");
|
||||||
|
n1.should.have.property("func", "rbe");
|
||||||
|
n1.should.have.property("gap", "0");
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should only send output if payload changes - with multiple topics (rbe)', function(done) {
|
||||||
|
var flow = [{"id":"n1", "type":"rbe", func:"rbe", gap:"0", 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", "a");
|
||||||
|
c+=1;
|
||||||
|
}
|
||||||
|
else if (c === 1) {
|
||||||
|
msg.should.have.a.property("payload", 2);
|
||||||
|
c+=1;
|
||||||
|
}
|
||||||
|
else if (c == 2) {
|
||||||
|
msg.should.have.a.property("payload");
|
||||||
|
msg.payload.should.have.a.property("b",1);
|
||||||
|
msg.payload.should.have.a.property("c",2);
|
||||||
|
c+=1;
|
||||||
|
}
|
||||||
|
else if (c == 3) {
|
||||||
|
msg.should.have.a.property("payload",true);
|
||||||
|
c+=1;
|
||||||
|
}
|
||||||
|
else if (c == 4) {
|
||||||
|
msg.should.have.a.property("payload",false);
|
||||||
|
c+=1;
|
||||||
|
}
|
||||||
|
else if (c == 5) {
|
||||||
|
msg.should.have.a.property("payload",true);
|
||||||
|
c+=1;
|
||||||
|
}
|
||||||
|
else if (c == 6) {
|
||||||
|
msg.should.have.a.property("topic","a");
|
||||||
|
msg.should.have.a.property("payload",1);
|
||||||
|
c+=1;
|
||||||
|
}
|
||||||
|
else if (c == 7) {
|
||||||
|
msg.should.have.a.property("topic","b");
|
||||||
|
msg.should.have.a.property("payload",1);
|
||||||
|
c+=1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
c += 1;
|
||||||
|
msg.should.have.a.property("topic","c");
|
||||||
|
msg.should.have.a.property("payload",1);
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
n1.emit("input", {payload:"a"});
|
||||||
|
n1.emit("input", {payload:"a"});
|
||||||
|
n1.emit("input", {payload:"a"});
|
||||||
|
n1.emit("input", {payload:2});
|
||||||
|
n1.emit("input", {payload:2});
|
||||||
|
n1.emit("input", {payload:{b:1,c:2}});
|
||||||
|
n1.emit("input", {payload:{c:2,b:1}});
|
||||||
|
n1.emit("input", {payload:{c:2,b:1}});
|
||||||
|
n1.emit("input", {payload:true});
|
||||||
|
n1.emit("input", {payload:false});
|
||||||
|
n1.emit("input", {payload:false});
|
||||||
|
n1.emit("input", {payload:true});
|
||||||
|
|
||||||
|
n1.emit("input", {topic:"a",payload:1});
|
||||||
|
n1.emit("input", {topic:"b",payload:1});
|
||||||
|
n1.emit("input", {topic:"b",payload:1});
|
||||||
|
n1.emit("input", {topic:"a",payload:1});
|
||||||
|
n1.emit("input", {topic:"c",payload:1});
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should ignore multiple topics if told to (rbe)', function(done) {
|
||||||
|
var flow = [{id:"n1", type:"rbe", func:"rbe", gap:"0", septopics:false, 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", "a");
|
||||||
|
c+=1;
|
||||||
|
}
|
||||||
|
else if (c === 1) {
|
||||||
|
msg.should.have.a.property("payload", 2);
|
||||||
|
c+=1;
|
||||||
|
}
|
||||||
|
else if (c == 2) {
|
||||||
|
msg.should.have.a.property("payload");
|
||||||
|
msg.payload.should.have.a.property("b",1);
|
||||||
|
msg.payload.should.have.a.property("c",2);
|
||||||
|
c+=1;
|
||||||
|
}
|
||||||
|
else if (c == 3) {
|
||||||
|
msg.should.have.a.property("payload",true);
|
||||||
|
c+=1;
|
||||||
|
}
|
||||||
|
else if (c == 4) {
|
||||||
|
msg.should.have.a.property("payload",false);
|
||||||
|
c+=1;
|
||||||
|
}
|
||||||
|
else if (c == 5) {
|
||||||
|
msg.should.have.a.property("payload",true);
|
||||||
|
c+=1;
|
||||||
|
}
|
||||||
|
else if (c == 6) {
|
||||||
|
msg.should.have.a.property("topic","a");
|
||||||
|
msg.should.have.a.property("payload",1);
|
||||||
|
c+=1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
msg.should.have.a.property("topic","a");
|
||||||
|
msg.should.have.a.property("payload",2);
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
n1.emit("input", {topic:"a",payload:"a"});
|
||||||
|
n1.emit("input", {topic:"b",payload:"a"});
|
||||||
|
n1.emit("input", {topic:"c",payload:"a"});
|
||||||
|
n1.emit("input", {topic:"a",payload:2});
|
||||||
|
n1.emit("input", {topic:"b",payload:2});
|
||||||
|
n1.emit("input", {payload:{b:1,c:2}});
|
||||||
|
n1.emit("input", {payload:{c:2,b:1}});
|
||||||
|
n1.emit("input", {payload:{c:2,b:1}});
|
||||||
|
n1.emit("input", {topic:"a",payload:true});
|
||||||
|
n1.emit("input", {topic:"b",payload:false});
|
||||||
|
n1.emit("input", {topic:"c",payload:false});
|
||||||
|
n1.emit("input", {topic:"d",payload:true});
|
||||||
|
|
||||||
|
n1.emit("input", {topic:"a",payload:1});
|
||||||
|
n1.emit("input", {topic:"b",payload:1});
|
||||||
|
n1.emit("input", {topic:"c",payload:1});
|
||||||
|
n1.emit("input", {topic:"d",payload:1});
|
||||||
|
n1.emit("input", {topic:"a",payload:2});
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should only send output if another chosen property changes - foo (rbe)', function(done) {
|
||||||
|
var flow = [{"id":"n1", "type":"rbe", func:"rbe", gap:"0", property:"foo", 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("foo", "a");
|
||||||
|
c+=1;
|
||||||
|
}
|
||||||
|
else if (c === 1) {
|
||||||
|
msg.should.have.a.property("foo", "b");
|
||||||
|
c+=1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
msg.should.have.a.property("foo");
|
||||||
|
msg.foo.should.have.a.property("b",1);
|
||||||
|
msg.foo.should.have.a.property("c",2);
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
n1.emit("input", {foo:"a"});
|
||||||
|
n1.emit("input", {payload:"a"});
|
||||||
|
n1.emit("input", {foo:"a"});
|
||||||
|
n1.emit("input", {payload:"a"});
|
||||||
|
n1.emit("input", {foo:"a"});
|
||||||
|
n1.emit("input", {foo:"b"});
|
||||||
|
n1.emit("input", {foo:{b:1,c:2}});
|
||||||
|
n1.emit("input", {foo:{c:2,b:1}});
|
||||||
|
n1.emit("input", {payload:{c:2,b:1}});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should only send output if payload changes - ignoring first value (rbei)', function(done) {
|
||||||
|
var flow = [{"id":"n1", "type":"rbe", func:"rbei", gap:"0", 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", "b");
|
||||||
|
msg.should.have.a.property("topic", "a");
|
||||||
|
c+=1;
|
||||||
|
}
|
||||||
|
else if (c === 1) {
|
||||||
|
msg.should.have.a.property("payload", "b");
|
||||||
|
msg.should.have.a.property("topic", "b");
|
||||||
|
c+=1;
|
||||||
|
}
|
||||||
|
else if (c === 2) {
|
||||||
|
msg.should.have.a.property("payload", "c");
|
||||||
|
msg.should.have.a.property("topic", "a");
|
||||||
|
c+=1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
msg.should.have.a.property("payload", "c");
|
||||||
|
msg.should.have.a.property("topic", "b");
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
n1.emit("input", {payload:"a", topic:"a"});
|
||||||
|
n1.emit("input", {payload:"a", topic:"b"});
|
||||||
|
n1.emit("input", {payload:"a", topic:"a"});
|
||||||
|
n1.emit("input", {payload:"b", topic:"a"});
|
||||||
|
n1.emit("input", {payload:"b", topic:"b"});
|
||||||
|
n1.emit("input", {payload:"c", topic:"a"});
|
||||||
|
n1.emit("input", {payload:"c", topic:"b"});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should send output if queue is reset (rbe)', function(done) {
|
||||||
|
var flow = [{"id":"n1", "type":"rbe", func:"rbe", gap:"0", 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", "a");
|
||||||
|
c+=1;
|
||||||
|
}
|
||||||
|
else if (c === 1) {
|
||||||
|
msg.should.have.a.property("payload", "b");
|
||||||
|
c+=1;
|
||||||
|
}
|
||||||
|
else if (c === 2) {
|
||||||
|
msg.should.have.a.property("payload", "a");
|
||||||
|
c+=1;
|
||||||
|
}
|
||||||
|
else if (c === 3) {
|
||||||
|
msg.should.have.a.property("payload", "b");
|
||||||
|
c+=1;
|
||||||
|
}
|
||||||
|
else if (c === 4) {
|
||||||
|
msg.should.have.a.property("payload", "b");
|
||||||
|
c+=1;
|
||||||
|
}
|
||||||
|
else if (c === 5) {
|
||||||
|
msg.should.have.a.property("payload", "b");
|
||||||
|
c+=1;
|
||||||
|
}
|
||||||
|
else if (c === 6) {
|
||||||
|
msg.should.have.a.property("payload", "a");
|
||||||
|
c+=1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
msg.should.have.a.property("payload", "c");
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
n1.emit("input", {topic:"a", payload:"a"});
|
||||||
|
n1.emit("input", {topic:"a", payload:"a"});
|
||||||
|
n1.emit("input", {topic:"b", payload:"b"});
|
||||||
|
n1.emit("input", {reset:true}); // reset all
|
||||||
|
n1.emit("input", {topic:"a", payload:"a"});
|
||||||
|
n1.emit("input", {topic:"b", payload:"b"});
|
||||||
|
n1.emit("input", {topic:"b", payload:"b"});
|
||||||
|
n1.emit("input", {topic:"b", reset:""}); // reset b
|
||||||
|
n1.emit("input", {topic:"b", payload:"b"});
|
||||||
|
n1.emit("input", {topic:"a", payload:"a"});
|
||||||
|
n1.emit("input", {reset:""}); // reset all
|
||||||
|
n1.emit("input", {topic:"b", payload:"b"});
|
||||||
|
n1.emit("input", {topic:"a", payload:"a"});
|
||||||
|
n1.emit("input", {topic:"c"}); // don't reset a non topic
|
||||||
|
n1.emit("input", {topic:"b", payload:"b"});
|
||||||
|
n1.emit("input", {topic:"a", payload:"a"});
|
||||||
|
n1.emit("input", {topic:"c", payload:"c"});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
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) {
|
||||||
|
var flow = [{"id":"n1", "type":"rbe", func:"deadband", gap:"10", 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", 20);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
msg.should.have.a.property("payload", "5 deg");
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
n1.emit("input", {payload:0});
|
||||||
|
n1.emit("input", {payload:2});
|
||||||
|
n1.emit("input", {payload:4});
|
||||||
|
n1.emit("input", {payload:"6 deg"});
|
||||||
|
n1.emit("input", {payload:8});
|
||||||
|
n1.emit("input", {payload:20});
|
||||||
|
n1.emit("input", {payload:15});
|
||||||
|
n1.emit("input", {payload:"5 deg"});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
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"]] },
|
||||||
|
{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", 100);
|
||||||
|
}
|
||||||
|
else if (c === 2) {
|
||||||
|
msg.should.have.a.property("payload", 111);
|
||||||
|
}
|
||||||
|
else if (c === 3) {
|
||||||
|
msg.should.have.a.property("payload", 135);
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
n1.emit("input", {payload:100});
|
||||||
|
n1.emit("input", {payload:95});
|
||||||
|
n1.emit("input", {payload:105});
|
||||||
|
n1.emit("input", {payload:111});
|
||||||
|
n1.emit("input", {payload:120});
|
||||||
|
n1.emit("input", {payload:135});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should warn if no number found in deadband mode', function(done) {
|
||||||
|
var flow = [{"id":"n1", "type":"rbe", func:"deadband", gap:"10", 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 += 1;
|
||||||
|
});
|
||||||
|
setTimeout( function() {
|
||||||
|
c.should.equal(0);
|
||||||
|
helper.log().called.should.be.true;
|
||||||
|
var logEvents = helper.log().args.filter(function (evt) {
|
||||||
|
return evt[0].type == "rbe";
|
||||||
|
});
|
||||||
|
logEvents.should.have.length(1);
|
||||||
|
var msg = logEvents[0][0];
|
||||||
|
msg.should.have.property('level', helper.log().WARN);
|
||||||
|
msg.should.have.property('id', 'n1');
|
||||||
|
msg.should.have.property('type', 'rbe');
|
||||||
|
msg.should.have.property('msg', 'rbe.warn.nonumber');
|
||||||
|
done();
|
||||||
|
},50);
|
||||||
|
n1.emit("input", {payload:"banana"});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
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) {
|
||||||
|
var flow = [{"id":"n1", "type":"rbe", func:"narrowband", gap:"10", 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", 0);
|
||||||
|
}
|
||||||
|
else if (c === 1) {
|
||||||
|
msg.should.have.a.property("payload","6 deg");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
msg.should.have.a.property("payload", "5 deg");
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
c += 1;
|
||||||
|
});
|
||||||
|
n1.emit("input", {payload:0});
|
||||||
|
n1.emit("input", {payload:20});
|
||||||
|
n1.emit("input", {payload:40});
|
||||||
|
n1.emit("input", {payload:"6 deg"});
|
||||||
|
n1.emit("input", {payload:18});
|
||||||
|
n1.emit("input", {payload:20});
|
||||||
|
n1.emit("input", {payload:50});
|
||||||
|
n1.emit("input", {payload:"5 deg"});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should send output if gap is 0 and input doesnt change (narrowband)', function(done) {
|
||||||
|
var flow = [{"id":"n1", "type":"rbe", func:"narrowband", gap:"0", 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", 1);
|
||||||
|
}
|
||||||
|
else if (c === 4) {
|
||||||
|
msg.should.have.a.property("payload",1);
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
c += 1;
|
||||||
|
});
|
||||||
|
n1.emit("input", {payload:1});
|
||||||
|
n1.emit("input", {payload:1});
|
||||||
|
n1.emit("input", {payload:1});
|
||||||
|
n1.emit("input", {payload:1});
|
||||||
|
n1.emit("input", {payload:0});
|
||||||
|
n1.emit("input", {payload:1});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
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});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user