remove: eliminate MoistureSensorState::Disabled, simplify moisture sensor processing, refactor pump logic, and clean up redundant/unnecessary code

This commit is contained in:
2026-03-12 20:36:18 +01:00
parent 5c78495bd5
commit a4d764c4fe
10 changed files with 145 additions and 144 deletions

View File

@@ -323,13 +323,12 @@ impl From<sntpc::Error> for FatError {
} }
} }
impl From<BmsProtocolError> for FatError {
impl From<BmsProtocolError> for FatError{
fn from(value: BmsProtocolError) -> Self { fn from(value: BmsProtocolError) -> Self {
match value { match value {
BmsProtocolError::I2cCommunicationError => { BmsProtocolError::I2cCommunicationError => FatError::String {
FatError::String{error: "I2C communication error".to_string()} error: "I2C communication error".to_string(),
} },
} }
} }
} }

View File

@@ -1,11 +1,13 @@
use crate::hal::Box;
use crate::fat_error::{FatError, FatResult}; use crate::fat_error::{FatError, FatResult};
use crate::hal::Box;
use async_trait::async_trait; use async_trait::async_trait;
use embassy_embedded_hal::shared_bus::blocking::i2c::I2cDevice; use embassy_embedded_hal::shared_bus::blocking::i2c::I2cDevice;
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
use esp_hal::i2c::master::I2c; use esp_hal::i2c::master::I2c;
use esp_hal::Blocking; use esp_hal::Blocking;
use lib_bms_protocol::{BatteryState as bstate, BmsReadable, Config, FirmwareVersion, ProtocolVersion}; use lib_bms_protocol::{
BatteryState as bstate, BmsReadable, Config, FirmwareVersion, ProtocolVersion,
};
use serde::Serialize; use serde::Serialize;
#[async_trait(?Send)] #[async_trait(?Send)]
@@ -59,18 +61,17 @@ impl BatteryInteraction for NoBatteryMonitor {
pub struct WchI2cSlave {} pub struct WchI2cSlave {}
pub struct WCHI2CSlave<'a> { pub struct WCHI2CSlave<'a> {
pub(crate) i2c: I2cDevice<'a, CriticalSectionRawMutex, I2c<'a, Blocking>> pub(crate) i2c: I2cDevice<'a, CriticalSectionRawMutex, I2c<'a, Blocking>>,
} }
#[async_trait(?Send)] #[async_trait(?Send)]
impl BatteryInteraction for WCHI2CSlave<'_> { impl BatteryInteraction for WCHI2CSlave<'_> {
async fn get_state(&mut self) -> FatResult<BatteryState> { async fn get_state(&mut self) -> FatResult<BatteryState> {
let state = bstate::read_from_i2c(&mut self.i2c)?; let state = bstate::read_from_i2c(&mut self.i2c)?;
let config = Config::read_from_i2c(&mut self.i2c)?; let config = Config::read_from_i2c(&mut self.i2c)?;
let state_of_charge = (state.remaining_capacity_mah * 100 / state.lifetime_capacity_mah) as u8; let state_of_charge =
(state.remaining_capacity_mah * 100 / state.lifetime_capacity_mah) as u8;
let state_of_health = state.lifetime_capacity_mah / config.capacity_mah * 100; let state_of_health = state.lifetime_capacity_mah / config.capacity_mah * 100;
Ok(BatteryState::Info(BatteryInfo { Ok(BatteryState::Info(BatteryInfo {
@@ -95,4 +96,4 @@ impl BatteryInteraction for WCHI2CSlave<'_> {
async fn reset(&mut self) -> FatResult<()> { async fn reset(&mut self) -> FatResult<()> {
todo!() todo!()
} }
} }

View File

@@ -25,7 +25,6 @@ use embedded_storage::nor_flash::{check_erase, NorFlash, ReadNorFlash};
use esp_bootloader_esp_idf::ota::OtaImageState::Valid; use esp_bootloader_esp_idf::ota::OtaImageState::Valid;
use esp_bootloader_esp_idf::ota::{Ota, OtaImageState}; use esp_bootloader_esp_idf::ota::{Ota, OtaImageState};
use esp_bootloader_esp_idf::partitions::{AppPartitionSubType, FlashRegion}; use esp_bootloader_esp_idf::partitions::{AppPartitionSubType, FlashRegion};
use esp_hal::Blocking;
use esp_hal::gpio::{Input, RtcPinWithResistors}; use esp_hal::gpio::{Input, RtcPinWithResistors};
use esp_hal::rng::Rng; use esp_hal::rng::Rng;
use esp_hal::rtc_cntl::{ use esp_hal::rtc_cntl::{
@@ -34,6 +33,7 @@ use esp_hal::rtc_cntl::{
}; };
use esp_hal::system::software_reset; use esp_hal::system::software_reset;
use esp_hal::uart::Uart; use esp_hal::uart::Uart;
use esp_hal::Blocking;
use esp_println::println; use esp_println::println;
use esp_radio::wifi::{ use esp_radio::wifi::{
AccessPointConfig, AccessPointInfo, AuthMethod, ClientConfig, ModeConfig, ScanConfig, AccessPointConfig, AccessPointInfo, AuthMethod, ClientConfig, ModeConfig, ScanConfig,
@@ -155,7 +155,6 @@ macro_rules! mk_static {
} }
impl Esp<'_> { impl Esp<'_> {
pub(crate) async fn read_serial_line(&mut self) -> FatResult<Option<alloc::string::String>> { pub(crate) async fn read_serial_line(&mut self) -> FatResult<Option<alloc::string::String>> {
let mut buf = [0u8; 1]; let mut buf = [0u8; 1];
let mut line = String::new(); let mut line = String::new();
@@ -171,7 +170,7 @@ impl Esp<'_> {
} }
line.push(c); line.push(c);
} }
Err(error ) => { Err(error) => {
if line.is_empty() { if line.is_empty() {
return Ok(None); return Ok(None);
} else { } else {

View File

@@ -1,5 +1,5 @@
use esp_hal::uart::Config as UartConfig;
use lib_bms_protocol::BmsReadable; use lib_bms_protocol::BmsReadable;
use esp_hal::uart::{Config as UartConfig};
pub(crate) mod battery; pub(crate) mod battery;
// mod can_api; // replaced by external canapi crate // mod can_api; // replaced by external canapi crate
pub mod esp; pub mod esp;
@@ -9,7 +9,6 @@ mod shared_flash;
mod v4_hal; mod v4_hal;
mod water; mod water;
use lib_bms_protocol::ProtocolVersion;
use crate::alloc::string::ToString; use crate::alloc::string::ToString;
use crate::hal::rtc::{DS3231Module, RTCModuleInteraction}; use crate::hal::rtc::{DS3231Module, RTCModuleInteraction};
use esp_hal::peripherals::Peripherals; use esp_hal::peripherals::Peripherals;
@@ -36,6 +35,7 @@ use esp_hal::peripherals::GPIO6;
use esp_hal::peripherals::GPIO7; use esp_hal::peripherals::GPIO7;
use esp_hal::peripherals::GPIO8; use esp_hal::peripherals::GPIO8;
use esp_hal::peripherals::TWAI0; use esp_hal::peripherals::TWAI0;
use lib_bms_protocol::ProtocolVersion;
use crate::{ use crate::{
bail, bail,
@@ -73,7 +73,7 @@ use esp_hal::gpio::{Input, InputConfig, Pull};
use measurements::{Current, Voltage}; use measurements::{Current, Voltage};
use crate::fat_error::{ContextExt, FatError, FatResult}; use crate::fat_error::{ContextExt, FatError, FatResult};
use crate::hal::battery::{WCHI2CSlave}; use crate::hal::battery::WCHI2CSlave;
use crate::hal::little_fs2storage_adapter::LittleFs2Filesystem; use crate::hal::little_fs2storage_adapter::LittleFs2Filesystem;
use crate::hal::water::TankSensor; use crate::hal::water::TankSensor;
use crate::log::LOG_ACCESS; use crate::log::LOG_ACCESS;
@@ -93,8 +93,8 @@ use esp_hal::rtc_cntl::{Rtc, SocResetReason};
use esp_hal::system::reset_reason; use esp_hal::system::reset_reason;
use esp_hal::time::Rate; use esp_hal::time::Rate;
use esp_hal::timer::timg::TimerGroup; use esp_hal::timer::timg::TimerGroup;
use esp_hal::Blocking;
use esp_hal::uart::Uart; use esp_hal::uart::Uart;
use esp_hal::Blocking;
use esp_radio::{init, Controller}; use esp_radio::{init, Controller};
use esp_storage::FlashStorage; use esp_storage::FlashStorage;
use littlefs2::fs::{Allocation, Filesystem as lfs2Filesystem}; use littlefs2::fs::{Allocation, Filesystem as lfs2Filesystem};
@@ -141,7 +141,6 @@ pub struct HAL<'a> {
pub struct DetectionRequest { pub struct DetectionRequest {
pub sensorsa: [Sensor; PLANT_COUNT], pub sensorsa: [Sensor; PLANT_COUNT],
pub sensorsb: [Sensor; PLANT_COUNT], pub sensorsb: [Sensor; PLANT_COUNT],
} }
#[async_trait(?Send)] #[async_trait(?Send)]
@@ -169,9 +168,7 @@ pub trait BoardInteraction<'a> {
async fn can_power(&mut self, state: bool) -> FatResult<()>; async fn can_power(&mut self, state: bool) -> FatResult<()>;
// Return JSON string with autodetected sensors per plant. Default: not supported. // Return JSON string with autodetected sensors per plant. Default: not supported.
async fn detect_sensors(&mut self, request: Detection) -> FatResult<Detection> { async fn detect_sensors(&mut self, request: Detection) -> FatResult<Detection>;
bail!("Autodetection is only available on v4 HAL with CAN bus");
}
async fn progress(&mut self, counter: u32) { async fn progress(&mut self, counter: u32) {
// Indicate progress is active to suppress default wait_infinity blinking // Indicate progress is active to suppress default wait_infinity blinking
@@ -401,8 +398,8 @@ impl PlantHal {
lfs2Filesystem::mount(alloc, lfs2filesystem).expect("Could not mount lfs2 filesystem"), lfs2Filesystem::mount(alloc, lfs2filesystem).expect("Could not mount lfs2 filesystem"),
)); ));
let uart0 = Uart::new(peripherals.UART0, UartConfig::default()) let uart0 =
.map_err(|_| FatError::String { Uart::new(peripherals.UART0, UartConfig::default()).map_err(|_| FatError::String {
error: "Uart creation failed".to_string(), error: "Uart creation failed".to_string(),
})?; })?;
@@ -421,7 +418,7 @@ impl PlantHal {
current: running, current: running,
slot0_state: state_0, slot0_state: state_0,
slot1_state: state_1, slot1_state: state_1,
uart0 uart0,
}; };
//init,reset rtc memory depending on cause //init,reset rtc memory depending on cause
@@ -553,7 +550,7 @@ impl PlantHal {
//BoardVersion::V4 => { //BoardVersion::V4 => {
v4_hal::create_v4(free_pins, esp, config, battery_interaction, rtc_module) v4_hal::create_v4(free_pins, esp, config, battery_interaction, rtc_module)
.await?; .await?;
//} //}
//}; //};
HAL { board_hal } HAL { board_hal }
@@ -571,9 +568,14 @@ impl PlantHal {
) )
.await; .await;
HAL { HAL {
board_hal: v4_hal::create_v4(free_pins, esp, PlantControllerConfig::default(), board_hal: v4_hal::create_v4(
Box::new(NoBatteryMonitor {}), rtc_module) free_pins,
.await? esp,
PlantControllerConfig::default(),
Box::new(NoBatteryMonitor {}),
rtc_module,
)
.await?,
} }
} }
}; };
@@ -699,4 +701,3 @@ pub struct DetectionSensorResult {
sensor_a: bool, sensor_a: bool,
sensor_b: bool, sensor_b: bool,
} }

View File

@@ -11,7 +11,7 @@ use crate::hal::{
}; };
use crate::log::{LogMessage, LOG_ACCESS}; use crate::log::{LogMessage, LOG_ACCESS};
use alloc::boxed::Box; use alloc::boxed::Box;
use alloc::string::{ToString}; use alloc::string::ToString;
use async_trait::async_trait; use async_trait::async_trait;
use canapi::id::{classify, plant_id, MessageKind, IDENTIFY_CMD_OFFSET}; use canapi::id::{classify, plant_id, MessageKind, IDENTIFY_CMD_OFFSET};
use canapi::SensorSlot; use canapi::SensorSlot;
@@ -133,10 +133,9 @@ pub struct V4<'a> {
extra1: Output<'a>, extra1: Output<'a>,
extra2: Output<'a>, extra2: Output<'a>,
twai_config: Option<TwaiConfiguration<'static, Blocking>> twai_config: Option<TwaiConfiguration<'static, Blocking>>,
} }
pub(crate) async fn create_v4( pub(crate) async fn create_v4(
peripherals: FreePeripherals<'static>, peripherals: FreePeripherals<'static>,
esp: Esp<'static>, esp: Esp<'static>,
@@ -263,12 +262,11 @@ pub(crate) async fn create_v4(
extra1, extra1,
extra2, extra2,
can_power, can_power,
twai_config twai_config,
}; };
Ok(Box::new(v)) Ok(Box::new(v))
} }
#[async_trait(?Send)] #[async_trait(?Send)]
impl<'a> BoardInteraction<'a> for V4<'a> { impl<'a> BoardInteraction<'a> for V4<'a> {
fn get_tank_sensor(&mut self) -> Result<&mut TankSensor<'a>, FatError> { fn get_tank_sensor(&mut self) -> Result<&mut TankSensor<'a>, FatError> {
@@ -395,11 +393,18 @@ impl<'a> BoardInteraction<'a> for V4<'a> {
if !detect { if !detect {
continue; continue;
} }
let target = let target = StandardId::new(plant_id(
StandardId::new(plant_id(IDENTIFY_CMD_OFFSET, sensor.into(), (plant +1) as u16)) IDENTIFY_CMD_OFFSET,
.context(">> Could not create address for sensor! (plant: {}) <<")?; sensor.into(),
(plant + 1) as u16,
))
.context(">> Could not create address for sensor! (plant: {}) <<")?;
let can_buffer = [0_u8; 0]; let can_buffer = [0_u8; 0];
info!("Sending test message to plant {} sensor {sensor:?} with id {}", plant +1, target.as_raw()); info!(
"Sending test message to plant {} sensor {sensor:?} with id {}",
plant + 1,
target.as_raw()
);
if let Some(frame) = EspTwaiFrame::new(target, &can_buffer) { if let Some(frame) = EspTwaiFrame::new(target, &can_buffer) {
// Try a few times; we intentionally ignore rx here and rely on stub logic // Try a few times; we intentionally ignore rx here and rely on stub logic
let resu = twai let resu = twai
@@ -407,12 +412,12 @@ impl<'a> BoardInteraction<'a> for V4<'a> {
.with_timeout(Duration::from_millis(3000)) .with_timeout(Duration::from_millis(3000))
.await; .await;
match resu { match resu {
Ok(_) => { Ok(_) => {}
}
Err(err) => { Err(err) => {
info!( info!(
"Error sending test message to plant {} sensor {sensor:?}: {err:?}", plant +1 "Error sending test message to plant {} sensor {sensor:?}: {err:?}",
); plant + 1
);
} }
} }
} else { } else {
@@ -426,20 +431,17 @@ impl<'a> BoardInteraction<'a> for V4<'a> {
.with_timeout(Duration::from_millis(3000)) .with_timeout(Duration::from_millis(3000))
.await; .await;
let config = twai.stop().into_blocking(); let config = twai.stop().into_blocking();
self.twai_config.replace(config); self.twai_config.replace(config);
self.can_power.set_low(); self.can_power.set_low();
let result = moistures.into(); let result = moistures.into();
info!("Autodetection result: {result:?}"); info!("Autodetection result: {result:?}");
Ok(result) Ok(result)
} }
async fn general_fault(&mut self, enable: bool) { async fn general_fault(&mut self, enable: bool) {
hold_disable(23); hold_disable(23);
self.general_fault.set_level(enable.into()); self.general_fault.set_level(enable.into());
@@ -482,7 +484,7 @@ impl<'a> BoardInteraction<'a> for V4<'a> {
LOG_ACCESS LOG_ACCESS
.lock() .lock()
.await .await
.log(LogMessage::TestSensor, a, b, &(plant+1).to_string(), "") .log(LogMessage::TestSensor, a, b, &(plant + 1).to_string(), "")
.await; .await;
} }
Timer::after_millis(10).await; Timer::after_millis(10).await;
@@ -511,7 +513,6 @@ impl<'a> BoardInteraction<'a> for V4<'a> {
} }
} }
async fn wait_for_can_measurements( async fn wait_for_can_measurements(
as_async: &mut Twai<'_, Async>, as_async: &mut Twai<'_, Async>,
moistures: &mut Moistures, moistures: &mut Moistures,
@@ -538,10 +539,12 @@ async fn wait_for_can_measurements(
let frequency = u32::from_be_bytes(bytes); let frequency = u32::from_be_bytes(bytes);
match sensor { match sensor {
SensorSlot::A => { SensorSlot::A => {
moistures.sensor_a_hz[plant-1] = Some(frequency as f32); moistures.sensor_a_hz[plant - 1] =
Some(frequency as f32);
} }
SensorSlot::B => { SensorSlot::B => {
moistures.sensor_b_hz[plant-1] = Some(frequency as f32); moistures.sensor_b_hz[plant - 1] =
Some(frequency as f32);
} }
} }
} else { } else {

View File

@@ -29,8 +29,8 @@ use ::log::{error, info, warn};
use alloc::borrow::ToOwned; use alloc::borrow::ToOwned;
use alloc::string::{String, ToString}; use alloc::string::{String, ToString};
use alloc::sync::Arc; use alloc::sync::Arc;
use alloc::{format, vec};
use alloc::vec::Vec; use alloc::vec::Vec;
use alloc::{format, vec};
use chrono::{DateTime, Datelike, Timelike, Utc}; use chrono::{DateTime, Datelike, Timelike, Utc};
use chrono_tz::Tz::{self, UTC}; use chrono_tz::Tz::{self, UTC};
use core::sync::atomic::{AtomicBool, Ordering}; use core::sync::atomic::{AtomicBool, Ordering};
@@ -501,16 +501,17 @@ async fn safe_main(spawner: Spawner) -> FatResult<()> {
info!("state of charg"); info!("state of charg");
let is_day = board.board_hal.is_day(); let is_day = board.board_hal.is_day();
let battery_state = board.board_hal.get_battery_monitor().get_state().await.unwrap_or(BatteryState::Unknown); let battery_state = board
.board_hal
.get_battery_monitor()
.get_state()
.await
.unwrap_or(BatteryState::Unknown);
info!("Battery state is {battery_state:?}"); info!("Battery state is {battery_state:?}");
let state_of_charge = match &battery_state { let state_of_charge = match &battery_state {
BatteryState::Unknown => { BatteryState::Unknown => 0,
0 BatteryState::Info(data) => data.state_of_charge,
}
BatteryState::Info(data) => {
data.state_of_charge
}
}; };
let mut light_state = LightState { let mut light_state = LightState {
@@ -529,22 +530,10 @@ async fn safe_main(spawner: Spawner) -> FatResult<()> {
board.board_hal.get_config().night_lamp.night_lamp_hour_end, board.board_hal.get_config().night_lamp.night_lamp_hour_end,
); );
if state_of_charge if state_of_charge < board.board_hal.get_config().night_lamp.low_soc_cutoff {
< board
.board_hal
.get_config()
.night_lamp
.low_soc_cutoff
{
board.board_hal.get_esp().set_low_voltage_in_cycle(); board.board_hal.get_esp().set_low_voltage_in_cycle();
info!("Set low voltage in cycle"); info!("Set low voltage in cycle");
} else if state_of_charge } else if state_of_charge > board.board_hal.get_config().night_lamp.low_soc_restore {
> board
.board_hal
.get_config()
.night_lamp
.low_soc_restore
{
board.board_hal.get_esp().clear_low_voltage_in_cycle(); board.board_hal.get_esp().clear_low_voltage_in_cycle();
info!("Clear low voltage in cycle"); info!("Clear low voltage in cycle");
} }
@@ -652,17 +641,23 @@ pub async fn do_secure_pump(
plant_config: &PlantConfig, plant_config: &PlantConfig,
dry_run: bool, dry_run: bool,
) -> FatResult<PumpResult> { ) -> FatResult<PumpResult> {
let mut current_collector = vec![0_u16; plant_config.pump_time_s.into()]; const STARTUP_IGNORE_MS: u32 = 500;
let mut flow_collector = vec![0_i16; plant_config.pump_time_s.into()]; const STARTUP_ABORT_CURRENT_MA: u16 = 1500;
let steps_in_50ms = plant_config.pump_time_s as usize * 20;
let mut current_collector = vec![0_u16; steps_in_50ms];
let mut flow_collector = vec![0_i16; steps_in_50ms];
let mut error = false; let mut error = false;
let mut first_error = true; let mut first_error = true;
let mut pump_time_s = 0; let mut pump_time_ms: u32 = 0;
if !dry_run { if !dry_run {
board.board_hal.get_tank_sensor()?.reset_flow_meter(); board.board_hal.get_tank_sensor()?.reset_flow_meter();
board.board_hal.get_tank_sensor()?.start_flow_meter(); board.board_hal.get_tank_sensor()?.start_flow_meter();
board.board_hal.pump(plant_id, true).await?; board.board_hal.pump(plant_id, true).await?;
Timer::after_millis(10).await;
for step in 0..plant_config.pump_time_s as usize { for step in 0..steps_in_50ms {
let flow_value = board.board_hal.get_tank_sensor()?.get_flow_meter_value(); let flow_value = board.board_hal.get_tank_sensor()?.get_flow_meter_value();
flow_collector[step] = flow_value; flow_collector[step] = flow_value;
let flow_value_ml = flow_value as f32 * board.board_hal.get_config().tank.ml_per_pulse; let flow_value_ml = flow_value as f32 * board.board_hal.get_config().tank.ml_per_pulse;
@@ -682,7 +677,20 @@ pub async fn do_secure_pump(
let current_ma = current.as_milliamperes() as u16; let current_ma = current.as_milliamperes() as u16;
current_collector[step] = current_ma; current_collector[step] = current_ma;
let high_current = current_ma > plant_config.max_pump_current_ma; let high_current = current_ma > plant_config.max_pump_current_ma;
if high_current && first_error { if pump_time_ms < STARTUP_IGNORE_MS
&& high_current
&& current_ma > STARTUP_ABORT_CURRENT_MA
{
log(
LogMessage::PumpOverCurrent,
plant_id as u32 + 1,
current_ma as u32,
plant_config.max_pump_current_ma.to_string().as_str(),
step.to_string().as_str(),
)
.await;
error = true;
} else if high_current && first_error {
log( log(
LogMessage::PumpOverCurrent, LogMessage::PumpOverCurrent,
plant_id as u32 + 1, plant_id as u32 + 1,
@@ -732,12 +740,14 @@ pub async fn do_secure_pump(
error = true; error = true;
break; break;
} else { } else {
//e.g., v3 without a sensor ends here, do not spam error!("Error getting pump current: {err}");
} }
} }
} }
Timer::after_millis(1000).await;
pump_time_s += 1; //todo calcualte dynamically to offset time for stuff
Timer::after_millis(50).await;
pump_time_ms += 50;
} }
} }
board.board_hal.get_tank_sensor()?.stop_flow_meter(); board.board_hal.get_tank_sensor()?.stop_flow_meter();
@@ -751,14 +761,14 @@ pub async fn do_secure_pump(
min_current_ma: current_collector[0], min_current_ma: current_collector[0],
flow_value_ml, flow_value_ml,
flow_value_count: final_flow_value, flow_value_count: final_flow_value,
pump_time_s, pump_time_s: (pump_time_ms / 1000) as u16,
error, error,
}) })
} }
async fn update_charge_indicator( async fn update_charge_indicator(
board: &mut MutexGuard<'static, CriticalSectionRawMutex, HAL<'static>>, board: &mut MutexGuard<'static, CriticalSectionRawMutex, HAL<'static>>,
) -> FatResult<()>{ ) -> FatResult<()> {
//FIXME add config and code to allow power supply mode, in this case this is a nop //FIXME add config and code to allow power supply mode, in this case this is a nop
//we have mppt controller, ask it for charging current //we have mppt controller, ask it for charging current
let current = board.board_hal.get_mptt_current().await?; let current = board.board_hal.get_mptt_current().await?;
@@ -766,10 +776,9 @@ async fn update_charge_indicator(
.board_hal .board_hal
.set_charge_indicator(current.as_milliamperes() > 20_f64) .set_charge_indicator(current.as_milliamperes() > 20_f64)
.await?; .await?;
Ok(()) Ok(())
} }
async fn publish_tank_state( async fn publish_tank_state(
board: &mut MutexGuard<'_, CriticalSectionRawMutex, HAL<'static>>, board: &mut MutexGuard<'_, CriticalSectionRawMutex, HAL<'static>>,
tank_state: &TankState, tank_state: &TankState,
@@ -949,11 +958,7 @@ async fn publish_mppt_state(
async fn publish_battery_state( async fn publish_battery_state(
board: &mut MutexGuard<'_, CriticalSectionRawMutex, HAL<'static>>, board: &mut MutexGuard<'_, CriticalSectionRawMutex, HAL<'static>>,
) -> () { ) -> () {
let state = board let state = board.board_hal.get_battery_monitor().get_state().await;
.board_hal
.get_battery_monitor()
.get_state()
.await;
let value = match state { let value = match state {
Ok(state) => { Ok(state) => {
let json = serde_json::to_string(&state).unwrap().to_owned(); let json = serde_json::to_string(&state).unwrap().to_owned();
@@ -986,7 +991,7 @@ async fn wait_infinity(
loop { loop {
{ {
let mut board = BOARD_ACCESS.get().await.lock().await; let mut board = BOARD_ACCESS.get().await.lock().await;
match update_charge_indicator(&mut board).await{ match update_charge_indicator(&mut board).await {
Ok(_) => {} Ok(_) => {}
Err(error) => { Err(error) => {
if !suppress_further_mppt_error { if !suppress_further_mppt_error {
@@ -1069,35 +1074,38 @@ async fn wait_infinity(
} }
} }
async fn handle_serial_config(board: &mut MutexGuard<'_, CriticalSectionRawMutex, HAL<'_>>, serial_config_receive: &AtomicBool, reboot_now: &AtomicBool) -> FatResult<()> { async fn handle_serial_config(
board: &mut MutexGuard<'_, CriticalSectionRawMutex, HAL<'_>>,
serial_config_receive: &AtomicBool,
reboot_now: &AtomicBool,
) -> FatResult<()> {
match board.board_hal.get_esp().read_serial_line().await { match board.board_hal.get_esp().read_serial_line().await {
Ok(serial_line) => { Ok(serial_line) => match serial_line {
match serial_line { None => Ok(()),
None => { Some(line) => {
if serial_config_receive.load(Ordering::Relaxed) {
let ll = line.as_str();
let config: PlantControllerConfig = serde_json::from_str(ll)?;
board
.board_hal
.get_esp()
.save_config(Vec::from(ll.as_bytes()))
.await?;
board.board_hal.set_config(config);
serial_config_receive.store(false, Ordering::Relaxed);
info!("Config received, rebooting");
board.board_hal.get_esp().set_restart_to_conf(false);
reboot_now.store(true, Ordering::Relaxed);
Ok(())
} else {
if line == "automation:streamconfig" {
serial_config_receive.store(true, Ordering::Relaxed);
info!("streamconfig:recieving");
}
Ok(()) Ok(())
} }
Some(line) => {
if serial_config_receive.load(Ordering::Relaxed) {
let ll = line.as_str();
let config: PlantControllerConfig = serde_json::from_str(ll)?;
board.board_hal.get_esp().save_config(Vec::from(ll.as_bytes())).await?;
board.board_hal.set_config(config);
serial_config_receive.store(false, Ordering::Relaxed);
info!("Config received, rebooting");
board.board_hal.get_esp().set_restart_to_conf(false);
reboot_now.store(true, Ordering::Relaxed);
Ok(())
} else {
if line == "automation:streamconfig" {
serial_config_receive.store(true, Ordering::Relaxed);
info!("streamconfig:recieving");
}
Ok(())
}
}
} }
} },
Err(_) => { Err(_) => {
error!("Error reading serial line"); error!("Error reading serial line");
Ok(()) Ok(())

View File

@@ -16,7 +16,6 @@ pub enum MoistureSensorError {
#[derive(Debug, PartialEq, Serialize)] #[derive(Debug, PartialEq, Serialize)]
pub enum MoistureSensorState { pub enum MoistureSensorState {
Disabled,
MoistureValue { raw_hz: f32, moisture_percent: f32 }, MoistureValue { raw_hz: f32, moisture_percent: f32 },
SensorError(MoistureSensorError), SensorError(MoistureSensorError),
} }
@@ -117,12 +116,11 @@ impl PlantState {
plant_id: usize, plant_id: usize,
board: &mut HAL<'_>, board: &mut HAL<'_>,
) -> Self { ) -> Self {
let sensor_a = { //if board.board_hal.get_config().plants[plant_id].sensor_a { let sensor_a = {
//if board.board_hal.get_config().plants[plant_id].sensor_a {
let raw = moistures.sensor_a_hz[plant_id]; let raw = moistures.sensor_a_hz[plant_id];
match raw { match raw {
None => { None => MoistureSensorState::SensorError(MoistureSensorError::NoMessage),
MoistureSensorState::SensorError(MoistureSensorError::NoMessage)
}
Some(raw) => { Some(raw) => {
match map_range_moisture( match map_range_moisture(
raw, raw,
@@ -141,17 +139,15 @@ impl PlantState {
} }
} }
} }
}; // else { }; // else {
// MoistureSensorState::Disabled // MoistureSensorState::Disabled
//}; //};
let sensor_b = { //if board.board_hal.get_config().plants[plant_id].sensor_b { let sensor_b = {
//if board.board_hal.get_config().plants[plant_id].sensor_b {
let raw = moistures.sensor_b_hz[plant_id]; let raw = moistures.sensor_b_hz[plant_id];
match raw { match raw {
None => { None => MoistureSensorState::SensorError(MoistureSensorError::NoMessage),
MoistureSensorState::SensorError(MoistureSensorError::NoMessage)
}
Some(raw) => { Some(raw) => {
match map_range_moisture( match map_range_moisture(
raw, raw,
@@ -171,8 +167,8 @@ impl PlantState {
} }
} }
}; // else { }; // else {
// MoistureSensorState::Disabled // MoistureSensorState::Disabled
//}; //};
let previous_pump = board.board_hal.get_esp().last_pump_time(plant_id); 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); let consecutive_pump_count = board.board_hal.get_esp().consecutive_pump_count(plant_id);

View File

@@ -43,7 +43,6 @@ where
plant_state.push(PlantState::read_hardware_state(moistures, i, &mut board).await); plant_state.push(PlantState::read_hardware_state(moistures, i, &mut board).await);
} }
let a = Vec::from_iter(plant_state.iter().map(|s| match &s.sensor_a { let a = Vec::from_iter(plant_state.iter().map(|s| match &s.sensor_a {
MoistureSensorState::Disabled => "disabled".to_string(),
MoistureSensorState::MoistureValue { MoistureSensorState::MoistureValue {
raw_hz, raw_hz,
moisture_percent, moisture_percent,
@@ -53,7 +52,6 @@ where
MoistureSensorState::SensorError(err) => format!("{err:?}"), MoistureSensorState::SensorError(err) => format!("{err:?}"),
})); }));
let b = Vec::from_iter(plant_state.iter().map(|s| match &s.sensor_b { let b = Vec::from_iter(plant_state.iter().map(|s| match &s.sensor_b {
MoistureSensorState::Disabled => "disabled".to_string(),
MoistureSensorState::MoistureValue { MoistureSensorState::MoistureValue {
raw_hz, raw_hz,
moisture_percent, moisture_percent,
@@ -128,11 +126,7 @@ pub(crate) async fn get_battery_state<T, const N: usize>(
_request: &mut Connection<'_, T, N>, _request: &mut Connection<'_, T, N>,
) -> FatResult<Option<String>> { ) -> FatResult<Option<String>> {
let mut board = BOARD_ACCESS.get().await.lock().await; let mut board = BOARD_ACCESS.get().await.lock().await;
let battery_state = board let battery_state = board.board_hal.get_battery_monitor().get_state().await?;
.board_hal
.get_battery_monitor()
.get_state()
.await?;
Ok(Some(serde_json::to_string(&battery_state)?)) Ok(Some(serde_json::to_string(&battery_state)?))
} }

View File

@@ -18,7 +18,10 @@ use crate::webserver::get_json::{
use crate::webserver::get_log::get_log; use crate::webserver::get_log::get_log;
use crate::webserver::get_static::{serve_bundle, serve_favicon, serve_index}; use crate::webserver::get_static::{serve_bundle, serve_favicon, serve_index};
use crate::webserver::ota::ota_operations; use crate::webserver::ota::ota_operations;
use crate::webserver::post_json::{board_test, can_power, detect_sensors, night_lamp_test, pump_test, set_config, wifi_scan, write_time}; use crate::webserver::post_json::{
board_test, can_power, detect_sensors, night_lamp_test, pump_test, set_config, wifi_scan,
write_time,
};
use crate::{bail, BOARD_ACCESS}; use crate::{bail, BOARD_ACCESS};
use alloc::borrow::ToOwned; use alloc::borrow::ToOwned;
use alloc::string::{String, ToString}; use alloc::string::{String, ToString};

View File

@@ -142,9 +142,6 @@ where
board.board_hal.can_power(can_power_request.state).await?; board.board_hal.can_power(can_power_request.state).await?;
let enable = can_power_request.state; let enable = can_power_request.state;
info!( info!("set can power to {enable}");
"set can power to {enable}"
);
Ok(None) Ok(None)
} }