Implement pump flow monitoring and UI normalization enhancements
- Rust: Add `MIN_PUMP_FLOW_ML` constant and logging for insufficient pump flow with fault handling. - UI: Normalize config fields to maintain consistency and prevent false dirty flags after round-trips. - KiCad: Update board zone settings for `PlantCtrlESP32` and `MPPT`. - IntelliJ: Add `.idea` configurations for project setup and inspections.
This commit is contained in:
Generated
+8
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="EMPTY_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<profile version="1.0">
|
||||||
|
<option name="myName" value="Project Default" />
|
||||||
|
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
|
</profile>
|
||||||
|
</component>
|
||||||
Generated
+8
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/PlantCtrl.iml" filepath="$PROJECT_DIR$/.idea/PlantCtrl.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
Generated
+6
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="PrettierConfiguration">
|
||||||
|
<option name="myConfigurationMode" value="AUTOMATIC" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
Generated
+7
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
<mapping directory="$PROJECT_DIR$/website/themes/blowfish" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
@@ -50,7 +50,23 @@
|
|||||||
"silk_text_thickness": 0.1,
|
"silk_text_thickness": 0.1,
|
||||||
"silk_text_upright": false,
|
"silk_text_upright": false,
|
||||||
"zones": {
|
"zones": {
|
||||||
"min_clearance": 0.5
|
"border_display_style": 2,
|
||||||
|
"border_hatch_pitch": 0.5,
|
||||||
|
"corner_radius": 0.0,
|
||||||
|
"corner_smoothing": 0,
|
||||||
|
"fill_mode": 0,
|
||||||
|
"hatch_gap": 1.5,
|
||||||
|
"hatch_orientation": 0.0,
|
||||||
|
"hatch_smoothing_level": 0,
|
||||||
|
"hatch_smoothing_value": 0.1,
|
||||||
|
"hatch_thickness": 1.0,
|
||||||
|
"min_clearance": 0.5,
|
||||||
|
"min_island_area": 10.0,
|
||||||
|
"min_thickness": 0.25,
|
||||||
|
"pad_connection": 1,
|
||||||
|
"remove_islands": 0,
|
||||||
|
"thermal_relief_gap": 0.5,
|
||||||
|
"thermal_relief_spoke_width": 0.5
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"diff_pair_dimensions": [
|
"diff_pair_dimensions": [
|
||||||
@@ -453,11 +469,14 @@
|
|||||||
"duplicate_sheet_names": "error",
|
"duplicate_sheet_names": "error",
|
||||||
"endpoint_off_grid": "warning",
|
"endpoint_off_grid": "warning",
|
||||||
"extra_units": "error",
|
"extra_units": "error",
|
||||||
|
"field_name_whitespace": "warning",
|
||||||
"footprint_filter": "ignore",
|
"footprint_filter": "ignore",
|
||||||
"footprint_link_issues": "warning",
|
"footprint_link_issues": "warning",
|
||||||
"four_way_junction": "ignore",
|
"four_way_junction": "ignore",
|
||||||
"global_label_dangling": "warning",
|
"global_label_dangling": "warning",
|
||||||
|
"ground_pin_not_ground": "warning",
|
||||||
"hier_label_mismatch": "error",
|
"hier_label_mismatch": "error",
|
||||||
|
"isolated_pin_label": "warning",
|
||||||
"label_dangling": "error",
|
"label_dangling": "error",
|
||||||
"label_multiple_wires": "warning",
|
"label_multiple_wires": "warning",
|
||||||
"lib_symbol_issues": "warning",
|
"lib_symbol_issues": "warning",
|
||||||
@@ -480,6 +499,7 @@
|
|||||||
"similar_power": "warning",
|
"similar_power": "warning",
|
||||||
"simulation_model_issue": "ignore",
|
"simulation_model_issue": "ignore",
|
||||||
"single_global_label": "ignore",
|
"single_global_label": "ignore",
|
||||||
|
"stacked_pin_name": "warning",
|
||||||
"unannotated": "error",
|
"unannotated": "error",
|
||||||
"unconnected_wire_endpoint": "warning",
|
"unconnected_wire_endpoint": "warning",
|
||||||
"undefined_netclass": "error",
|
"undefined_netclass": "error",
|
||||||
@@ -541,6 +561,10 @@
|
|||||||
},
|
},
|
||||||
"schematic": {
|
"schematic": {
|
||||||
"annotate_start_num": 0,
|
"annotate_start_num": 0,
|
||||||
|
"annotation": {
|
||||||
|
"method": 0,
|
||||||
|
"sort_order": 0
|
||||||
|
},
|
||||||
"bom_export_filename": "${PROJECTNAME}.csv",
|
"bom_export_filename": "${PROJECTNAME}.csv",
|
||||||
"bom_fmt_presets": [],
|
"bom_fmt_presets": [],
|
||||||
"bom_fmt_settings": {
|
"bom_fmt_settings": {
|
||||||
@@ -710,6 +734,7 @@
|
|||||||
"default_line_thickness": 6.0,
|
"default_line_thickness": 6.0,
|
||||||
"default_text_size": 50.0,
|
"default_text_size": 50.0,
|
||||||
"field_names": [],
|
"field_names": [],
|
||||||
|
"hop_over_size_choice": 0,
|
||||||
"intersheets_ref_own_page": false,
|
"intersheets_ref_own_page": false,
|
||||||
"intersheets_ref_prefix": "",
|
"intersheets_ref_prefix": "",
|
||||||
"intersheets_ref_short": false,
|
"intersheets_ref_short": false,
|
||||||
@@ -733,6 +758,7 @@
|
|||||||
"net_format_name": "",
|
"net_format_name": "",
|
||||||
"page_layout_descr_file": "",
|
"page_layout_descr_file": "",
|
||||||
"plot_directory": "",
|
"plot_directory": "",
|
||||||
|
"reuse_designators": true,
|
||||||
"space_save_all_events": true,
|
"space_save_all_events": true,
|
||||||
"spice_current_sheet_as_root": false,
|
"spice_current_sheet_as_root": false,
|
||||||
"spice_external_command": "spice \"%I\"",
|
"spice_external_command": "spice \"%I\"",
|
||||||
@@ -748,7 +774,9 @@
|
|||||||
"name": "MPPT",
|
"name": "MPPT",
|
||||||
"uuid": "00000000-0000-0000-0000-000000000000"
|
"uuid": "00000000-0000-0000-0000-000000000000"
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"used_designators": "",
|
||||||
|
"variants": []
|
||||||
},
|
},
|
||||||
"sheets": [
|
"sheets": [
|
||||||
[
|
[
|
||||||
|
|||||||
@@ -50,7 +50,23 @@
|
|||||||
"silk_text_thickness": 0.15,
|
"silk_text_thickness": 0.15,
|
||||||
"silk_text_upright": false,
|
"silk_text_upright": false,
|
||||||
"zones": {
|
"zones": {
|
||||||
"min_clearance": 0.0
|
"border_display_style": 2,
|
||||||
|
"border_hatch_pitch": 0.5,
|
||||||
|
"corner_radius": 0.0,
|
||||||
|
"corner_smoothing": 0,
|
||||||
|
"fill_mode": 0,
|
||||||
|
"hatch_gap": 1.5,
|
||||||
|
"hatch_orientation": 0.0,
|
||||||
|
"hatch_smoothing_level": 0,
|
||||||
|
"hatch_smoothing_value": 0.1,
|
||||||
|
"hatch_thickness": 1.0,
|
||||||
|
"min_clearance": 0.0,
|
||||||
|
"min_island_area": 10.0,
|
||||||
|
"min_thickness": 0.25,
|
||||||
|
"pad_connection": 1,
|
||||||
|
"remove_islands": 0,
|
||||||
|
"thermal_relief_gap": 0.5,
|
||||||
|
"thermal_relief_spoke_width": 0.5
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"diff_pair_dimensions": [
|
"diff_pair_dimensions": [
|
||||||
|
|||||||
@@ -321,6 +321,10 @@ pub enum LogMessage {
|
|||||||
serialize = "Trace: a: ${number_a} b: ${number_b} txt_s ${txt_short} long ${txt_long}"
|
serialize = "Trace: a: ${number_a} b: ${number_b} txt_s ${txt_short} long ${txt_long}"
|
||||||
)]
|
)]
|
||||||
Trace,
|
Trace,
|
||||||
|
#[strum(
|
||||||
|
serialize = "Pump insufficient flow, pump: ${number_a} measured ${number_b} ml, minimum is ${txt_short} ml"
|
||||||
|
)]
|
||||||
|
PumpInsufficientFlow,
|
||||||
#[strum(serialize = "Parsing error reading message")]
|
#[strum(serialize = "Parsing error reading message")]
|
||||||
UnknownMessage,
|
UnknownMessage,
|
||||||
#[strum(serialize = "Going to deep sleep for ${number_a} minutes")]
|
#[strum(serialize = "Going to deep sleep for ${number_a} minutes")]
|
||||||
|
|||||||
@@ -478,6 +478,17 @@ async fn safe_main(spawner: Spawner) -> FatResult<()> {
|
|||||||
state.flow_value_ml,
|
state.flow_value_ml,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
if !dry_run && state.flow_value_ml < MIN_PUMP_FLOW_ML {
|
||||||
|
log(
|
||||||
|
LogMessage::PumpInsufficientFlow,
|
||||||
|
(plant_id + 1) as u32,
|
||||||
|
state.flow_value_ml as u32,
|
||||||
|
&(MIN_PUMP_FLOW_ML as u32).to_string(),
|
||||||
|
"",
|
||||||
|
);
|
||||||
|
board.board_hal.general_fault(true).await;
|
||||||
|
board.board_hal.fault(plant_id, true).await?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
mqtt::pump_info(
|
mqtt::pump_info(
|
||||||
@@ -700,6 +711,8 @@ async fn safe_main(spawner: Spawner) -> FatResult<()> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const MIN_PUMP_FLOW_ML: f32 = 200.0;
|
||||||
|
|
||||||
pub async fn do_secure_pump(
|
pub async fn do_secure_pump(
|
||||||
board: &mut MutexGuard<'_, CriticalSectionRawMutex, HAL<'_>>,
|
board: &mut MutexGuard<'_, CriticalSectionRawMutex, HAL<'_>>,
|
||||||
plant_id: usize,
|
plant_id: usize,
|
||||||
|
|||||||
@@ -36,10 +36,10 @@ export interface BackupHeader {
|
|||||||
|
|
||||||
export interface NetworkConfig {
|
export interface NetworkConfig {
|
||||||
ap_ssid: string,
|
ap_ssid: string,
|
||||||
ssid: string,
|
ssid: string | null,
|
||||||
password: string,
|
password: string | null,
|
||||||
mqtt_url: string,
|
mqtt_url: string | null,
|
||||||
base_topic: string,
|
base_topic: string | null,
|
||||||
mqtt_user: string | null,
|
mqtt_user: string | null,
|
||||||
mqtt_password: string | null,
|
mqtt_password: string | null,
|
||||||
max_wait: number
|
max_wait: number
|
||||||
|
|||||||
@@ -246,8 +246,11 @@ export class Controller {
|
|||||||
const response = await fetch(PUBLIC_URL + "/get_config");
|
const response = await fetch(PUBLIC_URL + "/get_config");
|
||||||
const loaded = await response.json();
|
const loaded = await response.json();
|
||||||
const currentConfig = loaded as PlantControllerConfig;
|
const currentConfig = loaded as PlantControllerConfig;
|
||||||
controller.setInitialConfig(currentConfig);
|
|
||||||
controller.setConfig(currentConfig);
|
controller.setConfig(currentConfig);
|
||||||
|
// Store the config after the UI round-trip so null fields that the UI
|
||||||
|
// normalises (e.g. null → "" → null, null timezone → "UTC") are
|
||||||
|
// represented consistently and don't trigger a false dirty flag.
|
||||||
|
controller.setInitialConfig(controller.getConfig());
|
||||||
//sync json view initially
|
//sync json view initially
|
||||||
controller.configChanged();
|
controller.configChanged();
|
||||||
controller.progressview.removeProgress("get_config");
|
controller.progressview.removeProgress("get_config");
|
||||||
|
|||||||
@@ -102,10 +102,10 @@ export class NetworkConfigView {
|
|||||||
|
|
||||||
setConfig(network: NetworkConfig) {
|
setConfig(network: NetworkConfig) {
|
||||||
this.ap_ssid.value = network.ap_ssid;
|
this.ap_ssid.value = network.ap_ssid;
|
||||||
this.ssid.value = network.ssid;
|
this.ssid.value = network.ssid ?? "";
|
||||||
this.password.value = network.password;
|
this.password.value = network.password ?? "";
|
||||||
this.mqtt_url.value = network.mqtt_url;
|
this.mqtt_url.value = network.mqtt_url ?? "";
|
||||||
this.base_topic.value = network.base_topic;
|
this.base_topic.value = network.base_topic ?? "";
|
||||||
this.mqtt_user.value = network.mqtt_user ?? "";
|
this.mqtt_user.value = network.mqtt_user ?? "";
|
||||||
this.mqtt_password.value = network.mqtt_password ?? "";
|
this.mqtt_password.value = network.mqtt_password ?? "";
|
||||||
this.max_wait.value = network.max_wait.toString();
|
this.max_wait.value = network.max_wait.toString();
|
||||||
@@ -115,12 +115,12 @@ export class NetworkConfigView {
|
|||||||
return {
|
return {
|
||||||
max_wait: +this.max_wait.value,
|
max_wait: +this.max_wait.value,
|
||||||
ap_ssid: this.ap_ssid.value,
|
ap_ssid: this.ap_ssid.value,
|
||||||
ssid: this.ssid.value ?? null,
|
ssid: this.ssid.value || null,
|
||||||
password: this.password.value ?? null,
|
password: this.password.value || null,
|
||||||
mqtt_url: this.mqtt_url.value ?? null,
|
mqtt_url: this.mqtt_url.value || null,
|
||||||
mqtt_user: this.mqtt_user.value ? this.mqtt_user.value : null,
|
mqtt_user: this.mqtt_user.value || null,
|
||||||
mqtt_password: this.mqtt_password.value ? this.mqtt_password.value : null,
|
mqtt_password: this.mqtt_password.value || null,
|
||||||
base_topic: this.base_topic.value ?? null
|
base_topic: this.base_topic.value || null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+8
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="EMPTY_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
Reference in New Issue
Block a user