Improve error handling, ensure robust defaults, and eliminate unsafe unwraps/expectations across modules.
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
reason = "mem::forget is generally not safe to do with esp_hal types, especially those \
|
||||
holding buffers for the duration of a data transfer."
|
||||
)]
|
||||
#![deny(clippy::unwrap_used, clippy::expect_used, clippy::panic)]
|
||||
|
||||
//TODO insert version here and read it in other parts, also read this for the ota webview
|
||||
esp_bootloader_esp_idf::esp_app_desc!();
|
||||
@@ -39,7 +40,7 @@ use embassy_net::Stack;
|
||||
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||
use embassy_sync::mutex::{Mutex, MutexGuard};
|
||||
use embassy_sync::once_lock::OnceLock;
|
||||
use embassy_time::{Duration, Instant, Timer, WithTimeout};
|
||||
use embassy_time::{Duration, Instant, Timer};
|
||||
use esp_hal::rom::ets_delay_us;
|
||||
use esp_hal::system::software_reset;
|
||||
use esp_println::{logger, println};
|
||||
@@ -297,7 +298,9 @@ async fn safe_main(spawner: Spawner) -> FatResult<()> {
|
||||
|
||||
if let NetworkMode::Wifi { ref ip_address, .. } = network_mode {
|
||||
publish_firmware_info(&mut board, version, ip_address, &timezone_time.to_rfc3339()).await;
|
||||
publish_battery_state(&mut board).await;
|
||||
publish_battery_state(&mut board).await.unwrap_or_else(|e| {
|
||||
error!("Error publishing battery state {e}");
|
||||
});
|
||||
let _ = publish_mppt_state(&mut board).await;
|
||||
}
|
||||
|
||||
@@ -326,7 +329,12 @@ async fn safe_main(spawner: Spawner) -> FatResult<()> {
|
||||
info!("executing config mode override");
|
||||
//config upload will trigger reboot!
|
||||
let reboot_now = Arc::new(AtomicBool::new(false));
|
||||
spawner.spawn(http_server(reboot_now.clone(), stack.take().unwrap()))?;
|
||||
let stack_val = stack.take();
|
||||
if let Some(s) = stack_val {
|
||||
spawner.spawn(http_server(reboot_now.clone(), s))?;
|
||||
} else {
|
||||
bail!("Network stack missing, hard abort")
|
||||
}
|
||||
wait_infinity(board, WaitType::ConfigButton, reboot_now.clone()).await;
|
||||
} else {
|
||||
LOG_ACCESS
|
||||
@@ -406,7 +414,11 @@ async fn safe_main(spawner: Spawner) -> FatResult<()> {
|
||||
}
|
||||
info!("Water temp is {}", water_temp.as_ref().unwrap_or(&0.));
|
||||
|
||||
publish_tank_state(&mut board, &tank_state, water_temp).await;
|
||||
publish_tank_state(&mut board, &tank_state, water_temp)
|
||||
.await
|
||||
.unwrap_or_else(|e| {
|
||||
error!("Error publishing tank state {e}");
|
||||
});
|
||||
|
||||
let moisture = board.board_hal.measure_moisture_hz().await?;
|
||||
|
||||
@@ -421,7 +433,11 @@ async fn safe_main(spawner: Spawner) -> FatResult<()> {
|
||||
PlantState::read_hardware_state(moisture, 7, &mut board).await,
|
||||
];
|
||||
|
||||
publish_plant_states(&mut board, &timezone_time.clone(), &plantstate).await;
|
||||
publish_plant_states(&mut board, &timezone_time.clone(), &plantstate)
|
||||
.await
|
||||
.unwrap_or_else(|e| {
|
||||
error!("Error publishing plant states {e}");
|
||||
});
|
||||
|
||||
let pump_required = plantstate
|
||||
.iter()
|
||||
@@ -625,14 +641,18 @@ async fn safe_main(spawner: Spawner) -> FatResult<()> {
|
||||
|
||||
if stay_alive {
|
||||
let reboot_now = Arc::new(AtomicBool::new(false));
|
||||
let _webserver = http_server(reboot_now.clone(), stack.take().unwrap());
|
||||
wait_infinity(board, WaitType::MqttConfig, reboot_now.clone()).await;
|
||||
if let Some(s) = stack.take() {
|
||||
let _webserver = http_server(reboot_now.clone(), s);
|
||||
wait_infinity(board, WaitType::MqttConfig, reboot_now.clone()).await;
|
||||
} else {
|
||||
bail!("Network Stack missing, hard abort");
|
||||
}
|
||||
} else {
|
||||
//TODO wait for all mqtt publishes?
|
||||
Timer::after_millis(5000).await;
|
||||
|
||||
board.board_hal.get_esp().set_restart_to_conf(false);
|
||||
board
|
||||
let _ = board
|
||||
.board_hal
|
||||
.deep_sleep(1000 * 1000 * 60 * deep_sleep_duration_minutes as u64)
|
||||
.await;
|
||||
@@ -801,30 +821,29 @@ async fn publish_tank_state(
|
||||
board: &mut MutexGuard<'_, CriticalSectionRawMutex, HAL<'static>>,
|
||||
tank_state: &TankState,
|
||||
water_temp: FatResult<f32>,
|
||||
) {
|
||||
) -> FatResult<()> {
|
||||
let state = serde_json::to_string(
|
||||
&tank_state.as_mqtt_info(&board.board_hal.get_config().tank, &water_temp),
|
||||
)
|
||||
.unwrap();
|
||||
)?;
|
||||
board
|
||||
.board_hal
|
||||
.get_esp()
|
||||
.mqtt_publish("/water", &state)
|
||||
.await;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn publish_plant_states(
|
||||
board: &mut MutexGuard<'_, CriticalSectionRawMutex, HAL<'static>>,
|
||||
timezone_time: &DateTime<Tz>,
|
||||
plantstate: &[PlantState; 8],
|
||||
) {
|
||||
) -> FatResult<()> {
|
||||
for (plant_id, (plant_state, plant_conf)) in plantstate
|
||||
.iter()
|
||||
.zip(&board.board_hal.get_config().plants.clone())
|
||||
.enumerate()
|
||||
{
|
||||
let state =
|
||||
serde_json::to_string(&plant_state.to_mqtt_info(plant_conf, timezone_time)).unwrap();
|
||||
let state = serde_json::to_string(&plant_state.to_mqtt_info(plant_conf, timezone_time))?;
|
||||
let plant_topic = format!("/plant{}", plant_id + 1);
|
||||
let _ = board
|
||||
.board_hal
|
||||
@@ -832,6 +851,7 @@ async fn publish_plant_states(
|
||||
.mqtt_publish(&plant_topic, &state)
|
||||
.await;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn publish_firmware_info(
|
||||
@@ -907,13 +927,9 @@ async fn try_connect_wifi_sntp_mqtt(
|
||||
|
||||
let ip = match stack.config_v4() {
|
||||
Some(config) => config.address.address().to_string(),
|
||||
None => {
|
||||
match stack.config_v6() {
|
||||
Some(config) => config.address.address().to_string(),
|
||||
None => {
|
||||
String::from("No IP")
|
||||
}
|
||||
}
|
||||
None => match stack.config_v6() {
|
||||
Some(config) => config.address.address().to_string(),
|
||||
None => String::from("No IP"),
|
||||
},
|
||||
};
|
||||
NetworkMode::Wifi {
|
||||
@@ -987,11 +1003,11 @@ async fn publish_mppt_state(
|
||||
|
||||
async fn publish_battery_state(
|
||||
board: &mut MutexGuard<'_, CriticalSectionRawMutex, HAL<'static>>,
|
||||
) -> () {
|
||||
) -> FatResult<()> {
|
||||
let state = board.board_hal.get_battery_monitor().get_state().await;
|
||||
let value = match state {
|
||||
Ok(state) => {
|
||||
let json = serde_json::to_string(&state).unwrap().to_owned();
|
||||
let json = serde_json::to_string(&state)?.to_owned();
|
||||
json.to_owned()
|
||||
}
|
||||
Err(_) => "error".to_owned(),
|
||||
@@ -1003,6 +1019,7 @@ async fn publish_battery_state(
|
||||
.mqtt_publish("/battery", &value)
|
||||
.await;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn wait_infinity(
|
||||
@@ -1049,8 +1066,7 @@ async fn wait_infinity(
|
||||
exit_hold_blink = !exit_hold_blink;
|
||||
|
||||
let progress = core::cmp::min(elapsed, exit_hold_duration);
|
||||
let lit = ((progress.as_millis() * 8)
|
||||
/ exit_hold_duration.as_millis())
|
||||
let lit = ((progress.as_millis() * 8) / exit_hold_duration.as_millis())
|
||||
.saturating_add(1)
|
||||
.min(8) as usize;
|
||||
|
||||
@@ -1200,6 +1216,8 @@ async fn handle_serial_config(
|
||||
}
|
||||
}
|
||||
|
||||
use embassy_time::WithTimeout;
|
||||
#[allow(clippy::panic, clippy::unwrap_used, clippy::expect_used)]
|
||||
#[esp_rtos::main]
|
||||
async fn main(spawner: Spawner) -> ! {
|
||||
// intialize embassy
|
||||
|
||||
Reference in New Issue
Block a user