mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
Merge pull request #2436 from node-red/add-trigger-second-output
Add second output to trigger node
This commit is contained in:
commit
ad4779e32f
@ -47,6 +47,10 @@
|
||||
<input type="hidden" id="node-input-op2type">
|
||||
<input style="width:70%" type="text" id="node-input-op2" placeholder="0">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label></label>
|
||||
<input type="checkbox" id="node-input-second" style="margin-left: 0px; vertical-align: top; width: auto !important;"> <label style="width:auto !important;" for="node-input-second" data-i18n="trigger.second"></label>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label data-i18n="trigger.label.reset" style="width:auto"></label>
|
||||
<div style="display:inline-block; width:70%;vertical-align:top">
|
||||
@ -58,10 +62,13 @@
|
||||
<br/>
|
||||
<div class="form-row">
|
||||
<label data-i18n="trigger.for" for="node-input-bytopic"></label>
|
||||
<select id="node-input-bytopic">
|
||||
<select id="node-input-bytopic" style="width:120px;">
|
||||
<option value="all" data-i18n="trigger.alltopics"></option>
|
||||
<option value="topic" data-i18n="trigger.bytopics"></option>
|
||||
</select>
|
||||
<span class="form-row" id="node-stream-topic">
|
||||
<input type="text" id="node-input-topic" style="width:46%;"/>
|
||||
</span>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
||||
@ -74,6 +81,7 @@
|
||||
category: 'function',
|
||||
color:"#E6E0F8",
|
||||
defaults: {
|
||||
name: {value:""},
|
||||
op1: {value:"1", validate: RED.validators.typedInput("op1type")},
|
||||
op2: {value:"0", validate: RED.validators.typedInput("op2type")},
|
||||
op1type: {value:"val"},
|
||||
@ -82,8 +90,9 @@
|
||||
extend: {value:"false"},
|
||||
units: {value:"ms"},
|
||||
reset: {value:""},
|
||||
bytopic: {value: "all"},
|
||||
name: {value:""}
|
||||
bytopic: {value:"all"},
|
||||
topic: {value:"topic",required:true},
|
||||
outputs: {value:1}
|
||||
},
|
||||
inputs:1,
|
||||
outputs:1,
|
||||
@ -103,6 +112,28 @@
|
||||
return this.name?"node_label_italic":"";
|
||||
},
|
||||
oneditprepare: function() {
|
||||
var that = this;
|
||||
if (this.topic === undefined) { $("#node-input-topic").val("topic"); }
|
||||
$("#node-input-topic").typedInput({default:'msg',types:['msg']});
|
||||
$("#node-input-bytopic").on("change", function() {
|
||||
if ($("#node-input-bytopic").val() === "all") {
|
||||
$("#node-stream-topic").hide();
|
||||
} else {
|
||||
$("#node-stream-topic").show();
|
||||
}
|
||||
});
|
||||
|
||||
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")) {
|
||||
that.outputs = 2;
|
||||
}
|
||||
else {
|
||||
that.outputs = 1;
|
||||
}
|
||||
});
|
||||
$("#node-then-type").on("change", function() {
|
||||
if ($(this).val() == "block") {
|
||||
$(".node-type-wait").hide();
|
||||
@ -177,7 +208,7 @@
|
||||
}
|
||||
if ($("#node-then-type").val() == "loop") {
|
||||
$("#node-input-duration").val($("#node-input-duration").val() * -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
@ -24,6 +24,8 @@ module.exports = function(RED) {
|
||||
this.op2 = n.op2 || "0";
|
||||
this.op1type = n.op1type || "str";
|
||||
this.op2type = n.op2type || "str";
|
||||
this.second = (n.outputs == 2) ? true : false;
|
||||
this.topic = n.topic || "topic";
|
||||
|
||||
if (this.op1type === 'val') {
|
||||
if (this.op1 === 'true' || this.op1 === 'false') {
|
||||
@ -112,7 +114,7 @@ module.exports = function(RED) {
|
||||
});
|
||||
|
||||
var processMessage = function(msg) {
|
||||
var topic = msg.topic || "_none";
|
||||
var topic = RED.util.getMessageProperty(msg,node.topic) || "_none";
|
||||
var promise;
|
||||
if (node.bytopic === "all") { topic = "_none"; }
|
||||
node.topics[topic] = node.topics[topic] || {};
|
||||
@ -197,6 +199,9 @@ module.exports = function(RED) {
|
||||
node.send(msg2);
|
||||
}
|
||||
delete node.topics[topic];
|
||||
|
||||
if (node.second === true) { node.send([null,msg2]); }
|
||||
else { node.send(msg2); }
|
||||
node.status({});
|
||||
}).catch(err => {
|
||||
node.error(err);
|
||||
@ -246,7 +251,8 @@ module.exports = function(RED) {
|
||||
}
|
||||
delete node.topics[topic];
|
||||
node.status({});
|
||||
node.send(msg2);
|
||||
if (node.second === true) { node.send([null,msg2]); }
|
||||
else { node.send(msg2); }
|
||||
}).catch(err => {
|
||||
node.error(err);
|
||||
});
|
||||
|
@ -40,6 +40,6 @@
|
||||
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 with <code>msg.topic</code> as if they
|
||||
are separate streams.</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>
|
||||
</script>
|
||||
|
@ -302,7 +302,7 @@
|
||||
"wait-for": "wait for",
|
||||
"wait-loop": "resend it every",
|
||||
"for": "Handling",
|
||||
"bytopics": "each msg.topic independently",
|
||||
"bytopics": "each",
|
||||
"alltopics": "all messages",
|
||||
"duration": {
|
||||
"ms": "Milliseconds",
|
||||
@ -311,6 +311,7 @@
|
||||
"h": "Hours"
|
||||
},
|
||||
"extend": " extend delay if new message arrives",
|
||||
"second": " send second message to separate output",
|
||||
"label": {
|
||||
"trigger": "trigger",
|
||||
"trigger-block": "trigger & block",
|
||||
|
@ -302,7 +302,7 @@
|
||||
"wait-for": "指定した時間待機",
|
||||
"wait-loop": "指定した時間間隔毎に送信を繰り返す",
|
||||
"for": "処理対象",
|
||||
"bytopics": "msg.topic毎",
|
||||
"bytopics": "毎",
|
||||
"alltopics": "全メッセージ",
|
||||
"duration": {
|
||||
"ms": "ミリ秒",
|
||||
|
@ -102,20 +102,20 @@ describe('trigger node', function() {
|
||||
function basicTest(type, val, rval) {
|
||||
it('should output 1st value when triggered ('+type+')', function(done) {
|
||||
var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", op1:val, op1type:type, op2:"", op2type:"null", duration:"20", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"} ];
|
||||
{id:"n2", type:"helper"} ];
|
||||
process.env[val] = rval;
|
||||
helper.load(triggerNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
try {
|
||||
if (rval) {
|
||||
msg.should.have.property("payload");
|
||||
should.deepEqual(msg.payload, rval);
|
||||
}
|
||||
else {
|
||||
msg.should.have.property("payload", val);
|
||||
}
|
||||
if (rval) {
|
||||
msg.should.have.property("payload");
|
||||
should.deepEqual(msg.payload, rval);
|
||||
}
|
||||
else {
|
||||
msg.should.have.property("payload", val);
|
||||
}
|
||||
delete process.env[val];
|
||||
done();
|
||||
}
|
||||
@ -127,7 +127,7 @@ describe('trigger node', function() {
|
||||
|
||||
it('should output 2st value when triggered ('+type+')', function(done) {
|
||||
var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", op1:"foo", op1type:"str", op2:val, op2type:type, duration:"20", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"} ];
|
||||
{id:"n2", type:"helper"} ];
|
||||
process.env[val] = rval;
|
||||
helper.load(triggerNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
@ -136,17 +136,17 @@ describe('trigger node', function() {
|
||||
n2.on("input", function(msg) {
|
||||
try {
|
||||
if (c === 0) {
|
||||
msg.should.have.property("payload", "foo");
|
||||
msg.should.have.property("payload", "foo");
|
||||
c++;
|
||||
}
|
||||
else {
|
||||
if (rval) {
|
||||
msg.should.have.property("payload");
|
||||
should.deepEqual(msg.payload, rval);
|
||||
}
|
||||
else {
|
||||
msg.should.have.property("payload", val);
|
||||
}
|
||||
if (rval) {
|
||||
msg.should.have.property("payload");
|
||||
should.deepEqual(msg.payload, rval);
|
||||
}
|
||||
else {
|
||||
msg.should.have.property("payload", val);
|
||||
}
|
||||
delete process.env[val];
|
||||
done();
|
||||
}
|
||||
@ -378,6 +378,51 @@ describe('trigger node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle multiple other properties individually if asked to do so', function(done) {
|
||||
var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", bytopic:"topic", topic:"foo", op1:"1", op2:"0", op1type:"num", op2type:"num", duration:"30", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"} ];
|
||||
helper.load(triggerNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
var c = 0;
|
||||
n2.on("input", function(msg) {
|
||||
try {
|
||||
c += 1;
|
||||
if (c === 1) {
|
||||
msg.should.have.a.property("payload", 1);
|
||||
msg.should.have.a.property("foo", "A");
|
||||
}
|
||||
else if (c === 2) {
|
||||
msg.should.have.a.property("payload", 1);
|
||||
msg.should.have.a.property("foo", "B");
|
||||
}
|
||||
else if (c === 3) {
|
||||
msg.should.have.a.property("payload", 1);
|
||||
msg.should.have.a.property("foo", "C");
|
||||
}
|
||||
else if (c === 4) {
|
||||
msg.should.have.a.property("payload", 0);
|
||||
msg.should.have.a.property("foo", "A");
|
||||
}
|
||||
else if (c === 5) {
|
||||
msg.should.have.a.property("payload", 0);
|
||||
msg.should.have.a.property("foo", "B");
|
||||
}
|
||||
else if (c === 6) {
|
||||
msg.should.have.a.property("payload", 0);
|
||||
msg.should.have.a.property("foo", "C");
|
||||
done();
|
||||
}
|
||||
} catch(err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
n1.emit("input", {payload:1,foo:"A"});
|
||||
n1.emit("input", {payload:2,foo:"B"});
|
||||
n1.emit("input", {payload:3,foo:"C"});
|
||||
});
|
||||
});
|
||||
|
||||
it('should be able to return things from flow and global context variables', function(done) {
|
||||
var spy = sinon.stub(RED.util, 'evaluateNodeProperty',
|
||||
function(arg1, arg2, arg3, arg4, arg5) { if (arg5) { arg5(null, arg1) } else { return arg1; } }
|
||||
@ -408,8 +453,8 @@ describe('trigger node', function() {
|
||||
|
||||
it('should be able to return things from persistable flow and global context variables', function (done) {
|
||||
var flow = [{"id": "n1", "type": "trigger", "name": "triggerNode", "op1": "#:(memory1)::foo", "op1type": "flow",
|
||||
"op2": "#:(memory1)::bar", "op2type": "global", "duration": "20", "wires": [["n2"]], "z": "flow" },
|
||||
{"id": "n2", "type": "helper"}];
|
||||
"op2": "#:(memory1)::bar", "op2type": "global", "duration": "20", "wires": [["n2"]], "z": "flow" },
|
||||
{"id": "n2", "type": "helper"}];
|
||||
helper.load(triggerNode, flow, function () {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
@ -442,11 +487,11 @@ describe('trigger node', function() {
|
||||
|
||||
it('should be able to return things from multiple persistable global context variables', function (done) {
|
||||
var flow = [{"id": "n1", "z": "flow", "type": "trigger",
|
||||
"duration": "20", "wires": [["n2"]],
|
||||
"op1": "#:(memory1)::val", "op1type": "global",
|
||||
"op2": "#:(memory2)::val", "op2type": "global"
|
||||
},
|
||||
{"id": "n2", "type": "helper"}];
|
||||
"duration": "20", "wires": [["n2"]],
|
||||
"op1": "#:(memory1)::val", "op1type": "global",
|
||||
"op2": "#:(memory2)::val", "op2type": "global"
|
||||
},
|
||||
{"id": "n2", "type": "helper"}];
|
||||
helper.load(triggerNode, flow, function () {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
@ -481,11 +526,11 @@ describe('trigger node', function() {
|
||||
|
||||
it('should be able to return things from multiple persistable flow context variables', function (done) {
|
||||
var flow = [{"id": "n1", "z": "flow", "type": "trigger",
|
||||
"duration": "20", "wires": [["n2"]],
|
||||
"op1": "#:(memory1)::val", "op1type": "flow",
|
||||
"op2": "#:(memory2)::val", "op2type": "flow"
|
||||
},
|
||||
{"id": "n2", "type": "helper"}];
|
||||
"duration": "20", "wires": [["n2"]],
|
||||
"op1": "#:(memory1)::val", "op1type": "flow",
|
||||
"op2": "#:(memory2)::val", "op2type": "flow"
|
||||
},
|
||||
{"id": "n2", "type": "helper"}];
|
||||
helper.load(triggerNode, flow, function () {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
@ -520,11 +565,11 @@ describe('trigger node', function() {
|
||||
|
||||
it('should be able to return things from multiple persistable flow & global context variables', function (done) {
|
||||
var flow = [{"id": "n1", "z": "flow", "type": "trigger",
|
||||
"duration": "20", "wires": [["n2"]],
|
||||
"op1": "#:(memory1)::val", "op1type": "flow",
|
||||
"op2": "#:(memory2)::val", "op2type": "global"
|
||||
},
|
||||
{"id": "n2", "type": "helper"}];
|
||||
"duration": "20", "wires": [["n2"]],
|
||||
"op1": "#:(memory1)::val", "op1type": "flow",
|
||||
"op2": "#:(memory2)::val", "op2type": "global"
|
||||
},
|
||||
{"id": "n2", "type": "helper"}];
|
||||
helper.load(triggerNode, flow, function () {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
@ -818,6 +863,40 @@ describe('trigger node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should be able to send 2nd message to a 2nd output', function(done) {
|
||||
var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", op1type:"val", op2type:"val", op1:"hello", op2:"world", duration:"50", outputs:2, wires:[["n2"],["n3"]] },
|
||||
{id:"n2", type:"helper"}, {id:"n3", type:"helper"} ];
|
||||
helper.load(triggerNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
var n3 = helper.getNode("n3");
|
||||
var c = 0;
|
||||
n2.on("input", function(msg) {
|
||||
try {
|
||||
if (c === 0) {
|
||||
msg.should.have.a.property("payload", "hello");
|
||||
msg.should.have.a.property("topic", "test");
|
||||
c+=1;
|
||||
}
|
||||
else { done(err); }
|
||||
}
|
||||
catch(err) { done(err); }
|
||||
});
|
||||
n3.on("input", function(msg) {
|
||||
try {
|
||||
if (c === 1) {
|
||||
msg.should.have.a.property("payload", "world");
|
||||
msg.should.have.a.property("topic", "test");
|
||||
done();
|
||||
}
|
||||
else { done(err); }
|
||||
}
|
||||
catch(err) { done(err); }
|
||||
});
|
||||
n1.emit("input", {payload:"go",topic:"test"});
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle string null as null', function(done) {
|
||||
var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", op1type:"val", op2type:"pay", op1:"null", op2:"null", duration:"40", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"} ];
|
||||
|
Loading…
Reference in New Issue
Block a user