Skip to main content

lager/nets/
solar.rs

1//! Solar-simulator nets (EA PSB supplies in photovoltaic mode).
2//!
3//! A solar net drives PV-simulation mode on an EA PSB supply — the same
4//! physical VISA instrument a power-supply net can point at. Box-side, both
5//! roles serialize under hardware_service's per-VISA-address lock, so solar
6//! and supply commands on one EA can never interleave SCPI I/O.
7
8use super::net_handle;
9
10pub(crate) mod ops {
11    use std::time::Duration;
12
13    use serde_json::json;
14
15    use crate::wire::{net_command, unit, value_f64, Op, Timeout};
16
17    const ROLE: &str = "solar";
18
19    /// Every solar action re-asserts PV mode on the instrument (enable() with
20    /// settle retries) before doing its work, so even reads can be slow. The
21    /// box widens its internal proxy budget to 90s for set/stop and 60s for
22    /// reads; the client budget sits above both.
23    fn mode_timeout() -> Timeout {
24        Timeout::After(Duration::from_secs(120))
25    }
26
27    fn read_timeout() -> Timeout {
28        Timeout::After(Duration::from_secs(90))
29    }
30
31    pub(crate) fn set(name: &str) -> Op<()> {
32        Op {
33            req: net_command(name, ROLE, "set", json!({}), mode_timeout()),
34            parse: unit,
35        }
36    }
37
38    pub(crate) fn stop(name: &str) -> Op<()> {
39        Op {
40            req: net_command(name, ROLE, "stop", json!({}), mode_timeout()),
41            parse: unit,
42        }
43    }
44
45    fn read(name: &str, action: &str) -> Op<f64> {
46        Op {
47            req: net_command(name, ROLE, action, json!({}), read_timeout()),
48            parse: value_f64,
49        }
50    }
51
52    fn write(name: &str, action: &str, value: f64) -> Op<f64> {
53        Op {
54            req: net_command(name, ROLE, action, json!({ "value": value }), read_timeout()),
55            parse: value_f64,
56        }
57    }
58
59    pub(crate) fn irradiance(name: &str) -> Op<f64> {
60        read(name, "irradiance")
61    }
62
63    pub(crate) fn set_irradiance(name: &str, watts_per_m2: f64) -> Op<f64> {
64        write(name, "irradiance", watts_per_m2)
65    }
66
67    pub(crate) fn mpp_current(name: &str) -> Op<f64> {
68        read(name, "mpp_current")
69    }
70
71    pub(crate) fn mpp_voltage(name: &str) -> Op<f64> {
72        read(name, "mpp_voltage")
73    }
74
75    pub(crate) fn resistance(name: &str) -> Op<f64> {
76        read(name, "resistance")
77    }
78
79    pub(crate) fn set_resistance(name: &str, ohms: f64) -> Op<f64> {
80        write(name, "resistance", ohms)
81    }
82
83    pub(crate) fn temperature(name: &str) -> Op<f64> {
84        read(name, "temperature")
85    }
86
87    pub(crate) fn voc(name: &str) -> Op<f64> {
88        read(name, "voc")
89    }
90}
91
92net_handle! {
93    /// Handle for a solar-simulator net.
94    sync: Solar,
95    async: AsyncSolar,
96    methods: {
97        /// Initialize the instrument and start PV simulation mode.
98        fn set() -> () = ops::set;
99        /// Stop PV simulation and release the instrument's remote lock.
100        fn stop() -> () = ops::stop;
101        /// Read the configured irradiance (W/m²).
102        fn irradiance() -> f64 = ops::irradiance;
103        /// Set the irradiance (W/m², 0–1500); returns the applied value.
104        fn set_irradiance(watts_per_m2: f64) -> f64 = ops::set_irradiance;
105        /// Read the maximum-power-point current (A).
106        fn mpp_current() -> f64 = ops::mpp_current;
107        /// Read the maximum-power-point voltage (V).
108        fn mpp_voltage() -> f64 = ops::mpp_voltage;
109        /// Read the dynamic panel resistance (Voc / Isc, ohm).
110        fn resistance() -> f64 = ops::resistance;
111        /// Set the dynamic panel resistance (ohm); returns the applied value.
112        fn set_resistance(ohms: f64) -> f64 = ops::set_resistance;
113        /// Read the cell temperature (°C).
114        fn temperature() -> f64 = ops::temperature;
115        /// Read the open-circuit voltage (V).
116        fn voc() -> f64 = ops::voc;
117    }
118}