add single pump test mode to config page

This commit is contained in:
Empire Phoenix 2024-04-06 21:14:56 +02:00
parent 1f71b94238
commit e7e38e9fca
8 changed files with 182995 additions and 150452 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{ {
"board": { "board": {
"active_layer": 2, "active_layer": 39,
"active_layer_preset": "", "active_layer_preset": "",
"auto_track_width": false, "auto_track_width": false,
"hidden_netclasses": [], "hidden_netclasses": [],
@ -68,9 +68,15 @@
39, 39,
40 40
], ],
"visible_layers": "fffffff_ffffffff", "visible_layers": "ffdfffe_ffffffff",
"zone_display_mode": 1 "zone_display_mode": 1
}, },
"git": {
"repo_password": "",
"repo_type": "",
"repo_username": "",
"ssh_key": ""
},
"meta": { "meta": {
"filename": "PlantCtrlESP32.kicad_prl", "filename": "PlantCtrlESP32.kicad_prl",
"version": 3 "version": 3

View File

@ -3,14 +3,17 @@
"3dviewports": [], "3dviewports": [],
"design_settings": { "design_settings": {
"defaults": { "defaults": {
"board_outline_line_width": 0.049999999999999996, "apply_defaults_to_fp_fields": false,
"copper_line_width": 0.19999999999999998, "apply_defaults_to_fp_shapes": false,
"apply_defaults_to_fp_text": false,
"board_outline_line_width": 0.05,
"copper_line_width": 0.2,
"copper_text_italic": false, "copper_text_italic": false,
"copper_text_size_h": 1.5, "copper_text_size_h": 1.5,
"copper_text_size_v": 1.5, "copper_text_size_v": 1.5,
"copper_text_thickness": 0.3, "copper_text_thickness": 0.3,
"copper_text_upright": false, "copper_text_upright": false,
"courtyard_line_width": 0.049999999999999996, "courtyard_line_width": 0.05,
"dimension_precision": 4, "dimension_precision": 4,
"dimension_units": 3, "dimension_units": 3,
"dimensions": { "dimensions": {
@ -21,13 +24,13 @@
"text_position": 0, "text_position": 0,
"units_format": 1 "units_format": 1
}, },
"fab_line_width": 0.09999999999999999, "fab_line_width": 0.1,
"fab_text_italic": false, "fab_text_italic": false,
"fab_text_size_h": 1.0, "fab_text_size_h": 1.0,
"fab_text_size_v": 1.0, "fab_text_size_v": 1.0,
"fab_text_thickness": 0.15, "fab_text_thickness": 0.15,
"fab_text_upright": false, "fab_text_upright": false,
"other_line_width": 0.09999999999999999, "other_line_width": 0.1,
"other_text_italic": false, "other_text_italic": false,
"other_text_size_h": 1.0, "other_text_size_h": 1.0,
"other_text_size_v": 1.0, "other_text_size_v": 1.0,
@ -73,6 +76,7 @@
"duplicate_footprints": "warning", "duplicate_footprints": "warning",
"extra_footprint": "warning", "extra_footprint": "warning",
"footprint": "error", "footprint": "error",
"footprint_symbol_mismatch": "warning",
"footprint_type_mismatch": "ignore", "footprint_type_mismatch": "ignore",
"hole_clearance": "error", "hole_clearance": "error",
"hole_near_hole": "error", "hole_near_hole": "error",
@ -116,27 +120,24 @@
"max_error": 0.005, "max_error": 0.005,
"min_clearance": 0.0, "min_clearance": 0.0,
"min_connection": 0.0, "min_connection": 0.0,
"min_copper_edge_clearance": 0.024999999999999998, "min_copper_edge_clearance": 0.025,
"min_hole_clearance": 0.25, "min_hole_clearance": 0.25,
"min_hole_to_hole": 0.25, "min_hole_to_hole": 0.25,
"min_microvia_diameter": 0.19999999999999998, "min_microvia_diameter": 0.2,
"min_microvia_drill": 0.09999999999999999, "min_microvia_drill": 0.1,
"min_resolved_spokes": 1, "min_resolved_spokes": 1,
"min_silk_clearance": 0.0, "min_silk_clearance": 0.0,
"min_text_height": 0.7999999999999999, "min_text_height": 0.8,
"min_text_thickness": 0.08, "min_text_thickness": 0.08,
"min_through_hole_diameter": 0.19999999999999998, "min_through_hole_diameter": 0.2,
"min_track_width": 0.19999999999999998, "min_track_width": 0.2,
"min_via_annular_width": 0.09999999999999999, "min_via_annular_width": 0.1,
"min_via_diameter": 0.39999999999999997, "min_via_diameter": 0.4,
"solder_mask_to_copper_clearance": 0.005, "solder_mask_to_copper_clearance": 0.005,
"use_height_for_length_calcs": true "use_height_for_length_calcs": true
}, },
"teardrop_options": [ "teardrop_options": [
{ {
"td_allow_use_two_tracks": true,
"td_curve_segcount": 5,
"td_on_pad_in_zone": false,
"td_onpadsmd": true, "td_onpadsmd": true,
"td_onroundshapesonly": false, "td_onroundshapesonly": false,
"td_ontrackend": false, "td_ontrackend": false,
@ -145,29 +146,35 @@
], ],
"teardrop_parameters": [ "teardrop_parameters": [
{ {
"td_allow_use_two_tracks": true,
"td_curve_segcount": 0, "td_curve_segcount": 0,
"td_height_ratio": 1.0, "td_height_ratio": 1.0,
"td_length_ratio": 0.5, "td_length_ratio": 0.5,
"td_maxheight": 2.0, "td_maxheight": 2.0,
"td_maxlen": 1.0, "td_maxlen": 1.0,
"td_on_pad_in_zone": false,
"td_target_name": "td_round_shape", "td_target_name": "td_round_shape",
"td_width_to_size_filter_ratio": 0.9 "td_width_to_size_filter_ratio": 0.9
}, },
{ {
"td_allow_use_two_tracks": true,
"td_curve_segcount": 0, "td_curve_segcount": 0,
"td_height_ratio": 1.0, "td_height_ratio": 1.0,
"td_length_ratio": 0.5, "td_length_ratio": 0.5,
"td_maxheight": 2.0, "td_maxheight": 2.0,
"td_maxlen": 1.0, "td_maxlen": 1.0,
"td_on_pad_in_zone": false,
"td_target_name": "td_rect_shape", "td_target_name": "td_rect_shape",
"td_width_to_size_filter_ratio": 0.9 "td_width_to_size_filter_ratio": 0.9
}, },
{ {
"td_allow_use_two_tracks": true,
"td_curve_segcount": 0, "td_curve_segcount": 0,
"td_height_ratio": 1.0, "td_height_ratio": 1.0,
"td_length_ratio": 0.5, "td_length_ratio": 0.5,
"td_maxheight": 2.0, "td_maxheight": 2.0,
"td_maxlen": 1.0, "td_maxlen": 1.0,
"td_on_pad_in_zone": false,
"td_target_name": "td_track_end", "td_target_name": "td_track_end",
"td_width_to_size_filter_ratio": 0.9 "td_width_to_size_filter_ratio": 0.9
} }
@ -180,6 +187,32 @@
1.5, 1.5,
2.0 2.0
], ],
"tuning_pattern_settings": {
"diff_pair_defaults": {
"corner_radius_percentage": 80,
"corner_style": 1,
"max_amplitude": 1.0,
"min_amplitude": 0.2,
"single_sided": false,
"spacing": 1.0
},
"diff_pair_skew_defaults": {
"corner_radius_percentage": 80,
"corner_style": 1,
"max_amplitude": 1.0,
"min_amplitude": 0.2,
"single_sided": false,
"spacing": 0.6
},
"single_track_defaults": {
"corner_radius_percentage": 80,
"corner_style": 1,
"max_amplitude": 1.0,
"min_amplitude": 0.2,
"single_sided": false,
"spacing": 0.6
}
},
"via_dimensions": [ "via_dimensions": [
{ {
"diameter": 0.0, "diameter": 0.0,

File diff suppressed because it is too large Load Diff

View File

@ -83,6 +83,7 @@ pub enum ClearConfigType {
} }
#[derive(Debug)] #[derive(Debug)]
#[derive(PartialEq)]
pub enum Sensor { pub enum Sensor {
A, A,
B, B,
@ -143,6 +144,7 @@ pub trait PlantCtrlBoardInteraction {
fn wifi_ap(&mut self) -> Result<()>; fn wifi_ap(&mut self) -> Result<()>;
fn wifi_scan(&mut self) -> Result<Vec<AccessPointInfo>>; fn wifi_scan(&mut self) -> Result<Vec<AccessPointInfo>>;
fn test(&mut self) -> Result<()>; fn test(&mut self) -> Result<()>;
fn test_pump(&mut self, plant:usize) -> Result<()>;
fn is_wifi_config_file_existant(&mut self) -> bool; fn is_wifi_config_file_existant(&mut self) -> bool;
fn mqtt(&mut self, config: &Config) -> Result<()>; fn mqtt(&mut self, config: &Config) -> Result<()>;
fn mqtt_publish(&mut self, config: &Config, subtopic: &str, message: &[u8]) -> Result<()>; fn mqtt_publish(&mut self, config: &Config, subtopic: &str, message: &[u8]) -> Result<()>;
@ -357,12 +359,20 @@ impl PlantCtrlBoardInteraction for PlantCtrlBoard<'_> {
let factor = 1000 as f32 / measurement as f32; let factor = 1000 as f32 / measurement as f32;
self.shift_register.decompose()[index].set_high().unwrap(); self.shift_register.decompose()[index].set_high().unwrap();
if plant == 0 && sensor == Sensor::A {
let index = plant * PINS_PER_PLANT + PLANT_MOIST_PUMP_OFFSET;
//self.shift_register.decompose()[index].set_high().unwrap();
}
//give some time to stabilize //give some time to stabilize
delay.delay_ms(10); delay.delay_ms(10);
self.signal_counter.counter_resume()?; self.signal_counter.counter_resume()?;
delay.delay_ms(measurement); delay.delay_ms(measurement);
self.signal_counter.counter_pause()?; self.signal_counter.counter_pause()?;
self.shift_register.decompose()[index].set_low().unwrap(); self.shift_register.decompose()[index].set_low().unwrap();
if plant == 0 && sensor == Sensor::A {
let index = plant * PINS_PER_PLANT + PLANT_MOIST_PUMP_OFFSET;
//self.shift_register.decompose()[index].set_low().unwrap();
}
let unscaled = self.signal_counter.get_counter_value()? as i32; let unscaled = self.signal_counter.get_counter_value()? as i32;
let hz = (unscaled as f32 * factor) as i32; let hz = (unscaled as f32 * factor) as i32;
println!("Measuring {:?} @ {} with {}", sensor, plant, hz); println!("Measuring {:?} @ {} with {}", sensor, plant, hz);
@ -566,6 +576,15 @@ impl PlantCtrlBoardInteraction for PlantCtrlBoard<'_> {
Ok(self.wifi_driver.get_scan_result()?) Ok(self.wifi_driver.get_scan_result()?)
} }
fn test_pump(&mut self, plant:usize) -> Result<()> {
self.any_pump(true)?;
self.pump(plant, true)?;
unsafe { vTaskDelay(30000) };
self.pump(plant, false)?;
self.any_pump(false)?;
Ok(())
}
fn test(&mut self) -> Result<()> { fn test(&mut self) -> Result<()> {
self.general_fault(true); self.general_fault(true);
unsafe { vTaskDelay(100) }; unsafe { vTaskDelay(100) };
@ -791,6 +810,7 @@ impl PlantCtrlBoardInteraction for PlantCtrlBoard<'_> {
Err(err) => bail!("Error reading State of Health {:?}", err), Err(err) => bail!("Error reading State of Health {:?}", err),
} }
} }
} }
fn print_battery( fn print_battery(

View File

@ -1,5 +1,6 @@
<html> <html>
<body> <body>
<input type="button" id="test" value="Test">
<h2>Current Firmware</h2> <h2>Current Firmware</h2>
<div> <div>
<div id="firmware_buildtime">Buildtime loading</div> <div id="firmware_buildtime">Buildtime loading</div>

View File

@ -10,7 +10,7 @@ use core::result::Result::Ok;
use embedded_svc::http::Method; use embedded_svc::http::Method;
use esp_idf_svc::http::server::{Configuration, EspHttpServer}; use esp_idf_svc::http::server::{Configuration, EspHttpServer};
use heapless::String; use heapless::String;
use serde::Serialize; use serde::{Deserialize, Serialize};
use crate::{ use crate::{
config::{Config, WifiConfig}, config::{Config, WifiConfig},
@ -28,6 +28,11 @@ struct VersionInfo<'a> {
build_time: &'a str build_time: &'a str
} }
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct TestPump{
pump: usize
}
pub fn httpd_initial(reboot_now: Arc<AtomicBool>) -> Box<EspHttpServer<'static>> { pub fn httpd_initial(reboot_now: Arc<AtomicBool>) -> Box<EspHttpServer<'static>> {
let mut server = shared(); let mut server = shared();
server server
@ -91,15 +96,6 @@ pub fn httpd_initial(reboot_now: Arc<AtomicBool>) -> Box<EspHttpServer<'static>>
anyhow::Ok(()) anyhow::Ok(())
}) })
.unwrap(); .unwrap();
server
.fn_handler("/boardtest", Method::Post, move |_| {
let mut board = BOARD_ACCESS.lock().unwrap();
board.test()?;
anyhow::Ok(())
})
.unwrap();
server server
} }
@ -257,4 +253,39 @@ pub fn shared() -> Box<EspHttpServer<'static>> {
}) })
.unwrap(); .unwrap();
server server
.fn_handler("/boardtest", Method::Post, move |_| {
let mut board = BOARD_ACCESS.lock().unwrap();
board.test()?;
anyhow::Ok(())
})
.unwrap();
server
.fn_handler("/pumptest", Method::Post, |mut request| {
let mut buf = [0_u8; 3072];
let read = request.read(&mut buf);
if read.is_err() {
let error_text = read.unwrap_err().to_string();
println!("Could not parse testrequest {}", error_text);
request
.into_status_response(500)?
.write(error_text.as_bytes())?;
return anyhow::Ok(());
}
let actual_data = &buf[0..read.unwrap()];
println!("Raw data {}", from_utf8(actual_data).unwrap());
let pump_test: Result<TestPump, serde_json::Error> = serde_json::from_slice(actual_data);
if pump_test.is_err() {
let error_text = pump_test.unwrap_err().to_string();
println!("Could not parse TestPump {}", error_text);
request
.into_status_response(500)?
.write(error_text.as_bytes())?;
return Ok(());
}
let mut board = BOARD_ACCESS.lock().unwrap();
board.test_pump(pump_test.unwrap().pump)?;
anyhow::Ok(())
})
.unwrap();
server
} }

View File

@ -24,6 +24,10 @@ interface PlantConfig {
}[] }[]
} }
interface TestPump{
pump: number
}
let plants = document.getElementById("plants") as HTMLInputElement; let plants = document.getElementById("plants") as HTMLInputElement;
let fromWrapper = (() => { let fromWrapper = (() => {
@ -77,9 +81,33 @@ let fromWrapper = (() => {
header.textContent = "Plant " + (i + 1); header.textContent = "Plant " + (i + 1);
plant.appendChild(header); plant.appendChild(header);
{ {
let holder = document.createElement("div"); let holder = document.createElement("div");
plant.appendChild(holder); plant.appendChild(holder);
let testButton = document.createElement("button");
testButton.innerText = "Test";
testButton.id = "plant_" + i + "_test";
testButton.onclick = function (){
var body:TestPump = {
pump: i
}
var pretty = JSON.stringify(body, undefined, 1);
fetch("/pumptest", {
method :"POST",
body: pretty
})
.then(response => response.text())
.then(text => submit_status.innerText = text)
};
holder.appendChild(testButton);
let br = document.createElement("br");
holder.appendChild(br);
let inputf = document.createElement("select"); let inputf = document.createElement("select");
inputf.id = "plant_" + i + "_mode"; inputf.id = "plant_" + i + "_mode";
inputf.onchange = updateJson; inputf.onchange = updateJson;