Skip to main content

AsyncSerialClient

Struct AsyncSerialClient 

Source
pub struct AsyncSerialClient<const ASCII: bool = false> { /* private fields */ }
Expand description

Async Modbus serial client facade.

Supports both RTU and ASCII framing. All Modbus request methods (read_holding_registers, write_single_coil, etc.) are available directly on this type via Deref to AsyncClientCore.

Implementations§

Source§

impl<const ASCII: bool> AsyncSerialClient<ASCII>

Source

pub fn connect_with_transport<T>( transport: T, config: ModbusConfig, poll_interval: Duration, ) -> Result<AsyncSerialClient<ASCII>, AsyncError>
where T: AsyncTransport + Send + 'static,

👎Deprecated:

use AsyncSerialClient::new_with_transport(…) and then client.connect().await

Deprecated constructor alias.

Source

pub fn new_with_transport<T>( transport: T, config: ModbusConfig, _poll_interval: Duration, ) -> Result<AsyncSerialClient<ASCII>, AsyncError>
where T: AsyncTransport + Send + 'static,

Creates an async serial client from a caller-provided transport without connecting.

This is the escape hatch for custom serial drivers and integration tests that inject a mock transport. The config must be ModbusConfig::Serial(_) or the call returns AsyncError::Mbus(MbusError::InvalidTransport). Call AsyncClientCore::connect on the returned client before sending requests.

Methods from Deref<Target = AsyncClientCore>§

Source

pub async fn connect(&self) -> Result<(), AsyncError>

Establishes the underlying transport connection.

Must be called once before issuing Modbus requests. Can be called again after a disconnect to reconnect.

Source

pub async fn disconnect(&self) -> Result<(), AsyncError>

Disconnects the underlying transport.

Drains all in-flight and queued requests with MbusError::ConnectionClosed and closes the transport. After this call, connect can be called to reconnect.

This is an explicit, graceful disconnect. The background task continues running so the client can be reconnected later. Dropping the client handle entirely also stops the background task.

Source

pub fn has_pending_requests(&self) -> bool

Returns true when there are requests in-flight awaiting a response.

This is a synchronous check — no .await required.

Source

pub fn set_request_timeout(&self, timeout: Duration)

Sets a per-request deadline applied to every subsequent request call.

If a response is not received within timeout, the method returns AsyncError::Timeout. The in-flight entry remains in the background task until the transport delivers or errors; calling connect resets transport state.

The timeout can be updated at any time and takes effect on the next request. Call clear_request_timeout to remove it.

Source

pub fn clear_request_timeout(&self)

Removes the per-request timeout set by set_request_timeout, allowing requests to wait indefinitely for a server response.

Source

pub async fn read_multiple_coils( &self, unit_id: u8, address: u16, quantity: u16, ) -> Result<Coils, AsyncError>

Reads multiple coils (FC 01) from address with the given quantity.

Returns the coil values packed into a Coils object.

Source

pub async fn write_single_coil( &self, unit_id: u8, address: u16, value: bool, ) -> Result<(u16, bool), AsyncError>

Writes a single coil (FC 05) at address with the given boolean value.

Returns (address, value) echoed back by the server.

Source

pub async fn write_multiple_coils( &self, unit_id: u8, address: u16, coils: &Coils, ) -> Result<(u16, u16), AsyncError>

Writes multiple coils (FC 15) starting at address.

Returns (starting_address, quantity) echoed back by the server.

Source

pub async fn read_holding_registers( &self, unit_id: u8, address: u16, quantity: u16, ) -> Result<Registers<mbus_core::::models::register::model::HoldingRegisters::{constant#0}>, AsyncError>

Reads holding registers (FC 03) from address with the given quantity.

Returns the register values as a HoldingRegisters object.

Source

pub async fn read_input_registers( &self, unit_id: u8, address: u16, quantity: u16, ) -> Result<Registers<mbus_core::::models::register::model::InputRegisters::{constant#0}, Input>, AsyncError>

Reads input registers (FC 04) from address with the given quantity.

Returns the register values as an InputRegisters object.

Source

pub async fn write_single_register( &self, unit_id: u8, address: u16, value: u16, ) -> Result<(u16, u16), AsyncError>

Writes a single holding register (FC 06) at address with value.

Returns (address, value) echoed back by the server.

Source

pub async fn write_multiple_registers( &self, unit_id: u8, address: u16, values: &[u16], ) -> Result<(u16, u16), AsyncError>

Writes multiple holding registers (FC 16) starting at address.

Returns (starting_address, quantity) echoed back by the server.

Source

pub async fn read_write_multiple_registers( &self, unit_id: u8, read_address: u16, read_quantity: u16, write_address: u16, write_values: &[u16], ) -> Result<Registers<mbus_core::::models::register::model::HoldingRegisters::{constant#0}>, AsyncError>

Performs a combined read/write on holding registers (FC 23).

Reads read_quantity registers starting at read_address and simultaneously writes write_values starting at write_address. Returns the read registers.

Source

pub async fn mask_write_register( &self, unit_id: u8, address: u16, and_mask: u16, or_mask: u16, ) -> Result<(), AsyncError>

Applies an AND/OR bitmask to a holding register (FC 22).

The resulting register value is (current & and_mask) | (or_mask & !and_mask).

Source

pub async fn read_discrete_inputs( &self, unit_id: u8, address: u16, quantity: u16, ) -> Result<DiscreteInputs, AsyncError>

Reads discrete inputs (FC 02) from address with the given quantity.

Returns the input states as a DiscreteInputs object.

Source

pub async fn read_fifo_queue( &self, unit_id: u8, address: u16, ) -> Result<FifoQueue, AsyncError>

Reads the FIFO queue (FC 24) at address.

Returns up to 31 words from the FIFO queue as a FifoQueue object.

Source

pub async fn read_file_record( &self, unit_id: u8, sub_request: &SubRequest, ) -> Result<Vec<SubRequestParams>, AsyncError>

Reads a file record (FC 20) described by sub_request.

Returns the sub-request response parameters for each requested record.

Source

pub async fn write_file_record( &self, unit_id: u8, sub_request: &SubRequest, ) -> Result<(), AsyncError>

Writes a file record (FC 21) described by sub_request.

Source

pub async fn read_device_identification( &self, unit_id: u8, read_device_id_code: ReadDeviceIdCode, object_id: ObjectId, ) -> Result<DeviceIdentificationResponse, AsyncError>

Reads device identification objects (FC 43 / MEI 14).

Source

pub async fn encapsulated_interface_transport( &self, unit_id: u8, mei_type: EncapsulatedInterfaceType, data: &[u8], ) -> Result<(EncapsulatedInterfaceType, Vec<u8>), AsyncError>

Sends an encapsulated interface transport request (FC 43).

Returns the (mei_type, data) pair from the server response.

Source

pub async fn read_exception_status(&self, unit_id: u8) -> Result<u8, AsyncError>

Reads the device exception status (FC 07).

Source

pub async fn diagnostics( &self, unit_id: u8, sub_function: DiagnosticSubFunction, data: &[u16], ) -> Result<DiagnosticsDataResponse, AsyncError>

Sends a diagnostics request (FC 08).

Returns DiagnosticsDataResponse with echoed sub_function and data.

Source

pub async fn get_comm_event_counter( &self, unit_id: u8, ) -> Result<(u16, u16), AsyncError>

Reads the communication event counter (FC 11).

Returns (status_word, event_count).

Source

pub async fn get_comm_event_log( &self, unit_id: u8, ) -> Result<(u16, u16, u16, Vec<u8>), AsyncError>

Reads the communication event log (FC 12).

Returns (status, event_count, message_count, events).

Source

pub async fn report_server_id(&self, unit_id: u8) -> Result<Vec<u8>, AsyncError>

Requests the server identifier data (FC 17).

Returns the raw server ID byte array.

Trait Implementations§

Source§

impl<const ASCII: bool> Deref for AsyncSerialClient<ASCII>

Source§

type Target = AsyncClientCore

The resulting type after dereferencing.
Source§

fn deref(&self) -> &<AsyncSerialClient<ASCII> as Deref>::Target

Dereferences the value.

Auto Trait Implementations§

§

impl<const ASCII: bool> Freeze for AsyncSerialClient<ASCII>

§

impl<const ASCII: bool> RefUnwindSafe for AsyncSerialClient<ASCII>

§

impl<const ASCII: bool> Send for AsyncSerialClient<ASCII>

§

impl<const ASCII: bool> Sync for AsyncSerialClient<ASCII>

§

impl<const ASCII: bool> Unpin for AsyncSerialClient<ASCII>

§

impl<const ASCII: bool> UnsafeUnpin for AsyncSerialClient<ASCII>

§

impl<const ASCII: bool> UnwindSafe for AsyncSerialClient<ASCII>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.