Search code examples
node.jsnode-modulesnode-red

new not working in function block of node-red


I am trying to use nodes7 in a function block, as s7 did not suffice for my purpose (nodes7 is underlying library used by s7).

The example given in nodes7, works fine as an independent node application. The code is given below.

var nodes7 = require('nodes7');  // This is the package name, if the repository is cloned you may need to require 'nodeS7' with uppercase S
var conn = new nodes7;
var doneReading = false;
var doneWriting = false;

var variables = { TEST1: 'MR4',         // Memory real at MD4
          TEST2: 'M32.2',       // Bit at M32.2
          TEST3: 'M20.0',       // Bit at M20.0
          TEST4: 'DB1,REAL0.20',    // Array of 20 values in DB1
          TEST5: 'DB1,REAL4',       // Single real value
          TEST6: 'DB1,REAL8',       // Another single real value
          TEST7: 'DB1,INT12.2',     // Two integer value array
          TEST8: 'DB1,LREAL4'       // Single 8-byte real value
};

conn.initiateConnection({port: 102, host: '192.168.0.2', rack: 0, slot: 1}, connected); // slot 2 for 300/400, slot 1 for 1200/1500
//conn.initiateConnection({port: 102, host: '192.168.0.2', localTSAP: 0x0100, remoteTSAP: 0x0200, timeout: 8000}, connected); // local and remote TSAP can also be directly specified instead.  The timeout option specifies the TCP timeout.

function connected(err) {
    if (typeof(err) !== "undefined") {
        // We have an error.  Maybe the PLC is not reachable.
        console.log(err);
        process.exit();
    }
    conn.setTranslationCB(function(tag) {return variables[tag];});  // This sets the "translation" to allow us to work with object names
    conn.addItems(['TEST1', 'TEST4']);
    conn.addItems('TEST6');
//  conn.removeItems(['TEST2', 'TEST3']);  // We could do this.
//  conn.writeItems(['TEST5', 'TEST6'], [ 867.5309, 9 ], valuesWritten);  // You can write an array of items as well.
    conn.writeItems('TEST7', [ 666, 777 ], valuesWritten);  // You can write a single array item too.
    conn.readAllItems(valuesReady);
}

function valuesReady(anythingBad, values) {
    if (anythingBad) { console.log("SOMETHING WENT WRONG READING VALUES!!!!"); }
    console.log(values);
    doneReading = true;
    if (doneWriting) { process.exit(); }
}

function valuesWritten(anythingBad) {
    if (anythingBad) { console.log("SOMETHING WENT WRONG WRITING VALUES!!!!"); }
    console.log("Done writing.");
    doneWriting = true;
    if (doneReading) { process.exit(); }
}

However, I am unable to use this in function block. I have included the nodes7 as below as advised by the node-red community while requiring additional package

    functionGlobalContext: {
        nodes7:require('nodes7')
        // os:require('os'),
        // jfive:require("johnny-five"),
        // j5board:require("johnny-five").Board({repl:false})
    },

However my code breaks when I construct the object as below as given in example.

var conn = new nodes7;

I have tried var conn = new nodes7(); also but in vain. I am getting the below error.

"TypeError: nodes7 is not a constructor"

So the nodes7 variable is referenced properly, but node-red complaints its not a constructor. how do I then go ahead. Below is my whole function block code throwing above error.

var nodes7 = global.get('nodes7');
var conn = new nodes7();

conn.initiateConnection({port: 102, host: '127.0.0.1', rack: 0, slot: 1}, connected); // slot 2 for 300/400, slot 1 for 1200/1500
node.log('This worked');

function connected(err) 
{
    if (typeof(err) !== "undefined") 
    {
        // We have an error.  Maybe the PLC is not reachable.
        node.log('Connection not successful');
    }

}

return msg;

If helps, I have just used an inject node before and a debug node after, just to observe. I am newbie to node-red. Please help.

enter image description here

Update 1:

As requested by one user, I inserted node.warn(nodes7) before calling constructor and observe that it is undefined. But why? I am using global.get, installed in proper directly (I could see in node_modules folder of node-red) still this happens.

enter image description here

Update 2

I updated the settings.js file as in usr directory but still getting the same response as undefined. Please find below pics.

Locating the settings.js file..

enter image description here

Navigating to that file...

enter image description here

Updating that file by opening vs code there..

enter image description here

Installed nodes7 and then and restarting node-red, I still get same error.. below is the code..

enter image description here

Update 3

My update 2 works after closing all, and restarting..


Solution

  • NPM modules referenced from the settings.js in the functionGlobalContext need to be installed in the userDir because they are loaded relative to the active settings.js file.

    Both the userDIR and settings.js file that are in use are logged in the first few lines of output when Node-RED starts up.

    You should only be editing the settings.js file in the userDir. The version in the Node-RED install dir is only used when setting up new userDir's. You will also need to restart Node-RED when ever you edit this file.