use crate::classes::{AsyncDcPowerSupply, AsyncDmm, AsyncFunctionGenerator};
use instrument_core::async_session::AsyncSessionOpener;
use instrument_core::connect::ConnectOptions;
use instrument_core::diagnostics::{CommsObserver, DeviceHealth, Diagnostics};
use instrument_core::error::Result;
use instrument_core::kind::InstrumentKind;
use instrument_core::session::ensure_kind_supported;
use instrument_core::{AsyncInstrumentSession, AsyncSessionPool, DiscoveredDevice};
use std::sync::{Arc, Mutex};
#[derive(Clone)]
pub struct AsyncDeviceRef {
pub(crate) device: DiscoveredDevice,
pub(crate) opener: Arc<dyn AsyncSessionOpener>,
pub(crate) connect_options: ConnectOptions,
pub(crate) health: Arc<Mutex<DeviceHealth>>,
pub(crate) observer: Option<Arc<dyn CommsObserver>>,
}
impl AsyncDeviceRef {
pub fn discovered(&self) -> &DiscoveredDevice {
&self.device
}
pub fn address(&self) -> &instrument_core::ResourceAddress {
&self.device.address
}
pub fn supported_kinds(&self) -> &[InstrumentKind] {
&self.device.supported_kinds
}
pub fn connect_options(&self) -> &ConnectOptions {
&self.connect_options
}
pub fn health(&self) -> DeviceHealth {
self.health.lock().unwrap().clone()
}
pub fn with_connect_options(mut self, opts: ConnectOptions) -> Self {
self.connect_options = opts;
self
}
fn diagnostics(&self) -> Diagnostics {
let mut diag = Diagnostics::new(&self.device.address.raw).with_health(self.health.clone());
if let Some(observer) = &self.observer {
diag = diag.with_observer(observer.clone());
}
diag
}
pub async fn open_session(&self) -> Result<AsyncInstrumentSession> {
let transport = self
.opener
.open(&self.device.address, &self.connect_options)
.await?;
AsyncInstrumentSession::new_with_diagnostics(
self.device.address.clone(),
transport,
self.connect_options.clone(),
self.device.identity.clone(),
Some(self.diagnostics()),
)
.await
}
pub async fn session_pool(&self) -> Result<AsyncSessionPool> {
Ok(AsyncSessionPool::new(self.open_session().await?))
}
pub async fn open_dmm(&self) -> Result<AsyncDmm> {
ensure_kind_supported(
&self.device.address,
InstrumentKind::Dmm,
&self.device.supported_kinds,
)?;
Ok(AsyncDmm::new(self.open_session().await?))
}
pub async fn open_dc_power_supply(&self) -> Result<AsyncDcPowerSupply> {
ensure_kind_supported(
&self.device.address,
InstrumentKind::DcPowerSupply,
&self.device.supported_kinds,
)?;
Ok(AsyncDcPowerSupply::new(self.open_session().await?))
}
pub async fn open_function_generator(&self) -> Result<AsyncFunctionGenerator> {
ensure_kind_supported(
&self.device.address,
InstrumentKind::FunctionGenerator,
&self.device.supported_kinds,
)?;
Ok(AsyncFunctionGenerator::new(self.open_session().await?))
}
pub async fn open_untyped(&self) -> Result<AsyncInstrumentSession> {
self.open_session().await
}
}