Compare commits
2 Commits
9f249af430
...
4c19d757c6
Author | SHA1 | Date | |
---|---|---|---|
4c19d757c6 | |||
3d17ba67ff |
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"board": {
|
"board": {
|
||||||
"active_layer": 31,
|
"active_layer": 1,
|
||||||
"active_layer_preset": "",
|
"active_layer_preset": "",
|
||||||
"auto_track_width": false,
|
"auto_track_width": false,
|
||||||
"hidden_netclasses": [],
|
"hidden_netclasses": [],
|
||||||
|
@ -8456,6 +8456,12 @@
|
|||||||
(color 0 0 0 0)
|
(color 0 0 0 0)
|
||||||
(uuid "0bf93224-513b-43b0-b34e-b83cf88ace50")
|
(uuid "0bf93224-513b-43b0-b34e-b83cf88ace50")
|
||||||
)
|
)
|
||||||
|
(junction
|
||||||
|
(at 287.02 129.54)
|
||||||
|
(diameter 0)
|
||||||
|
(color 0 0 0 0)
|
||||||
|
(uuid "0c1a2e2b-69cb-4ba8-9ed6-a21b6fe1cbe7")
|
||||||
|
)
|
||||||
(junction
|
(junction
|
||||||
(at 31.75 59.69)
|
(at 31.75 59.69)
|
||||||
(diameter 0)
|
(diameter 0)
|
||||||
@ -8522,12 +8528,6 @@
|
|||||||
(color 0 0 0 0)
|
(color 0 0 0 0)
|
||||||
(uuid "1e71c6eb-62eb-41d4-bfde-df1e7aa7c319")
|
(uuid "1e71c6eb-62eb-41d4-bfde-df1e7aa7c319")
|
||||||
)
|
)
|
||||||
(junction
|
|
||||||
(at 444.5 280.67)
|
|
||||||
(diameter 0)
|
|
||||||
(color 0 0 0 0)
|
|
||||||
(uuid "1ec24ea8-049a-4547-addf-26eafaa81113")
|
|
||||||
)
|
|
||||||
(junction
|
(junction
|
||||||
(at 468.63 85.09)
|
(at 468.63 85.09)
|
||||||
(diameter 0)
|
(diameter 0)
|
||||||
@ -12802,7 +12802,7 @@
|
|||||||
)
|
)
|
||||||
(wire
|
(wire
|
||||||
(pts
|
(pts
|
||||||
(xy 287.02 128.27) (xy 287.02 132.08)
|
(xy 287.02 128.27) (xy 287.02 129.54)
|
||||||
)
|
)
|
||||||
(stroke
|
(stroke
|
||||||
(width 0)
|
(width 0)
|
||||||
@ -13230,16 +13230,6 @@
|
|||||||
)
|
)
|
||||||
(uuid "7a3ebb50-4f58-4e1a-a5ff-481fddcdfef7")
|
(uuid "7a3ebb50-4f58-4e1a-a5ff-481fddcdfef7")
|
||||||
)
|
)
|
||||||
(wire
|
|
||||||
(pts
|
|
||||||
(xy 444.5 280.67) (xy 444.5 292.1)
|
|
||||||
)
|
|
||||||
(stroke
|
|
||||||
(width 0)
|
|
||||||
(type default)
|
|
||||||
)
|
|
||||||
(uuid "7a9a9650-b9a8-436c-8029-e24751d2221a")
|
|
||||||
)
|
|
||||||
(wire
|
(wire
|
||||||
(pts
|
(pts
|
||||||
(xy 449.58 372.11) (xy 449.58 375.92)
|
(xy 449.58 372.11) (xy 449.58 375.92)
|
||||||
@ -14510,6 +14500,16 @@
|
|||||||
)
|
)
|
||||||
(uuid "acdcea68-0d69-4342-8f07-b4457aea6c6c")
|
(uuid "acdcea68-0d69-4342-8f07-b4457aea6c6c")
|
||||||
)
|
)
|
||||||
|
(wire
|
||||||
|
(pts
|
||||||
|
(xy 287.02 129.54) (xy 287.02 132.08)
|
||||||
|
)
|
||||||
|
(stroke
|
||||||
|
(width 0)
|
||||||
|
(type default)
|
||||||
|
)
|
||||||
|
(uuid "ada2d200-6a4f-42a6-91cf-1c0fb24761e4")
|
||||||
|
)
|
||||||
(wire
|
(wire
|
||||||
(pts
|
(pts
|
||||||
(xy 502.92 82.55) (xy 502.92 86.36)
|
(xy 502.92 82.55) (xy 502.92 86.36)
|
||||||
@ -14832,7 +14832,7 @@
|
|||||||
)
|
)
|
||||||
(wire
|
(wire
|
||||||
(pts
|
(pts
|
||||||
(xy 444.5 276.86) (xy 444.5 280.67)
|
(xy 444.5 276.86) (xy 444.5 292.1)
|
||||||
)
|
)
|
||||||
(stroke
|
(stroke
|
||||||
(width 0)
|
(width 0)
|
||||||
@ -21725,28 +21725,6 @@
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(global_label "SIGNAL"
|
|
||||||
(shape input)
|
|
||||||
(at 224.79 90.17 0)
|
|
||||||
(fields_autoplaced yes)
|
|
||||||
(effects
|
|
||||||
(font
|
|
||||||
(size 1.27 1.27)
|
|
||||||
)
|
|
||||||
(justify left)
|
|
||||||
)
|
|
||||||
(uuid "665b125c-32af-4eac-b20b-f2b9f3f9ad59")
|
|
||||||
(property "Intersheetrefs" "${INTERSHEET_REFS}"
|
|
||||||
(at 233.5731 90.17 0)
|
|
||||||
(effects
|
|
||||||
(font
|
|
||||||
(size 1.27 1.27)
|
|
||||||
)
|
|
||||||
(justify left)
|
|
||||||
(hide yes)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(global_label "PUMP2"
|
(global_label "PUMP2"
|
||||||
(shape input)
|
(shape input)
|
||||||
(at 281.94 280.67 90)
|
(at 281.94 280.67 90)
|
||||||
@ -26785,6 +26763,28 @@
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
(global_label "CD_Probe"
|
||||||
|
(shape input)
|
||||||
|
(at 224.79 90.17 0)
|
||||||
|
(fields_autoplaced yes)
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1.27 1.27)
|
||||||
|
)
|
||||||
|
(justify left)
|
||||||
|
)
|
||||||
|
(uuid "e5fc8039-2e3c-4d37-a2b7-76c0322c7dd3")
|
||||||
|
(property "Intersheetrefs" "${INTERSHEET_REFS}"
|
||||||
|
(at 236.0714 90.17 0)
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1.27 1.27)
|
||||||
|
)
|
||||||
|
(justify left)
|
||||||
|
(hide yes)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
(global_label "GND"
|
(global_label "GND"
|
||||||
(shape input)
|
(shape input)
|
||||||
(at 502.92 105.41 270)
|
(at 502.92 105.41 270)
|
||||||
@ -53055,7 +53055,7 @@
|
|||||||
)
|
)
|
||||||
(symbol
|
(symbol
|
||||||
(lib_id "Connector:TestPoint")
|
(lib_id "Connector:TestPoint")
|
||||||
(at 444.5 280.67 90)
|
(at 287.02 129.54 90)
|
||||||
(unit 1)
|
(unit 1)
|
||||||
(exclude_from_sim no)
|
(exclude_from_sim no)
|
||||||
(in_bom yes)
|
(in_bom yes)
|
||||||
@ -53064,7 +53064,7 @@
|
|||||||
(fields_autoplaced yes)
|
(fields_autoplaced yes)
|
||||||
(uuid "eb5a6fda-d618-4386-8c57-d62f452b6d41")
|
(uuid "eb5a6fda-d618-4386-8c57-d62f452b6d41")
|
||||||
(property "Reference" "TP25"
|
(property "Reference" "TP25"
|
||||||
(at 441.198 275.59 90)
|
(at 283.718 124.46 90)
|
||||||
(effects
|
(effects
|
||||||
(font
|
(font
|
||||||
(size 1.27 1.27)
|
(size 1.27 1.27)
|
||||||
@ -53072,7 +53072,7 @@
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
(property "Value" "TestPoint"
|
(property "Value" "TestPoint"
|
||||||
(at 441.198 278.13 90)
|
(at 283.718 127 90)
|
||||||
(effects
|
(effects
|
||||||
(font
|
(font
|
||||||
(size 1.27 1.27)
|
(size 1.27 1.27)
|
||||||
@ -53080,7 +53080,7 @@
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
(property "Footprint" "TestPoint:TestPoint_Pad_2.0x2.0mm"
|
(property "Footprint" "TestPoint:TestPoint_Pad_2.0x2.0mm"
|
||||||
(at 444.5 275.59 0)
|
(at 287.02 124.46 0)
|
||||||
(effects
|
(effects
|
||||||
(font
|
(font
|
||||||
(size 1.27 1.27)
|
(size 1.27 1.27)
|
||||||
@ -53089,7 +53089,7 @@
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
(property "Datasheet" "~"
|
(property "Datasheet" "~"
|
||||||
(at 444.5 275.59 0)
|
(at 287.02 124.46 0)
|
||||||
(effects
|
(effects
|
||||||
(font
|
(font
|
||||||
(size 1.27 1.27)
|
(size 1.27 1.27)
|
||||||
@ -53098,7 +53098,7 @@
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
(property "Description" ""
|
(property "Description" ""
|
||||||
(at 444.5 280.67 0)
|
(at 287.02 129.54 0)
|
||||||
(effects
|
(effects
|
||||||
(font
|
(font
|
||||||
(size 1.27 1.27)
|
(size 1.27 1.27)
|
||||||
|
@ -8,7 +8,7 @@ rust-version = "1.71"
|
|||||||
|
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
# Explicitly disable LTO which the Xtensa codegen backend has issues
|
# Explicitly disable LTO which the Xtensa codegen backend has issues
|
||||||
lto = false
|
lto = true
|
||||||
strip = false
|
strip = false
|
||||||
debug = true
|
debug = true
|
||||||
overflow-checks = true
|
overflow-checks = true
|
||||||
@ -78,6 +78,7 @@ serde_json = "1.0.108"
|
|||||||
chrono = { version = "0.4.23", default-features = false , features = ["iana-time-zone" , "alloc"] }
|
chrono = { version = "0.4.23", default-features = false , features = ["iana-time-zone" , "alloc"] }
|
||||||
chrono-tz = {version="0.8.0", default-features = false , features = [ "filter-by-regex" ]}
|
chrono-tz = {version="0.8.0", default-features = false , features = [ "filter-by-regex" ]}
|
||||||
eeprom24x = "0.7.2"
|
eeprom24x = "0.7.2"
|
||||||
|
url = "2.5.3"
|
||||||
|
|
||||||
|
|
||||||
[patch.crates-io]
|
[patch.crates-io]
|
||||||
|
@ -2,6 +2,7 @@ use bq34z100::{Bq34Z100Error, Bq34z100g1, Bq34z100g1Driver};
|
|||||||
|
|
||||||
use ds323x::{DateTimeAccess, Ds323x};
|
use ds323x::{DateTimeAccess, Ds323x};
|
||||||
|
|
||||||
|
use eeprom24x::page_size::No;
|
||||||
use eeprom24x::{Eeprom24x, SlaveAddr};
|
use eeprom24x::{Eeprom24x, SlaveAddr};
|
||||||
use embedded_hal_bus::i2c::MutexDevice;
|
use embedded_hal_bus::i2c::MutexDevice;
|
||||||
use embedded_svc::wifi::{
|
use embedded_svc::wifi::{
|
||||||
@ -13,6 +14,7 @@ use esp_idf_hal::adc::{attenuation, Resolution};
|
|||||||
use esp_idf_hal::i2c::{APBTickType, I2cConfig, I2cDriver, I2cError};
|
use esp_idf_hal::i2c::{APBTickType, I2cConfig, I2cDriver, I2cError};
|
||||||
use esp_idf_hal::units::FromValueType;
|
use esp_idf_hal::units::FromValueType;
|
||||||
use esp_idf_svc::eventloop::EspSystemEventLoop;
|
use esp_idf_svc::eventloop::EspSystemEventLoop;
|
||||||
|
use esp_idf_svc::io::vfs;
|
||||||
use esp_idf_svc::ipv4::IpInfo;
|
use esp_idf_svc::ipv4::IpInfo;
|
||||||
use esp_idf_svc::mqtt::client::QoS::AtLeastOnce;
|
use esp_idf_svc::mqtt::client::QoS::AtLeastOnce;
|
||||||
use esp_idf_svc::mqtt::client::QoS::ExactlyOnce;
|
use esp_idf_svc::mqtt::client::QoS::ExactlyOnce;
|
||||||
@ -50,7 +52,7 @@ use esp_idf_hal::prelude::Peripherals;
|
|||||||
use esp_idf_hal::reset::ResetReason;
|
use esp_idf_hal::reset::ResetReason;
|
||||||
use esp_idf_svc::sntp::{self, SyncStatus};
|
use esp_idf_svc::sntp::{self, SyncStatus};
|
||||||
use esp_idf_svc::systime::EspSystemTime;
|
use esp_idf_svc::systime::EspSystemTime;
|
||||||
use esp_idf_sys::{gpio_hold_dis, gpio_hold_en, vTaskDelay, EspError};
|
use esp_idf_sys::{esp, esp_spiffs_check, f_opendir, gpio_hold_dis, gpio_hold_en, vTaskDelay, EspError};
|
||||||
use one_wire_bus::OneWire;
|
use one_wire_bus::OneWire;
|
||||||
|
|
||||||
use crate::config::{self, Config};
|
use crate::config::{self, Config};
|
||||||
@ -174,21 +176,82 @@ pub struct FileInfo{
|
|||||||
size:usize
|
size:usize
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Debug)]
|
||||||
|
pub struct FileList{
|
||||||
|
files: Vec<FileInfo>,
|
||||||
|
file_system_corrupt: Option<String>,
|
||||||
|
iter_error: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
impl PlantCtrlBoard<'_> {
|
impl PlantCtrlBoard<'_> {
|
||||||
pub fn list_files(&self) -> Result<Vec<FileInfo>> {
|
pub fn list_files(&self, filename:&str) -> FileList {
|
||||||
let spiffs = Path::new(BASE_PATH);
|
let storage = CString::new(SPIFFS_PARTITION_NAME).unwrap();
|
||||||
let list = fs::read_dir(spiffs).unwrap().map(|dir| {
|
let error = unsafe {
|
||||||
let file = dir.unwrap();
|
esp!{
|
||||||
FileInfo{
|
esp_spiffs_check(storage.as_ptr())
|
||||||
filename: file.file_name().into_string().unwrap(),
|
|
||||||
size: file.metadata().unwrap().len() as usize
|
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
return Ok(list.collect());
|
|
||||||
|
let mut file_system_corrupt = match error {
|
||||||
|
OkStd(_) => {
|
||||||
|
None
|
||||||
|
},
|
||||||
|
Err(err) => {
|
||||||
|
println!("Corrupt spiffs {err:?}");
|
||||||
|
Some(format!("{err:?}"))
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut iter_error = None;
|
||||||
|
let mut result = Vec::new();
|
||||||
|
|
||||||
|
println!("Filename {filename}");
|
||||||
|
let filepath = Path::new(BASE_PATH);
|
||||||
|
let read_dir = fs::read_dir(filepath);
|
||||||
|
match read_dir {
|
||||||
|
OkStd(read_dir) => {
|
||||||
|
for item in read_dir {
|
||||||
|
println!("start loop");
|
||||||
|
match item {
|
||||||
|
OkStd(file) => {
|
||||||
|
let f = FileInfo{
|
||||||
|
filename: file.file_name().into_string().unwrap(),
|
||||||
|
size: file.metadata().and_then(|it| core::result::Result::Ok(it.len())).unwrap_or_default() as usize
|
||||||
|
};
|
||||||
|
println!("fileinfo {f:?}");
|
||||||
|
result.push(f);
|
||||||
|
},
|
||||||
|
Err(err) => {
|
||||||
|
iter_error = Some (format!("{err:?}"));
|
||||||
|
break;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(err) => {
|
||||||
|
file_system_corrupt = Some(format!("{err:?}"));
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return FileList{
|
||||||
|
file_system_corrupt,
|
||||||
|
files: result,
|
||||||
|
iter_error
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_file_handle(&self, filename:String, write:bool) -> Result<File> {
|
pub fn delete_file(&self, filename:&str) -> Result<()>{
|
||||||
let filepath = Path::new(BASE_PATH).join(Path::new(&filename));
|
let filepath = Path::new(BASE_PATH).join(Path::new(filename));
|
||||||
|
match (fs::remove_file(filepath)){
|
||||||
|
OkStd(_) => Ok(()),
|
||||||
|
Err(err) => {
|
||||||
|
bail!(format!("{err:?}"))
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_file_handle(&self, filename:&str, write:bool) -> Result<File> {
|
||||||
|
let filepath = Path::new(BASE_PATH).join(Path::new(filename));
|
||||||
return Ok(if write {
|
return Ok(if write {
|
||||||
File::create(filepath)?
|
File::create(filepath)?
|
||||||
} else {
|
} else {
|
||||||
@ -417,7 +480,7 @@ impl PlantCtrlBoard<'_> {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let delay = Delay::new_default();
|
let delay = Delay::new_default();
|
||||||
let measurement = 5000;
|
let measurement = 100;
|
||||||
let factor = 1000 as f32 / measurement as f32;
|
let factor = 1000 as f32 / measurement as f32;
|
||||||
|
|
||||||
//give some time to stabilize
|
//give some time to stabilize
|
||||||
@ -532,9 +595,11 @@ impl PlantCtrlBoard<'_> {
|
|||||||
let conf = esp_idf_sys::esp_vfs_spiffs_conf_t {
|
let conf = esp_idf_sys::esp_vfs_spiffs_conf_t {
|
||||||
base_path: base_path.as_ptr(),
|
base_path: base_path.as_ptr(),
|
||||||
partition_label: storage.as_ptr(),
|
partition_label: storage.as_ptr(),
|
||||||
max_files: 2,
|
max_files: 5,
|
||||||
format_if_mount_failed: true,
|
format_if_mount_failed: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//TODO check fielsystem esp_spiffs_check
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
esp_idf_sys::esp!(esp_idf_sys::esp_vfs_spiffs_register(&conf))?;
|
esp_idf_sys::esp!(esp_idf_sys::esp_vfs_spiffs_register(&conf))?;
|
||||||
|
@ -1,18 +1,16 @@
|
|||||||
//offer ota and config mode
|
//offer ota and config mode
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
collections::VecDeque,
|
collections::VecDeque, fs, io::{BufRead, Read, Write}, str::from_utf8, sync::{atomic::AtomicBool, Arc}
|
||||||
io::{BufRead, Read, Seek, Write},
|
|
||||||
str::from_utf8,
|
|
||||||
sync::{atomic::AtomicBool, Arc},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{espota::OtaUpdate, map_range_moisture, plant_hal::{FileInfo, PLANT_COUNT}, BOARD_ACCESS};
|
use crate::{espota::OtaUpdate, map_range_moisture, plant_hal::FileInfo, BOARD_ACCESS};
|
||||||
use chrono::DateTime;
|
use chrono::DateTime;
|
||||||
|
use url::Url;
|
||||||
use core::result::Result::Ok;
|
use core::result::Result::Ok;
|
||||||
use embedded_svc::http::{Method, Query};
|
use embedded_svc::http::Method;
|
||||||
use esp_idf_hal::{delay::Delay, io::Write};
|
use esp_idf_hal::delay::Delay;
|
||||||
use esp_idf_svc::{fs, http::server::{Configuration, EspHttpConnection, EspHttpServer, Request}};
|
use esp_idf_svc::{http::server::{Configuration, EspHttpConnection, EspHttpServer, Request}};
|
||||||
use heapless::String;
|
use heapless::String;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
@ -81,7 +79,7 @@ fn get_data(
|
|||||||
|
|
||||||
let mut a: Vec<u8> = Vec::new();
|
let mut a: Vec<u8> = Vec::new();
|
||||||
let mut b: Vec<u8> = Vec::new();
|
let mut b: Vec<u8> = Vec::new();
|
||||||
for plant in 0..2 {
|
for plant in 0..8 {
|
||||||
let a_hz = board.measure_moisture_hz(plant, crate::plant_hal::Sensor::A)?;
|
let a_hz = board.measure_moisture_hz(plant, crate::plant_hal::Sensor::A)?;
|
||||||
let b_hz = board.measure_moisture_hz(plant, crate::plant_hal::Sensor::B)?;
|
let b_hz = board.measure_moisture_hz(plant, crate::plant_hal::Sensor::B)?;
|
||||||
let a_pct = map_range_moisture(a_hz as f32);
|
let a_pct = map_range_moisture(a_hz as f32);
|
||||||
@ -176,11 +174,12 @@ fn wifi_scan(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn list_files(
|
fn list_files(
|
||||||
_request: &mut Request<&mut EspHttpConnection>,
|
request: &mut Request<&mut EspHttpConnection>,
|
||||||
) -> Result<Option<std::string::String>, anyhow::Error> {
|
) -> Result<Option<std::string::String>, anyhow::Error> {
|
||||||
|
let filename = query_param(request.uri(),"filename").unwrap_or_default();
|
||||||
let board = BOARD_ACCESS.lock().unwrap();
|
let board = BOARD_ACCESS.lock().unwrap();
|
||||||
let result = board.list_files()?;
|
let result = board.list_files(&filename);
|
||||||
let file_list_json = serde_json::to_string(&FileList { file: result })?;
|
let file_list_json = serde_json::to_string(&result)?;
|
||||||
return anyhow::Ok(Some(file_list_json));
|
return anyhow::Ok(Some(file_list_json));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,6 +215,20 @@ fn ota(
|
|||||||
finalizer.restart();
|
finalizer.restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn httpd(_reboot_now: Arc<AtomicBool>) -> Box<EspHttpServer<'static>> {
|
pub fn httpd(_reboot_now: Arc<AtomicBool>) -> Box<EspHttpServer<'static>> {
|
||||||
let server_config = Configuration {
|
let server_config = Configuration {
|
||||||
stack_size: 32768,
|
stack_size: 32768,
|
||||||
@ -255,7 +268,7 @@ pub fn httpd(_reboot_now: Arc<AtomicBool>) -> Box<EspHttpServer<'static>> {
|
|||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
server
|
server
|
||||||
.fn_handler("/ota", Method::Post, |mut request| {
|
.fn_handler("/ota", Method::Post, |request| {
|
||||||
handle_error_to500(request, ota)
|
handle_error_to500(request, ota)
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -271,16 +284,16 @@ pub fn httpd(_reboot_now: Arc<AtomicBool>) -> Box<EspHttpServer<'static>> {
|
|||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
server
|
server
|
||||||
.fn_handler("/list_files", Method::Get, move |request| {
|
.fn_handler("/files", Method::Get, move |request| {
|
||||||
handle_error_to500(request, list_files)
|
handle_error_to500(request, list_files)
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
server
|
server
|
||||||
.fn_handler("/get_file", Method::Get, move |request| {
|
.fn_handler("/file", Method::Get, move |request| {
|
||||||
let filename:String = request.uri().magic_here().get("filename");
|
let filename = query_param(request.uri(),"filename").unwrap();
|
||||||
let file_handle = BOARD_ACCESS.lock().unwrap().get_file_handle(filename);
|
let file_handle = BOARD_ACCESS.lock().unwrap().get_file_handle(&filename, false);
|
||||||
match file_handle {
|
match file_handle {
|
||||||
Ok(file_handle) => {
|
Ok(mut file_handle) => {
|
||||||
let mut response = request.into_ok_response()?;
|
let mut response = request.into_ok_response()?;
|
||||||
const BUFFER_SIZE: usize = 512;
|
const BUFFER_SIZE: usize = 512;
|
||||||
let mut buffer: [u8; BUFFER_SIZE] = [0; BUFFER_SIZE];
|
let mut buffer: [u8; BUFFER_SIZE] = [0; BUFFER_SIZE];
|
||||||
@ -288,7 +301,7 @@ pub fn httpd(_reboot_now: Arc<AtomicBool>) -> Box<EspHttpServer<'static>> {
|
|||||||
loop {
|
loop {
|
||||||
let read = file_handle.read(&mut buffer)?;
|
let read = file_handle.read(&mut buffer)?;
|
||||||
total_read += read;
|
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];
|
let to_write = &buffer[0..read];
|
||||||
response.write(to_write)?;
|
response.write(to_write)?;
|
||||||
println!("wrote {read} bytes of {total_read} for file {filename}");
|
println!("wrote {read} bytes of {total_read} for file {filename}");
|
||||||
@ -296,6 +309,7 @@ pub fn httpd(_reboot_now: Arc<AtomicBool>) -> Box<EspHttpServer<'static>> {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
drop(file_handle);
|
||||||
response.flush()?;
|
response.flush()?;
|
||||||
|
|
||||||
},
|
},
|
||||||
@ -312,11 +326,11 @@ pub fn httpd(_reboot_now: Arc<AtomicBool>) -> Box<EspHttpServer<'static>> {
|
|||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
server
|
server
|
||||||
.fn_handler("/put_file", Method::Post, move |request| {
|
.fn_handler("/file", Method::Post, move |mut request| {
|
||||||
let filename:String = request.uri().magic_here().get("filename");
|
let filename = query_param(request.uri(),"filename").unwrap();
|
||||||
let file_handle = BOARD_ACCESS.lock().unwrap().get_file_handle(filename);
|
let file_handle = BOARD_ACCESS.lock().unwrap().get_file_handle(&filename,true);
|
||||||
match file_handle {
|
match file_handle {
|
||||||
Ok(file_handle) => {
|
Ok(mut file_handle) => {
|
||||||
const BUFFER_SIZE: usize = 512;
|
const BUFFER_SIZE: usize = 512;
|
||||||
let mut buffer: [u8; BUFFER_SIZE] = [0; BUFFER_SIZE];
|
let mut buffer: [u8; BUFFER_SIZE] = [0; BUFFER_SIZE];
|
||||||
let mut total_read: usize = 0;
|
let mut total_read: usize = 0;
|
||||||
@ -331,7 +345,7 @@ pub fn httpd(_reboot_now: Arc<AtomicBool>) -> Box<EspHttpServer<'static>> {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
request.into_ok_response().unwrap().write(format!("saved {total_read} bytes").as_bytes());
|
request.into_ok_response().unwrap().write(format!("saved {total_read} bytes").as_bytes()).unwrap();
|
||||||
},
|
},
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
//todo set headers here for filename to be error
|
//todo set headers here for filename to be error
|
||||||
@ -345,17 +359,26 @@ pub fn httpd(_reboot_now: Arc<AtomicBool>) -> Box<EspHttpServer<'static>> {
|
|||||||
anyhow::Ok(())
|
anyhow::Ok(())
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
server
|
|
||||||
.fn_handler("/get_file", Method::Post, move |request| {
|
|
||||||
handle_error_to500(request, set_config)
|
|
||||||
})
|
|
||||||
.unwrap();
|
|
||||||
server
|
|
||||||
.fn_handler("/put_file", Method::Post, move |request| {
|
|
||||||
handle_error_to500(request, set_config)
|
|
||||||
})
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
|
server
|
||||||
|
.fn_handler("/file", Method::Delete, move |request| {
|
||||||
|
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}");
|
||||||
|
request.into_ok_response().unwrap().write(info.as_bytes()).unwrap();
|
||||||
|
},
|
||||||
|
Err(err) => {
|
||||||
|
let info = format!("Could not delete file {copy} {err:?}");
|
||||||
|
request.into_status_response(400).unwrap().write(info.as_bytes()).unwrap();
|
||||||
|
},
|
||||||
|
}
|
||||||
|
anyhow::Ok(())
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
server
|
server
|
||||||
.fn_handler("/flashbattery", Method::Post, move |mut request| {
|
.fn_handler("/flashbattery", Method::Post, move |mut request| {
|
||||||
|
|
||||||
@ -428,12 +451,6 @@ pub fn httpd(_reboot_now: Arc<AtomicBool>) -> Box<EspHttpServer<'static>> {
|
|||||||
.fn_handler("/", Method::Get, move |request| {
|
.fn_handler("/", Method::Get, move |request| {
|
||||||
let mut response = request.into_ok_response()?;
|
let mut response = request.into_ok_response()?;
|
||||||
response.write(include_bytes!("config.html"))?;let mut buf = [0_u8; 3072];
|
response.write(include_bytes!("config.html"))?;let mut buf = [0_u8; 3072];
|
||||||
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)?;
|
|
||||||
|
|
||||||
.write(include_bytes!("bundle.js"))?;
|
|
||||||
anyhow::Ok(())
|
anyhow::Ok(())
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -447,6 +464,15 @@ pub fn httpd(_reboot_now: Arc<AtomicBool>) -> Box<EspHttpServer<'static>> {
|
|||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
server
|
server
|
||||||
|
.fn_handler("/bundle.js", Method::Get, |request| {
|
||||||
|
request
|
||||||
|
.into_ok_response()?
|
||||||
|
.write(include_bytes!("bundle.js"))?;
|
||||||
|
anyhow::Ok(())
|
||||||
|
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
server
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user