stream icon indicating copy to clipboard operation
stream copied to clipboard

Keep getting GatewayTargetDeviceFailedToRespond

Open dyaacov opened this issue 4 years ago • 18 comments

Hi All,

I'm using the basic example to get coils/registers from our Meter. I keep getting GatewayTargetDeviceFailedToRespond :(

var modbus = require("modbus-stream");

modbus.tcp.server({ debug: null  }, (connection) => {
  console.log("incoming connection");
  connection.readCoils({ address: 0, quantity: 5 }, (err, info) => {
      console.error("err", err);
      console.log("response", info);
  });
  
}).listen(502);

Please help, Dekel

dyaacov avatar Mar 21 '21 18:03 dyaacov

Hi,

I had a similar responde from a S&P Domeo. It was a very simple fix:

  • The device is sleeping and you need to wake it up, by sending something. A request is enough but it won't reply to that request, it will just wake up;
  • The device will get back to sleep usually under a minute.

The problem is that the library defaults have a very large timeout value. Try changing to this:

modbus.tcp.connect(502, "1.2.3.4", {
	debug   : null,
	retries : 5,   // number of tries
	retry   : 500, // half a second retry (default is 30 seconds or more, which does not work)
}, (err, connection) => {
	// ...
});

dresende avatar Mar 22 '21 09:03 dresende

Hi,

In my case, I develop the server, the client is a meter. in the meter, I changed the timeout to 1 second, still same issue

var modbus = require("modbus-stream");

modbus.tcp.server({ debug: null }, (connection) => { console.log("incoming connection"); connection.readInputRegisters({ address: 0, quantity: 16 }, (err, info) => { console.error("err", err); console.log("response", info); }); }).listen(502);

On Mon, Mar 22, 2021 at 11:43 AM Diogo Resende @.***> wrote:

Hi,

I had a similar responde from a S&P Domeo. It was a very simple fix:

  • The device is sleeping and you need to wake it up, by sending something. A request is enough but it won't reply to that request, it will just wake up;
  • The device will get back to sleep usually under a minute.

The problem is that the library defaults have a very large timeout value. Try changing to this:

modbus.tcp.connect(502, "1.2.3.4", { debug : null, retries : 5, // number of tries retry : 500, // half a second retry (default is 30 seconds or more, which does not work)}, (err, connection) => { // ...});

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/node-modbus/stream/issues/66#issuecomment-803920626, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAZ3NNHRG2V5SUYKOXNWQ6DTE4GN3ANCNFSM4ZR2ODBA .

dyaacov avatar Mar 22 '21 11:03 dyaacov

And you seen an incoming connection but the devices doesn't respond to your request?

dresende avatar Mar 22 '21 12:03 dresende

exactly.

connection.readInputRegistersends up in GatewayTargetDeviceFailedToRespond

On Mon, Mar 22, 2021 at 2:22 PM Diogo Resende @.***> wrote:

And you seen an incoming connection but the devices doesn't respond to your request?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/node-modbus/stream/issues/66#issuecomment-804021262, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAZ3NNGWLUOG6XERAIPLEHLTE4ZBDANCNFSM4ZR2ODBA .

dyaacov avatar Mar 22 '21 14:03 dyaacov

In that case, it makes little sense. Are you sure it doesn't need any type of wake up? If it's compliant, it should respond with an error. That error is the library telling you it didn't respond.

dresende avatar Mar 22 '21 17:03 dresende

Still, try passing a lower retry option (2nd argument). The default is 30 seconds and the device might respond to the 2nd or 3rd try.

dresende avatar Mar 22 '21 17:03 dresende

Hi, Sorry for the very late response, is it possible that the server did not send the tcp handshake to the hardware (upon connection recieved), and therefore cannot request for registers?

dyaacov avatar May 23 '21 18:05 dyaacov

TCP is handled in a lower level, we have no control. But it should handle network issues. What doesn't handle is if the hardware is sleeping and uses the first try to wake up. That's the point of retrying a few times, to give it time to wake up and respond.

dresende avatar May 23 '21 20:05 dresende

Still same :(

I had a session with the hardware support (https://www.satec-global.com/PM135) He showed me that via their administrative tools (resides on the same network as the meter), he is able to read registers.

Any additional methods to debug the issue?

var modbus = require("modbus-stream");

modbus.tcp.server({ debug: null  }, (connection) => {
  console.log("incoming connection");
  connection.readInputRegisters({ address: 46081, quantity: 6, retry: 5000, retries: 10 }, (err, info) => {
      console.error("err", err);
      console.log("response", info);
  });
  
}).listen(502);
incoming connection
err Error: GatewayTargetDeviceFailedToRespond
    at Object.exports.error (/home/ubuntu/altecog/netzer/code/node_modules/modbus-pdu/lib/Exception.js:24:13)
    at Timeout._onTimeout (/home/ubuntu/altecog/netzer/code/node_modules/modbus-stream/lib/transport/transport.js:93:33)
    at listOnTimeout (internal/timers.js:549:17)
    at processTimers (internal/timers.js:492:7) {
  code: 11
}
response undefined

dyaacov avatar May 24 '21 04:05 dyaacov

He showed me that via their administrative tools (resides on the same network as the meter), he is able to read registers.

You're not? Can you test your code there?

Another thing, you're reading address 46081. Is that address on the specification of that device? Usually devices start input registers at 40001 but the protocol address always starts at zero. Perhaps the devices just ignores your request because of that address, try using address 6080 (46081-40001).

dresende avatar May 24 '21 08:05 dresende

I tried a different approach:

I ran the code on a local machine resides on the same network as the device:

  1. the above code still did not work.
  2. the following code does work (connecting from the machine to the device):
var modbus = require("modbus-stream");

modbus.tcp.connect(502, "10.0.0.55", { debug: "automaton-2454" }, (err, connection) => {
   connection.readHoldingRegisters({ address: 0,quantity: 6, retry: 5000, retries: 10 }, (err, info) => {
        console.error("err", err);
        console.log("response", info);
     });
});


.....
 response: {
    code: 'ReadHoldingRegisters',
    data: [
      <Buffer 0b ab>,
      <Buffer 00 00>,
      <Buffer 01 d1>,
      <Buffer 09 52>,
      <Buffer 00 00>,
      <Buffer 10 24>
    ]
  }

dyaacov avatar May 24 '21 19:05 dyaacov

I believe it was the address. Now you just have to parse those registers. I would assume they are (u)int16 big endian as most are. So maybe...

> Buffer.from([ 0x0b, 0xab ]).readUInt16BE(0)
2987

And perhaps that number has decimals and it's 298,7 or 29,87

dresende avatar May 24 '21 23:05 dresende

I think you misunderstood me...

It is still doesn't work when the device ping the server and the server requests from registers. It only works when I try to connect directly to the device, which in reality cannot work since I will not have access to devices from remote.

dyaacov avatar May 25 '21 05:05 dyaacov

Oh..

  • so modbus seems to work;
  • network seems to not be an issue.

Perhaps the device has some kind of handshake or something? I had a bridge once that did just that. It would open a connection but before switching to modbus tcp, there was a very basic (and insecure) handshake/authentication. Perhaps the device is waiting for an hello packet or it send an hello packet..?

dresende avatar May 25 '21 08:05 dresende

Hi again,

We continued the debugging, I do see the registers are sent from the meter (using wireshark) but the server cannot get them (Error: GatewayTargetDeviceFailedToRespond). I made sure no firewall or permissions interrupt but I still cannot get it to work.

Attached is the tcpdump from the server. maybe you can take a look? output.zip

dyaacov avatar Jun 23 '21 15:06 dyaacov

Apparently the problem is in the address we read from, when we read from 0 (which holds custom registers) we get errors. when reading from 256 it should work, however, im getting "This socket has been ended by the other party"

any idea?

dyaacov avatar Aug 02 '21 07:08 dyaacov

That error usually means the other endpoint terminated connection in the meantime. Perhaps listening to end event will catch that. If not, the other endpoint is ending without telling you (like a TCP RESET).

dresende avatar Aug 02 '21 08:08 dresende

Yes, I found one of the posts here talking about this. The thing is that we changed the device to talk to a friend's server and it works there. I will take a look at his code next week.

is there an example on how to somehow keep the socket open once connection is made?

dyaacov avatar Aug 02 '21 08:08 dyaacov