mirror of
https://github.com/node-red/node-red-nodes.git
synced 2025-03-01 10:37:43 +00:00
port select
This commit is contained in:
parent
4c3e7bff91
commit
98948c8296
@ -230,7 +230,7 @@
|
||||
RED.nodes.registerType('serial-port',{
|
||||
category: 'config',
|
||||
defaults: {
|
||||
//name: {value:""},
|
||||
name: {value:""},
|
||||
serialport: {value:"",required:true},
|
||||
serialbaud: {value:"57600",required:true,validate:RED.validators.number()},
|
||||
databits: {value:8,required:true},
|
||||
@ -252,7 +252,7 @@
|
||||
this.databits = this.databits || 8;
|
||||
this.parity = this.parity || this._("serial.label.none");
|
||||
this.stopbits = this.stopbits || 1;
|
||||
return this.serialport+":"+this.serialbaud+"-"+this.databits+this.parity.charAt(0).toUpperCase()+this.stopbits;
|
||||
return this.name||(this.serialport+":"+this.serialbaud+"-"+this.databits+this.parity.charAt(0).toUpperCase()+this.stopbits);
|
||||
},
|
||||
oneditprepare: function() {
|
||||
var previous = null;
|
||||
@ -361,3 +361,37 @@
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="text/html" data-template-name="port select">
|
||||
<div class="form-row node-input-serial">
|
||||
<label for="node-input-serial"><i class="fa fa-random"></i> <span data-i18n="serial.label.serialport"></span></label>
|
||||
<input type="text" id="node-input-serial">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-inputoutput-name"><i class="fa fa-tag"></i> <span data-i18n="node-red:common.label.name"></span></label>
|
||||
<input type="text" id="node-input-name" data-i18n="[placeholder]node-red:common.label.name">
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('port select',{
|
||||
category: 'network',
|
||||
defaults: {
|
||||
name: {name:""},
|
||||
serial: {type:"serial-port",required:true}
|
||||
},
|
||||
color:"BurlyWood",
|
||||
inputs:1,
|
||||
outputs:1,
|
||||
icon: "serial.png",
|
||||
align: "left",
|
||||
label: function() {
|
||||
var serialNode = RED.nodes.node(this.serial);
|
||||
return this.name||(serialNode?serialNode.label().split(":")[0]:this._("serial.label.serial"));
|
||||
},
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
},
|
||||
outputLabels: function() { return RED.nodes.node(this.serial).bin === "bin" ? "buffer" : "string"; }
|
||||
});
|
||||
</script>
|
@ -27,42 +27,102 @@ module.exports = function(RED) {
|
||||
this.out = n.out || "char";
|
||||
this.waitfor = n.waitfor || "";
|
||||
this.responsetimeout = n.responsetimeout || 10000;
|
||||
}
|
||||
RED.nodes.registerType("serial-port",SerialPortNode);
|
||||
|
||||
this.newPort = (serialPort) => {
|
||||
serialPool.close(this.serialport,() => {});
|
||||
this.serialport = serialPort.port;
|
||||
this.serialbaud = parseInt(serialPort.serialbaud) || this.serialbaud;
|
||||
this.databits = parseInt(serialPort.databits) || this.databits;
|
||||
this.parity = serialPort.parity || this.parity;
|
||||
this.stopbits = parseInt(serialPort.stopbits) || this.stopbits;
|
||||
this.dtr = serialPort.dtr || this.dtr;
|
||||
this.rts = serialPort.rts || this.rts;
|
||||
this.cts = serialPort.cts || this.cts;
|
||||
this.dsr = serialPort.dsr || this.dsr;
|
||||
this.bin = serialPort.bin || this.bin;
|
||||
this.out = serialPort.out || this.out;
|
||||
this.waitfor = serialPort.waitfor || this.waitfor;
|
||||
this.responsetimeout = n.responsetimeout || 10000;
|
||||
return serialPool.get(this);
|
||||
}
|
||||
|
||||
};
|
||||
RED.nodes.registerType("serial-port",SerialPortNode);
|
||||
|
||||
// receives msgs and sends them to the serial port
|
||||
function SerialOutNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.serialConfig = RED.nodes.getNode(n.serial);
|
||||
|
||||
if (!this.serialConfig) {
|
||||
this.error(RED._("serial.errors.missing-conf"), {});
|
||||
return;
|
||||
}
|
||||
|
||||
this.serial = n.serial;
|
||||
this.serialConfig = RED.nodes.getNode(this.serial);
|
||||
var node = this;
|
||||
node.port = serialPool.get(this.serialConfig);
|
||||
var serialConfig = this.serialConfig;
|
||||
|
||||
if (this.serialConfig) {
|
||||
var node = this;
|
||||
node.port = serialPool.get(this.serialConfig);
|
||||
this.serialConfig.on('newport', function(newPort) {
|
||||
node.port = serialPool.get(serialConfig);
|
||||
});
|
||||
|
||||
node.on("input",function(msg) {
|
||||
if (msg.hasOwnProperty("baudrate")) {
|
||||
var baud = parseInt(msg.baudrate);
|
||||
if (isNaN(baud)) {
|
||||
node.error(RED._("serial.errors.badbaudrate"),msg);
|
||||
} else {
|
||||
node.port.update({baudRate: baud},function(err,res) {
|
||||
if (err) {
|
||||
var errmsg = err.toString().replace("Serialport","Serialport "+node.port.serial.path);
|
||||
node.error(errmsg,msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
node.on("input",function(msg) {
|
||||
if (msg.hasOwnProperty("baudrate")) {
|
||||
var baud = parseInt(msg.baudrate);
|
||||
if (isNaN(baud)) {
|
||||
node.error(RED._("serial.errors.badbaudrate"),msg);
|
||||
} else {
|
||||
node.port.update({baudRate: baud},function(err,res) {
|
||||
if (err) {
|
||||
var errmsg = err.toString().replace("Serialport","Serialport "+node.port.serial.path);
|
||||
node.error(errmsg,msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (!msg.hasOwnProperty("payload")) { return; } // do nothing unless we have a payload
|
||||
var payload = node.port.encodePayload(msg.payload);
|
||||
node.port.write(payload,function(err,res) {
|
||||
if (err) {
|
||||
var errmsg = err.toString().replace("Serialport","Serialport "+node.port.serial.path);
|
||||
node.error(errmsg,msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (!msg.hasOwnProperty("payload")) { return; } // do nothing unless we have a payload
|
||||
var payload = node.port.encodePayload(msg.payload);
|
||||
node.port.write(payload,function(err,res) {
|
||||
if (err) {
|
||||
var errmsg = err.toString().replace("Serialport","Serialport "+node.port.serial.path);
|
||||
node.error(errmsg,msg);
|
||||
}
|
||||
});
|
||||
});
|
||||
node.port.on('ready', function() {
|
||||
node.status({fill:"green",shape:"dot",text:"node-red:common.status.connected"});
|
||||
});
|
||||
node.port.on('closed', function() {
|
||||
node.status({fill:"red",shape:"ring",text:"node-red:common.status.not-connected"});
|
||||
});
|
||||
}
|
||||
RED.nodes.registerType("serial out",SerialOutNode);
|
||||
|
||||
// receives data from the serial port and emits msgs
|
||||
function SerialInNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.serialConfig = RED.nodes.getNode(n.serial);
|
||||
|
||||
if (!this.serialConfig) {
|
||||
this.error(RED._("serial.errors.missing-conf"), {});
|
||||
return;
|
||||
}
|
||||
|
||||
this.serial = n.serial;
|
||||
var node = this;
|
||||
|
||||
this.serialConfig.on('newport', function(newPort) {
|
||||
setCallback(node, node.serialConfig);
|
||||
});
|
||||
|
||||
function setCallback(node) {
|
||||
node.status({fill:"grey",shape:"dot",text:"node-red:common.status.not-connected"});
|
||||
node.port = serialPool.get(node.serialConfig);
|
||||
|
||||
node.port.on('data', function(msgout) {
|
||||
node.send(msgout);
|
||||
});
|
||||
node.port.on('ready', function() {
|
||||
node.status({fill:"green",shape:"dot",text:"node-red:common.status.connected"});
|
||||
@ -70,56 +130,8 @@ module.exports = function(RED) {
|
||||
node.port.on('closed', function() {
|
||||
node.status({fill:"red",shape:"ring",text:"node-red:common.status.not-connected"});
|
||||
});
|
||||
}
|
||||
else {
|
||||
this.error(RED._("serial.errors.missing-conf"), {});
|
||||
}
|
||||
|
||||
this.on("close", function(done) {
|
||||
if (this.serialConfig) {
|
||||
serialPool.close(this.serialConfig.serialport,done);
|
||||
}
|
||||
else {
|
||||
done();
|
||||
}
|
||||
});
|
||||
}
|
||||
RED.nodes.registerType("serial out",SerialOutNode);
|
||||
|
||||
|
||||
// receives data from the serial port and emits msgs
|
||||
function SerialInNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.serial = n.serial;
|
||||
this.serialConfig = RED.nodes.getNode(this.serial);
|
||||
|
||||
if (this.serialConfig) {
|
||||
var node = this;
|
||||
node.status({fill:"grey",shape:"dot",text:"node-red:common.status.not-connected"});
|
||||
node.port = serialPool.get(this.serialConfig);
|
||||
|
||||
this.port.on('data', function(msgout) {
|
||||
node.send(msgout);
|
||||
});
|
||||
this.port.on('ready', function() {
|
||||
node.status({fill:"green",shape:"dot",text:"node-red:common.status.connected"});
|
||||
});
|
||||
this.port.on('closed', function() {
|
||||
node.status({fill:"red",shape:"ring",text:"node-red:common.status.not-connected"});
|
||||
});
|
||||
}
|
||||
else {
|
||||
this.error(RED._("serial.errors.missing-conf"), {});
|
||||
}
|
||||
|
||||
this.on("close", function(done) {
|
||||
if (this.serialConfig) {
|
||||
serialPool.close(this.serialConfig.serialport,done);
|
||||
}
|
||||
else {
|
||||
done();
|
||||
}
|
||||
});
|
||||
};
|
||||
setCallback(node)
|
||||
}
|
||||
RED.nodes.registerType("serial in",SerialInNode);
|
||||
|
||||
@ -200,6 +212,32 @@ module.exports = function(RED) {
|
||||
}
|
||||
RED.nodes.registerType("serial request", SerialRequestNode);
|
||||
|
||||
|
||||
// Port Select Node
|
||||
function PortSelectNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.serialConfig = RED.nodes.getNode(n.serial);
|
||||
|
||||
if (!this.serialConfig) {
|
||||
this.error(RED._("serial.errors.missing-conf"), {});
|
||||
return;
|
||||
}
|
||||
|
||||
this.serial = n.serial;
|
||||
var node = this;
|
||||
node.port = serialPool.get(this.serialConfig);
|
||||
node.on("input",function(msg) {
|
||||
if (msg.payload.hasOwnProperty("port")) {
|
||||
node.serialConfig.newPort(msg.payload);
|
||||
node.serialConfig.emit('newport',msg.payload);
|
||||
node.send(msg);
|
||||
} else {
|
||||
node.send({payload: {port: node.serialConfig.serialport}});
|
||||
}
|
||||
});
|
||||
}
|
||||
RED.nodes.registerType("port select", PortSelectNode);
|
||||
|
||||
var serialPool = (function() {
|
||||
var connections = {};
|
||||
return {
|
||||
|
@ -55,3 +55,18 @@ This node behaves as a tightly coupled combination of serial in and serial out n
|
||||
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 on the output, with msg.payload containing the received response (or missing in case if timeout), msg.status containing relevant info, and all other fields preserved.
|
||||
|
||||
For consistency with the serial in node, msg.port is also set to the name of the port selected.
|
||||
|
||||
### Port Select
|
||||
|
||||
Provides the capability to change the serial ports on the run time programatically.
|
||||
|
||||
When you start the node-red, the flow(program) picks up the pre-programmed serial ports and open them. But when a device re-connects after disconnecting for any reason, it may be possible the port number change, and the end user of the flow can't change the port. With this `port selection node`, it's possible to let the user change the port while running the program by sending a message like this.
|
||||
```json
|
||||
{
|
||||
"port": "/dev/tty.usbmodem1234561",
|
||||
"serialbaud": 115200,
|
||||
"databits": 8,
|
||||
"parity": "none",
|
||||
"stopbits": 1
|
||||
}
|
||||
```
|
||||
|
Loading…
x
Reference in New Issue
Block a user