Skip to main content

ModbusClient

Trait ModbusClient 

Source
pub trait ModbusClient: Send + Sync {
    // Required method
    fn call<'life0, 'life1, 'async_trait>(
        &'life0 self,
        slave: u8,
        request: Request<'life1>,
    ) -> Pin<Box<dyn Future<Output = Result<Response, ModbusError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;

    // Provided methods
    fn read_coils<'life0, 'async_trait>(
        &'life0 self,
        slave: u8,
        addr: u16,
        quantity: u16,
    ) -> Pin<Box<dyn Future<Output = Result<Vec<bool>, ModbusError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait { ... }
    fn read_discrete_inputs<'life0, 'async_trait>(
        &'life0 self,
        slave: u8,
        addr: u16,
        quantity: u16,
    ) -> Pin<Box<dyn Future<Output = Result<Vec<bool>, ModbusError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait { ... }
    fn read_holding_registers<'life0, 'async_trait>(
        &'life0 self,
        slave: u8,
        addr: u16,
        quantity: u16,
    ) -> Pin<Box<dyn Future<Output = Result<Vec<u16>, ModbusError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait { ... }
    fn read_input_registers<'life0, 'async_trait>(
        &'life0 self,
        slave: u8,
        addr: u16,
        quantity: u16,
    ) -> Pin<Box<dyn Future<Output = Result<Vec<u16>, ModbusError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait { ... }
    fn write_single_coil<'life0, 'async_trait>(
        &'life0 self,
        slave: u8,
        addr: u16,
        value: bool,
    ) -> Pin<Box<dyn Future<Output = Result<(), ModbusError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait { ... }
    fn write_single_register<'life0, 'async_trait>(
        &'life0 self,
        slave: u8,
        addr: u16,
        value: u16,
    ) -> Pin<Box<dyn Future<Output = Result<(), ModbusError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait { ... }
    fn write_multiple_coils<'life0, 'life1, 'async_trait>(
        &'life0 self,
        slave: u8,
        addr: u16,
        values: &'life1 [bool],
    ) -> Pin<Box<dyn Future<Output = Result<(), ModbusError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait { ... }
    fn write_multiple_registers<'life0, 'life1, 'async_trait>(
        &'life0 self,
        slave: u8,
        addr: u16,
        values: &'life1 [u16],
    ) -> Pin<Box<dyn Future<Output = Result<(), ModbusError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait { ... }
    fn mask_write_register<'life0, 'async_trait>(
        &'life0 self,
        slave: u8,
        addr: u16,
        and_mask: u16,
        or_mask: u16,
    ) -> Pin<Box<dyn Future<Output = Result<(), ModbusError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait { ... }
    fn diagnostic<'life0, 'async_trait>(
        &'life0 self,
        slave: u8,
        sub_function: u16,
        data: u16,
    ) -> Pin<Box<dyn Future<Output = Result<(u16, u16), ModbusError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait { ... }
    fn read_write_multiple_registers<'life0, 'life1, 'async_trait>(
        &'life0 self,
        slave: u8,
        read_addr: u16,
        read_qty: u16,
        write_addr: u16,
        values: &'life1 [u16],
    ) -> Pin<Box<dyn Future<Output = Result<Vec<u16>, ModbusError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait { ... }
}
Expand description

Transport-independent Modbus client interface.

Each transport implements call — the only required method. All specific methods (read_coils, write_single_register, etc.) have default implementations that delegate to call.

slave is a per-request parameter — a single client instance handles the whole RS-485 bus, addressing different slaves on each call.

§Examples

use oms_modbus::*;
use std::time::Duration;

// TCP
let client = tcp::TcpClient::connect_with_timeout(
    "192.168.1.10:502".parse()?, Duration::from_secs(3),
).await?;

// RTU serial
let client = rtu::RtuClient::with_timeout(port, Duration::from_secs(3));

// All function codes work the same way
let regs = client.read_holding_registers(1, 0, 5).await?;
client.write_single_register(1, 0, 42).await?;

// Share via Arc
let shared: std::sync::Arc<dyn ModbusClient> = std::sync::Arc::new(client);

Required Methods§

Source

fn call<'life0, 'life1, 'async_trait>( &'life0 self, slave: u8, request: Request<'life1>, ) -> Pin<Box<dyn Future<Output = Result<Response, ModbusError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Send a raw Modbus request to the given slave and return the response. Transports must implement this; all other methods delegate to it.

Provided Methods§

Source

fn read_coils<'life0, 'async_trait>( &'life0 self, slave: u8, addr: u16, quantity: u16, ) -> Pin<Box<dyn Future<Output = Result<Vec<bool>, ModbusError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Read coils (FC01) — returns the ON/OFF status of discrete outputs.

Source

fn read_discrete_inputs<'life0, 'async_trait>( &'life0 self, slave: u8, addr: u16, quantity: u16, ) -> Pin<Box<dyn Future<Output = Result<Vec<bool>, ModbusError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Read discrete inputs (FC02) — returns the ON/OFF status of digital inputs.

Source

fn read_holding_registers<'life0, 'async_trait>( &'life0 self, slave: u8, addr: u16, quantity: u16, ) -> Pin<Box<dyn Future<Output = Result<Vec<u16>, ModbusError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Read holding registers (FC03) — returns the contents of read/write registers.

Source

fn read_input_registers<'life0, 'async_trait>( &'life0 self, slave: u8, addr: u16, quantity: u16, ) -> Pin<Box<dyn Future<Output = Result<Vec<u16>, ModbusError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Read input registers (FC04) — returns the contents of read-only registers.

Source

fn write_single_coil<'life0, 'async_trait>( &'life0 self, slave: u8, addr: u16, value: bool, ) -> Pin<Box<dyn Future<Output = Result<(), ModbusError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Write a single coil (FC05) — set a discrete output ON (true) or OFF (false).

Source

fn write_single_register<'life0, 'async_trait>( &'life0 self, slave: u8, addr: u16, value: u16, ) -> Pin<Box<dyn Future<Output = Result<(), ModbusError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Write a single holding register (FC06).

Source

fn write_multiple_coils<'life0, 'life1, 'async_trait>( &'life0 self, slave: u8, addr: u16, values: &'life1 [bool], ) -> Pin<Box<dyn Future<Output = Result<(), ModbusError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Write multiple coils (FC15).

Source

fn write_multiple_registers<'life0, 'life1, 'async_trait>( &'life0 self, slave: u8, addr: u16, values: &'life1 [u16], ) -> Pin<Box<dyn Future<Output = Result<(), ModbusError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Write multiple holding registers (FC16).

Source

fn mask_write_register<'life0, 'async_trait>( &'life0 self, slave: u8, addr: u16, and_mask: u16, or_mask: u16, ) -> Pin<Box<dyn Future<Output = Result<(), ModbusError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Write a single register using a mask (FC 22).

Source

fn diagnostic<'life0, 'async_trait>( &'life0 self, slave: u8, sub_function: u16, data: u16, ) -> Pin<Box<dyn Future<Output = Result<(u16, u16), ModbusError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Send a Diagnostic request (FC 08).

Source

fn read_write_multiple_registers<'life0, 'life1, 'async_trait>( &'life0 self, slave: u8, read_addr: u16, read_qty: u16, write_addr: u16, values: &'life1 [u16], ) -> Pin<Box<dyn Future<Output = Result<Vec<u16>, ModbusError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Read and write multiple registers in a single transaction (FC 23).

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§

Source§

impl ModbusClient for TcpClient

Source§

impl<T> ModbusClient for AsciiClient<T>
where T: AsyncRead + AsyncWrite + Send + Unpin + 'static,

Source§

impl<T> ModbusClient for RtuClient<T>
where T: AsyncRead + AsyncWrite + Send + Unpin + 'static,