use super::*;
use std::ops::Deref;
pub struct AsyncSerialClient {
core: AsyncClientCore,
}
impl Deref for AsyncSerialClient {
type Target = AsyncClientCore;
fn deref(&self) -> &Self::Target {
&self.core
}
}
impl AsyncSerialClient {
#[cfg(feature = "serial-rtu")]
#[deprecated(note = "use AsyncSerialClient::new_rtu(...) and then client.connect().await")]
pub fn connect_rtu(serial_config: ModbusSerialConfig) -> Result<Self, AsyncError> {
Self::new_rtu(serial_config)
}
#[cfg(feature = "serial-rtu")]
#[deprecated(
note = "use AsyncSerialClient::new_rtu_with_poll_interval(...) and then client.connect().await"
)]
pub fn connect_rtu_with_poll_interval(
serial_config: ModbusSerialConfig,
poll_interval: Duration,
) -> Result<Self, AsyncError> {
Self::new_rtu_with_poll_interval(serial_config, poll_interval)
}
#[cfg(feature = "serial-ascii")]
#[deprecated(note = "use AsyncSerialClient::new_ascii(...) and then client.connect().await")]
pub fn connect_ascii(serial_config: ModbusSerialConfig) -> Result<Self, AsyncError> {
Self::new_ascii(serial_config)
}
#[cfg(feature = "serial-ascii")]
#[deprecated(
note = "use AsyncSerialClient::new_ascii_with_poll_interval(...) and then client.connect().await"
)]
pub fn connect_ascii_with_poll_interval(
serial_config: ModbusSerialConfig,
poll_interval: Duration,
) -> Result<Self, AsyncError> {
Self::new_ascii_with_poll_interval(serial_config, poll_interval)
}
#[deprecated(
note = "use AsyncSerialClient::new_with_transport(...) and then client.connect().await"
)]
pub fn connect_with_transport<TRANSPORT>(
transport: TRANSPORT,
config: ModbusConfig,
poll_interval: Duration,
) -> Result<Self, AsyncError>
where
TRANSPORT: Transport + Send + 'static,
{
Self::new_with_transport(transport, config, poll_interval)
}
#[cfg(feature = "serial-rtu")]
pub fn new_rtu(serial_config: ModbusSerialConfig) -> Result<Self, AsyncError> {
if serial_config.mode != SerialMode::Rtu {
return Err(AsyncError::Mbus(MbusError::InvalidConfiguration));
}
let transport = StdSerialTransport::new(SerialMode::Rtu);
let config = ModbusConfig::Serial(serial_config);
Self::from_transport_config(transport, config, Duration::from_millis(20))
}
#[cfg(feature = "serial-rtu")]
pub fn new_rtu_with_poll_interval(
serial_config: ModbusSerialConfig,
poll_interval: Duration,
) -> Result<Self, AsyncError> {
if serial_config.mode != SerialMode::Rtu {
return Err(AsyncError::Mbus(MbusError::InvalidConfiguration));
}
let transport = StdSerialTransport::new(SerialMode::Rtu);
let config = ModbusConfig::Serial(serial_config);
Self::from_transport_config(transport, config, poll_interval)
}
#[cfg(feature = "serial-ascii")]
pub fn new_ascii(serial_config: ModbusSerialConfig) -> Result<Self, AsyncError> {
if serial_config.mode != SerialMode::Ascii {
return Err(AsyncError::Mbus(MbusError::InvalidConfiguration));
}
let transport = StdSerialTransport::new(SerialMode::Ascii);
let config = ModbusConfig::Serial(serial_config);
Self::from_transport_config(transport, config, Duration::from_millis(20))
}
#[cfg(feature = "serial-ascii")]
pub fn new_ascii_with_poll_interval(
serial_config: ModbusSerialConfig,
poll_interval: Duration,
) -> Result<Self, AsyncError> {
if serial_config.mode != SerialMode::Ascii {
return Err(AsyncError::Mbus(MbusError::InvalidConfiguration));
}
let transport = StdSerialTransport::new(SerialMode::Ascii);
let config = ModbusConfig::Serial(serial_config);
Self::from_transport_config(transport, config, poll_interval)
}
pub fn new_with_transport<TRANSPORT>(
transport: TRANSPORT,
config: ModbusConfig,
poll_interval: Duration,
) -> Result<Self, AsyncError>
where
TRANSPORT: Transport + Send + 'static,
{
if !matches!(config, ModbusConfig::Serial(_)) {
return Err(AsyncError::Mbus(MbusError::InvalidTransport));
}
let pending = Arc::new(Mutex::new(HashMap::new()));
#[cfg(feature = "traffic")]
let traffic_handler = Arc::new(Mutex::new(None));
#[cfg(feature = "traffic")]
let (traffic_sender, traffic_receiver) = mpsc::channel();
let app = AsyncApp {
pending: pending.clone(),
#[cfg(feature = "traffic")]
traffic_sender,
};
let client = ClientServices::<_, _, 1>::new(transport, app, config)?;
let (sender, receiver) = mpsc::channel();
thread::spawn(move || run_worker(client, pending, receiver, poll_interval));
#[cfg(feature = "traffic")]
{
let dispatcher_handler = traffic_handler.clone();
thread::spawn(move || run_traffic_dispatcher(traffic_receiver, dispatcher_handler));
}
#[cfg(feature = "traffic")]
{
return Ok(Self {
core: AsyncClientCore::new(sender, traffic_handler),
});
}
#[cfg(not(feature = "traffic"))]
{
Ok(Self {
core: AsyncClientCore::new(sender),
})
}
}
#[cfg(any(feature = "serial-rtu", feature = "serial-ascii"))]
fn from_transport_config(
transport: StdSerialTransport,
config: ModbusConfig,
poll_interval: Duration,
) -> Result<Self, AsyncError> {
Self::new_with_transport(transport, config, poll_interval)
}
}