Skip to content

Commit

Permalink
Merge pull request #2707 from node-red/trigger-delay-override
Browse files Browse the repository at this point in the history
Allow trigger node delay to be overridden with msg.delay
  • Loading branch information
knolleary committed Sep 29, 2020
2 parents 3b68f56 + 2962c43 commit 59adf82
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@
<label></label>
<input type="checkbox" id="node-input-extend" style="margin-left:0px; vertical-align:top; width:auto !important;"> <label style="width:auto !important;" for="node-input-extend" data-i18n="trigger.extend"></label>
</div>
<div class="form-row node-type-override">
<label></label>
<input type="checkbox" id="node-input-overrideDelay" style="margin-left:0px; vertical-align:top; width:auto !important;"> <label style="width:auto !important;" for="node-input-overrideDelay" data-i18n="trigger.override"></label>
</div>
<div class="form-row node-type-wait">
<label data-i18n="trigger.then-send"></label>
<input type="hidden" id="node-input-op2type">
Expand Down Expand Up @@ -89,6 +93,7 @@
op2type: {value:"val"},
duration: {value:"250",required:true,validate:RED.validators.number()},
extend: {value:"false"},
overrideDelay: {value:"false"},
units: {value:"ms"},
reset: {value:""},
bytopic: {value:"all"},
Expand Down Expand Up @@ -126,7 +131,7 @@

if (this.outputs == 2) { $("#node-input-second").prop('checked', true) }
else { $("#node-input-second").prop('checked', false) }

$("#node-input-second").change(function() {
if ($("#node-input-second").is(":checked")) {
$("#node-input-outputs").val(2);
Expand All @@ -138,6 +143,7 @@
$("#node-then-type").on("change", function() {
if ($(this).val() == "block") {
$(".node-type-wait").hide();
$(".node-type-override").hide();
$(".node-type-duration").hide();
$("#node-second-output").hide();
$("#node-input-second").prop('checked', false);
Expand All @@ -146,13 +152,15 @@
else if ($(this).val() == "loop") {
if ($("#node-input-duration").val() == 0) { $("#node-input-duration").val(250); }
$(".node-type-wait").hide();
$(".node-type-override").show();
$(".node-type-duration").show();
$("#node-second-output").hide();
$("#node-input-second").prop('checked', false);
$("#node-input-outputs").val(1);
} else {
if ($("#node-input-duration").val() == 0) { $("#node-input-duration").val(250); }
$(".node-type-wait").show();
$(".node-type-override").show();
$(".node-type-duration").show();
$("#node-second-output").show();
}
Expand Down Expand Up @@ -208,7 +216,11 @@
} else {
$("#node-input-extend").prop("checked",false);
}

if (this.overrideDelay === "true" || this.overrideDelay === true) {
$("#node-input-overrideDelay").prop("checked",true);
} else {
$("#node-input-overrideDelay").prop("checked",false);
}
},
oneditsave: function() {
if ($("#node-then-type").val() == "block") {
Expand Down
17 changes: 11 additions & 6 deletions packages/node_modules/@node-red/nodes/core/function/89-trigger.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ module.exports = function(RED) {
}
}
this.extend = n.extend || "false";
this.overrideDelay = n.overrideDelay || false;
this.units = n.units || "ms";
this.reset = n.reset || '';
this.duration = parseFloat(n.duration);
Expand Down Expand Up @@ -117,12 +118,16 @@ module.exports = function(RED) {
var l = Object.keys(node.topics).length;
if (l === 0) { return {} }
else if (l === 1) { return {fill:"blue",shape:"dot"} }
else return {fill:"blue",shape:"dot",text:l};
else return {fill:"blue",shape:"dot",text:l};
}

var processMessage = function(msg) {
var topic = RED.util.getMessageProperty(msg,node.topic) || "_none";
var promise;
var delayDuration = node.duration;
if (node.overrideDelay && msg.hasOwnProperty("delay") && !isNaN(parseFloat(msg.delay))) {
delayDuration = parseFloat(msg.delay);
}
if (node.bytopic === "all") { topic = "_none"; }
node.topics[topic] = node.topics[topic] || {};
if (msg.hasOwnProperty("reset") || ((node.reset !== '') && msg.hasOwnProperty("payload") && (msg.payload !== null) && msg.payload.toString && (msg.payload.toString() == node.reset)) ) {
Expand Down Expand Up @@ -167,14 +172,14 @@ module.exports = function(RED) {
});
}
return promise.then(() => {
if (node.duration === 0) { node.topics[topic].tout = 0; }
if (delayDuration === 0) { node.topics[topic].tout = 0; }
else if (node.loop === true) {
/* istanbul ignore else */
if (node.topics[topic].tout) { clearInterval(node.topics[topic].tout); }
/* istanbul ignore else */
if (node.op1type !== "nul") {
var msg2 = RED.util.cloneMessage(msg);
node.topics[topic].tout = setInterval(function() { node.send(RED.util.cloneMessage(msg2)); }, node.duration);
node.topics[topic].tout = setInterval(function() { node.send(RED.util.cloneMessage(msg2)); }, delayDuration);
}
}
else {
Expand Down Expand Up @@ -217,15 +222,15 @@ module.exports = function(RED) {
node.status(stat());
}

}, node.duration);
}, delayDuration);
}
}
node.status(stat());
if (node.op1type !== "nul") { node.send(RED.util.cloneMessage(msg)); }
});
});
}
else if ((node.extend === "true" || node.extend === true) && (node.duration > 0)) {
else if ((node.extend === "true" || node.extend === true) && (delayDuration > 0)) {
/* istanbul ignore else */
if (node.op2type === "payl") { node.topics[topic].m2 = RED.util.cloneMessage(msg.payload); }
/* istanbul ignore else */
Expand Down Expand Up @@ -262,7 +267,7 @@ module.exports = function(RED) {
}).catch(err => {
node.error(err);
});
}, node.duration);
}, delayDuration);
}
// else {
// if (node.op2type === "payl") {node.topics[topic].m2 = RED.util.cloneMessage(msg.payload); }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

<h3>Inputs</h3>
<dl class="message-properties">
<dt class="optional">delay <span class="property-type">number</span></dt>
<dd>Sets the delay, in milliseconds, to be applied to the message. This option only applies if the node is configured to allow the message to override the configured default delay interval.</dd>
<dt class="optional">reset</dt>
<dd>If a message is received with this property, any timeout or repeat
currently in progress will be cleared and no message triggered.</dd>
Expand All @@ -35,13 +37,14 @@ <h3>Details</h3>
act as a watchdog timer; only sending a message if nothing is received within the
set interval.</p>
<p>If set to a <i>string</i> type, the node supports the mustache template syntax.</p>
<p>The delay between sending messages can be overridden by <code>msg.delay</code> if that option is enabled in the node. The value must be provided in milliseconds.</p>
<p>If the node receives a message with a <code>reset</code> property, or a <code>payload</code>
that matches that configured in the node, any timeout or repeat currently in
progress will be cleared and no message triggered.</p>
<p>The node can be configured to resend a message at a regular interval until it
is reset by a received message.</p>
<p>Optionally, the node can be configured to treat messages as if they are separate streams,
using a msg property to identify each stream. Default <code>msg.topic</code>.</p>
<p>The status indicates the node is currently active. If multiple streams are used the status
<p>The status indicates the node is currently active. If multiple streams are used the status
indicates the number of streams being held.</p>
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,7 @@
"h": "Hours"
},
"extend": " extend delay if new message arrives",
"override": "override delay with msg.delay",
"second": " send second message to separate output",
"label": {
"trigger": "trigger",
Expand Down
59 changes: 59 additions & 0 deletions test/nodes/core/function/89-trigger_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,65 @@ describe('trigger node', function() {
});
});

it('should ignore msg.delay if overrideDelay not set', function(done) {
var flow = [
{"id":"n1", "type":"trigger", "name":"triggerNode", duration:"50",wires:[["n2"]] },
{id:"n2", type:"helper"}
];
helper.load(triggerNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
var c = 0;
var firstTime;
n2.on("input", function(msg) {
if (c === 0) {
firstTime = Date.now();
} else if (c === 1) {
try {
var delta = Date.now() - firstTime;
delta.should.be.greaterThan(30);
delta.should.be.lessThan(100);
done();
} catch(err) {
done(err);
}
}
c++;
});
n1.emit("input", {payload:null, delay: 300});
});
});

it('should use msg.delay if overrideDelay is set', function(done) {
var flow = [
{"id":"n1", "type":"trigger", "name":"triggerNode", overrideDelay: true, duration:"50",wires:[["n2"]] },
{id:"n2", type:"helper"}
];
helper.load(triggerNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
var c = 0;
var firstTime;
n2.on("input", function(msg) {
if (c === 0) {
firstTime = Date.now();
} else if (c === 1) {
try {
var delta = Date.now() - firstTime;
delta.should.be.greaterThan(270);
delta.should.be.lessThan(380);
done();
} catch(err) {
done(err);
}
}
c++;
});
n1.emit("input", {payload:null, delay: 300});
});
});


it('should handle true and false as strings and delay of 0', function(done) {
var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", op1:"true",op1type:"val",op2:"false",op2type:"val",duration:"30", wires:[["n2"]] },
{id:"n2", type:"helper"} ];
Expand Down

0 comments on commit 59adf82

Please sign in to comment.