我正在编程一个库以扩展传感器的使用,并使其他人更容易使用它。我的目标是在单个节点中实现40个传感器作为node-red-contrib-library,供其他人使用,简单直观,无需对传感器本身进行任何进一步编码。
我遇到了需要使用名为node-red-contrib-gpio的其他库的问题。我想过要么包装它,要么适应它。遗憾的是,我没有发现将任何npm包装到另一个包装中也没有找到任何帮助以适应其中一个。所以现在我试着在这里寻求帮助。
我现在适应上述npm的状态如下: 我设法重新创建了gpio库中使用的配置节点并注册了所有内容,但此时我已经卡住了。
我的终端输出如下所示: Node Red Terminal error output
Welcome to Node-RED
===================
5 Nov 15:49:38 - [info] Node-RED version: v0.16.2
5 Nov 15:49:38 - [info] Node.js version: v6.10.1
5 Nov 15:49:38 - [info] Darwin 16.6.0 x64 LE
5 Nov 15:49:39 - [info] Loading palette nodes
5 Nov 15:49:41 - [warn] ------------------------------------------------------
5 Nov 15:49:41 - [warn] [rpi-gpio] Info : Ignoring Raspberry Pi specific node
5 Nov 15:49:41 - [warn] [wrapper] TypeError: Cannot read property 'nodes' of undefined
5 Nov 15:49:41 - [warn] [button-eot-v2] TypeError: Cannot read property 'nodes' of undefined
5 Nov 15:49:41 - [warn] ------------------------------------------------------
5 Nov 15:49:41 - [warn] Missing node modules:
5 Nov 15:49:41 - [warn] - node-red-contrib-eot-sensors: wrapper in, wrapper out, nodebot, wrapper in, wrapper out, node-led, nodebot, johnny5, remote-server
5 Nov 15:49:41 - [info] Removing modules from config
5 Nov 15:49:41 - [info] Settings file : /Users/philipp/.node-red/settings.js
5 Nov 15:49:41 - [info] User directory : /Users/philipp/.node-red
5 Nov 15:49:41 - [info] Flows file : /Users/philipp/.node-red/flows_Philipps-MBP.fritz.box.json
5 Nov 15:49:41 - [info] Server now running at http://127.0.0.1:1880/
5 Nov 15:49:41 - [debug] loaded flow revision: 62cdd1b04215af983ae9e1a2bac01e43
5 Nov 15:49:41 - [debug] red/runtime/nodes/credentials.load : no user key present
5 Nov 15:49:41 - [debug] red/runtime/nodes/credentials.load : using default key
5 Nov 15:49:41 - [info] Starting flows
1509893381861 Available Firmata
1509893381868 Available Firmata
5 Nov 15:49:41 - [info] Started flows
5 Nov 15:49:41 - [error] [nodebot:Arduino USB-links] Error: Error: No such file or directory, cannot open /dev/cu.usbmodem1411
5 Nov 15:49:41 - [error] [nodebot:Arduino USB-rechts] Error: Error: No such file or directory, cannot open /dev/cu.usbmodem1421
要更多地了解npm文件夹树: Node Red npm folder tree
我假设在wrapper.js文件的代码中出现错误
module.exports = function(RED) {
createNodebotNode(RED);
function wrapperInNode(n) {
RED.nodes.createNode(this,n);
this.buttonState = -1;
this.pin = n.pin;
this.state = n.state;
this.wrapperbot = RED.nodes.getNode(n.board);
if (typeof this.wrapperbot === "object") {
var node = this;
connectingStatus(node);
node.wrapperbot.on('ioready', function() {
var io = node.wrapperbot.io;
connectedStatus(node);
if (node.state == "ANALOG") {
var samplingInterval = parseInt(n.samplingInterval, 10) || 300;
try{io.setSamplingInterval(samplingInterval);}catch(exp){ console.log(exp); }
try{io.pinMode(node.pin, io.MODES.ANALOG);}catch(exp){ console.log(exp); }
io.analogRead(node.pin, function(data) {
var msg = {payload:data, topic:node.pin};
node.send(msg);
});
}
else {
try{io.pinMode(node.pin, io.MODES.INPUT);}catch(exp){ console.log(exp); }
io.digitalRead(node.pin, function(data) {
var msg = {payload:data, topic:node.pin};
node.send(msg);
});
}
});
node.wrapperbot.on('networkReady', function(){
networkReadyStatus(node);
});
node.wrapperbot.on('networkError', function(){
networkErrorStatus(node);
});
node.wrapperbot.on('ioError', function(err){
ioErrorStatus(node, err);
});
}
else {
this.warn("wrapperbot not configured");
}
}
RED.nodes.registerType("wrapper in",wrapperInNode);
function wrapperOutNode(n) {
RED.nodes.createNode(this,n);
this.buttonState = -1;
this.pin = n.pin;
this.state = n.state;
this.arduino = n.arduino;
this.wrapperbot = RED.nodes.getNode(n.board);
this.i2cAddress = parseInt(n.i2cAddress, 10);
this.i2cRegister = parseInt(n.i2cRegister, 10);
if (typeof this.wrapperbot === "object") {
var node = this;
connectingStatus(node);
node.wrapperbot.on('ioready', function() {
connectedStatus(node);
node.on('input', function(msg) {
try{
var state = msg.state || node.state;
var io = node.wrapperbot.io;
if (state === 'OUTPUT') {
try{io.pinMode(node.pin, io.MODES[state]);}catch(exp){ console.log(exp); }
if ((msg.payload == true)||(msg.payload == 1)||(msg.payload.toString().toLowerCase() === "on")) {
io.digitalWrite(node.pin, 1);
}
if ((msg.payload == false)||(msg.payload == 0)||(msg.payload.toString().toLowerCase() === "off")) {
io.digitalWrite(node.pin, 0);
}
}
else if (state === 'PWM') {
try{io.pinMode(node.pin, io.MODES[state]);}catch(exp){ console.log(exp); }
msg.payload = msg.payload * 1;
if ((msg.payload >= 0) && (msg.payload <= 255)) {
//console.log(msg.payload, node.pin);
io.analogWrite(node.pin, msg.payload);
}
}
else if (state === 'SERVO') {
try{io.pinMode(node.pin, io.MODES[state]);}catch(exp){ console.log(exp); }
msg.payload = msg.payload * 1;
if ((msg.payload >= 0) && (msg.payload <= 180)) {
//console.log(msg.payload, node.pin);
io.servoWrite(node.pin, msg.payload);
}
}
else if(node.state === 'I2C_READ_REQUEST'){
var register = parseInt(msg.i2cRegister, 10) || parseInt(node.i2cRegister, 10);
var i2cAddress = parseInt(msg.i2cAddress, 10) || parseInt(node.i2cAddress, 10);
var numBytes = parseInt(msg.payload, 10);
if(io.i2cReadOnce && i2cAddress && numBytes){
if(register){
io.i2cReadOnce(i2cAddress, register, numBytes, function(data){
node.send({
payload: data,
register: register,
i2cAddress: i2cAddress,
numBytes: numBytes
});
});
}else{
io.i2cReadOnce(i2cAddress, numBytes, function(data){
node.send({
payload: data,
i2cAddress: i2cAddress,
numBytes: numBytes
});
});
}
}
}
else if(node.state === 'I2C_WRITE_REQUEST'){
var register = parseInt(msg.i2cRegister, 10) || parseInt(node.i2cRegister, 10);
var i2cAddress = parseInt(msg.i2cAddress, 10) || parseInt(node.i2cAddress, 10);
if(io.i2cWrite && i2cAddress && msg.payload){
if(register){
io.i2cWrite(i2cAddress, register, msg.payload);
}else{
io.i2cWrite(i2cAddress, msg.payload);
}
}
}
else if(node.state === 'I2C_DELAY'){
if(io.i2cConfig){
if(register){
io.i2cConfig(parseInt(msg.payload, 10));
}
}
}
}
catch(inputExp){
node.warn(inputExp);
}
});
});
node.wrapperbot.on('networkReady', function(){
networkReadyStatus(node);
});
node.wrapperbot.on('networkError', function(){
networkErrorStatus(node);
});
node.wrapperbot.on('ioError', function(err){
ioErrorStatus(node, err);
});
}
else {
this.warn("wrapperbot not configured");
}
}
RED.nodes.registerType("wrapper out",wrapperOutNode);
function nodeLedNode(n) {
RED.nodes.createNode(this,n);
this.buttonState = -1;
this.address = Number(n.address);
this.mode = n.mode;
this.arduino = n.arduino;
this.wrapperbot = RED.nodes.getNode(n.board);
if (typeof this.wrapperbot === "object") {
var node = this;
connectingStatus(node);
node.wrapperbot.on('ioready', function() {
node.comp = new NodeLed[node.mode](node.wrapperbot.io, {address: node.address});
connectedStatus(node);
node.on('input', function(msg) {
try{
if(node.mode === 'AlphaNum4' || node.mode === 'SevenSegment'){
node.comp.writeText(msg.payload);
}
else{
node.comp.drawBitmap(msg.payload);
}
}
catch(inputExp){
node.warn(inputExp);
}
});
});
node.wrapperbot.on('networkReady', function(){
networkReadyStatus(node);
});
node.wrapperbot.on('networkError', function(){
networkErrorStatus(node);
});
node.wrapperbot.on('ioError', function(err){
ioErrorStatus(node, err);
});
}
else {
this.warn("wrapperbot not configured");
}
}
RED.nodes.registerType("wrapper-node-led",nodeLedNode);
function handleRoute(req, res, handler){
handler(req.query)
.then(function(data){
res.send(data);
}, function(err){
console.log('error in wrapper request', err);
res.send(500);
});
}
function listArduinoPorts(callback) {
return serialport.list(function(err, ports) {
if (err) {
return callback(err);
}
var devices = [];
for (var i = 0; i < ports.length; i++) {
if (/usb|acm|com\d+/i.test(ports[i].comName)) {
devices.push(ports[i].comName);
}
}
return callback(null, devices);
});
}
function johnny5Node(n) {
RED.nodes.createNode(this,n);
// console.log('initializing johnny5Node', n);
this.wrapperbot = RED.nodes.getNode(n.board);
this.func = n.func;
var node = this;
if (typeof this.wrapperbot === "object") {
process.nextTick(function(){
connectingStatus(node);
});
// console.log('launching johnny5Node', n);
node.wrapperbot.on('ioready', function() {
// console.log('launching johnny5Node ioready', n);
connectedStatus(node);
function sendResults(node,msgs) {
var _msgid = (1 + Math.random() * 4294967295).toString(16);
if (msgs == null) {
return;
} else if (!util.isArray(msgs)) {
msgs = [msgs];
}
var msgCount = 0;
for (var m=0;m<msgs.length;m++) {
if (msgs[m]) {
if (util.isArray(msgs[m])) {
for (var n=0; n < msgs[m].length; n++) {
msgs[m][n]._msgid = _msgid;
msgCount++;
}
} else {
msgs[m]._msgid = _msgid;
msgCount++;
}
}
}
if (msgCount>0) {
node.send(msgs);
}
}
var functionText = "var results = null;"+
"results = (function(){ "+
"var node = {"+
"log:__node__.log,"+
"error:__node__.error,"+
"warn:__node__.warn,"+
"on:__node__.on,"+
"status:__node__.status,"+
"send:function(msgs){ __node__.send(msgs);}"+
"};\n"+
node.func+"\n"+
"})();";
var sandbox = {
console:console,
util:util,
Buffer:Buffer,
__node__: {
log: function() {
node.log.apply(node, arguments);
},
error: function() {
node.error.apply(node, arguments);
},
warn: function() {
node.warn.apply(node, arguments);
},
send: function(msgs) {
sendResults(node, msgs);
},
on: function() {
node.on.apply(node, arguments);
},
status: function() {
node.status.apply(node, arguments);
}
},
context: {
set: function () {
return node.context().set.apply(node, arguments);
},
get: function () {
return node.context().get.apply(node, arguments);
},
get global() {
return node.context().global;
},
get flow() {
return node.context().flow;
}
},
flow: {
set: function () {
node.context().flow.set.apply(node, arguments);
},
get: function () {
return node.context().flow.get.apply(node, arguments);
}
},
global: {
set: function () {
node.context().global.set.apply(node, arguments);
},
get: function () {
return node.context().global.get.apply(node, arguments);
}
},
setTimeout: setTimeout,
clearTimeout: clearTimeout,
_:_,
five: five,
board: node.wrapperbot.board,
RED: RED,
require: require
};
var context = vm.createContext(sandbox);
try {
node.script = vm.createScript(functionText);
try {
var start = Date.now(); //process.hrtime();
//context.msg = msg;
node.script.runInContext(context);
// console.log('ran script', context);
} catch(err) {
var line = 0;
var errorMessage;
var stack = err.stack.split(/\r?\n/);
if (stack.length > 0) {
while (line < stack.length && stack[line].indexOf("ReferenceError") !== 0) {
line++;
}
if (line < stack.length) {
errorMessage = stack[line];
var m = /:(\d+):(\d+)$/.exec(stack[line+1]);
if (m) {
var lineno = Number(m[1])-1;
var cha = m[2];
errorMessage += " (line "+lineno+", col "+cha+")";
}
}
}
if (!errorMessage) {
errorMessage = err.toString();
}
this.error(errorMessage);
}
} catch(err) {
// eg SyntaxError - which v8 doesn't include line number information
// so we can't do better than this
this.error(err);
}
});
node.wrapperbot.on('networkReady', function(){
networkReadyStatus(node);
});
node.wrapperbot.on('networkError', function(){
networkErrorStatus(node);
});
node.wrapperbot.on('ioError', function(err){
ioErrorStatus(node, err);
});
}
else {
this.warn("wrapperbot not configured");
}
}
RED.nodes.registerType("wrapper-johnny5",johnny5Node);
//routes
RED.httpAdmin.get("/wrapperserialports", RED.auth.needsPermission("arduino.read"), function(req,res) {
listArduinoPorts(function (err, ports) {
res.json(ports);
});
});
}
我按照此处找到的所有文档:https://nodered.org/docs/
希望有人可以提供帮助:)
答案 0 :(得分:0)
首先,似乎您的RED变量未定义,因此这是主要问题。
createNodebotNode(RED);
然后在函数内定义一个函数:
module.exports = function(RED) {
createNodebotNode(RED);
function wrapperInNode(n) {
最后,就像有人说的那样,你将很难包装整个模块。只需要您需要的模块作为依赖项,并实现一个更高的组件来使用它。无需包装或扩展每个功能。