Housekeeping #18
							
								
								
									
										7
									
								
								rust/.idea/dictionaries/project.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										7
									
								
								rust/.idea/dictionaries/project.xml
									
									
									
										generated
									
									
									
								
							| @@ -1,7 +1,14 @@ | ||||
| <component name="ProjectDictionaryState"> | ||||
|   <dictionary name="project"> | ||||
|     <words> | ||||
|       <w>buildtime</w> | ||||
|       <w>deepsleep</w> | ||||
|       <w>githash</w> | ||||
|       <w>lightstate</w> | ||||
|       <w>mppt</w> | ||||
|       <w>plantstate</w> | ||||
|       <w>sntp</w> | ||||
|       <w>vergen</w> | ||||
|     </words> | ||||
|   </dictionary> | ||||
| </component> | ||||
| @@ -63,14 +63,14 @@ pub struct MqttClient<'a> { | ||||
|     mqtt_client: EspMqttClient<'a>, | ||||
|     base_topic: heapless::String<64>, | ||||
| } | ||||
| pub struct ESP<'a> { | ||||
| pub struct Esp<'a> { | ||||
|     pub(crate) mqtt_client: Option<MqttClient<'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) delay: Delay, | ||||
| } | ||||
|  | ||||
| impl ESP<'_> { | ||||
| impl Esp<'_> { | ||||
|     const SPIFFS_PARTITION_NAME: &'static str = "storage"; | ||||
|     const CONFIG_FILE: &'static str = "/spiffs/config.cfg"; | ||||
|     const BASE_PATH: &'static str = "/spiffs"; | ||||
| @@ -310,7 +310,7 @@ impl ESP<'_> { | ||||
|                                 filename: file.file_name().into_string().unwrap(), | ||||
|                                 size: file | ||||
|                                     .metadata() | ||||
|                                     .and_then(|it| Ok(it.len())) | ||||
|                                     .map(|it| it.len()) | ||||
|                                     .unwrap_or_default() | ||||
|                                     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::{ | ||||
|     config::PlantControllerConfig, | ||||
| @@ -13,7 +13,7 @@ use measurements::{Current, Voltage}; | ||||
|  | ||||
| pub struct Initial<'a> { | ||||
|     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) battery: Box<dyn BatteryInteraction + Send>, | ||||
| } | ||||
| @@ -22,7 +22,7 @@ pub(crate) fn create_initial_board( | ||||
|     free_pins: FreePeripherals, | ||||
|     fs_mount_error: bool, | ||||
|     config: PlantControllerConfig, | ||||
|     esp: ESP<'static>, | ||||
|     esp: Esp<'static>, | ||||
| ) -> Result<Box<dyn BoardInteraction<'static> + Send>> { | ||||
|     let mut general_fault = PinDriver::input_output(free_pins.gpio6.downgrade())?; | ||||
|     general_fault.set_pull(Pull::Floating)?; | ||||
| @@ -41,7 +41,7 @@ pub(crate) fn create_initial_board( | ||||
| } | ||||
|  | ||||
| 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 | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -8,7 +8,7 @@ use crate::{ | ||||
|     config::{BatteryBoardVersion, BoardVersion, PlantControllerConfig}, | ||||
|     hal::{ | ||||
|         battery::{print_battery_bq34z100, BatteryInteraction, NoBatteryMonitor}, | ||||
|         esp::ESP, | ||||
|         esp::Esp, | ||||
|     }, | ||||
|     log::{log, LogMessage}, | ||||
| }; | ||||
| @@ -37,12 +37,12 @@ use esp_idf_sys::{ | ||||
|     esp_sleep_ext1_wakeup_mode_t_ESP_EXT1_WAKEUP_ANY_LOW, | ||||
| }; | ||||
| use esp_ota::mark_app_valid; | ||||
| use measurements::{Current, Voltage}; | ||||
| use once_cell::sync::Lazy; | ||||
| use serde::{Deserialize, Serialize}; | ||||
| use std::result::Result::Ok as OkStd; | ||||
| use std::sync::Mutex; | ||||
| use std::time::Duration; | ||||
| use measurements::{Current, Voltage}; | ||||
|  | ||||
| //Only support for 8 right now! | ||||
| pub const PLANT_COUNT: usize = 8; | ||||
| @@ -84,25 +84,15 @@ pub struct HAL<'a> { | ||||
|     pub board_hal: Box<dyn BoardInteraction<'a> + Send>, | ||||
| } | ||||
|  | ||||
| #[derive(Serialize, Deserialize, PartialEq, Debug)] | ||||
| #[derive(Serialize, Deserialize, PartialEq, Debug, Default)] | ||||
| pub struct BackupHeader { | ||||
|     pub timestamp: i64, | ||||
|     crc16: u16, | ||||
|     pub size: usize, | ||||
| } | ||||
|  | ||||
| impl Default for BackupHeader { | ||||
|     fn default() -> Self { | ||||
|         Self { | ||||
|             timestamp: Default::default(), | ||||
|             crc16: Default::default(), | ||||
|             size: Default::default(), | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| 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_battery_monitor(&mut self) -> &mut Box<dyn BatteryInteraction + Send>; | ||||
|     fn set_charge_indicator(&mut self, charging: bool) -> Result<()>; | ||||
| @@ -225,7 +215,7 @@ impl PlantHal { | ||||
|             gpio30: peripherals.pins.gpio30, | ||||
|         }; | ||||
|  | ||||
|         let mut esp = ESP { | ||||
|         let mut esp = Esp { | ||||
|             mqtt_client: None, | ||||
|             wifi_driver, | ||||
|             boot_button, | ||||
|   | ||||
| @@ -5,7 +5,7 @@ use crate::hal::{ | ||||
| use crate::log::{log, LogMessage}; | ||||
| use crate::{ | ||||
|     config::PlantControllerConfig, | ||||
|     hal::{battery::BatteryInteraction, esp::ESP}, | ||||
|     hal::{battery::BatteryInteraction, esp::Esp}, | ||||
| }; | ||||
| use anyhow::{anyhow, bail, Ok, Result}; | ||||
| use chrono::{DateTime, Utc}; | ||||
| @@ -79,7 +79,7 @@ const FAULT_2: usize = 23; | ||||
| pub struct V3<'a> { | ||||
|     config: PlantControllerConfig, | ||||
|     battery_monitor: Box<dyn BatteryInteraction + Send>, | ||||
|     esp: ESP<'a>, | ||||
|     esp: Esp<'a>, | ||||
|     shift_register: ShiftRegister40< | ||||
|         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( | ||||
|     peripherals: FreePeripherals, | ||||
|     esp: ESP<'static>, | ||||
|     esp: Esp<'static>, | ||||
|     config: PlantControllerConfig, | ||||
|     battery_monitor: Box<dyn BatteryInteraction + 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> { | ||||
|         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 | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| use crate::config::PlantControllerConfig; | ||||
| use crate::hal::battery::BatteryInteraction; | ||||
| use crate::hal::esp::ESP; | ||||
| use crate::hal::esp::Esp; | ||||
| use crate::hal::{ | ||||
|     deep_sleep, BackupHeader, BoardInteraction, FreePeripherals, Sensor, I2C_DRIVER, PLANT_COUNT, | ||||
|     REPEAT_MOIST_MEASURE, TANK_MULTI_SAMPLE, X25, | ||||
| @@ -22,15 +22,15 @@ use esp_idf_hal::i2c::I2cDriver; | ||||
| use esp_idf_hal::pcnt::{ | ||||
|     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::calibration::{Calibration, UnCalibrated}; | ||||
| use ina219::calibration::UnCalibrated; | ||||
| use ina219::configuration::{Configuration, OperatingMode}; | ||||
| use ina219::SyncIna219; | ||||
| use measurements::{Current, Resistance, Voltage}; | ||||
| use one_wire_bus::OneWire; | ||||
| use pca9535::{GPIOBank, Pca9535Immediate, StandardExpanderInterface}; | ||||
| use std::result::Result::Ok as OkStd; | ||||
| use ina219::configuration::{Configuration, OperatingMode}; | ||||
|  | ||||
| const MS0: u8 = 1_u8; | ||||
| const MS1: u8 = 0_u8; | ||||
| @@ -47,23 +47,27 @@ pub enum Charger<'a> { | ||||
|     }, | ||||
| } | ||||
|  | ||||
| impl<'a> Charger<'a> { | ||||
|     pub(crate) fn powersave(&mut self) { | ||||
|         match self { Charger::SolarMpptV1 { mppt_ina, .. } => { | ||||
|             let _ = mppt_ina.set_configuration(Configuration { | ||||
| impl Charger<'_> { | ||||
|     pub(crate) fn power_save(&mut self) { | ||||
|         match self { | ||||
|             Charger::SolarMpptV1 { mppt_ina, .. } => { | ||||
|                 let _ = mppt_ina | ||||
|                     .set_configuration(Configuration { | ||||
|                         reset: Default::default(), | ||||
|                         bus_voltage_range: Default::default(), | ||||
|                         shunt_voltage_range: Default::default(), | ||||
|                         bus_resolution: Default::default(), | ||||
|                         shunt_resolution: Default::default(), | ||||
|                         operating_mode: OperatingMode::PowerDown, | ||||
|             }).map_err(|e| { | ||||
|                     }) | ||||
|                     .map_err(|e| { | ||||
|                         println!( | ||||
|                     "Error setting ina mppt configuration during deep sleep preparation{:?}", | ||||
|                     e | ||||
|                 ); | ||||
|                     }); | ||||
|         } } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     fn set_charge_indicator(&mut self, charging: bool) -> anyhow::Result<()> { | ||||
|         match self { | ||||
| @@ -105,7 +109,7 @@ impl<'a> Charger<'a> { | ||||
| } | ||||
|  | ||||
| pub struct V4<'a> { | ||||
|     esp: ESP<'a>, | ||||
|     esp: Esp<'a>, | ||||
|     charger: Charger<'a>, | ||||
|     battery_monitor: Box<dyn BatteryInteraction + Send>, | ||||
|     config: PlantControllerConfig, | ||||
| @@ -130,10 +134,10 @@ pub struct V4<'a> { | ||||
|  | ||||
| pub(crate) fn create_v4( | ||||
|     peripherals: FreePeripherals, | ||||
|     esp: ESP<'static>, | ||||
|     esp: Esp<'static>, | ||||
|     config: PlantControllerConfig, | ||||
|     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())?; | ||||
|     awake.set_high()?; | ||||
|  | ||||
| @@ -252,7 +256,7 @@ pub(crate) fn create_v4( | ||||
|         shunt_resolution: ina219::configuration::Resolution::Avg128, | ||||
|         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( | ||||
|         mppt_ina | ||||
|             .configuration()? | ||||
| @@ -288,7 +292,7 @@ pub(crate) fn create_v4( | ||||
| } | ||||
|  | ||||
| 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 | ||||
|     } | ||||
|  | ||||
| @@ -306,7 +310,7 @@ impl<'a> BoardInteraction<'a> for V4<'a> { | ||||
|  | ||||
|     fn deep_sleep(&mut self, duration_in_ms: u64) -> ! { | ||||
|         self.awake.set_low().unwrap(); | ||||
|         self.charger.powersave(); | ||||
|         self.charger.power_save(); | ||||
|         deep_sleep(duration_in_ms); | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -65,7 +65,7 @@ pub fn get_log() -> Vec<LogEntry> { | ||||
|         read_copy.push(copy); | ||||
|     } | ||||
|     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) { | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| use crate::{ | ||||
|     config::BoardVersion::INITIAL, | ||||
|     hal::{PlantHal, HAL, PLANT_COUNT}, | ||||
|     webserver::webserver::httpd, | ||||
|     webserver::httpd, | ||||
| }; | ||||
| use anyhow::bail; | ||||
| 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_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_VALID, vTaskDelay, | ||||
|     esp_ota_img_states_t_ESP_OTA_IMG_VALID, | ||||
| }; | ||||
| use esp_ota::{mark_app_valid, rollback_and_reboot}; | ||||
| use hal::battery::BatteryState; | ||||
| @@ -28,13 +28,12 @@ mod hal; | ||||
| mod log; | ||||
| mod plant_state; | ||||
| mod tank; | ||||
| mod webserver; | ||||
|  | ||||
| pub static BOARD_ACCESS: Lazy<Mutex<HAL>> = Lazy::new(|| PlantHal::create().unwrap()); | ||||
| pub static STAY_ALIVE: Lazy<AtomicBool> = Lazy::new(|| AtomicBool::new(false)); | ||||
|  | ||||
| mod webserver { | ||||
|     pub mod webserver; | ||||
| } | ||||
|  | ||||
|  | ||||
| #[derive(Serialize, Deserialize, Debug, PartialEq)] | ||||
| enum WaitType { | ||||
| @@ -69,7 +68,7 @@ struct LightState { | ||||
| } | ||||
|  | ||||
| #[derive(Serialize, Deserialize, Debug, PartialEq, Default)] | ||||
| ///mqtt stuct to track pump activities | ||||
| ///mqtt struct to track pump activities | ||||
| struct PumpInfo { | ||||
|     enabled: bool, | ||||
|     pump_ineffective: bool, | ||||
| @@ -175,16 +174,7 @@ fn safe_main() -> anyhow::Result<()> { | ||||
|     } | ||||
|  | ||||
|     println!("cur is {}", cur); | ||||
|     match board | ||||
|         .board_hal | ||||
|         .get_battery_monitor() | ||||
|         .average_current_milli_ampere() | ||||
|     { | ||||
|         Ok(charging) => { | ||||
|             let _ = board.board_hal.set_charge_indicator(charging > 20); | ||||
|         } | ||||
|         Err(_) => {} | ||||
|     } | ||||
|     update_charge_indicator(&mut board); | ||||
|  | ||||
|     if board.board_hal.get_esp().get_restart_to_conf() { | ||||
|         log(LogMessage::ConfigModeSoftwareOverride, 0, 0, "", ""); | ||||
| @@ -265,7 +255,7 @@ fn safe_main() -> anyhow::Result<()> { | ||||
|             address, | ||||
|             ota_state_string, | ||||
|             &mut board, | ||||
|             &ip_address, | ||||
|             ip_address, | ||||
|             timezone_time, | ||||
|         ); | ||||
|         publish_battery_state(&mut board); | ||||
| @@ -426,7 +416,7 @@ fn safe_main() -> anyhow::Result<()> { | ||||
|         .board_hal | ||||
|         .get_battery_monitor() | ||||
|         .get_battery_state() | ||||
|         .unwrap_or(hal::battery::BatteryState::Unknown); | ||||
|         .unwrap_or(BatteryState::Unknown); | ||||
|  | ||||
|     let mut light_state = LightState { | ||||
|         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); | ||||
| } | ||||
|  | ||||
| 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> { | ||||
|     //multisample should be moved to water_temperature_c | ||||
|     let mut attempt = 1; | ||||
| @@ -608,7 +618,7 @@ fn publish_plant_states( | ||||
|         .zip(&board.board_hal.get_config().plants.clone()) | ||||
|         .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) => { | ||||
|                 let plant_topic = format!("/plant{}", plant_id + 1); | ||||
|                 let _ = board | ||||
| @@ -679,7 +689,7 @@ fn try_connect_wifi_sntp_mqtt(board: &mut MutexGuard<HAL>) -> NetworkMode { | ||||
|                     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(); | ||||
|                 match board.board_hal.get_esp().mqtt(nw_config) { | ||||
|                     Ok(_) => { | ||||
| @@ -750,27 +760,10 @@ fn wait_infinity(wait_type: WaitType, reboot_now: Arc<AtomicBool>) -> ! { | ||||
|     let delay = wait_type.blink_pattern(); | ||||
|     let mut led_count = 8; | ||||
|     let mut pattern_step = 0; | ||||
|  | ||||
|     let delay_handle = Delay::new_default(); | ||||
|     loop { | ||||
|         unsafe { | ||||
|         let mut board = BOARD_ACCESS.lock().unwrap(); | ||||
|  | ||||
|             //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); | ||||
|             } | ||||
|         update_charge_indicator(&mut board); | ||||
|  | ||||
|         match wait_type { | ||||
|             WaitType::MissingConfig => { | ||||
| @@ -799,7 +792,8 @@ fn wait_infinity(wait_type: WaitType, reboot_now: Arc<AtomicBool>) -> ! { | ||||
|  | ||||
|         board.board_hal.general_fault(true); | ||||
|         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(); | ||||
|         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); | ||||
|         } | ||||
|         drop(board); | ||||
|             vTaskDelay(delay); | ||||
|         delay_handle.delay_ms(delay); | ||||
|  | ||||
|         if wait_type == WaitType::MqttConfig | ||||
|             && !STAY_ALIVE.load(std::sync::atomic::Ordering::Relaxed) | ||||
| @@ -822,12 +816,11 @@ fn wait_infinity(wait_type: WaitType, reboot_now: Arc<AtomicBool>) -> ! { | ||||
|         } | ||||
|     } | ||||
| } | ||||
| } | ||||
|  | ||||
| fn main() { | ||||
|     let result = safe_main(); | ||||
|     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 | ||||
|         Ok(_) => { | ||||
|             println!("Main app finished, restarting"); | ||||
| @@ -849,13 +842,13 @@ fn main() { | ||||
| } | ||||
|  | ||||
| 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 | ||||
|     if start < end { | ||||
|         curhour > start && curhour < end | ||||
|         current_hour > start && current_hour < end | ||||
|     } else { | ||||
|         //eg 20-05 | ||||
|         curhour > start || curhour < end | ||||
|         current_hour > start || current_hour < end | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user