From 249350730486972fecb5d175ca24d826f5f07ad4 Mon Sep 17 00:00:00 2001 From: Empire Phoenix Date: Thu, 16 Apr 2026 23:58:23 +0200 Subject: [PATCH] Refactor plant state handling and moisture interpretation - Replaced `read_hardware_state` with `interpret_raw_values` for better abstraction and clarity. - Enhanced error handling by introducing `NoMessage` and `NotExpectedMessage` states. - Updated moisture sensor logic to differentiate expected and unexpected messages. - Renamed and refactored enum fields for consistency (`raw_hz` to `hz`). - Minor imports and formatting optimizations. --- .../rust/src/hal/savegame_manager.rs | 2 +- Software/MainBoard/rust/src/main.rs | 16 ++-- Software/MainBoard/rust/src/plant_state.rs | 87 ++++++++----------- .../MainBoard/rust/src/webserver/get_json.rs | 10 ++- 4 files changed, 51 insertions(+), 64 deletions(-) diff --git a/Software/MainBoard/rust/src/hal/savegame_manager.rs b/Software/MainBoard/rust/src/hal/savegame_manager.rs index 172df5a..42af9cf 100644 --- a/Software/MainBoard/rust/src/hal/savegame_manager.rs +++ b/Software/MainBoard/rust/src/hal/savegame_manager.rs @@ -2,7 +2,7 @@ use alloc::vec::Vec; use bincode::{Decode, Encode}; use embedded_savegame::storage::{Flash, Storage}; use embedded_storage::nor_flash::{NorFlash, ReadNorFlash}; -use esp_bootloader_esp_idf::partitions::{Error as PartitionError, Error, FlashRegion}; +use esp_bootloader_esp_idf::partitions::{Error as PartitionError, FlashRegion}; use log::{error, info}; use serde::Serialize; diff --git a/Software/MainBoard/rust/src/main.rs b/Software/MainBoard/rust/src/main.rs index c028d51..1b097aa 100644 --- a/Software/MainBoard/rust/src/main.rs +++ b/Software/MainBoard/rust/src/main.rs @@ -385,14 +385,14 @@ async fn safe_main(spawner: Spawner) -> FatResult<()> { let moisture = board.board_hal.measure_moisture_hz().await?; let plantstate: [PlantState; PLANT_COUNT] = [ - PlantState::read_hardware_state(moisture, 0, &mut board).await, - PlantState::read_hardware_state(moisture, 1, &mut board).await, - PlantState::read_hardware_state(moisture, 2, &mut board).await, - PlantState::read_hardware_state(moisture, 3, &mut board).await, - PlantState::read_hardware_state(moisture, 4, &mut board).await, - PlantState::read_hardware_state(moisture, 5, &mut board).await, - PlantState::read_hardware_state(moisture, 6, &mut board).await, - PlantState::read_hardware_state(moisture, 7, &mut board).await, + 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, + PlantState::interpret_raw_values(moisture, 3, &mut board).await, + PlantState::interpret_raw_values(moisture, 4, &mut board).await, + PlantState::interpret_raw_values(moisture, 5, &mut board).await, + PlantState::interpret_raw_values(moisture, 6, &mut board).await, + PlantState::interpret_raw_values(moisture, 7, &mut board).await, ]; publish_plant_states(&mut board, &timezone_time.clone(), &plantstate) diff --git a/Software/MainBoard/rust/src/plant_state.rs b/Software/MainBoard/rust/src/plant_state.rs index eed0c9d..4d9356e 100644 --- a/Software/MainBoard/rust/src/plant_state.rs +++ b/Software/MainBoard/rust/src/plant_state.rs @@ -10,14 +10,16 @@ const MOIST_SENSOR_MIN_FREQUENCY: f32 = 150.; // this is really, really dry, thi #[derive(Debug, PartialEq, Serialize)] pub enum MoistureSensorError { - NoMessage, + MissingMessage, + NotExpectedMessage { hz: f32 }, ShortCircuit { hz: f32, max: f32 }, OpenLoop { hz: f32, min: f32 }, } #[derive(Debug, PartialEq, Serialize)] pub enum MoistureSensorState { - MoistureValue { raw_hz: f32, moisture_percent: f32 }, + MoistureValue { hz: f32, moisture_percent: f32 }, + NoMessage, SensorError(MoistureSensorError), } @@ -31,7 +33,7 @@ impl MoistureSensorState { pub fn moisture_percent(&self) -> Option { if let MoistureSensorState::MoistureValue { - raw_hz: _, + hz: _, moisture_percent, } = self { @@ -112,64 +114,47 @@ fn map_range_moisture( } impl PlantState { - pub async fn read_hardware_state( + pub async fn interpret_raw_values( moistures: Moistures, plant_id: usize, board: &mut HAL<'_>, ) -> Self { - let sensor_a = { - //if board.board_hal.get_config().plants[plant_id].sensor_a { - let raw = moistures.sensor_a_hz[plant_id]; - match raw { - None => MoistureSensorState::SensorError(MoistureSensorError::NoMessage), - Some(raw) => { - match map_range_moisture( - raw, - board.board_hal.get_config().plants[plant_id] - .moisture_sensor_min_frequency - .map(|a| a as f32), - board.board_hal.get_config().plants[plant_id] - .moisture_sensor_max_frequency - .map(|b| b as f32), - ) { - Ok(moisture_percent) => MoistureSensorState::MoistureValue { - raw_hz: raw, - moisture_percent, - }, - Err(err) => MoistureSensorState::SensorError(err), - } - } - } - }; // else { - // MoistureSensorState::Disabled - //}; + let min = board.board_hal.get_config().plants[plant_id].moisture_sensor_min_frequency; + let max = board.board_hal.get_config().plants[plant_id].moisture_sensor_max_frequency; - let sensor_b = { - //if board.board_hal.get_config().plants[plant_id].sensor_b { - let raw = moistures.sensor_b_hz[plant_id]; + let raw_to_value = |raw: Option, expected: bool| -> MoistureSensorState { match raw { - None => MoistureSensorState::SensorError(MoistureSensorError::NoMessage), + None => { + if expected { + MoistureSensorState::SensorError(MoistureSensorError::MissingMessage) + } else { + MoistureSensorState::NoMessage + } + } Some(raw) => { - match map_range_moisture( - raw, - board.board_hal.get_config().plants[plant_id] - .moisture_sensor_min_frequency - .map(|a| a as f32), - board.board_hal.get_config().plants[plant_id] - .moisture_sensor_max_frequency - .map(|b| b as f32), - ) { - Ok(moisture_percent) => MoistureSensorState::MoistureValue { - raw_hz: raw, - moisture_percent, - }, - Err(err) => MoistureSensorState::SensorError(err), + if expected { + match map_range_moisture(raw, min.map(|a| a as f32), max.map(|b| b as f32)) + { + Ok(moisture_percent) => MoistureSensorState::MoistureValue { + hz: raw, + moisture_percent, + }, + Err(err) => MoistureSensorState::SensorError(err), + } + } else { + MoistureSensorState::SensorError(MoistureSensorError::NotExpectedMessage { + hz: raw, + }) } } } - }; // else { - // MoistureSensorState::Disabled - //}; + }; + + let expected_a = board.board_hal.get_config().plants[plant_id].sensor_a; + let expected_b = board.board_hal.get_config().plants[plant_id].sensor_b; + + let sensor_a = { raw_to_value(moistures.sensor_a_hz[plant_id], expected_a) }; + let sensor_b = { raw_to_value(moistures.sensor_b_hz[plant_id], expected_b) }; let previous_pump = board.board_hal.get_esp().last_pump_time(plant_id); let consecutive_pump_count = board.board_hal.get_esp().consecutive_pump_count(plant_id); diff --git a/Software/MainBoard/rust/src/webserver/get_json.rs b/Software/MainBoard/rust/src/webserver/get_json.rs index 7251ae2..d07c44f 100644 --- a/Software/MainBoard/rust/src/webserver/get_json.rs +++ b/Software/MainBoard/rust/src/webserver/get_json.rs @@ -5,7 +5,7 @@ use crate::plant_state::{MoistureSensorState, PlantState}; use crate::tank::determine_tank_state; use crate::{get_version, BOARD_ACCESS}; use alloc::format; -use alloc::string::String; +use alloc::string::{String, ToString}; use alloc::vec::Vec; use chrono_tz::Tz; use core::str::FromStr; @@ -40,25 +40,27 @@ where let moistures = board.board_hal.measure_moisture_hz().await?; let mut plant_state = Vec::new(); for i in 0..PLANT_COUNT { - plant_state.push(PlantState::read_hardware_state(moistures, i, &mut board).await); + plant_state.push(PlantState::interpret_raw_values(moistures, i, &mut board).await); } let a = Vec::from_iter(plant_state.iter().map(|s| match &s.sensor_a { MoistureSensorState::MoistureValue { - raw_hz, + hz: raw_hz, moisture_percent, } => { format!("{moisture_percent:.2}% {raw_hz}hz",) } MoistureSensorState::SensorError(err) => format!("{err:?}"), + MoistureSensorState::NoMessage => "No Message".to_string(), })); let b = Vec::from_iter(plant_state.iter().map(|s| match &s.sensor_b { MoistureSensorState::MoistureValue { - raw_hz, + hz: raw_hz, moisture_percent, } => { format!("{moisture_percent:.2}% {raw_hz}hz",) } MoistureSensorState::SensorError(err) => format!("{err:?}"), + MoistureSensorState::NoMessage => "No Message".to_string(), })); let data = Moistures {