diff --git a/charge-controller-supervisor/src/controller.rs b/charge-controller-supervisor/src/controller.rs index 6b7d824..dd51203 100644 --- a/charge-controller-supervisor/src/controller.rs +++ b/charge-controller-supervisor/src/controller.rs @@ -99,17 +99,14 @@ impl Controller { &self.name } - pub fn set_tx_to_secondary( - &mut self, - tx: Vec<tokio::sync::mpsc::UnboundedSender<VoltageCommand>>, - ) { + pub fn set_tx_to_secondary(&mut self, tx: MultiTx) { assert!( self.voltage_rx.is_none(), "trying to set {} as primary when it is also a secondary!", self.name ); - self.voltage_tx = Some(MultiTx(tx)); + self.voltage_tx = Some(tx); } pub fn get_rx(&mut self) -> Option<&mut tokio::sync::mpsc::UnboundedReceiver<VoltageCommand>> { @@ -125,11 +122,12 @@ impl Controller { } } -struct MultiTx(Vec<tokio::sync::mpsc::UnboundedSender<VoltageCommand>>); +#[derive(Clone)] +pub struct MultiTx(pub Vec<tokio::sync::mpsc::UnboundedSender<VoltageCommand>>); impl MultiTx { - fn send_to_all(&mut self, command: VoltageCommand) { - for sender in &mut self.0 { + pub fn send_to_all(&self, command: VoltageCommand) { + for sender in &self.0 { if let Err(e) = sender.send(command) { log::error!("failed to send command {command:?}: {e:?}"); } diff --git a/charge-controller-supervisor/src/main.rs b/charge-controller-supervisor/src/main.rs index 7caeac2..e4febb3 100644 --- a/charge-controller-supervisor/src/main.rs +++ b/charge-controller-supervisor/src/main.rs @@ -69,7 +69,7 @@ async fn run() -> eyre::Result<()> { async fn watch(args: Args) -> eyre::Result<()> { let _w = config::init_config(&args.config); - let (map, mut controller_tasks) = { + let (map, follow_voltage_tx, mut controller_tasks) = { let config = config::access_config().await; if config .charge_controllers @@ -99,11 +99,13 @@ async fn watch(args: Args) -> eyre::Result<()> { } } + let follow_voltage_tx = controller::MultiTx(follow_voltage_tx); + if let Some(primary) = controllers .iter_mut() .find(|c| c.name() == config.primary_charge_controller) { - primary.set_tx_to_secondary(follow_voltage_tx); + primary.set_tx_to_secondary(follow_voltage_tx.clone()); } let controller_tasks = futures::stream::FuturesUnordered::new(); @@ -111,12 +113,13 @@ async fn watch(args: Args) -> eyre::Result<()> { controller_tasks.push(run_loop(controller)); } - (map, controller_tasks) + (map, follow_voltage_tx, controller_tasks) }; let server = web::rocket(web::ServerState::new( &config::access_config().await.primary_charge_controller, map, + follow_voltage_tx, )); let server_task = tokio::task::spawn(server.launch()); diff --git a/charge-controller-supervisor/src/web.rs b/charge-controller-supervisor/src/web.rs index 8ebf93f..925045e 100644 --- a/charge-controller-supervisor/src/web.rs +++ b/charge-controller-supervisor/src/web.rs @@ -8,6 +8,7 @@ pub struct ServerState { String, std::sync::Arc<tokio::sync::RwLock<crate::controller::CommonData>>, >, + tx_to_controllers: crate::controller::MultiTx, } impl ServerState { @@ -17,9 +18,14 @@ impl ServerState { String, std::sync::Arc<tokio::sync::RwLock<crate::controller::CommonData>>, >, + tx_to_controllers: crate::controller::MultiTx, ) -> Self { let primary_name = primary_name.to_string(); - Self { primary_name, map } + Self { + primary_name, + map, + tx_to_controllers, + } } } @@ -133,11 +139,14 @@ async fn enable_control() { } #[post("/control/disable")] -async fn disable_control() { +async fn disable_control(state: &State<ServerState>) { log::warn!("disabling control"); crate::config::write_to_config() .await .enable_secondary_control = false; + state + .tx_to_controllers + .send_to_all(crate::controller::VoltageCommand::Set(-1.0)); } enum ServerError { Prometheus,