Skip to main content

instrument/classes/
power_meter.rs

1use super::dialect_io;
2use instrument_core::error::Result;
3use instrument_core::kind::InstrumentKind;
4use instrument_core::scpi::ScpiSession;
5use instrument_core::InstrumentSession;
6
7/// Power meter display / readout unit.
8#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9pub enum PowerUnit {
10    Watt,
11    Dbm,
12}
13
14impl PowerUnit {
15    pub(crate) fn scpi_name(self) -> &'static str {
16        match self {
17            Self::Watt => "W",
18            Self::Dbm => "DBM",
19        }
20    }
21}
22
23/// RF / microwave power meter session view.
24pub struct PowerMeter {
25    session: InstrumentSession,
26}
27
28impl PowerMeter {
29    pub fn new(session: InstrumentSession) -> Self {
30        Self { session }
31    }
32
33    pub fn session(&self) -> &InstrumentSession {
34        &self.session
35    }
36
37    pub fn session_mut(&mut self) -> &mut InstrumentSession {
38        &mut self.session
39    }
40
41    fn dialect(&self) -> &'static instrument_core::DialectProfile {
42        self.session.dialect_for(InstrumentKind::PowerMeter)
43    }
44
45    fn write_dialect(&mut self, key: &str, vars: &[(&str, String)]) -> Result<()> {
46        let cmd = dialect_io::formatted(self.dialect(), key, vars)?;
47        self.session.scpi_mut().write(&cmd)
48    }
49
50    fn query_dialect(&mut self, key: &str) -> Result<String> {
51        let cmd = dialect_io::command(self.dialect(), key)?;
52        self.session.scpi_mut().query(cmd)
53    }
54
55    /// Configures units, auto-range/average, optional correction frequency and offset.
56    pub fn configure_measurement(
57        &mut self,
58        unit: PowerUnit,
59        auto_range: bool,
60        auto_average: bool,
61        correction_freq_hz: Option<f64>,
62        offset_db: Option<f64>,
63    ) -> Result<()> {
64        let on_off = |enabled: bool| if enabled { "ON" } else { "OFF" };
65        self.write_dialect("unit", &[("unit", unit.scpi_name().into())])?;
66        self.write_dialect("auto_range", &[("state", on_off(auto_range).into())])?;
67        self.write_dialect("auto_average", &[("state", on_off(auto_average).into())])?;
68        if let Some(hz) = correction_freq_hz {
69            self.write_dialect("correction_frequency", &[("hz", dialect_io::f64_text(hz))])?;
70        }
71        if let Some(db) = offset_db {
72            self.write_dialect("offset", &[("db", dialect_io::f64_text(db))])?;
73        }
74        Ok(())
75    }
76
77    /// Initiates a measurement (INIT).
78    pub fn initiate(&mut self) -> Result<()> {
79        let cmd = dialect_io::command(self.dialect(), "initiate")?;
80        self.session.scpi_mut().write(cmd)
81    }
82
83    /// Fetches the last initiated measurement (FETC?).
84    pub fn fetch(&mut self) -> Result<f64> {
85        ScpiSession::parse_f64(&self.query_dialect("fetch")?)
86    }
87
88    /// Reads a measurement immediately (READ?).
89    pub fn read(&mut self) -> Result<f64> {
90        ScpiSession::parse_f64(&self.query_dialect("read")?)
91    }
92}