diff --git a/Software/MainBoard/.idea/.gitignore b/Software/MainBoard/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/Software/MainBoard/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/Software/MainBoard/.idea/MainBoard.iml b/Software/MainBoard/.idea/MainBoard.iml new file mode 100644 index 0000000..f8e3774 --- /dev/null +++ b/Software/MainBoard/.idea/MainBoard.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/Software/MainBoard/.idea/modules.xml b/Software/MainBoard/.idea/modules.xml new file mode 100644 index 0000000..affad87 --- /dev/null +++ b/Software/MainBoard/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/Software/MainBoard/.idea/vcs.xml b/Software/MainBoard/.idea/vcs.xml new file mode 100644 index 0000000..9e376f2 --- /dev/null +++ b/Software/MainBoard/.idea/vcs.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/Software/MainBoard/d1.json b/Software/MainBoard/d1.json new file mode 100644 index 0000000..b5f0541 --- /dev/null +++ b/Software/MainBoard/d1.json @@ -0,0 +1,172 @@ +{ + "hardware": { + "board": "V4", + "battery": "Disabled" + }, + "network": { + "max_wait": 10000, + "ap_ssid": "PlantCtrl Init", + "ssid": "private", + "password": "wertertzu", + "mqtt_url": "", + "mqtt_user": null, + "mqtt_password": null, + "base_topic": "" + }, + "tank": { + "tank_allow_pumping_if_sensor_error": true, + "tank_empty_percent": 5, + "tank_full_percent": 95, + "tank_sensor_enabled": false, + "tank_useable_ml": 50000, + "tank_warn_percent": 40, + "ml_per_pulse": 0 + }, + "night_lamp": { + "night_lamp_hour_start": 19, + "night_lamp_hour_end": 2, + "night_lamp_only_when_dark": true, + "enabled": true, + "low_soc_cutoff": 30, + "low_soc_restore": 50 + }, + "plants": [ + { + "mode": "Off", + "target_moisture": 40, + "min_moisture": 30, + "pump_time_s": 30, + "pump_cooldown_min": 60, + "pump_hour_start": 9, + "pump_hour_end": 20, + "sensor_b": false, + "sensor_a": true, + "max_consecutive_pump_count": 10, + "moisture_sensor_min_frequency": null, + "moisture_sensor_max_frequency": null, + "min_pump_current_ma": 10, + "max_pump_current_ma": 3000, + "ignore_current_error": true + }, + { + "mode": "Off", + "target_moisture": 40, + "min_moisture": 30, + "pump_time_s": 30, + "pump_cooldown_min": 60, + "pump_hour_start": 9, + "pump_hour_end": 20, + "sensor_b": false, + "sensor_a": true, + "max_consecutive_pump_count": 10, + "moisture_sensor_min_frequency": null, + "moisture_sensor_max_frequency": null, + "min_pump_current_ma": 10, + "max_pump_current_ma": 3000, + "ignore_current_error": true + }, + { + "mode": "Off", + "target_moisture": 40, + "min_moisture": 30, + "pump_time_s": 30, + "pump_cooldown_min": 60, + "pump_hour_start": 9, + "pump_hour_end": 20, + "sensor_b": false, + "sensor_a": true, + "max_consecutive_pump_count": 10, + "moisture_sensor_min_frequency": null, + "moisture_sensor_max_frequency": null, + "min_pump_current_ma": 10, + "max_pump_current_ma": 3000, + "ignore_current_error": true + }, + { + "mode": "Off", + "target_moisture": 40, + "min_moisture": 30, + "pump_time_s": 30, + "pump_cooldown_min": 60, + "pump_hour_start": 9, + "pump_hour_end": 20, + "sensor_b": false, + "sensor_a": true, + "max_consecutive_pump_count": 10, + "moisture_sensor_min_frequency": null, + "moisture_sensor_max_frequency": null, + "min_pump_current_ma": 10, + "max_pump_current_ma": 3000, + "ignore_current_error": true + }, + { + "mode": "Off", + "target_moisture": 40, + "min_moisture": 30, + "pump_time_s": 30, + "pump_cooldown_min": 60, + "pump_hour_start": 9, + "pump_hour_end": 20, + "sensor_b": false, + "sensor_a": true, + "max_consecutive_pump_count": 10, + "moisture_sensor_min_frequency": null, + "moisture_sensor_max_frequency": null, + "min_pump_current_ma": 10, + "max_pump_current_ma": 3000, + "ignore_current_error": true + }, + { + "mode": "Off", + "target_moisture": 40, + "min_moisture": 30, + "pump_time_s": 30, + "pump_cooldown_min": 60, + "pump_hour_start": 9, + "pump_hour_end": 20, + "sensor_b": false, + "sensor_a": true, + "max_consecutive_pump_count": 10, + "moisture_sensor_min_frequency": null, + "moisture_sensor_max_frequency": null, + "min_pump_current_ma": 10, + "max_pump_current_ma": 3000, + "ignore_current_error": true + }, + { + "mode": "Off", + "target_moisture": 40, + "min_moisture": 30, + "pump_time_s": 30, + "pump_cooldown_min": 60, + "pump_hour_start": 9, + "pump_hour_end": 20, + "sensor_b": false, + "sensor_a": true, + "max_consecutive_pump_count": 10, + "moisture_sensor_min_frequency": null, + "moisture_sensor_max_frequency": null, + "min_pump_current_ma": 10, + "max_pump_current_ma": 3000, + "ignore_current_error": true + }, + { + "mode": "Off", + "target_moisture": 40, + "min_moisture": 30, + "pump_time_s": 30, + "pump_cooldown_min": 60, + "pump_hour_start": 9, + "pump_hour_end": 20, + "sensor_b": false, + "sensor_a": true, + "max_consecutive_pump_count": 10, + "moisture_sensor_min_frequency": null, + "moisture_sensor_max_frequency": null, + "min_pump_current_ma": 10, + "max_pump_current_ma": 3000, + "ignore_current_error": true + } + ], + "timezone": "Europe/Berlin" +} \ No newline at end of file diff --git a/Software/MainBoard/d2.json b/Software/MainBoard/d2.json new file mode 100644 index 0000000..c848b4c --- /dev/null +++ b/Software/MainBoard/d2.json @@ -0,0 +1,180 @@ +{ + "hardware": { + "board": "V4", + "battery": "Disabled" + }, + "network": { + "ap_ssid": "PlantCtrl Init", + "ssid": "private", + "password": "wertertzu", + "mqtt_url": "", + "base_topic": "", + "mqtt_user": null, + "mqtt_password": null, + "max_wait": 10000 + }, + "tank": { + "tank_sensor_enabled": false, + "tank_allow_pumping_if_sensor_error": true, + "tank_useable_ml": 50000, + "tank_warn_percent": 40, + "tank_empty_percent": 5, + "tank_full_percent": 95, + "ml_per_pulse": 0.0 + }, + "night_lamp": { + "enabled": true, + "night_lamp_hour_start": 19, + "night_lamp_hour_end": 2, + "night_lamp_only_when_dark": true, + "low_soc_cutoff": 30, + "low_soc_restore": 50 + }, + "plants": [ + { + "mode": "Off", + "target_moisture": 40, + "min_moisture": 30, + "pump_time_s": 30, + "pump_limit_ml": 5000, + "pump_cooldown_min": 60, + "pump_hour_start": 9, + "pump_hour_end": 20, + "sensor_a": true, + "sensor_b": false, + "max_consecutive_pump_count": 10, + "moisture_sensor_min_frequency": null, + "moisture_sensor_max_frequency": null, + "min_pump_current_ma": 10, + "max_pump_current_ma": 3000, + "ignore_current_error": true + }, + { + "mode": "Off", + "target_moisture": 40, + "min_moisture": 30, + "pump_time_s": 30, + "pump_limit_ml": 5000, + "pump_cooldown_min": 60, + "pump_hour_start": 9, + "pump_hour_end": 20, + "sensor_a": true, + "sensor_b": false, + "max_consecutive_pump_count": 10, + "moisture_sensor_min_frequency": null, + "moisture_sensor_max_frequency": null, + "min_pump_current_ma": 10, + "max_pump_current_ma": 3000, + "ignore_current_error": true + }, + { + "mode": "Off", + "target_moisture": 40, + "min_moisture": 30, + "pump_time_s": 30, + "pump_limit_ml": 5000, + "pump_cooldown_min": 60, + "pump_hour_start": 9, + "pump_hour_end": 20, + "sensor_a": true, + "sensor_b": false, + "max_consecutive_pump_count": 10, + "moisture_sensor_min_frequency": null, + "moisture_sensor_max_frequency": null, + "min_pump_current_ma": 10, + "max_pump_current_ma": 3000, + "ignore_current_error": true + }, + { + "mode": "Off", + "target_moisture": 40, + "min_moisture": 30, + "pump_time_s": 30, + "pump_limit_ml": 5000, + "pump_cooldown_min": 60, + "pump_hour_start": 9, + "pump_hour_end": 20, + "sensor_a": true, + "sensor_b": false, + "max_consecutive_pump_count": 10, + "moisture_sensor_min_frequency": null, + "moisture_sensor_max_frequency": null, + "min_pump_current_ma": 10, + "max_pump_current_ma": 3000, + "ignore_current_error": true + }, + { + "mode": "Off", + "target_moisture": 40, + "min_moisture": 30, + "pump_time_s": 30, + "pump_limit_ml": 5000, + "pump_cooldown_min": 60, + "pump_hour_start": 9, + "pump_hour_end": 20, + "sensor_a": true, + "sensor_b": false, + "max_consecutive_pump_count": 10, + "moisture_sensor_min_frequency": null, + "moisture_sensor_max_frequency": null, + "min_pump_current_ma": 10, + "max_pump_current_ma": 3000, + "ignore_current_error": true + }, + { + "mode": "Off", + "target_moisture": 40, + "min_moisture": 30, + "pump_time_s": 30, + "pump_limit_ml": 5000, + "pump_cooldown_min": 60, + "pump_hour_start": 9, + "pump_hour_end": 20, + "sensor_a": true, + "sensor_b": false, + "max_consecutive_pump_count": 10, + "moisture_sensor_min_frequency": null, + "moisture_sensor_max_frequency": null, + "min_pump_current_ma": 10, + "max_pump_current_ma": 3000, + "ignore_current_error": true + }, + { + "mode": "Off", + "target_moisture": 40, + "min_moisture": 30, + "pump_time_s": 30, + "pump_limit_ml": 5000, + "pump_cooldown_min": 60, + "pump_hour_start": 9, + "pump_hour_end": 20, + "sensor_a": true, + "sensor_b": false, + "max_consecutive_pump_count": 10, + "moisture_sensor_min_frequency": null, + "moisture_sensor_max_frequency": null, + "min_pump_current_ma": 10, + "max_pump_current_ma": 3000, + "ignore_current_error": true + }, + { + "mode": "Off", + "target_moisture": 40, + "min_moisture": 30, + "pump_time_s": 30, + "pump_limit_ml": 5000, + "pump_cooldown_min": 60, + "pump_hour_start": 9, + "pump_hour_end": 20, + "sensor_a": true, + "sensor_b": false, + "max_consecutive_pump_count": 10, + "moisture_sensor_min_frequency": null, + "moisture_sensor_max_frequency": null, + "min_pump_current_ma": 10, + "max_pump_current_ma": 3000, + "ignore_current_error": true + } + ], + "timezone": "Europe/Berlin" +} \ No newline at end of file diff --git a/Software/MainBoard/rust/Cargo.toml b/Software/MainBoard/rust/Cargo.toml index d59103c..0aa9409 100644 --- a/Software/MainBoard/rust/Cargo.toml +++ b/Software/MainBoard/rust/Cargo.toml @@ -151,6 +151,8 @@ heapless = { version = "0.7.17", features = ["serde"] } mcutie = { version = "0.3.0", default-features = false, features = ["log", "homeassistant"] } nb = "1.1.0" embedded-can = "0.4.1" +no-panic = "0.1.35" +dont_panic = "0.1.0" diff --git a/Software/MainBoard/rust/flash.sh b/Software/MainBoard/rust/flash.sh index 8dff1d5..2a8e622 100755 --- a/Software/MainBoard/rust/flash.sh +++ b/Software/MainBoard/rust/flash.sh @@ -2,6 +2,11 @@ rm ./src/webserver/index.html.gz rm ./src/webserver/bundle.js.gz +rm ./src_webpack/index.html.gz +rm ./src_webpack/bundle.js.gz +rm ./src_webpack/index.html +rm ./src_webpack/bundle.js + set -e pushd ./src_webpack/ diff --git a/Software/MainBoard/rust/src/config.rs b/Software/MainBoard/rust/src/config.rs index 7c23a21..947e0c0 100644 --- a/Software/MainBoard/rust/src/config.rs +++ b/Software/MainBoard/rust/src/config.rs @@ -115,8 +115,8 @@ pub struct PlantControllerConfig { #[serde(default)] pub struct PlantConfig { pub mode: PlantWateringMode, - pub target_moisture: f32, - pub min_moisture: f32, + pub target_moisture: u8, + pub min_moisture: u8, pub pump_time_s: u16, pub pump_limit_ml: u16, pub pump_cooldown_min: u16, @@ -125,8 +125,8 @@ pub struct PlantConfig { pub sensor_a: bool, pub sensor_b: bool, pub max_consecutive_pump_count: u8, - pub moisture_sensor_min_frequency: Option, // Optional min frequency - pub moisture_sensor_max_frequency: Option, // Optional max frequency + pub moisture_sensor_min_frequency: Option, // Optional min frequency + pub moisture_sensor_max_frequency: Option, // Optional max frequency pub min_pump_current_ma: u16, pub max_pump_current_ma: u16, pub ignore_current_error: bool, @@ -136,8 +136,8 @@ impl Default for PlantConfig { fn default() -> Self { Self { mode: PlantWateringMode::Off, - target_moisture: 40., - min_moisture: 30., + target_moisture: 40, + min_moisture: 30, pump_time_s: 30, pump_limit_ml: 5000, pump_cooldown_min: 60, diff --git a/Software/MainBoard/rust/src/fat_error.rs b/Software/MainBoard/rust/src/fat_error.rs index cd465d7..838bbf4 100644 --- a/Software/MainBoard/rust/src/fat_error.rs +++ b/Software/MainBoard/rust/src/fat_error.rs @@ -316,3 +316,4 @@ impl From for FatError { FatError::SNTPError { error: value } } } + diff --git a/Software/MainBoard/rust/src/hal/esp.rs b/Software/MainBoard/rust/src/hal/esp.rs index 4b6c437..e6c254c 100644 --- a/Software/MainBoard/rust/src/hal/esp.rs +++ b/Software/MainBoard/rust/src/hal/esp.rs @@ -146,7 +146,7 @@ macro_rules! mk_static { ($t:ty,$val:expr) => {{ static STATIC_CELL: static_cell::StaticCell<$t> = static_cell::StaticCell::new(); #[deny(unused_attributes)] - let x = STATIC_CELL.uninit().write(($val)); + let x = STATIC_CELL.uninit().write($val); x }}; } diff --git a/Software/MainBoard/rust/src/hal/mod.rs b/Software/MainBoard/rust/src/hal/mod.rs index a3d2d68..564ce20 100644 --- a/Software/MainBoard/rust/src/hal/mod.rs +++ b/Software/MainBoard/rust/src/hal/mod.rs @@ -238,7 +238,7 @@ macro_rules! mk_static { ($t:ty,$val:expr) => {{ static STATIC_CELL: static_cell::StaticCell<$t> = static_cell::StaticCell::new(); #[deny(unused_attributes)] - let x = STATIC_CELL.uninit().write(($val)); + let x = STATIC_CELL.uninit().write($val); x }}; } diff --git a/Software/MainBoard/rust/src/hal/v4_sensor.rs b/Software/MainBoard/rust/src/hal/v4_sensor.rs index 774107e..d618616 100644 --- a/Software/MainBoard/rust/src/hal/v4_sensor.rs +++ b/Software/MainBoard/rust/src/hal/v4_sensor.rs @@ -1,17 +1,16 @@ use crate::bail; -use crate::fat_error::{ContextExt, FatError, FatResult}; +use crate::fat_error::{ContextExt, FatResult}; use crate::hal::Box; use crate::hal::{DetectionResult, Moistures, Sensor}; use crate::log::{LogMessage, LOG_ACCESS}; use alloc::format; use alloc::string::ToString; use async_trait::async_trait; -use bincode::config; use canapi::id::{classify, plant_id, MessageKind, IDENTIFY_CMD_OFFSET}; use canapi::SensorSlot; use embassy_embedded_hal::shared_bus::blocking::i2c::I2cDevice; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; -use embassy_time::{Duration, Instant, Timer, WithTimeout}; +use embassy_time::{Duration, Timer, WithTimeout}; use embedded_can::{Frame, Id}; use esp_hal::gpio::Output; use esp_hal::i2c::master::I2c; @@ -86,7 +85,7 @@ impl SensorInteraction for SensorImpl { } => { can_power.set_high(); let config = twai_config.take().expect("twai config not set"); - let mut twai = config.start(); + let mut twai = config.into_async().start(); loop { let rec = twai.receive(); @@ -100,15 +99,17 @@ impl SensorInteraction for SensorImpl { } Timer::after_millis(10).await; - let can = Self::inner_can(&mut twai).await; + + let mut moistures = Moistures::default(); + let _ = Self::wait_for_can_measurements(&mut twai, &mut moistures).with_timeout(Duration::from_millis(5000)).await; + can_power.set_low(); - let config = twai.stop(); + let config = twai.stop().into_blocking(); twai_config.replace(config); - let value = can?; - Ok(value) + Ok(moistures) } } } @@ -160,9 +161,8 @@ impl SensorImpl { } } - let mut result = DetectionResult::default(); - // Wait for messages to arrive - let _ = Self::wait_for_can_measurements(&mut as_async, &mut result) + let mut moistures = Moistures::default(); + let _ = Self::wait_for_can_measurements(&mut as_async, &mut moistures) .with_timeout(Duration::from_millis(5000)) .await; @@ -170,6 +170,8 @@ impl SensorImpl { can_power.set_low(); twai_config.replace(config); + let result= moistures.into(); + info!("Autodetection result: {result:?}"); Ok(result) } @@ -178,8 +180,9 @@ impl SensorImpl { async fn wait_for_can_measurements( as_async: &mut Twai<'_, Async>, - result: &mut DetectionResult, - ) { + moistures: &mut Moistures, + ) -> FatResult<()> { + loop { match as_async.receive_async().await { Ok(can_frame) => match can_frame.id() { @@ -196,12 +199,14 @@ impl SensorImpl { if msg.0 == MessageKind::MoistureData { let plant = msg.1 as usize; let sensor = msg.2; + let data = can_frame.data(); + match sensor { SensorSlot::A => { - result.plant[plant].sensor_a = true; + moistures.sensor_a_hz[plant] = data[0] as f32; } SensorSlot::B => { - result.plant[plant].sensor_b = true; + moistures.sensor_b_hz[plant] = data[0] as f32; } } } @@ -214,7 +219,6 @@ impl SensorImpl { }, Err(err) => { error!("Error receiving CAN message: {err:?}"); - break; } } } @@ -302,31 +306,17 @@ impl SensorImpl { let median = results[mid]; Ok(median) } - - async fn inner_can(twai: &mut Twai<'static, Blocking>) -> FatResult { - config::standard(); - - let timeout = Instant::now() - .checked_add(embassy_time::Duration::from_millis(100)) - .context("Timeout")?; - loop { - let answer = twai.receive(); - match answer { - Ok(answer) => { - info!("Received CAN message: {answer:?}"); - } - Err(error) => match error { - nb::Error::Other(error) => { - return Err(FatError::CanBusError { error }); - } - nb::Error::WouldBlock => { - if Instant::now() > timeout { - bail!("Timeout waiting for CAN answer"); - } - Timer::after_millis(10).await; - } - }, - } - } - } } + +impl From for DetectionResult { + fn from(value: Moistures) -> Self { + let mut result = DetectionResult::default(); + for (plant, sensor) in value.sensor_a_hz.iter().enumerate() { + result.plant[plant].sensor_a = *sensor > 1.0_f32; + } + for (plant, sensor) in value.sensor_b_hz.iter().enumerate() { + result.plant[plant].sensor_b = *sensor > 1.0_f32; + } + result + } +} \ No newline at end of file diff --git a/Software/MainBoard/rust/src/log/mod.rs b/Software/MainBoard/rust/src/log/mod.rs index a735ff8..ccbb164 100644 --- a/Software/MainBoard/rust/src/log/mod.rs +++ b/Software/MainBoard/rust/src/log/mod.rs @@ -7,7 +7,7 @@ use deranged::RangedU8; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::mutex::Mutex; use esp_hal::Persistable; -use log::info; +use log::{info, warn}; use serde::Serialize; use strum_macros::IntoStaticStr; use unit_enum::UnitEnum; @@ -159,24 +159,41 @@ impl LogArray { } } + fn limit_length(input: &str, target: &mut heapless::String) { for char in input.chars() { match target.push(char) { Ok(_) => {} //continue adding chars Err(_) => { //clear space for two asci chars + info!("pushing char {char} to limit {LIMIT} current value {target} input {input}"); while target.len() + 2 >= LIMIT { - target.pop().unwrap(); + target.pop(); } //add .. to shortened strings - target.push('.').unwrap(); - target.push('.').unwrap(); + match target.push('.'){ + Ok(_) => {} + Err(_) => { + warn!("Error pushin . to limit {LIMIT} current value {target} input {input}") + } + } + match target.push('.'){ + Ok(_) => {} + Err(_) => { + warn!("Error pushin . to limit {LIMIT} current value {target} input {input}") + } + } return; } } } while target.len() < LIMIT { - target.push(' ').unwrap(); + match target.push(' ') { + Ok(_) => {} + Err(_) => { + warn!("Error pushing space to limit {LIMIT} current value {target} input {input}") + } + } } } diff --git a/Software/MainBoard/rust/src/main.rs b/Software/MainBoard/rust/src/main.rs index a0387ee..77ecb50 100644 --- a/Software/MainBoard/rust/src/main.rs +++ b/Software/MainBoard/rust/src/main.rs @@ -832,7 +832,7 @@ macro_rules! mk_static { ($t:ty,$val:expr) => {{ static STATIC_CELL: static_cell::StaticCell<$t> = static_cell::StaticCell::new(); #[deny(unused_attributes)] - let x = STATIC_CELL.uninit().write(($val)); + let x = STATIC_CELL.uninit().write($val); x }}; } diff --git a/Software/MainBoard/rust/src/plant_state.rs b/Software/MainBoard/rust/src/plant_state.rs index 23ef170..b4d2cca 100644 --- a/Software/MainBoard/rust/src/plant_state.rs +++ b/Software/MainBoard/rust/src/plant_state.rs @@ -120,8 +120,8 @@ impl PlantState { let raw = moistures.sensor_a_hz[plant_id]; match map_range_moisture( raw, - board.board_hal.get_config().plants[plant_id].moisture_sensor_min_frequency, - board.board_hal.get_config().plants[plant_id].moisture_sensor_max_frequency, + 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, @@ -137,8 +137,8 @@ impl PlantState { let raw = moistures.sensor_b_hz[plant_id]; match map_range_moisture( raw, - board.board_hal.get_config().plants[plant_id].moisture_sensor_min_frequency, - board.board_hal.get_config().plants[plant_id].moisture_sensor_max_frequency, + 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, @@ -186,7 +186,7 @@ impl PlantState { pub fn plant_moisture( &self, ) -> ( - Option, + Option, (Option<&MoistureSensorError>, Option<&MoistureSensorError>), ) { match ( @@ -194,10 +194,10 @@ impl PlantState { self.sensor_b.moisture_percent(), ) { (Some(moisture_a), Some(moisture_b)) => { - (Some((moisture_a + moisture_b) / 2.), (None, None)) + (Some(((moisture_a + moisture_b) / 2.) as u8), (None, None)) } - (Some(moisture_percent), _) => (Some(moisture_percent), (None, self.sensor_b.is_err())), - (_, Some(moisture_percent)) => (Some(moisture_percent), (self.sensor_a.is_err(), None)), + (Some(moisture_percent), _) => (Some(moisture_percent as u8), (None, self.sensor_b.is_err())), + (_, Some(moisture_percent)) => (Some(moisture_percent as u8), (self.sensor_a.is_err(), None)), _ => (None, (self.sensor_a.is_err(), self.sensor_b.is_err())), } } diff --git a/Software/MainBoard/rust/src_webpack/package-lock.json b/Software/MainBoard/rust/src_webpack/package-lock.json index 26340b5..46ef213 100644 --- a/Software/MainBoard/rust/src_webpack/package-lock.json +++ b/Software/MainBoard/rust/src_webpack/package-lock.json @@ -707,6 +707,7 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -731,6 +732,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -957,6 +959,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "baseline-browser-mapping": "^2.8.3", "caniuse-lite": "^1.0.30001741", @@ -2274,6 +2277,7 @@ "integrity": "sha512-V/PZeWsqhfpE27nKeX9EO2sbR+D17A+tLf6qU+ht66jdUsN0QLKJN27Z+1+gHrVMKgndBahes0PU6rRihDgHTw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/html-minifier-terser": "^6.0.0", "html-minifier-terser": "^6.0.2", @@ -3380,6 +3384,7 @@ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -4338,7 +4343,8 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "dev": true, - "license": "0BSD" + "license": "0BSD", + "peer": true }, "node_modules/type-is": { "version": "1.6.18", @@ -4360,6 +4366,7 @@ "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -4508,6 +4515,7 @@ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.101.3.tgz", "integrity": "sha512-7b0dTKR3Ed//AD/6kkx/o7duS8H3f1a4w3BYpIriX4BzIhjkn4teo05cptsxvLesHFKK5KObnadmCHBwGc+51A==", "license": "MIT", + "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.8", @@ -4557,6 +4565,7 @@ "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@discoveryjs/json-ext": "^0.5.0", "@webpack-cli/configtest": "^2.1.1", diff --git a/Software/MainBoard/rust/src_webpack/src/api.ts b/Software/MainBoard/rust/src_webpack/src/api.ts index 287f8be..52261bc 100644 --- a/Software/MainBoard/rust/src_webpack/src/api.ts +++ b/Software/MainBoard/rust/src_webpack/src/api.ts @@ -112,6 +112,7 @@ export interface PlantConfig { pump_cooldown_min: number, pump_hour_start: number, pump_hour_end: number, + pump_limit_ml: number, sensor_a: boolean, sensor_b: boolean, max_consecutive_pump_count: number, diff --git a/Software/MainBoard/rust/src_webpack/src/main.ts b/Software/MainBoard/rust/src_webpack/src/main.ts index e8a4f41..5b0bac5 100644 --- a/Software/MainBoard/rust/src_webpack/src/main.ts +++ b/Software/MainBoard/rust/src_webpack/src/main.ts @@ -296,6 +296,7 @@ export class Controller { configChanged() { const current = controller.getConfig(); var pretty = JSON.stringify(current, undefined, 0); + controller.submitView.setJson(pretty); diff --git a/Software/MainBoard/rust/src_webpack/src/plant.html b/Software/MainBoard/rust/src_webpack/src/plant.html index 230838e..cd07cc5 100644 --- a/Software/MainBoard/rust/src_webpack/src/plant.html +++ b/Software/MainBoard/rust/src_webpack/src/plant.html @@ -53,7 +53,7 @@ Mode: