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",
|
"actix-web",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"asn1",
|
"asn1",
|
||||||
|
"chrono",
|
||||||
"clap",
|
"clap",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"foreign-types-shared",
|
"foreign-types-shared",
|
||||||
|
@ -36,3 +36,4 @@ mime_guess = "2.0.5"
|
|||||||
rust-embed = "8.5.0"
|
rust-embed = "8.5.0"
|
||||||
jsonwebtoken = { version = "9.3.0", features = ["use_pem"] }
|
jsonwebtoken = { version = "9.3.0", features = ["use_pem"] }
|
||||||
prettytable-rs = "0.10.0"
|
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
|
/// The seconds in the days (from 00:00) where the counter is reset
|
||||||
pub reset_time: usize,
|
pub reset_time: usize,
|
||||||
/// The hours during which the relay should be turned on to reach expected runtime
|
/// 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)]
|
#[derive(Clone, Copy, Debug, serde::Serialize, serde::Deserialize, Eq, PartialEq, Hash)]
|
||||||
|
@ -40,7 +40,7 @@ impl EnergyActor {
|
|||||||
|
|
||||||
let devices_list = self.devices.full_list();
|
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)?;
|
self.engine.persist_relays_state(&devices_list)?;
|
||||||
|
|
||||||
|
@ -6,8 +6,9 @@ use prettytable::{row, Table};
|
|||||||
use crate::constants;
|
use crate::constants;
|
||||||
use crate::devices::device::{Device, DeviceId, DeviceRelay, DeviceRelayID};
|
use crate::devices::device::{Device, DeviceId, DeviceRelay, DeviceRelayID};
|
||||||
use crate::energy::consumption::EnergyConsumption;
|
use crate::energy::consumption::EnergyConsumption;
|
||||||
|
use crate::energy::relay_state_history;
|
||||||
use crate::energy::relay_state_history::RelayStateHistory;
|
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)]
|
#[derive(Default)]
|
||||||
pub struct DeviceState {
|
pub struct DeviceState {
|
||||||
@ -168,7 +169,11 @@ impl EnergyEngine {
|
|||||||
curr_consumption - sum_relays_consumption(&self.relays_state, devices) as i32
|
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);
|
let base_production = self.estimated_consumption_without_relays(curr_consumption, devices);
|
||||||
log::info!("Estimated base production: {base_production}");
|
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
|
// Order relays
|
||||||
let mut ordered_relays = devices
|
let mut ordered_relays = devices
|
||||||
@ -320,6 +357,8 @@ impl EnergyEngine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.print_summary(curr_consumption, devices);
|
self.print_summary(curr_consumption, devices);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Save relays state to disk
|
/// Save relays state to disk
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use chrono::prelude::*;
|
||||||
use std::time::{SystemTime, UNIX_EPOCH};
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
|
|
||||||
/// Get the current time since epoch
|
/// Get the current time since epoch
|
||||||
@ -16,11 +17,25 @@ pub fn time_millis() -> u128 {
|
|||||||
.as_millis()
|
.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 {
|
pub fn day_number(time: u64) -> u64 {
|
||||||
time / (3600 * 24)
|
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)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use crate::utils::time_utils::day_number;
|
use crate::utils::time_utils::day_number;
|
||||||
|
Loading…
Reference in New Issue
Block a user