Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Keep getting GatewayTargetDeviceFailedToRespond #66

Open
dyaacov opened this issue Mar 21, 2021 · 18 comments
Open

Keep getting GatewayTargetDeviceFailedToRespond #66

dyaacov opened this issue Mar 21, 2021 · 18 comments

Comments

@dyaacov
Copy link

dyaacov commented Mar 21, 2021

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

@dresende
Copy link
Member

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) => {
	// ...
});

@dyaacov
Copy link
Author

dyaacov commented Mar 22, 2021 via email

@dresende
Copy link
Member

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

@dyaacov
Copy link
Author

dyaacov commented Mar 22, 2021 via email

@dresende
Copy link
Member

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
Copy link
Member

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.

@dyaacov
Copy link
Author

dyaacov commented May 23, 2021

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?

@dresende
Copy link
Member

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.

@dyaacov
Copy link
Author

dyaacov commented May 24, 2021

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

@dresende
Copy link
Member

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).

@dyaacov
Copy link
Author

dyaacov commented May 24, 2021

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>
    ]
  }

@dresende
Copy link
Member

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

@dyaacov
Copy link
Author

dyaacov commented May 25, 2021

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.

@dresende
Copy link
Member

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..?

@dyaacov
Copy link
Author

dyaacov commented Jun 23, 2021

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
Copy link
Author

dyaacov commented Aug 2, 2021

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?

@dresende
Copy link
Member

dresende commented Aug 2, 2021

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).

@dyaacov
Copy link
Author

dyaacov commented Aug 2, 2021

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants