作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在编写一个库来扩展传感器的使用,并使其他人更容易使用它。我的目标是将 40 个传感器实现为单个 Node 中的 node-red-contrib-library,以便发布供其他人简单直观地使用,而无需对传感器本身进行任何进一步编码。
我被困在需要使用另一个名为 node-red-contrib-gpio 的库的位置上.我想要么包装它,要么改编它。可悲的是,我没有找到任何关于将任何 npm 包包装到另一个包中的信息,也没有找到任何调整一个包的帮助。所以现在我试着在这里寻求帮助。
我目前在适配上述npm的状态如下:我设法重新创建了 gpio 库中使用的配置 Node 并注册了所有内容,但就在此时我卡住了。
我的终端输出是这样的: 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/
希望有人能帮忙:)
最佳答案
嗯,几个想法。
首先,您的 RED 变量似乎未定义,所以这是主要问题。
createNodebotNode(RED);
然后在函数内部定义一个函数:
module.exports = function(RED) {
createNodebotNode(RED);
function wrapperInNode(n) {
最后,您将很难像有人说的那样包装整个模块。只需将您需要的模块作为依赖项,并实现将使用它的更高组件。无需包装或扩展每个功能。
关于javascript - Node 红色 : TypeError: Cannot read property 'nodes' of undefined,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47123365/
我是一名优秀的程序员,十分优秀!