diff --git a/rust/src/plant_state.rs b/rust/src/plant_state.rs index 26c7288..1560719 100644 --- a/rust/src/plant_state.rs +++ b/rust/src/plant_state.rs @@ -11,11 +11,12 @@ use serde::{Deserialize, Serialize}; const MOIST_SENSOR_MAX_FREQUENCY: f32 = 7500.; // 60kHz (500Hz margin) const MOIST_SENSOR_MIN_FREQUENCY: f32 = 150.; // this is really, really dry, think like cactus levels -#[derive(Debug, PartialEq, Serialize)] +#[derive(Debug, PartialEq, Clone, Serialize)] +#[serde(tag = "kind")] pub enum MoistureSensorError { ShortCircuit { hz: f32, max: f32 }, OpenLoop { hz: f32, min: f32 }, - BoardError(String), + BoardError { message: String }, } #[derive(Debug, PartialEq, Serialize)] @@ -49,6 +50,14 @@ impl MoistureSensorState { impl MoistureSensorState {} #[derive(Debug, PartialEq, Serialize)] +pub struct SensorTelemetry { + pub moisture_pct: Option, + pub raw_hz: Option, + pub error: Option, +} + +#[derive(Debug, PartialEq, Serialize)] +#[serde(tag = "kind")] pub enum PumpError { PumpNotWorking { failed_attempts: usize, @@ -134,9 +143,9 @@ impl PlantState { }, Err(err) => MoistureSensorState::SensorError(err), }, - Err(err) => MoistureSensorState::SensorError(MoistureSensorError::BoardError( - err.to_string(), - )), + Err(err) => MoistureSensorState::SensorError(MoistureSensorError::BoardError { + message: err.to_string(), + }) } } else { MoistureSensorState::Disabled @@ -159,9 +168,9 @@ impl PlantState { }, Err(err) => MoistureSensorState::SensorError(err), }, - Err(err) => MoistureSensorState::SensorError(MoistureSensorError::BoardError( - err.to_string(), - )), + Err(err) => MoistureSensorState::SensorError(MoistureSensorError::BoardError { + message: err.to_string(), + }) } } else { MoistureSensorState::Disabled @@ -277,19 +286,21 @@ impl PlantState { &self, plant_conf: &PlantConfig, current_time: &DateTime, - ) -> PlantInfo<'_> { + ) -> PlantInfo { + let (moisture_pct, _) = self.plant_moisture(); PlantInfo { - sensor_a: &self.sensor_a, - sensor_b: &self.sensor_b, + moisture_pct, + sensor_a: Self::sensor_to_telemetry(&self.sensor_a), + sensor_b: Self::sensor_to_telemetry(&self.sensor_b), mode: plant_conf.mode, do_water: self.needs_to_be_watered(plant_conf, current_time), - dry: if let Some(moisture_percent) = self.plant_moisture().0 { + dry: if let Some(moisture_percent) = moisture_pct { moisture_percent < plant_conf.target_moisture } else { false }, cooldown: self.pump_in_timeout(plant_conf, current_time), - out_of_work_hour: in_time_range( + out_of_work_hour: !in_time_range( current_time, plant_conf.pump_hour_start, plant_conf.pump_hour_end, @@ -316,15 +327,40 @@ impl PlantState { }, } } + + fn sensor_to_telemetry(sensor: &MoistureSensorState) -> SensorTelemetry { + match sensor { + MoistureSensorState::Disabled => SensorTelemetry { + moisture_pct: None, + raw_hz: None, + error: None, + }, + MoistureSensorState::MoistureValue { + raw_hz, + moisture_percent, + } => SensorTelemetry { + moisture_pct: Some(*moisture_percent), + raw_hz: Some(*raw_hz), + error: None, + }, + MoistureSensorState::SensorError(err) => SensorTelemetry { + moisture_pct: None, + raw_hz: None, + error: Some(err.clone()), + }, + } + } } #[derive(Debug, PartialEq, Serialize)] /// State of a single plant to be tracked -pub struct PlantInfo<'a> { +pub struct PlantInfo { + /// combined plant moisture from available sensors + moisture_pct: Option, /// state of humidity sensor on bank a - sensor_a: &'a MoistureSensorState, + sensor_a: SensorTelemetry, /// state of humidity sensor on bank b - sensor_b: &'a MoistureSensorState, + sensor_b: SensorTelemetry, /// configured plant watering mode mode: PlantWateringMode, /// the plant needs to be watered