From bc25fef5ec9b6289018fe460a5d9453f8c2ed316 Mon Sep 17 00:00:00 2001 From: Empire Date: Fri, 10 Apr 2026 18:53:30 +0200 Subject: [PATCH] refactor: consolidate logging and time handling, remove `TIME_ACCESS` and `LOG_ACCESS` --- Software/MainBoard/rust/src/hal/esp.rs | 227 ++++++++---------- Software/MainBoard/rust/src/hal/mod.rs | 74 ++---- Software/MainBoard/rust/src/hal/v4_hal.rs | 22 +- Software/MainBoard/rust/src/log/mod.rs | 69 ++++-- Software/MainBoard/rust/src/main.rs | 133 ++++------ .../MainBoard/rust/src/webserver/get_json.rs | 4 +- .../MainBoard/rust/src/webserver/post_json.rs | 5 +- 7 files changed, 232 insertions(+), 302 deletions(-) diff --git a/Software/MainBoard/rust/src/hal/esp.rs b/Software/MainBoard/rust/src/hal/esp.rs index aa608a5..a619f41 100644 --- a/Software/MainBoard/rust/src/hal/esp.rs +++ b/Software/MainBoard/rust/src/hal/esp.rs @@ -1,8 +1,8 @@ use crate::bail; use crate::config::{NetworkConfig, PlantControllerConfig}; use crate::hal::savegame_manager::SavegameManager; -use crate::hal::{PLANT_COUNT, TIME_ACCESS}; -use crate::log::{LogMessage, LOG_ACCESS}; +use crate::hal::PLANT_COUNT; +use crate::log::{log, LogMessage}; use chrono::{DateTime, Utc}; use crate::fat_error::{ContextExt, FatError, FatResult}; @@ -16,7 +16,7 @@ use embassy_executor::Spawner; use embassy_net::udp::UdpSocket; use embassy_net::{DhcpConfig, Ipv4Cidr, Runner, Stack, StackResources, StaticConfigV4}; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; -use embassy_sync::mutex::{Mutex, MutexGuard}; +use embassy_sync::mutex::Mutex; use embassy_sync::once_lock::OnceLock; use embassy_time::{Duration, Timer, WithTimeout}; use embedded_storage::nor_flash::{check_erase, NorFlash, ReadNorFlash, RmwNorFlashStorage}; @@ -112,6 +112,8 @@ pub struct Esp<'a> { pub wake_gpio1: esp_hal::peripherals::GPIO1<'static>, pub uart0: Uart<'a, Blocking>, + pub rtc: Rtc<'a>, + pub ota: Ota<'static, RmwNorFlashStorage<'static, &'static mut MutexFlashStorage>>, pub ota_target: &'static mut FlashRegion<'static, MutexFlashStorage>, pub current: AppPartitionSubType, @@ -137,6 +139,14 @@ macro_rules! mk_static { } impl Esp<'_> { + pub fn get_time(&self) -> DateTime { + DateTime::from_timestamp_micros(self.rtc.current_time_us() as i64).unwrap_or(DateTime::UNIX_EPOCH) + } + + pub fn set_time(&mut self, time: DateTime) { + self.rtc.set_current_time_us(time.timestamp_micros() as u64); + } + pub(crate) async fn read_serial_line(&mut self) -> FatResult> { let mut buf = [0u8; 1]; let mut line = String::new(); @@ -442,70 +452,65 @@ impl Esp<'_> { spawner.spawn(net_task(runner)).ok(); self.controller.lock().await.start_async().await?; - let timeout = { - let guard = TIME_ACCESS.get().await.lock().await; - guard.current_time_us() - } + max_wait as u64 * 1000; - loop { - let state = esp_radio::wifi::sta_state(); - if state == WifiStaState::Started { - self.controller.lock().await.connect()?; - break; + let res = async { + loop { + let state = esp_radio::wifi::sta_state(); + if state == WifiStaState::Started { + self.controller.lock().await.connect()?; + break; + } + Timer::after(Duration::from_millis(500)).await; } - if { - let guard = TIME_ACCESS.get().await.lock().await; - guard.current_time_us() - } > timeout - { - bail!("Timeout waiting for wifi sta ready") - } - Timer::after(Duration::from_millis(500)).await; + Ok::<(), FatError>(()) } - let timeout = { - let guard = TIME_ACCESS.get().await.lock().await; - guard.current_time_us() - } + max_wait as u64 * 1000; - loop { - let state = esp_radio::wifi::sta_state(); - if state == WifiStaState::Connected { - break; - } - if { - let guard = TIME_ACCESS.get().await.lock().await; - guard.current_time_us() - } > timeout - { - bail!("Timeout waiting for wifi sta connected") - } - Timer::after(Duration::from_millis(500)).await; + .with_timeout(Duration::from_millis(max_wait as u64 * 1000)) + .await; + + if res.is_err() { + bail!("Timeout waiting for wifi sta ready") } - let timeout = { - let guard = TIME_ACCESS.get().await.lock().await; - guard.current_time_us() - } + max_wait as u64 * 1000; - while !stack.is_link_up() { - if { - let guard = TIME_ACCESS.get().await.lock().await; - guard.current_time_us() - } > timeout - { - bail!("Timeout waiting for wifi link up") + + let res = async { + loop { + let state = esp_radio::wifi::sta_state(); + if state == WifiStaState::Connected { + break; + } + Timer::after(Duration::from_millis(500)).await; } - Timer::after(Duration::from_millis(500)).await; + Ok::<(), FatError>(()) } - let timeout = { - let guard = TIME_ACCESS.get().await.lock().await; - guard.current_time_us() - } + max_wait as u64 * 1000; - while !stack.is_config_up() { - if { - let guard = TIME_ACCESS.get().await.lock().await; - guard.current_time_us() - } > timeout - { - bail!("Timeout waiting for wifi config up") + .with_timeout(Duration::from_millis(max_wait as u64 * 1000)) + .await; + + if res.is_err() { + bail!("Timeout waiting for wifi sta connected") + } + + let res = async { + while !stack.is_link_up() { + Timer::after(Duration::from_millis(500)).await; } - Timer::after(Duration::from_millis(100)).await + Ok::<(), FatError>(()) + } + .with_timeout(Duration::from_millis(max_wait as u64 * 1000)) + .await; + + if res.is_err() { + bail!("Timeout waiting for wifi link up") + } + + let res = async { + while !stack.is_config_up() { + Timer::after(Duration::from_millis(100)).await + } + Ok::<(), FatError>(()) + } + .with_timeout(Duration::from_millis(max_wait as u64 * 1000)) + .await; + + if res.is_err() { + bail!("Timeout waiting for wifi config up") } info!("Connected WIFI, dhcp: {:?}", stack.config_v4()); @@ -515,7 +520,6 @@ impl Esp<'_> { pub fn deep_sleep( &mut self, duration_in_ms: u64, - mut rtc: MutexGuard, ) -> ! { // Mark the current OTA image as valid if we reached here while in pending verify. if let Ok(cur) = self.ota.current_ota_state() { @@ -536,7 +540,7 @@ impl Esp<'_> { let mut wake_pins: [(&mut dyn RtcPinWithResistors, WakeupLevel); 1] = [(&mut self.wake_gpio1, WakeupLevel::Low)]; let ext1 = esp_hal::rtc_cntl::sleep::Ext1WakeupSource::new(&mut wake_pins); - rtc.sleep_deep(&[&timer, &ext1]); + self.rtc.sleep_deep(&[&timer, &ext1]); } } @@ -603,28 +607,15 @@ impl Esp<'_> { if to_config_mode { RESTART_TO_CONF = 1; } - LOG_ACCESS - .lock() - .await - .log( - LogMessage::RestartToConfig, - RESTART_TO_CONF as u32, - 0, - "", - "", - ) - .await; - LOG_ACCESS - .lock() - .await - .log( - LogMessage::LowVoltage, - LOW_VOLTAGE_DETECTED as u32, - 0, - "", - "", - ) - .await; + log(LogMessage::RestartToConfig, RESTART_TO_CONF as u32, 0, "", "").await; + log( + LogMessage::LowVoltage, + LOW_VOLTAGE_DETECTED as u32, + 0, + "", + "", + ) + .await; // is executed before main, no other code will alter these values during printing #[allow(static_mut_refs)] for (i, time) in LAST_WATERING_TIMESTAMP.iter().enumerate() { @@ -703,29 +694,22 @@ impl Esp<'_> { ))?; spawner.spawn(mqtt_runner(task))?; - LOG_ACCESS - .lock() - .await - .log(LogMessage::StayAlive, 0, 0, "", &stay_alive_topic) - .await; + log(LogMessage::StayAlive, 0, 0, "", &stay_alive_topic).await; - LOG_ACCESS - .lock() - .await - .log(LogMessage::MqttInfo, 0, 0, "", mqtt_url) - .await; + log(LogMessage::MqttInfo, 0, 0, "", mqtt_url).await; let mqtt_timeout = 15000; - let timeout = { - let guard = TIME_ACCESS.get().await.lock().await; - guard.current_time_us() - } + mqtt_timeout as u64 * 1000; - while !MQTT_CONNECTED_EVENT_RECEIVED.load(Ordering::Relaxed) { - let cur = TIME_ACCESS.get().await.lock().await.current_time_us(); - if cur > timeout { - bail!("Timeout waiting MQTT connect event") + let res = async { + while !MQTT_CONNECTED_EVENT_RECEIVED.load(Ordering::Relaxed) { + Timer::after(Duration::from_millis(100)).await; } - Timer::after(Duration::from_millis(100)).await; + Ok::<(), FatError>(()) + } + .with_timeout(Duration::from_millis(mqtt_timeout as u64)) + .await; + + if res.is_err() { + bail!("Timeout waiting MQTT connect event") } let _ = Topic::General(round_trip_topic.clone()) @@ -733,18 +717,19 @@ impl Esp<'_> { .publish() .await; - let timeout = { - let guard = TIME_ACCESS.get().await.lock().await; - guard.current_time_us() - } + mqtt_timeout as u64 * 1000; - while !MQTT_ROUND_TRIP_RECEIVED.load(Ordering::Relaxed) { - let cur = TIME_ACCESS.get().await.lock().await.current_time_us(); - if cur > timeout { - //ensure we do not further try to publish - MQTT_CONNECTED_EVENT_RECEIVED.store(false, Ordering::Relaxed); - bail!("Timeout waiting MQTT roundtrip") + let res = async { + while !MQTT_ROUND_TRIP_RECEIVED.load(Ordering::Relaxed) { + Timer::after(Duration::from_millis(100)).await; } - Timer::after(Duration::from_millis(100)).await; + Ok::<(), FatError>(()) + } + .with_timeout(Duration::from_millis(mqtt_timeout as u64)) + .await; + + if res.is_err() { + //ensure we do not further try to publish + MQTT_CONNECTED_EVENT_RECEIVED.store(false, Ordering::Relaxed); + bail!("Timeout waiting MQTT roundtrip") } Ok(()) } @@ -851,18 +836,10 @@ async fn mqtt_incoming_task( true => 1, false => 0, }; - LOG_ACCESS - .lock() - .await - .log(LogMessage::MqttStayAliveRec, a, 0, "", "") - .await; + log(LogMessage::MqttStayAliveRec, a, 0, "", "").await; MQTT_STAY_ALIVE.store(value, Ordering::Relaxed); } else { - LOG_ACCESS - .lock() - .await - .log(LogMessage::UnknownTopic, 0, 0, "", &topic) - .await; + log(LogMessage::UnknownTopic, 0, 0, "", &topic).await; } } }, diff --git a/Software/MainBoard/rust/src/hal/mod.rs b/Software/MainBoard/rust/src/hal/mod.rs index 0fe230d..8d99879 100644 --- a/Software/MainBoard/rust/src/hal/mod.rs +++ b/Software/MainBoard/rust/src/hal/mod.rs @@ -44,8 +44,8 @@ use crate::{ battery::{BatteryInteraction, NoBatteryMonitor}, esp::Esp, }, + log::log, log::LogMessage, - BOARD_ACCESS, }; use alloc::boxed::Box; use alloc::format; @@ -77,7 +77,6 @@ use crate::fat_error::{ContextExt, FatError, FatResult}; use crate::hal::battery::WCHI2CSlave; use crate::hal::savegame_manager::SavegameManager; use crate::hal::water::TankSensor; -use crate::log::LOG_ACCESS; use embassy_sync::mutex::Mutex; use embassy_sync::once_lock::OnceLock; use embedded_storage::nor_flash::RmwNorFlashStorage; @@ -104,8 +103,6 @@ use portable_atomic::AtomicBool; use serde::{Deserialize, Serialize}; use shared_flash::MutexFlashStorage; -pub static TIME_ACCESS: OnceLock> = OnceLock::new(); - //Only support for 8 right now! pub const PLANT_COUNT: usize = 8; @@ -145,6 +142,8 @@ pub trait BoardInteraction<'a> { fn get_config(&mut self) -> &PlantControllerConfig; fn get_battery_monitor(&mut self) -> &mut Box; fn get_rtc_module(&mut self) -> &mut Box; + async fn get_time(&mut self) -> DateTime; + async fn set_time(&mut self, time: &DateTime) -> FatResult<()>; async fn set_charge_indicator(&mut self, charging: bool) -> Result<(), FatError>; async fn deep_sleep(&mut self, duration_in_ms: u64) -> !; @@ -246,12 +245,7 @@ impl PlantHal { esp_alloc::heap_allocator!(size: 64 * 1024); esp_alloc::heap_allocator!(#[link_section = ".dram2_uninit"] size: 64000); - let rtc: Rtc = Rtc::new(peripherals.LPWR); - TIME_ACCESS - .init(Mutex::new(rtc)) - .map_err(|_| FatError::String { - error: "Init error rct".to_string(), - })?; + let rtc_peripheral: Rtc = Rtc::new(peripherals.LPWR); let timg0 = TimerGroup::new(peripherals.TIMG0); let sw_int = SoftwareInterruptControl::new(peripherals.SW_INTERRUPT); @@ -409,6 +403,7 @@ impl PlantHal { slot0_state: state_0, slot1_state: state_1, uart0, + rtc: rtc_peripheral, }; //init,reset rtc memory depending on cause @@ -444,17 +439,14 @@ impl PlantHal { SocResetReason::Cpu0JtagCpu => "cpu0 jtag cpu", }, }; - LOG_ACCESS - .lock() - .await - .log( - LogMessage::ResetReason, - init_rtc_store as u32, - to_config_mode as u32, - "", - &format!("{reasons:?}"), - ) - .await; + log( + LogMessage::ResetReason, + init_rtc_store as u32, + to_config_mode as u32, + "", + &format!("{reasons:?}"), + ) + .await; esp.init_rtc_deepsleep_memory(init_rtc_store, to_config_mode) .await; @@ -548,17 +540,14 @@ impl PlantHal { HAL { board_hal } } Err(err) => { - LOG_ACCESS - .lock() - .await - .log( - LogMessage::ConfigModeMissingConfig, - 0, - 0, - "", - &err.to_string(), - ) - .await; + log( + LogMessage::ConfigModeMissingConfig, + 0, + 0, + "", + &err.to_string(), + ) + .await; HAL { board_hal: v4_hal::create_v4( free_pins, @@ -641,27 +630,6 @@ pub fn next_partition(current: AppPartitionSubType) -> FatResult DateTime { - let guard = TIME_ACCESS.get().await.lock().await; - DateTime::from_timestamp_micros(guard.current_time_us() as i64).unwrap_or(DateTime::UNIX_EPOCH) -} - -pub async fn esp_set_time(time: DateTime) -> FatResult<()> { - { - let guard = TIME_ACCESS.get().await.lock().await; - guard.set_current_time_us(time.timestamp_micros() as u64); - } - BOARD_ACCESS - .get() - .await - .lock() - .await - .board_hal - .get_rtc_module() - .set_rtc_time(&time.to_utc()) - .await -} - #[derive(Debug, Clone, Copy, PartialEq, Default, Serialize)] pub struct Moistures { pub sensor_a_hz: [Option; PLANT_COUNT], diff --git a/Software/MainBoard/rust/src/hal/v4_hal.rs b/Software/MainBoard/rust/src/hal/v4_hal.rs index e91997b..d4df758 100644 --- a/Software/MainBoard/rust/src/hal/v4_hal.rs +++ b/Software/MainBoard/rust/src/hal/v4_hal.rs @@ -7,15 +7,15 @@ use crate::hal::rtc::{BackupHeader, RTCModuleInteraction, EEPROM_PAGE, X25}; use crate::hal::water::TankSensor; use crate::hal::{ BoardInteraction, Detection, FreePeripherals, Moistures, Sensor, I2C_DRIVER, PLANT_COUNT, - TIME_ACCESS, }; -use crate::log::{LogMessage, LOG_ACCESS}; +use crate::log::{log, LogMessage}; use alloc::boxed::Box; 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 chrono::{DateTime, FixedOffset, Utc}; use core::cmp::min; use embassy_embedded_hal::shared_bus::blocking::i2c::I2cDevice; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; @@ -300,6 +300,16 @@ impl<'a> BoardInteraction<'a> for V4<'a> { &mut self.rtc_module } + async fn get_time(&mut self) -> DateTime { + self.esp.get_time() + } + + async fn set_time(&mut self, time: &DateTime) -> FatResult<()> { + self.rtc_module.set_rtc_time(&time.to_utc()).await?; + self.esp.set_time(time.to_utc()); + Ok(()) + } + async fn set_charge_indicator(&mut self, charging: bool) -> Result<(), FatError> { self.charger.set_charge_indicator(charging) } @@ -307,8 +317,7 @@ impl<'a> BoardInteraction<'a> for V4<'a> { async fn deep_sleep(&mut self, duration_in_ms: u64) -> ! { self.awake.set_low(); self.charger.power_save(); - let rtc = TIME_ACCESS.get().await.lock().await; - self.esp.deep_sleep(duration_in_ms, rtc); + self.esp.deep_sleep(duration_in_ms); } fn is_day(&self) -> bool { @@ -507,10 +516,7 @@ impl<'a> BoardInteraction<'a> for V4<'a> { for plant in 0..PLANT_COUNT { let a = moisture.sensor_a_hz[plant].unwrap_or(0.0) as u32; let b = moisture.sensor_b_hz[plant].unwrap_or(0.0) as u32; - 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; diff --git a/Software/MainBoard/rust/src/log/mod.rs b/Software/MainBoard/rust/src/log/mod.rs index 577e3ce..3c2ce9c 100644 --- a/Software/MainBoard/rust/src/log/mod.rs +++ b/Software/MainBoard/rust/src/log/mod.rs @@ -1,10 +1,11 @@ -use crate::hal::TIME_ACCESS; +use crate::BOARD_ACCESS; use crate::vec; use alloc::string::ToString; use alloc::vec::Vec; use bytemuck::{AnyBitPattern, Pod, Zeroable}; use deranged::RangedU8; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; +use embassy_sync::channel::Channel; use embassy_sync::mutex::Mutex; use esp_hal::Persistable; use log::{info, warn}; @@ -32,6 +33,34 @@ static mut LOG_ARRAY: LogArray = LogArray { pub static LOG_ACCESS: Mutex = unsafe { Mutex::new(&mut LOG_ARRAY) }; +pub struct LogRequest { + pub message_key: LogMessage, + pub number_a: u32, + pub number_b: u32, + pub txt_short: heapless::String, + pub txt_long: heapless::String, +} + +static LOG_CHANNEL: Channel = Channel::new(); + +#[embassy_executor::task] +pub async fn log_task() { + loop { + let request = LOG_CHANNEL.receive().await; + LOG_ACCESS + .lock() + .await + .log( + request.message_key, + request.number_a, + request.number_b, + request.txt_short.as_str(), + request.txt_long.as_str(), + ) + .await; + } +} + const TXT_SHORT_LENGTH: usize = 8; const TXT_LONG_LENGTH: usize = 32; @@ -87,11 +116,21 @@ pub async fn log( txt_short: &str, txt_long: &str, ) { - LOG_ACCESS - .lock() - .await - .log(message_key, number_a, number_b, txt_short, txt_long) - .await + let mut txt_short_stack: heapless::String = heapless::String::new(); + let mut txt_long_stack: heapless::String = heapless::String::new(); + + limit_length(txt_short, &mut txt_short_stack); + limit_length(txt_long, &mut txt_long_stack); + + LOG_CHANNEL + .send(LogRequest { + message_key, + number_a, + number_b, + txt_short: txt_short_stack, + txt_long: txt_long_stack, + }) + .await; } impl LogArray { @@ -122,15 +161,9 @@ impl LogArray { let mut head: RangedU8<0, MAX_LOG_ARRAY_INDEX> = RangedU8::new(self.head).unwrap_or(RangedU8::new_saturating(0)); - let mut txt_short_stack: heapless::String = heapless::String::new(); - let mut txt_long_stack: heapless::String = heapless::String::new(); - - limit_length(txt_short, &mut txt_short_stack); - limit_length(txt_long, &mut txt_long_stack); - let time = { - let guard = TIME_ACCESS.get().await.lock().await; - guard.current_time_us() + let mut guard = BOARD_ACCESS.get().await.lock().await; + guard.board_hal.get_esp().rtc.current_time_us() } / 1000; let ordinal = message_key.ordinal() as u16; @@ -148,12 +181,8 @@ impl LogArray { to_modify.message_id = ordinal; to_modify.a = number_a; to_modify.b = number_b; - to_modify - .txt_short - .clone_from_slice(txt_short_stack.as_bytes()); - to_modify - .txt_long - .clone_from_slice(txt_long_stack.as_bytes()); + to_modify.txt_short.clone_from_slice(txt_short.as_bytes()); + to_modify.txt_long.clone_from_slice(txt_long.as_bytes()); head = head.wrapping_add(1); self.head = head.get(); } diff --git a/Software/MainBoard/rust/src/main.rs b/Software/MainBoard/rust/src/main.rs index 05366ab..64374af 100644 --- a/Software/MainBoard/rust/src/main.rs +++ b/Software/MainBoard/rust/src/main.rs @@ -18,8 +18,7 @@ use crate::config::{NetworkConfig, PlantConfig, PlantControllerConfig}; use crate::fat_error::FatResult; use crate::hal::esp::MQTT_STAY_ALIVE; use crate::hal::PROGRESS_ACTIVE; -use crate::hal::{esp_time, TIME_ACCESS}; -use crate::log::{log, LOG_ACCESS}; +use crate::log::log; use crate::tank::{determine_tank_state, TankError, TankState, WATER_FROZEN_THRESH}; use crate::webserver::http_server; use crate::{ @@ -168,26 +167,21 @@ async fn safe_main(spawner: Spawner) -> FatResult<()> { let cur = match board.board_hal.get_rtc_module().get_rtc_time().await { Ok(value) => { { - let guard = TIME_ACCESS.get().await.lock().await; - guard.set_current_time_us(value.timestamp_micros() as u64); + board.board_hal.get_esp().rtc.set_current_time_us(value.timestamp_micros() as u64); } value } Err(err) => { info!("rtc module error: {err:?}"); board.board_hal.general_fault(true).await; - esp_time().await + board.board_hal.get_time().await } }; //check if we know the time current > 2020 (plausibility checks, this code is newer than 2020) if cur.year() < 2020 { to_config = true; - LOG_ACCESS - .lock() - .await - .log(LogMessage::YearInplausibleForceConfig, 0, 0, "", "") - .await; + log(LogMessage::YearInplausibleForceConfig, 0, 0, "", "").await; } info!("cur is {cur}"); match update_charge_indicator(&mut board).await { @@ -200,11 +194,7 @@ async fn safe_main(spawner: Spawner) -> FatResult<()> { } } if board.board_hal.get_esp().get_restart_to_conf() { - LOG_ACCESS - .lock() - .await - .log(LogMessage::ConfigModeSoftwareOverride, 0, 0, "", "") - .await; + log(LogMessage::ConfigModeSoftwareOverride, 0, 0, "", "").await; for _i in 0..2 { board.board_hal.general_fault(true).await; Timer::after_millis(100).await; @@ -216,11 +206,7 @@ async fn safe_main(spawner: Spawner) -> FatResult<()> { board.board_hal.get_esp().set_restart_to_conf(false); } else if board.board_hal.get_esp().mode_override_pressed() { board.board_hal.general_fault(true).await; - LOG_ACCESS - .lock() - .await - .log(LogMessage::ConfigModeButtonOverride, 0, 0, "", "") - .await; + log(LogMessage::ConfigModeButtonOverride, 0, 0, "", "").await; for _i in 0..5 { board.board_hal.general_fault(true).await; Timer::after_millis(100).await; @@ -304,25 +290,22 @@ async fn safe_main(spawner: Spawner) -> FatResult<()> { let _ = publish_mppt_state(&mut board).await; } - LOG_ACCESS - .lock() - .await - .log( - LogMessage::StartupInfo, - matches!(network_mode, NetworkMode::Wifi { .. }) as u32, - matches!( - network_mode, - NetworkMode::Wifi { - sntp: SntpMode::Sync { .. }, - .. - } - ) as u32, - matches!(network_mode, NetworkMode::Wifi { mqtt: true, .. }) - .to_string() - .as_str(), - "", - ) - .await; + log( + LogMessage::StartupInfo, + matches!(network_mode, NetworkMode::Wifi { .. }) as u32, + matches!( + network_mode, + NetworkMode::Wifi { + sntp: SntpMode::Sync { .. }, + .. + } + ) as u32, + matches!(network_mode, NetworkMode::Wifi { mqtt: true, .. }) + .to_string() + .as_str(), + "", + ) + .await; if to_config { //check if client or ap mode and init Wi-Fi @@ -337,14 +320,10 @@ async fn safe_main(spawner: Spawner) -> FatResult<()> { } wait_infinity(board, WaitType::ConfigButton, reboot_now.clone()).await; } else { - LOG_ACCESS - .lock() - .await - .log(LogMessage::NormalRun, 0, 0, "", "") - .await; + log(LogMessage::NormalRun, 0, 0, "", "").await; } - let dry_run = false; + let dry_run = MQTT_STAY_ALIVE.load(Ordering::Relaxed); let tank_state = determine_tank_state(&mut board).await; @@ -353,37 +332,20 @@ async fn safe_main(spawner: Spawner) -> FatResult<()> { match err { TankError::SensorDisabled => { /* unreachable */ } TankError::SensorMissing(raw_value_mv) => { - LOG_ACCESS - .lock() - .await - .log( - LogMessage::TankSensorMissing, - raw_value_mv as u32, - 0, - "", - "", - ) - .await + log(LogMessage::TankSensorMissing, raw_value_mv as u32, 0, "", "").await } TankError::SensorValueError { value, min, max } => { - LOG_ACCESS - .lock() - .await - .log( - LogMessage::TankSensorValueRangeError, - min as u32, - max as u32, - &format!("{value}"), - "", - ) - .await + log( + LogMessage::TankSensorValueRangeError, + min as u32, + max as u32, + &format!("{value}"), + "", + ) + .await } TankError::BoardError(err) => { - LOG_ACCESS - .lock() - .await - .log(LogMessage::TankSensorBoardError, 0, 0, "", &err.to_string()) - .await + log(LogMessage::TankSensorBoardError, 0, 0, "", &err.to_string()).await } } // disabled cannot trigger this because of wrapping if is_enabled @@ -392,11 +354,7 @@ async fn safe_main(spawner: Spawner) -> FatResult<()> { .warn_level(&board.board_hal.get_config().tank) .is_ok_and(|warn| warn) { - LOG_ACCESS - .lock() - .await - .log(LogMessage::TankWaterLevelLow, 0, 0, "", "") - .await; + log(LogMessage::TankWaterLevelLow, 0, 0, "", "").await; board.board_hal.general_fault(true).await; } } @@ -445,11 +403,7 @@ async fn safe_main(spawner: Spawner) -> FatResult<()> { .any(|(it, conf)| it.needs_to_be_watered(conf, &timezone_time)) && !water_frozen; if pump_required { - LOG_ACCESS - .lock() - .await - .log(LogMessage::EnableMain, dry_run as u32, 0, "", "") - .await; + log(LogMessage::EnableMain, dry_run as u32, 0, "", "").await; for (plant_id, (state, plant_config)) in plantstate .iter() .zip(&board.board_hal.get_config().plants.clone()) @@ -489,12 +443,13 @@ async fn safe_main(spawner: Spawner) -> FatResult<()> { board.board_hal.get_esp().last_pump_time(plant_id); //state.active = true; - pump_info(plant_id, true, pump_ineffective, 0, 0, 0, false).await; + pump_info(&mut board, plant_id, true, pump_ineffective, 0, 0, 0, false).await; let result = do_secure_pump(&mut board, plant_id, plant_config, dry_run).await?; //stop pump regardless of prior result//todo refactor to inner? board.board_hal.pump(plant_id, false).await?; pump_info( + &mut board, plant_id, false, pump_ineffective, @@ -947,6 +902,7 @@ async fn try_connect_wifi_sntp_mqtt( } async fn pump_info( + board: &mut MutexGuard<'_, CriticalSectionRawMutex, HAL<'static>>, plant_id: usize, pump_active: bool, pump_ineffective: bool, @@ -966,15 +922,7 @@ async fn pump_info( match serde_json::to_string(&pump_info) { Ok(state) => { - BOARD_ACCESS - .get() - .await - .lock() - .await - .board_hal - .get_esp() - .mqtt_publish(&pump_topic, &state) - .await; + board.board_hal.get_esp().mqtt_publish(&pump_topic, &state).await; } Err(err) => { warn!("Error publishing pump state {err}"); @@ -1222,6 +1170,7 @@ use embassy_time::WithTimeout; async fn main(spawner: Spawner) -> ! { // intialize embassy logger::init_logger_from_env(); + spawner.must_spawn(crate::log::log_task()); //force init here! match BOARD_ACCESS.init( PlantHal::create() diff --git a/Software/MainBoard/rust/src/webserver/get_json.rs b/Software/MainBoard/rust/src/webserver/get_json.rs index e97b75a..4f2ee77 100644 --- a/Software/MainBoard/rust/src/webserver/get_json.rs +++ b/Software/MainBoard/rust/src/webserver/get_json.rs @@ -1,5 +1,5 @@ use crate::fat_error::{FatError, FatResult}; -use crate::hal::{esp_time, PLANT_COUNT}; +use crate::hal::PLANT_COUNT; use crate::log::LogMessage; use crate::plant_state::{MoistureSensorState, PlantState}; use crate::tank::determine_tank_state; @@ -174,7 +174,7 @@ pub(crate) async fn get_time( }, }; - let native = esp_time().await.with_timezone(&tz).to_rfc3339(); + let native = board.board_hal.get_time().await.with_timezone(&tz).to_rfc3339(); let rtc = match board.board_hal.get_rtc_module().get_rtc_time().await { Ok(time) => time.with_timezone(&tz).to_rfc3339(), diff --git a/Software/MainBoard/rust/src/webserver/post_json.rs b/Software/MainBoard/rust/src/webserver/post_json.rs index 2c476a5..b6afff5 100644 --- a/Software/MainBoard/rust/src/webserver/post_json.rs +++ b/Software/MainBoard/rust/src/webserver/post_json.rs @@ -1,6 +1,6 @@ use crate::config::PlantControllerConfig; use crate::fat_error::FatResult; -use crate::hal::{esp_set_time, Detection}; +use crate::hal::Detection; use crate::webserver::read_up_to_bytes_from_request; use crate::{do_secure_pump, BOARD_ACCESS}; use alloc::string::{String, ToString}; @@ -109,7 +109,8 @@ where let actual_data = read_up_to_bytes_from_request(request, None).await?; let time: SetTime = serde_json::from_slice(&actual_data)?; let parsed = DateTime::parse_from_rfc3339(time.time)?; - esp_set_time(parsed).await?; + let mut board = BOARD_ACCESS.get().await.lock().await; + board.board_hal.set_time(&parsed).await?; Ok(None) }