Modbus read callback

I am using this modbus master RTU library

// Read from a single coil
modbus.read(0x01, MODBUSRTU_TARGET_TYPE.COIL, 0x0001, 1, function(error, result) {
  if (error) {
    server.error(error);
  } else {
    server.log(result);
  }
}.bindenv(this));

How can I pass an additional argument to the callback “function(error, result)” ?

Not Modbus specific, so apologies if I’m answering the wrong question, but if you generally want to pass additional context to a squirrel callback you can wrap the context in a class and then bindenv the function to an instance of that class, e.g.:

class Context {
    _context = null;
    constructor(context) { _context = context; }
    function context() { return _context; }
};

function callbackWithContext(context) {
    imp.wakeup(0, function() {
        server.log("additional argument = " + this.context());
    }.bindenv(Context(context)));
}

callbackWithContext("foo");
callbackWithContext("bar");
callbackWithContext(this);
callbackWithContext(123);

Phil’s solution is a great generic approach. For the Modbus lib in particular, the callback parameters are defined by the library itself. Look for _callbackHander() in ModbusSerialMaster.device.lib.nut, which triggers the callback you supply in the line you quote and passes in values for error and result.

You can add to a third param to the function you pass into modbus.read(), but you’ll need to provide a default parameter value, or you’ll get an wrong number of parameters error when the callback is executed: _callbackHander() hasn’t passed in a value. Soemthing like:

function dataLog(m) {
    server.log(m);
}

local myData = "This is my extra data";
modbus.read(0x01, MODBUSRTU_TARGET_TYPE.COIL, 0x0001, 1, function(err, result, userData = myData) {
    if (err) {
        server.error(err);
    } else {
        server.log(result);
    }

    // Do something with the userData
    dataLog(userData);
}.bindenv(this));

Alternatively, you can subclass ModbusSerialMaster ( class ModbusSerialMasterAlt extends ModbusSerialMaster { ... }) which just overrides _callbackHander() to pass an extra param into the callback? Could get messy, though, depending on what else calls that function.

Thank you for help @phil , @smittytone .

This topic was automatically closed after 60 days. New replies are no longer allowed.