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

@@ -1,11 +1,13 @@
use crate::hal::Box;
use crate::fat_error::{FatError, FatResult};
use crate::hal::Box;
use async_trait::async_trait;
use embassy_embedded_hal::shared_bus::blocking::i2c::I2cDevice;
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
use esp_hal::i2c::master::I2c;
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;
#[async_trait(?Send)]
@@ -59,18 +61,17 @@ impl BatteryInteraction for NoBatteryMonitor {
pub struct WchI2cSlave {}
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)]
impl BatteryInteraction for WCHI2CSlave<'_> {
async fn get_state(&mut self) -> FatResult<BatteryState> {
let state = bstate::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;
Ok(BatteryState::Info(BatteryInfo {
@@ -95,4 +96,4 @@ impl BatteryInteraction for WCHI2CSlave<'_> {
async fn reset(&mut self) -> FatResult<()> {
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::{Ota, OtaImageState};
use esp_bootloader_esp_idf::partitions::{AppPartitionSubType, FlashRegion};
use esp_hal::Blocking;
use esp_hal::gpio::{Input, RtcPinWithResistors};
use esp_hal::rng::Rng;
use esp_hal::rtc_cntl::{
@@ -34,6 +33,7 @@ use esp_hal::rtc_cntl::{
};
use esp_hal::system::software_reset;
use esp_hal::uart::Uart;
use esp_hal::Blocking;
use esp_println::println;
use esp_radio::wifi::{
AccessPointConfig, AccessPointInfo, AuthMethod, ClientConfig, ModeConfig, ScanConfig,
@@ -155,7 +155,6 @@ macro_rules! mk_static {
}
impl Esp<'_> {
pub(crate) async fn read_serial_line(&mut self) -> FatResult<Option<alloc::string::String>> {
let mut buf = [0u8; 1];
let mut line = String::new();
@@ -171,7 +170,7 @@ impl Esp<'_> {
}
line.push(c);
}
Err(error ) => {
Err(error) => {
if line.is_empty() {
return Ok(None);
} else {

View File

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

View File

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