rustmod-client 0.1.0

High-level resilient Modbus client for rust-mod.
Documentation
# rust-mod

A modern Rust Modbus workspace for building automation and industrial integrations.

`rust-mod` is organized as a crate family:

- `rustmod-core`: `no_std`-compatible protocol codec layer (PDU + TCP/RTU framing)
- `rustmod-datalink`: async transport abstraction + TCP transport implementation
- `rustmod-client`: high-level resilient async client API
- `rustmod-tools`: CLI tools built on top of the client

## Current Status

Implemented and validated:

- Core Modbus function codes: FC01, FC02, FC03, FC04, FC05, FC06, FC15, FC16, FC22, FC23
- Custom function-code pass-through support for vendor extensions
- FC17 (`Report Server ID`) support via client API + simulator service
- FC43/MEI 0x0E (`Read Device Identification`) typed client API + simulator support
- Exception response decoding (including unknown exception codes)
- TCP MBAP framing and RTU CRC/frame codec in `rustmod-core`
- Async `DataLink::exchange` contract in `rustmod-datalink`
- Production-usable TCP transport (`ModbusTcpTransport`)
- Optional RTU serial transport (`ModbusRtuTransport`, `rtu` feature)
- Optional native RTU serial server (`ModbusRtuServer`, `rtu` feature)
- RTU-over-TCP server support (`ModbusRtuOverTcpServer`)
- In-memory simulator service and point-model helpers for virtual device hosting
- Simulator fixture integration tests for both client and datalink paths
- Correlated tracing hooks and feature-gated metrics counters
- Resilient client with timeout/retry/throttle controls
- Blocking sync TCP facade (`SyncModbusTcpClient`) for non-async applications
- Safe retry defaults (`RetryPolicy::ReadOnly`) to avoid duplicate writes after ambiguous failures
- CLI binaries:
  - `readholding`
  - `readinput`
  - `readcoils`
  - `writeholding`
  - `writecoil`
  - `scandevices`

## Workspace Validation

All of the following pass:

- `cargo check --workspace`
- `cargo test --workspace`
- `cargo check --workspace --all-features`
- `cargo test --workspace --all-features`
- `cargo clippy --workspace --all-features --all-targets -- -D warnings`
- `cargo check -p rustmod-core --no-default-features`
- `cargo test -p rustmod-core --no-default-features`
- `cargo clippy --workspace --all-targets -- -D warnings`

## Quick Start

Build everything:

```bash
cargo build --workspace
```

Read holding registers from a TCP device:

```bash
cargo run -p rustmod-tools --bin readholding -- \
  --host 127.0.0.1 --port 502 --unit-id 1 --start 107 --quantity 3
```

Write holding register(s):

```bash
# single register (FC06)
cargo run -p rustmod-tools --bin writeholding -- \
  --host 127.0.0.1 --port 502 --unit-id 1 --start 10 --values 42

# multiple registers (FC16)
cargo run -p rustmod-tools --bin writeholding -- \
  --host 127.0.0.1 --port 502 --unit-id 1 --start 10 --values 42,43,44
```

Scan unit IDs:

```bash
cargo run -p rustmod-tools --bin scandevices -- \
  --host 127.0.0.1 --port 502 --unit-start 1 --unit-end 20 --timeout 300
```

## Library Example

```rust
use rustmod_client::ModbusClient;
use rustmod_datalink::ModbusTcpTransport;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let link = ModbusTcpTransport::connect("127.0.0.1:502").await?;
    let client = ModbusClient::new(link);

    let regs = client.read_holding_registers(1, 0x006B, 3).await?;
    println!("registers: {regs:?}");
    Ok(())
}
```

## Notes

- `rustmod-core` is `no_std`-compatible with `std` + `alloc` enabled by default.
- `rustmod-datalink` supports TCP, optional RTU client transport, optional RTU serial server, and RTU-over-TCP server.
- The simulator components in `rustmod-datalink::sim` are designed for BACnet+Modbus app simulation workflows and virtual device hosting.
- Unknown Modbus exception codes are preserved as `ExceptionCode::Unknown(u8)`.
- `ModbusClient::custom_request` provides a compatibility path for vendor/private function codes.
- `ModbusClient::report_server_id` (FC17) is available for device identity/status polling.
- `ModbusClient::read_device_identification` supports typed FC43/MEI 0x0E reads.
- `ModbusClient` includes typed helpers for FC22 (`mask_write_register`) and FC23 (`read_write_multiple_registers`).
- `SyncModbusTcpClient` provides a blocking API over the same high-level operations.

## Parity Snapshot

Relative to `tokio-modbus` (0.17.x), `rust-mod` now has comparable support for:

- Async TCP client operations
- Blocking TCP client facade
- Optional async RTU client transport
- TCP server path suitable for simulator/virtual-device hosting
- Optional RTU serial server path
- RTU-over-TCP server path
- Custom function-code interoperability
- FC17 Report Server ID access
- FC22/FC23 typed operations
- Typed FC43/MEI 0x0E Read Device Identification client support

Still intentionally not at parity:
- Blocking sync RTU facade equivalent to `tokio-modbus` `rtu-sync`
- Typed wrappers for some less-common/public function families (can still be used via `custom_request`)