mirror of
https://github.com/node-red/node-red-nodes.git
synced 2025-12-26 23:16:47 +01:00
Merge against v1.3.4 instead of 1.3.3
not sure what went wrong but here we are... Setting to v1.4.0 as def a functionality change
This commit is contained in:
@@ -18,7 +18,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-config-input-samplingInt" style="width:150px;"><i class="fa fa-circle"></i> <span data-i18n="arduino.label.samplingInt"></span></label>
|
<label for="node-config-input-samplingInt" style="width:150px;"><i class="fa fa-circle"></i> <span data-i18n="arduino.label.samplingInt"></span></label>
|
||||||
<input type="number" id="node-config-input-samplingInt" style="width:20%;" data-i18n="[placeholder]arduino.placeholder.samplingInt" min=10 max=65500 />
|
<input type="number" id="node-config-input-samplingInt" style="width:20%;" data-i18n="[placeholder]arduino.placeholder.samplingInt" min=10 max=65500 /> mS
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-config-input-log2consol"><i class="icon-bookmark"></i>Log to console</label>
|
<label for="node-config-input-log2consol"><i class="icon-bookmark"></i>Log to console</label>
|
||||||
@@ -43,30 +43,41 @@
|
|||||||
},
|
},
|
||||||
oneditprepare: function() {
|
oneditprepare: function() {
|
||||||
try {
|
try {
|
||||||
$("#node-config-input-device").autocomplete( "destroy" );
|
$("#node-config-input-device").autocomplete( "destroy" ); // Remove auto-complete functionality from an <input>.
|
||||||
} catch(err) { };
|
} catch(err) { };
|
||||||
|
|
||||||
$("#node-config-lookup-serial").click(function() { // Board's serial port search function
|
$("#node-config-lookup-serial").click(async function() { // Board's serial port search function
|
||||||
//console.log("Serial Auto-search started.");
|
console.log("Serial Auto-search started.");
|
||||||
$("#node-config-lookup-serial-icon").removeClass('fa-search');
|
$("#node-config-lookup-serial-icon").removeClass('fa-search').addClass('spinner');
|
||||||
$("#node-config-lookup-serial-icon").addClass('spinner');
|
$("#node-config-lookup-serial").addClass('disabled');
|
||||||
$("#node-config-lookup-serial") .addClass('disabled');
|
|
||||||
|
|
||||||
$.getJSON('arduinoports', function(data) {
|
try {
|
||||||
//console.log('Serial Auto-search found data: %o', data);
|
$.getJSON('arduinoports', async function(data, data2) {
|
||||||
$("#node-config-lookup-serial-icon").removeClass('spinner');
|
//console.log('Serial Auto-search found data: %o', data);
|
||||||
$("#node-config-lookup-serial") .removeClass('disabled');
|
//console.log('Data2: %o', data2);
|
||||||
$("#node-config-lookup-serial-icon").addClass('fa-search');
|
|
||||||
let ports = data || [];
|
// UI Updates
|
||||||
$("#node-config-input-device").autocomplete({
|
$("#node-config-lookup-serial-icon").removeClass('spinner').addClass('fa-search');
|
||||||
source: ports,
|
$("#node-config-lookup-serial").removeClass('disabled');
|
||||||
minLength: 0,
|
// Ensure ports is an array (fallback to empty array)
|
||||||
close: function( event, ui ) {
|
ports = data || [];
|
||||||
//console.log("Serial Auto-search closing.");
|
|
||||||
$("#node-config-input-device").autocomplete( "destroy" );
|
$("#node-config-input-device").autocomplete({
|
||||||
}
|
source: ports,
|
||||||
}).autocomplete("search", "");
|
minLength: 0,
|
||||||
});
|
close: function(event, ui) {
|
||||||
|
console.log("Serial Auto-search closing.");
|
||||||
|
$("#node-config-input-device").autocomplete("destroy");
|
||||||
|
}
|
||||||
|
}).autocomplete("search", "");
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error fetching serial ports:', error);
|
||||||
|
|
||||||
|
// Reset UI on error
|
||||||
|
$("#node-config-lookup-serial-icon").removeClass('spinner').addClass('fa-search');
|
||||||
|
$("#node-config-lookup-serial").removeClass('disabled');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -216,7 +227,7 @@
|
|||||||
color:"#3fadb5",
|
color:"#3fadb5",
|
||||||
defaults: {
|
defaults: {
|
||||||
name: {value:""},
|
name: {value:""},
|
||||||
pin: {value:"",validate: function(v) {
|
pin: {value:"", validate: function(v) {
|
||||||
var ct = $("#node-input-state").val() || this.state;
|
var ct = $("#node-input-state").val() || this.state;
|
||||||
return ct === 'STRING' || (v !== '');
|
return ct === 'STRING' || (v !== '');
|
||||||
}},
|
}},
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ Memo for debugging:
|
|||||||
|
|
||||||
module.exports = function(RED) {
|
module.exports = function(RED) {
|
||||||
"use strict";
|
"use strict";
|
||||||
const SP = require('serialport');
|
const { SerialPort } = require('serialport'); // changed format SP -> to {SP} at v9 => v10. See: https://serialport.io/docs/guide-upgrade
|
||||||
const firmataBoard = require('./lib/firmata');
|
const firmataBoard = require('./lib/firmata');
|
||||||
|
|
||||||
let moreLogs = RED.settings.verbose || false; // enable this for "debugging"
|
let moreLogs = RED.settings.verbose || false; // enable this for "debugging"
|
||||||
@@ -220,10 +220,10 @@ module.exports = function(RED) {
|
|||||||
|
|
||||||
function pinAlreadyUsed (_parentNode, _newNode) { // Check, if there is already a Node registered with same pin -> report pin-conflict
|
function pinAlreadyUsed (_parentNode, _newNode) { // Check, if there is already a Node registered with same pin -> report pin-conflict
|
||||||
if (_parentNode.myChirdren.length === 0) return false;
|
if (_parentNode.myChirdren.length === 0) return false;
|
||||||
if (([c_RESET, c_STRING, c_SYSEX, c_INTER]).includes(_newNode.type)) return false;
|
if (([c_RESET, c_STRING, c_SYSEX, c_INTER]).includes(_newNode.pinType)) return false;
|
||||||
|
|
||||||
let _pin = _newNode.pin;
|
let _pin = _newNode.pin;
|
||||||
if (_newNode.type === c_ANALOG) {
|
if (_newNode.pinType === c_ANALOG) {
|
||||||
if (_newNode.pin >= _parentNode.board.analogPins.length) return false; // wrong pin number
|
if (_newNode.pin >= _parentNode.board.analogPins.length) return false; // wrong pin number
|
||||||
_pin = _parentNode.board.analogPins[_newNode.pin]; // get from the reference Like: [26,27,28,29] _pin=3 -> _pin=29
|
_pin = _parentNode.board.analogPins[_newNode.pin]; // get from the reference Like: [26,27,28,29] _pin=3 -> _pin=29
|
||||||
}
|
}
|
||||||
@@ -238,7 +238,7 @@ module.exports = function(RED) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( _ch.type === c_ANALOG) {
|
if ( _ch.pinType === c_ANALOG) {
|
||||||
if (_pin === _parentNode.board.analogPins[_ch.pin]) return reportErrorAndExit(); // found similar! Exit
|
if (_pin === _parentNode.board.analogPins[_ch.pin]) return reportErrorAndExit(); // found similar! Exit
|
||||||
} else {
|
} else {
|
||||||
if (_pin === _ch.pin) return reportErrorAndExit(); // found similar! Exit
|
if (_pin === _ch.pin) return reportErrorAndExit(); // found similar! Exit
|
||||||
@@ -419,7 +419,7 @@ module.exports = function(RED) {
|
|||||||
updateBrdState(BdStates.disconnected);
|
updateBrdState(BdStates.disconnected);
|
||||||
resetBoard(brdNode); // this will try to send a "last minute" signal to the board to: reset.
|
resetBoard(brdNode); // this will try to send a "last minute" signal to the board to: reset.
|
||||||
if ( ! brdNode.closing) brdNode.error(RED._("arduino.status.portclosed"));
|
if ( ! brdNode.closing) brdNode.error(RED._("arduino.status.portclosed"));
|
||||||
if (done) { done(); }
|
if (done !== undefined) done();
|
||||||
});
|
});
|
||||||
|
|
||||||
brdNode.board.on('disconnect', function() {
|
brdNode.board.on('disconnect', function() {
|
||||||
@@ -428,31 +428,30 @@ module.exports = function(RED) {
|
|||||||
if ( ! brdNode.closing) startBoardLoopTimer(); // do not start, if proper closing is happening
|
if ( ! brdNode.closing) startBoardLoopTimer(); // do not start, if proper closing is happening
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
debugger
|
//debugger
|
||||||
|
|
||||||
|
|
||||||
// START board initialization the first time
|
// START board initialization the first time
|
||||||
startupBrd();
|
startupBrd();
|
||||||
|
|
||||||
if (brdNode.loop == null) {
|
if (brdNode.loop == null)
|
||||||
startBoardLoopTimer();
|
startBoardLoopTimer();
|
||||||
}
|
else
|
||||||
else {
|
if (moreLogs) brdNode.log(c_fbr + "already present. Loop start skipped. ");
|
||||||
if (moreLogs) {
|
|
||||||
brdNode.log(c_fbr + "already present. Loop start skipped. ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// brdNode.removeAllListeners('close');
|
// brdNode.removeAllListeners('close');
|
||||||
brdNode.on('close', function(removed, done) { // the Node itself is getting destoyed memo: function(done) did not work, TypeError
|
brdNode.on('close', function(removed, done) { // the Node itself is getting destoyed memo: function(done) did not work, TypeError
|
||||||
brdNode.closing = true;
|
brdNode.closing = true;
|
||||||
if (!removed) updateBrdState(BdStates.disconnected); // this will notify clients too
|
if (!removed) updateBrdState(BdStates.disconnected); // this will notify clients too
|
||||||
clearTimeout(brdNode.loop); brdNode.loop = null;
|
clearTimeout(brdNode.loop); brdNode.loop = null;
|
||||||
if ((brdNode.board == null) || (brdNode.board.transport == null) ) {done(); return; }
|
if ((brdNode.board == null) || (brdNode.board.transport == null) ) {
|
||||||
|
if (done !== undefined) done();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (brdNode.board.transport.closing) {
|
if (brdNode.board.transport.closing) {
|
||||||
if (moreLogs) { brdNode.log(c_fbr + "Nothing to do, because this port is already closing: " + brdNode.port); }
|
if (moreLogs) { brdNode.log(c_fbr + "Nothing to do, because this port is already closing: " + brdNode.port); }
|
||||||
if (done) { done(); }
|
if (done !== undefined) done();
|
||||||
return;// EXIT
|
return;// EXIT
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -464,16 +463,13 @@ debugger
|
|||||||
brdNode.board.transport.close(function(err) {
|
brdNode.board.transport.close(function(err) {
|
||||||
if (moreLogs) { brdNode.log(RED._("arduino.status.portclosed") + err?"Err: ":"" , err); }
|
if (moreLogs) { brdNode.log(RED._("arduino.status.portclosed") + err?"Err: ":"" , err); }
|
||||||
});
|
});
|
||||||
if (done) { done(); }
|
if (done !== undefined) done();
|
||||||
}
|
}
|
||||||
catch(e) {
|
catch(e) {
|
||||||
if (moreLogs) { brdNode.error("Could not close port: " + brdNode.port + (e?"Err: ":"") , e); }
|
if (moreLogs) { brdNode.error("Could not close port: " + brdNode.port + (e?"Err: ":"") , e); }
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (done) { done(); }
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
else { if (done !== undefined) done(); return;}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// *** REGISTERING the (parent) board node *** //
|
// *** REGISTERING the (parent) board node *** //
|
||||||
@@ -484,14 +480,14 @@ debugger
|
|||||||
/**
|
/**
|
||||||
* The Input (child) Node
|
* The Input (child) Node
|
||||||
*
|
*
|
||||||
* type: can be ANALOG, DIGITAL ... (Warning! in html it is called "state")
|
* pinType: can be ANALOG, DIGITAL ... (Warning! in html it is called "state")
|
||||||
*/
|
*/
|
||||||
function DuinoNodeIn(_setupIn) {
|
function DuinoNodeIn(_setupIn) {
|
||||||
RED.nodes.createNode(this, _setupIn); // n = setupNode
|
RED.nodes.createNode(this, _setupIn); // n = setupNode
|
||||||
let nodeIn = this;
|
let nodeIn = this;
|
||||||
nodeIn.n_status = ndStats.start;
|
nodeIn.n_status = ndStats.start;
|
||||||
nodeIn.pin = _setupIn.pin;
|
nodeIn.pin = _setupIn.pin;
|
||||||
nodeIn.type = _setupIn.state; // "state" is a wrong naming at the html definition. It is the current type of the Pin. (Like: "ANALOG" or "PWM"...)
|
nodeIn.pinType = _setupIn.state; // "state" is a wrong naming at the html definition. It is the current "Type" of the Pin. (Like: "ANALOG" or "PWM"...)
|
||||||
nodeIn.parentNode = RED.nodes.getNode(_setupIn.arduino); // n.arduino = The ArduinoNode's ID. It is defined at `package.json`: "node-red": {... "nodes": { "arduino": "35-arduino.js" }
|
nodeIn.parentNode = RED.nodes.getNode(_setupIn.arduino); // n.arduino = The ArduinoNode's ID. It is defined at `package.json`: "node-red": {... "nodes": { "arduino": "35-arduino.js" }
|
||||||
let loopIn = null; // timer
|
let loopIn = null; // timer
|
||||||
|
|
||||||
@@ -511,7 +507,7 @@ debugger
|
|||||||
|
|
||||||
// *** first initialization *** //
|
// *** first initialization *** //
|
||||||
let startupIn = function() {
|
let startupIn = function() {
|
||||||
if (moreLogs) console.info(c_fbr + "Node-In created." + (nodeIn.name ? " Name=["+ nodeIn.name +"]" : "") + " Pin=" + nodeIn.pin + " Type=" + nodeIn.type);
|
if (moreLogs) console.info(c_fbr + "Node-In created." + (nodeIn.name ? " Name=["+ nodeIn.name +"]" : "") + " Pin=" + nodeIn.pin + " Type=" + nodeIn.pinType);
|
||||||
if (loopIn !== null) {clearTimeout(loopIn); loopIn = null};
|
if (loopIn !== null) {clearTimeout(loopIn); loopIn = null};
|
||||||
//nodeIn.frmBoard.setMaxListeners(0); Deleted 2025-03-17. DO NOT USE THIS ! See: https://stackoverflow.com/a/44143119
|
//nodeIn.frmBoard.setMaxListeners(0); Deleted 2025-03-17. DO NOT USE THIS ! See: https://stackoverflow.com/a/44143119
|
||||||
// nodeIn.frmBoard.setMaxListeners(11); // no need either
|
// nodeIn.frmBoard.setMaxListeners(11); // no need either
|
||||||
@@ -520,9 +516,9 @@ debugger
|
|||||||
|
|
||||||
let doit = function() {
|
let doit = function() {
|
||||||
if (pinAlreadyUsed(nodeIn.parentNode, nodeIn) === true) return; // EXIT; // pin-conflict check
|
if (pinAlreadyUsed(nodeIn.parentNode, nodeIn) === true) return; // EXIT; // pin-conflict check
|
||||||
if (moreLogs) console.info(c_fbr + "Node-In init started." + (nodeIn.name ? " Name=["+ nodeIn.name +"]" : "") + " Pin=" + nodeIn.pin + " Type=" + nodeIn.type);
|
if (moreLogs) console.info(c_fbr + "Node-In init started." + (nodeIn.name ? " Name=["+ nodeIn.name +"]" : "") + " Pin=" + nodeIn.pin + " Type=" + nodeIn.pinType);
|
||||||
let goodPin = (nodeIn.pin != null) && !isNaN(nodeIn.pin) && (nodeIn.pin >=0) && (nodeIn.pin < nodeIn.frmBoard.pins.length);
|
let goodPin = (nodeIn.pin != null) && !isNaN(nodeIn.pin) && (nodeIn.pin >=0) && (nodeIn.pin < nodeIn.frmBoard.pins.length);
|
||||||
if (goodPin === true && nodeIn.type === c_ANALOG) {
|
if (goodPin === true && nodeIn.pinType === c_ANALOG) {
|
||||||
goodPin = ( nodeIn.pin in nodeIn.frmBoard.analogPins ); // found analogue pin
|
goodPin = ( nodeIn.pin in nodeIn.frmBoard.analogPins ); // found analogue pin
|
||||||
if (!goodPin){ nodeIn.error( c_invalidPin + nodeIn.pin
|
if (!goodPin){ nodeIn.error( c_invalidPin + nodeIn.pin
|
||||||
+ (nodeIn.frmBoard.analogPins ? ". Only these analogue pin numbers are allowed: [0.."
|
+ (nodeIn.frmBoard.analogPins ? ". Only these analogue pin numbers are allowed: [0.."
|
||||||
@@ -536,9 +532,9 @@ debugger
|
|||||||
}
|
}
|
||||||
if (goodPin === true) {
|
if (goodPin === true) {
|
||||||
try {
|
try {
|
||||||
if (nodeIn.type === c_ANALOG) { nodeIn.frmBoard.pinMode(nodeIn.pin, 0x02); } else
|
if (nodeIn.pinType === c_ANALOG) { nodeIn.frmBoard.pinMode(nodeIn.pin, 0x02); } else
|
||||||
if (nodeIn.type === c_INPUT ) { nodeIn.frmBoard.pinMode(nodeIn.pin, 0x00); } else
|
if (nodeIn.pinType === c_INPUT ) { nodeIn.frmBoard.pinMode(nodeIn.pin, 0x00); } else
|
||||||
if (nodeIn.type === c_PULLUP) { nodeIn.frmBoard.pinMode(nodeIn.pin, 0x0B); }
|
if (nodeIn.pinType === c_PULLUP) { nodeIn.frmBoard.pinMode(nodeIn.pin, 0x0B); }
|
||||||
updateNodeStatus(nodeIn, ndStats.OK);
|
updateNodeStatus(nodeIn, ndStats.OK);
|
||||||
} catch (setPinError) {
|
} catch (setPinError) {
|
||||||
updateNodeStatus(nodeIn, ndStats.wrongPin);
|
updateNodeStatus(nodeIn, ndStats.wrongPin);
|
||||||
@@ -547,7 +543,7 @@ debugger
|
|||||||
}
|
}
|
||||||
|
|
||||||
// subscribing to pin-event listeners. These will call at firmata-io.js: board.addListener(`analog-read-${pin}`, callback);
|
// subscribing to pin-event listeners. These will call at firmata-io.js: board.addListener(`analog-read-${pin}`, callback);
|
||||||
if (nodeIn.type === c_ANALOG) {
|
if (nodeIn.pinType === c_ANALOG) {
|
||||||
nodeIn.frmBoard.analogRead(nodeIn.pin, function(v) {
|
nodeIn.frmBoard.analogRead(nodeIn.pin, function(v) {
|
||||||
if (nodeIn.n_status !== ndStats.OK) updateNodeStatus(nodeIn, ndStats.OK);
|
if (nodeIn.n_status !== ndStats.OK) updateNodeStatus(nodeIn, ndStats.OK);
|
||||||
if (v !== nodeIn.oldval) {
|
if (v !== nodeIn.oldval) {
|
||||||
@@ -556,7 +552,7 @@ debugger
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else
|
} else
|
||||||
if (nodeIn.type === c_INPUT) {
|
if (nodeIn.pinType === c_INPUT) {
|
||||||
nodeIn.frmBoard.digitalRead(nodeIn.pin, function(v) {
|
nodeIn.frmBoard.digitalRead(nodeIn.pin, function(v) {
|
||||||
if (nodeIn.n_status !== ndStats.OK) updateNodeStatus(nodeIn, ndStats.OK);
|
if (nodeIn.n_status !== ndStats.OK) updateNodeStatus(nodeIn, ndStats.OK);
|
||||||
if (v !== nodeIn.oldval) {
|
if (v !== nodeIn.oldval) {
|
||||||
@@ -566,7 +562,7 @@ debugger
|
|||||||
});
|
});
|
||||||
// nodeIn.frmBoard.queryPinState(nodeIn.pin, callback); // TODO ?
|
// nodeIn.frmBoard.queryPinState(nodeIn.pin, callback); // TODO ?
|
||||||
} else
|
} else
|
||||||
if (nodeIn.type === c_PULLUP) {
|
if (nodeIn.pinType === c_PULLUP) {
|
||||||
nodeIn.frmBoard.digitalRead(nodeIn.pin, function(v) {
|
nodeIn.frmBoard.digitalRead(nodeIn.pin, function(v) {
|
||||||
if (nodeIn.n_status !== ndStats.OK) updateNodeStatus(nodeIn, ndStats.OK);
|
if (nodeIn.n_status !== ndStats.OK) updateNodeStatus(nodeIn, ndStats.OK);
|
||||||
if (v !== nodeIn.oldval) {
|
if (v !== nodeIn.oldval) {
|
||||||
@@ -576,7 +572,7 @@ debugger
|
|||||||
});
|
});
|
||||||
// nodeIn.frmBoard.queryPinState(nodeIn.pin); // TODO ?
|
// nodeIn.frmBoard.queryPinState(nodeIn.pin); // TODO ?
|
||||||
} else
|
} else
|
||||||
if (nodeIn.type == c_STRING) {
|
if (nodeIn.pinType == c_STRING) {
|
||||||
nodeIn.frmBoard.on('string', function(v) {
|
nodeIn.frmBoard.on('string', function(v) {
|
||||||
if (nodeIn.n_status !== ndStats.OK) updateNodeStatus(nodeIn, ndStats.OK);
|
if (nodeIn.n_status !== ndStats.OK) updateNodeStatus(nodeIn, ndStats.OK);
|
||||||
// if (v !== nodeIn.oldval) { //OMG! deleted 2025-03-17
|
// if (v !== nodeIn.oldval) { //OMG! deleted 2025-03-17
|
||||||
@@ -603,7 +599,7 @@ debugger
|
|||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
if (loopIn === null) {
|
if (loopIn === null) {
|
||||||
if (moreLogs) console.info(c_fbr + "Timeout set for loop. Name="+ nodeIn.name + " Pin=" + nodeIn.pin + " State=" + nodeIn.type);
|
if (moreLogs) console.info(c_fbr + "Timeout set for loop. Name="+ nodeIn.name + " Pin=" + nodeIn.pin + " State=" + nodeIn.pinType);
|
||||||
loopIn = setTimeout(function() { if (nodeIn.running === false) { startupIn(); } }, 4500);
|
loopIn = setTimeout(function() { if (nodeIn.running === false) { startupIn(); } }, 4500);
|
||||||
loopIn.name = "startupIN-timeout";
|
loopIn.name = "startupIN-timeout";
|
||||||
}
|
}
|
||||||
@@ -620,7 +616,7 @@ debugger
|
|||||||
clearTimeout(loopIn);
|
clearTimeout(loopIn);
|
||||||
if (removed) {removeFromChildren(nodeIn);}
|
if (removed) {removeFromChildren(nodeIn);}
|
||||||
else {updateNodeStatus(nodeIn, ndStats.equalsBoard);}
|
else {updateNodeStatus(nodeIn, ndStats.equalsBoard);}
|
||||||
done();
|
if (done !== undefined) done();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
RED.nodes.registerType("arduino in", DuinoNodeIn);
|
RED.nodes.registerType("arduino in", DuinoNodeIn);
|
||||||
@@ -629,17 +625,32 @@ debugger
|
|||||||
/**
|
/**
|
||||||
* The Output (child) Node
|
* The Output (child) Node
|
||||||
*
|
*
|
||||||
* type: can be ANALOG, DIGITAL ... (Warning! in html "type" is called "state")
|
* pinType: can be ANALOG, DIGITAL ... (Warning! in html "pinType" is called "state")
|
||||||
*/
|
*/
|
||||||
function DuinoNodeOut(_setupOut) {
|
function DuinoNodeOut(_setupOut) {
|
||||||
RED.nodes.createNode(this, _setupOut);
|
RED.nodes.createNode(this, _setupOut);
|
||||||
let nodeOut = this;
|
let nodeOut = this;
|
||||||
nodeOut.n_status = ndStats.start;
|
nodeOut.n_status = ndStats.start;
|
||||||
nodeOut.pin = _setupOut.pin;
|
nodeOut.pin = _setupOut.pin;
|
||||||
nodeOut.type = _setupOut.state; // "state" is a wrong naming at the html definition. It is the current type of the Pin. (Like: "ANALOG" or "PWM"...)
|
nodeOut.pinType = _setupOut.state; // "state" is a wrong naming at the html definition. It is the current type of the Pin. (Like: "ANALOG" or "PWM"...)
|
||||||
nodeOut.parentNode = RED.nodes.getNode(_setupOut.arduino); // _setupOut.arduino = The board config. It is defined at `package.json`: "node-red": {... "nodes": { "arduino": "35-arduino.js" }
|
nodeOut.parentNode = RED.nodes.getNode(_setupOut.arduino); // _setupOut.arduino = The board config. It is defined at `package.json`: "node-red": {... "nodes": { "arduino": "35-arduino.js" }
|
||||||
let loopOut = null; // timer
|
let loopOut = null; // timer
|
||||||
|
|
||||||
|
// create an event-listener outside the scope of normal inputs, for "override-reset"
|
||||||
|
if (nodeOut.pinType === c_RESET) {
|
||||||
|
nodeOut.on("input", function(msg, send, done) {
|
||||||
|
if ( Boolean(msg.payload) === true) {
|
||||||
|
try {
|
||||||
|
resetBoard(nodeOut.parentNode);
|
||||||
|
if (moreLogs) nodeOut.warn(c_fbr + "... sending reset from NR");
|
||||||
|
} catch (_error) {
|
||||||
|
nodeOut.error(c_fbr + "Could not send RESET to the board.", _error);
|
||||||
|
};
|
||||||
|
if (done !== undefined) done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Test to see, what's inside:
|
// Test to see, what's inside:
|
||||||
//console.log("ou- _setupOut.arduino: %o", _setupOut.arduino);
|
//console.log("ou- _setupOut.arduino: %o", _setupOut.arduino);
|
||||||
//console.log("/n ====================================================================================== /n", n.arduino);
|
//console.log("/n ====================================================================================== /n", n.arduino);
|
||||||
@@ -662,26 +673,26 @@ debugger
|
|||||||
});
|
});
|
||||||
|
|
||||||
let startupOut = function() {
|
let startupOut = function() {
|
||||||
if (moreLogs) console.info(c_fbr + "Node-Out created." + (nodeOut.name ? " Name=["+ nodeOut.name + "]" : "") + " Pin=" + nodeOut.pin + " Type=" + nodeOut.type);
|
if (moreLogs) console.info(c_fbr + "Node-Out created." + (nodeOut.name ? " Name=["+ nodeOut.name + "]" : "") + " Pin=" + nodeOut.pin + " Type=" + nodeOut.pinType);
|
||||||
if (loopOut !== null) {clearTimeout(loopOut); loopOut = null};
|
if (loopOut !== null) {clearTimeout(loopOut); loopOut = null};
|
||||||
|
|
||||||
updateNodeStatus(nodeOut, ndStats.equalsBoard);
|
updateNodeStatus(nodeOut, ndStats.equalsBoard);
|
||||||
|
|
||||||
let doit = function() {
|
let doit = function() {
|
||||||
if (pinAlreadyUsed(nodeOut.parentNode, nodeOut) === true) return; // EXIT; // pin-conflict check
|
if (pinAlreadyUsed(nodeOut.parentNode, nodeOut) === true) return; // EXIT; // pin-conflict check
|
||||||
if (moreLogs) console.info(c_fbr + "Node-Out init started." + (nodeOut.name ? " Name=["+ nodeOut.name + "]" : "") + " Pin=" + nodeOut.pin + " Type=" + nodeOut.type);
|
if (moreLogs) console.info(c_fbr + "Node-Out init started." + (nodeOut.name ? " Name=["+ nodeOut.name + "]" : "") + " Pin=" + nodeOut.pin + " Type=" + nodeOut.pinType);
|
||||||
|
|
||||||
if ((nodeOut.pin != null) && !isNaN(nodeOut.pin) && nodeOut.pin >=0 && nodeOut.pin < nodeOut.frmBoard.pins.length) {
|
if ((nodeOut.pin != null) && !isNaN(nodeOut.pin) && nodeOut.pin >=0 && nodeOut.pin < nodeOut.frmBoard.pins.length) {
|
||||||
if (nodeOut.type === c_OUTPUT) { nodeOut.frmBoard.pinMode(nodeOut.pin, 0x01); }
|
if (nodeOut.pinType === c_OUTPUT) { nodeOut.frmBoard.pinMode(nodeOut.pin, 0x01); }
|
||||||
if (nodeOut.type === c_PWM ) { nodeOut.frmBoard.pinMode(nodeOut.pin, 0x03); }
|
if (nodeOut.pinType === c_PWM ) { nodeOut.frmBoard.pinMode(nodeOut.pin, 0x03); }
|
||||||
if (nodeOut.type === c_SERVO ) { nodeOut.frmBoard.pinMode(nodeOut.pin, 0x04); }
|
if (nodeOut.pinType === c_SERVO ) { nodeOut.frmBoard.pinMode(nodeOut.pin, 0x04); }
|
||||||
|
|
||||||
updateNodeStatus(nodeOut, ndStats.OK);
|
updateNodeStatus(nodeOut, ndStats.OK);
|
||||||
|
|
||||||
nodeOut.on("input", function(msg, send, done) {
|
nodeOut.on("input", function(msg, send, done) {
|
||||||
if ((msg == null) || (msg.payload == null)) { // NULL input -> send warning & exit
|
if ((msg == null) || (msg.payload == null)) { // NULL input -> send warning & exit
|
||||||
nodeOut.warn("msg.payload must not be null!");
|
nodeOut.warn("msg.payload must not be null!");
|
||||||
done();
|
if (done !== undefined) done();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -691,7 +702,7 @@ debugger
|
|||||||
updateNodeStatus(nodeOut, ndStats.equalsBoard);
|
updateNodeStatus(nodeOut, ndStats.equalsBoard);
|
||||||
resetBoard(nodeOut.parentNode);
|
resetBoard(nodeOut.parentNode);
|
||||||
} else
|
} else
|
||||||
if (nodeOut.type === c_OUTPUT) {
|
if (nodeOut.pinType === c_OUTPUT) {
|
||||||
const str = msg.payload.toString();
|
const str = msg.payload.toString();
|
||||||
if ((msg.payload === true ) || (str === "1") || (str.toLowerCase() === "on")) {
|
if ((msg.payload === true ) || (str === "1") || (str.toLowerCase() === "on")) {
|
||||||
nodeOut.frmBoard.digitalWrite(nodeOut.pin, nodeOut.frmBoard.HIGH);
|
nodeOut.frmBoard.digitalWrite(nodeOut.pin, nodeOut.frmBoard.HIGH);
|
||||||
@@ -700,31 +711,31 @@ debugger
|
|||||||
nodeOut.frmBoard.digitalWrite(nodeOut.pin, nodeOut.frmBoard.LOW);
|
nodeOut.frmBoard.digitalWrite(nodeOut.pin, nodeOut.frmBoard.LOW);
|
||||||
};
|
};
|
||||||
} else
|
} else
|
||||||
if (nodeOut.type === c_PWM) {
|
if (nodeOut.pinType === c_PWM) {
|
||||||
msg.payload = parseInt((msg.payload * 1) + 0.5); // round to int
|
msg.payload = parseInt((msg.payload * 1) + 0.5); // round to int
|
||||||
if ((msg.payload >= 0) && (msg.payload <= 255)) {
|
if ((msg.payload >= 0) && (msg.payload <= 255)) {
|
||||||
nodeOut.frmBoard.analogWrite(nodeOut.pin, msg.payload);
|
nodeOut.frmBoard.analogWrite(nodeOut.pin, msg.payload);
|
||||||
} else nodeOut.warn("PWM value must be: 0..255");
|
} else nodeOut.warn("PWM value must be: 0..255");
|
||||||
} else
|
} else
|
||||||
if (nodeOut.type === c_SERVO) {
|
if (nodeOut.pinType === c_SERVO) {
|
||||||
msg.payload = parseInt((msg.payload * 1) + 0.5);
|
msg.payload = parseInt((msg.payload * 1) + 0.5);
|
||||||
if ((msg.payload >= 0) && (msg.payload <= 180)) {
|
if ((msg.payload >= 0) && (msg.payload <= 180)) {
|
||||||
nodeOut.frmBoard.servoWrite(nodeOut.pin, msg.payload);
|
nodeOut.frmBoard.servoWrite(nodeOut.pin, msg.payload);
|
||||||
} else nodeOut.warn("PWM value must be: 0..180");
|
} else nodeOut.warn("PWM value must be: 0..180");
|
||||||
} else
|
} else
|
||||||
if (nodeOut.type === c_SYSEX) {
|
if (nodeOut.pinType === c_SYSEX) {
|
||||||
nodeOut.frmBoard.sysexCommand(msg.payload);
|
nodeOut.frmBoard.sysexCommand(msg.payload);
|
||||||
} else
|
} else
|
||||||
if (nodeOut.type === c_STRING) {
|
if (nodeOut.pinType === c_STRING) {
|
||||||
nodeOut.frmBoard.sendString(msg.payload.toString());
|
nodeOut.frmBoard.sendString(msg.payload.toString());
|
||||||
} else
|
} else
|
||||||
if (nodeOut.type === c_RESET) {
|
/* if (nodeOut.pinType === c_RESET) {
|
||||||
if ( Boolean(msg.payload) === true) {
|
if ( Boolean(msg.payload) === true) {
|
||||||
updateNodeStatus(nodeOut, ndStats.equalsBoard);
|
updateNodeStatus(nodeOut, ndStats.equalsBoard);
|
||||||
resetBoard(nodeOut.parentNode);
|
resetBoard(nodeOut.parentNode);
|
||||||
}
|
}
|
||||||
} else
|
} else */
|
||||||
if (nodeOut.type === c_INTER) {
|
if (nodeOut.pinType === c_INTER) {
|
||||||
const i = 0 + msg.payload;
|
const i = 0 + msg.payload;
|
||||||
if (i < 10 || i > 65535) {
|
if (i < 10 || i > 65535) {
|
||||||
nodeOut.warn("Invalid new interval input value (10-65535): ["+ msg.payload +"]");
|
nodeOut.warn("Invalid new interval input value (10-65535): ["+ msg.payload +"]");
|
||||||
@@ -735,7 +746,7 @@ debugger
|
|||||||
nodeOut.status({fill:c_yellow, shape:c_ring, text:"Interval= " + i});
|
nodeOut.status({fill:c_yellow, shape:c_ring, text:"Interval= " + i});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
done();
|
if (done !== undefined) done();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -770,25 +781,32 @@ debugger
|
|||||||
clearTimeout(loopOut);
|
clearTimeout(loopOut);
|
||||||
if (removed === true) {removeFromChildren(nodeOut);}
|
if (removed === true) {removeFromChildren(nodeOut);}
|
||||||
else {updateNodeStatus(nodeOut, ndStats.equalsBoard);};
|
else {updateNodeStatus(nodeOut, ndStats.equalsBoard);};
|
||||||
done();
|
if (done !== undefined) done();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
RED.nodes.registerType("arduino out", DuinoNodeOut);
|
RED.nodes.registerType("arduino out", DuinoNodeOut);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Listing serial ports (used at Board-configuration)
|
* Listing serial ports (used at Board-configuration, by clicking the SEARCH button on the right side of port editbox)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
RED.httpAdmin.get("/arduinoports", RED.auth.needsPermission("arduino.read"), function(req, res) {
|
RED.httpAdmin.get("/arduinoports", RED.auth.needsPermission("arduino.read"), function(req, res) {
|
||||||
SP.SerialPort.list().then(
|
|
||||||
(data) => {
|
let _arr = ["-- no ports found --"];
|
||||||
const a = data.map(p => p.path);
|
async function listSerialPorts() {
|
||||||
res.json(a);
|
try {
|
||||||
},
|
const ports = await SerialPort.list();
|
||||||
err => {
|
if ((ports != null) && (Array.isArray(ports)) && ports.length !== 0)
|
||||||
this.log('Error listing serial ports', err)
|
_arr = ports.map(p => p.path);
|
||||||
}
|
res.json(_arr);
|
||||||
)
|
} catch (err) {
|
||||||
|
this.log('Error listing ports: '+ err);
|
||||||
|
_arr.push( err.toString );
|
||||||
|
res.json(_arr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
listSerialPorts();
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,8 @@ details and examples of how to use this node.
|
|||||||
Install
|
Install
|
||||||
-------
|
-------
|
||||||
|
|
||||||
Either use the Menu - Manage Palette option or run the following command in your Node-RED user directory - typically `~/.node-red`
|
Either use the Menu - Manage Palette option,
|
||||||
|
or run the following command in your Node-RED user directory - typically `~/.node-red`
|
||||||
|
|
||||||
npm i --unsafe-perm node-red-node-arduino
|
npm i --unsafe-perm node-red-node-arduino
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "node-red-node-arduino",
|
"name": "node-red-node-arduino",
|
||||||
"version": "2.0.0",
|
"version": "1.4.0",
|
||||||
"description": "A Node-RED Node, to talk to a chip as I/O extender, which is running Firmata firmware",
|
"description": "A Node-RED Node, to talk to a chip as I/O extender, which is running Firmata firmware",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"serialport": "^12.0.0"
|
"serialport": "^12.0.0"
|
||||||
|
|||||||
Reference in New Issue
Block a user