implement log localization config generation #1
| @@ -60,22 +60,7 @@ | ||||
|       ], | ||||
|       "drc_exclusions": [ | ||||
|         "footprint_symbol_mismatch|177050000|59025000|a624af3d-bffa-4ff7-9554-e16d3c677f69|00000000-0000-0000-0000-000000000000", | ||||
|         "footprint_symbol_mismatch|237580000|53970000|c9d8d35b-26b7-4992-9d25-be9130d57b1a|00000000-0000-0000-0000-000000000000", | ||||
|         "footprint_symbol_mismatch|256580000|49370000|b33af7ef-63da-4a51-8d8a-183cadd974de|00000000-0000-0000-0000-000000000000", | ||||
|         "net_conflict|177050000|59025000|09cad967-1882-4dd3-8900-445282e228e5|00000000-0000-0000-0000-000000000000", | ||||
|         "net_conflict|177050000|59025000|20ab85c0-b3f3-4826-a86d-065fee01e11f|00000000-0000-0000-0000-000000000000", | ||||
|         "net_conflict|177050000|59025000|3da9717d-9800-42f9-97d1-56d23bf085aa|00000000-0000-0000-0000-000000000000", | ||||
|         "net_conflict|177050000|59025000|444aab2b-3a9b-444e-b60c-b5b5ff830942|00000000-0000-0000-0000-000000000000", | ||||
|         "net_conflict|177050000|59025000|6b067fd3-d374-4937-8779-958994d9163b|00000000-0000-0000-0000-000000000000", | ||||
|         "net_conflict|177050000|59025000|9839c562-7672-4ea8-a74d-bea83ae26677|00000000-0000-0000-0000-000000000000", | ||||
|         "net_conflict|177050000|59025000|9ce2df19-edf4-40d2-8e85-8c33008b8df0|00000000-0000-0000-0000-000000000000", | ||||
|         "net_conflict|177050000|59025000|a8ab716a-cd1e-4842-ad8e-3d6d1db9770b|00000000-0000-0000-0000-000000000000", | ||||
|         "net_conflict|177050000|59025000|aaf09ae3-4ace-49d7-a050-44cb4c93d63b|00000000-0000-0000-0000-000000000000", | ||||
|         "net_conflict|177050000|59025000|af55e8a2-ba8d-462e-807f-99ca5906f801|00000000-0000-0000-0000-000000000000", | ||||
|         "net_conflict|177050000|59025000|c36efd78-869f-40e7-86fc-97e5ed683fec|00000000-0000-0000-0000-000000000000", | ||||
|         "net_conflict|177050000|59025000|d668fda0-e4be-4e1f-95b8-8cd59a67cb21|00000000-0000-0000-0000-000000000000", | ||||
|         "net_conflict|177050000|59025000|d99401c6-2b75-46f7-8616-cdd7755709ee|00000000-0000-0000-0000-000000000000", | ||||
|         "net_conflict|177050000|59025000|f1fd5816-e8bd-4ba6-9d53-54b58d25e2dc|00000000-0000-0000-0000-000000000000" | ||||
|         "footprint_symbol_mismatch|237580000|53970000|c9d8d35b-26b7-4992-9d25-be9130d57b1a|00000000-0000-0000-0000-000000000000" | ||||
|       ], | ||||
|       "meta": { | ||||
|         "filename": "board_design_settings.json", | ||||
| @@ -98,6 +83,7 @@ | ||||
|         "footprint_type_mismatch": "ignore", | ||||
|         "hole_clearance": "error", | ||||
|         "hole_near_hole": "error", | ||||
|         "holes_co_located": "warning", | ||||
|         "invalid_outline": "error", | ||||
|         "isolated_copper": "warning", | ||||
|         "item_on_disabled_layer": "error", | ||||
|   | ||||
| @@ -8,7 +8,7 @@ resolver = "2" | ||||
|  | ||||
| [profile.dev] | ||||
| # Explicitly disable LTO which the Xtensa codegen backend has issues | ||||
| lto = true | ||||
| lto = false | ||||
| strip = false | ||||
| debug = true  | ||||
| overflow-checks = true | ||||
|   | ||||
| @@ -156,6 +156,30 @@ pub enum LogMessage { | ||||
|     mqtt_stay_alive_rec, | ||||
|     #[strum(serialize = "Unknown topic recieved {{txt_long}}")]    | ||||
|     unknown_topic, | ||||
|     #[strum(serialize = "Partition state is {{txt_long}}")]    | ||||
|     partition_state, | ||||
|     #[strum(serialize = "Mounted Filesystem free {{a}} total {{b}} use {{txt_short}}")] | ||||
|     filesystem_mount, | ||||
|     #[strum(serialize = "Mounting Filesystem, this will format the first time and needs quite some time!")] | ||||
|     mounting_filesystem, | ||||
|     #[strum(serialize = "Year inplausible, force config mode")] | ||||
|     year_inplausible_force_config, | ||||
|     #[strum(serialize = "Going to config mode, due to request from prior run")] | ||||
|     config_mode_software_override, | ||||
|     #[strum(serialize = "Going to config mode, due to request via config mode button")] | ||||
|     config_mode_button_override, | ||||
|     #[strum(serialize = "Going to normal mode")] | ||||
|     normal_run, | ||||
|     #[strum(serialize = "Missing normal config, entering config mode {{txt_long}}")] | ||||
|     config_mode_missing_config, | ||||
|     #[strum(serialize = "startup state wifi {{a}} sntp {{b}} mqtt {{txt_short}}")] | ||||
|     startup_info, | ||||
|     #[strum(serialize = "Trying to pump for {{b}}s with pump {{a}} now dryrun: {{txt_short}}")] | ||||
|     pump_plant, | ||||
|     #[strum(serialize = "Enable main power dryrun: {{a}}")] | ||||
|     enable_main, | ||||
|     #[strum(serialize = "Pumped multiple times, but plant is still to try attempt: {{a}} limit :: {{b}} plant: {{txt_short}}")] | ||||
|     consecutive_pump_count_limit | ||||
| } | ||||
|  | ||||
| impl LogMessage { | ||||
|   | ||||
							
								
								
									
										136
									
								
								rust/src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										136
									
								
								rust/src/main.rs
									
									
									
									
									
								
							| @@ -22,6 +22,7 @@ use esp_idf_sys::{ | ||||
|     esp_ota_img_states_t_ESP_OTA_IMG_VALID,  | ||||
|     vTaskDelay | ||||
| }; | ||||
| use log::log; | ||||
| use once_cell::sync::Lazy; | ||||
| use plant_hal::{PlantCtrlBoard, PlantHal, PLANT_COUNT}; | ||||
| use serde::{Deserialize, Serialize}; | ||||
| @@ -170,35 +171,33 @@ fn safe_main() -> anyhow::Result<()> { | ||||
|     let ota_state_string = unsafe { | ||||
|         esp_ota_get_state_partition(running_partition, &mut ota_state); | ||||
|         if ota_state == esp_ota_img_states_t_ESP_OTA_IMG_NEW { | ||||
|             format!("Partition state is {}", "ESP_OTA_IMG_NEW") | ||||
|             "ESP_OTA_IMG_NEW" | ||||
|         } else if ota_state == esp_ota_img_states_t_ESP_OTA_IMG_PENDING_VERIFY { | ||||
|             format!("Partition state is {}", "ESP_OTA_IMG_PENDING_VERIFY") | ||||
|             "ESP_OTA_IMG_PENDING_VERIFY" | ||||
|         } else if ota_state == esp_ota_img_states_t_ESP_OTA_IMG_VALID { | ||||
|             format!("Partition state is {}", "ESP_OTA_IMG_VALID") | ||||
|             "ESP_OTA_IMG_VALID" | ||||
|         } else if ota_state == esp_ota_img_states_t_ESP_OTA_IMG_INVALID { | ||||
|             format!("Partition state is {}", "ESP_OTA_IMG_INVALID") | ||||
|             "ESP_OTA_IMG_INVALID" | ||||
|         } else if ota_state == esp_ota_img_states_t_ESP_OTA_IMG_ABORTED { | ||||
|             format!("Partition state is {}", "ESP_OTA_IMG_ABORTED") | ||||
|             "ESP_OTA_IMG_ABORTED" | ||||
|         } else if ota_state == esp_ota_img_states_t_ESP_OTA_IMG_UNDEFINED { | ||||
|             format!("Partition state is {}", "ESP_OTA_IMG_UNDEFINED") | ||||
|             "ESP_OTA_IMG_UNDEFINED" | ||||
|         } else { | ||||
|             format!("Partition state is {}", ota_state) | ||||
|             &format!("unknown {ota_state}") | ||||
|         } | ||||
|     }; | ||||
|     println!("{}", ota_state_string); | ||||
|     log(log::LogMessage::partition_state, 0,0, "", ota_state_string); | ||||
|  | ||||
|      | ||||
|     println!("Board hal init"); | ||||
|     let mut board: std::sync::MutexGuard<'_, PlantCtrlBoard<'_>> = BOARD_ACCESS.lock().unwrap(); | ||||
|     board.general_fault(false); | ||||
|  | ||||
|     println!("Mounting filesystem"); | ||||
|     log(log::LogMessage::mounting_filesystem, 0,0,"",""); | ||||
|     board.mount_file_system()?; | ||||
|     let free_space = board.file_system_size()?; | ||||
|     println!( | ||||
|         "Mounted, total space {} used {} free {}", | ||||
|         free_space.total_size, free_space.used_size, free_space.free_size | ||||
|     ); | ||||
|     log(log::LogMessage::filesystem_mount, free_space.free_size as u32, | ||||
|         free_space.total_size as u32, &free_space.used_size.to_string(), ""); | ||||
|  | ||||
|  | ||||
|     let mut cur = match board.get_rtc_time() { | ||||
|         Ok(time) => time, | ||||
| @@ -219,12 +218,13 @@ fn safe_main() -> anyhow::Result<()> { | ||||
|     //check if we know the time current > 2020 | ||||
|     if cur.year() < 2020 { | ||||
|         to_config = true; | ||||
|         log(log::LogMessage::year_inplausible_force_config, 0,0,"",""); | ||||
|     } | ||||
|  | ||||
|     println!("cur is {}", cur); | ||||
|  | ||||
|     if board.get_restart_to_conf() { | ||||
|         println!("config mode software override"); | ||||
|         log(log::LogMessage::config_mode_software_override, 0,0,"",""); | ||||
|         for _i in 0..2 { | ||||
|             board.general_fault(true); | ||||
|             Delay::new_default().delay_ms(100); | ||||
| @@ -236,7 +236,7 @@ fn safe_main() -> anyhow::Result<()> { | ||||
|         board.set_restart_to_conf(false); | ||||
|     } else if board.is_mode_override() { | ||||
|         board.general_fault(true); | ||||
|         println!("config mode override is pressed, waiting 5s"); | ||||
|         log(log::LogMessage::config_mode_button_override, 0,0,"",""); | ||||
|         for _i in 0..5 { | ||||
|             board.general_fault(true); | ||||
|             Delay::new_default().delay_ms(100); | ||||
| @@ -250,10 +250,7 @@ fn safe_main() -> anyhow::Result<()> { | ||||
|         } else { | ||||
|             board.general_fault(false); | ||||
|         } | ||||
|     } else { | ||||
|         println!("No config override start detected"); | ||||
|     } | ||||
|      | ||||
|     }  | ||||
|  | ||||
|     let config: PlantControllerConfig; | ||||
|     match board.get_config() { | ||||
| @@ -261,7 +258,7 @@ fn safe_main() -> anyhow::Result<()> { | ||||
|             config = valid; | ||||
|         } | ||||
|         Err(err) => { | ||||
|             println!("Missing normal config, entering config mode {}", err); | ||||
|             log(log::LogMessage::config_mode_missing_config, 0,0,"",&err.to_string()); | ||||
|             //config upload will trigger reboot! | ||||
|             let _ = board.wifi_ap(Option::None); | ||||
|             drop(board); | ||||
| @@ -365,7 +362,7 @@ fn safe_main() -> anyhow::Result<()> { | ||||
|         publish_battery_state(&mut board, &config); | ||||
|     } | ||||
|  | ||||
|     println!("startup state wifi {} sntp {} mqtt {}", wifi, sntp, mqtt); | ||||
|     log(log::LogMessage::startup_info, wifi as u32, sntp as u32,&mqtt.to_string(),""); | ||||
|  | ||||
|     if to_config { | ||||
|         //check if client or ap mode and init wifi | ||||
| @@ -375,8 +372,13 @@ fn safe_main() -> anyhow::Result<()> { | ||||
|         let reboot_now = Arc::new(AtomicBool::new(false)); | ||||
|         let _webserver = httpd(reboot_now.clone()); | ||||
|         wait_infinity(WaitType::ConfigButton, reboot_now.clone()); | ||||
|     } else { | ||||
|         log(log::LogMessage::normal_run, 0,0,"",""); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     let dry_run = false; | ||||
|  | ||||
|     let tank_state = determine_tank_state(&mut board, &config); | ||||
|     let mut tank_state_mqtt = TankStateMQTT { | ||||
|         enough_water: tank_state.enough_water, | ||||
| @@ -421,6 +423,8 @@ fn safe_main() -> anyhow::Result<()> { | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|  | ||||
|  | ||||
|     let mut plantstate: [PlantState; PLANT_COUNT] = core::array::from_fn(|_| PlantState { | ||||
|         ..Default::default() | ||||
|     }); | ||||
| @@ -433,45 +437,38 @@ fn safe_main() -> anyhow::Result<()> { | ||||
|         &mut board, | ||||
|     ); | ||||
|  | ||||
|     let stay_alive_mqtt = STAY_ALIVE.load(std::sync::atomic::Ordering::Relaxed); | ||||
|  | ||||
|     let stay_alive = stay_alive_mqtt; | ||||
|     println!("Check stay alive, current state is {}", stay_alive); | ||||
|  | ||||
|     let mut did_pump = false; | ||||
|     match plant_to_pump { | ||||
|         Some(plant) => { | ||||
|             let plant_config = &config.plants[plant]; | ||||
|  | ||||
|     let pump_required = plantstate.iter().any(|it| it.do_water) && !water_frozen; | ||||
|     if pump_required { | ||||
|         log(log::LogMessage::enable_main, dry_run as u32,0,"",""); | ||||
|         if !dry_run{ | ||||
|             board.any_pump(true)?;     | ||||
|         }        | ||||
|         for plant in 0..PLANT_COUNT { | ||||
|             let state = &mut plantstate[plant]; | ||||
|             state.consecutive_pump_count = board.consecutive_pump_count(plant) + 1; | ||||
|             board.store_consecutive_pump_count(plant, state.consecutive_pump_count); | ||||
|             if state.consecutive_pump_count > plant_config.max_consecutive_pump_count.into() { | ||||
|                 state.not_effective = true; | ||||
|                 board.fault(plant, true); | ||||
|             } | ||||
|  | ||||
|             println!( | ||||
|                 "Trying to pump for {}s with pump {} now", | ||||
|                 plant_config.pump_time_s, plant | ||||
|             ); | ||||
|             if !stay_alive && !to_config { | ||||
|                 did_pump = true; | ||||
|                 board.any_pump(true)?; | ||||
|             if state.do_water { | ||||
|                  | ||||
|                 let plant_config = &config.plants[plant]; | ||||
|                 state.consecutive_pump_count = board.consecutive_pump_count(plant) + 1; | ||||
|                 board.store_consecutive_pump_count(plant, state.consecutive_pump_count); | ||||
|                 if state.consecutive_pump_count > plant_config.max_consecutive_pump_count as u32 { | ||||
|                     log(log::LogMessage::consecutive_pump_count_limit, state.consecutive_pump_count as u32,plant_config.max_consecutive_pump_count as u32,&plant.to_string(),""); | ||||
|                     state.not_effective = true; | ||||
|                     board.fault(plant, true); | ||||
|                 } | ||||
|                 log(log::LogMessage::pump_plant, (plant + 1) as u32,plant_config.pump_time_s as u32,&dry_run.to_string(),""); | ||||
|                 board.store_last_pump_time(plant, cur); | ||||
|                 board.pump(plant, true)?; | ||||
|                 board.last_pump_time(plant); | ||||
|                 state.active = true; | ||||
|                 for _ in 0..plant_config.pump_time_s { | ||||
|                     Delay::new_default().delay_ms(1000); | ||||
|                 if !dry_run { | ||||
|                     board.pump(plant, true)?; | ||||
|                     for _ in 0..plant_config.pump_time_s { | ||||
|                         Delay::new_default().delay_ms(1000); | ||||
|                     } | ||||
|                     board.pump(plant, false)?; | ||||
|                 } | ||||
|  | ||||
|                 board.pump(plant, false)?; | ||||
|             } | ||||
|         } | ||||
|         None => { | ||||
|             println!("Nothing to do"); | ||||
|         } | ||||
|     } | ||||
|     update_plant_state(&mut plantstate, &mut board, &config); | ||||
|  | ||||
| @@ -532,14 +529,8 @@ fn safe_main() -> anyhow::Result<()> { | ||||
|         let _ = board.mqtt_publish(&config, "/deepsleep", "low Volt 12h".as_bytes()); | ||||
|         12 * 60 | ||||
|     } else if is_day { | ||||
|         if did_pump { | ||||
|             let _ = board.mqtt_publish(&config, "/deepsleep", "after pump".as_bytes()); | ||||
|             0 | ||||
|         } else { | ||||
|             let _ = board.mqtt_publish(&config, "/deepsleep", "normal 20m".as_bytes()); | ||||
|  | ||||
|             20 | ||||
|         } | ||||
|         let _ = board.mqtt_publish(&config, "/deepsleep", "normal 20m".as_bytes()); | ||||
|         20 | ||||
|     } else { | ||||
|         let _ = board.mqtt_publish(&config, "/deepsleep", "night 1h".as_bytes()); | ||||
|         60 | ||||
| @@ -552,6 +543,13 @@ fn safe_main() -> anyhow::Result<()> { | ||||
|     //is deep sleep | ||||
|     mark_app_valid(); | ||||
|  | ||||
|  | ||||
|     let stay_alive_mqtt = STAY_ALIVE.load(std::sync::atomic::Ordering::Relaxed); | ||||
|  | ||||
|     let stay_alive = stay_alive_mqtt; | ||||
|     println!("Check stay alive, current state is {}", stay_alive); | ||||
|  | ||||
|  | ||||
|     if stay_alive { | ||||
|         println!("Go to stay alive move"); | ||||
|         drop(board); | ||||
| @@ -821,7 +819,7 @@ fn determine_next_plant( | ||||
|     water_frozen: bool, | ||||
|     config: &PlantControllerConfig, | ||||
|     board: &mut std::sync::MutexGuard<'_, PlantCtrlBoard<'_>>, | ||||
| ) -> Option<usize> { | ||||
| ) { | ||||
|     for plant in 0..PLANT_COUNT { | ||||
|         let state = &mut plantstate[plant]; | ||||
|         let plant_config = &config.plants[plant]; | ||||
| @@ -851,20 +849,6 @@ fn determine_next_plant( | ||||
|         } | ||||
|         println!("Plant {} state is {:?}", plant, state); | ||||
|     } | ||||
|     for plant in 0..PLANT_COUNT { | ||||
|         let state = &plantstate[plant]; | ||||
|         println!( | ||||
|             "Checking for water plant {} with state {}", | ||||
|             plant, state.do_water | ||||
|         ); | ||||
|         if !water_frozen { | ||||
|             if state.do_water { | ||||
|                 return Some(plant); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     println!("No plant needs water"); | ||||
|     return None; | ||||
| } | ||||
|  | ||||
| fn update_plant_state( | ||||
|   | ||||
		Reference in New Issue
	
	Block a user