1use crate::classes::{
2 Counter, DcPowerSupply, Dmm, FunctionGenerator, Oscilloscope, PowerMeter, SpectrumAnalyzer,
3 Switch,
4};
5use instrument_core::connect::ConnectOptions;
6use instrument_core::diagnostics::{CommsObserver, DeviceHealth, Diagnostics};
7use instrument_core::error::Result;
8use instrument_core::kind::InstrumentKind;
9use instrument_core::session::{
10 ensure_kind_supported, InstrumentSession, SessionOpener, SessionPool,
11};
12use instrument_core::DiscoveredDevice;
13use std::sync::{Arc, Mutex};
14
15#[derive(Clone)]
17pub struct DeviceRef {
18 pub(crate) device: DiscoveredDevice,
19 pub(crate) opener: Arc<dyn SessionOpener>,
20 pub(crate) connect_options: ConnectOptions,
21 pub(crate) health: Arc<Mutex<DeviceHealth>>,
22 pub(crate) observer: Option<Arc<dyn CommsObserver>>,
23}
24
25impl DeviceRef {
26 pub fn discovered(&self) -> &DiscoveredDevice {
27 &self.device
28 }
29
30 pub fn address(&self) -> &instrument_core::ResourceAddress {
31 &self.device.address
32 }
33
34 pub fn supported_kinds(&self) -> &[InstrumentKind] {
35 &self.device.supported_kinds
36 }
37
38 pub fn connect_options(&self) -> &ConnectOptions {
39 &self.connect_options
40 }
41
42 pub fn health(&self) -> DeviceHealth {
43 self.health.lock().unwrap().clone()
44 }
45
46 pub fn with_connect_options(mut self, opts: ConnectOptions) -> Self {
47 self.connect_options = opts;
48 self
49 }
50
51 fn diagnostics(&self) -> Diagnostics {
52 let mut diag = Diagnostics::new(&self.device.address.raw).with_health(self.health.clone());
53 if let Some(observer) = &self.observer {
54 diag = diag.with_observer(observer.clone());
55 }
56 diag
57 }
58
59 pub fn open_session(&self) -> Result<InstrumentSession> {
61 let transport = self
62 .opener
63 .open(&self.device.address, &self.connect_options)?;
64 InstrumentSession::new_with_diagnostics(
65 self.device.address.clone(),
66 transport,
67 self.connect_options.clone(),
68 self.device.identity.clone(),
69 Some(self.diagnostics()),
70 )
71 }
72
73 pub fn session_pool(&self) -> Result<SessionPool> {
74 Ok(SessionPool::new(self.open_session()?))
75 }
76
77 pub fn open_dmm(&self) -> Result<Dmm> {
78 ensure_kind_supported(
79 &self.device.address,
80 InstrumentKind::Dmm,
81 &self.device.supported_kinds,
82 )?;
83 Ok(Dmm::new(self.open_session()?))
84 }
85
86 pub fn open_dc_power_supply(&self) -> Result<DcPowerSupply> {
87 ensure_kind_supported(
88 &self.device.address,
89 InstrumentKind::DcPowerSupply,
90 &self.device.supported_kinds,
91 )?;
92 Ok(DcPowerSupply::new(self.open_session()?))
93 }
94
95 pub fn open_function_generator(&self) -> Result<FunctionGenerator> {
96 ensure_kind_supported(
97 &self.device.address,
98 InstrumentKind::FunctionGenerator,
99 &self.device.supported_kinds,
100 )?;
101 Ok(FunctionGenerator::new(self.open_session()?))
102 }
103
104 pub fn open_oscilloscope(&self) -> Result<Oscilloscope> {
105 ensure_kind_supported(
106 &self.device.address,
107 InstrumentKind::Oscilloscope,
108 &self.device.supported_kinds,
109 )?;
110 Ok(Oscilloscope::new(self.open_session()?))
111 }
112
113 pub fn open_switch(&self) -> Result<Switch> {
114 ensure_kind_supported(
115 &self.device.address,
116 InstrumentKind::Switch,
117 &self.device.supported_kinds,
118 )?;
119 Ok(Switch::new(self.open_session()?))
120 }
121
122 pub fn open_counter(&self) -> Result<Counter> {
123 ensure_kind_supported(
124 &self.device.address,
125 InstrumentKind::Counter,
126 &self.device.supported_kinds,
127 )?;
128 Ok(Counter::new(self.open_session()?))
129 }
130
131 pub fn open_power_meter(&self) -> Result<PowerMeter> {
132 ensure_kind_supported(
133 &self.device.address,
134 InstrumentKind::PowerMeter,
135 &self.device.supported_kinds,
136 )?;
137 Ok(PowerMeter::new(self.open_session()?))
138 }
139
140 pub fn open_spectrum_analyzer(&self) -> Result<SpectrumAnalyzer> {
141 ensure_kind_supported(
142 &self.device.address,
143 InstrumentKind::SpectrumAnalyzer,
144 &self.device.supported_kinds,
145 )?;
146 Ok(SpectrumAnalyzer::new(self.open_session()?))
147 }
148
149 pub fn open_untyped(&self) -> Result<InstrumentSession> {
150 self.open_session()
151 }
152}