mbus_async/runtime/
serial_client.rs1use std::ops::Deref;
14use super::*;
15
16pub struct AsyncSerialClient {
22 core: AsyncClientCore,
23}
24
25impl Deref for AsyncSerialClient {
26 type Target = AsyncClientCore;
27
28 fn deref(&self) -> &Self::Target {
29 &self.core
30 }
31}
32
33impl AsyncSerialClient {
36 #[cfg(feature = "serial-rtu")]
41 pub fn connect_rtu(serial_config: ModbusSerialConfig) -> Result<Self, AsyncError> {
42 if serial_config.mode != SerialMode::Rtu {
43 return Err(AsyncError::Mbus(MbusError::InvalidConfiguration));
44 }
45
46 let transport = StdSerialTransport::new(SerialMode::Rtu);
47 let config = ModbusConfig::Serial(serial_config);
48 Self::from_transport_config(transport, config, Duration::from_millis(20))
49 }
50
51 #[cfg(feature = "serial-rtu")]
55 pub fn connect_rtu_with_poll_interval(
56 serial_config: ModbusSerialConfig,
57 poll_interval: Duration,
58 ) -> Result<Self, AsyncError> {
59 if serial_config.mode != SerialMode::Rtu {
60 return Err(AsyncError::Mbus(MbusError::InvalidConfiguration));
61 }
62
63 let transport = StdSerialTransport::new(SerialMode::Rtu);
64 let config = ModbusConfig::Serial(serial_config);
65 Self::from_transport_config(transport, config, poll_interval)
66 }
67
68 #[cfg(feature = "serial-ascii")]
73 pub fn connect_ascii(serial_config: ModbusSerialConfig) -> Result<Self, AsyncError> {
74 if serial_config.mode != SerialMode::Ascii {
75 return Err(AsyncError::Mbus(MbusError::InvalidConfiguration));
76 }
77
78 let transport = StdSerialTransport::new(SerialMode::Ascii);
79 let config = ModbusConfig::Serial(serial_config);
80 Self::from_transport_config(transport, config, Duration::from_millis(20))
81 }
82
83 #[cfg(feature = "serial-ascii")]
87 pub fn connect_ascii_with_poll_interval(
88 serial_config: ModbusSerialConfig,
89 poll_interval: Duration,
90 ) -> Result<Self, AsyncError> {
91 if serial_config.mode != SerialMode::Ascii {
92 return Err(AsyncError::Mbus(MbusError::InvalidConfiguration));
93 }
94
95 let transport = StdSerialTransport::new(SerialMode::Ascii);
96 let config = ModbusConfig::Serial(serial_config);
97 Self::from_transport_config(transport, config, poll_interval)
98 }
99
100 pub fn connect_with_transport<TRANSPORT>(
107 transport: TRANSPORT,
108 config: ModbusConfig,
109 poll_interval: Duration,
110 ) -> Result<Self, AsyncError>
111 where
112 TRANSPORT: Transport + Send + 'static,
113 {
114 if !matches!(config, ModbusConfig::Serial(_)) {
115 return Err(AsyncError::Mbus(MbusError::InvalidTransport));
116 }
117
118 let pending = Arc::new(Mutex::new(HashMap::new()));
119 let app = AsyncApp {
120 pending: pending.clone(),
121 };
122
123 let client = ClientServices::<_, _, 1>::new(transport, app, config)?;
125 let (sender, receiver) = mpsc::channel();
126
127 thread::spawn(move || run_worker(client, pending, receiver, poll_interval));
128
129 Ok(Self {
130 core: AsyncClientCore::new(sender),
131 })
132 }
133
134 #[cfg(any(feature = "serial-rtu", feature = "serial-ascii"))]
136 fn from_transport_config(
137 transport: StdSerialTransport,
138 config: ModbusConfig,
139 poll_interval: Duration,
140 ) -> Result<Self, AsyncError> {
141 Self::connect_with_transport(transport, config, poll_interval)
142 }
143}