1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
//! A library for controlling the R413D08 8-channel relay module via Modbus.
//!
//! This crate provides two main ways to interact with the R413D08 relay module:
//!
//! 1. **High-Level, Safe Clients**: Stateful, thread-safe clients that are easy
//! to share and use in concurrent applications. This is the recommended
//! approach for most users. See [`tokio_sync_safe_client::SafeClient`] (blocking)
//! and [`tokio_async_safe_client::SafeClient`] (`async`).
//!
//! 2. **Low-Level, Stateless Functions**: A set of stateless functions that
//! directly map to the device's Modbus commands. This API offers maximum
//! flexibility but requires manual management of the Modbus context. See
//! the [`tokio_sync`] and [`tokio_async`] modules.
//!
//! ## Features
//!
//! - **Protocol Implementation**: Complete implementation of the R413D08 Modbus protocol.
//! - **Stateful, Thread-Safe Clients**: For easy and safe concurrent use.
//! - **Stateless, Low-Level Functions**: For maximum flexibility and control.
//! - **Synchronous and Asynchronous APIs**: Both blocking and `async/await` APIs are available.
//! - **Strongly-Typed API**: Utilizes Rust's type system for protocol correctness
//! (e.g., `Port`, `Address`, `PortState`).
//!
//! ## Quick Start
//!
//! This example shows how to use the recommended high-level, synchronous `SafeClient`.
//!
//! ```no_run
//! use r413d08_lib::{
//! protocol::{Address, Port},
//! tokio_sync_safe_client::SafeClient,
//! };
//! use tokio_modbus::client::sync::tcp;
//! use tokio_modbus::Slave;
//!
//! fn main() -> Result<(), Box<dyn std::error::Error>> {
//! // Connect to the device and create a stateful, safe client
//! let socket_addr = "192.168.1.100:502".parse()?;
//! let ctx = tcp::connect_slave(socket_addr, Slave(*Address::default()))?;
//! let client = SafeClient::new(ctx);
//!
//! // Use the client to interact with the device
//! client.set_port_open(Port::try_from(0)?)?;
//! let status = client.read_ports()?;
//!
//! println!("Successfully turned on relay 0. Current status: {}", status);
//!
//! Ok(())
//! }
//! ```
//!
//! For more details, see the documentation for the specific client you wish to use.