diff --git a/rust/src/hal/initial_hal.rs b/rust/src/hal/initial_hal.rs index 9bed418..f11e416 100644 --- a/rust/src/hal/initial_hal.rs +++ b/rust/src/hal/initial_hal.rs @@ -32,7 +32,7 @@ pub(crate) fn create_initial_board( general_fault, config, esp, - battery: Box::new(NoBatteryMonitor{}), + battery: Box::new(NoBatteryMonitor {}), }; Ok(Box::new(v)) } diff --git a/rust/src/hal/mod.rs b/rust/src/hal/mod.rs index 94688b1..232664c 100644 --- a/rust/src/hal/mod.rs +++ b/rust/src/hal/mod.rs @@ -281,34 +281,35 @@ impl PlantHal { let hal = match config { Result::Ok(config) => { - let battery_interaction: Box = match config.hardware.battery { - BatteryBoardVersion::Disabled => Box::new(NoBatteryMonitor{}), - BatteryBoardVersion::BQ34Z100G1 => { - let mut battery_driver = Bq34z100g1Driver { - i2c: MutexDevice::new(&I2C_DRIVER), - delay: Delay::new(0), - flash_block_data: [0; 32], - }; - let status = print_battery_bq34z100(&mut battery_driver); - match status { - OkStd(_) => {} - Err(err) => { - log( - LogMessage::BatteryCommunicationError, - 0u32, - 0, - "", - &format!("{err:?})"), - ); + let battery_interaction: Box = + match config.hardware.battery { + BatteryBoardVersion::Disabled => Box::new(NoBatteryMonitor {}), + BatteryBoardVersion::BQ34Z100G1 => { + let mut battery_driver = Bq34z100g1Driver { + i2c: MutexDevice::new(&I2C_DRIVER), + delay: Delay::new(0), + flash_block_data: [0; 32], + }; + let status = print_battery_bq34z100(&mut battery_driver); + match status { + OkStd(_) => {} + Err(err) => { + log( + LogMessage::BatteryCommunicationError, + 0u32, + 0, + "", + &format!("{err:?})"), + ); + } } + Box::new(BQ34Z100G1 { battery_driver }) } - Box::new(BQ34Z100G1 { battery_driver }) - } - BatteryBoardVersion::WchI2cSlave => { - // TODO use correct implementation once availible - Box::new(NoBatteryMonitor{}) - }, - }; + BatteryBoardVersion::WchI2cSlave => { + // TODO use correct implementation once availible + Box::new(NoBatteryMonitor {}) + } + }; let board_hal: Box = match config.hardware.board { BoardVersion::INITIAL => { diff --git a/rust/src/main.rs b/rust/src/main.rs index 9073795..d2a63d1 100644 --- a/rust/src/main.rs +++ b/rust/src/main.rs @@ -12,6 +12,7 @@ use esp_idf_sys::{ esp_ota_img_states_t_ESP_OTA_IMG_VALID, vTaskDelay, }; use esp_ota::{mark_app_valid, rollback_and_reboot}; +use hal::battery::BatteryState; use log::{log, LogMessage}; use once_cell::sync::Lazy; use serde::{Deserialize, Serialize}; @@ -421,7 +422,14 @@ fn safe_main() -> anyhow::Result<()> { .board_hal .get_battery_monitor() .state_charge_percent() - .unwrap_or(0); + .unwrap_or(0.); + + /// try to load full battery state if failed the battery state is unknown + let battery_state = board + .board_hal + .get_battery_monitor() + .get_battery_state() + .unwrap_or(hal::battery::BatteryState::Unknown); let mut light_state = LightState { enabled: board.board_hal.get_config().night_lamp.enabled, @@ -439,9 +447,23 @@ fn safe_main() -> anyhow::Result<()> { board.board_hal.get_config().night_lamp.night_lamp_hour_end, ); - if state_of_charge < board.board_hal.get_config().night_lamp.low_soc_cutoff { + if state_of_charge + < board + .board_hal + .get_config() + .night_lamp + .low_soc_cutoff + .into() + { board.board_hal.get_esp().set_low_voltage_in_cycle(); - } else if state_of_charge > board.board_hal.get_config().night_lamp.low_soc_restore { + } else if state_of_charge + > board + .board_hal + .get_config() + .night_lamp + .low_soc_restore + .into() + { board.board_hal.get_esp().clear_low_voltage_in_cycle(); } light_state.battery_low = board.board_hal.get_esp().low_voltage_in_cycle(); @@ -487,25 +509,27 @@ fn safe_main() -> anyhow::Result<()> { } }; - let deep_sleep_duration_minutes: u32 = if state_of_charge < 10 { - let _ = board - .board_hal - .get_esp() - .mqtt_publish("/deepsleep", "low Volt 12h".as_bytes()); - 12 * 60 - } else if is_day { - let _ = board - .board_hal - .get_esp() - .mqtt_publish("/deepsleep", "normal 20m".as_bytes()); - 20 - } else { - let _ = board - .board_hal - .get_esp() - .mqtt_publish("/deepsleep", "night 1h".as_bytes()); - 60 - }; + let deep_sleep_duration_minutes: u32 = + // if battery soc is unknown assume battery has enough change + if state_of_charge < 10.0 && !matches!(battery_state, BatteryState::Unknown) { + let _ = board + .board_hal + .get_esp() + .mqtt_publish("/deepsleep", "low Volt 12h".as_bytes()); + 12 * 60 + } else if is_day { + let _ = board + .board_hal + .get_esp() + .mqtt_publish("/deepsleep", "normal 20m".as_bytes()); + 20 + } else { + let _ = board + .board_hal + .get_esp() + .mqtt_publish("/deepsleep", "night 1h".as_bytes()); + 60 + }; let _ = board .board_hal .get_esp() @@ -715,10 +739,13 @@ fn pump_info( fn publish_battery_state(board: &mut MutexGuard<'_, HAL<'_>>) { let state = board.board_hal.get_battery_monitor().get_battery_state(); - let _ = board - .board_hal - .get_esp() - .mqtt_publish("/battery", state.as_bytes()); + if let Ok(serialized_battery_state_bytes) = serde_json::to_string(&state).map(|s| s.into_bytes()) + { + let _ = board + .board_hal + .get_esp() + .mqtt_publish("/battery", &serialized_battery_state_bytes); + } } fn wait_infinity(wait_type: WaitType, reboot_now: Arc) -> ! { diff --git a/rust/src/webserver/webserver.rs b/rust/src/webserver/webserver.rs index 9d0bdb0..53ca85d 100644 --- a/rust/src/webserver/webserver.rs +++ b/rust/src/webserver/webserver.rs @@ -223,7 +223,7 @@ fn get_battery_state( ) -> Result, anyhow::Error> { let mut board = BOARD_ACCESS.lock().expect("board access"); let battery_state = board.board_hal.get_battery_monitor().get_battery_state(); - anyhow::Ok(Some(battery_state)) + anyhow::Ok(Some(serde_json::to_string(&battery_state)?)) } fn get_log(