i2c working, rtc working, eeprom working
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
//offer ota and config mode
|
||||
|
||||
use crate::config::PlantControllerConfig;
|
||||
use crate::hal::rtc::X25;
|
||||
use crate::hal::{esp_set_time, esp_time};
|
||||
use crate::log::LOG_ACCESS;
|
||||
use crate::tank::{determine_tank_state, TankInfo};
|
||||
@@ -123,56 +124,9 @@ pub struct NightLampCommand {
|
||||
// anyhow::Ok(Some(json))
|
||||
// }
|
||||
//
|
||||
|
||||
//
|
||||
// fn backup_config(
|
||||
// request: &mut Request<&mut EspHttpConnection>,
|
||||
// ) -> Result<Option<std::string::String>, anyhow::Error> {
|
||||
// let all = read_up_to_bytes_from_request(request, Some(3072))?;
|
||||
// let mut board = BOARD_ACCESS.lock().expect("board access");
|
||||
//
|
||||
// //TODO how to handle progress here? prior versions animated the fault leds while running
|
||||
// board.board_hal.get_rtc_module().backup_config(&all)?;
|
||||
// anyhow::Ok(Some("saved".to_owned()))
|
||||
// }
|
||||
//
|
||||
// fn get_backup_config(
|
||||
// _request: &mut Request<&mut EspHttpConnection>,
|
||||
// ) -> Result<Option<std::string::String>, anyhow::Error> {
|
||||
// let mut board = BOARD_ACCESS.lock().expect("board access");
|
||||
// let json = match board.board_hal.get_rtc_module().get_backup_config() {
|
||||
// Ok(config) => from_utf8(&config)?.to_owned(),
|
||||
// Err(err) => {
|
||||
// log::info!("Error get backup config {:?}", err);
|
||||
// err.to_string()
|
||||
// }
|
||||
// };
|
||||
// anyhow::Ok(Some(json))
|
||||
// }
|
||||
//
|
||||
// fn backup_info(
|
||||
// _request: &mut Request<&mut EspHttpConnection>,
|
||||
// ) -> Result<Option<std::string::String>, anyhow::Error> {
|
||||
// let mut board = BOARD_ACCESS.lock().expect("Should never fail");
|
||||
// let header = board.board_hal.get_rtc_module().get_backup_info();
|
||||
// let json = match header {
|
||||
// Ok(h) => {
|
||||
// let timestamp = DateTime::from_timestamp_millis(h.timestamp).unwrap();
|
||||
// let wbh = WebBackupHeader {
|
||||
// timestamp: timestamp.to_rfc3339(),
|
||||
// size: h.size,
|
||||
// };
|
||||
// serde_json::to_string(&wbh)?
|
||||
// }
|
||||
// Err(err) => {
|
||||
// let wbh = WebBackupHeader {
|
||||
// timestamp: err.to_string(),
|
||||
// size: 0,
|
||||
// };
|
||||
// serde_json::to_string(&wbh)?
|
||||
// }
|
||||
// };
|
||||
// anyhow::Ok(Some(json))
|
||||
// }
|
||||
|
||||
//
|
||||
|
||||
//
|
||||
@@ -415,6 +369,10 @@ impl Handler for HttpHandler {
|
||||
let buf = get_log(conn).await;
|
||||
Some(200)
|
||||
}
|
||||
"/get_backup_config" => {
|
||||
get_backup_config(conn).await?;
|
||||
Some(200)
|
||||
}
|
||||
&_ => {
|
||||
let json = match path {
|
||||
"/version" => Some(get_version_web(conn).await),
|
||||
@@ -424,7 +382,8 @@ impl Handler for HttpHandler {
|
||||
"/get_config" => Some(get_config(conn).await),
|
||||
"/files" => Some(list_files(conn).await),
|
||||
"/log_localization" => Some(get_log_localization_config(conn).await),
|
||||
"/wifiscan" => Some(wifi_scan(conn).await),
|
||||
"/tank" => Some(tank_info(conn).await),
|
||||
"/backup_info" => Some(backup_info(conn).await),
|
||||
_ => None,
|
||||
};
|
||||
match json {
|
||||
@@ -438,6 +397,7 @@ impl Handler for HttpHandler {
|
||||
"/wifiscan" => Some(wifi_scan(conn).await),
|
||||
"/set_config" => Some(set_config(conn).await),
|
||||
"/time" => Some(write_time(conn).await),
|
||||
"/backup_config" => Some(backup_config(conn).await),
|
||||
"/reboot" => {
|
||||
let mut board = BOARD_ACCESS.get().await.lock().await;
|
||||
board.board_hal.get_esp().set_restart_to_conf(true);
|
||||
@@ -471,101 +431,173 @@ impl Handler for HttpHandler {
|
||||
}
|
||||
}
|
||||
|
||||
// .fn_handler("/file", Method::Get, move |request| {
|
||||
// let filename = query_param(request.uri(), "filename").unwrap();
|
||||
// let file_handle = BOARD_ACCESS
|
||||
// .lock()
|
||||
// .unwrap()
|
||||
// .board_hal
|
||||
// .get_esp()
|
||||
// .get_file_handle(&filename, false);
|
||||
// match file_handle {
|
||||
// Ok(mut file_handle) => {
|
||||
// let headers = [("Access-Control-Allow-Origin", "*")];
|
||||
// let mut response = request.into_response(200, None, &headers)?;
|
||||
// const BUFFER_SIZE: usize = 512;
|
||||
// let mut buffer: [u8; BUFFER_SIZE] = [0; BUFFER_SIZE];
|
||||
// let mut total_read: usize = 0;
|
||||
// loop {
|
||||
// unsafe { vTaskDelay(1) };
|
||||
// let read = std::io::Read::read(&mut file_handle, &mut buffer)?;
|
||||
// total_read += read;
|
||||
// let to_write = &buffer[0..read];
|
||||
// response.write(to_write)?;
|
||||
// if read == 0 {
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// log::info!("wrote {total_read} for file {filename}");
|
||||
// drop(file_handle);
|
||||
// response.flush()?;
|
||||
// }
|
||||
// Err(err) => {
|
||||
// //todo set headers here for filename to be error
|
||||
// let error_text = err.to_string();
|
||||
// log::info!("error handling get file {}", error_text);
|
||||
// cors_response(request, 500, &error_text)?;
|
||||
// }
|
||||
// }
|
||||
// anyhow::Ok(())
|
||||
// })
|
||||
// .unwrap();
|
||||
// server
|
||||
// .fn_handler("/file", Method::Post, move |mut request| {
|
||||
// let filename = query_param(request.uri(), "filename").unwrap();
|
||||
// let mut board = BOARD_ACCESS.lock().unwrap();
|
||||
// let file_handle = board.board_hal.get_esp().get_file_handle(&filename, true);
|
||||
// match file_handle {
|
||||
// //TODO get free filesystem size, check against during write if not to large
|
||||
// Ok(mut file_handle) => {
|
||||
// const BUFFER_SIZE: usize = 512;
|
||||
// let mut buffer: [u8; BUFFER_SIZE] = [0; BUFFER_SIZE];
|
||||
// let mut total_read: usize = 0;
|
||||
// let mut lastiter = 0;
|
||||
// loop {
|
||||
// let iter = (total_read / 1024) % 8;
|
||||
// if iter != lastiter {
|
||||
// for i in 0..PLANT_COUNT {
|
||||
// let _ = board.board_hal.fault(i, iter == i);
|
||||
// }
|
||||
// lastiter = iter;
|
||||
// }
|
||||
//
|
||||
// let read = request.read(&mut buffer)?;
|
||||
// total_read += read;
|
||||
// let to_write = &buffer[0..read];
|
||||
// std::io::Write::write(&mut file_handle, to_write)?;
|
||||
// if read == 0 {
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// cors_response(request, 200, &format!("saved {total_read} bytes"))?;
|
||||
// }
|
||||
// Err(err) => {
|
||||
// //todo set headers here for filename to be error
|
||||
// let error_text = err.to_string();
|
||||
// log::info!("error handling get file {}", error_text);
|
||||
// cors_response(request, 500, &error_text)?;
|
||||
// }
|
||||
// }
|
||||
// drop(board);
|
||||
// anyhow::Ok(())
|
||||
// })
|
||||
// .unwrap();
|
||||
async fn get_backup_config<T, const N: usize>(
|
||||
conn: &mut Connection<'_, T, { N }>,
|
||||
) -> Result<(), FatError>
|
||||
where
|
||||
T: Read + Write,
|
||||
{
|
||||
let mut checksum = X25.digest();
|
||||
let mut chunk = 0_usize;
|
||||
loop {
|
||||
info!("Chunk {}", chunk);
|
||||
let mut board = BOARD_ACCESS.get().await.lock().await;
|
||||
board.board_hal.progress(chunk as u32).await;
|
||||
let read_chunk = board
|
||||
.board_hal
|
||||
.get_rtc_module()
|
||||
.get_backup_config(chunk)
|
||||
.await?;
|
||||
let length = read_chunk.1;
|
||||
info!("Length {}", length);
|
||||
if length == 0 {
|
||||
let check = checksum.finalize();
|
||||
if check != read_chunk.2 {
|
||||
if check != read_chunk.2 {
|
||||
conn.initiate_response(
|
||||
409,
|
||||
Some(
|
||||
format!("Checksum mismatch expected {} got {}", read_chunk.2, check)
|
||||
.as_str(),
|
||||
),
|
||||
&[],
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
info!("file request for backup finished");
|
||||
break;
|
||||
}
|
||||
let data = &read_chunk.0[0..length];
|
||||
checksum.update(&data);
|
||||
if length < read_chunk.0.len() {
|
||||
let check = checksum.finalize();
|
||||
if check != read_chunk.2 {
|
||||
conn.initiate_response(
|
||||
409,
|
||||
Some(
|
||||
format!("Checksum mismatch expected {} got {}", read_chunk.2, check)
|
||||
.as_str(),
|
||||
),
|
||||
&[],
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
info!("file request for backup finished");
|
||||
break;
|
||||
}
|
||||
chunk = chunk + 1;
|
||||
}
|
||||
conn.initiate_response(200, Some("OK"), &[]).await?;
|
||||
|
||||
async fn tank_info<T, const N: usize>(
|
||||
request: &mut Connection<'_, T, N>,
|
||||
let mut chunk = 0;
|
||||
loop {
|
||||
let mut board = BOARD_ACCESS.get().await.lock().await;
|
||||
board.board_hal.progress(chunk as u32).await;
|
||||
let read_chunk = board
|
||||
.board_hal
|
||||
.get_rtc_module()
|
||||
.get_backup_config(chunk)
|
||||
.await?;
|
||||
let length = read_chunk.1;
|
||||
if length == 0 {
|
||||
info!("file request for backup finished");
|
||||
break;
|
||||
}
|
||||
let data = &read_chunk.0[0..length];
|
||||
conn.write_all(data).await?;
|
||||
if length < read_chunk.0.len() {
|
||||
info!("file request for backup finished");
|
||||
break;
|
||||
}
|
||||
chunk = chunk + 1;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn backup_config<T, const N: usize>(
|
||||
conn: &mut Connection<'_, T, N>,
|
||||
) -> FatResult<Option<String>>
|
||||
where
|
||||
T: Read + Write,
|
||||
{
|
||||
let mut offset = 0_usize;
|
||||
let mut buf = [0_u8; 32];
|
||||
|
||||
let mut checksum = crate::hal::rtc::X25.digest();
|
||||
|
||||
let mut counter = 0;
|
||||
loop {
|
||||
let to_write = conn.read(&mut buf).await?;
|
||||
if to_write == 0 {
|
||||
info!("backup finished");
|
||||
break;
|
||||
} else {
|
||||
let mut board = BOARD_ACCESS.get().await.lock().await;
|
||||
board.board_hal.progress(counter).await;
|
||||
|
||||
counter = counter + 1;
|
||||
board
|
||||
.board_hal
|
||||
.get_rtc_module()
|
||||
.backup_config(offset, &buf[0..to_write])
|
||||
.await?;
|
||||
checksum.update(&buf[0..to_write]);
|
||||
}
|
||||
offset = offset + to_write;
|
||||
}
|
||||
|
||||
let mut board = BOARD_ACCESS.get().await.lock().await;
|
||||
board
|
||||
.board_hal
|
||||
.get_rtc_module()
|
||||
.backup_config_finalize(checksum.finalize(), offset)
|
||||
.await?;
|
||||
Ok(Some("saved".to_owned()))
|
||||
}
|
||||
|
||||
async fn backup_info<T, const N: usize>(
|
||||
_request: &mut Connection<'_, T, N>,
|
||||
) -> Result<Option<String>, FatError>
|
||||
where
|
||||
T: Read + Write,
|
||||
{
|
||||
let mut board = BOARD_ACCESS.get().await.lock().await;
|
||||
determine_tank_state(&mut board);
|
||||
//should be multsampled
|
||||
let header = board.board_hal.get_rtc_module().get_backup_info().await;
|
||||
let json = match header {
|
||||
Ok(h) => {
|
||||
let timestamp = DateTime::from_timestamp_millis(h.timestamp).unwrap();
|
||||
let wbh = WebBackupHeader {
|
||||
timestamp: timestamp.to_rfc3339(),
|
||||
size: h.size,
|
||||
};
|
||||
serde_json::to_string(&wbh)?
|
||||
}
|
||||
Err(err) => {
|
||||
let wbh = WebBackupHeader {
|
||||
timestamp: err.to_string(),
|
||||
size: 0,
|
||||
};
|
||||
serde_json::to_string(&wbh)?
|
||||
}
|
||||
};
|
||||
Ok(Some(json))
|
||||
}
|
||||
|
||||
async fn tank_info<T, const N: usize>(
|
||||
_request: &mut Connection<'_, T, N>,
|
||||
) -> Result<Option<String>, FatError>
|
||||
where
|
||||
T: Read + Write,
|
||||
{
|
||||
let mut board = BOARD_ACCESS.get().await.lock().await;
|
||||
let tank_state = determine_tank_state(&mut board).await;
|
||||
//should be multisampled
|
||||
let sensor = board.board_hal.get_tank_sensor()?;
|
||||
|
||||
let water_temp = sensor.water_temperature_c().await?;
|
||||
Ok(Some(serde_json::to_string(&tank_info.as_mqtt_info(
|
||||
let water_temp: FatResult<f32> = sensor.water_temperature_c().await;
|
||||
Ok(Some(serde_json::to_string(&tank_state.as_mqtt_info(
|
||||
&board.board_hal.get_config().tank,
|
||||
&water_temp,
|
||||
))?))
|
||||
@@ -892,29 +924,6 @@ pub async fn httpd(reboot_now: Arc<AtomicBool>, stack: Stack<'static>) {
|
||||
// server
|
||||
|
||||
//
|
||||
// server
|
||||
// .fn_handler("/file", Method::Delete, move |request| {
|
||||
// let filename = query_param(request.uri(), "filename").unwrap();
|
||||
// let copy = filename.clone();
|
||||
// let mut board = BOARD_ACCESS.lock().unwrap();
|
||||
// match board.board_hal.get_esp().delete_file(&filename) {
|
||||
// Ok(_) => {
|
||||
// let info = format!("Deleted file {copy}");
|
||||
// cors_response(request, 200, &info)?;
|
||||
// }
|
||||
// Err(err) => {
|
||||
// let info = format!("Could not delete file {copy} {err:?}");
|
||||
// cors_response(request, 400, &info)?;
|
||||
// }
|
||||
// }
|
||||
// anyhow::Ok(())
|
||||
// })
|
||||
// .unwrap();
|
||||
// server
|
||||
// .fn_handler("/file", Method::Options, |request| {
|
||||
// cors_response(request, 200, "")
|
||||
// })
|
||||
// .unwrap();
|
||||
// unsafe { vTaskDelay(1) };
|
||||
// server
|
||||
// .fn_handler("/", Method::Get, move |request| {
|
||||
|
||||
Reference in New Issue
Block a user