diff --git a/io/serialport/25-serial.html b/io/serialport/25-serial.html
index 30469ddd7..39e40cc69 100644
--- a/io/serialport/25-serial.html
+++ b/io/serialport/25-serial.html
@@ -213,8 +213,15 @@
-
+
+
+
+
+
+
+
+
@@ -245,7 +252,9 @@
bin: {value:"false"},
out: {value:"char"},
addchar: {value:""},
- responsetimeout: {value: 10000}
+ responsetimeout: {value: 10000},
+ serialReconnectTime: {value: ""},
+ autoConnect: {value: true}
},
label: function() {
this.serialbaud = this.serialbaud || 57600;
@@ -255,6 +264,13 @@
return this.serialport+":"+this.serialbaud+"-"+this.databits+this.parity.charAt(0).toUpperCase()+this.stopbits;
},
oneditprepare: function() {
+ if(typeof this.autoConnect === "undefined"){ this.autoConnect = true; }
+ var defReconnectTime = RED.settings.serialReconnectTime || 15000;
+ $('#node-config-input-serialReconnectTime').attr('placeholder',Math.round(defReconnectTime/1000));
+ var reconnectms = $('#node-config-input-serialReconnectTime').val();
+ if(reconnectms){
+ $('#node-config-input-serialReconnectTime').val(Math.round(reconnectms/1000));
+ }
var previous = null;
var blist = [
{value:"230400",label:"230400",hasValue:false},
@@ -353,6 +369,11 @@
});
},
oneditsave: function() {
+ var reconnectms = $('#node-config-input-serialReconnectTime').val();
+ if(reconnectms){
+ $('#node-config-input-serialReconnectTime').val(reconnectms*1000);
+ }
+
var mytype = $("#node-config-input-serialbaud").typedInput('type');
if (mytype !== "other") {
$("#node-config-input-serialbaud").typedInput('value',mytype);
diff --git a/io/serialport/25-serial.js b/io/serialport/25-serial.js
index 64093ceb9..4a10d8b92 100644
--- a/io/serialport/25-serial.js
+++ b/io/serialport/25-serial.js
@@ -5,7 +5,6 @@ module.exports = function(RED) {
var events = require("events");
const { SerialPort } = require('serialport');
var bufMaxSize = 32768; // Max serial buffer size, for inputs...
- const serialReconnectTime = settings.serialReconnectTime || 15000;
// TODO: 'serialPool' should be encapsulated in SerialPortNode
@@ -27,6 +26,8 @@ module.exports = function(RED) {
this.out = n.out || "char";
this.waitfor = n.waitfor || "";
this.responsetimeout = n.responsetimeout || 10000;
+ this.serialReconnectTime = n.serialReconnectTime || settings.serialReconnectTime || 15000;
+ this.autoConnect = (typeof n.autoConnect === "undefined")? true : n.autoConnect;
}
RED.nodes.registerType("serial-port",SerialPortNode);
@@ -42,7 +43,16 @@ module.exports = function(RED) {
node.port = serialPool.get(this.serialConfig);
node.on("input",function(msg) {
- if (msg.hasOwnProperty("baudrate")) {
+ if (msg.hasOwnProperty("action") && this.serialConfig) {
+ if(msg.action == "disconnect"){
+ serialPool.disconnect(this.serialConfig.serialport);
+ node.status({fill:"red",shape:"ring",text:"node-red:common.status.not-connected"});
+ }else if(msg.action == "connect"){
+ serialPool.connect(this.serialConfig.serialport);
+ }
+ return;
+ }
+ if (msg.hasOwnProperty("baudrate")) {
var baud = parseInt(msg.baudrate);
if (isNaN(baud)) {
node.error(RED._("serial.errors.badbaudrate"),msg);
@@ -135,6 +145,15 @@ module.exports = function(RED) {
node.port = serialPool.get(this.serialConfig);
// Serial Out
node.on("input",function(msg) {
+ if (msg.hasOwnProperty("action") && this.serialConfig) {
+ if(msg.action == "disconnect"){
+ serialPool.disconnect(this.serialConfig.serialport);
+ node.status({fill:"red",shape:"ring",text:"node-red:common.status.not-connected"});
+ }else if(msg.action == "connect"){
+ serialPool.connect(this.serialConfig.serialport);
+ }
+ return;
+ }
if (msg.hasOwnProperty("baudrate")) {
var baud = parseInt(msg.baudrate);
if (isNaN(baud)) {
@@ -255,11 +274,17 @@ module.exports = function(RED) {
var obj = {
_emitter: new events.EventEmitter(),
serial: null,
+ isOpen: false,
+ forceDc: false,
+ autoConnect: serialConfig.autoConnect,
+ _autoConnect: serialConfig.autoConnect,
_closing: false,
tout: null,
queue: [],
on: function(a,b) { this._emitter.on(a,b); },
close: function(cb) { this.serial.close(cb); },
+ connect: function() { setupSerial(); },
+ disconnect: function(cb) { this.serial.close(cb); },
encodePayload: function (payload) {
if (!Buffer.isBuffer(payload)) {
if (typeof payload === "object") {
@@ -350,30 +375,38 @@ module.exports = function(RED) {
olderr = err.toString();
RED.log.error("[serialconfig:"+serialConfig.id+"] "+RED._("serial.errors.error",{port:port,error:olderr}), {});
}
- obj.tout = setTimeout(function() {
- setupSerial();
- }, serialReconnectTime);
+ if(obj._autoConnect){
+ obj.tout = setTimeout(function() {
+ setupSerial();
+ }, serialConfig.serialReconnectTime);
+ }
}
});
obj.serial.on('error', function(err) {
RED.log.error("[serialconfig:"+serialConfig.id+"] "+RED._("serial.errors.error",{port:port,error:err.toString()}), {});
obj._emitter.emit('closed');
+ obj.isOpen = false;
if (obj.tout) { clearTimeout(obj.tout); }
- obj.tout = setTimeout(function() {
- setupSerial();
- }, serialReconnectTime);
+ if(obj._autoConnect){
+ obj.tout = setTimeout(function() {
+ setupSerial();
+ }, serialConfig.serialReconnectTime);
+ }
});
obj.serial.on('close', function() {
if (!obj._closing) {
- if (olderr !== "unexpected") {
+ if (olderr !== "unexpected" && obj.forceDc == false) {
olderr = "unexpected";
RED.log.error("[serialconfig:"+serialConfig.id+"] "+RED._("serial.errors.unexpected-close",{port:port}), {});
}
+ obj.isOpen = false;
obj._emitter.emit('closed');
- if (obj.tout) { clearTimeout(obj.tout); }
- obj.tout = setTimeout(function() {
- setupSerial();
- }, serialReconnectTime);
+ if(obj._autoConnect){
+ if (obj.tout) { clearTimeout(obj.tout); }
+ obj.tout = setTimeout(function() {
+ setupSerial();
+ }, serialConfig.serialReconnectTime);
+ }
}
});
obj.serial.on('open',function() {
@@ -388,6 +421,7 @@ module.exports = function(RED) {
if (dtr != "none" || rts != "none" || cts != "none" || dsr != "none") { obj.serial.set(flags); }
if (obj.tout) { clearTimeout(obj.tout); obj.tout = null; }
//obj.serial.flush();
+ obj.isOpen = true;
obj._emitter.emit('ready');
});
@@ -483,6 +517,22 @@ module.exports = function(RED) {
else {
done();
}
+ },
+ connect: function(port) {
+ if (connections[port] && connections[port].isOpen == false ) {
+ connections[port]._autoConnect = connections[port].autoConnect; // restore original auto connect config
+ connections[port].connect();
+ }
+ },
+ disconnect: function(port) {
+ if (connections[port] && connections[port].isOpen == true) {
+ connections[port]._autoConnect = false; // disable auto connect on manual disconnect
+ connections[port].forceDc = true; // to prevent logging as an unexpected error
+ connections[port].disconnect(function() {
+ RED.log.info(RED._("serial.errors.closed",{port:port}), {});
+ connections[port].forceDc = false;
+ });
+ }
}
}
}());
diff --git a/io/serialport/locales/en-US/25-serial.html b/io/serialport/locales/en-US/25-serial.html
index 9094acce7..740b15a96 100644
--- a/io/serialport/locales/en-US/25-serial.html
+++ b/io/serialport/locales/en-US/25-serial.html
@@ -32,6 +32,8 @@ Inputs
data to be sent via the serial port
baudrate string
baudrate of the serial port (optional)
+ action string
+ disconnect/reconnect the serial port eg. {action:"connect"} or {action:"disconnect"}(optional)
Only the msg.payload
is sent.
Optionally the baudrate can be changed using msg.baudrate
.
@@ -62,6 +64,7 @@ Inputs
msg.waitfor
must be a 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.
Optionally the baudrate can be changed using msg.baudrate
+ msg.action
disconnect/reconnect the serial port eg. {action:"connect"} or {action:"disconnect"} (optional)
Outputs
diff --git a/io/serialport/locales/en-US/25-serial.json b/io/serialport/locales/en-US/25-serial.json
index c15c6d447..bd70a9656 100644
--- a/io/serialport/locales/en-US/25-serial.json
+++ b/io/serialport/locales/en-US/25-serial.json
@@ -17,11 +17,14 @@
"output": "Output",
"request": "Request",
"responsetimeout": "Default response timeout",
+ "serialReconnectTime": "Reconnect After",
"ms": "ms",
+ "sec": "Seconds",
"serial": "serial",
"none": "none",
"start": "Optionally wait for a start character of",
- "startor": ", then"
+ "startor": ", then",
+ "autoconnect": "Auto Connect"
},
"placeholder": {
"serialport": "for example: /dev/ttyUSB0/"