Implement catchup hours logic
This commit is contained in:
parent
09c25a67c5
commit
fe0bc03c03
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;
|
||||
|
Loading…
Reference in New Issue
Block a user