diff --git a/io/serialport/25-serial.html b/io/serialport/25-serial.html
index 835ad5a9..b78905f5 100644
--- a/io/serialport/25-serial.html
+++ b/io/serialport/25-serial.html
@@ -99,7 +99,7 @@
with which it shares the configuration.
Send the request message in msg.payload as you would do with a serial out node.
The message will be forwarded to the serial port following a strict FIFO (First In, First Out) queue, waiting for a single response before transmitting the next request.
- Once a response is received (with the same logic of a serial in node), or after a timeout occurs, a message is produced to the output (see Outputs below),
+ Once a response is received (with the same logic of a serial in node), or after a timeout occurs, a message is sent to the output (see Outputs below),
with msg.payload containing the received response (or missing in case if timeout) and all other fields preserved.
For consistency with the serial in node, msg.port is set to the name of the port selected.
Inputs
@@ -108,7 +108,8 @@
msg.timeout is the timeout (in ms) after which the incoming message is propagated to the output with msg.status set to "ERR_TIMEOUT" and missing payload.
If not present, the default value is 10000 (10s).
-
Any other field will be propagated to the output so to allow to match responses with requests.
+
msg.count if set this will override the configured number of characters as long as it is less than the number configured.
+
msg.waitfor single character, escape code, or hex code. If set, the node will wait until it matches that character in the stream and then start the output.
Outputs
@@ -178,59 +179,66 @@
-
-
+
-
+
+
+
+
+
+
-
-
+
-
+
-
-
+
-
-
+
+
+
-
-
-
+
+
-
+
-
+
+
+
+
@@ -244,6 +252,7 @@
databits: {value:8,required:true},
parity: {value:"none",required:true},
stopbits: {value:1,required:true},
+ waitfor: {value:""},
newline: {value:"\\n"},
bin: {value:"false"},
out: {value:"char"},
@@ -290,41 +299,50 @@
if ($("#node-config-input-out").val() == "char") {
if (previous != "char") { $("#node-config-input-newline").val("\\n"); }
$("#node-units").text("");
- $("#node-config-addchar").show();
+ // $("#node-config-addchar").show();
$("#tip-split").show();
$("#tip-timeout").hide();
$("#tip-silent").hide();
+ $("#tip-count").hide();
}
else if ($("#node-config-input-out").val() == "time") {
if (previous != "time") { $("#node-config-input-newline").val("0"); }
$("#node-units").text("ms");
- $("#node-config-addchar").hide();
- $("#node-config-input-addchar").val("false");
+ // $("#node-config-addchar").hide();
+ // $("#node-config-input-addchar").val("false");
$("#tip-split").hide();
$("#tip-timeout").show();
$("#tip-silent").hide();
+ $("#tip-count").hide();
}
else if ($("#node-config-input-out").val() == "interbyte") {
if (previous != "interbyte") { $("#node-config-input-newline").val("0"); }
$("#node-units").text("ms");
- $("#node-config-addchar").hide();
- $("#node-config-input-addchar").val("false");
+ // $("#node-config-addchar").hide();
+ // $("#node-config-input-addchar").val("false");
$("#tip-split").hide();
$("#tip-timeout").hide();
$("#tip-silent").show();
+ $("#tip-count").hide();
}
else {
if (previous != "count") { $("#node-config-input-newline").val(""); }
$("#node-units").text("chars");
- $("#node-config-addchar").hide();
- $("#node-config-input-addchar").val("false");
+ // $("#node-config-addchar").hide();
+ // $("#node-config-input-addchar").val("false");
$("#tip-split").hide();
$("#tip-timeout").hide();
$("#tip-silent").hide();
+ $("#tip-count").show();
}
});
$("#node-config-input-responsetimeout").on('focus', function () { $("#tip-responsetimeout").show(); });
+ $("#node-config-input-responsetimeout").on('blur', function () { $("#tip-responsetimeout").hide(); });
+ $("#node-config-input-waitfor").on('focus', function () { $("#tip-waitfor").show(); });
+ $("#node-config-input-waitfor").on('blur', function () { $("#tip-waitfor").hide(); });
+ $("#node-config-input-addchar").on('focus', function () { $("#tip-addchar").show(); });
+ $("#node-config-input-addchar").on('blur', function () { $("#tip-addchar").hide(); });
try {
$("#node-config-input-serialport").autocomplete( "destroy" );
diff --git a/io/serialport/25-serial.js b/io/serialport/25-serial.js
index 0a02a89d..d94c4e21 100644
--- a/io/serialport/25-serial.js
+++ b/io/serialport/25-serial.js
@@ -13,13 +13,14 @@ module.exports = function(RED) {
RED.nodes.createNode(this,n);
this.serialport = n.serialport;
this.newline = n.newline; /* overloaded: split character, timeout, or character count */
- this.addchar = n.addchar || "false";
+ this.addchar = n.addchar || "";
this.serialbaud = parseInt(n.serialbaud) || 57600;
this.databits = parseInt(n.databits) || 8;
this.parity = n.parity || "none";
this.stopbits = parseInt(n.stopbits) || 1;
this.bin = n.bin || "false";
this.out = n.out || "char";
+ this.waitfor = n.waitfor || "";
this.responsetimeout = n.responsetimeout || 10000;
}
RED.nodes.registerType("serial-port",SerialPortNode);
@@ -117,6 +118,10 @@ module.exports = function(RED) {
// Serial Out
node.on("input",function(msg) {
if (!msg.hasOwnProperty("payload")) { return; } // do nothing unless we have a payload
+ if (msg.hasOwnProperty("count") && (typeof msg.count === "number") && (node.serialConfig.out === "count")) {
+ node.serialConfig.newline = msg.count;
+ }
+ if (msg.hasOwnProperty("flush") && msg.flush === true) { node.port.serial.flush(); }
node.status({fill:"yellow",shape:"dot",text:"serial.status.waiting"});
node.port.enqueue(msg,node,function(err,res) {
if (err) {
@@ -176,6 +181,7 @@ module.exports = function(RED) {
stopbits = serialConfig.stopbits,
newline = serialConfig.newline,
spliton = serialConfig.out,
+ waitfor = serialConfig.waitfor,
binoutput = serialConfig.bin,
addchar = serialConfig.addchar,
responsetimeout = serialConfig.responsetimeout;
@@ -191,17 +197,25 @@ module.exports = function(RED) {
// "time" : a msg will be sent after .newline milliseconds
// "count" : a msg will be sent after .newline characters
// if we use "count", we already know how big the buffer will be
- var bufSize = spliton == "count" ? Number(newline): bufMaxSize;
- var buf = new Buffer(bufSize);
+ var bufSize = (spliton === "count") ? Number(newline): bufMaxSize;
+
+ waitfor = waitfor.replace("\\n","\n").replace("\\r","\r").replace("\\t","\t").replace("\\e","\e").replace("\\f","\f").replace("\\0","\0"); // jshint ignore:line
+ if (waitfor.substr(0,2) == "0x") { waitfor = parseInt(waitfor,16); }
+ if (waitfor.length === 1) { waitfor = waitfor.charCodeAt(0); }
+ console.log("WF2",waitfor);
+ var active = (waitfor === "") ? true : false;
+ var buf = new Buffer.alloc(bufSize);
var splitc; // split character
// Parse the split character onto a 1-char buffer we can immediately compare against
if (newline.substr(0,2) == "0x") {
- splitc = new Buffer([parseInt(newline)]);
+ splitc = new Buffer.alloc([parseInt(newline,16)]);
}
else {
- splitc = new Buffer(newline.replace("\\n","\n").replace("\\r","\r").replace("\\t","\t").replace("\\e","\e").replace("\\f","\f").replace("\\0","\0")); // jshint ignore:line
+ splitc = new Buffer.from(newline.replace("\\n","\n").replace("\\r","\r").replace("\\t","\t").replace("\\e","\e").replace("\\f","\f").replace("\\0","\0")); // jshint ignore:line
}
+ if (addchar === true) { addchar = splitc; }
+ console.log("AC:",addchar,":");
connections[id] = (function() {
var obj = {
@@ -220,10 +234,10 @@ module.exports = function(RED) {
else {
payload = payload.toString();
}
- if ((spliton === "char") && (addchar === true)) { payload += splitc; }
+ if ((spliton === "char") && (addchar !== "")) { payload += addchar; }
}
- else if ((spliton === "char") && (addchar === true) && (splitc !== "")) {
- payload = Buffer.concat([payload,splitc]);
+ else if ((spliton === "char") && (addchar !== "")) {
+ payload = Buffer.concat([payload,addchar]);
}
return payload;
},
@@ -287,6 +301,7 @@ module.exports = function(RED) {
//newline = newline.replace("\\n","\n").replace("\\r","\r");
var olderr = "";
var setupSerial = function() {
+
obj.serial = new serialp(port,{
baudRate: baud,
dataBits: databits,
@@ -331,23 +346,26 @@ module.exports = function(RED) {
obj.serial.on('data',function(d) {
function emitData(data) {
- var m = Buffer.from(data);
- var last_sender = null;
- if (obj.queue.length) { last_sender = obj.queue[0].sender; }
- if (binoutput !== "bin") { m = m.toString(); }
- var msgout = obj.dequeue() || {};
- msgout.payload = m;
- msgout.port = port;
- obj._emitter.emit('data',
- msgout,
- last_sender);
+ if (active === true) {
+ var m = Buffer.from(data);
+ var last_sender = null;
+ if (obj.queue.length) { last_sender = obj.queue[0].sender; }
+ if (binoutput !== "bin") { m = m.toString(); }
+ var msgout = obj.dequeue() || {};
+ msgout.payload = m;
+ msgout.port = port;
+ obj._emitter.emit('data', msgout, last_sender);
+ }
+ active = (waitfor === "") ? true : false;
}
for (var z=0; z= parseInt(newline)) {
emitData(buf.slice(0,i));
i=0;
diff --git a/io/serialport/locales/en-US/25-serial.json b/io/serialport/locales/en-US/25-serial.json
index e6246c27..46ea9641 100644
--- a/io/serialport/locales/en-US/25-serial.json
+++ b/io/serialport/locales/en-US/25-serial.json
@@ -19,7 +19,9 @@
"responsetimeout": "Default response timeout",
"ms": "ms",
"serial": "serial",
- "none": "none"
+ "none": "none",
+ "start": "Optionally wait for a start character of",
+ "startor": ", then"
},
"placeholder": {
"serialport": "for example: /dev/ttyUSB0/"
@@ -41,12 +43,15 @@
"ascii": "ascii strings",
"binary": "binary buffers"
},
- "addsplit": "add split character to output messages",
+ "addsplit": "Add character to output messages",
"tip": {
"responsetimeout": "Tip: The default response timeout can be overridden by setting msg.timeout.",
- "split": "Tip: the \"Split on\" character is used to split the input into separate messages. It can also be added to every message sent out to the serial port.",
+ "split": "Tip: the \"Split on\" character is used to split the input into separate messages. Can accept chars ($), escape codes (\\n), or hex codes (0x03).",
"silent": "Tip: In line-silent mode timeout is restarted upon arrival of any character (i.e. inter-byte timeout).",
- "timeout": "Tip: In timeout mode timeout starts from arrival of first character."
+ "timeout": "Tip: In timeout mode timeout starts from arrival of first character.",
+ "count": "Tip: In count mode msg.count can override the configured count as long as it smaller than the configured value.",
+ "waitfor": "Tip: Optional. Leave blank to receive all data. Can accept chars ($), escape codes (\\n), or hex codes (0x02)." ,
+ "addchar": "Tip: This character is added to every message sent out to the serial port. Usually \\r or \\n."
},
"onopen": "serial port __port__ opened at __baud__ baud __config__",
"errors": {
diff --git a/io/serialport/package.json b/io/serialport/package.json
index f0214b22..e78c7b1e 100644
--- a/io/serialport/package.json
+++ b/io/serialport/package.json
@@ -1,6 +1,6 @@
{
"name" : "node-red-node-serialport",
- "version" : "0.7.1",
+ "version" : "0.8.0",
"description" : "Node-RED nodes to talk to serial ports",
"dependencies" : {
"serialport" : "^7.1.4"