Implement catchup hours logic
This commit is contained in:
		
							
								
								
									
										1
									
								
								central_backend/Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1
									
								
								central_backend/Cargo.lock
									
									
									
										generated
									
									
									
								
							| @@ -613,6 +613,7 @@ dependencies = [ | ||||
|  "actix-web", | ||||
|  "anyhow", | ||||
|  "asn1", | ||||
|  "chrono", | ||||
|  "clap", | ||||
|  "env_logger", | ||||
|  "foreign-types-shared", | ||||
|   | ||||
| @@ -36,3 +36,4 @@ mime_guess = "2.0.5" | ||||
| rust-embed = "8.5.0" | ||||
| jsonwebtoken = { version = "9.3.0", features = ["use_pem"] } | ||||
| prettytable-rs = "0.10.0" | ||||
| chrono = "0.4.38" | ||||
| @@ -73,7 +73,7 @@ pub struct DailyMinRuntime { | ||||
|     /// The seconds in the days (from 00:00) where the counter is reset | ||||
|     pub reset_time: usize, | ||||
|     /// The hours during which the relay should be turned on to reach expected runtime | ||||
|     pub catch_up_hours: Vec<usize>, | ||||
|     pub catch_up_hours: Vec<u32>, | ||||
| } | ||||
|  | ||||
| #[derive(Clone, Copy, Debug, serde::Serialize, serde::Deserialize, Eq, PartialEq, Hash)] | ||||
|   | ||||
| @@ -40,7 +40,7 @@ impl EnergyActor { | ||||
|  | ||||
|         let devices_list = self.devices.full_list(); | ||||
|  | ||||
|         self.engine.refresh(self.curr_consumption, &devices_list); | ||||
|         self.engine.refresh(self.curr_consumption, &devices_list)?; | ||||
|  | ||||
|         self.engine.persist_relays_state(&devices_list)?; | ||||
|  | ||||
|   | ||||
| @@ -6,8 +6,9 @@ use prettytable::{row, Table}; | ||||
| use crate::constants; | ||||
| use crate::devices::device::{Device, DeviceId, DeviceRelay, DeviceRelayID}; | ||||
| use crate::energy::consumption::EnergyConsumption; | ||||
| use crate::energy::relay_state_history; | ||||
| use crate::energy::relay_state_history::RelayStateHistory; | ||||
| use crate::utils::time_utils::time_secs; | ||||
| use crate::utils::time_utils::{curr_hour, time_secs, time_start_of_day}; | ||||
|  | ||||
| #[derive(Default)] | ||||
| pub struct DeviceState { | ||||
| @@ -168,7 +169,11 @@ impl EnergyEngine { | ||||
|         curr_consumption - sum_relays_consumption(&self.relays_state, devices) as i32 | ||||
|     } | ||||
|  | ||||
|     pub fn refresh(&mut self, curr_consumption: EnergyConsumption, devices: &[Device]) { | ||||
|     pub fn refresh( | ||||
|         &mut self, | ||||
|         curr_consumption: EnergyConsumption, | ||||
|         devices: &[Device], | ||||
|     ) -> anyhow::Result<()> { | ||||
|         let base_production = self.estimated_consumption_without_relays(curr_consumption, devices); | ||||
|         log::info!("Estimated base production: {base_production}"); | ||||
|  | ||||
| @@ -254,7 +259,39 @@ impl EnergyEngine { | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // TODO Turn on relays with running constraints (only ENABLED) | ||||
|         // Turn on relays with running constraints (only ENABLED) | ||||
|         for d in devices { | ||||
|             for r in &d.relays { | ||||
|                 if !r.enabled || !d.enabled || !self.device_state(&d.id).is_online() { | ||||
|                     continue; | ||||
|                 } | ||||
|  | ||||
|                 if new_relays_state.get(&r.id).unwrap().is_on() { | ||||
|                     continue; | ||||
|                 } | ||||
|  | ||||
|                 let Some(constraints) = &r.daily_runtime else { | ||||
|                     continue; | ||||
|                 }; | ||||
|  | ||||
|                 if !constraints.catch_up_hours.contains(&curr_hour()) { | ||||
|                     continue; | ||||
|                 } | ||||
|  | ||||
|                 let time_start_day = time_start_of_day()?; | ||||
|                 let start_time = time_start_day + constraints.reset_time as u64; | ||||
|                 let end_time = time_start_day + 3600 * 24 + constraints.reset_time as u64; | ||||
|                 let total_runtime = | ||||
|                     relay_state_history::relay_total_runtime(r.id, start_time, end_time)?; | ||||
|  | ||||
|                 if total_runtime > constraints.min_runtime { | ||||
|                     continue; | ||||
|                 } | ||||
|  | ||||
|                 log::info!("Forcefully turn on relay {} to catch up running constraints (only {}s this day)", r.name, total_runtime); | ||||
|                 new_relays_state.get_mut(&r.id).unwrap().on = true; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Order relays | ||||
|         let mut ordered_relays = devices | ||||
| @@ -320,6 +357,8 @@ impl EnergyEngine { | ||||
|         } | ||||
|  | ||||
|         self.print_summary(curr_consumption, devices); | ||||
|  | ||||
|         Ok(()) | ||||
|     } | ||||
|  | ||||
|     /// Save relays state to disk | ||||
|   | ||||
| @@ -1,3 +1,4 @@ | ||||
| use chrono::prelude::*; | ||||
| use std::time::{SystemTime, UNIX_EPOCH}; | ||||
|  | ||||
| /// Get the current time since epoch | ||||
| @@ -16,11 +17,25 @@ pub fn time_millis() -> u128 { | ||||
|         .as_millis() | ||||
| } | ||||
|  | ||||
| /// Get the number of the day since 01-01-1970 of a given UNIX timestamp | ||||
| /// Get the number of the day since 01-01-1970 of a given UNIX timestamp (UTC) | ||||
| pub fn day_number(time: u64) -> u64 { | ||||
|     time / (3600 * 24) | ||||
| } | ||||
|  | ||||
| /// Get current hour, 00 => 23 (local time) | ||||
| pub fn curr_hour() -> u32 { | ||||
|     let local: DateTime<Local> = Local::now(); | ||||
|     local.hour() | ||||
| } | ||||
|  | ||||
| /// Get the first second of the day (local time) | ||||
| pub fn time_start_of_day() -> anyhow::Result<u64> { | ||||
|     let local: DateTime<Local> = Local::now() | ||||
|         .with_time(NaiveTime::from_hms_opt(0, 0, 0).unwrap()) | ||||
|         .unwrap(); | ||||
|     Ok(local.timestamp() as u64) | ||||
| } | ||||
|  | ||||
| #[cfg(test)] | ||||
| mod test { | ||||
|     use crate::utils::time_utils::day_number; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user