Housekeeping #18
							
								
								
									
										7
									
								
								rust/.idea/dictionaries/project.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										7
									
								
								rust/.idea/dictionaries/project.xml
									
									
									
										generated
									
									
									
								
							| @@ -1,7 +1,14 @@ | |||||||
| <component name="ProjectDictionaryState"> | <component name="ProjectDictionaryState"> | ||||||
|   <dictionary name="project"> |   <dictionary name="project"> | ||||||
|     <words> |     <words> | ||||||
|  |       <w>buildtime</w> | ||||||
|  |       <w>deepsleep</w> | ||||||
|  |       <w>githash</w> | ||||||
|  |       <w>lightstate</w> | ||||||
|  |       <w>mppt</w> | ||||||
|  |       <w>plantstate</w> | ||||||
|       <w>sntp</w> |       <w>sntp</w> | ||||||
|  |       <w>vergen</w> | ||||||
|     </words> |     </words> | ||||||
|   </dictionary> |   </dictionary> | ||||||
| </component> | </component> | ||||||
| @@ -63,14 +63,14 @@ pub struct MqttClient<'a> { | |||||||
|     mqtt_client: EspMqttClient<'a>, |     mqtt_client: EspMqttClient<'a>, | ||||||
|     base_topic: heapless::String<64>, |     base_topic: heapless::String<64>, | ||||||
| } | } | ||||||
| pub struct ESP<'a> { | pub struct Esp<'a> { | ||||||
|     pub(crate) mqtt_client: Option<MqttClient<'a>>, |     pub(crate) mqtt_client: Option<MqttClient<'a>>, | ||||||
|     pub(crate) wifi_driver: EspWifi<'a>, |     pub(crate) wifi_driver: EspWifi<'a>, | ||||||
|     pub(crate) boot_button: PinDriver<'a, esp_idf_hal::gpio::AnyIOPin, esp_idf_hal::gpio::Input>, |     pub(crate) boot_button: PinDriver<'a, esp_idf_hal::gpio::AnyIOPin, esp_idf_hal::gpio::Input>, | ||||||
|     pub(crate) delay: Delay, |     pub(crate) delay: Delay, | ||||||
| } | } | ||||||
|  |  | ||||||
| impl ESP<'_> { | impl Esp<'_> { | ||||||
|     const SPIFFS_PARTITION_NAME: &'static str = "storage"; |     const SPIFFS_PARTITION_NAME: &'static str = "storage"; | ||||||
|     const CONFIG_FILE: &'static str = "/spiffs/config.cfg"; |     const CONFIG_FILE: &'static str = "/spiffs/config.cfg"; | ||||||
|     const BASE_PATH: &'static str = "/spiffs"; |     const BASE_PATH: &'static str = "/spiffs"; | ||||||
| @@ -310,7 +310,7 @@ impl ESP<'_> { | |||||||
|                                 filename: file.file_name().into_string().unwrap(), |                                 filename: file.file_name().into_string().unwrap(), | ||||||
|                                 size: file |                                 size: file | ||||||
|                                     .metadata() |                                     .metadata() | ||||||
|                                     .and_then(|it| Ok(it.len())) |                                     .map(|it| it.len()) | ||||||
|                                     .unwrap_or_default() |                                     .unwrap_or_default() | ||||||
|                                     as usize, |                                     as usize, | ||||||
|                             }; |                             }; | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| use crate::hal::esp::ESP; | use crate::hal::esp::Esp; | ||||||
| use crate::hal::{deep_sleep, BackupHeader, BoardInteraction, FreePeripherals, Sensor}; | use crate::hal::{deep_sleep, BackupHeader, BoardInteraction, FreePeripherals, Sensor}; | ||||||
| use crate::{ | use crate::{ | ||||||
|     config::PlantControllerConfig, |     config::PlantControllerConfig, | ||||||
| @@ -13,7 +13,7 @@ use measurements::{Current, Voltage}; | |||||||
|  |  | ||||||
| pub struct Initial<'a> { | pub struct Initial<'a> { | ||||||
|     pub(crate) general_fault: PinDriver<'a, esp_idf_hal::gpio::AnyIOPin, InputOutput>, |     pub(crate) general_fault: PinDriver<'a, esp_idf_hal::gpio::AnyIOPin, InputOutput>, | ||||||
|     pub(crate) esp: ESP<'a>, |     pub(crate) esp: Esp<'a>, | ||||||
|     pub(crate) config: PlantControllerConfig, |     pub(crate) config: PlantControllerConfig, | ||||||
|     pub(crate) battery: Box<dyn BatteryInteraction + Send>, |     pub(crate) battery: Box<dyn BatteryInteraction + Send>, | ||||||
| } | } | ||||||
| @@ -22,7 +22,7 @@ pub(crate) fn create_initial_board( | |||||||
|     free_pins: FreePeripherals, |     free_pins: FreePeripherals, | ||||||
|     fs_mount_error: bool, |     fs_mount_error: bool, | ||||||
|     config: PlantControllerConfig, |     config: PlantControllerConfig, | ||||||
|     esp: ESP<'static>, |     esp: Esp<'static>, | ||||||
| ) -> Result<Box<dyn BoardInteraction<'static> + Send>> { | ) -> Result<Box<dyn BoardInteraction<'static> + Send>> { | ||||||
|     let mut general_fault = PinDriver::input_output(free_pins.gpio6.downgrade())?; |     let mut general_fault = PinDriver::input_output(free_pins.gpio6.downgrade())?; | ||||||
|     general_fault.set_pull(Pull::Floating)?; |     general_fault.set_pull(Pull::Floating)?; | ||||||
| @@ -41,7 +41,7 @@ pub(crate) fn create_initial_board( | |||||||
| } | } | ||||||
|  |  | ||||||
| impl<'a> BoardInteraction<'a> for Initial<'a> { | impl<'a> BoardInteraction<'a> for Initial<'a> { | ||||||
|     fn get_esp(&mut self) -> &mut ESP<'a> { |     fn get_esp(&mut self) -> &mut Esp<'a> { | ||||||
|         &mut self.esp |         &mut self.esp | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ use crate::{ | |||||||
|     config::{BatteryBoardVersion, BoardVersion, PlantControllerConfig}, |     config::{BatteryBoardVersion, BoardVersion, PlantControllerConfig}, | ||||||
|     hal::{ |     hal::{ | ||||||
|         battery::{print_battery_bq34z100, BatteryInteraction, NoBatteryMonitor}, |         battery::{print_battery_bq34z100, BatteryInteraction, NoBatteryMonitor}, | ||||||
|         esp::ESP, |         esp::Esp, | ||||||
|     }, |     }, | ||||||
|     log::{log, LogMessage}, |     log::{log, LogMessage}, | ||||||
| }; | }; | ||||||
| @@ -37,12 +37,12 @@ use esp_idf_sys::{ | |||||||
|     esp_sleep_ext1_wakeup_mode_t_ESP_EXT1_WAKEUP_ANY_LOW, |     esp_sleep_ext1_wakeup_mode_t_ESP_EXT1_WAKEUP_ANY_LOW, | ||||||
| }; | }; | ||||||
| use esp_ota::mark_app_valid; | use esp_ota::mark_app_valid; | ||||||
|  | use measurements::{Current, Voltage}; | ||||||
| use once_cell::sync::Lazy; | use once_cell::sync::Lazy; | ||||||
| use serde::{Deserialize, Serialize}; | use serde::{Deserialize, Serialize}; | ||||||
| use std::result::Result::Ok as OkStd; | use std::result::Result::Ok as OkStd; | ||||||
| use std::sync::Mutex; | use std::sync::Mutex; | ||||||
| use std::time::Duration; | use std::time::Duration; | ||||||
| use measurements::{Current, Voltage}; |  | ||||||
|  |  | ||||||
| //Only support for 8 right now! | //Only support for 8 right now! | ||||||
| pub const PLANT_COUNT: usize = 8; | pub const PLANT_COUNT: usize = 8; | ||||||
| @@ -84,25 +84,15 @@ pub struct HAL<'a> { | |||||||
|     pub board_hal: Box<dyn BoardInteraction<'a> + Send>, |     pub board_hal: Box<dyn BoardInteraction<'a> + Send>, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Serialize, Deserialize, PartialEq, Debug)] | #[derive(Serialize, Deserialize, PartialEq, Debug, Default)] | ||||||
| pub struct BackupHeader { | pub struct BackupHeader { | ||||||
|     pub timestamp: i64, |     pub timestamp: i64, | ||||||
|     crc16: u16, |     crc16: u16, | ||||||
|     pub size: usize, |     pub size: usize, | ||||||
| } | } | ||||||
|  |  | ||||||
| impl Default for BackupHeader { |  | ||||||
|     fn default() -> Self { |  | ||||||
|         Self { |  | ||||||
|             timestamp: Default::default(), |  | ||||||
|             crc16: Default::default(), |  | ||||||
|             size: Default::default(), |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| pub trait BoardInteraction<'a> { | pub trait BoardInteraction<'a> { | ||||||
|     fn get_esp(&mut self) -> &mut ESP<'a>; |     fn get_esp(&mut self) -> &mut Esp<'a>; | ||||||
|     fn get_config(&mut self) -> &PlantControllerConfig; |     fn get_config(&mut self) -> &PlantControllerConfig; | ||||||
|     fn get_battery_monitor(&mut self) -> &mut Box<dyn BatteryInteraction + Send>; |     fn get_battery_monitor(&mut self) -> &mut Box<dyn BatteryInteraction + Send>; | ||||||
|     fn set_charge_indicator(&mut self, charging: bool) -> Result<()>; |     fn set_charge_indicator(&mut self, charging: bool) -> Result<()>; | ||||||
| @@ -225,7 +215,7 @@ impl PlantHal { | |||||||
|             gpio30: peripherals.pins.gpio30, |             gpio30: peripherals.pins.gpio30, | ||||||
|         }; |         }; | ||||||
|  |  | ||||||
|         let mut esp = ESP { |         let mut esp = Esp { | ||||||
|             mqtt_client: None, |             mqtt_client: None, | ||||||
|             wifi_driver, |             wifi_driver, | ||||||
|             boot_button, |             boot_button, | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ use crate::hal::{ | |||||||
| use crate::log::{log, LogMessage}; | use crate::log::{log, LogMessage}; | ||||||
| use crate::{ | use crate::{ | ||||||
|     config::PlantControllerConfig, |     config::PlantControllerConfig, | ||||||
|     hal::{battery::BatteryInteraction, esp::ESP}, |     hal::{battery::BatteryInteraction, esp::Esp}, | ||||||
| }; | }; | ||||||
| use anyhow::{anyhow, bail, Ok, Result}; | use anyhow::{anyhow, bail, Ok, Result}; | ||||||
| use chrono::{DateTime, Utc}; | use chrono::{DateTime, Utc}; | ||||||
| @@ -79,7 +79,7 @@ const FAULT_2: usize = 23; | |||||||
| pub struct V3<'a> { | pub struct V3<'a> { | ||||||
|     config: PlantControllerConfig, |     config: PlantControllerConfig, | ||||||
|     battery_monitor: Box<dyn BatteryInteraction + Send>, |     battery_monitor: Box<dyn BatteryInteraction + Send>, | ||||||
|     esp: ESP<'a>, |     esp: Esp<'a>, | ||||||
|     shift_register: ShiftRegister40< |     shift_register: ShiftRegister40< | ||||||
|         PinDriver<'a, esp_idf_hal::gpio::AnyIOPin, InputOutput>, |         PinDriver<'a, esp_idf_hal::gpio::AnyIOPin, InputOutput>, | ||||||
|         PinDriver<'a, esp_idf_hal::gpio::AnyIOPin, InputOutput>, |         PinDriver<'a, esp_idf_hal::gpio::AnyIOPin, InputOutput>, | ||||||
| @@ -107,7 +107,7 @@ pub struct V3<'a> { | |||||||
|  |  | ||||||
| pub(crate) fn create_v3( | pub(crate) fn create_v3( | ||||||
|     peripherals: FreePeripherals, |     peripherals: FreePeripherals, | ||||||
|     esp: ESP<'static>, |     esp: Esp<'static>, | ||||||
|     config: PlantControllerConfig, |     config: PlantControllerConfig, | ||||||
|     battery_monitor: Box<dyn BatteryInteraction + Send>, |     battery_monitor: Box<dyn BatteryInteraction + Send>, | ||||||
| ) -> Result<Box<dyn BoardInteraction<'static> + Send>> { | ) -> Result<Box<dyn BoardInteraction<'static> + Send>> { | ||||||
| @@ -270,7 +270,7 @@ impl<'a> BoardInteraction<'a> for V3<'a> { | |||||||
|     fn get_mptt_current(&mut self) -> Result<Current> { |     fn get_mptt_current(&mut self) -> Result<Current> { | ||||||
|         bail!("Board does not have current sensor") |         bail!("Board does not have current sensor") | ||||||
|     } |     } | ||||||
|     fn get_esp(&mut self) -> &mut ESP<'a> { |     fn get_esp(&mut self) -> &mut Esp<'a> { | ||||||
|         &mut self.esp |         &mut self.esp | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| use crate::config::PlantControllerConfig; | use crate::config::PlantControllerConfig; | ||||||
| use crate::hal::battery::BatteryInteraction; | use crate::hal::battery::BatteryInteraction; | ||||||
| use crate::hal::esp::ESP; | use crate::hal::esp::Esp; | ||||||
| use crate::hal::{ | use crate::hal::{ | ||||||
|     deep_sleep, BackupHeader, BoardInteraction, FreePeripherals, Sensor, I2C_DRIVER, PLANT_COUNT, |     deep_sleep, BackupHeader, BoardInteraction, FreePeripherals, Sensor, I2C_DRIVER, PLANT_COUNT, | ||||||
|     REPEAT_MOIST_MEASURE, TANK_MULTI_SAMPLE, X25, |     REPEAT_MOIST_MEASURE, TANK_MULTI_SAMPLE, X25, | ||||||
| @@ -22,15 +22,15 @@ use esp_idf_hal::i2c::I2cDriver; | |||||||
| use esp_idf_hal::pcnt::{ | use esp_idf_hal::pcnt::{ | ||||||
|     PcntChannel, PcntChannelConfig, PcntControlMode, PcntCountMode, PcntDriver, PinIndex, |     PcntChannel, PcntChannelConfig, PcntControlMode, PcntCountMode, PcntDriver, PinIndex, | ||||||
| }; | }; | ||||||
| use esp_idf_sys::{gpio_hold_dis, gpio_hold_en, vTaskDelay, EspError}; | use esp_idf_sys::{gpio_hold_dis, gpio_hold_en, EspError}; | ||||||
| use ina219::address::{Address, Pin}; | use ina219::address::{Address, Pin}; | ||||||
| use ina219::calibration::{Calibration, UnCalibrated}; | use ina219::calibration::UnCalibrated; | ||||||
|  | use ina219::configuration::{Configuration, OperatingMode}; | ||||||
| use ina219::SyncIna219; | use ina219::SyncIna219; | ||||||
| use measurements::{Current, Resistance, Voltage}; | use measurements::{Current, Resistance, Voltage}; | ||||||
| use one_wire_bus::OneWire; | use one_wire_bus::OneWire; | ||||||
| use pca9535::{GPIOBank, Pca9535Immediate, StandardExpanderInterface}; | use pca9535::{GPIOBank, Pca9535Immediate, StandardExpanderInterface}; | ||||||
| use std::result::Result::Ok as OkStd; | use std::result::Result::Ok as OkStd; | ||||||
| use ina219::configuration::{Configuration, OperatingMode}; |  | ||||||
|  |  | ||||||
| const MS0: u8 = 1_u8; | const MS0: u8 = 1_u8; | ||||||
| const MS1: u8 = 0_u8; | const MS1: u8 = 0_u8; | ||||||
| @@ -47,23 +47,27 @@ pub enum Charger<'a> { | |||||||
|     }, |     }, | ||||||
| } | } | ||||||
|  |  | ||||||
| impl<'a> Charger<'a> { | impl Charger<'_> { | ||||||
|     pub(crate) fn powersave(&mut self) { |     pub(crate) fn power_save(&mut self) { | ||||||
|         match self { Charger::SolarMpptV1 { mppt_ina, .. } => { |         match self { | ||||||
|             let _ = mppt_ina.set_configuration(Configuration { |             Charger::SolarMpptV1 { mppt_ina, .. } => { | ||||||
|  |                 let _ = mppt_ina | ||||||
|  |                     .set_configuration(Configuration { | ||||||
|                         reset: Default::default(), |                         reset: Default::default(), | ||||||
|                         bus_voltage_range: Default::default(), |                         bus_voltage_range: Default::default(), | ||||||
|                         shunt_voltage_range: Default::default(), |                         shunt_voltage_range: Default::default(), | ||||||
|                         bus_resolution: Default::default(), |                         bus_resolution: Default::default(), | ||||||
|                         shunt_resolution: Default::default(), |                         shunt_resolution: Default::default(), | ||||||
|                         operating_mode: OperatingMode::PowerDown, |                         operating_mode: OperatingMode::PowerDown, | ||||||
|             }).map_err(|e| { |                     }) | ||||||
|  |                     .map_err(|e| { | ||||||
|                         println!( |                         println!( | ||||||
|                     "Error setting ina mppt configuration during deep sleep preparation{:?}", |                     "Error setting ina mppt configuration during deep sleep preparation{:?}", | ||||||
|                     e |                     e | ||||||
|                 ); |                 ); | ||||||
|                     }); |                     }); | ||||||
|         } } |             } | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|     fn set_charge_indicator(&mut self, charging: bool) -> anyhow::Result<()> { |     fn set_charge_indicator(&mut self, charging: bool) -> anyhow::Result<()> { | ||||||
|         match self { |         match self { | ||||||
| @@ -105,7 +109,7 @@ impl<'a> Charger<'a> { | |||||||
| } | } | ||||||
|  |  | ||||||
| pub struct V4<'a> { | pub struct V4<'a> { | ||||||
|     esp: ESP<'a>, |     esp: Esp<'a>, | ||||||
|     charger: Charger<'a>, |     charger: Charger<'a>, | ||||||
|     battery_monitor: Box<dyn BatteryInteraction + Send>, |     battery_monitor: Box<dyn BatteryInteraction + Send>, | ||||||
|     config: PlantControllerConfig, |     config: PlantControllerConfig, | ||||||
| @@ -130,10 +134,10 @@ pub struct V4<'a> { | |||||||
|  |  | ||||||
| pub(crate) fn create_v4( | pub(crate) fn create_v4( | ||||||
|     peripherals: FreePeripherals, |     peripherals: FreePeripherals, | ||||||
|     esp: ESP<'static>, |     esp: Esp<'static>, | ||||||
|     config: PlantControllerConfig, |     config: PlantControllerConfig, | ||||||
|     battery_monitor: Box<dyn BatteryInteraction + Send>, |     battery_monitor: Box<dyn BatteryInteraction + Send>, | ||||||
| ) -> anyhow::Result<Box<dyn BoardInteraction + Send + '_>> { | ) -> anyhow::Result<Box<dyn BoardInteraction<'static> + Send + 'static>> { | ||||||
|     let mut awake = PinDriver::output(peripherals.gpio15.downgrade())?; |     let mut awake = PinDriver::output(peripherals.gpio15.downgrade())?; | ||||||
|     awake.set_high()?; |     awake.set_high()?; | ||||||
|  |  | ||||||
| @@ -252,7 +256,7 @@ pub(crate) fn create_v4( | |||||||
|         shunt_resolution: ina219::configuration::Resolution::Avg128, |         shunt_resolution: ina219::configuration::Resolution::Avg128, | ||||||
|         operating_mode: Default::default(), |         operating_mode: Default::default(), | ||||||
|     })?; |     })?; | ||||||
|     //TODO this is probably laready done untill we are ready first time?, maybee add startup time comparison on access? |     //TODO this is probably already done until we are ready first time?, maybe add startup time comparison on access? | ||||||
|     esp.delay.delay_ms( |     esp.delay.delay_ms( | ||||||
|         mppt_ina |         mppt_ina | ||||||
|             .configuration()? |             .configuration()? | ||||||
| @@ -288,7 +292,7 @@ pub(crate) fn create_v4( | |||||||
| } | } | ||||||
|  |  | ||||||
| impl<'a> BoardInteraction<'a> for V4<'a> { | impl<'a> BoardInteraction<'a> for V4<'a> { | ||||||
|     fn get_esp(&mut self) -> &mut ESP<'a> { |     fn get_esp(&mut self) -> &mut Esp<'a> { | ||||||
|         &mut self.esp |         &mut self.esp | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -306,7 +310,7 @@ impl<'a> BoardInteraction<'a> for V4<'a> { | |||||||
|  |  | ||||||
|     fn deep_sleep(&mut self, duration_in_ms: u64) -> ! { |     fn deep_sleep(&mut self, duration_in_ms: u64) -> ! { | ||||||
|         self.awake.set_low().unwrap(); |         self.awake.set_low().unwrap(); | ||||||
|         self.charger.powersave(); |         self.charger.power_save(); | ||||||
|         deep_sleep(duration_in_ms); |         deep_sleep(duration_in_ms); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -65,7 +65,7 @@ pub fn get_log() -> Vec<LogEntry> { | |||||||
|         read_copy.push(copy); |         read_copy.push(copy); | ||||||
|     } |     } | ||||||
|     drop(buffer); |     drop(buffer); | ||||||
|     return read_copy; |     read_copy | ||||||
| } | } | ||||||
|  |  | ||||||
| pub fn log(message_key: LogMessage, number_a: u32, number_b: u32, txt_short: &str, txt_long: &str) { | pub fn log(message_key: LogMessage, number_a: u32, number_b: u32, txt_short: &str, txt_long: &str) { | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| use crate::{ | use crate::{ | ||||||
|     config::BoardVersion::INITIAL, |     config::BoardVersion::INITIAL, | ||||||
|     hal::{PlantHal, HAL, PLANT_COUNT}, |     hal::{PlantHal, HAL, PLANT_COUNT}, | ||||||
|     webserver::webserver::httpd, |     webserver::httpd, | ||||||
| }; | }; | ||||||
| use anyhow::bail; | use anyhow::bail; | ||||||
| use chrono::{DateTime, Datelike, Timelike, Utc}; | use chrono::{DateTime, Datelike, Timelike, Utc}; | ||||||
| @@ -12,7 +12,7 @@ use esp_idf_sys::{ | |||||||
|     esp_ota_img_states_t, esp_ota_img_states_t_ESP_OTA_IMG_ABORTED, |     esp_ota_img_states_t, esp_ota_img_states_t_ESP_OTA_IMG_ABORTED, | ||||||
|     esp_ota_img_states_t_ESP_OTA_IMG_INVALID, esp_ota_img_states_t_ESP_OTA_IMG_NEW, |     esp_ota_img_states_t_ESP_OTA_IMG_INVALID, esp_ota_img_states_t_ESP_OTA_IMG_NEW, | ||||||
|     esp_ota_img_states_t_ESP_OTA_IMG_PENDING_VERIFY, esp_ota_img_states_t_ESP_OTA_IMG_UNDEFINED, |     esp_ota_img_states_t_ESP_OTA_IMG_PENDING_VERIFY, esp_ota_img_states_t_ESP_OTA_IMG_UNDEFINED, | ||||||
|     esp_ota_img_states_t_ESP_OTA_IMG_VALID, vTaskDelay, |     esp_ota_img_states_t_ESP_OTA_IMG_VALID, | ||||||
| }; | }; | ||||||
| use esp_ota::{mark_app_valid, rollback_and_reboot}; | use esp_ota::{mark_app_valid, rollback_and_reboot}; | ||||||
| use hal::battery::BatteryState; | use hal::battery::BatteryState; | ||||||
| @@ -28,13 +28,12 @@ mod hal; | |||||||
| mod log; | mod log; | ||||||
| mod plant_state; | mod plant_state; | ||||||
| mod tank; | mod tank; | ||||||
|  | mod webserver; | ||||||
|  |  | ||||||
| pub static BOARD_ACCESS: Lazy<Mutex<HAL>> = Lazy::new(|| PlantHal::create().unwrap()); | pub static BOARD_ACCESS: Lazy<Mutex<HAL>> = Lazy::new(|| PlantHal::create().unwrap()); | ||||||
| pub static STAY_ALIVE: Lazy<AtomicBool> = Lazy::new(|| AtomicBool::new(false)); | pub static STAY_ALIVE: Lazy<AtomicBool> = Lazy::new(|| AtomicBool::new(false)); | ||||||
|  |  | ||||||
| mod webserver { |  | ||||||
|     pub mod webserver; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[derive(Serialize, Deserialize, Debug, PartialEq)] | #[derive(Serialize, Deserialize, Debug, PartialEq)] | ||||||
| enum WaitType { | enum WaitType { | ||||||
| @@ -69,7 +68,7 @@ struct LightState { | |||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Serialize, Deserialize, Debug, PartialEq, Default)] | #[derive(Serialize, Deserialize, Debug, PartialEq, Default)] | ||||||
| ///mqtt stuct to track pump activities | ///mqtt struct to track pump activities | ||||||
| struct PumpInfo { | struct PumpInfo { | ||||||
|     enabled: bool, |     enabled: bool, | ||||||
|     pump_ineffective: bool, |     pump_ineffective: bool, | ||||||
| @@ -175,16 +174,7 @@ fn safe_main() -> anyhow::Result<()> { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     println!("cur is {}", cur); |     println!("cur is {}", cur); | ||||||
|     match board |     update_charge_indicator(&mut board); | ||||||
|         .board_hal |  | ||||||
|         .get_battery_monitor() |  | ||||||
|         .average_current_milli_ampere() |  | ||||||
|     { |  | ||||||
|         Ok(charging) => { |  | ||||||
|             let _ = board.board_hal.set_charge_indicator(charging > 20); |  | ||||||
|         } |  | ||||||
|         Err(_) => {} |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     if board.board_hal.get_esp().get_restart_to_conf() { |     if board.board_hal.get_esp().get_restart_to_conf() { | ||||||
|         log(LogMessage::ConfigModeSoftwareOverride, 0, 0, "", ""); |         log(LogMessage::ConfigModeSoftwareOverride, 0, 0, "", ""); | ||||||
| @@ -265,7 +255,7 @@ fn safe_main() -> anyhow::Result<()> { | |||||||
|             address, |             address, | ||||||
|             ota_state_string, |             ota_state_string, | ||||||
|             &mut board, |             &mut board, | ||||||
|             &ip_address, |             ip_address, | ||||||
|             timezone_time, |             timezone_time, | ||||||
|         ); |         ); | ||||||
|         publish_battery_state(&mut board); |         publish_battery_state(&mut board); | ||||||
| @@ -426,7 +416,7 @@ fn safe_main() -> anyhow::Result<()> { | |||||||
|         .board_hal |         .board_hal | ||||||
|         .get_battery_monitor() |         .get_battery_monitor() | ||||||
|         .get_battery_state() |         .get_battery_state() | ||||||
|         .unwrap_or(hal::battery::BatteryState::Unknown); |         .unwrap_or(BatteryState::Unknown); | ||||||
|  |  | ||||||
|     let mut light_state = LightState { |     let mut light_state = LightState { | ||||||
|         enabled: board.board_hal.get_config().night_lamp.enabled, |         enabled: board.board_hal.get_config().night_lamp.enabled, | ||||||
| @@ -556,6 +546,26 @@ fn safe_main() -> anyhow::Result<()> { | |||||||
|         .deep_sleep(1000 * 1000 * 60 * deep_sleep_duration_minutes as u64); |         .deep_sleep(1000 * 1000 * 60 * deep_sleep_duration_minutes as u64); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | fn update_charge_indicator(board: &mut MutexGuard<HAL>) { | ||||||
|  |     //we have mppt controller, ask it for charging current | ||||||
|  |     if let Ok(current) = board.board_hal.get_mptt_current() { | ||||||
|  |         let _ = board | ||||||
|  |             .board_hal | ||||||
|  |             .set_charge_indicator(current.as_milliamperes() > 20_f64); | ||||||
|  |     } | ||||||
|  |     //fallback to battery controller and ask it instead | ||||||
|  |     else if let Ok(charging) = board | ||||||
|  |         .board_hal | ||||||
|  |         .get_battery_monitor() | ||||||
|  |         .average_current_milli_ampere() | ||||||
|  |     { | ||||||
|  |         let _ = board.board_hal.set_charge_indicator(charging > 20); | ||||||
|  |     } else { | ||||||
|  |         //who knows | ||||||
|  |         let _ = board.board_hal.set_charge_indicator(false); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
| fn obtain_tank_temperature(board: &mut MutexGuard<HAL>) -> anyhow::Result<f32> { | fn obtain_tank_temperature(board: &mut MutexGuard<HAL>) -> anyhow::Result<f32> { | ||||||
|     //multisample should be moved to water_temperature_c |     //multisample should be moved to water_temperature_c | ||||||
|     let mut attempt = 1; |     let mut attempt = 1; | ||||||
| @@ -608,7 +618,7 @@ fn publish_plant_states( | |||||||
|         .zip(&board.board_hal.get_config().plants.clone()) |         .zip(&board.board_hal.get_config().plants.clone()) | ||||||
|         .enumerate() |         .enumerate() | ||||||
|     { |     { | ||||||
|         match serde_json::to_string(&plant_state.to_mqtt_info(plant_conf, &timezone_time)) { |         match serde_json::to_string(&plant_state.to_mqtt_info(plant_conf, timezone_time)) { | ||||||
|             Ok(state) => { |             Ok(state) => { | ||||||
|                 let plant_topic = format!("/plant{}", plant_id + 1); |                 let plant_topic = format!("/plant{}", plant_id + 1); | ||||||
|                 let _ = board |                 let _ = board | ||||||
| @@ -679,7 +689,7 @@ fn try_connect_wifi_sntp_mqtt(board: &mut MutexGuard<HAL>) -> NetworkMode { | |||||||
|                     SntpMode::OFFLINE |                     SntpMode::OFFLINE | ||||||
|                 } |                 } | ||||||
|             }; |             }; | ||||||
|             let mqtt_connected = if let Some(_) = board.board_hal.get_config().network.mqtt_url { |             let mqtt_connected = if board.board_hal.get_config().network.mqtt_url.is_some() { | ||||||
|                 let nw_config = &board.board_hal.get_config().network.clone(); |                 let nw_config = &board.board_hal.get_config().network.clone(); | ||||||
|                 match board.board_hal.get_esp().mqtt(nw_config) { |                 match board.board_hal.get_esp().mqtt(nw_config) { | ||||||
|                     Ok(_) => { |                     Ok(_) => { | ||||||
| @@ -750,27 +760,10 @@ fn wait_infinity(wait_type: WaitType, reboot_now: Arc<AtomicBool>) -> ! { | |||||||
|     let delay = wait_type.blink_pattern(); |     let delay = wait_type.blink_pattern(); | ||||||
|     let mut led_count = 8; |     let mut led_count = 8; | ||||||
|     let mut pattern_step = 0; |     let mut pattern_step = 0; | ||||||
|  |     let delay_handle = Delay::new_default(); | ||||||
|     loop { |     loop { | ||||||
|         unsafe { |  | ||||||
|         let mut board = BOARD_ACCESS.lock().unwrap(); |         let mut board = BOARD_ACCESS.lock().unwrap(); | ||||||
|  |         update_charge_indicator(&mut board); | ||||||
|             //we have mppt controller, ask it for charging current |  | ||||||
|             if let Ok(current) = board.board_hal.get_mptt_current() { |  | ||||||
|                 let _ = board.board_hal.set_charge_indicator(current.as_milliamperes() > 20_f64); |  | ||||||
|             } |  | ||||||
|             //fallback to battery controller and ask it instead |  | ||||||
|             else if let Ok(charging) = board |  | ||||||
|                 .board_hal |  | ||||||
|                 .get_battery_monitor() |  | ||||||
|                 .average_current_milli_ampere() |  | ||||||
|             { |  | ||||||
|                 let _ = board.board_hal.set_charge_indicator(charging > 20); |  | ||||||
|             } |  | ||||||
|             else { |  | ||||||
|                 //who knows |  | ||||||
|                 let _ = board.board_hal.set_charge_indicator(false); |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|         match wait_type { |         match wait_type { | ||||||
|             WaitType::MissingConfig => { |             WaitType::MissingConfig => { | ||||||
| @@ -799,7 +792,8 @@ fn wait_infinity(wait_type: WaitType, reboot_now: Arc<AtomicBool>) -> ! { | |||||||
|  |  | ||||||
|         board.board_hal.general_fault(true); |         board.board_hal.general_fault(true); | ||||||
|         drop(board); |         drop(board); | ||||||
|             vTaskDelay(delay); |         //cannot use shared delay as that is inside the mutex here | ||||||
|  |         delay_handle.delay_ms(delay); | ||||||
|         let mut board = BOARD_ACCESS.lock().unwrap(); |         let mut board = BOARD_ACCESS.lock().unwrap(); | ||||||
|         board.board_hal.general_fault(false); |         board.board_hal.general_fault(false); | ||||||
|  |  | ||||||
| @@ -808,7 +802,7 @@ fn wait_infinity(wait_type: WaitType, reboot_now: Arc<AtomicBool>) -> ! { | |||||||
|             let _ = board.board_hal.fault(i, false); |             let _ = board.board_hal.fault(i, false); | ||||||
|         } |         } | ||||||
|         drop(board); |         drop(board); | ||||||
|             vTaskDelay(delay); |         delay_handle.delay_ms(delay); | ||||||
|  |  | ||||||
|         if wait_type == WaitType::MqttConfig |         if wait_type == WaitType::MqttConfig | ||||||
|             && !STAY_ALIVE.load(std::sync::atomic::Ordering::Relaxed) |             && !STAY_ALIVE.load(std::sync::atomic::Ordering::Relaxed) | ||||||
| @@ -822,12 +816,11 @@ fn wait_infinity(wait_type: WaitType, reboot_now: Arc<AtomicBool>) -> ! { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| } |  | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let result = safe_main(); |     let result = safe_main(); | ||||||
|     match result { |     match result { | ||||||
|         // this should not get triggered, safe_main should not return but go into deep sleep with sensbile |         // this should not get triggered, safe_main should not return but go into deep sleep with sensible | ||||||
|         // timeout, this is just a fallback |         // timeout, this is just a fallback | ||||||
|         Ok(_) => { |         Ok(_) => { | ||||||
|             println!("Main app finished, restarting"); |             println!("Main app finished, restarting"); | ||||||
| @@ -849,13 +842,13 @@ fn main() { | |||||||
| } | } | ||||||
|  |  | ||||||
| pub fn in_time_range(cur: &DateTime<Tz>, start: u8, end: u8) -> bool { | pub fn in_time_range(cur: &DateTime<Tz>, start: u8, end: u8) -> bool { | ||||||
|     let curhour = cur.hour() as u8; |     let current_hour = cur.hour() as u8; | ||||||
|     //eg 10-14 |     //eg 10-14 | ||||||
|     if start < end { |     if start < end { | ||||||
|         curhour > start && curhour < end |         current_hour > start && current_hour < end | ||||||
|     } else { |     } else { | ||||||
|         //eg 20-05 |         //eg 20-05 | ||||||
|         curhour > start || curhour < end |         current_hour > start || current_hour < end | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user