plcpeople / nodeS7

Node.JS library for communication to Siemens S7 PLCs
MIT License
356 stars 120 forks source link

Read single item #127

Open WirelessSwitcher opened 2 years ago

WirelessSwitcher commented 2 years ago

I've been looking into a way to read one or a few booleans and although I managed to use the "conn.readAllItems(valuesReady);", I would like to bind the logged values to variables, so I could send them back to my client.

console.log("\n\n\nTrying to read something here"); conn.addItems(["TEST3"]); let read = conn.readAllItems(valuesReady); console.log("Read is: " + read); // this results in "Read is: Undefined"

I also tried to modify the valuesReady function:

function valuesReady(anythingBad, values) {

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

}

But again, no success.

Does anyone knows how can I get a readable value? Maybe I could even contribute to some specific code if there's no such a function to do it.

plcpeople commented 2 years ago

readAllItems doesn't return the values synchronously. It is meant to be called with a callback function (asynchronously) to initiate a read, which can take a while depending on how many values you are reading and what your network is like. nodes7 can be used over a VPN which means a response can take seconds, and you don't want your app to be non-responsive in that time. Modifying valuesReady isn't what I would suggest either as valuesReady is meant to be called as a callback function with the values when they are returned from the PLC, not as a function to get the values for use elsewhere.

You can, however, create an object within your module and update it in valuesReady, then have another function that returns its value.

Try this sort of pattern:

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 theValues = {};

var variables = {
      TEST1: 'MR40',          // Memory real at MD4
      TEST3: 'M20.0',        // Bit at M20.0
};

conn.initiateConnection({ port: 102, host: '192.168.1.113', rack: 0, slot: 1, debug: false }, connected); // slot 2 for 300/400, slot 1 for 1200/1500, change debug to true to get more info

setInterval(() => {
    console.log(theValues);
}, 2000);

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', 'TEST3']);
  conn.readAllItems(valuesReady);
}

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

function getValues() {
    return theValues;
}
WirelessSwitcher commented 2 years ago

Thanks for the suggestion, I will see if this can solve the issue. I understand nodeS7 has to be usable in a lot of different scenarios and I find it incredible that it can. Whenever I have the chance, I'll post the results. I'm also going to add the project to my git.

WirelessSwitcher commented 2 years ago

I'm getting "[84762,535272400 172.16.1.11 S1] Waiting to read for all R/W operations to complete. Will re-trigger readAllItems in 100ms." in a eternal loop. It only stops if I send a command write. And value printed is [object Object], when I get the response in the client side, it is "{}"