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

Client: how to identify Modbus exception code sent by server in response #169

Closed
cdbennett opened this issue Mar 10, 2023 · 2 comments
Closed

Comments

@cdbennett
Copy link
Contributor

How can user code using tokio-modbus as a Modbus client detect what specific exception code a server returned?

Two interrelated parts of this question:

  1. How user code can distinguish between a recoverable error during a Modbus request, (e.g. IllegalDataAddress, and a connection failure, e.g. TCP connection closed by remote host, or a protocol framing error.)
  2. How can user code identify which specific Modbus exception code was returned by the server. (E.g. IllegalDataAddress vs IllegalFunction)

In the case of Modbus exception responses, we don't want to close the Modbus connection. But if the network connection was lost, then user code needs to re-create a new tokio-modbus connection and start over.

Related:

@Stupremee
Copy link

Hey 👋

I'm really in the need of finding out what Modbus error I got from a slave for my application.
I noticed it's not possible using tokio-modbus yet (at leat without doing silly err.to_string().contains("illegal data address"), and co), and found this issue.

After looking through the code. I found a fast, simple way to get access to the exception from a modbus server. You just have to make the ExceptionResponse and Exception types publicy accessible. Then someone using this crate can try to downcast the std::io::Error to the ExceptionResponse type to extract the error.

@cdbennett
Copy link
Contributor Author

This issue is resolved, verified working now in tokio-modbus v0.14.0.

Example of issuing a command like:

    let values = read_registers(connection, start, count)
    .await
    .context("communication error")?
    .context("received a Modbus exception response")?;

and then the program might produce either a Modbus exception response:

Error: received a Modbus exception response

Caused by:
    Gateway target device failed to respond

or some other I/O error (in this case simulated by connecting to a server that sends random bytes instead of Modbus frames back):

Error: communication error

Caused by:
    Connection reset by peer (os error 104)

Thanks for getting this working!

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

Successfully merging a pull request may close this issue.

2 participants