use std::ops::Deref;
use super::*;
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")]
pub fn connect_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 connect_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 connect_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 connect_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 connect_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()));
let app = AsyncApp {
pending: pending.clone(),
};
let client = ClientServices::<_, _, 1>::new(transport, app, config)?;
let (sender, receiver) = mpsc::channel();
thread::spawn(move || run_worker(client, pending, receiver, poll_interval));
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::connect_with_transport(transport, config, poll_interval)
}
}