use crate::config::PlantControllerConfig; use crate::fat_error::FatResult; use crate::hal::esp_set_time; use crate::webserver::read_up_to_bytes_from_request; use crate::{do_secure_pump, BOARD_ACCESS}; use alloc::string::{String, ToString}; use alloc::vec::Vec; use chrono::DateTime; use edge_http::io::server::Connection; use edge_nal::io::{Read, Write}; use log::info; use serde::{Deserialize, Serialize}; #[derive(Deserialize)] pub struct NightLampCommand { active: bool, } #[derive(Serialize, Debug)] struct SSIDList { ssids: Vec, } #[derive(Deserialize, Debug)] struct SetTime<'a> { time: &'a str, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] pub struct TestPump { pump: usize, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] pub struct CanPower { state: bool, } pub(crate) async fn wifi_scan( _request: &mut Connection<'_, T, N>, ) -> FatResult> { let mut board = BOARD_ACCESS.get().await.lock().await; info!("start wifi scan"); let mut ssids: Vec = Vec::new(); let scan_result = board.board_hal.get_esp().wifi_scan().await?; scan_result .iter() .for_each(|s| ssids.push(s.ssid.to_string())); let ssid_json = serde_json::to_string(&SSIDList { ssids })?; info!("Sending ssid list {}", &ssid_json); Ok(Some(ssid_json)) } pub(crate) async fn board_test() -> FatResult> { let mut board = BOARD_ACCESS.get().await.lock().await; board.board_hal.test().await?; Ok(None) } pub(crate) async fn detect_sensors() -> FatResult> { let mut board = BOARD_ACCESS.get().await.lock().await; let result = board.board_hal.detect_sensors().await?; let json = serde_json::to_string(&result)?; Ok(Some(json)) } pub(crate) async fn pump_test( request: &mut Connection<'_, T, N>, ) -> FatResult> 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?)?)) } pub(crate) async fn night_lamp_test( request: &mut Connection<'_, T, N>, ) -> FatResult> 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) } pub(crate) async fn write_time( request: &mut Connection<'_, T, N>, ) -> FatResult> where T: Read + Write, { 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).unwrap(); esp_set_time(parsed).await?; Ok(None) } pub(crate) async fn set_config( request: &mut Connection<'_, T, N>, ) -> FatResult> where T: Read + Write, { let all = read_up_to_bytes_from_request(request, Some(4096)).await?; let length = all.len(); let config: PlantControllerConfig = serde_json::from_slice(&all)?; let mut board = BOARD_ACCESS.get().await.lock().await; board.board_hal.get_esp().save_config(all).await?; info!("Wrote config config {config:?} with size {length}"); board.board_hal.set_config(config); Ok(Some("Ok".to_string())) } pub(crate) async fn can_power( request: &mut Connection<'_, T, N>, ) -> FatResult> where T: Read + Write, { let actual_data = read_up_to_bytes_from_request(request, None).await?; let can_power_request: CanPower = serde_json::from_slice(&actual_data)?; let mut board = BOARD_ACCESS.get().await.lock().await; board.board_hal.can_power(can_power_request.state).await?; let enable = can_power_request.state; info!( "set can power to {enable}" ); Ok(None) }