Git Product home page Git Product logo

tokio-modbus's Introduction

tokio-modbus

A pure Rust Modbus library based on tokio.

Crates.io Docs.rs Security audit Continuous integration MIT licensed Apache 2.0 licensed

Modbus is based on a master/slave communication pattern. To avoid confusion with the Tokio terminology the master is called client and the slave is called server in this library.

Features

  • Pure Rust library
  • Modbus TCP or RTU at your choice
  • Both async (non-blocking, default) and sync (blocking, optional)
  • Client API
  • Server implementations
    • for out-of-the-box usage or
    • as a starting point for a customized implementation
  • Open source (MIT/Apache-2.0)

Installation

Add this to your Cargo.toml:

[dependencies]
tokio-modbus = "*"

Cargo Features

  • "rtu": Asynchronous RTU client (default)
  • "tcp": Asynchronous TCP client (default)
  • "rtu-sync: Synchronous RTU client
  • "tcp-sync": Synchronous TCP client
  • "rtu-server": (Asynchronous) RTU server
  • "tcp-server": (Asynchronous) TCP server
  • "rtu-over-tcp-server": (Asynchronous) RTU over TCP server

Examples

If you only need an asynchronous TCP client add the following line to your Cargo.toml file:

[dependencies]
tokio-modbus = { version = "*", default-features = false, features = ["tcp"] }

For an asynchronous RTU client:

[dependencies]
tokio-modbus = { version = "*", default-features = false, features = ["rtu"] }

For an RTU server:

[dependencies]
tokio-modbus = { version = "*", default-features = false, features = ["rtu-server"] }

For a TCP server:

[dependencies]
tokio-modbus = { version = "*", default-features = false, features = ["tcp-server"] }

Examples

Various examples for Modbus RTU and TCP using either the asynchronous or synchronous API can be found in the examples folder.

Testing

The workspace contains documentation, tests, and examples for all available features.

cargo test --workspace
cargo test --workspace --all-features

Protocol-Specification

License

Copyright (c) 2017-2024 slowtec GmbH

MIT/Apache-2.0

tokio-modbus's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tokio-modbus's Issues

tcp-server.rs tag v0.4.0 doesn't compile

Hello,

Last week (11th June) I have been testing 'tcp-server.rs' from 'slowtec/tokio-modbus/examples' and there is some kind of issue related to 'tcp' and 'server' features. If you try to compile 'tcp-server.rs' you will receive an error and I think that it comes from the feature 'server'. It is like it cannot be found even writing it in 'dependencies' in 'Cargo.toml'

However, I tried 'tcp-server.rs' tag v0.3.5 and it runs without problem.

method not found in `impl futures::future::Future`

Cargo.toml :

[dependencies]
serde = "*"
serde_json = "*"
serde_derive = "*"
derive-new = "*"
tokio-modbus = "*"
tokio-serial = "*"

My Custom Example:

use tokio_modbus::prelude::*;
use tokio_serial::{Serial, SerialPortSettings};
use tokio_core::reactor::Core;
use futures::future::Future;

let mut settings = tokio_serial::SerialPortSettings::default();
settings.baud_rate = 115200;
settings.timeout = time::Duration::from_millis(500);
println!("settings is '{:?}'", settings);

let mut core = Core::new().unwrap();
let handle = core.handle();
let tty_path = "/dev/ttyUSB0";
const SLAVE_1: Slave = Slave(0x01);
	
let port = Serial::from_path_with_handle(tty_path, &settings, &handle.new_tokio_handle()).unwrap();
	
let task = rtu::connect_slave(&handle, port, slave).and_then(|ctx| {
	println!("Reading a sensor value");
	ctx
		.read_holding_registers(0x082B, 2)
		.and_then(move |rsp| {
			println!("Sensor value is: {:?}", rsp);
			Ok(())
			})
	});
	
core.run(task).unwrap();

Error:

method named `and_then` found for opaque type `impl futures::future::Future` in the current scope
let task = rtu::connect_slave(&handle, port, slave).and_then(|ctx| {
    |                                                             ^^^^^^^^ method not found in `impl futures::future::Future`

Move from tokio-core and tokio-proto to tokio

First and foremost! Thanks a lot for sharing this library! I was trying to use it today and noticed that it uses the deprecated tokio-core and tokio-proto crates. Is there any particular issue holding back the migration to the current tokio crate?

Modbus TCP / RTU Gateway

Hello.
I need simple example with modbus gateway - TCP Server/RTU master(serial port).
Please help me.

Support for unit ids

First of all thank you for sharing this crate with us!

I guess this is a feature request but it may just be a documentation issue.
I need to setup a modbus TCP communication relying on unit identifiers (I think it is also referred to as slave id). I think this is not supported by this crate but could you please confirm it ?

If the feature is actually missing, is there any plan to implement it ?

Reponse to WriteSingleCoil is malformed

The response to WriteSingleCoil is not correct.

I was testing with the Node.js module 'modbus-serial' as a TCP client and this crate as the Modbus TCP server, when I got an error on writeCoil (aka WriteSingleCoil).

I then traced the packets using WireShark and it confirmes that Data is missing from the Response.

Modbus
    .000 0101 = Function Code: Write Single Coil (5)
    [Request Frame: 2612]
    [Time from request: 0.000282788 seconds]
    Reference Number: 20
    Data: <MISSING>
[Malformed Packet: Modbus]
    [Expert Info (Error/Malformed): Malformed Packet (Exception occurred)]
        [Malformed Packet (Exception occurred)]
        [Severity level: Error]
        [Group: Malformed]

I am not sure on the validity of this page https://www.modbustools.com/modbus.html#function05, but it specifies that the response must be an echo of the request.

I have clone the project and will try to fix it. I would like here, however, if you agreed with my findings or I'm wrong.

Regards,
Thomas

Panic when pulling cable on RTU device

Pulling the cable on a device while a request is processing results in a panic at tokio-modbus/src/service/rtu.rs:60:

    async fn call(&mut self, req: Request) -> Result<Response, Error> {
        let disconnect = req == Request::Disconnect;
        let req_adu = self.next_request_adu(req, disconnect);
        let req_hdr = req_adu.hdr;

        self.service.send(req_adu).await?;
        let res_adu = self.service.next().await.unwrap()?; // This is where it panics

        match res_adu.pdu {
            ResponsePdu(Ok(res)) => verify_response_header(req_hdr, res_adu.hdr).and(Ok(res)),
            ResponsePdu(Err(err)) => Err(Error::new(ErrorKind::Other, err)),
        }
    }

This seems to be a regression from v0.3.5 where it would instead return a broken pipe error.

It looks like it should be a pretty easy fix. Just map the None to some error and return that.

Having trouble running a simple read register example

Hi I was wondering if you can see why I can't get the following example to work.
I get the error
ExceptionResponse { function: 3, exception: GatewayTargetDevice }

pub fn main() {

    let mut core = Core::new().unwrap();
    let handle = core.handle();
    let socket_addr = "10.0.128.181:502".parse().unwrap();

    let task = tcp::connect(&handle, socket_addr).and_then(|ctx| {

        ctx
            .read_holding_registers(0x16, 2)
            .and_then(move |data| {
                println!("Response is '{:?}'", data);
                Ok(())
            })
    });
    core.run(task).unwrap();
}

I know the ip code is correct as the following Python code works

c = ModbusClient()
c.host("10.0.128.181")
c.port(502)
c.unit_id(1)
c.debug(False)
c.open()

regs = c.read_holding_registers(0x16, 2)

if regs:
    print(regs)
    lsb = regs[0]
    msb = regs[1]
    print (msb << 16) | lsb
else:
    print("read error")

c.close()

What could be the issue here ?
Thanks

Any example for ExceptionResponse?

I'm a rust newcomer and am building a modbus server, and when the client sends the wrong address I need to give feedback on the error message, whether there are any examples of ExpressinResponse

Error inspection is difficult because error types are not exported

There are some errors that could be survived, for instance if an illegal address is used. But some errors, like a broken connection, are hard if not impossible to survive.

However, all the error types in the library seem to be pub(crate) meaning I cannot downcast any errors to eg ExceptionResponse (even though it implements Error).

I would suggest making ExceptionResponse and Exception (here) public to allow anyone handling errors when using the libray to inspect the cause of the error. As it stands, I imagine I have to call .description() and match on the returned string.

I haven't thought the implications through, I just wanted to file this request and am hoping to open a discussion from here.

Multiple servers on same tokio runtime

Hello,

I see this library is being actively developed, and I want to suggest to make it possible to spawn MODBUS TCP slave on the same tokio runtime (reactor) as other servers. I want to make an APP which listens on HTTP, MODBUS TCP and Serial port at the same time, and not to use threads for this purpose. Currently it seems there are not enough abstraction for the TCP server and its startup can't be easily customized. Perhaps you can suggest a way of doing what I need without modifying the tokio-modbus library?

How to use it๏ผŸ

I am sorry๏ผŒi am a newest rusterใ€‚

when i use you code,
i got below error

cargo run
feature tcp is required to run this example

can you help me !
appreciate you!!!!!!!!!!!!!!!!

ps: I am really not understand how to use rust features.

build problem

hi
when i build the code๏ผŒi got below error๏ผš

root@zynq:~/test_modbus# cargo build --features "tcp server"
   Compiling test_modbus v0.1.0 (/root/test_modbus)
error[E0433]: failed to resolve: could not find `tcp` in `server`
  --> src/main.rs:34:17
   |
34 |         server::tcp::Server::new(socket_addr).serve(|| Ok(MbServer));
   |                 ^^^ could not find `tcp` in `server`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0433`.
error: could not compile `test_modbus`.

To learn more, run the command again with --verbose.


Can you help me, appreciate you!!!!!!!!!!!!!!!!!!!!!!!!!!

Unable to Close TCP Client Connection

Target: ARMv7 (musl)

I have a warp webserver that upon a request will open a connection and read some registers, and I want the connection to close after the registers are successfully read. Using the async API, I expected the TCP client connections to close when contexts are dropped, but they do not (netstat shows them in established state). I tried Context::disconnect, but that causes a panic ('internal error: entered unreachable code'). What is the correct way to disconnect the TCP connection?

let read_input_registers = get2()
        .and(path!("rir" / u16 / u16)
        .and(path::end())
        .and_then(move |start, count|{
            let (p, c) = futures::sync::oneshot::channel::<String>();
            remote.spawn(move |handle|
                client::tcp::connect(handle, localhost)
                .and_then(move |ctx| ctx.read_input_registers(start, count)/*.and_then(move |res| ctx.disconnect().then(|_| Ok(res)))*/)
                .then(|res|{
                    p.send(match res{
                        Ok(data) => format!("{:?}", data),
                        Err(err) =>  format!("{:?}", err)
                    }).unwrap_or(());
                    Ok(())
                })
            );
            c.map_err(|err| warp::reject::custom(err))
        }));

I've switched to the modbus crate until I can figure this out. I'd prefer to use this one since it's non-blocking.

Cannot run RTU client sync example

  • I wanted to give to give the Modbus RTU client examples a test drive but failed in both cases
    • rtu-client-sync.rs panics with
      $ cargo run --features rtu,sync --example rtu-client-sync
         Compiling tokio-modbus v0.5.2 (/.../tokio-modbus)
          Finished dev [unoptimized + debuginfo] target(s) in 0.85s
           Running `target/debug/examples/rtu-client-sync`
      thread 'main' panicked at 'there is no reactor running, must be called from the context of a Tokio 1.x runtime', /.../.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.14.0/src/runtime/context.rs:29:26
      note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
      
  • Is this examples expected to run out of the box?
  • What could I do to actually get it running?
  • At a first first glance into context.rs:29 it looks like borrowing from CONTEXT fails and I bet there is some initialization missing. But this is my first contact with Tokio and I have no idea about the what, how, and why.

Making a new release?

Thanks for your work on this project!

The last release of this projects is v0.3.5 which was released December 2019. Since than quite some changes have been made. Are you planning on releasing those soon?

Custom TCP connect timeout ?

Hello,

Is it possible to set a custom TCP connect timeout ?
I'm new to rust, I might be missing some things obvious in the way tokio works

If it's not possible and of interest, I'm willing to give it a go.

Thanks!

Upgrade to tokio 0.3

Hi!

Currently tokio is on version 0.3.6, while this crate only supports the 0.2 versions of tokio.

Using the 0.3 versions of tokio leads to a thread 'tokio-runtime-worker' panicked at 'there is no reactor running, must be called from the context of Tokio runtime' runtime error, when using the tcp client to connect to something.

Split Reader/Writer from ModbusClient trait

The ModbusClient trait contains many read/write methods that can all be implemented in terms of the generic call() method. Those methods could be factored out into separate Reader and Writer adapters to simplify the trait.

This becomes even more significant when duplicating the methods by introducing a device_id as proposed in #8 and #9. With separate Reader and Writer adapters the resulting trait would only contain two methods call(request) and call_device(request, device_id).

consider using `async_trait`

This is more of an internal structuring thing, but I noticed that in many parts of the code base explicit Pin<Box<dyn Future<...>>>s are returned.
While this works, it's a bit tedious to read, so using async-trait may be worth considering for the internal traits, such as Client, Reader and Writer.

RTU example panics with BorrowMutError

Running the rtu-example panics with:

Reading a sensor value from Slave(2)
thread 'main' panicked at 'already borrowed: BorrowMutError', src/libcore/result.rs:1188:5

Deleting lines 67 and 68 fixes the issue.

Server::Service trait has no mechanism to obtain request's unit ID in call implementation

For an RTU server, it's important to know a request's unit ID when the devices are on a bus. For example, on an RS-485 bus, all devices will receive all requests but only the intended receipient should send a reply.

For a TCP server, knowing the request's unit ID allows implementing logical devices or the implementation of a gateway that forwards a request to an RTU device.

The rtu and tcp server implementation already have the unit id readily available in the Header struct that they get in a frame:

let hdr = request.hdr;
let response = service.call(request.pdu.0).await.map_err(Into::into)?;

let hdr = request.hdr;
let response = service.call(request.pdu.0).await.map_err(Into::into)?;

The first potential solution that comes to mind is modifying Server::Service::call's signature to this:

fn call(&self, slave: Slave, req: Self::Request) -> Self::Future;

no method named `read_holding_registers` found for type `impl std::future::Future`

Firstly, thanks to both Slowtec for creating this library and Omnioiot for updating it with async/await support!
My code below is based on omnioiot's async branch (#35 ) so I could use the new async/await functionality. I have also included my Cargo.toml

I'm running into an issue when trying to use the tokio_modbus::client::sync::tcp::connect function. It seems to be returning the result of the connection from my connect_sync() function wrapped in a Future even though the function signature states that it only returns a Result

The source for this function does not mention a Future. I may be missing something here but I'm confused as to why a sync method needs to be using a Future

Here is my code, the error is on line 8

Thanks for the help!

use tokio_modbus::prelude::*;
use tokio_modbus::client::tcp;
use tokio_modbus::client::sync::*; // TODO, refactor this to use async I/O

pub fn main() {

    let ctx = connect_sync();
    let power = ctx.read_holding_registers(40204, 1);
    println!("Power = {:?}", power);
    
}

async fn connect_sync() -> Result<tokio_modbus::client::sync::Context, std::io::Error> {
    
    let socket_addr = "127.0.0.1:5020".parse().unwrap();
    
    println!("attempting to connect");
    println!("{:?}", socket_addr);
    
    let ctx = tokio_modbus::client::sync::tcp::connect(socket_addr)?;
    Ok(ctx)
}

Cargo.toml

[package]
name = "tokio-mb-omnioiot"
version = "0.1.0"
authors = ["conorf50"]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
tokio-modbus = {git = "https://github.com/omnioiot/tokio-modbus", branch = "async"}
tokio = {version = "0.2.9", features = ["full"]}
async-std = "1.4.0"

[features]
tcp = []
sync = []

Trying to understand asynchronous client.

Hi I am having trouble understanding how or the best way to make many requests in a multi threaded way.
Basically I was trying to simulate talking to a couple of thousand modbus devices as quickly as possible. As I don't have those devices :) I was running your tcp-server.rs example with added delays of 60-80 ms. This seems reasonable as a simulation.

My trouble is developing the client code.

I want all the requests to be asynchronous. Once they all complete I would store these results into a db.

Would you recommend running code like

let socket_addr = "192.168.0.222:502".parse().unwrap();
let mut ctx = sync::tcp::connect(socket_addr).unwrap();
let buff = ctx.read_input_registers(0x1000, 7).unwrap();

in many threads and having each result send back through a channel ? or is there a better way built in using tokio async ?

Thanks

Missing futures-util/sink and tokio/net features

Steps to reproduce

  1. Define dependency in your project:
[dependencies.tokio-modbus]
version = "0.4"
default-features = false
features = ["tcp"]
git = "https://github.com/slowtec/tokio-modbus"
rev = "48a3b93"
  1. run cargo-check:
error[E0432]: unresolved import `futures_util::sink`
 --> ~/.cargo/git/checkouts/tokio-modbus-4bf0058fcb35ae92/48a3b93/src/service/tcp.rs:8:20
  |
8 | use futures_util::{sink::SinkExt, stream::StreamExt};
  |                    ^^^^ could not find `sink` in `futures_util`

error[E0432]: unresolved import `tokio::net::TcpStream`
  --> ~/.cargo/git/checkouts/tokio-modbus-4bf0058fcb35ae92/48a3b93/src/service/tcp.rs:16:5
   |
16 | use tokio::net::TcpStream;
   |     ^^^^^^^^^^^^^^^^^^^^^ no `TcpStream` in `net`

The problem

Running

cargo build --no-default-features --features tcp

within the tokio-modbus project does not fail! Why?

Fix

We just have to enable the sink and net features within the tokio-modbus feature tcp:

  [features]
- tcp = []
+ tcp = ["tokio/net", "futures-util/sink"]

Sync Client: could not find `runtime` in `tokio`

Hello,

Thank you for this nice project :-).

Trying the small project with tokio-modbus 0.5.0 raises a compilation error:

[dependencies]
tokio-modbus = { version = "0.5", default-features = false, features = ["tcp", "sync"] }
pub fn main() {
    use tokio_modbus::prelude::*;

    let socket_addr = "192.168.0.222:502".parse().unwrap();
    let mut ctx = client::sync::tcp::connect(socket_addr).unwrap();
    let buff = ctx.read_input_registers(0x1000, 7).unwrap();
    println!("Response is '{:?}'", buff);
}

It raises the following error:

cargo run
   Compiling tokio-modbus v0.5.0
error[E0433]: failed to resolve: could not find `runtime` in `tokio`
  --> /Users/hwhost/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-modbus-0.5.0/src/client/sync/mod.rs:50:18
   |
50 |     core: tokio::runtime::Runtime,
   |                  ^^^^^^^ could not find `runtime` in `tokio`

error[E0433]: failed to resolve: could not find `runtime` in `tokio`
  --> /Users/hwhost/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-modbus-0.5.0/src/client/sync/tcp.rs:16:30
   |
16 |     let rt = tokio::runtime::Builder::new_current_thread()
   |                              ^^^^^^^ not found in `tokio::runtime`
   |
help: consider importing one of these items
   |
1  | use std::thread::Builder;
   |
1  | use tokio_util::codec::length_delimited::Builder;
   |

For more information about this error, try `rustc --explain E0433`.
error: could not compile `tokio-modbus` due to 2 previous errors

Can you reproduce this error? It seems to happen only with the sync feature.

Release v0.4.0

ToDo's:

  • Resolve #32
  • Resolve #38
  • Resolve #49
  • merge server/tcp.rs and server/tcp_server.rs
  • Update CHANGELOG
  • Create a migration guide
  • Test TCP client with real hardware (ur20)
  • Publish on crates.io

Not fixed

  • fix cargo test --no-default-features --all - see #49 (comment)
  • Resolve #19 (moved to v0.4.1)
  • Test RTU client with real hardware (SMT100)

connect_slave reuse connections for different slaves ?

I am using

tokio_modbus::client::sync::tcp::connect_slave

Is it possible to connect to one ip / port once
and then read from different slaves with having to reconnect to each ?

Is this allow in modbus ? I am aware it would break the api so not suggesting it to be changed just curious if I could cache the connection maybe.

Thanks

Socket not flushed before write - perpetual error once a read timeouts

I'm using tokio::time::timeout on the Futures returned by e.g. client.read_holding_registers(), as real-world devices are not reliable and a retry is sometimes needed, also I don't want to block forever and freeze on one failing device.

When a device responds too late for a timeout, the response is queued in the TcpStream for reading.

Next time a read-write operation runs, it receives the OLD frame and errors out. Next time, it gets a newer old frame, ad infinitum.

Call ReadHoldingRegisters(0, 74)
Read error: Invalid response header: expected/request = Header { transaction_id: 67, unit_id: 12 }, actual/response = Header { transaction_id: 66, unit_id: 12 }
Retrying (retry 1/3)
Call ReadHoldingRegisters(0, 74)
Read error: Invalid response header: expected/request = Header { transaction_id: 68, unit_id: 12 }, actual/response = Header { transaction_id: 67, unit_id: 12 }
Retrying (retry 2/3)
Call ReadHoldingRegisters(0, 74)
Read error: Invalid response header: expected/request = Header { transaction_id: 69, unit_id: 12 }, actual/response = Header { transaction_id: 68, unit_id: 12 }
Retrying (retry 3/3)
Call ReadHoldingRegisters(0, 74)
Read error: Invalid response header: expected/request = Header { transaction_id: 70, unit_id: 12 }, actual/response = Header { transaction_id: 69, unit_id: 12 }
Retries exhausted!

I'm not sure where or how, but the socket needs to be flushed. I think a similar problem will be in the RTU client, but since it doesn't use transaction IDs, it might be harder to detect.

Nix OS support file outdated?

dev-env.nix seems to be outdated, e.g. the dependency on libudev should be obsolete. Please update or remove this file.

Poor recovery from malformed frames in RTU

We have a modbus slave which implements modbus in the usual vendor way, i.e., wrong: It does not send CRC with error frames.

Req: 0A 01 04 A1 00 01 AC 63
Resp: 0A 81 02 <no_crc>

To debug this, I copied the crate to a local folder and added trace logging to the RTU decoder.

Trace logs (long)
[2020-05-19T11:37:31.393Z TRACE tokio_util::codec::framed_read] attempting to decode a frame
[2020-05-19T11:37:31.393Z TRACE tokio_modbus::codec::rtu] ClientCodec::decode(b"\x01")
[2020-05-19T11:37:31.393Z TRACE tokio_modbus::codec::rtu] ResponseDecoder::decode(b"\x01")
[2020-05-19T11:37:31.393Z TRACE tokio_modbus::codec::rtu] --- decode b"\x01"
[2020-05-19T11:37:31.393Z TRACE tokio_modbus::codec::rtu] get_response_pdu_len b"\x01"
[2020-05-19T11:37:31.393Z TRACE tokio_modbus::codec::rtu] pdu len none
[2020-05-19T11:37:31.393Z TRACE tokio_modbus::codec::rtu] PDU len is None
[2020-05-19T11:37:31.393Z TRACE tokio_modbus::codec::rtu] no retry
[2020-05-19T11:37:31.393Z TRACE tokio_modbus::codec::rtu] decode resulted in -> None
[2020-05-19T11:37:31.393Z TRACE tokio_modbus::codec::rtu] frame is partial, ask for more bytes
[2020-05-19T11:37:31.393Z TRACE tokio_util::codec::framed_read] attempting to decode a frame
[2020-05-19T11:37:31.393Z TRACE tokio_modbus::codec::rtu] ClientCodec::decode(b"\x01\x83")
[2020-05-19T11:37:31.393Z TRACE tokio_modbus::codec::rtu] ResponseDecoder::decode(b"\x01\x83")
[2020-05-19T11:37:31.393Z TRACE tokio_modbus::codec::rtu] --- decode b"\x01\x83"
[2020-05-19T11:37:31.393Z TRACE tokio_modbus::codec::rtu] get_response_pdu_len b"\x01\x83"
[2020-05-19T11:37:31.393Z TRACE tokio_modbus::codec::rtu] len=Some(2)
[2020-05-19T11:37:31.393Z TRACE tokio_modbus::codec::rtu] PDU len is Some(2)
[2020-05-19T11:37:31.393Z TRACE tokio_modbus::codec::rtu] FrameDecoder::decode(b"\x01\x83", len 2)
[2020-05-19T11:37:31.394Z TRACE tokio_modbus::codec::rtu] Incomplete frame
[2020-05-19T11:37:31.394Z TRACE tokio_modbus::codec::rtu] no retry
[2020-05-19T11:37:31.394Z TRACE tokio_modbus::codec::rtu] decode resulted in -> None
[2020-05-19T11:37:31.394Z TRACE tokio_modbus::codec::rtu] frame is partial, ask for more bytes
[2020-05-19T11:37:31.395Z TRACE tokio_util::codec::framed_read] attempting to decode a frame
[2020-05-19T11:37:31.395Z TRACE tokio_modbus::codec::rtu] ClientCodec::decode(b"\x01\x83\x02")
[2020-05-19T11:37:31.395Z TRACE tokio_modbus::codec::rtu] ResponseDecoder::decode(b"\x01\x83\x02")
[2020-05-19T11:37:31.395Z TRACE tokio_modbus::codec::rtu] --- decode b"\x01\x83\x02"
[2020-05-19T11:37:31.395Z TRACE tokio_modbus::codec::rtu] get_response_pdu_len b"\x01\x83\x02"
[2020-05-19T11:37:31.395Z TRACE tokio_modbus::codec::rtu] len=Some(2)
[2020-05-19T11:37:31.395Z TRACE tokio_modbus::codec::rtu] PDU len is Some(2)
[2020-05-19T11:37:31.395Z TRACE tokio_modbus::codec::rtu] FrameDecoder::decode(b"\x01\x83\x02", len 2)
[2020-05-19T11:37:31.395Z TRACE tokio_modbus::codec::rtu] Incomplete frame
[2020-05-19T11:37:31.395Z TRACE tokio_modbus::codec::rtu] no retry
[2020-05-19T11:37:31.395Z TRACE tokio_modbus::codec::rtu] decode resulted in -> None
[2020-05-19T11:37:31.395Z TRACE tokio_modbus::codec::rtu] frame is partial, ask for more bytes
[2020-05-19T11:37:31.878Z ERROR fb_modbus::client] Read error: Timed out
[2020-05-19T11:37:31.878Z DEBUG fb_modbus::client] Retrying (retry 1/3)
[2020-05-19T11:37:32.878Z TRACE tokio_modbus::codec::rtu] encode RequestAdu { hdr: Header { slave_id: 1 }, pdu: RequestPdu(ReadHoldingRegisters(1, 3)), disconnect: false }
[2020-05-19T11:37:32.879Z TRACE tokio_modbus::codec::rtu] encoded as b"\x01\x03\0\x01\0\x03T\x0b"
[2020-05-19T11:37:32.879Z TRACE tokio_util::codec::framed_write] flushing framed transport
[2020-05-19T11:37:32.879Z TRACE tokio_util::codec::framed_write] writing; remaining=8
[2020-05-19T11:37:32.879Z TRACE tokio_util::codec::framed_write] framed transport flushed
[2020-05-19T11:37:32.895Z TRACE tokio_util::codec::framed_read] attempting to decode a frame
[2020-05-19T11:37:32.895Z TRACE tokio_modbus::codec::rtu] ClientCodec::decode(b"\x01\x83\x02\x01")
[2020-05-19T11:37:32.895Z TRACE tokio_modbus::codec::rtu] ResponseDecoder::decode(b"\x01\x83\x02\x01")
[2020-05-19T11:37:32.895Z TRACE tokio_modbus::codec::rtu] --- decode b"\x01\x83\x02\x01"
[2020-05-19T11:37:32.895Z TRACE tokio_modbus::codec::rtu] get_response_pdu_len b"\x01\x83\x02\x01"
[2020-05-19T11:37:32.895Z TRACE tokio_modbus::codec::rtu] len=Some(2)
[2020-05-19T11:37:32.895Z TRACE tokio_modbus::codec::rtu] PDU len is Some(2)
[2020-05-19T11:37:32.895Z TRACE tokio_modbus::codec::rtu] FrameDecoder::decode(b"\x01\x83\x02\x01", len 2)
[2020-05-19T11:37:32.896Z TRACE tokio_modbus::codec::rtu] Incomplete frame
[2020-05-19T11:37:32.896Z TRACE tokio_modbus::codec::rtu] no retry
[2020-05-19T11:37:32.896Z TRACE tokio_modbus::codec::rtu] decode resulted in -> None
[2020-05-19T11:37:32.896Z TRACE tokio_modbus::codec::rtu] frame is partial, ask for more bytes
[2020-05-19T11:37:32.896Z TRACE tokio_util::codec::framed_read] attempting to decode a frame
[2020-05-19T11:37:32.896Z TRACE tokio_modbus::codec::rtu] ClientCodec::decode(b"\x01\x83\x02\x01\x83")
[2020-05-19T11:37:32.896Z TRACE tokio_modbus::codec::rtu] ResponseDecoder::decode(b"\x01\x83\x02\x01\x83")
[2020-05-19T11:37:32.896Z TRACE tokio_modbus::codec::rtu] --- decode b"\x01\x83\x02\x01\x83"
[2020-05-19T11:37:32.896Z TRACE tokio_modbus::codec::rtu] get_response_pdu_len b"\x01\x83\x02\x01\x83"
[2020-05-19T11:37:32.896Z TRACE tokio_modbus::codec::rtu] len=Some(2)
[2020-05-19T11:37:32.896Z TRACE tokio_modbus::codec::rtu] PDU len is Some(2)
[2020-05-19T11:37:32.896Z TRACE tokio_modbus::codec::rtu] FrameDecoder::decode(b"\x01\x83\x02\x01\x83", len 2)
[2020-05-19T11:37:32.896Z TRACE tokio_modbus::codec::rtu] good length for a packet: b"\x01\x83\x02\x01\x83"
[2020-05-19T11:37:32.896Z TRACE tokio_modbus::codec::rtu] adu b"\x01\x83\x02"
[2020-05-19T11:37:32.896Z TRACE tokio_modbus::codec::rtu] crc b"\x01\x83"
[2020-05-19T11:37:32.896Z TRACE tokio_modbus::codec::rtu] crc error, adu [1, 131, 2], expected 0x183
[2020-05-19T11:37:32.896Z TRACE tokio_modbus::codec::rtu] err Custom { kind: InvalidData, error: "Invalid CRC: expected = 0x0183, actual = 0xC0F1" }, restore input buffer
[2020-05-19T11:37:32.896Z WARN  tokio_modbus::codec::rtu] Failed to decode response frame: Invalid CRC: expected = 0x0183, actual = 0xC0F1
[2020-05-19T11:37:32.897Z TRACE tokio_modbus::codec::rtu] recover_on_error
[2020-05-19T11:37:32.897Z DEBUG tokio_modbus::codec::rtu] Dropped first byte: 1
[2020-05-19T11:37:32.897Z TRACE tokio_modbus::codec::rtu] decoder loop retry
[2020-05-19T11:37:32.897Z TRACE tokio_modbus::codec::rtu] get_response_pdu_len b"\x83\x02\x01\x83"
[2020-05-19T11:37:32.897Z TRACE tokio_modbus::codec::rtu] len=Some(3)
[2020-05-19T11:37:32.897Z TRACE tokio_modbus::codec::rtu] PDU len is Some(3)
[2020-05-19T11:37:32.897Z TRACE tokio_modbus::codec::rtu] FrameDecoder::decode(b"\x83\x02\x01\x83", len 3)
[2020-05-19T11:37:32.897Z TRACE tokio_modbus::codec::rtu] Incomplete frame
[2020-05-19T11:37:32.897Z TRACE tokio_modbus::codec::rtu] no retry
[2020-05-19T11:37:32.897Z TRACE tokio_modbus::codec::rtu] decode resulted in -> None
[2020-05-19T11:37:32.897Z TRACE tokio_modbus::codec::rtu] frame is partial, ask for more bytes
[2020-05-19T11:37:32.897Z TRACE tokio_util::codec::framed_read] attempting to decode a frame
[2020-05-19T11:37:32.897Z TRACE tokio_modbus::codec::rtu] ClientCodec::decode(b"\x83\x02\x01\x83\x02")
[2020-05-19T11:37:32.897Z TRACE tokio_modbus::codec::rtu] ResponseDecoder::decode(b"\x83\x02\x01\x83\x02")
[2020-05-19T11:37:32.897Z TRACE tokio_modbus::codec::rtu] --- decode b"\x83\x02\x01\x83\x02"
[2020-05-19T11:37:32.897Z TRACE tokio_modbus::codec::rtu] get_response_pdu_len b"\x83\x02\x01\x83\x02"
[2020-05-19T11:37:32.897Z TRACE tokio_modbus::codec::rtu] len=Some(3)
[2020-05-19T11:37:32.897Z TRACE tokio_modbus::codec::rtu] PDU len is Some(3)
[2020-05-19T11:37:32.897Z TRACE tokio_modbus::codec::rtu] FrameDecoder::decode(b"\x83\x02\x01\x83\x02", len 3)
[2020-05-19T11:37:32.897Z TRACE tokio_modbus::codec::rtu] Incomplete frame
[2020-05-19T11:37:32.897Z TRACE tokio_modbus::codec::rtu] no retry
[2020-05-19T11:37:32.897Z TRACE tokio_modbus::codec::rtu] decode resulted in -> None
[2020-05-19T11:37:32.898Z TRACE tokio_modbus::codec::rtu] frame is partial, ask for more bytes
[2020-05-19T11:37:33.380Z ERROR fb_modbus::client] Read error: Timed out
[2020-05-19T11:37:33.380Z DEBUG fb_modbus::client] Retrying (retry 2/3)
[2020-05-19T11:37:34.381Z TRACE tokio_modbus::codec::rtu] encode RequestAdu { hdr: Header { slave_id: 1 }, pdu: RequestPdu(ReadHoldingRegisters(1, 3)), disconnect: false }
[2020-05-19T11:37:34.381Z TRACE tokio_modbus::codec::rtu] encoded as b"\x01\x03\0\x01\0\x03T\x0b"
[2020-05-19T11:37:34.381Z TRACE tokio_util::codec::framed_write] flushing framed transport
[2020-05-19T11:37:34.381Z TRACE tokio_util::codec::framed_write] writing; remaining=8
[2020-05-19T11:37:34.381Z TRACE tokio_util::codec::framed_write] framed transport flushed
[2020-05-19T11:37:34.398Z TRACE tokio_util::codec::framed_read] attempting to decode a frame
[2020-05-19T11:37:34.398Z TRACE tokio_modbus::codec::rtu] ClientCodec::decode(b"\x83\x02\x01\x83\x02\x01")
[2020-05-19T11:37:34.398Z TRACE tokio_modbus::codec::rtu] ResponseDecoder::decode(b"\x83\x02\x01\x83\x02\x01")
[2020-05-19T11:37:34.398Z TRACE tokio_modbus::codec::rtu] --- decode b"\x83\x02\x01\x83\x02\x01"
[2020-05-19T11:37:34.398Z TRACE tokio_modbus::codec::rtu] get_response_pdu_len b"\x83\x02\x01\x83\x02\x01"
[2020-05-19T11:37:34.398Z TRACE tokio_modbus::codec::rtu] len=Some(3)
[2020-05-19T11:37:34.398Z TRACE tokio_modbus::codec::rtu] PDU len is Some(3)
[2020-05-19T11:37:34.398Z TRACE tokio_modbus::codec::rtu] FrameDecoder::decode(b"\x83\x02\x01\x83\x02\x01", len 3)
[2020-05-19T11:37:34.398Z TRACE tokio_modbus::codec::rtu] good length for a packet: b"\x83\x02\x01\x83\x02\x01"
[2020-05-19T11:37:34.398Z TRACE tokio_modbus::codec::rtu] adu b"\x83\x02\x01\x83"
[2020-05-19T11:37:34.398Z TRACE tokio_modbus::codec::rtu] crc b"\x02\x01"
[2020-05-19T11:37:34.398Z TRACE tokio_modbus::codec::rtu] crc error, adu [131, 2, 1, 131], expected 0x201
[2020-05-19T11:37:34.398Z TRACE tokio_modbus::codec::rtu] err Custom { kind: InvalidData, error: "Invalid CRC: expected = 0x0201, actual = 0xC851" }, restore input buffer
[2020-05-19T11:37:34.398Z WARN  tokio_modbus::codec::rtu] Failed to decode response frame: Invalid CRC: expected = 0x0201, actual = 0xC851
[2020-05-19T11:37:34.398Z TRACE tokio_modbus::codec::rtu] recover_on_error
[2020-05-19T11:37:34.398Z DEBUG tokio_modbus::codec::rtu] Dropped first byte: 83
[2020-05-19T11:37:34.399Z TRACE tokio_modbus::codec::rtu] decoder loop retry
[2020-05-19T11:37:34.399Z TRACE tokio_modbus::codec::rtu] get_response_pdu_len b"\x02\x01\x83\x02\x01"
[2020-05-19T11:37:34.399Z TRACE tokio_modbus::codec::rtu] len=Some(133)
[2020-05-19T11:37:34.399Z TRACE tokio_modbus::codec::rtu] PDU len is Some(133)
[2020-05-19T11:37:34.399Z TRACE tokio_modbus::codec::rtu] FrameDecoder::decode(b"\x02\x01\x83\x02\x01", len 133)
[2020-05-19T11:37:34.399Z TRACE tokio_modbus::codec::rtu] Incomplete frame
[2020-05-19T11:37:34.399Z TRACE tokio_modbus::codec::rtu] no retry
[2020-05-19T11:37:34.399Z TRACE tokio_modbus::codec::rtu] decode resulted in -> None
[2020-05-19T11:37:34.399Z TRACE tokio_modbus::codec::rtu] frame is partial, ask for more bytes
[2020-05-19T11:37:34.399Z TRACE tokio_util::codec::framed_read] attempting to decode a frame
[2020-05-19T11:37:34.399Z TRACE tokio_modbus::codec::rtu] ClientCodec::decode(b"\x02\x01\x83\x02\x01\x83")
[2020-05-19T11:37:34.399Z TRACE tokio_modbus::codec::rtu] ResponseDecoder::decode(b"\x02\x01\x83\x02\x01\x83")
[2020-05-19T11:37:34.399Z TRACE tokio_modbus::codec::rtu] --- decode b"\x02\x01\x83\x02\x01\x83"
[2020-05-19T11:37:34.399Z TRACE tokio_modbus::codec::rtu] get_response_pdu_len b"\x02\x01\x83\x02\x01\x83"
[2020-05-19T11:37:34.399Z TRACE tokio_modbus::codec::rtu] len=Some(133)
[2020-05-19T11:37:34.399Z TRACE tokio_modbus::codec::rtu] PDU len is Some(133)
[2020-05-19T11:37:34.399Z TRACE tokio_modbus::codec::rtu] FrameDecoder::decode(b"\x02\x01\x83\x02\x01\x83", len 133)
[2020-05-19T11:37:34.399Z TRACE tokio_modbus::codec::rtu] Incomplete frame
[2020-05-19T11:37:34.400Z TRACE tokio_modbus::codec::rtu] no retry
[2020-05-19T11:37:34.400Z TRACE tokio_modbus::codec::rtu] decode resulted in -> None
[2020-05-19T11:37:34.400Z TRACE tokio_modbus::codec::rtu] frame is partial, ask for more bytes
[2020-05-19T11:37:34.400Z TRACE tokio_util::codec::framed_read] attempting to decode a frame
[2020-05-19T11:37:34.400Z TRACE tokio_modbus::codec::rtu] ClientCodec::decode(b"\x02\x01\x83\x02\x01\x83\x02")
[2020-05-19T11:37:34.400Z TRACE tokio_modbus::codec::rtu] ResponseDecoder::decode(b"\x02\x01\x83\x02\x01\x83\x02")
[2020-05-19T11:37:34.400Z TRACE tokio_modbus::codec::rtu] --- decode b"\x02\x01\x83\x02\x01\x83\x02"
[2020-05-19T11:37:34.400Z TRACE tokio_modbus::codec::rtu] get_response_pdu_len b"\x02\x01\x83\x02\x01\x83\x02"
[2020-05-19T11:37:34.400Z TRACE tokio_modbus::codec::rtu] len=Some(133)
[2020-05-19T11:37:34.400Z TRACE tokio_modbus::codec::rtu] PDU len is Some(133)
[2020-05-19T11:37:34.400Z TRACE tokio_modbus::codec::rtu] FrameDecoder::decode(b"\x02\x01\x83\x02\x01\x83\x02", len 133)
[2020-05-19T11:37:34.400Z TRACE tokio_modbus::codec::rtu] Incomplete frame
[2020-05-19T11:37:34.400Z TRACE tokio_modbus::codec::rtu] no retry
[2020-05-19T11:37:34.400Z TRACE tokio_modbus::codec::rtu] decode resulted in -> None
[2020-05-19T11:37:34.400Z TRACE tokio_modbus::codec::rtu] frame is partial, ask for more bytes
[2020-05-19T11:37:34.882Z ERROR fb_modbus::client] Read error: Timed out
[2020-05-19T11:37:34.882Z DEBUG fb_modbus::client] Retrying (retry 3/3)
[2020-05-19T11:37:35.882Z TRACE tokio_modbus::codec::rtu] encode RequestAdu { hdr: Header { slave_id: 1 }, pdu: RequestPdu(ReadHoldingRegisters(1, 3)), disconnect: false }
[2020-05-19T11:37:35.883Z TRACE tokio_modbus::codec::rtu] encoded as b"\x01\x03\0\x01\0\x03T\x0b"
[2020-05-19T11:37:35.883Z TRACE tokio_util::codec::framed_write] flushing framed transport
[2020-05-19T11:37:35.883Z TRACE tokio_util::codec::framed_write] writing; remaining=8
[2020-05-19T11:37:35.883Z TRACE tokio_util::codec::framed_write] framed transport flushed
[2020-05-19T11:37:35.900Z TRACE tokio_util::codec::framed_read] attempting to decode a frame
[2020-05-19T11:37:35.900Z TRACE tokio_modbus::codec::rtu] ClientCodec::decode(b"\x02\x01\x83\x02\x01\x83\x02\x01")
[2020-05-19T11:37:35.900Z TRACE tokio_modbus::codec::rtu] ResponseDecoder::decode(b"\x02\x01\x83\x02\x01\x83\x02\x01")
[2020-05-19T11:37:35.901Z TRACE tokio_modbus::codec::rtu] --- decode b"\x02\x01\x83\x02\x01\x83\x02\x01"
[2020-05-19T11:37:35.901Z TRACE tokio_modbus::codec::rtu] get_response_pdu_len b"\x02\x01\x83\x02\x01\x83\x02\x01"
[2020-05-19T11:37:35.901Z TRACE tokio_modbus::codec::rtu] len=Some(133)
[2020-05-19T11:37:35.901Z TRACE tokio_modbus::codec::rtu] PDU len is Some(133)
[2020-05-19T11:37:35.901Z TRACE tokio_modbus::codec::rtu] FrameDecoder::decode(b"\x02\x01\x83\x02\x01\x83\x02\x01", len 133)
[2020-05-19T11:37:35.901Z TRACE tokio_modbus::codec::rtu] Incomplete frame
[2020-05-19T11:37:35.901Z TRACE tokio_modbus::codec::rtu] no retry
[2020-05-19T11:37:35.901Z TRACE tokio_modbus::codec::rtu] decode resulted in -> None
[2020-05-19T11:37:35.901Z TRACE tokio_modbus::codec::rtu] frame is partial, ask for more bytes
[2020-05-19T11:37:35.901Z TRACE tokio_util::codec::framed_read] attempting to decode a frame
[2020-05-19T11:37:35.901Z TRACE tokio_modbus::codec::rtu] ClientCodec::decode(b"\x02\x01\x83\x02\x01\x83\x02\x01\x83")
[2020-05-19T11:37:35.901Z TRACE tokio_modbus::codec::rtu] ResponseDecoder::decode(b"\x02\x01\x83\x02\x01\x83\x02\x01\x83")
[2020-05-19T11:37:35.902Z TRACE tokio_modbus::codec::rtu] --- decode b"\x02\x01\x83\x02\x01\x83\x02\x01\x83"
[2020-05-19T11:37:35.902Z TRACE tokio_modbus::codec::rtu] get_response_pdu_len b"\x02\x01\x83\x02\x01\x83\x02\x01\x83"
[2020-05-19T11:37:35.902Z TRACE tokio_modbus::codec::rtu] len=Some(133)
[2020-05-19T11:37:35.902Z TRACE tokio_modbus::codec::rtu] PDU len is Some(133)
[2020-05-19T11:37:35.902Z TRACE tokio_modbus::codec::rtu] FrameDecoder::decode(b"\x02\x01\x83\x02\x01\x83\x02\x01\x83", len 133)
[2020-05-19T11:37:35.902Z TRACE tokio_modbus::codec::rtu] Incomplete frame
[2020-05-19T11:37:35.902Z TRACE tokio_modbus::codec::rtu] no retry
[2020-05-19T11:37:35.902Z TRACE tokio_modbus::codec::rtu] decode resulted in -> None
[2020-05-19T11:37:35.902Z TRACE tokio_modbus::codec::rtu] frame is partial, ask for more bytes
[2020-05-19T11:37:35.902Z TRACE tokio_util::codec::framed_read] attempting to decode a frame
[2020-05-19T11:37:35.902Z TRACE tokio_modbus::codec::rtu] ClientCodec::decode(b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02")
[2020-05-19T11:37:35.902Z TRACE tokio_modbus::codec::rtu] ResponseDecoder::decode(b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02")
[2020-05-19T11:37:35.903Z TRACE tokio_modbus::codec::rtu] --- decode b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02"
[2020-05-19T11:37:35.903Z TRACE tokio_modbus::codec::rtu] get_response_pdu_len b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02"
[2020-05-19T11:37:35.903Z TRACE tokio_modbus::codec::rtu] len=Some(133)
[2020-05-19T11:37:35.903Z TRACE tokio_modbus::codec::rtu] PDU len is Some(133)
[2020-05-19T11:37:35.903Z TRACE tokio_modbus::codec::rtu] FrameDecoder::decode(b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02", len 133)
[2020-05-19T11:37:35.903Z TRACE tokio_modbus::codec::rtu] Incomplete frame
[2020-05-19T11:37:35.903Z TRACE tokio_modbus::codec::rtu] no retry
[2020-05-19T11:37:35.903Z TRACE tokio_modbus::codec::rtu] decode resulted in -> None
[2020-05-19T11:37:35.903Z TRACE tokio_modbus::codec::rtu] frame is partial, ask for more bytes
[2020-05-19T11:37:36.385Z ERROR fb_modbus::client] Read error: Timed out
[2020-05-19T11:37:36.385Z WARN  fb_modbus::client] Retries exhausted!
[2020-05-19T11:37:36.385Z ERROR mod_inepro380max] Error reading amps mb ID 1: Timed out
[2020-05-19T11:37:36.886Z TRACE tokio_modbus::codec::rtu] encode RequestAdu { hdr: Header { slave_id: 1 }, pdu: RequestPdu(ReadHoldingRegisters(1, 3)), disconnect: false }
[2020-05-19T11:37:36.886Z TRACE tokio_modbus::codec::rtu] encoded as b"\x01\x03\0\x01\0\x03T\x0b"
[2020-05-19T11:37:36.886Z TRACE tokio_util::codec::framed_write] flushing framed transport
[2020-05-19T11:37:36.886Z TRACE tokio_util::codec::framed_write] writing; remaining=8
[2020-05-19T11:37:36.886Z TRACE tokio_util::codec::framed_write] framed transport flushed
[2020-05-19T11:37:36.902Z TRACE tokio_util::codec::framed_read] attempting to decode a frame
[2020-05-19T11:37:36.902Z TRACE tokio_modbus::codec::rtu] ClientCodec::decode(b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01")
[2020-05-19T11:37:36.902Z TRACE tokio_modbus::codec::rtu] ResponseDecoder::decode(b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01")
[2020-05-19T11:37:36.902Z TRACE tokio_modbus::codec::rtu] --- decode b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01"
[2020-05-19T11:37:36.902Z TRACE tokio_modbus::codec::rtu] get_response_pdu_len b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01"
[2020-05-19T11:37:36.902Z TRACE tokio_modbus::codec::rtu] len=Some(133)
[2020-05-19T11:37:36.902Z TRACE tokio_modbus::codec::rtu] PDU len is Some(133)
[2020-05-19T11:37:36.902Z TRACE tokio_modbus::codec::rtu] FrameDecoder::decode(b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01", len 133)
[2020-05-19T11:37:36.902Z TRACE tokio_modbus::codec::rtu] Incomplete frame
[2020-05-19T11:37:36.902Z TRACE tokio_modbus::codec::rtu] no retry
[2020-05-19T11:37:36.902Z TRACE tokio_modbus::codec::rtu] decode resulted in -> None
[2020-05-19T11:37:36.902Z TRACE tokio_modbus::codec::rtu] frame is partial, ask for more bytes
[2020-05-19T11:37:36.903Z TRACE tokio_util::codec::framed_read] attempting to decode a frame
[2020-05-19T11:37:36.903Z TRACE tokio_modbus::codec::rtu] ClientCodec::decode(b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83")
[2020-05-19T11:37:36.903Z TRACE tokio_modbus::codec::rtu] ResponseDecoder::decode(b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83")
[2020-05-19T11:37:36.903Z TRACE tokio_modbus::codec::rtu] --- decode b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83"
[2020-05-19T11:37:36.903Z TRACE tokio_modbus::codec::rtu] get_response_pdu_len b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83"
[2020-05-19T11:37:36.903Z TRACE tokio_modbus::codec::rtu] len=Some(133)
[2020-05-19T11:37:36.903Z TRACE tokio_modbus::codec::rtu] PDU len is Some(133)
[2020-05-19T11:37:36.903Z TRACE tokio_modbus::codec::rtu] FrameDecoder::decode(b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83", len 133)
[2020-05-19T11:37:36.903Z TRACE tokio_modbus::codec::rtu] Incomplete frame
[2020-05-19T11:37:36.903Z TRACE tokio_modbus::codec::rtu] no retry
[2020-05-19T11:37:36.903Z TRACE tokio_modbus::codec::rtu] decode resulted in -> None
[2020-05-19T11:37:36.903Z TRACE tokio_modbus::codec::rtu] frame is partial, ask for more bytes
[2020-05-19T11:37:36.904Z TRACE tokio_util::codec::framed_read] attempting to decode a frame
[2020-05-19T11:37:36.904Z TRACE tokio_modbus::codec::rtu] ClientCodec::decode(b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02")
[2020-05-19T11:37:36.904Z TRACE tokio_modbus::codec::rtu] ResponseDecoder::decode(b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02")
[2020-05-19T11:37:36.904Z TRACE tokio_modbus::codec::rtu] --- decode b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02"
[2020-05-19T11:37:36.904Z TRACE tokio_modbus::codec::rtu] get_response_pdu_len b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02"
[2020-05-19T11:37:36.904Z TRACE tokio_modbus::codec::rtu] len=Some(133)
[2020-05-19T11:37:36.904Z TRACE tokio_modbus::codec::rtu] PDU len is Some(133)
[2020-05-19T11:37:36.904Z TRACE tokio_modbus::codec::rtu] FrameDecoder::decode(b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02", len 133)
[2020-05-19T11:37:36.904Z TRACE tokio_modbus::codec::rtu] Incomplete frame
[2020-05-19T11:37:36.904Z TRACE tokio_modbus::codec::rtu] no retry
[2020-05-19T11:37:36.904Z TRACE tokio_modbus::codec::rtu] decode resulted in -> None
[2020-05-19T11:37:36.904Z TRACE tokio_modbus::codec::rtu] frame is partial, ask for more bytes
[2020-05-19T11:37:37.388Z ERROR fb_modbus::client] Read error: Timed out
[2020-05-19T11:37:37.388Z DEBUG fb_modbus::client] Retrying (retry 1/3)
[2020-05-19T11:37:38.388Z TRACE tokio_modbus::codec::rtu] encode RequestAdu { hdr: Header { slave_id: 1 }, pdu: RequestPdu(ReadHoldingRegisters(1, 3)), disconnect: false }
[2020-05-19T11:37:38.388Z TRACE tokio_modbus::codec::rtu] encoded as b"\x01\x03\0\x01\0\x03T\x0b"
[2020-05-19T11:37:38.389Z TRACE tokio_util::codec::framed_write] flushing framed transport
[2020-05-19T11:37:38.389Z TRACE tokio_util::codec::framed_write] writing; remaining=8
[2020-05-19T11:37:38.389Z TRACE tokio_util::codec::framed_write] framed transport flushed
[2020-05-19T11:37:38.405Z TRACE tokio_util::codec::framed_read] attempting to decode a frame
[2020-05-19T11:37:38.405Z TRACE tokio_modbus::codec::rtu] ClientCodec::decode(b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01")
[2020-05-19T11:37:38.405Z TRACE tokio_modbus::codec::rtu] ResponseDecoder::decode(b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01")
[2020-05-19T11:37:38.405Z TRACE tokio_modbus::codec::rtu] --- decode b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01"
[2020-05-19T11:37:38.405Z TRACE tokio_modbus::codec::rtu] get_response_pdu_len b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01"
[2020-05-19T11:37:38.405Z TRACE tokio_modbus::codec::rtu] len=Some(133)
[2020-05-19T11:37:38.405Z TRACE tokio_modbus::codec::rtu] PDU len is Some(133)
[2020-05-19T11:37:38.405Z TRACE tokio_modbus::codec::rtu] FrameDecoder::decode(b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01", len 133)
[2020-05-19T11:37:38.405Z TRACE tokio_modbus::codec::rtu] Incomplete frame
[2020-05-19T11:37:38.405Z TRACE tokio_modbus::codec::rtu] no retry
[2020-05-19T11:37:38.405Z TRACE tokio_modbus::codec::rtu] decode resulted in -> None
[2020-05-19T11:37:38.405Z TRACE tokio_modbus::codec::rtu] frame is partial, ask for more bytes
[2020-05-19T11:37:38.405Z TRACE tokio_util::codec::framed_read] attempting to decode a frame
[2020-05-19T11:37:38.406Z TRACE tokio_modbus::codec::rtu] ClientCodec::decode(b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83")
[2020-05-19T11:37:38.406Z TRACE tokio_modbus::codec::rtu] ResponseDecoder::decode(b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83")
[2020-05-19T11:37:38.406Z TRACE tokio_modbus::codec::rtu] --- decode b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83"
[2020-05-19T11:37:38.406Z TRACE tokio_modbus::codec::rtu] get_response_pdu_len b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83"
[2020-05-19T11:37:38.406Z TRACE tokio_modbus::codec::rtu] len=Some(133)
[2020-05-19T11:37:38.406Z TRACE tokio_modbus::codec::rtu] PDU len is Some(133)
[2020-05-19T11:37:38.406Z TRACE tokio_modbus::codec::rtu] FrameDecoder::decode(b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83", len 133)
[2020-05-19T11:37:38.406Z TRACE tokio_modbus::codec::rtu] Incomplete frame
[2020-05-19T11:37:38.406Z TRACE tokio_modbus::codec::rtu] no retry
[2020-05-19T11:37:38.406Z TRACE tokio_modbus::codec::rtu] decode resulted in -> None
[2020-05-19T11:37:38.406Z TRACE tokio_modbus::codec::rtu] frame is partial, ask for more bytes
[2020-05-19T11:37:38.406Z TRACE tokio_util::codec::framed_read] attempting to decode a frame
[2020-05-19T11:37:38.406Z TRACE tokio_modbus::codec::rtu] ClientCodec::decode(b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02")
[2020-05-19T11:37:38.406Z TRACE tokio_modbus::codec::rtu] ResponseDecoder::decode(b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02")
[2020-05-19T11:37:38.407Z TRACE tokio_modbus::codec::rtu] --- decode b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02"
[2020-05-19T11:37:38.407Z TRACE tokio_modbus::codec::rtu] get_response_pdu_len b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02"
[2020-05-19T11:37:38.407Z TRACE tokio_modbus::codec::rtu] len=Some(133)
[2020-05-19T11:37:38.407Z TRACE tokio_modbus::codec::rtu] PDU len is Some(133)
[2020-05-19T11:37:38.407Z TRACE tokio_modbus::codec::rtu] FrameDecoder::decode(b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02", len 133)
[2020-05-19T11:37:38.407Z TRACE tokio_modbus::codec::rtu] Incomplete frame
[2020-05-19T11:37:38.407Z TRACE tokio_modbus::codec::rtu] no retry
[2020-05-19T11:37:38.407Z TRACE tokio_modbus::codec::rtu] decode resulted in -> None
[2020-05-19T11:37:38.407Z TRACE tokio_modbus::codec::rtu] frame is partial, ask for more bytes
[2020-05-19T11:37:38.891Z ERROR fb_modbus::client] Read error: Timed out
[2020-05-19T11:37:38.891Z DEBUG fb_modbus::client] Retrying (retry 2/3)
[2020-05-19T11:37:39.891Z TRACE tokio_modbus::codec::rtu] encode RequestAdu { hdr: Header { slave_id: 1 }, pdu: RequestPdu(ReadHoldingRegisters(1, 3)), disconnect: false }
[2020-05-19T11:37:39.891Z TRACE tokio_modbus::codec::rtu] encoded as b"\x01\x03\0\x01\0\x03T\x0b"
[2020-05-19T11:37:39.891Z TRACE tokio_util::codec::framed_write] flushing framed transport
[2020-05-19T11:37:39.891Z TRACE tokio_util::codec::framed_write] writing; remaining=8
[2020-05-19T11:37:39.891Z TRACE tokio_util::codec::framed_write] framed transport flushed
[2020-05-19T11:37:39.907Z TRACE tokio_util::codec::framed_read] attempting to decode a frame
[2020-05-19T11:37:39.907Z TRACE tokio_modbus::codec::rtu] ClientCodec::decode(b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01")
[2020-05-19T11:37:39.907Z TRACE tokio_modbus::codec::rtu] ResponseDecoder::decode(b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01")
[2020-05-19T11:37:39.907Z TRACE tokio_modbus::codec::rtu] --- decode b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01"
[2020-05-19T11:37:39.907Z TRACE tokio_modbus::codec::rtu] get_response_pdu_len b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01"
[2020-05-19T11:37:39.907Z TRACE tokio_modbus::codec::rtu] len=Some(133)
[2020-05-19T11:37:39.907Z TRACE tokio_modbus::codec::rtu] PDU len is Some(133)
[2020-05-19T11:37:39.907Z TRACE tokio_modbus::codec::rtu] FrameDecoder::decode(b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01", len 133)
[2020-05-19T11:37:39.907Z TRACE tokio_modbus::codec::rtu] Incomplete frame
[2020-05-19T11:37:39.907Z TRACE tokio_modbus::codec::rtu] no retry
[2020-05-19T11:37:39.907Z TRACE tokio_modbus::codec::rtu] decode resulted in -> None
[2020-05-19T11:37:39.907Z TRACE tokio_modbus::codec::rtu] frame is partial, ask for more bytes
[2020-05-19T11:37:39.908Z TRACE tokio_util::codec::framed_read] attempting to decode a frame
[2020-05-19T11:37:39.908Z TRACE tokio_modbus::codec::rtu] ClientCodec::decode(b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83")
[2020-05-19T11:37:39.908Z TRACE tokio_modbus::codec::rtu] ResponseDecoder::decode(b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83")
[2020-05-19T11:37:39.908Z TRACE tokio_modbus::codec::rtu] --- decode b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83"
[2020-05-19T11:37:39.908Z TRACE tokio_modbus::codec::rtu] get_response_pdu_len b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83"
[2020-05-19T11:37:39.908Z TRACE tokio_modbus::codec::rtu] len=Some(133)
[2020-05-19T11:37:39.908Z TRACE tokio_modbus::codec::rtu] PDU len is Some(133)
[2020-05-19T11:37:39.908Z TRACE tokio_modbus::codec::rtu] FrameDecoder::decode(b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83", len 133)
[2020-05-19T11:37:39.908Z TRACE tokio_modbus::codec::rtu] Incomplete frame
[2020-05-19T11:37:39.908Z TRACE tokio_modbus::codec::rtu] no retry
[2020-05-19T11:37:39.908Z TRACE tokio_modbus::codec::rtu] decode resulted in -> None
[2020-05-19T11:37:39.908Z TRACE tokio_modbus::codec::rtu] frame is partial, ask for more bytes
[2020-05-19T11:37:39.908Z TRACE tokio_util::codec::framed_read] attempting to decode a frame
[2020-05-19T11:37:39.908Z TRACE tokio_modbus::codec::rtu] ClientCodec::decode(b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02")
[2020-05-19T11:37:39.908Z TRACE tokio_modbus::codec::rtu] ResponseDecoder::decode(b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02")
[2020-05-19T11:37:39.909Z TRACE tokio_modbus::codec::rtu] --- decode b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02"
[2020-05-19T11:37:39.909Z TRACE tokio_modbus::codec::rtu] get_response_pdu_len b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02"
[2020-05-19T11:37:39.909Z TRACE tokio_modbus::codec::rtu] len=Some(133)
[2020-05-19T11:37:39.909Z TRACE tokio_modbus::codec::rtu] PDU len is Some(133)
[2020-05-19T11:37:39.909Z TRACE tokio_modbus::codec::rtu] FrameDecoder::decode(b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02", len 133)
[2020-05-19T11:37:39.909Z TRACE tokio_modbus::codec::rtu] Incomplete frame
[2020-05-19T11:37:39.909Z TRACE tokio_modbus::codec::rtu] no retry
[2020-05-19T11:37:39.909Z TRACE tokio_modbus::codec::rtu] decode resulted in -> None
[2020-05-19T11:37:39.909Z TRACE tokio_modbus::codec::rtu] frame is partial, ask for more bytes
[2020-05-19T11:37:40.392Z ERROR fb_modbus::client] Read error: Timed out
[2020-05-19T11:37:40.393Z DEBUG fb_modbus::client] Retrying (retry 3/3)
[2020-05-19T11:37:41.393Z TRACE tokio_modbus::codec::rtu] encode RequestAdu { hdr: Header { slave_id: 1 }, pdu: RequestPdu(ReadHoldingRegisters(1, 3)), disconnect: false }
[2020-05-19T11:37:41.393Z TRACE tokio_modbus::codec::rtu] encoded as b"\x01\x03\0\x01\0\x03T\x0b"
[2020-05-19T11:37:41.393Z TRACE tokio_util::codec::framed_write] flushing framed transport
[2020-05-19T11:37:41.393Z TRACE tokio_util::codec::framed_write] writing; remaining=8
[2020-05-19T11:37:41.393Z TRACE tokio_util::codec::framed_write] framed transport flushed
[2020-05-19T11:37:41.409Z TRACE tokio_util::codec::framed_read] attempting to decode a frame
[2020-05-19T11:37:41.409Z TRACE tokio_modbus::codec::rtu] ClientCodec::decode(b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01")
[2020-05-19T11:37:41.410Z TRACE tokio_modbus::codec::rtu] ResponseDecoder::decode(b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01")
[2020-05-19T11:37:41.410Z TRACE tokio_modbus::codec::rtu] --- decode b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01"
[2020-05-19T11:37:41.410Z TRACE tokio_modbus::codec::rtu] get_response_pdu_len b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01"
[2020-05-19T11:37:41.410Z TRACE tokio_modbus::codec::rtu] len=Some(133)
[2020-05-19T11:37:41.410Z TRACE tokio_modbus::codec::rtu] PDU len is Some(133)
[2020-05-19T11:37:41.410Z TRACE tokio_modbus::codec::rtu] FrameDecoder::decode(b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01", len 133)
[2020-05-19T11:37:41.410Z TRACE tokio_modbus::codec::rtu] Incomplete frame
[2020-05-19T11:37:41.410Z TRACE tokio_modbus::codec::rtu] no retry
[2020-05-19T11:37:41.410Z TRACE tokio_modbus::codec::rtu] decode resulted in -> None
[2020-05-19T11:37:41.410Z TRACE tokio_modbus::codec::rtu] frame is partial, ask for more bytes
[2020-05-19T11:37:41.410Z TRACE tokio_util::codec::framed_read] attempting to decode a frame
[2020-05-19T11:37:41.410Z TRACE tokio_modbus::codec::rtu] ClientCodec::decode(b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83")
[2020-05-19T11:37:41.410Z TRACE tokio_modbus::codec::rtu] ResponseDecoder::decode(b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83")
[2020-05-19T11:37:41.411Z TRACE tokio_modbus::codec::rtu] --- decode b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83"
[2020-05-19T11:37:41.411Z TRACE tokio_modbus::codec::rtu] get_response_pdu_len b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83"
[2020-05-19T11:37:41.411Z TRACE tokio_modbus::codec::rtu] len=Some(133)
[2020-05-19T11:37:41.411Z TRACE tokio_modbus::codec::rtu] PDU len is Some(133)
[2020-05-19T11:37:41.411Z TRACE tokio_modbus::codec::rtu] FrameDecoder::decode(b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83", len 133)
[2020-05-19T11:37:41.411Z TRACE tokio_modbus::codec::rtu] Incomplete frame
[2020-05-19T11:37:41.411Z TRACE tokio_modbus::codec::rtu] no retry
[2020-05-19T11:37:41.411Z TRACE tokio_modbus::codec::rtu] decode resulted in -> None
[2020-05-19T11:37:41.411Z TRACE tokio_modbus::codec::rtu] frame is partial, ask for more bytes
[2020-05-19T11:37:41.411Z TRACE tokio_util::codec::framed_read] attempting to decode a frame
[2020-05-19T11:37:41.411Z TRACE tokio_modbus::codec::rtu] ClientCodec::decode(b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02")
[2020-05-19T11:37:41.411Z TRACE tokio_modbus::codec::rtu] ResponseDecoder::decode(b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02")
[2020-05-19T11:37:41.412Z TRACE tokio_modbus::codec::rtu] --- decode b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02"
[2020-05-19T11:37:41.412Z TRACE tokio_modbus::codec::rtu] get_response_pdu_len b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02"
[2020-05-19T11:37:41.412Z TRACE tokio_modbus::codec::rtu] len=Some(133)
[2020-05-19T11:37:41.412Z TRACE tokio_modbus::codec::rtu] PDU len is Some(133)
[2020-05-19T11:37:41.412Z TRACE tokio_modbus::codec::rtu] FrameDecoder::decode(b"\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02\x01\x83\x02", len 133)
(it continues..)

(without the trace logging, you really can't see anything, the parser continuously fails.)

Several things are going wrong:

  • The decoder receive buffer is NOT cleared before writing a command (very similar to bug #59)
  • The received invalid frame is NOT discarded on CRC mismatch, instead the byte dropping algorithm starts removing leading bytes. I can see how that can sometimes work, except:
  • At one point it thinks it needs 133 bytes, and from then just keeps collecting and growing the buffer
  • There are no decoder timeouts ... a real frame will never be sent over the span of several seconds or minutes.

All (possibly valid) responses received while the decoder is set on collecting the 133 bytes, will be lost. I'll admit I don't know how to fix it or work around the problem :/

How to use tokio-modbus with dynamic values ?

Hi all,

I'm kind of new to rust development, I trying to implement tokio-modbus to get asynchronous tcp server running alongside of random number generator.

And I'm in trouble to get a randomly generated Vec to dispatch through modbus holding registers.

I implemented this kind of code, but response is always the same and never been recomputed:

#[derive(Clone)]
pub struct MbServer{
    pub(crate) response: Response,
}

impl Service for MbServer {
    type Request = Request;
    type Response = Response;
    type Error = std::io::Error;
    type Future = future::Ready<Result<Self::Response, Self::Error>>;

    fn call(&self, req: Self::Request) -> Self::Future {
        println!("{:?}" , req);
        let res = self.response.clone();
        println!("{:?}", res);
        future::ready(Ok(self.response.clone()))
    }
}

#[tokio::main]
pub async fn main() -> Result<(), Box<dyn Error>> {

    let server = server::tcp::Server::new("0.0.0.0:502".parse().unwrap());

    let mb_server = MbServer{
        response: Response::ReadInputRegisters(get_datas())
    };

    server.serve(move ||Ok(mb_server.clone())).await.unwrap();

    Ok(())
}

fn get_datas() -> Vec<u16> {
    let mut rng = rand::thread_rng();
    let vals: Vec<u16> = (0..1).map(|_| rng.gen_range(0, 20)).collect();
    vals
}
$ ./modpoll -m tcp -c1 -t3 127.0.0.1
modpoll 3.10 - FieldTalk(tm) Modbus(R) Master Simulator
Copyright (c) 2002-2021 proconX Pty Ltd
Visit https://www.modbusdriver.com for Modbus libraries and tools.
Protocol configuration: MODBUS/TCP, FC4
Slave configuration...: address = 1, start reference = 1, count = 1
Communication.........: 127.0.0.1, port 502, t/o 1.00 s, poll rate 1000 ms
Data type.............: 16-bit register, input register table
-- Polling slave... (Ctrl-C to stop)
[1]: 12
-- Polling slave... (Ctrl-C to stop)
[1]: 12
-- Polling slave... (Ctrl-C to stop)
[1]: 12
-- Polling slave... (Ctrl-C to stop)
[1]: 12
-- Polling slave... (Ctrl-C to stop)

As you can see the response is always the same and seems the get_datas function was executed only once.

How can I provide dynamic response to the modbus response ?

Thank you for your help

rtu non-functional when used

main.rs

extern crate futures;
extern crate tokio_core;
extern crate tokio_modbus;
extern crate tokio_serial;
extern crate tokio_service;
use tokio_modbus::*;

pub fn main() {
    use tokio_core::reactor::Core;
    use futures::future::Future;
    use tokio_serial::{BaudRate, Serial, SerialPortSettings};

    let mut core = Core::new().unwrap();
    let handle = core.handle();
    let tty_path = "/dev/ttyUSB0";
    let server_addr = 0x01;

    let mut settings = SerialPortSettings::default();
    settings.baud_rate = BaudRate::Baud19200;
    let mut port = Serial::from_path(tty_path, &settings, &handle)
        .expect(&format!("Unable to open serial device '{}'", tty_path));
    port.set_exclusive(false)
        .expect("Unable to set serial port exlusive");

    let task = Client::connect_rtu(port, server_addr, &handle).and_then(|client| {
        println!("Reading a sensor value");
        client
            .read_holding_registers(0x082B, 2)
            .and_then(move |res| {
                println!("Sensor value is: {:?}", res);
                Ok(())
            })
    });

    core.run(task).unwrap();
}

Cargo.toml

[dependencies]
futures = "*"
tokio = "*"
tokio-core = "*"
tokio-serial = "*"
tokio-service = "*"
tokio-modbus = { version = "*", default-features = false, features = ["rtu"] }

Results

error[E0599]: no function or associated item named `connect_rtu` found for type `tokio_modbus::Client` in the current scope
  --> src/main.rs:25:16
   |
25 |     let task = Client::connect_rtu(port, server_addr, &handle).and_then(|client| {
   |                ^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

TCP_NODELAY

A small piece of the Modbus_Messaging_Implementation_Guide_V1_0b is listed below. I don't see anywhere in the code that is implemented. Should this be added? Is there some technical reason it is not?

TCP-NODELAY:
Small packets (called tinygrams) are normally not a problem on LANs, since most LANs
are not congested, but these tinygrams can lead to congestion on wide area networks.
A simple solution, called the "NAGLE algorithm", is to collect small amounts of data and
sends them in a single segment when TCP acknowledgments of previous packets
arrive.
In order to have better real-time behavior it is recommended to send small amounts of
data directly without trying to gather them in a single segment. That is why it is
recommended to force the TCP-NODELAY option that disables the "NAGLE algorithm"
on client and server connections.

Windows support

main.rs

extern crate futures;
extern crate tokio_core;
extern crate tokio_modbus;
extern crate tokio_serial;

use tokio_core::reactor::Core;
use futures::future::Future;
use tokio_serial::{Serial, SerialPortSettings};
use tokio_modbus::*;

pub fn main() {
    let mut core = Core::new().unwrap();
    let handle = core.handle();
    let port_path = "COM1";
    let server_addr = 0x01;

    let mut settings = SerialPortSettings::default();
    settings.baud_rate = 19200;
    let mut port = Serial::from_path(port_path, &settings, &handle).unwrap();
    port.set_exclusive(false).unwrap();

    let task = Client::connect_rtu(port, server_addr, &handle).and_then(|client| {
        println!("Reading a sensor value");
        client
            .read_holding_registers(0x082B, 2)
            .and_then(move |res| {
                println!("Sensor value is: {:?}", res);
                Ok(())
            })
    });

    core.run(task).unwrap();
}

Cargo.toml

[dependencies]  
futures = "*"  
tokio = "*"  
tokio-core = "*"
tokio-serial = "*"
tokio-service = "*"
tokio-modbus = { version = "*", default-features = false, features = ["rtu"] }

Results

C:/Users/test/.cargo/bin/cargo.exe run --package modbus_test --bin modbus_test
   Compiling tokio-modbus v0.2.1
error[E0432]: unresolved import `tokio_serial::Serial`
 --> C:\Users\test\.cargo\registry\src\github.com-1ecc6299db9ec823\tokio-modbus-0.2.1\src\service\rtu.rs:3:5
  |
3 | use tokio_serial::Serial;
  |     ^^^^^^^^^^^^^^^^^^^^ no `Serial` in the root

error[E0432]: unresolved imports `tokio_serial::Serial`, `tokio_serial::SerialPortSettings`
 --> C:\Users\test\.cargo\registry\src\github.com-1ecc6299db9ec823\tokio-modbus-0.2.1\src\client.rs:9:20
  |
9 | use tokio_serial::{Serial, SerialPortSettings};
  |                    ^^^^^^  ^^^^^^^^^^^^^^^^^^ no `SerialPortSettings` in the root
  |                    |
  |                    no `Serial` in the root

error[E0433]: failed to resolve. Could not find `tcp` in `proto`
  --> C:\Users\test\.cargo\registry\src\github.com-1ecc6299db9ec823\tokio-modbus-0.2.1\src\server.rs:75:39
   |
75 |                 TcpServer::new(proto::tcp::Proto, addr)
   |                                       ^^^ Could not find `tcp` in `proto`

error[E0277]: the size for values of type `dyn futures::Future<Item=frame::Response, Error=std::io::Error>` cannot be known at compilation time
  --> C:\Users\test\.cargo\registry\src\github.com-1ecc6299db9ec823\tokio-modbus-0.2.1\src\service\rtu.rs:52:9
   |
52 |         Box::new(result)
   |         ^^^^^^^^ doesn't have a size known at compile-time
   |
   = help: the trait `std::marker::Sized` is not implemented for `dyn futures::Future<Item=frame::Response, Error=std::io::Error>`
   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
   = note: required by `<std::boxed::Box<T>>::new`

error[E0277]: the size for values of type `dyn futures::Future<Item=frame::Response, Error=std::io::Error>` cannot be known at compilation time
  --> C:\Users\test\.cargo\registry\src\github.com-1ecc6299db9ec823\tokio-modbus-0.2.1\src\service\rtu.rs:40:13
   |
40 |         let result = self.service.call(req).and_then(move |resp| {
   |             ^^^^^^ doesn't have a size known at compile-time
   |
   = help: the trait `std::marker::Sized` is not implemented for `dyn futures::Future<Item=frame::Response, Error=std::io::Error>`
   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
   = note: all local variables must have a statically known size
   = help: unsized locals are gated as an unstable feature

error: aborting due to 5 previous errors

Some errors occurred: E0277, E0432, E0433.
For more information about an error, try `rustc --explain E0277`.
error: Could not compile `tokio-modbus`.

To learn more, run the command again with --verbose.

Process finished with exit code 101

Communicate with multiple RTU modbus addresses concurrently

Hi, the modbus rtu example demonstrates how to use set_slave to talk to different addresses in turn. I would like to be able to talk to two different addresses simultaneously - send a request to device 1, send a request to device 2, then collect the two responses (possibly out of order).
Since only one packet will be sent on the wire at a time this certainly seems like it should be possible to me.
However currently the first suspended future will hold onto the Rc's mutable borrow and the second one panics.
I tried also sharing the underlying serial with different SharedContexts but due to the 'static requirement that isn't great either - I don't think that a mutex would avoid the problem that Rc had.

Will I need to manually implement packet routing on the incoming modbus frames? Surely there's something like this for TCP already?

I'd appreciate any pointers for how to go about this. I'm currently just experimenting with the unreleased 0.4.0 on master.

Whats the purpose of the sync rtu client?

With the async rtu client under windows I had massive Permission denied issues (A separate issue follows).

Now I try to get the sync rtu part up and running and stumbled upon this one:

thread 'main' panicked at 'there is no reactor running, must be called from the context of Tokio runtime'

Here is my example

#[cfg(all(feature = "rtu", feature = "sync"))]
pub fn main() {
    use tokio_modbus::prelude::*;
    use tokio_serial::{Serial, SerialPortSettings};

    let tty_path = "/dev/ttyUSB0";
    let slave = Slave(247);
    let settings = SerialPortSettings::default();

    let mut ctx = sync::rtu::connect_slave(&tty_path, &settings, slave).unwrap();
    let buff = ctx.read_input_registers(0x1000, 7).unwrap();
    println!("Response is '{:?}'", buff);
}

#[cfg(not(all(feature = "rtu", feature = "sync")))]
pub fn main() {
    println!("features `rtu` and `sync` are required to run this example");
    std::process::exit(1);
}

Does the "sync" rtu part differ from the sync tcp one? The tcp example looks for me really sync without a runtime I mean.

Read/write timeout

When you run the example in Windows 10 and there is no response to reading the registers from the device, the program just hangs without returning an error. Is it possible to set a read/write timeout?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.