adjust rust code to new config file, fix bq34z100 flasher
This commit is contained in:
@@ -1,20 +1,23 @@
|
||||
//offer ota and config mode
|
||||
|
||||
use std::{
|
||||
collections::VecDeque, fs, io::{BufRead, Read, Write}, str::from_utf8, sync::{atomic::AtomicBool, Arc}
|
||||
io::{BufRead, BufReader, Read, Write},
|
||||
str::from_utf8,
|
||||
sync::{atomic::AtomicBool, Arc},
|
||||
};
|
||||
|
||||
use crate::{espota::OtaUpdate, map_range_moisture, plant_hal::FileInfo, BOARD_ACCESS};
|
||||
use anyhow::bail;
|
||||
use chrono::DateTime;
|
||||
use url::Url;
|
||||
use core::result::Result::Ok;
|
||||
use embedded_svc::http::Method;
|
||||
use esp_idf_hal::delay::Delay;
|
||||
use esp_idf_svc::{http::server::{Configuration, EspHttpConnection, EspHttpServer, Request}};
|
||||
use esp_idf_svc::http::server::{Configuration, EspHttpConnection, EspHttpServer, Request};
|
||||
use heapless::String;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use url::Url;
|
||||
|
||||
use crate::config::Config;
|
||||
use crate::config::PlantControllerConfig;
|
||||
|
||||
#[derive(Serialize, Debug)]
|
||||
struct SSIDList<'a> {
|
||||
@@ -87,8 +90,8 @@ fn get_data(
|
||||
match a_pct {
|
||||
Ok(result) => {
|
||||
a.push(result);
|
||||
},
|
||||
Err(err) => {
|
||||
}
|
||||
Err(_) => {
|
||||
a.push(200);
|
||||
}
|
||||
}
|
||||
@@ -97,19 +100,18 @@ fn get_data(
|
||||
match b_pct {
|
||||
Ok(result) => {
|
||||
b.push(result);
|
||||
},
|
||||
Err(err) => {
|
||||
}
|
||||
Err(_) => {
|
||||
b.push(200);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let data = LoadData {
|
||||
rtc: rtc.as_str(),
|
||||
native: native.as_str(),
|
||||
moisture_a: a,
|
||||
moisture_b: b
|
||||
moisture_b: b,
|
||||
};
|
||||
let json = serde_json::to_string(&data)?;
|
||||
|
||||
@@ -122,7 +124,7 @@ fn get_config(
|
||||
let mut board = BOARD_ACCESS.lock().unwrap();
|
||||
let json = match board.get_config() {
|
||||
Ok(config) => serde_json::to_string(&config)?,
|
||||
Err(_) => serde_json::to_string(&Config::default())?,
|
||||
Err(_) => serde_json::to_string(&PlantControllerConfig::default())?,
|
||||
};
|
||||
anyhow::Ok(Some(json))
|
||||
}
|
||||
@@ -134,7 +136,7 @@ fn set_config(
|
||||
let read = request.read(&mut buf)?;
|
||||
let actual_data = &buf[0..read];
|
||||
println!("Raw data {}", from_utf8(actual_data).unwrap());
|
||||
let config: Config = serde_json::from_slice(actual_data)?;
|
||||
let config: PlantControllerConfig = serde_json::from_slice(actual_data)?;
|
||||
let mut board = BOARD_ACCESS.lock().unwrap();
|
||||
board.set_config(&config)?;
|
||||
anyhow::Ok(Some("saved".to_owned()))
|
||||
@@ -176,7 +178,7 @@ fn wifi_scan(
|
||||
fn list_files(
|
||||
request: &mut Request<&mut EspHttpConnection>,
|
||||
) -> Result<Option<std::string::String>, anyhow::Error> {
|
||||
let filename = query_param(request.uri(),"filename").unwrap_or_default();
|
||||
let filename = query_param(request.uri(), "filename").unwrap_or_default();
|
||||
let board = BOARD_ACCESS.lock().unwrap();
|
||||
let result = board.list_files(&filename);
|
||||
let file_list_json = serde_json::to_string(&result)?;
|
||||
@@ -215,17 +217,54 @@ fn ota(
|
||||
finalizer.restart();
|
||||
}
|
||||
|
||||
fn query_param(uri:&str, param_name:&str) -> Option<std::string::String>{
|
||||
fn flash_bq(filename: &str, dryrun: bool) -> anyhow::Result<()> {
|
||||
let mut board = BOARD_ACCESS.lock().unwrap();
|
||||
|
||||
let mut toggle = true;
|
||||
let delay = Delay::new(1);
|
||||
|
||||
let file_handle = board.get_file_handle(filename, false)?;
|
||||
|
||||
let mut reader = BufReader::with_capacity(512, file_handle).lines();
|
||||
let mut line = 0;
|
||||
loop {
|
||||
board.general_fault(toggle);
|
||||
toggle = !toggle;
|
||||
|
||||
delay.delay_us(2);
|
||||
line += 1;
|
||||
match reader.next() {
|
||||
Some(next) => {
|
||||
let input = next?;
|
||||
println!("flashing bq34z100 dryrun:{dryrun} line {line} payload: {input}");
|
||||
match board.flash_bq34_z100(&input, dryrun) {
|
||||
Ok(_) => {
|
||||
println!("ok")
|
||||
}
|
||||
Err(err) => {
|
||||
bail!(
|
||||
"Error flashing bq34z100 in dryrun: {dryrun} line: {line} error: {err}"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
None => break,
|
||||
}
|
||||
}
|
||||
println!("Finished flashing file {line} lines processed");
|
||||
board.general_fault(false);
|
||||
return anyhow::Ok(());
|
||||
}
|
||||
|
||||
fn query_param(uri: &str, param_name: &str) -> Option<std::string::String> {
|
||||
println!("{uri} get {param_name}");
|
||||
let parsed = Url::parse(&format!("http://127.0.0.1/{uri}")).unwrap();
|
||||
let value = parsed.query_pairs().filter(|it| it.0 == param_name).next();
|
||||
match value {
|
||||
Some(found) => {
|
||||
return Some(found.1.into_owned());
|
||||
},
|
||||
None => {
|
||||
return None
|
||||
},
|
||||
}
|
||||
None => return None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -284,18 +323,20 @@ pub fn httpd(_reboot_now: Arc<AtomicBool>) -> Box<EspHttpServer<'static>> {
|
||||
})
|
||||
.unwrap();
|
||||
server
|
||||
.fn_handler("/files", Method::Get, move |request| {
|
||||
handle_error_to500(request, list_files)
|
||||
})
|
||||
.unwrap();
|
||||
.fn_handler("/files", Method::Get, move |request| {
|
||||
handle_error_to500(request, list_files)
|
||||
})
|
||||
.unwrap();
|
||||
server
|
||||
.fn_handler("/file", Method::Get, move |request| {
|
||||
let filename = query_param(request.uri(),"filename").unwrap();
|
||||
let file_handle = BOARD_ACCESS.lock().unwrap().get_file_handle(&filename, false);
|
||||
let filename = query_param(request.uri(), "filename").unwrap();
|
||||
let file_handle = BOARD_ACCESS
|
||||
.lock()
|
||||
.unwrap()
|
||||
.get_file_handle(&filename, false);
|
||||
match file_handle {
|
||||
Ok(mut file_handle) => {
|
||||
|
||||
let headers = [("Access-Control-Allow-Origin","*")];
|
||||
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];
|
||||
@@ -303,7 +344,10 @@ pub fn httpd(_reboot_now: Arc<AtomicBool>) -> Box<EspHttpServer<'static>> {
|
||||
loop {
|
||||
let read = file_handle.read(&mut buffer)?;
|
||||
total_read += read;
|
||||
println!("sending {read} bytes of {total_read} for file {}", &filename);
|
||||
println!(
|
||||
"sending {read} bytes of {total_read} for file {}",
|
||||
&filename
|
||||
);
|
||||
let to_write = &buffer[0..read];
|
||||
response.write(to_write)?;
|
||||
println!("wrote {read} bytes of {total_read} for file {filename}");
|
||||
@@ -313,8 +357,7 @@ pub fn httpd(_reboot_now: Arc<AtomicBool>) -> Box<EspHttpServer<'static>> {
|
||||
}
|
||||
drop(file_handle);
|
||||
response.flush()?;
|
||||
|
||||
},
|
||||
}
|
||||
Err(err) => {
|
||||
//todo set headers here for filename to be error
|
||||
let error_text = err.to_string();
|
||||
@@ -327,8 +370,11 @@ pub fn httpd(_reboot_now: Arc<AtomicBool>) -> Box<EspHttpServer<'static>> {
|
||||
.unwrap();
|
||||
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 filename = query_param(request.uri(), "filename").unwrap();
|
||||
let file_handle = BOARD_ACCESS
|
||||
.lock()
|
||||
.unwrap()
|
||||
.get_file_handle(&filename, true);
|
||||
match file_handle {
|
||||
Ok(mut file_handle) => {
|
||||
const BUFFER_SIZE: usize = 512;
|
||||
@@ -346,7 +392,7 @@ pub fn httpd(_reboot_now: Arc<AtomicBool>) -> Box<EspHttpServer<'static>> {
|
||||
}
|
||||
}
|
||||
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();
|
||||
@@ -357,90 +403,51 @@ pub fn httpd(_reboot_now: Arc<AtomicBool>) -> Box<EspHttpServer<'static>> {
|
||||
anyhow::Ok(())
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
server
|
||||
|
||||
server
|
||||
.fn_handler("/file", Method::Delete, move |request| {
|
||||
let filename = query_param(request.uri(),"filename").unwrap();
|
||||
let filename = query_param(request.uri(), "filename").unwrap();
|
||||
let copy = filename.clone();
|
||||
let board = BOARD_ACCESS.lock().unwrap();
|
||||
match board.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("/flashbattery", Method::Post, move |mut request| {
|
||||
|
||||
let mut board = BOARD_ACCESS.lock().unwrap();
|
||||
let mut buffer: [u8; 128] = [0; 128];
|
||||
let mut line_buffer: VecDeque<u8> = VecDeque::new();
|
||||
|
||||
let is_dry_run = !request.uri().ends_with("?flash=true");
|
||||
let mut total_read: usize = 0;
|
||||
|
||||
let mut toggle = true;
|
||||
let delay = Delay::new(1);
|
||||
todo!("Write to storage before attempting to flash!");
|
||||
loop {
|
||||
delay.delay_us(2);
|
||||
let read = request.read(&mut buffer).unwrap();
|
||||
total_read += read;
|
||||
if read == 0 {
|
||||
if line_buffer.len() > 0 {
|
||||
println!("No further body but no endline");
|
||||
let mut line = std::string::String::new();
|
||||
line_buffer.read_to_string(&mut line).unwrap();
|
||||
let msg = format!("Finished reading, but there is still some leftover in buffer and no full line {line}<br>");
|
||||
println!("{}", msg);
|
||||
let mut response = request.into_status_response(400_u16).unwrap();
|
||||
response.write(msg.as_bytes()).unwrap();
|
||||
response.flush().unwrap();
|
||||
return anyhow::Ok(())
|
||||
.fn_handler("/flashbattery", Method::Post, move |request| {
|
||||
let filename = query_param(request.uri(),"filename").unwrap();
|
||||
let dryrun = true;
|
||||
match flash_bq(&filename, false) {
|
||||
Ok(_) => {
|
||||
if !dryrun {
|
||||
match flash_bq(&filename, true) {
|
||||
Ok(_) => {
|
||||
cors_response(request, 200, "Sucessfully flashed bq34z100")?;
|
||||
},
|
||||
Err(err) => {
|
||||
let info = format!("Could not flash bq34z100, could be bricked now! {filename} {err:?}");
|
||||
cors_response(request, 500, &info)?;
|
||||
},
|
||||
}
|
||||
} else {
|
||||
cors_response(request, 200, "Sucessfully processed bq34z100")?;
|
||||
}
|
||||
break;
|
||||
}
|
||||
let to_write = &buffer[0..read];
|
||||
|
||||
line_buffer.write_all(to_write).unwrap();
|
||||
board.general_fault(toggle);
|
||||
toggle = !toggle;
|
||||
loop {
|
||||
let has_line = line_buffer.contains(&b'\n');
|
||||
if !has_line {
|
||||
break;
|
||||
}
|
||||
let mut line = std::string::String::new();
|
||||
line_buffer.read_line(&mut line)?;
|
||||
let line2 = &line[0..line.len()-1];
|
||||
println!("Processing dry:{} line {}", is_dry_run, line2);
|
||||
let validate = board.flash_bq34_z100(&line2, is_dry_run);
|
||||
delay.delay_us(2);
|
||||
if validate.is_err() {
|
||||
let mut response = request.into_status_response(400_u16).unwrap();
|
||||
let err = validate.unwrap_err();
|
||||
let err_str = err.to_string();
|
||||
let err_msg = err_str.as_bytes();
|
||||
println!("Error writing {}", err_str);
|
||||
response
|
||||
.write(err_msg)
|
||||
.unwrap();
|
||||
return anyhow::Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
let mut response = request.into_status_response(200_u16).unwrap();
|
||||
let msg = format!("Finished writing {total_read} bytes<br>");
|
||||
response.write(msg.as_bytes()).unwrap();
|
||||
board.general_fault(false);
|
||||
},
|
||||
Err(err) => {
|
||||
let info = format!("Could not process firmware file for, bq34z100, refusing to flash! {filename} {err:?}");
|
||||
cors_response(request, 500, &info)?;
|
||||
},
|
||||
};
|
||||
anyhow::Ok(())
|
||||
})
|
||||
.unwrap();
|
||||
@@ -448,7 +455,7 @@ pub fn httpd(_reboot_now: Arc<AtomicBool>) -> Box<EspHttpServer<'static>> {
|
||||
server
|
||||
.fn_handler("/", Method::Get, move |request| {
|
||||
let mut response = request.into_ok_response()?;
|
||||
response.write(include_bytes!("index.html"))?;let mut buf = [0_u8; 3072];
|
||||
response.write(include_bytes!("index.html"))?;
|
||||
anyhow::Ok(())
|
||||
})
|
||||
.unwrap();
|
||||
@@ -458,7 +465,6 @@ pub fn httpd(_reboot_now: Arc<AtomicBool>) -> Box<EspHttpServer<'static>> {
|
||||
.into_ok_response()?
|
||||
.write(include_bytes!("favicon.ico"))?;
|
||||
anyhow::Ok(())
|
||||
|
||||
})
|
||||
.unwrap();
|
||||
server
|
||||
@@ -467,14 +473,17 @@ pub fn httpd(_reboot_now: Arc<AtomicBool>) -> Box<EspHttpServer<'static>> {
|
||||
.into_ok_response()?
|
||||
.write(include_bytes!("bundle.js"))?;
|
||||
anyhow::Ok(())
|
||||
|
||||
})
|
||||
.unwrap();
|
||||
server
|
||||
}
|
||||
|
||||
fn cors_response(request: Request<&mut EspHttpConnection>, status: u16, body: &str) -> Result<(), anyhow::Error>{
|
||||
let headers = [("Access-Control-Allow-Origin","*")];
|
||||
fn cors_response(
|
||||
request: Request<&mut EspHttpConnection>,
|
||||
status: u16,
|
||||
body: &str,
|
||||
) -> Result<(), anyhow::Error> {
|
||||
let headers = [("Access-Control-Allow-Origin", "*")];
|
||||
let mut response = request.into_response(status, None, &headers)?;
|
||||
response.write(body.as_bytes())?;
|
||||
response.flush()?;
|
||||
@@ -504,4 +513,4 @@ fn handle_error_to500(
|
||||
}
|
||||
}
|
||||
return anyhow::Ok(());
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user