added file manager, upload animation, unsaved config indicator

This commit is contained in:
2025-01-21 01:18:36 +01:00
parent e7556b7ec9
commit 1ce4d74a65
21 changed files with 550 additions and 186 deletions

View File

@@ -956,6 +956,8 @@ fn wait_infinity(wait_type: WaitType, reboot_now: Arc<AtomicBool>) -> ! {
}
}
if reboot_now.load(std::sync::atomic::Ordering::Relaxed) {
//ensure clean http answer
Delay::new_default().delay_ms(500);
BOARD_ACCESS.lock().unwrap().deep_sleep( 1);
}
}
@@ -1067,9 +1069,17 @@ fn get_version() -> VersionInfo {
let branch = env!("VERGEN_GIT_BRANCH").to_owned();
let hash = &env!("VERGEN_GIT_SHA")[0..8];
let running_partition = unsafe { esp_ota_get_running_partition() };
let address = unsafe { (*running_partition).address };
let partition = if address > 20000 {
"ota_1"
} else {
"ota_0"
};
return VersionInfo {
git_hash: (branch + "@" + hash),
build_time: env!("VERGEN_BUILD_TIMESTAMP").to_owned(),
partition: partition.to_owned()
};
}
@@ -1077,4 +1087,5 @@ fn get_version() -> VersionInfo {
struct VersionInfo {
git_hash: String,
build_time: String,
partition: String,
}

View File

@@ -24,7 +24,7 @@ use esp_idf_svc::wifi::EspWifi;
use measurements::Temperature;
use once_cell::sync::Lazy;
use plant_ctrl2::sipo::ShiftRegister40;
use esp_idf_sys::{esp_deep_sleep, esp_sleep_enable_ext1_wakeup, esp_sleep_ext1_wakeup_mode_t_ESP_EXT1_WAKEUP_ANY_LOW};
use esp_idf_sys::{esp_deep_sleep, esp_sleep_enable_ext1_wakeup, esp_sleep_ext1_wakeup_mode_t_ESP_EXT1_WAKEUP_ANY_LOW, esp_spiffs_info};
use esp_idf_sys::esp_restart;
use anyhow::{anyhow, Context};
@@ -182,6 +182,8 @@ pub struct FileInfo {
#[derive(Serialize, Debug)]
pub struct FileList {
total: usize,
used: usize,
files: Vec<FileInfo>,
file_system_corrupt: Option<String>,
iter_error: Option<String>,
@@ -232,19 +234,8 @@ impl PlantCtrlBoard<'_> {
pub fn list_files(&self, filename: &str) -> FileList {
let storage = CString::new(SPIFFS_PARTITION_NAME).unwrap();
let error = unsafe {
esp! {
esp_spiffs_check(storage.as_ptr())
}
};
let mut file_system_corrupt = match error {
OkStd(_) => None,
Err(err) => {
println!("Corrupt spiffs {err:?}");
Some(format!("{err:?}"))
}
};
let mut file_system_corrupt = Option::None;
let mut iter_error = None;
let mut result = Vec::new();
@@ -280,8 +271,15 @@ impl PlantCtrlBoard<'_> {
file_system_corrupt = Some(format!("{err:?}"));
}
}
let mut total:usize = 0;
let mut used:usize = 0;
unsafe {
esp_spiffs_info(storage.as_ptr(), &mut total, &mut used);
}
return FileList {
total,
used,
file_system_corrupt,
files: result,
iter_error,

View File

@@ -5,7 +5,7 @@ use std::{
sync::{atomic::AtomicBool, Arc},
};
use crate::{
espota::OtaUpdate, get_version, map_range_moisture, plant_hal::FileInfo, BOARD_ACCESS,
espota::OtaUpdate, get_version, map_range_moisture, plant_hal::{FileInfo, PLANT_COUNT}, BOARD_ACCESS,
};
use anyhow::bail;
use chrono::DateTime;
@@ -159,6 +159,7 @@ fn get_battery_state(
fn get_version_web(
_request: &mut Request<&mut EspHttpConnection>,
) -> Result<Option<std::string::String>, anyhow::Error> {
anyhow::Ok(Some(serde_json::to_string(&get_version())?))
}
@@ -197,19 +198,30 @@ fn list_files(
fn ota(
request: &mut Request<&mut EspHttpConnection>,
) -> Result<Option<std::string::String>, anyhow::Error> {
let mut board = BOARD_ACCESS.lock().unwrap();
let mut ota = OtaUpdate::begin()?;
println!("start ota");
//having a larger buffer is not really faster, requires more stack and prevents the progress bar from working ;)
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 read = request.read(&mut buffer)?;
total_read += read;
println!("received {read} bytes ota {total_read}");
let to_write = &buffer[0..read];
let iter = (total_read/1024)%8;
if iter != lastiter {
for i in 0..PLANT_COUNT {
board.fault(i, iter==i);
}
lastiter = iter;
}
ota.write(to_write)?;
println!("wrote {read} bytes ota {total_read}");
if read == 0 {
@@ -222,6 +234,8 @@ fn ota(
let mut finalizer = ota.finalize()?;
println!("changing boot partition");
board.set_restart_to_conf(true);
drop(board);
finalizer.set_as_boot_partition()?;
finalizer.restart();
}
@@ -413,10 +427,11 @@ pub fn httpd(reboot_now: Arc<AtomicBool>) -> Box<EspHttpServer<'static>> {
server
.fn_handler("/file", Method::Post, move |mut request| {
let filename = query_param(request.uri(), "filename").unwrap();
let file_handle = BOARD_ACCESS
.lock()
.unwrap()
.get_file_handle(&filename, true);
let lock = BOARD_ACCESS
.lock()
.unwrap();
let file_handle =
lock.get_file_handle(&filename, true);
match file_handle {
//TODO get free filesystem size, check against during write if not to large
@@ -424,13 +439,21 @@ pub fn httpd(reboot_now: Arc<AtomicBool>) -> Box<EspHttpServer<'static>> {
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 {
lock.fault(i, iter==i);
}
lastiter = iter;
}
let read = request.read(&mut buffer)?;
total_read += read;
println!("sending {read} bytes of {total_read} for upload {filename}");
let to_write = &buffer[0..read];
std::io::Write::write(&mut file_handle, to_write)?;
println!("wrote {read} bytes of {total_read} for upload {filename}");
if read == 0 {
break;
}
@@ -444,6 +467,7 @@ pub fn httpd(reboot_now: Arc<AtomicBool>) -> Box<EspHttpServer<'static>> {
cors_response(request, 500, &error_text)?;
}
}
drop(lock);
anyhow::Ok(())
})
.unwrap();
@@ -466,6 +490,11 @@ pub fn httpd(reboot_now: Arc<AtomicBool>) -> Box<EspHttpServer<'static>> {
anyhow::Ok(())
})
.unwrap();
server
.fn_handler("/file", Method::Options, |request| {
cors_response(request, 200, "")
})
.unwrap();
server
.fn_handler("/flashbattery", Method::Post, move |request| {
@@ -529,6 +558,7 @@ fn cors_response(
let headers = [
("Access-Control-Allow-Origin", "*"),
("Access-Control-Allow-Headers", "*"),
("Access-Control-Allow-Methods", "*"),
];
let mut response = request.into_response(status, None, &headers)?;
response.write(body.as_bytes())?;