refactor: add timezone support to wait_infinity, improve MQTT updates in config mode, and minor cleanup

This commit is contained in:
2026-04-16 20:42:08 +02:00
parent 6a71ac4234
commit b740574c68
3 changed files with 30 additions and 12 deletions

View File

@@ -2,7 +2,7 @@ use alloc::vec::Vec;
use bincode::{Decode, Encode}; use bincode::{Decode, Encode};
use embedded_savegame::storage::{Flash, Storage}; use embedded_savegame::storage::{Flash, Storage};
use embedded_storage::nor_flash::{NorFlash, ReadNorFlash}; use embedded_storage::nor_flash::{NorFlash, ReadNorFlash};
use esp_bootloader_esp_idf::partitions::{Error as PartitionError, Error, FlashRegion}; use esp_bootloader_esp_idf::partitions::{Error as PartitionError, FlashRegion};
use log::{error, info}; use log::{error, info};
use serde::Serialize; use serde::Serialize;
@@ -64,8 +64,8 @@ impl Flash for SavegameFlashAdapter<'_> {
data.len() data.len()
); );
let error = NorFlash::write(self.region, addr, data); let error = NorFlash::write(self.region, addr, data);
if error.is_err() { if let Err(err) = error {
error!("error {:?}", error.unwrap_err()) error!("error {:?}", err);
} }
error.map_err(SavegameFlashError) error.map_err(SavegameFlashError)
} }

View File

@@ -34,8 +34,7 @@ impl InterceptorLogger {
} }
pub fn init(&'static self) { pub fn init(&'static self) {
match log::set_logger(self) match log::set_logger(self).map(|()| log::set_max_level(LevelFilter::Info)) {
.map(|()| log::set_max_level(LevelFilter::Info)) {
Ok(()) => {} Ok(()) => {}
Err(e) => { Err(e) => {
error!("Logger already set: {}", e); error!("Logger already set: {}", e);

View File

@@ -239,7 +239,7 @@ async fn safe_main(spawner: Spawner) -> FatResult<()> {
println!("starting webserver"); println!("starting webserver");
let _ = http_server(reboot_now.clone(), stack); let _ = http_server(reboot_now.clone(), stack);
wait_infinity(board, WaitType::MissingConfig, reboot_now.clone()).await; wait_infinity(board, WaitType::MissingConfig, reboot_now.clone(), UTC).await;
} }
let mut stack: OptionLock<Stack> = OptionLock::empty(); let mut stack: OptionLock<Stack> = OptionLock::empty();
@@ -276,7 +276,6 @@ async fn safe_main(spawner: Spawner) -> FatResult<()> {
}), }),
None => UTC, // Fallback to UTC if no timezone is set None => UTC, // Fallback to UTC if no timezone is set
}; };
let _timezone = UTC;
let timezone_time = cur.with_timezone(&timezone); let timezone_time = cur.with_timezone(&timezone);
info!( info!(
@@ -321,7 +320,7 @@ async fn safe_main(spawner: Spawner) -> FatResult<()> {
} else { } else {
bail!("Network stack missing, hard abort") bail!("Network stack missing, hard abort")
} }
wait_infinity(board, WaitType::ConfigButton, reboot_now.clone()).await; wait_infinity(board, WaitType::ConfigButton, reboot_now.clone(), timezone).await;
} else { } else {
log(LogMessage::NormalRun, 0, 0, "", ""); log(LogMessage::NormalRun, 0, 0, "", "");
} }
@@ -578,19 +577,18 @@ async fn safe_main(spawner: Spawner) -> FatResult<()> {
.mqtt_publish("/deepsleep", "night 1h").await; .mqtt_publish("/deepsleep", "night 1h").await;
60 60
}; };
let _ = board let _ = board
.board_hal .board_hal
.get_esp() .get_esp()
.mqtt_publish("/state", "sleep") .mqtt_publish("/state", "sleep")
.await; .await;
info!("Go to sleep for {deep_sleep_duration_minutes} minutes"); info!("Go to sleep for {deep_sleep_duration_minutes} minutes");
//determine next event //determine next event
//is light out of work trigger soon? //is light out of work trigger soon?
//is battery low ?? //is battery low ??
//is deep sleep //is deep sleep
//TODO
//mark_app_valid();
let stay_alive = MQTT_STAY_ALIVE.load(Ordering::Relaxed); let stay_alive = MQTT_STAY_ALIVE.load(Ordering::Relaxed);
info!("Check stay alive, current state is {stay_alive}"); info!("Check stay alive, current state is {stay_alive}");
@@ -599,7 +597,7 @@ async fn safe_main(spawner: Spawner) -> FatResult<()> {
let reboot_now = Arc::new(AtomicBool::new(false)); let reboot_now = Arc::new(AtomicBool::new(false));
if let Some(s) = stack.take() { if let Some(s) = stack.take() {
spawner.spawn(http_server(reboot_now.clone(), s))?; spawner.spawn(http_server(reboot_now.clone(), s))?;
wait_infinity(board, WaitType::MqttConfig, reboot_now.clone()).await; wait_infinity(board, WaitType::MqttConfig, reboot_now.clone(), timezone).await;
} else { } else {
bail!("Network Stack missing, hard abort"); bail!("Network Stack missing, hard abort");
} }
@@ -740,6 +738,9 @@ pub async fn do_secure_pump(
Timer::after(sleep_time).await; Timer::after(sleep_time).await;
pump_time_ms += 50; pump_time_ms += 50;
} }
} else {
//noticable dummy value
pump_time_ms = 1337;
} }
board.board_hal.get_tank_sensor()?.stop_flow_meter(); board.board_hal.get_tank_sensor()?.stop_flow_meter();
let final_flow_value = board.board_hal.get_tank_sensor()?.get_flow_meter_value(); let final_flow_value = board.board_hal.get_tank_sensor()?.get_flow_meter_value();
@@ -975,6 +976,7 @@ async fn wait_infinity(
board: MutexGuard<'_, CriticalSectionRawMutex, HAL<'static>>, board: MutexGuard<'_, CriticalSectionRawMutex, HAL<'static>>,
wait_type: WaitType, wait_type: WaitType,
reboot_now: Arc<AtomicBool>, reboot_now: Arc<AtomicBool>,
timezone: Tz,
) -> ! { ) -> ! {
//since we force to have the lock when entering, we can release it to ensure the caller does not forget to dispose of it //since we force to have the lock when entering, we can release it to ensure the caller does not forget to dispose of it
drop(board); drop(board);
@@ -984,6 +986,7 @@ async fn wait_infinity(
let mut pattern_step = 0; let mut pattern_step = 0;
let serial_config_receive = AtomicBool::new(false); let serial_config_receive = AtomicBool::new(false);
let mut suppress_further_mppt_error = false; let mut suppress_further_mppt_error = false;
let mut last_mqtt_update: Option<Instant> = None;
// Long-press exit (for webserver config modes): hold boot button for 5 seconds. // Long-press exit (for webserver config modes): hold boot button for 5 seconds.
let mut exit_hold_started: Option<Instant> = None; let mut exit_hold_started: Option<Instant> = None;
@@ -1060,6 +1063,22 @@ async fn wait_infinity(
} }
} }
// MQTT updates in config mode
let now = Instant::now();
if last_mqtt_update.is_none()
|| now.duration_since(last_mqtt_update.unwrap_or(Instant::from_secs(0)))
>= Duration::from_secs(60)
{
let cur = board.board_hal.get_time().await;
let timezone_time = cur.with_timezone(&timezone);
let esp = board.board_hal.get_esp();
esp.mqtt_publish("/firmware/state", "config").await;
esp.mqtt_publish("/firmware/last_online", &timezone_time.to_rfc3339())
.await;
last_mqtt_update = Some(now);
}
// Skip default blink code when a progress display is active // Skip default blink code when a progress display is active
if !PROGRESS_ACTIVE.load(Ordering::Relaxed) { if !PROGRESS_ACTIVE.load(Ordering::Relaxed) {
match wait_type { match wait_type {