easy_modbus/
lib.rs

1//! A Rust Modbus library.
2//!
3//! # Examples
4//!
5//! A simple Modbus TCP Server:
6//!
7//! ```rust,no_run
8//! use std::error::Error;
9//!
10//! use futures::SinkExt;
11//! use tokio::net::{TcpListener, TcpStream};
12//! use tokio_stream::StreamExt;
13//! use tokio_util::codec::Framed;
14//!
15//! use easy_modbus::{Frame, codec::TcpServerCodec};
16//!
17//! #[tokio::main]
18//! async fn main() -> Result<(), Box<dyn Error>> {
19//!     let addr = "127.0.0.1:502".to_string();
20//!     let server = TcpListener::bind(&addr).await?;
21//!     println!("Listening on: {}", addr);
22//!
23//!     loop {
24//!         let (stream, _) = server.accept().await?;
25//!         tokio::spawn(async move {
26//!             if let Err(e) = process(stream).await {
27//!                 println!("failed to  process connection; error = {}", e);
28//!             }
29//!         });
30//!     }
31//! }
32//!
33//! async fn process(stream: TcpStream) -> Result<(), Box<dyn Error>> {
34//!     let mut transport = Framed::new(stream, TcpServerCodec);
35//!     let frame = Frame::tcp();
36//!     while let Some(request) = transport.next().await {
37//!         match request {
38//!             Ok(request) => {
39//!                 println!("load request --- {:?}", request);
40//!                 let response = frame.read_coils_response(0x01, vec![0x00, 0x01]);
41//!                 println!("send response --- {:?}", response);
42//!                 transport.send(response).await?;
43//!             }
44//!             Err(e) => return Err(e.into()),
45//!         }
46//!     }
47//!     Ok(())
48//! }
49//! ```
50//!
51//! A simple Modbus TCP Client:
52//!
53//! ``` rust,no_run
54//! use futures::{SinkExt, StreamExt};
55//! use tokio_serial::SerialStream;
56//! use tokio_util::codec::Framed;
57//!
58//! use easy_modbus::{Frame, Response};
59//! use easy_modbus::codec::RtuClientCodec;
60//!
61//! #[tokio::main(flavor = "current_thread")]
62//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
63//!     let tty_path = "COM4";
64//!     let rate = 9600;
65//!     let slave = 0x01;
66//!
67//!     let serial_builder = tokio_serial::new(tty_path, rate);
68//!     let port = SerialStream::open(&serial_builder).unwrap();
69//!
70//!     let mut transport = Framed::new(port, RtuClientCodec);
71//!
72//!     let frame = Frame::rtu();
73//!     let request = frame.read_multiple_holding_registers_request(slave, 0x00, 0x02);
74//!     println!("Request:\t{}", request);
75//!
76//!     transport.send(request).await?;
77//!     while let Some(response) = transport.next().await {
78//!         match response {
79//!             Ok(response) => {
80//!                 println!("Response:\t{}", response);
81//!                 match response {
82//!                     Response::ReadMultipleHoldingRegisters(_, res) => {
83//!                         let a = res.get_values();
84//!                         let h = ((a[0] as u16 * 256) + a[1] as u16) as f64 / 10.0;
85//!                         let t = ((a[2] as u16 * 256) + a[3] as u16) as f64 / 10.0;
86//!                         println!("h {} t {}", h, t);
87//!                         return Ok(())
88//!                     }
89//!                     _ => {
90//!                         println!("unknown")
91//!                     }
92//!                 }
93//!             }
94//!             Err(e) => {
95//!                 return Err(e.into());
96//!             }
97//!         }
98//!     }
99//!
100//!     Ok(())
101//! }
102//! ```
103//!
104//! A simple Modbus RTU Client:
105//!
106//! ``` rust,no_run
107//! use futures::{SinkExt, StreamExt};
108//! use tokio_serial::SerialStream;
109//! use tokio_util::codec::Framed;
110//!
111//! use easy_modbus::{Frame, Response};
112//! use easy_modbus::codec::RtuClientCodec;
113//!
114//! #[tokio::main(flavor = "current_thread")]
115//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
116//!     let tty_path = "COM4";
117//!     let rate = 9600;
118//!     let slave = 0x01;
119//!
120//!     let serial_builder = tokio_serial::new(tty_path, rate);
121//!     let port = SerialStream::open(&serial_builder).unwrap();
122//!
123//!     let mut transport = Framed::new(port, RtuClientCodec);
124//!
125//!     let frame = Frame::rtu();
126//!     let request = frame.read_multiple_holding_registers_request(slave, 0x00, 0x02);
127//!     println!("Request:\t{}", request);
128//!
129//!     transport.send(request).await?;
130//!     while let Some(response) = transport.next().await {
131//!         match response {
132//!             Ok(response) => {
133//!                 println!("Response:\t{}", response);
134//!                 match response {
135//!                     Response::ReadMultipleHoldingRegisters(_, res) => {
136//!                         let a = res.get_values();
137//!                         let h = ((a[0] as u16 * 256) + a[1] as u16) as f64 / 10.0;
138//!                         let t = ((a[2] as u16 * 256) + a[3] as u16) as f64 / 10.0;
139//!                         println!("h {} t {}", h, t);
140//!                         return Ok(())
141//!                     }
142//!                     _ => {
143//!                         println!("unknown")
144//!                     }
145//!                 }
146//!             }
147//!             Err(e) => {
148//!                 return Err(e.into());
149//!             }
150//!         }
151//!     }
152//!
153//!     Ok(())
154//! }
155//! ```
156extern crate core;
157
158pub use frame::Frame;
159pub use frame::Function;
160pub use frame::Exception;
161pub use frame::request::*;
162pub use frame::response::Response;
163
164pub mod codec;
165pub mod util;
166
167mod frame;
168