diff --git a/hardware/Arduino/35-arduino.html b/hardware/Arduino/35-arduino.html index 4cd1fef1..90df533b 100644 --- a/hardware/Arduino/35-arduino.html +++ b/hardware/Arduino/35-arduino.html @@ -62,7 +62,7 @@ @@ -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..c039e30d 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,18 +197,24 @@ 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); } + 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; } + connections[id] = (function() { var obj = { _emitter: new events.EventEmitter(), @@ -220,10 +232,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 +299,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 +344,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..845167da 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.1", "description" : "Node-RED nodes to talk to serial ports", "dependencies" : { "serialport" : "^7.1.4" diff --git a/social/email/61-email.js b/social/email/61-email.js index acf8ebd9..e9cc7974 100644 --- a/social/email/61-email.js +++ b/social/email/61-email.js @@ -116,10 +116,10 @@ module.exports = function(RED) { smtpTransport.sendMail(sendopts, function(error, info) { if (error) { node.error(error,msg); - node.status({fill:"red",shape:"ring",text:"email.status.sendfail"}); + node.status({fill:"red",shape:"ring",text:"email.status.sendfail",response:error.response,msg:{to:msg.to,topic:msg.topic,id:msg._msgid}}); } else { node.log(RED._("email.status.messagesent",{response:info.response})); - node.status({}); + node.status({text:"",response:info.response,msg:{to:msg.to,topic:msg.topic,id:msg._msgid}}); } }); } @@ -357,7 +357,7 @@ module.exports = function(RED) { //console.log("> search - err=%j, results=%j", err, results); if (results.length === 0) { //console.log(" [X] - Nothing to fetch"); - node.status({}); + node.status({results:0}); imap.end(); s = false; setInputRepeatTimeout(); @@ -397,7 +397,7 @@ module.exports = function(RED) { // When we have fetched all the messages, we don't need the imap connection any more. fetch.on('end', function() { - node.status({}); + node.status({results:results.length}); var cleanup = function() { imap.end(); s = false; diff --git a/social/email/package.json b/social/email/package.json index 62e3ac5f..28a7884a 100644 --- a/social/email/package.json +++ b/social/email/package.json @@ -1,11 +1,11 @@ { "name": "node-red-node-email", - "version": "1.3.0", + "version": "1.4.0", "description": "Node-RED nodes to send and receive simple emails", "dependencies": { "imap": "^0.8.19", "mailparser-mit": "^1.0.0", - "nodemailer": "^4.7.0", + "nodemailer": "^5.1.1", "poplib": "^0.1.7" }, "repository": {