Dia antes primera install

This commit is contained in:
2025-12-08 15:20:28 -06:00
commit 1416478c9c
4130 changed files with 886376 additions and 0 deletions

401
node_modules/node-red-node-serialport/25-serial.html generated vendored Normal file
View File

@@ -0,0 +1,401 @@
<script type="text/html" data-template-name="serial in">
<div class="form-row">
<label for="node-input-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>
<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>
</script>
<script type="text/javascript">
RED.nodes.registerType('serial in',{
category: 'network',
defaults: {
name: {name:""},
serial: {type:"serial-port",required:true}
},
color:"BurlyWood",
inputs:0,
outputs:1,
icon: "serial.png",
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>
<script type="text/html" data-template-name="serial out">
<div class="form-row">
<label for="node-input-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>
<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>
</script>
<script type="text/javascript">
RED.nodes.registerType('serial out',{
category: 'network',
defaults: {
name: {name:""},
serial: {type:"serial-port",required:true}
},
color:"BurlyWood",
inputs:1,
outputs:0,
icon: "serial.png",
align: "right",
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":"";
}
});
</script>
<script type="text/html" data-template-name="serial request">
<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>
<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>
</script>
<script type="text/javascript">
RED.nodes.registerType('serial request',{
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>
<script type="text/html" data-template-name="serial-port">
<div class="form-row">
<label for="node-config-input-name"><i class="fa fa-tag"></i> <span data-i18n="node-red:common.label.name"></span></label>
<input type="text" id="node-config-input-name" data-i18n="[placeholder]node-red:common.label.name">
</div>
<div class="form-row">
<label for="node-config-input-serialport"><i class="fa fa-random"></i> <span data-i18n="serial.label.serialport"></span></label>
<input type="text" id="node-config-input-serialport" style="width:66%;" data-i18n="[placeholder]serial.placeholder.serialport">
<a id="node-config-lookup-serial" class="red-ui-button"><i id="node-config-lookup-serial-icon" class="fa fa-search"></i></a>
</div>
<div class="form-row" style="margin-bottom:8px;">
<table width="100%">
<tr style="line-height:10px;">
<td width="90px" style="font-size:14px;"><i class="fa fa-wrench"></i> <span data-i18n="serial.label.settings"></span></td>
<td width="110px" data-i18n="serial.label.baudrate"></td>
<td width="70px" data-i18n="serial.label.databits"></td>
<td width="80px" data-i18n="serial.label.parity"></td>
<td width="70px" data-i18n="serial.label.stopbits"></td>
</tr>
<tr>
<td>&nbsp;</td>
<td>
<input type="text" id="node-config-input-serialbaud" style="width:92%; height:30px;">
</td>
<td><select type="text" id="node-config-input-databits" style="width:90%; height:30px;">
<option value="8">8</option>
<option value="7">7</option>
<option value="6">6</option>
<option value="5">5</option>
</select></td>
<td><select type="text" id="node-config-input-parity" style="width:90%; height:30px;">
<option value="none" data-i18n="serial.parity.none"></option>
<option value="even" data-i18n="serial.parity.even"></option>
<option value="mark" data-i18n="serial.parity.mark"></option>
<option value="odd" data-i18n="serial.parity.odd"></option>
<option value="space" data-i18n="serial.parity.space"></option>
</select></td>
<td><select type="text" id="node-config-input-stopbits" style="width:60px; height:30px;">
<option value="2">2</option>
<option value="1">1</option>
</select></td>
</tr></table>
</div>
<div class="form-row" style="margin-bottom:0px;">
<table width="100%">
<tr style="line-height:10px;">
<td style="width:90px;">&nbsp;</td>
<td>DTR</td>
<td>RTS</td>
<td>CTS</td>
<td>DSR</td>
</tr>
<tr>
<td>&nbsp;</td>
<td><select type="text" id="node-config-input-dtr" style="width:72px; height:30px;">
<option value="none" data-i18n="serial.linestates.none"></option>
<option value="high" data-i18n="serial.linestates.high"></option>
<option value="low" data-i18n="serial.linestates.low"></option>
</select></td>
<td><select type="text" id="node-config-input-rts" style="width:72px; height:30px;">
<option value="none" data-i18n="serial.linestates.none"></option>
<option value="high" data-i18n="serial.linestates.high"></option>
<option value="low" data-i18n="serial.linestates.low"></option>
</select></td>
<td><select type="text" id="node-config-input-cts" style="width:72px; height:30px;">
<option value="none" data-i18n="serial.linestates.none"></option>
<option value="high" data-i18n="serial.linestates.high"></option>
<option value="low" data-i18n="serial.linestates.low"></option>
</select></td>
<td><select type="text" id="node-config-input-dsr" style="width:72px; height:30px;">
<option value="none" data-i18n="serial.linestates.none"></option>
<option value="high" data-i18n="serial.linestates.high"></option>
<option value="low" data-i18n="serial.linestates.low"></option>
</select></td>
</tr>
</table>
</div>
<div class="form-row" style="margin-top:12px; margin-bottom:0;">
<label><i class="fa fa-sign-in"></i> <span data-i18n="serial.label.input"></span></label>
</div>
<div class="form-row" style="padding-left:18px; margin-bottom:4px;">
<span data-i18n="serial.label.start"></span>
<input type="text" id="node-config-input-waitfor" style="width:50px; height:28px; text-decoration:grey dotted underline;">
<span data-i18n="serial.label.startor"></span>
</div>
<div class="form-row" style="padding-left:18px; margin-bottom:4px;">
<span data-i18n="serial.label.split"></span>
<select type="text" id="node-config-input-out" style="margin-left:11px; width:200px;">
<option value="char" data-i18n="serial.split.character"></option>
<option value="time" data-i18n="serial.split.timeout"></option>
<option value="interbyte" data-i18n="serial.split.silent"></option>
<option value="count" data-i18n="serial.split.lengths"></option>
</select>
<input type="text" id="node-config-input-newline" style="width:50px;">
<span id="node-units"></span>
</div>
<div class="form-row" style="padding-left:18px; margin-bottom:4px;">
<span data-i18n="serial.label.deliver"></span>
<select type="text" id="node-config-input-bin" style="margin-left:5px; width:150px;">
<option value="false" data-i18n="serial.output.ascii"></option>
<option value="bin" data-i18n="serial.output.binary"></option>
</select>
</div>
<div id="node-config-addchar">
<div class="form-row" style="margin-top:16px; margin-bottom:0;">
<label><i class="fa fa-sign-out"></i> <span data-i18n="serial.label.output"></span></label>
</div>
<div class="form-row" style="padding-left:18px; margin-bottom:4px;">
<label style="width:auto;" for="node-config-input-addchar"><span data-i18n="serial.addsplit"></span></label>
<input type="text" id="node-config-input-addchar" style="width:50px; height:28px; text-decoration:grey dotted underline;">
</div>
</div>
<div id="node-config-req">
<div class="form-row" style="margin-top:16px; margin-bottom:0;">
<label><i class="fa fa-exchange"></i> <span data-i18n="serial.label.request"></span></label>
</div>
<div class="form-row" style="padding-left:18px; margin-bottom:18px;">
<span data-i18n="serial.label.responsetimeout"></span>
<input type="text" id="node-config-input-responsetimeout" style="width:60px; height:28px;">
<span data-i18n="serial.label.ms"></span>
</div>
</div>
<div class="form-tips" id="tip-waitfor" hidden><span data-i18n="serial.tip.waitfor"></span></div>
<div class="form-tips" id="tip-addchar" hidden><span data-i18n="serial.tip.addchar"></span></div>
<div class="form-tips" id="tip-responsetimeout" hidden><span data-i18n="serial.tip.responsetimeout"></span></div>
<div class="form-tips" id="tip-split"><span data-i18n="serial.tip.split"></span></div>
<div class="form-tips" id="tip-timeout" hidden><span data-i18n="serial.tip.timeout"></span></div>
<div class="form-tips" id="tip-silent" hidden><span data-i18n="serial.tip.silent"></span></div>
<div class="form-tips" id="tip-count" hidden><span data-i18n="serial.tip.count"></span></div>
</script>
<script type="text/javascript">
RED.nodes.registerType('serial-port',{
category: 'config',
defaults: {
name: {value:""},
serialport: {value:"",required:true},
serialbaud: {value:"57600",required:true,validate:RED.validators.number()},
databits: {value:8,required:true},
parity: {value:"none",required:true},
stopbits: {value:1,required:true},
waitfor: {value:""},
dtr: {value:"none"},
rts: {value:"none"},
cts: {value:"none"},
dsr: {value:"none"},
newline: {value:"\\n"},
bin: {value:"false"},
out: {value:"char"},
addchar: {value:""},
responsetimeout: {value: 10000}
},
label: function() {
this.serialbaud = this.serialbaud || 57600;
this.databits = this.databits || 8;
this.parity = this.parity || this._("serial.label.none");
this.stopbits = this.stopbits || 1;
return this.name||(this.serialport+":"+this.serialbaud+"-"+this.databits+this.parity.charAt(0).toUpperCase()+this.stopbits);
},
oneditprepare: function() {
var previous = null;
var blist = [
{value:"230400",label:"230400",hasValue:false},
{value:"115200",label:"115200",hasValue:false},
{value:"57600",label:"57600",hasValue:false},
{value:"38400",label:"38400",hasValue:false},
{value:"19200",label:"19200",hasValue:false},
{value:"9600",label:"9600",hasValue:false},
{value:"4800",label:"4800",hasValue:false},
{value:"2400",label:"2400",hasValue:false},
{value:"1200",label:"1200",hasValue:false},
{value:"600",label:"600",hasValue:false},
{value:"300",label:"300",hasValue:false},
{label:"other",value:"other",icon:"red/images/typedInput/09.png",validate:/^[0-9]*$/}
];
var serialbaudType = "custom";
for (var i in blist) {
if (this.serialbaud == blist[i].value) {
serialbaudType = this.serialbaud;
}
}
$("#node-config-input-serialbaud").typedInput({
default: this.serialbaud,
types:blist
});
$("#node-config-input-out").on('focus', function () { previous = this.value; }).change(function() {
if (previous == null) { previous = $("#node-config-input-out").val(); }
if ($("#node-config-input-out").val() == "char") {
if (previous != "char") { $("#node-config-input-newline").val("\\n"); }
$("#node-units").text("");
// $("#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");
$("#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");
$("#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");
$("#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" );
} catch(err) {
}
$("#node-config-lookup-serial").click(function() {
$("#node-config-lookup-serial").addClass('disabled');
$.getJSON('serialports',function(data) {
$("#node-config-lookup-serial").removeClass('disabled');
var ports = data || [];
$("#node-config-input-serialport").autocomplete({
source:ports,
minLength:0,
close: function( event, ui ) {
$("#node-config-input-serialport").autocomplete( "destroy" );
}
}).autocomplete("search","");
});
});
},
oneditsave: function() {
var mytype = $("#node-config-input-serialbaud").typedInput('type');
if (mytype !== "other") {
$("#node-config-input-serialbaud").typedInput('value',mytype);
}
this.serialbaud = $("#node-config-input-serialbaud").typedInput('value');
}
});
</script>
<script type="text/html" data-template-name="serial control">
<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>
<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>
</script>
<script type="text/javascript">
RED.nodes.registerType('serial control',{
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>

591
node_modules/node-red-node-serialport/25-serial.js generated vendored Normal file
View File

@@ -0,0 +1,591 @@
module.exports = function(RED) {
/*jshint -W082 */
"use strict";
var settings = RED.settings;
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
// Configuration Node
function SerialPortNode(n) {
RED.nodes.createNode(this,n);
this.serialport = n.serialport;
this.newline = n.newline; /* overloaded: split character, timeout, or character count */
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.dtr = n.dtr || "none";
this.rts = n.rts || "none";
this.cts = n.cts || "none";
this.dsr = n.dsr || "none";
this.bin = n.bin || "false";
this.out = n.out || "char";
this.enabled = n.enabled || true;
this.waitfor = n.waitfor || "";
this.responsetimeout = n.responsetimeout || 10000;
this.changePort = (serialPort) => {
serialPool.close(this.serialport,() => {});
this.serialport = serialPort.serialport || this.serialport;
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;
}
}
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;
var node = this;
node.port = serialPool.get(this.serialConfig);
var serialConfig = this.serialConfig;
this.serialConfig.on('start', function() {
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);
}
});
}
}
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"});
});
node.port.on('stopped', function() {
node.status({fill:"grey",shape:"ring",text:"serial.status.stopped"});
});
}
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('start', function() {
setCallback(node, node.serialConfig);
});
this.on("close", function(done) {
serialPool.close(this.serialConfig.serialport,done);
});
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"});
});
node.port.on('closed', function() {
node.status({fill:"red",shape:"ring",text:"node-red:common.status.not-connected"});
});
node.port.on('stopped', function() {
node.status({fill:"grey",shape:"ring",text:"serial.status.stopped"});
});
}
setCallback(node)
}
RED.nodes.registerType("serial in",SerialInNode);
// request data and waits for reply
function SerialRequestNode(n) {
RED.nodes.createNode(this,n);
this.serial = n.serial;
this.serialConfig = RED.nodes.getNode(this.serial);
if (this.serialConfig) {
var node = this;
node.port = serialPool.get(this.serialConfig);
// Serial Out
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
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) {
var errmsg = err.toString().replace("Serialport","Serialport "+node.port.serial.path);
node.error(errmsg,msg);
}
});
});
let serialConfig = this.serialConfig;
serialConfig.on('start', function() {
node.port = serialPool.get(serialConfig);
setCallback(node);
});
// Serial In
function setCallback(node) {
node.port.on('data', function (msgout, sender) {
// serial request will only process incoming data pertaining to its own request (i.e. when it's at the head of the queue)
if (sender !== node) { return; }
node.status({ fill: "green", shape: "dot", text: "node-red:common.status.ok" });
msgout.status = "OK";
node.send(msgout);
});
node.port.on('timeout', function (msgout, sender) {
if (sender !== node) { return; }
msgout.status = "ERR_TIMEOUT";
node.status({ fill: "red", shape: "ring", text: "serial.status.timeout" });
node.send(msgout);
});
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" });
});
node.port.on('stopped', function() {
node.status({fill:"grey",shape:"ring",text:"serial.status.stopped"});
});
}
setCallback(node);
}
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 request", SerialRequestNode);
// control node to stop, start, reconfigure ports
function SerialControlNode(n) {
const configProps = [
"serialport", "serialbaud", "databits", "parity", "stopbits",
"dtr", "rts", "cts", "dsr"
]
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(node.serialConfig);
node.port.on('stopped', function() {
node.status({fill:"grey",shape:"ring",text:"serial.status.stopped"});
});
node.port.on('ready', function() {
node.status({fill:"green",shape:"dot",text:node.serialConfig.serialbaud+","+node.serialConfig.databits+","+(node.serialConfig.parity.toUpperCase().substr(0,1))+","+node.serialConfig.stopbits});
});
node.on("input",function(msg) {
if (msg.hasOwnProperty("flush") && msg.flush === true) { node.port.serial.flush(); }
if (configProps.some((p) => { return msg.payload.hasOwnProperty(p) })) {
msg.payload.enabled = msg.payload.hasOwnProperty('enabled') ? msg.payload.enabled : true;
node.serialConfig.changePort(msg.payload);
}
var stat = {fill:"green",shape:"dot",text:node.serialConfig.serialbaud+","+node.serialConfig.databits+","+(node.serialConfig.parity.toUpperCase().substr(0,1))+","+node.serialConfig.stopbits}
if (msg.payload.hasOwnProperty("enabled")) {
node.serialConfig.enabled = msg.payload.enabled;
if (msg.payload.enabled === true || msg.payload.enabled === "true") {
node.serialConfig.emit('start');
}
else {
serialPool.close(node.serialConfig.serialport,() => {
RED.log.info("[serialconfig:"+node.serialConfig.id+"] " + RED._("serial.stopped",{port:node.serialConfig.serialport}));
});
stat.fill = "grey";
stat.shape = "ring";
}
}
let currentConfig = {};
configProps.map((p) => {
currentConfig[p] = node.serialConfig[p];
});
currentConfig.enabled = node.serialConfig.enabled;
node.status(stat);
node.send({payload:currentConfig});
});
}
RED.nodes.registerType("serial control", SerialControlNode);
var serialPool = (function() {
var connections = {};
return {
get:function(serialConfig) {
// make local copy of configuration -- perhaps not needed?
var port = serialConfig.serialport,
baud = serialConfig.serialbaud,
databits = serialConfig.databits,
parity = serialConfig.parity,
stopbits = serialConfig.stopbits,
dtr = serialConfig.dtr,
rts = serialConfig.rts,
cts = serialConfig.cts,
dsr = serialConfig.dsr,
newline = ""+serialConfig.newline,
spliton = serialConfig.out,
waitfor = serialConfig.waitfor,
binoutput = serialConfig.bin,
addchar = serialConfig.addchar,
responsetimeout = serialConfig.responsetimeout;
var id = port;
// just return the connection object if already have one
// key is the port (file path)
if (connections[id]) { return connections[id]; }
// State variables to be used by the on('data') handler
var i = 0; // position in the buffer
// .newline is misleading as its meaning depends on the split input policy:
// "char" : a msg will be sent after a character with value .newline is received
// "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;
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.from([newline]);
}
else {
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; }
addchar = addchar.replace("\\n","\n").replace("\\r","\r").replace("\\t","\t").replace("\\e","\e").replace("\\f","\f").replace("\\0","\0"); // jshint ignore:line
if (addchar.substr(0,2) == "0x") { addchar = new Buffer.from([addchar]); }
connections[id] = (function() {
var obj = {
_emitter: new events.EventEmitter(),
serial: null,
_closing: false,
tout: null,
queue: [],
on: function(a,b) { this._emitter.on(a,b); },
close: function(cb) { this.serial.close(cb); },
encodePayload: function (payload) {
if (!Buffer.isBuffer(payload)) {
if (typeof payload === "object") {
payload = JSON.stringify(payload);
}
else {
payload = payload.toString();
}
if (addchar !== "") { payload += addchar; }
}
else if (addchar !== "") {
payload = Buffer.concat([payload,Buffer.from(addchar)]);
}
return payload;
},
write: function(m,cb) { this.serial.write(m,cb); },
update: function(m,cb) { this.serial.update(m,cb); },
enqueue: function(msg,sender,cb) {
var payload = this.encodePayload(msg.payload);
var qobj = {
sender: sender,
msg: msg,
payload: payload,
cb: cb,
}
this.queue.push(qobj);
// If we're enqueing the first message in line,
// we shall send it right away
if (this.queue.length === 1) {
this.writehead();
}
},
writehead: function() {
if (!this.queue.length) { return; }
var qobj = this.queue[0];
this.write(qobj.payload,qobj.cb);
var msg = qobj.msg;
var timeout = msg.timeout || responsetimeout;
this.tout = setTimeout(function () {
this.tout = null;
var msgout = obj.dequeue() || {};
msgout.port = port;
// if we have some leftover stuff, just send it
if (i !== 0) {
var m = buf.slice(0,i);
m = Buffer.from(m);
i = 0;
if (binoutput !== "bin") { m = m.toString(); }
msgout.payload = m;
}
/* Notify the sender that a timeout occurred */
obj._emitter.emit('timeout',msgout,qobj.sender);
}, timeout);
},
dequeue: function() {
// if we are trying to dequeue stuff from an
// empty queue, that's an unsolicited message
if (!this.queue.length) { return null; }
var msg = Object.assign({}, this.queue[0].msg);
msg = Object.assign(msg, {
request_payload: msg.payload,
request_msgid: msg._msgid,
});
delete msg.payload;
if (this.tout) {
clearTimeout(obj.tout);
obj.tout = null;
}
this.queue.shift();
this.writehead();
return msg;
},
}
//newline = newline.replace("\\n","\n").replace("\\r","\r");
obj._emitter.setMaxListeners(50);
var olderr = "";
var setupSerial = function() {
obj.serial = new SerialPort({
path: port,
baudRate: baud,
dataBits: databits,
parity: parity,
stopBits: stopbits,
//parser: serialp.parsers.raw,
autoOpen: true
}, function(err, results) {
if (err) {
if (err.toString() !== olderr) {
olderr = err.toString();
RED.log.error("[serialconfig:"+serialConfig.id+"] "+RED._("serial.errors.error",{port:port,error:olderr}), {});
}
obj.tout = setTimeout(function() {
setupSerial();
}, 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');
if (obj.tout) { clearTimeout(obj.tout); }
obj.tout = setTimeout(function() {
setupSerial();
}, serialReconnectTime);
});
obj.serial.on('close', function() {
if (!obj._closing) {
if (olderr !== "unexpected") {
olderr = "unexpected";
RED.log.error("[serialconfig:"+serialConfig.id+"] "+RED._("serial.errors.unexpected-close",{port:port}), {});
}
obj._emitter.emit('closed');
if (obj.tout) { clearTimeout(obj.tout); }
obj.tout = setTimeout(function() {
setupSerial();
}, serialReconnectTime);
}
else {
obj._emitter.emit('stopped');
}
});
obj.serial.on('open',function() {
olderr = "";
RED.log.info("[serialconfig:"+serialConfig.id+"] "+RED._("serial.onopen",{port:port,baud:baud,config: databits+""+parity.charAt(0).toUpperCase()+stopbits}));
// Set flow control pins if necessary. Must be set all in same command.
var flags = {};
if (dtr != "none") { flags.dtr = (dtr!="low"); }
if (rts != "none") { flags.rts = (rts!="low"); }
if (cts != "none") { flags.cts = (cts!="low"); }
if (dsr != "none") { flags.dsr = (dsr!="low"); }
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._emitter.emit('ready');
});
obj.serial.on('data',function(d) {
function emitData(data) {
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<d.length; z++) {
var c = d[z];
if (c === waitfor) { active = true; }
if (!active) { continue; }
// handle the trivial case first -- single char buffer
if ((newline === 0)||(newline === "")) {
emitData(new Buffer.from([c]));
continue;
}
// save incoming data into local buffer
buf[i] = c;
i += 1;
// do the timer thing
if (spliton === "time" || spliton === "interbyte") {
// start the timeout at the first character in case of regular timeout
// restart it at the last character of the this event in case of interbyte timeout
if ((spliton === "time" && i === 1) ||
(spliton === "interbyte" && z === d.length-1)) {
// if we had a response timeout set, clear it:
// we'll emit at least 1 character at some point anyway
if (obj.tout) {
clearTimeout(obj.tout);
obj.tout = null;
}
obj.tout = setTimeout(function () {
obj.tout = null;
emitData(buf.slice(0, i));
i=0;
}, newline);
}
}
// count bytes into a buffer...
else if (spliton === "count") {
newline = serialConfig.newline;
if ( i >= parseInt(newline)) {
emitData(buf.slice(0,i));
i=0;
}
}
// look to match char...
else if (spliton === "char") {
if ((c === splitc[0]) || (i === bufMaxSize)) {
emitData(buf.slice(0,i));
i=0;
}
}
}
});
// obj.serial.on("disconnect",function() {
// RED.log.error(RED._("serial.errors.disconnected",{port:port}));
// });
}
setupSerial();
return obj;
}());
return connections[id];
},
close: function(port,done) {
if (connections[port]) {
if (connections[port].tout != null) {
clearTimeout(connections[port].tout);
}
connections[port]._closing = true;
try {
connections[port].close(function() {
RED.log.info(RED._("serial.errors.closed",{port:port}), {});
done();
});
}
catch(err) { }
delete connections[port];
}
else {
done();
}
}
}
}());
RED.httpAdmin.get("/serialports", RED.auth.needsPermission('serial.read'), function(req,res) {
SerialPort.list().then(
ports => {
const a = ports.map(p => p.path);
res.json(a);
},
err => {
res.json([RED._("serial.errors.list")]);
}
)
});
}

14
node_modules/node-red-node-serialport/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,14 @@
Copyright 2016,2018 JS Foundation and other contributors, https://js.foundation/
Copyright 2013-2016 IBM Corp.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

102
node_modules/node-red-node-serialport/README.md generated vendored Normal file
View File

@@ -0,0 +1,102 @@
node-red-node-serialport
========================
<a href="http://nodered.org" target="noderedinfo">Node-RED</a> nodes to talk to
hardware serial ports.
## Install
To install the stable version use the `Menu - Manage palette - Install` option and search for node-red-node-serialport, or run the following command in your Node-RED user directory, typically `~/.node-red`
npm i node-red-node-serialport
During install there may be multiple messages about optional compilation.
These may look like failures... as they report as failure to compile errors -
but often are warnings and the node will continue to install and, assuming nothing else
failed, you should be able to use it. Occasionally some platforms *will* require
you to install the full set of tools in order to compile the underlying package.
## Usage
Provides four nodes - one to receive messages, and one to send, a request node which can send then wait for a response, and a control node that allows dynamic control of the ports in use.
### Input
Reads data from a local serial port.
Clicking on the search icon will attempt to autodetect serial ports attached to
the device, however you many need to manually specify it. COM1, /dev/ttyUSB0, etc
It can either
- wait for a "split" character (default \n). Also accepts hex notation (0x0a).
- wait for a timeout in milliseconds from the first character received
- wait to fill a fixed sized buffer
It then outputs `msg.payload` as either a UTF8 ascii string or a binary Buffer object.
If no split character is specified, or a timeout or buffer size of 0, then a stream
of single characters is sent - again either as ascii chars or size 1 binary buffers.
### Output
Provides a connection to an outbound serial port.
Only the `msg.payload` is sent.
Optionally the character used to split the input can be appended to every message sent out to the serial port.
### Request
Provides a connection to a request/response serial port.
This node behaves as a tightly coupled combination of serial in and serial out nodes, 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 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.
### Control
When the node-red starts, the flow(program) picks up the pre-programmed serial port, open it, and starts the communication. But there are some cases the port needs to switch to a different port, stop, and start again. For example, in order to upload a new binary for Arduino, the serial port needs to be stopped relased from the nodered, and start it again after uploading. Or when the FTDI device re-connects after disconnecting for any reason, it may be possible that the port number changes, and the end user of the flow can't change the port.
This node provides the ability to:
1. change the serial port and its configuration on the run time programatically.
2. stop the communication and release the serial port.
3. reopen the port and restart the communications.
In order to control the communication, send a **msg.payload** to the control node.
{
"serialport": "/dev/ttyUSB0",
"serialbaud": 115200,
"databits": 8,
"parity": "none",
"stopbits": 1,
"enabled": true
}
changes the serial port and the configuration on the fly.
The following optional parameters will change the configuration only if they are present.
Any combination of them can be passed to change/control the serial communication
- serialport
- serialbaud
- databits
- parity
- stopbits
- dtr
- rts
- cts
- dsr
- enabled
If the `enabled` property is not present, it will default to `true`.
`{"enabled":true}` or `{"enabled":false}` will start or stop the communication.
If `enabled` is passed along with other parameters, the configuration will be changed and the port will be either started or remain stopped, ready to be started later depending on its value.
Any input message will cause the node to output the current port configuration.

View File

@@ -0,0 +1,153 @@
<script type="text/html" data-help-name="serial in">
<p>Datenempfang von lokaler serieller Schnittstelle.</p>
<h3>Ausgangsdaten</h3>
<dl class="message-properties">
<dt>payload <span class="property-type">string | buffer</span></dt>
<dd>Empfangene Daten von serieller Schnittstelle</dd>
<dt>port <span class="property-type">string</span></dt>
<dd>Name der seriellen Schnittstelle</dd>
</dl>
<p>Der Node kann entweder
<ul>
<li>warten auf ein Aufteilungszeichen (standardmäßig \n).
Escape-Sequenzen (z.B. \n) und Hex-Notation (0x0d) werden ebenso akzeptiert.</li>
<li>warten auf Zeitablauf in Millisekunden seit Empfang des ersten Zeichens.</li>
<li>eine Ruhezeit in Millisekunden seit Empfang des letzten Zeichens abwarten.</li>
<li>warten bis ein Puffer mit fester Größer gefüllt ist.</li>
</ul>
</p>
<p>Dann wird <code>msg.payload</code> entweder als UTF-8 ASCII Zeichenfolge (string) oder
als binäres Buffer-Objekt ausgegeben.</p>
<p><code>msg.port</code> enthält den Namen der ausgewählten seriellen Schnittstelle.</p>
<p>Wenn kein Aufteilungszeichen vorgegeben ist oder ein Zeitlimit oder eine Puffergröße von 0 angegeben ist,
wird ein Strom von einzelnen Zeichen ausgegeben -
wieder entweder als ASCII-Zeichen oder als binärer Buffer, jeweils der Größe 1.</p>
</script>
<script type="text/html" data-help-name="serial out">
<p>Datenversand über lokale serielle Schnittstelle.</p>
<h3>Inputs</h3>
<dl class="message-properties">
<dt>payload <span class="property-type">string | buffer</span></dt>
<dd>Zu sendende Daten über serielle Schnittstelle</dd>
<dt class="optional">baudrate <span class="property-type">string</span></dt>
<dd>Baudrate der seriellen Schnittstelle (optional)</dd>
</dl>
<p>Nur <code>msg.payload</code> wird gesendet.</p>
<p>Optional kann die Baudrate geändert werden über <code>msg.baudrate</code></p>
<p>Optional kann das Zeilenvorschub-Zeichen (\n), was zum Aufteilen der Eingangsdaten genutzt wird,
auch jeder zu sendenden Nachricht angefügt werden.</p>
<p>Binäre Nutzdaten (Payload) können unter Verwendung von Buffer-Objekten gesendet werden.</p>
</script>
<script type="text/html" data-help-name="serial request">
<p>Verbindung zu einer seriellen Schnittstelle mit Request/Response-Protokoll (Anfrage/Antwort).</p>
<p>Dieser Node verhält sich wie eine fest gekoppelte Kombination aus einem
<span style="background-color:Gainsboro">serial in</span>- und einem
<span style="background-color:Gainsboro">serial out</span>-Node,
welche sich eine Konfiguration teilen.</p>
<p>Die Anfrage-Nachricht wird über <code>msg.payload</code> so versendet,
wie man es den <span style="background-color:Gainsboro">serial out</span>-Node machen würde.
Die Nachrichten werden an die serielle Schnittstelle nach dem strikten FIFO-Prinzip (First In, First Out) weitergereicht,
d.h. nach jeder gesendeten Anfrage wird auf die Antwort der Gegenstelle gewartet,
bevor mit der nächsten Anfrage fortgefahren wird.
Wenn die Antwort empfangen wurde (mit der selben Logik eines <span style="background-color:Gainsboro">serial in</span>-Nodes)
oder wenn ein Zeitablauf aufgetreten ist, wird eine Nachricht ausgegeben (siehe Ausgangsdaten unten)
mit <code>msg.payload</code>, die empfangene Antwort enthaltend (oder fehlend im Falle eines Zeitablaufs),
und allen anderen unveränderten Eigenschaften der Eingangsnachricht.</p>
<p>Analog zum <span style="background-color:Gainsboro">serial in</span>-Node ist
<code>msg.port</code> ebenso auf den Namen der seriellen Schnittstelle gesetzt.</p>
<h3>Eingangsdaten</h3>
<ul>
<li><code>msg.timeout</code> ist die Ablaufzeit (in ms), nach der eine unbeantwortete Eingangsnachricht
an den Ausgang mit <code>msg.status</code>, gesetzt auf <code>"ERR_TIMEOUT"</code>,
und den unbeantworteten Nutzdaten (Payload) weitergereicht wird.
Wenn nicht vorhanden, wird der Standardwert 10000 (10s) verwendet.</li>
<li>Falls <code>msg.count</code> gesetzt ist, überschreibt sie die konfigurierte Zeichenanzahl,
sofern sie kleiner als die konfigurierte ist.</li>
<li><code>msg.waitfor</code> muss ein Einzelzeichen, ein Escape-Code oder eine Hex-Code sein.
Wenn gesetzt, wartet der Node bis zum passenden Zeichen im Datenstrom und startet dann die Ausgabe.</li>
<li>Optional kann die Baudrate geändert werden über <code>msg.baudrate</code></li>
</ul>
<h3>Ausgangsdaten</h3>
<ul>
<li><code>msg.payload</code> ist die Antwort. Wenn keine Antwort erfolgte, ist die Eigenschaft nicht vorhanden.</li>
<li><code>msg.status</code> ist <code>"OK"</code> im Falle einer empfangenen Antwort oder
<code>"ERR_TIMEOUT"</code> im Falle eines Zeitablaufs.</li>
<li>Alle anderen Eigenschaften der Eingangsdaten werden beibehalten.</li>
</ul>
</script>
<script type="text/html" data-help-name="serial-port">
<p>Konfigurationsoptionen einer lokalen seriellen Schnittstelle.</p>
<p>Die Suchschaltfläche sollte eine Liste der verfügbaren seriellen Schnittstellen zur Auswahl zurückgeben.
Alternativ kann der Schnittstellenname direkt eingegeben werden, sofern bekannt.</p>
<p>Die DTR-, RTS-, CTS- und DSR-Einstellugnen können genutzt werden,
um den entsprechenden Flusskontroll-Pin permanent auf High- oder Low-Pegel zu ziehen,
z.B. um angeschlossene Geräte darüber mit Strom zu versorgen.</p>
<p>Der Node kann optional darauf warten, bis ein vorgegebenes Startzeichen empfangen wurde.</p>
<p>Der Node kann entweder
<ul>
<li>warten auf ein Aufteilungszeichen (standardmäßig \n).
Escape-Sequenzen (z.B. \n) und Hex-Notation (0x0d) werden ebenso akzeptiert.</li>
<li>warten auf Zeitablauf in Millisekunden seit Empfang des ersten Zeichens.</li>
<li>eine Ruhezeit in Millisekunden seit Empfang des letzten Zeichens abwarten.</li>
<li>warten bis ein Puffer mit fester Größer gefüllt ist.</li>
</ul>
</p>
<p>Dann wird <code>msg.payload</code> entweder als UTF-8 ASCII Zeichenfolge (string) oder
als binäres Buffer-Objekt ausgegeben.</p>
<p>Wenn kein Aufteilungszeichen vorgegeben ist oder ein Zeitlimit oder eine Puffergröße von 0 angegeben ist,
wird ein Strom von einzelnen Zeichen ausgegeben -
wieder entweder als ASCII-Zeichen oder als binärer Buffer, jeweils der Größe 1.</p>
<p>Optional kann das Zeilenvorschub-Zeichen (\n), was zum Aufteilen der Eingangsdaten genutzt wird,
auch jeder zu sendenden Nachricht angefügt werden.</p>
</script>
<script type="text/html" data-help-name="serial control">
<p>Stoppt, startet die serielle Kommunikation und ändert die Konfiguration der seriellen Schnittstelle.</p>
<p>Dieser Node bietet die Möglichkeiten:</p>
<ul>
<li>stoppen der Kommunikation und die serielle Schnittstelle freigeben,</li>
<li>den Port erneut öffnen und die Kommunikation neu starten,</li>
<li>dynamische Änderung des seriellen Ports und deren Konfiguration,</li>
<li>abfragen der Konfiguration der seriellen Schnittstelle.</li>
</ul>
<h3>Eingangsdaten</h3>
<p>Um die Kommunikation zu steuern, senden Sie einfach <b>msg.payload</b> mit:</p>
<pre>
{
"serialport": "/dev/ttyUSB0",
"serialbaud": 115200,
"databits": 8,
"parity": "none",
"stopbits": 1,
"enabled": true
}
</pre>
<p>Die folgenden optionalen Parameter ändern die Konfiguration nur, wenn sie vorhanden sind</p>
<p>Jede beliebige Kombination davon kann zur Änderung/Steuerung der seriellen Kommunikation übergeben werden</p>
<ul>
<li> serialport </li>
<li> serialbaud </li>
<li> databits </li>
<li> parity </li>
<li> stopbits </li>
<li> dtr </li>
<li> rts </li>
<li> cts </li>
<li> dsr </li>
<li> enabled </li>
</ul>
<p>Wenn die <code>enabled</code> Eigenschaft nicht vorhanden ist, wird sie standardmäßig auf <code>true</code> gesetzt.</p>
<p>
<code>{"enabled":true}</code> oder <code>{"enabled":false}</code> startet oder stopt die Kommunikation.</p>
<p>Wenn <code>enabled</code> zusammen mit anderen Parametern übergeben wird, wird die Konfiguration geändert und der Port wird entweder gestartet oder bleibt gestoppt, sodass er abhängig von seinem Wert später gestartet werden kann.</p>
<h3>Ausgangsdaten</h3>
<p>Jede Eingabenachricht führt dazu, dass der Knoten die aktuelle Portkonfiguration in <code>msg.payload</code> ausgibt.</p>
</script>

View File

@@ -0,0 +1,73 @@
{
"serial": {
"status": {
"waiting": "Wartend",
"timeout": "Zeitablauf"
},
"label": {
"serialport": "Serieller Port",
"settings": "Einstellungen",
"baudrate": "Baudrate",
"databits": "Datenbits",
"parity": "Parität",
"stopbits": "Stoppbits",
"input": "Empfang",
"split": "Aufteilung",
"deliver": "und Ausgabe als",
"output": "Versand",
"request": "Anforderung",
"responsetimeout": "Standardwert Antwort-Zeitablauf",
"ms": "ms",
"serial": "seriell",
"none": "none",
"start": "Optional Warten auf das Startzeichen",
"startor": ", dann"
},
"placeholder": {
"serialport": "z.B. /dev/ttyUSB0/"
},
"parity": {
"none": "Keine",
"even": "Gerade",
"mark": "Mark",
"odd": "Ungerade",
"space": "Space"
},
"linestates": {
"none": "Auto",
"high": "High",
"low": "Low"
},
"split": {
"character": "anhand Zeichen",
"timeout": "nach Zeitablauf von",
"silent": "nach Ruhezeit von",
"lengths": "in feste Längen von"
},
"output": {
"ascii": "ASCII-Strings",
"binary": "Binäre Buffer"
},
"addsplit": "Zeichen zu Ausgangsnachrichten hinzufügen",
"tip": {
"responsetimeout": "Tipp: Der Standardwert des Antwort-Zeitablaufs (default response timeout) kann durch Setzen von msg.timeout überschrieben werden",
"split": "Tipp: Das Aufteilungszeichen wird benutzt, um die empfangenen Daten in einzelne Nachrichten aufzuteilen. Es werden Zeichen ($), Escape-Codes (\\n) oder Hex-Codes (0x03) akzeptiert.",
"silent": "Tipp: Im Ruhezeit-Modus wird die Ruhezeitmessung bei jedem neu empfangenen Zeichen neu gestartet",
"timeout": "Tipp: Im Zeitablauf-Modus startet die Zeitmessung mit Empfang des ersten Zeichens",
"count": "Tipp: Im Modus der festen Längen kann msg.count die vorgegebene Anzahl überschreiben, sofern dieser Wert kleiner ist",
"waitfor": "Tipp: Optional. Leer lassen, um alle Daten zu empfangen. Es werden Zeichen ($), Escape-Codes (\\n) oder Hex-Codes (0x03) akzeptiert." ,
"addchar": "Tipp: Dieses Zeichen wird jeder über den seriellen Port gesendeten Nachricht hinzugefügt. Üblicherweise \\r oder \\n."
},
"onopen": "Seriellen Port __port__ geöffnet mit __baud__ Baud, __config__",
"errors": {
"missing-conf": "Fehlende serielle Konfiguration",
"serial-port": "Serieller Port",
"error": "Serieller Port __port__ FEHLER: __error__",
"unexpected-close": "Serieller Port __port__ unerwartet geschlossen",
"disconnected": "Serieller Port __port__ getrennt",
"closed": "Serieller Port __port__ geschlossen",
"list": "Port-Auflistung fehlgeschlagen. Bitte manuell eintragen.",
"badbaudrate": "Ungültige Baudrate"
}
}
}

View File

@@ -0,0 +1,143 @@
<script type="text/html" data-help-name="serial in">
<p>Reads data from a local serial port.</p>
<h3>Outputs</h3>
<dl class="message-properties">
<dt>payload <span class="property-type">string | buffer</span></dt>
<dd>received data via the serial port</dd>
<dt>port <span class="property-type">string</span></dt>
<dd>name of the serial port</dd>
</dl>
<p>The node can either
<ul>
<li>wait for a "split" character (default \n).
Also accepts escaped shortcut (e.g. \n) or hex notation (0x0d).</li>
<li>wait for a timeout in milliseconds from the first character received.</li>
<li>wait for a silence time in milliseconds after the last character received.</li>
<li>wait to fill a fixed sized buffer.</li>
</ul>
</p>
<p>It then outputs <code>msg.payload</code> as either a UTF-8 ASCII string or a binary buffer object.</p>
<p><code>msg.port</code> is set to the name of the port selected.</p>
<p>If no split character is specified, or a timeout or buffer size of 0,
then a stream of single characters is sent -
again either as ASCII chars or size 1 binary buffers.</p>
</script>
<script type="text/html" data-help-name="serial out">
<p>Send data via a local serial port.</p>
<h3>Inputs</h3>
<dl class="message-properties">
<dt>payload <span class="property-type">string | buffer</span></dt>
<dd>data to be sent via the serial port</dd>
<dt class="optional">baudrate <span class="property-type">string</span></dt>
<dd>baudrate of the serial port (optional)</dd>
</dl>
<p>Only the <code>msg.payload</code> is sent.</p>
<p>Optionally the baudrate can be changed using <code>msg.baudrate</code>.</p>
<p>Optionally the new line character used to split the input
can be appended to every message sent out to the serial port.</p>
<p>Binary payloads can be sent by using a buffer object.</p>
</script>
<script type="text/html" data-help-name="serial request">
<p>Provides a connection to a request/response serial port.</p>
<p>This node behaves as a tightly coupled combination of <code>serial in</code> and <code>serial out</code> nodes,
with which it shares the configuration.</p>
<p>Send the request message in <code>msg.payload</code> as you would do with a <code>serial out</code> 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 <code>serial in</code> node), or after a timeout occurs,
a message is sent to the output (see Outputs below),
with <code>msg.payload</code> containing the received response (or missing in case if timeout) and
all other properties are preserved.</p>
<p>For consistency with the <code>serial in</code> node, <code>msg.port</code> is set to the name of the port selected.</p>
<h3>Inputs</h3>
<ul>
<li><code>msg.timeout</code> is the timeout (in ms) after which the incoming message is propagated
to the output with <code>msg.status</code> set to <code>"ERR_TIMEOUT"</code> and missing payload.
If not present, the default value is 10000 (10s).</li>
<li><code>msg.count</code> if set this will override the configured number of characters
as long as it is less than the number configured.</li>
<li><code>msg.waitfor</code> 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.</li>
<li>Optionally the baudrate can be changed using <code>msg.baudrate</code></li>
</ul>
<h3>Outputs</h3>
<ul>
<li><code>msg.payload</code> is the response. If no response occured, this property is removed.</li>
<li><code>msg.status</code> is <code>"OK"</code> in case a response is received,
or <code>"ERR_TIMEOUT"</code> if a timeout occurs.</li>
<li>Any other property coming from the input will be preserved.</li>
</ul>
</script>
<script type="text/html" data-help-name="serial-port">
<p>Configuration options for a local serial port.</p>
<p>The search button should return a list of available serial ports to choose from,
or you can type in the location if known.</p>
<p>The DTR, RTS, CTS and DSR switches can be used to permanently pull the corresponding flow control pin high or low,
e.g. in order to power devices via those pins.</p>
<p>The node can optionally wait until it matches a pre-defined character.</p>
<p>The serial data reception can either
<ul>
<li>wait for a "split" character (default \n). Also accepts escaped shortcut (e.g. \n) or hex notation (0x0d).</li>
<li>wait for a timeout in milliseconds from the first character received.</li>
<li>wait for a silence time in milliseconds after the last character received.</li>
<li>wait to fill a fixed sized buffer.</li>
</ul>
</p>
<p>It then outputs the received data as either a UTF-8 ASCII string or a binary buffer object.</p>
<p>If no split character is specified, or a timeout or buffer size of 0, then a stream of single characters is sent -
again either as ASCII chars or size 1 binary buffers.</p>
<p>Optionally the new line character used to split the input
can be appended to every message sent out to the serial port.</p>
</script>
<script type="text/html" data-help-name="serial control">
<p>Stops, starts the serial communication and changes the serial port configuration.</p>
<p>This node provides the ability to:</p>
<ul>
<li>stop the communication and release the serial port.</li>
<li>reopen the port and restart the communications.</li>
<li>change the serial port and the configuration dynamically.</li>
<li>query the serial port configuration.</li>
</ul>
<h3>Inputs</h3>
<p>In order to control the communication, just send <b>msg.payload</b> containing.</p>
<pre>
{
"serialport": "/dev/ttyUSB0",
"serialbaud": 115200,
"databits": 8,
"parity": "none",
"stopbits": 1,
"enabled": true
}
</pre>
<p>The following optional parameters will change the configuration only if they are present.</p>
<p>Any combination of them can be passed to change/control the serial communication</p>
<ul>
<li> serialport </li>
<li> serialbaud </li>
<li> databits </li>
<li> parity </li>
<li> stopbits </li>
<li> dtr </li>
<li> rts </li>
<li> cts </li>
<li> dsr </li>
<li> enabled </li>
</ul>
<p>If the <code>enabled</code> property is not present, it will default to <code>true</code>.</p>
<p>
<code>{"enabled":true}</code> or <code>{"enabled":false}</code> will start or stop the communication.</p>
<p>If <code>enabled</code> is passed along with other parameters, the configuration will be changed and the
port will be either started or remain stopped, ready to be started later depending on its value.</p>
<h3>Outputs</h3>
<p><code>msg.payload</code> containing the serial port configuration.</p>
</script>

View File

@@ -0,0 +1,75 @@
{
"serial": {
"status": {
"waiting": "waiting",
"timeout": "timeout",
"stopped": "stopped"
},
"label": {
"serialport": "Serial Port",
"settings": "Settings",
"baudrate": "Baud Rate",
"databits": "Data Bits",
"parity": "Parity",
"stopbits": "Stop Bits",
"input": "Input",
"split": "Split input",
"deliver": "and deliver",
"output": "Output",
"request": "Request",
"responsetimeout": "Default response timeout",
"ms": "ms",
"serial": "serial",
"none": "none",
"start": "Optionally wait for a start character of",
"startor": ", then"
},
"placeholder": {
"serialport": "for example: /dev/ttyUSB0/"
},
"parity": {
"none": "None",
"even": "Even",
"mark": "Mark",
"odd": "Odd",
"space": "Space"
},
"linestates": {
"none": "auto",
"high": "High",
"low": "Low"
},
"split": {
"character": "on the character",
"timeout": "after a timeout of",
"silent": "after a silence of",
"lengths": "into fixed lengths of"
},
"output": {
"ascii": "ASCII strings",
"binary": "binary buffers"
},
"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. 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.",
"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": {
"missing-conf": "missing serial config",
"serial-port": "serial port",
"error": "serial port __port__ error: __error__",
"unexpected-close": "serial port __port__ closed unexpectedly",
"disconnected": "serial port __port__ disconnected",
"closed": "serial port __port__ closed",
"list": "Failed to list ports. Please enter manually.",
"badbaudrate": "Baudrate is invalid"
},
"stopped": "__port__ stopped"
}
}

View File

@@ -0,0 +1,73 @@
{
"serial": {
"status": {
"waiting": "waiting",
"timeout": "timeout"
},
"label": {
"serialport": "シリアルポート",
"settings": "設定",
"baudrate": "ボーレート",
"databits": "データビット",
"parity": "パリティ",
"stopbits": "終了ビット",
"input": "入力",
"split": "入力の分割方法",
"deliver": "分割後の配信データ",
"output": "出力",
"request": "リクエスト",
"responsetimeout": "デフォルトの応答タイムアウト",
"ms": "ミリ秒",
"serial": "serial",
"none": "なし",
"start": "オプションで開始文字",
"startor": "を待ちます。"
},
"placeholder": {
"serialport": "例: /dev/ttyUSB0/"
},
"parity": {
"none": "なし",
"even": "偶数",
"mark": "マーク",
"odd": "奇数",
"space": "スペース"
},
"linestates": {
"none": "自動",
"high": "高",
"low": "低"
},
"split": {
"character": "文字列で区切る",
"timeout": "タイムアウト後で区切る",
"silent": "一定の待ち時間後に区切る",
"lengths": "一定の文字数で区切る"
},
"output": {
"ascii": "文字列",
"binary": "バイナリバッファ"
},
"addsplit": "出力メッセージに分割文字を追加する",
"tip": {
"responsetimeout": "Tip: デフォルトの応答タイムアウトは msg.timeout の設定で上書きすることができます。",
"split": "Tip: \"区切り\" 文字は、入力を別々のメッセージに分割するために使用され、シリアルポートに送信されるすべてのメッセージに追加することもできます。",
"silent": "Tip: In line-silent mode timeout is restarted upon arrival of any character (i.e. inter-byte timeout).",
"timeout": "Tip: タイムアウトモードでのタイムアウトは最初の文字が到着したときから始まります。",
"count": "Tip: カウントモードでは msg.count 設定は、構成された値よりも小さいときに限り、構成されたカウントを上書きすることができます。",
"waitfor": "Tip: オプションです。すべてのデータを受信するには、空白のままにします。文字($)・エスケープコード(\\n)・16進コード(0x02)を受け入れることができます。" ,
"addchar": "Tip: この文字は、シリアルポートに送信されるすべてのメッセージに追加されます。通常は \\r や \\n です。"
},
"onopen": "シリアルポート __port__ が __baud__ ボー __config__ で開かれました",
"errors": {
"missing-conf": "シリアル設定がありません。",
"serial-port": "シリアルポート",
"error": "シリアルポート __port__ エラー: __error__",
"unexpected-close": "シリアルポート __port__ が予期せず閉じられました",
"disconnected": "シリアルポート __port__ 切断",
"closed": "シリアルポート __port__ 閉じられました",
"list": "ポートのリスト化に失敗しました。手動で入力してください。",
"badbaudrate": "ボーレートが不正です。"
}
}
}

30
node_modules/node-red-node-serialport/package.json generated vendored Normal file
View File

@@ -0,0 +1,30 @@
{
"name" : "node-red-node-serialport",
"version" : "2.0.3",
"description" : "Node-RED nodes to talk to serial ports",
"dependencies" : {
"serialport" : "^12.0.0"
},
"repository" : {
"type":"git",
"url":"https://github.com/node-red/node-red-nodes.git",
"directory": "tree/master/io/serialport"
},
"license": "Apache-2.0",
"keywords": [ "node-red", "serial" ],
"node-red": {
"version": ">=3.0.0",
"nodes": {
"serialport": "25-serial.js"
}
},
"engines" : { "node" : ">=16.0.0" },
"author": {
"name": "Dave Conway-Jones",
"email": "dceejay@gmail.com",
"url": "http://nodered.org"
},
"contributors" : [
"@yhur"
]
}