pub struct Controller { name: String, interval: std::time::Duration, inner: ControllerInner, data: std::sync::Arc>, } #[derive(Default, serde::Serialize, Clone)] pub struct CommonData { pub battery_voltage: f64, pub target_voltage: f64, pub battery_temp: f64, } impl Controller { pub fn new(config: crate::config::ChargeControllerConfig) -> eyre::Result { let inner = match config.variant { crate::config::ChargeControllerVariant::Tristar => ControllerInner::Tristar( crate::tristar::Tristar::new(&config.serial_port, &config.name, config.baud_rate)?, ), crate::config::ChargeControllerVariant::Pl { timeout_milliseconds, } => ControllerInner::Pl(crate::pl::Pli::new( &config.serial_port, &config.name, config.baud_rate, timeout_milliseconds, )?), }; let data = CommonData::default(); let data = std::sync::Arc::new(tokio::sync::RwLock::new(data)); Ok(Self { name: config.name, interval: std::time::Duration::from_secs(config.watch_interval_seconds), inner, data, }) } pub fn get_data_ptr(&self) -> std::sync::Arc> { self.data.clone() } pub async fn refresh(&mut self) -> eyre::Result<()> { let data = self.inner.refresh().await?; *self.data.write().await = data; Ok(()) } pub fn timeout_interval(&self) -> std::time::Duration { self.interval } pub fn name(&self) -> &str { &self.name } } pub enum ControllerInner { Pl(crate::pl::Pli), Tristar(crate::tristar::Tristar), } impl ControllerInner { pub async fn refresh(&mut self) -> eyre::Result { match self { ControllerInner::Pl(pli) => { let pl_data = pli.refresh().await?; Ok(pl_data) } ControllerInner::Tristar(tristar) => { let tristar_data = tristar.refresh().await?; Ok(tristar_data) } } } }