add null board

This commit is contained in:
Empire Phoenix 2025-06-11 17:35:23 +02:00
parent 38f4ada433
commit a9d7936376
4 changed files with 118 additions and 40 deletions

View File

@ -184,7 +184,12 @@ fn safe_main() -> anyhow::Result<()> {
}
println!("cur is {}", cur);
board.update_charge_indicator();
match board.battery_monitor.average_current_milli_ampere() {
Ok(charging) => {
board.set_charge_indicator(charging > 20)
}
Err(_) => {}
}
if board.get_restart_to_conf() {
log(LogMessage::ConfigModeSoftwareOverride, 0, 0, "", "");
@ -362,12 +367,12 @@ fn safe_main() -> anyhow::Result<()> {
if pump_ineffective {
log(
LogMessage::ConsecutivePumpCountLimit,
pump_count as u32,
pump_count,
plant_config.max_consecutive_pump_count as u32,
&(plant_id+1).to_string(),
"",
);
board.fault(plant_id, true);
board.fault(plant_id, true)?;
}
log(
LogMessage::PumpPlant,
@ -638,28 +643,30 @@ fn wait_infinity(wait_type: WaitType, reboot_now: Arc<AtomicBool>) -> ! {
loop {
unsafe {
let mut lock = BOARD_ACCESS.lock().unwrap();
lock.update_charge_indicator();
if let Ok(charging) = lock.battery_monitor.average_current_milli_ampere() {
lock.set_charge_indicator(charging > 20)
}
match wait_type {
WaitType::MissingConfig => {
// Keep existing behavior: circular filling pattern
led_count %= 8;
led_count += 1;
for i in 0..8 {
lock.fault(i, i < led_count);
let _ = lock.fault(i, i < led_count);
}
}
WaitType::ConfigButton => {
// Alternating pattern: 1010 1010 -> 0101 0101
pattern_step = (pattern_step + 1) % 2;
for i in 0..8 {
lock.fault(i, (i + pattern_step) % 2 == 0);
let _ = lock.fault(i, (i + pattern_step) % 2 == 0);
}
}
WaitType::MqttConfig => {
// Moving dot pattern
pattern_step = (pattern_step + 1) % 8;
for i in 0..8 {
lock.fault(i, i == pattern_step);
let _ = lock.fault(i, i == pattern_step);
}
}
}
@ -672,7 +679,7 @@ fn wait_infinity(wait_type: WaitType, reboot_now: Arc<AtomicBool>) -> ! {
// Clear all LEDs
for i in 0..8 {
lock.fault(i, false);
let _ = lock.fault(i, false);
}
drop(lock);
vTaskDelay(delay);

View File

@ -63,7 +63,7 @@ use one_wire_bus::OneWire;
use crate::config::PlantControllerConfig;
use crate::log::log;
use crate::plant_hal::BoardHal::V3;
use crate::{to_string, STAY_ALIVE};
use crate::{plant_hal, to_string, STAY_ALIVE};
//Only support for 8 right now!
pub const PLANT_COUNT: usize = 8;
@ -167,6 +167,9 @@ pub struct HAL<'a>{
}
pub enum BatteryMonitor<'a> {
Disabled {
},
BQ34Z100G1 {
battery_driver: Bq34z100g1Driver<MutexDevice<'a, I2cDriver<'a>>, Delay>
},
@ -176,6 +179,9 @@ pub enum BatteryMonitor<'a> {
}
pub enum BoardHal<'a>{
Initial {
},
V3 {
shift_register: ShiftRegister40<
PinDriver<'a, esp_idf_hal::gpio::AnyIOPin, InputOutput>,
@ -269,6 +275,9 @@ impl BatteryInteraction for BatteryMonitor<'_> {
BatteryMonitor::WchI2cSlave { .. } => {
bail!("Not implemented")
}
BatteryMonitor::Disabled {} => {
bail!("Battery monitor is disabled")
}
}
}
@ -282,6 +291,9 @@ impl BatteryInteraction for BatteryMonitor<'_> {
},
BatteryMonitor::WchI2cSlave { .. } => {
bail!("Not implemented")
},
&mut BatteryMonitor::Disabled { } => {
bail!("Battery monitor is disabled")
}
}
}
@ -295,6 +307,9 @@ impl BatteryInteraction for BatteryMonitor<'_> {
},
BatteryMonitor::WchI2cSlave { .. } => {
bail!("Not implemented")
},
&mut BatteryMonitor::Disabled { } => {
bail!("Battery monitor is disabled")
}
}
}
@ -308,6 +323,9 @@ impl BatteryInteraction for BatteryMonitor<'_> {
},
BatteryMonitor::WchI2cSlave { .. } => {
bail!("Not implemented")
},
&mut BatteryMonitor::Disabled { } => {
bail!("Battery monitor is disabled")
}
}
}
@ -321,6 +339,9 @@ impl BatteryInteraction for BatteryMonitor<'_> {
},
BatteryMonitor::WchI2cSlave { .. } => {
bail!("Not implemented")
},
&mut BatteryMonitor::Disabled { } => {
bail!("Battery monitor is disabled")
}
}
}
@ -334,6 +355,9 @@ impl BatteryInteraction for BatteryMonitor<'_> {
},
BatteryMonitor::WchI2cSlave { .. } => {
bail!("Not implemented")
},
&mut BatteryMonitor::Disabled { } => {
bail!("Battery monitor is disabled")
}
}
}
@ -347,6 +371,9 @@ impl BatteryInteraction for BatteryMonitor<'_> {
},
BatteryMonitor::WchI2cSlave { .. } => {
bail!("Not implemented")
},
&mut BatteryMonitor::Disabled { } => {
bail!("Battery monitor is disabled")
}
}
}
@ -360,6 +387,9 @@ impl BatteryInteraction for BatteryMonitor<'_> {
},
BatteryMonitor::WchI2cSlave { .. } => {
bail!("Not implemented")
},
&mut BatteryMonitor::Disabled { } => {
bail!("Battery monitor is disabled")
}
}
}
@ -373,30 +403,26 @@ impl BatteryInteraction for BatteryMonitor<'_> {
},
BatteryMonitor::WchI2cSlave { .. } => {
bail!("Not implemented")
},
&mut BatteryMonitor::Disabled { } => {
bail!("Battery monitor is disabled")
}
}
}
}
impl BoardInteraction for HAL<'_> {
fn update_charge_indicator(&mut self) {
let is_charging = match &mut self.battery_monitor {
BatteryMonitor::BQ34Z100G1 { battery_driver, .. } => {
match battery_driver.average_current() {
OkStd(current) => current < 20,
Err(_) => false,
}
}
_ => false
};
fn set_charge_indicator(&mut self, charging: bool) {
match &mut self.board_hal {
BoardHal::V3 { shift_register, .. } => {
shift_register.decompose()[CHARGING]
.set_state(is_charging.into())
.set_state(charging.into())
.unwrap();
}
BoardHal::V4 { .. } => {}
BoardHal::V4 { .. } => {},
&mut plant_hal::BoardHal::Initial { } => {
}
}
}
fn deep_sleep(&mut self, duration_in_ms: u64) -> ! {
@ -404,7 +430,10 @@ impl BoardInteraction for HAL<'_> {
BoardHal::V3 { shift_register, .. } => {
shift_register.decompose()[AWAKE].set_low().unwrap();
}
BoardHal::V4 { .. } => {}
BoardHal::V4 { .. } => {},
&mut plant_hal::BoardHal::Initial { } => {
}
}
unsafe {
@ -426,7 +455,10 @@ impl BoardInteraction for HAL<'_> {
fn get_backup_info(&mut self) -> Result<BackupHeader> {
let eeprom = match &mut self.board_hal {
BoardHal::V3 { eeprom, .. } => {eeprom}
BoardHal::V4 { eeprom, .. } => {eeprom }
BoardHal::V4 { eeprom, .. } => {eeprom },
&mut plant_hal::BoardHal::Initial { } => {
bail!("Board not configured yet")
}
};
let dummy = BackupHeader {
timestamp: 0,
@ -448,6 +480,9 @@ impl BoardInteraction for HAL<'_> {
let eeprom = match &mut self.board_hal {
BoardHal::V3 { eeprom, .. } => {eeprom}
BoardHal::V4 { eeprom, .. } => {eeprom }
&mut plant_hal::BoardHal::Initial { } => {
bail!("Board not configured yet")
}
};
let dummy = BackupHeader {
@ -489,7 +524,10 @@ impl BoardInteraction for HAL<'_> {
V3 { eeprom, .. } => {
eeprom
}
BoardHal::V4 { eeprom, .. } => { eeprom }
BoardHal::V4 { eeprom, .. } => { eeprom },
&mut plant_hal::BoardHal::Initial { } => {
bail!("Board not configured yet")
}
};
let delay = Delay::new_default();
@ -530,6 +568,9 @@ impl BoardInteraction for HAL<'_> {
eeprom
}
BoardHal::V4 { eeprom, .. } => { eeprom }
&mut plant_hal::BoardHal::Initial { } => {
bail!("Board not configured yet")
}
};
match eeprom.write_page(address, chunk) {
OkStd(_) => {}
@ -642,6 +683,9 @@ impl BoardInteraction for HAL<'_> {
match & self.board_hal {
BoardHal::V3 { solar_is_day, .. } => {solar_is_day.get_level().into()}
BoardHal::V4 { solar_is_day, .. } => {solar_is_day.get_level().into() }
plant_hal::BoardHal::Initial {} => {
false
}
}
}
//should be multsampled
@ -679,6 +723,9 @@ impl BoardInteraction for HAL<'_> {
let (tank_power, tank_channel) = match &mut self.board_hal {
BoardHal::V3 { tank_power, tank_channel, .. } => {(tank_power,tank_channel)}
BoardHal::V4 { tank_power, tank_channel, .. } => {(tank_power,tank_channel) }
&mut plant_hal::BoardHal::Initial { } => {
bail!("Board not configured yet")
}
};
@ -711,7 +758,10 @@ impl BoardInteraction for HAL<'_> {
fn light(&mut self, enable: bool) -> Result<()> {
let light = match &mut self.board_hal {
BoardHal::V3 { light, .. } => light,
BoardHal::V4 { light, .. } => light
BoardHal::V4 { light, .. } => light,
&mut plant_hal::BoardHal::Initial { } => {
bail!("Board not configured yet")
}
};
unsafe { gpio_hold_dis(light.pin()) };
@ -736,7 +786,12 @@ impl BoardInteraction for HAL<'_> {
//currently infallible error, keep for future as result anyway
shift_register.decompose()[index].set_state(enable.into())?;
}
BoardHal::V4 { .. } => {}
BoardHal::V4 { .. } => {
bail!("Not yet implemented")
},
&plant_hal::BoardHal::Initial {} => {
bail!("Board not configured yet")
}
}
Ok(())
@ -758,7 +813,7 @@ impl BoardInteraction for HAL<'_> {
fn consecutive_pump_count(&mut self, plant: usize) -> u32 {
unsafe { CONSECUTIVE_WATERING_PLANT[plant] }
}
fn fault(& self, plant: usize, enable: bool) {
fn fault(& self, plant: usize, enable: bool) -> Result<()>{
match & self.board_hal {
V3 { shift_register, .. } => {
let index = match plant {
@ -773,11 +828,15 @@ impl BoardInteraction for HAL<'_> {
_ => panic!("Invalid plant id {}", plant),
};
shift_register.decompose()[index]
.set_state(enable.into())
.unwrap()
.set_state(enable.into())?;
Ok(())
}
BoardHal::V4 { .. } => {
bail!("Not yet implemented")
}
&plant_hal::BoardHal::Initial {} => {
bail!("Board not configured yet")
}
}
@ -794,6 +853,9 @@ impl BoardInteraction for HAL<'_> {
BoardHal::V4 { main_pump, .. } => {
main_pump.set_state(enable.into())?;
}
&mut plant_hal::BoardHal::Initial { } => {
bail!("Board not configured yet")
}
}
Ok(())
@ -922,7 +984,10 @@ impl BoardInteraction for HAL<'_> {
fn general_fault(&mut self, enable: bool) {
let general_fault = match &mut self.board_hal {
BoardHal::V3 { general_fault, .. } => {general_fault}
BoardHal::V4 { general_fault, .. } => {general_fault}
BoardHal::V4 { general_fault, .. } => {general_fault},
&mut plant_hal::BoardHal::Initial { } => {
return
}
};
unsafe { gpio_hold_dis(general_fault.pin()) };
general_fault.set_state(enable.into()).unwrap();
@ -1056,7 +1121,10 @@ impl BoardInteraction for HAL<'_> {
fn get_rtc_time(&mut self) -> Result<DateTime<Utc>> {
let rtc = match &mut self.board_hal {
BoardHal::V3 { rtc, .. } => {rtc}
BoardHal::V4 { rtc, .. } => {rtc}
BoardHal::V4 { rtc, .. } => {rtc},
&mut plant_hal::BoardHal::Initial { } => {
bail!("Board not configured yet")
}
};
match rtc.datetime() {
OkStd(rtc_time) => Ok(rtc_time.and_utc()),
@ -1069,6 +1137,9 @@ impl BoardInteraction for HAL<'_> {
let rtc = match &mut self.board_hal {
BoardHal::V3 { rtc, .. } => {rtc}
BoardHal::V4 { rtc, .. } => {rtc}
&mut plant_hal::BoardHal::Initial { } => {
bail!("Board not configured yet")
}
};
let naive_time = time.naive_utc();
match rtc.set_datetime(&naive_time) {
@ -1122,9 +1193,9 @@ impl BoardInteraction for HAL<'_> {
self.light(false)?;
unsafe { vTaskDelay(500) };
for i in 0..PLANT_COUNT {
self.fault(i, true);
self.fault(i, true)?;
unsafe { vTaskDelay(500) };
self.fault(i, false);
self.fault(i, false)?;
unsafe { vTaskDelay(500) };
}
for i in 0..PLANT_COUNT {
@ -1381,7 +1452,7 @@ pub trait BatteryInteraction {
}
pub trait BoardInteraction {
fn update_charge_indicator(&mut self);
fn set_charge_indicator(&mut self, charging: bool);
fn deep_sleep(&mut self, duration_in_ms: u64) -> !;
fn get_backup_info(&mut self) -> Result<BackupHeader>;
fn get_backup_config(&mut self) -> Result<Vec<u8>>;
@ -1403,7 +1474,7 @@ pub trait BoardInteraction {
fn store_last_pump_time(&mut self, plant: usize, time: DateTime<Utc>);
fn store_consecutive_pump_count(&mut self, plant: usize, count: u32);
fn consecutive_pump_count(&mut self, plant: usize) -> u32;
fn fault(&self, plant: usize, enable: bool);
fn fault(&self, plant: usize, enable: bool) -> Result<()>;
fn low_voltage_in_cycle(&mut self) -> bool;
fn any_pump(&mut self, enable: bool) -> Result<()>;
fn time(&mut self) -> Result<DateTime<Utc>>;

View File

@ -170,7 +170,7 @@ impl PlantState {
},
};
if state.is_err() {
board.fault(plant_id, true);
let _ = board.fault(plant_id, true);
}
state
}

View File

@ -328,7 +328,7 @@ fn ota(
let iter = (total_read / 1024) % 8;
if iter != lastiter {
for i in 0..PLANT_COUNT {
board.fault(i, iter == i);
let _ = board.fault(i, iter == i);
}
lastiter = iter;
}
@ -541,7 +541,7 @@ pub fn httpd(reboot_now: Arc<AtomicBool>) -> Box<EspHttpServer<'static>> {
let iter = (total_read / 1024) % 8;
if iter != lastiter {
for i in 0..PLANT_COUNT {
lock.fault(i, iter == i);
let _ = lock.fault(i, iter == i);
}
lastiter = iter;
}