bring selftest online, bring tz online, fix set_config/get_config race

This commit is contained in:
2025-09-24 22:29:58 +02:00
parent 5b009f50e5
commit e20b474dfd
13 changed files with 247 additions and 344 deletions

View File

@@ -5,8 +5,8 @@ use crate::hal::rtc::X25;
use crate::hal::{esp_set_time, esp_time};
use crate::log::LOG_ACCESS;
use crate::tank::determine_tank_state;
use crate::FatError::{FatError, FatResult};
use crate::{bail, get_version, log::LogMessage, BOARD_ACCESS};
use crate::fat_error::{FatError, FatResult};
use crate::{bail, do_secure_pump, get_version, log::LogMessage, BOARD_ACCESS};
use alloc::borrow::ToOwned;
use alloc::format;
use alloc::string::{String, ToString};
@@ -16,8 +16,9 @@ use chrono::DateTime;
use core::fmt::{Debug, Display};
use core::net::{IpAddr, Ipv4Addr, SocketAddr};
use core::result::Result::Ok;
use core::str::from_utf8;
use core::str::{from_utf8, FromStr};
use core::sync::atomic::{AtomicBool, Ordering};
use chrono_tz::Tz;
use edge_http::io::server::{Connection, Handler, Server};
use edge_http::Method;
use edge_nal::TcpBind;
@@ -77,16 +78,7 @@ pub struct NightLampCommand {
//
//
// fn get_timezones(
// _request: &mut Request<&mut EspHttpConnection>,
// ) -> Result<Option<std::string::String>, anyhow::Error> {
// // Get all timezones using chrono-tz
// let timezones: Vec<&'static str> = chrono_tz::TZ_VARIANTS.iter().map(|tz| tz.name()).collect();
//
// // Convert to JSON
// let json = serde_json::to_string(&timezones)?;
// anyhow::Ok(Some(json))
// }
//
// fn get_live_moisture(
// _request: &mut Request<&mut EspHttpConnection>,
@@ -124,51 +116,6 @@ pub struct NightLampCommand {
// anyhow::Ok(Some(json))
// }
//
//
//
//
//
// fn pump_test(
// request: &mut Request<&mut EspHttpConnection>,
// ) -> Result<Option<std::string::String>, anyhow::Error> {
// let actual_data = read_up_to_bytes_from_request(request, None)?;
// let pump_test: TestPump = serde_json::from_slice(&actual_data)?;
// let mut board = BOARD_ACCESS.lock().unwrap();
//
// let config = &board.board_hal.get_config().plants[pump_test.pump].clone();
// let pump_result = do_secure_pump(&mut board, pump_test.pump, config, false)?;
// board.board_hal.pump(pump_test.pump, false)?;
// anyhow::Ok(Some(serde_json::to_string(&pump_result)?))
// }
//
//
// fn night_lamp_test(
// request: &mut Request<&mut EspHttpConnection>,
// ) -> Result<Option<std::string::String>, anyhow::Error> {
// let actual_data = read_up_to_bytes_from_request(request, None)?;
// let light_command: NightLampCommand = serde_json::from_slice(&actual_data)?;
// let mut board = BOARD_ACCESS.lock().unwrap();
// board.board_hal.light(light_command.active)?;
// anyhow::Ok(None)
// }
//
// fn wifi_scan(
// _request: &mut Request<&mut EspHttpConnection>,
// ) -> Result<Option<std::string::String>, anyhow::Error> {
// let mut board = BOARD_ACCESS.lock().unwrap();
// let scan_result = board.board_hal.get_esp().wifi_scan()?;
// let mut ssids: Vec<&String<32>> = Vec::new();
// scan_result.iter().for_each(|s| ssids.push(&s.ssid));
// let ssid_json = serde_json::to_string(&SSIDList { ssids })?;
// log::info!("Sending ssid list {}", &ssid_json);
// anyhow::Ok(Some(ssid_json))
// }
//
//
// fn ota(
// request: &mut Request<&mut EspHttpConnection>,
@@ -403,6 +350,7 @@ impl Handler for HttpHandler {
"/log_localization" => Some(get_log_localization_config(conn).await),
"/tank" => Some(tank_info(conn).await),
"/backup_info" => Some(backup_info(conn).await),
"/timezones" => Some(get_timezones(conn).await),
_ => None,
};
match json {
@@ -417,6 +365,9 @@ impl Handler for HttpHandler {
"/set_config" => Some(set_config(conn).await),
"/time" => Some(write_time(conn).await),
"/backup_config" => Some(backup_config(conn).await),
"/pumptest" => Some(pump_test(conn).await),
"/lamptest" => Some(night_lamp_test(conn).await),
"/boardtest" => Some(board_test(conn).await),
"/reboot" => {
let mut board = BOARD_ACCESS.get().await.lock().await;
board.board_hal.get_esp().set_restart_to_conf(true);
@@ -450,6 +401,60 @@ impl Handler for HttpHandler {
}
}
async fn get_timezones<T, const N: usize>(
request: &mut Connection<'_, T, N>,
) -> FatResult<Option<String>>
where
T: Read + Write,
{
// Get all timezones using chrono-tz
let timezones: Vec<&'static str> = chrono_tz::TZ_VARIANTS.iter().map(|tz| tz.name()).collect();
let json = serde_json::to_string(&timezones)?;
Ok(Some(json))
}
async fn board_test<T, const N: usize>(
request: &mut Connection<'_, T, N>,
) -> FatResult<Option<String>>
where
T: Read + Write,
{
let mut board = BOARD_ACCESS.get().await.lock().await;
board.board_hal.test().await?;
Ok(None)
}
async fn pump_test<T, const N: usize>(
request: &mut Connection<'_, T, N>,
) -> FatResult<Option<String>>
where
T: Read + Write,
{
let actual_data = read_up_to_bytes_from_request(request, None).await?;
let pump_test: TestPump = serde_json::from_slice(&actual_data)?;
let mut board = BOARD_ACCESS.get().await.lock().await;
let config = &board.board_hal.get_config().plants[pump_test.pump].clone();
let pump_result = do_secure_pump(&mut board, pump_test.pump, config, false).await;
//ensure it is disabled before unwrapping
board.board_hal.pump(pump_test.pump, false).await?;
Ok(Some(serde_json::to_string(&pump_result?)?))
}
async fn night_lamp_test<T, const N: usize>(
request: &mut Connection<'_, T, N>,
) -> FatResult<Option<String>>
where
T: Read + Write,
{
let actual_data = read_up_to_bytes_from_request(request, None).await?;
let light_command: NightLampCommand = serde_json::from_slice(&actual_data)?;
let mut board = BOARD_ACCESS.get().await.lock().await;
board.board_hal.light(light_command.active).await?;
Ok(None)
}
async fn get_backup_config<T, const N: usize>(
conn: &mut Connection<'_, T, { N }>,
) -> Result<(), FatError>
@@ -777,11 +782,12 @@ async fn get_time<T, const N: usize>(
_request: &mut Connection<'_, T, N>,
) -> FatResult<Option<String>> {
let mut board = BOARD_ACCESS.get().await.lock().await;
let native = esp_time().await.to_rfc3339();
let conf = board.board_hal.get_config();
let tz = Tz::from_str(conf.timezone.as_ref().unwrap().as_str()).unwrap();
let native = esp_time().await.with_timezone(&tz).to_rfc3339();
let rtc = match board.board_hal.get_rtc_module().get_rtc_time().await {
Ok(time) => time.to_rfc3339(),
Ok(time) => time.with_timezone(&tz).to_rfc3339(),
Err(err) => {
format!("Error getting time: {}", err)
}
@@ -812,77 +818,12 @@ pub async fn httpd(reboot_now: Arc<AtomicBool>, stack: Stack<'static>) {
.expect("TODO: panic message");
println!("Wait for connection...");
// let server_config = Configuration {
// stack_size: 32768,
// ..Default::default()
// };
// let mut server: Box<EspHttpServer<'static>> =
// Box::new(EspHttpServer::new(&server_config).unwrap());
// server
// .fn_handler("/version", Method::Get, |request| {
// handle_error_to500(request, get_version_web)
// })
// .unwrap();
// server
// .fn_handler("/log", Method::Get, |request| {
// handle_error_to500(request, get_log)
// })
// .unwrap();
// server
// .fn_handler("/log_localization", Method::Get, |request| {
// cors_response(request, 200, &get_log_localization_config().unwrap())
// })
// .unwrap();
// server
// .fn_handler("/battery", Method::Get, |request| {
// handle_error_to500(request, get_battery_state)
// })
// .unwrap();
// server
// .fn_handler("/solar", Method::Get, |request| {
// handle_error_to500(request, get_solar_state)
// })
// .unwrap();
// server
// .fn_handler("/time", Method::Get, |request| {
// handle_error_to500(request, get_time)
// })
// .unwrap();
// server
// .fn_handler("/moisture", Method::Get, |request| {
// handle_error_to500(request, get_live_moisture)
// })
// .unwrap();
// server
// .fn_handler("/time", Method::Post, |request| {
// handle_error_to500(request, write_time)
// })
// .unwrap();
// server
// .fn_handler("/tank", Method::Get, |request| {
// handle_error_to500(request, tank_info)
// })
// .unwrap();
// server
// .fn_handler("/pumptest", Method::Post, |request| {
// handle_error_to500(request, pump_test)
// })
// .unwrap();
// server
// .fn_handler("/lamptest", Method::Post, |request| {
// handle_error_to500(request, night_lamp_test)
// })
// .unwrap();
// server
// .fn_handler("/boardtest", Method::Post, move |_| {
// BOARD_ACCESS.lock().unwrap().board_hal.test()
// })
// .unwrap();
// server
// .fn_handler("/wifiscan", Method::Post, move |request| {
// handle_error_to500(request, wifi_scan)
// })
// .unwrap();
// server
// .fn_handler("/ota", Method::Post, |request| {
// handle_error_to500(request, ota)
@@ -917,40 +858,7 @@ pub async fn httpd(reboot_now: Arc<AtomicBool>, stack: Stack<'static>) {
// })
// .unwrap();
// server
//
// unsafe { vTaskDelay(1) };
// server
// .fn_handler("/", Method::Get, move |request| {
// let mut response = request.into_ok_response()?;
// response.write(include_bytes!("index.html"))?;
// anyhow::Ok(())
// })
// .unwrap();
// server
// .fn_handler("/favicon.ico", Method::Get, |request| {
// request
// .into_ok_response()?
// .write(include_bytes!("favicon.ico"))?;
// anyhow::Ok(())
// })
// .unwrap();
// server
// .fn_handler("/bundle.js", Method::Get, |request| {
// request
// .into_ok_response()?
// .write(include_bytes!("bundle.js"))?;
// anyhow::Ok(())
// })
// .unwrap();
// server
// .fn_handler("/timezones", Method::Get, move |request| {
// handle_error_to500(request, get_timezones)
// })
// .unwrap();
//server
}
//
async fn handle_json<'a, T, const N: usize>(
conn: &mut Connection<'a, T, N>,