diff --git a/Software/MainBoard/rust/src/main.rs b/Software/MainBoard/rust/src/main.rs index a11a8c5..663a5ae 100644 --- a/Software/MainBoard/rust/src/main.rs +++ b/Software/MainBoard/rust/src/main.rs @@ -134,6 +134,7 @@ pub struct PumpResult { flow_value_ml: f32, flow_value_count: i16, pump_time_s: u16, + overcurrent_ma: Option, } #[derive(Serialize, Debug, PartialEq)] @@ -384,7 +385,7 @@ async fn safe_main(spawner: Spawner) -> FatResult<()> { let moisture = board.board_hal.measure_moisture_hz().await?; - let plantstate: [PlantState; PLANT_COUNT] = [ + let mut plantstate: [PlantState; PLANT_COUNT] = [ PlantState::interpret_raw_values(moisture, 0, &mut board).await, PlantState::interpret_raw_values(moisture, 1, &mut board).await, PlantState::interpret_raw_values(moisture, 2, &mut board).await, @@ -408,6 +409,7 @@ async fn safe_main(spawner: Spawner) -> FatResult<()> { && !water_frozen; if pump_required { log(LogMessage::EnableMain, dry_run as u32, 0, "", ""); + let mut overcurrent_results: [Option; PLANT_COUNT] = [None; PLANT_COUNT]; for (plant_id, (state, plant_config)) in plantstate .iter() .zip(&board.board_hal.get_config().plants.clone()) @@ -460,6 +462,7 @@ async fn safe_main(spawner: Spawner) -> FatResult<()> { let result = do_secure_pump(&mut board, plant_id, plant_config, dry_run).await; match result { Ok(state) => { + overcurrent_results[plant_id] = state.overcurrent_ma; pump_info( &mut board, plant_id, @@ -497,6 +500,16 @@ async fn safe_main(spawner: Spawner) -> FatResult<()> { .store_consecutive_pump_count(plant_id, 0); } } + for (plant_id, overcurrent) in overcurrent_results.iter().enumerate() { + if let Some(current_ma) = *overcurrent { + plantstate[plant_id].pump.overcurrent_error = Some(current_ma); + } + } + publish_plant_states(&mut board, &timezone_time.clone(), &plantstate) + .await + .unwrap_or_else(|e| { + error!("Error publishing plant states after pumping {e}"); + }); } else { // Pump corrosion protection: pulses each pump once a week for 2s around midday. let last_check_day = board @@ -713,6 +726,7 @@ pub async fn do_secure_pump( let mut error = String::new(); let mut first_error = true; let mut pump_time_ms: u32 = 0; + let mut overcurrent_ma: Option = None; if !dry_run { // Run fertilizer pump first if configured and not in cooldown @@ -790,6 +804,7 @@ pub async fn do_secure_pump( plant_config.max_pump_current_ma.to_string().as_str(), step.to_string().as_str(), ); + overcurrent_ma = Some(current_ma); error = err_msg; } else if high_current && first_error { let err_msg = format!("OverCurrent: {}mA", current_ma); @@ -800,6 +815,7 @@ pub async fn do_secure_pump( plant_config.max_pump_current_ma.to_string().as_str(), step.to_string().as_str(), ); + overcurrent_ma = Some(current_ma); board.board_hal.general_fault(true).await; board.board_hal.fault(plant_id, true).await?; if !plant_config.ignore_current_error { @@ -881,6 +897,7 @@ pub async fn do_secure_pump( flow_value_count: final_flow_value, pump_time_s: (pump_time_ms / 1000) as u16, error, + overcurrent_ma, }) } diff --git a/Software/MainBoard/rust/src/plant_state.rs b/Software/MainBoard/rust/src/plant_state.rs index b8d6d8b..5f00a8a 100644 --- a/Software/MainBoard/rust/src/plant_state.rs +++ b/Software/MainBoard/rust/src/plant_state.rs @@ -51,16 +51,27 @@ pub enum PumpError { failed_attempts: usize, max_allowed_failures: usize, }, + OverCurrent { + current_ma: u16, + max_allowed_ma: u16, + }, } #[derive(Debug, Serialize)] pub struct PumpState { consecutive_pump_count: u32, previous_pump: Option>, + pub overcurrent_error: Option, } impl PumpState { fn is_err(&self, plant_config: &PlantConfig) -> Option { + if let Some(current_ma) = self.overcurrent_error { + return Some(PumpError::OverCurrent { + current_ma, + max_allowed_ma: plant_config.max_pump_current_ma, + }); + } if self.consecutive_pump_count > plant_config.max_consecutive_pump_count as u32 { Some(PumpError::PumpNotWorking { failed_attempts: self.consecutive_pump_count as usize, @@ -172,6 +183,7 @@ impl PlantState { pump: PumpState { consecutive_pump_count, previous_pump, + overcurrent_error: None, }, sensor_a_firmware_build_minutes: a_builds[plant_id], sensor_b_firmware_build_minutes: b_builds[plant_id],