add: implement UART-based serial configuration handling and improve error handling in charge indicator updates

This commit is contained in:
2026-01-05 19:57:57 +01:00
parent 8fc2a89503
commit 1de40085fb
5 changed files with 124 additions and 24 deletions

View File

@@ -13,7 +13,7 @@
esp_bootloader_esp_idf::esp_app_desc!();
use esp_backtrace as _;
use crate::config::{NetworkConfig, PlantConfig};
use crate::config::{NetworkConfig, PlantConfig, PlantControllerConfig};
use crate::fat_error::FatResult;
use crate::hal::esp::MQTT_STAY_ALIVE;
use crate::hal::PROGRESS_ACTIVE;
@@ -25,11 +25,12 @@ use crate::{
config::BoardVersion::Initial,
hal::{PlantHal, HAL, PLANT_COUNT},
};
use ::log::{info, warn};
use ::log::{error, info, warn};
use alloc::borrow::ToOwned;
use alloc::string::{String, ToString};
use alloc::sync::Arc;
use alloc::{format, vec};
use alloc::vec::Vec;
use chrono::{DateTime, Datelike, Timelike, Utc};
use chrono_tz::Tz::{self, UTC};
use core::sync::atomic::{AtomicBool, Ordering};
@@ -188,7 +189,15 @@ async fn safe_main(spawner: Spawner) -> FatResult<()> {
.await;
}
info!("cur is {cur}");
update_charge_indicator(&mut board).await;
match update_charge_indicator(&mut board).await {
Ok(_) => {}
Err(error) => {
board.board_hal.general_fault(true).await;
error!("Error updating charge indicator: {error}");
log(LogMessage::MPPTError, 0, 0, "", "").await;
let _ = board.board_hal.set_charge_indicator(false).await;
}
}
if board.board_hal.get_esp().get_restart_to_conf() {
LOG_ACCESS
.lock()
@@ -749,23 +758,18 @@ pub async fn do_secure_pump(
async fn update_charge_indicator(
board: &mut MutexGuard<'static, CriticalSectionRawMutex, HAL<'static>>,
) {
) -> FatResult<()>{
//FIXME add config and code to allow power supply mode, in this case this is a nop
//we have mppt controller, ask it for charging current
if let Ok(current) = board.board_hal.get_mptt_current().await {
let _ = board
.board_hal
.set_charge_indicator(current.as_milliamperes() > 20_f64)
.await;
} else {
//who knows
board.board_hal.general_fault(true).await;
log(LogMessage::MPPTError, 0, 0, "", "").await;
let _ = board.board_hal.set_charge_indicator(false).await;
}
let current = board.board_hal.get_mptt_current().await?;
board
.board_hal
.set_charge_indicator(current.as_milliamperes() > 20_f64)
.await?;
Ok(())
}
async fn publish_tank_state(
board: &mut MutexGuard<'_, CriticalSectionRawMutex, HAL<'static>>,
tank_state: &TankState,
@@ -977,10 +981,27 @@ async fn wait_infinity(
let delay = wait_type.blink_pattern();
let mut led_count = 8;
let mut pattern_step = 0;
let serial_config_receive = AtomicBool::new(false);
let mut suppress_further_mppt_error = false;
loop {
{
let mut board = BOARD_ACCESS.get().await.lock().await;
update_charge_indicator(&mut board).await;
match update_charge_indicator(&mut board).await{
Ok(_) => {}
Err(error) => {
if !suppress_further_mppt_error {
error!("Error updating charge indicator: {error}");
suppress_further_mppt_error = true;
}
}
};
match handle_serial_config(&mut board, &serial_config_receive, &reboot_now).await {
Ok(_) => {}
Err(e) => {
error!("Error handling serial config: {e}");
}
}
// Skip default blink code when a progress display is active
if !PROGRESS_ACTIVE.load(Ordering::Relaxed) {
@@ -1033,6 +1054,7 @@ async fn wait_infinity(
reboot_now.store(true, Ordering::Relaxed);
}
if reboot_now.load(Ordering::Relaxed) {
info!("Rebooting now");
//ensure clean http answer
Timer::after_millis(500).await;
BOARD_ACCESS
@@ -1047,6 +1069,42 @@ async fn wait_infinity(
}
}
async fn handle_serial_config(board: &mut MutexGuard<'_, CriticalSectionRawMutex, HAL<'_>>, serial_config_receive: &AtomicBool, reboot_now: &AtomicBool) -> FatResult<()> {
match board.board_hal.get_esp().read_serial_line().await {
Ok(serial_line) => {
match serial_line {
None => {
Ok(())
}
Some(line) => {
if serial_config_receive.load(Ordering::Relaxed) {
let ll = line.as_str();
let config: PlantControllerConfig = serde_json::from_str(ll)?;
board.board_hal.get_esp().save_config(Vec::from(ll.as_bytes())).await?;
board.board_hal.set_config(config);
serial_config_receive.store(false, Ordering::Relaxed);
info!("Config received, rebooting");
board.board_hal.get_esp().set_restart_to_conf(false);
reboot_now.store(true, Ordering::Relaxed);
Ok(())
} else {
if line == "automation:streamconfig" {
serial_config_receive.store(true, Ordering::Relaxed);
info!("streamconfig:recieving");
}
Ok(())
}
}
}
}
Err(_) => {
error!("Error reading serial line");
Ok(())
}
}
}
#[esp_rtos::main]
async fn main(spawner: Spawner) -> ! {
// intialize embassy