Take relays consumption in account
This commit is contained in:
parent
79b2ad12d8
commit
20bc71851d
@ -76,6 +76,14 @@ pub struct AppConfig {
|
|||||||
#[arg(short, long, env, default_value = "storage")]
|
#[arg(short, long, env, default_value = "storage")]
|
||||||
storage: String,
|
storage: String,
|
||||||
|
|
||||||
|
/// The minimal production that must be excluded when selecting relays to turn on
|
||||||
|
#[arg(short('m'), long, env, default_value_t = -500)]
|
||||||
|
pub production_margin: i32,
|
||||||
|
|
||||||
|
/// Energy refresh operations interval, in seconds
|
||||||
|
#[arg(short('i'), long, env, default_value_t = 30)]
|
||||||
|
pub refresh_interval: u64,
|
||||||
|
|
||||||
/// Consumption backend provider
|
/// Consumption backend provider
|
||||||
#[clap(subcommand)]
|
#[clap(subcommand)]
|
||||||
pub consumption_backend: Option<ConsumptionBackend>,
|
pub consumption_backend: Option<ConsumptionBackend>,
|
||||||
|
@ -1,11 +1,6 @@
|
|||||||
use std::time::Duration;
|
|
||||||
|
|
||||||
/// Name of the cookie that contains session information
|
/// Name of the cookie that contains session information
|
||||||
pub const SESSION_COOKIE_NAME: &str = "X-session-cookie";
|
pub const SESSION_COOKIE_NAME: &str = "X-session-cookie";
|
||||||
|
|
||||||
/// Energy refresh operations interval
|
|
||||||
pub const ENERGY_REFRESH_INTERVAL: Duration = Duration::from_secs(30);
|
|
||||||
|
|
||||||
/// Maximum time after a ping during which a device is considered "up"
|
/// Maximum time after a ping during which a device is considered "up"
|
||||||
pub const DEVICE_MAX_PING_TIME: u64 = 30;
|
pub const DEVICE_MAX_PING_TIME: u64 = 30;
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use crate::app_config::AppConfig;
|
||||||
use crate::constants;
|
use crate::constants;
|
||||||
use crate::devices::device::{
|
use crate::devices::device::{
|
||||||
Device, DeviceGeneralInfo, DeviceId, DeviceInfo, DeviceRelay, DeviceRelayID,
|
Device, DeviceGeneralInfo, DeviceId, DeviceInfo, DeviceRelay, DeviceRelayID,
|
||||||
@ -9,6 +10,7 @@ use crate::energy::engine::EnergyEngine;
|
|||||||
use crate::utils::time_utils::time_secs;
|
use crate::utils::time_utils::time_secs;
|
||||||
use actix::prelude::*;
|
use actix::prelude::*;
|
||||||
use openssl::x509::X509Req;
|
use openssl::x509::X509Req;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
pub struct EnergyActor {
|
pub struct EnergyActor {
|
||||||
curr_consumption: EnergyConsumption,
|
curr_consumption: EnergyConsumption,
|
||||||
@ -49,12 +51,15 @@ impl Actor for EnergyActor {
|
|||||||
fn started(&mut self, ctx: &mut Self::Context) {
|
fn started(&mut self, ctx: &mut Self::Context) {
|
||||||
log::info!("Energy actor successfully started!");
|
log::info!("Energy actor successfully started!");
|
||||||
|
|
||||||
ctx.run_interval(constants::ENERGY_REFRESH_INTERVAL, |act, _ctx| {
|
ctx.run_interval(
|
||||||
|
Duration::from_secs(AppConfig::get().refresh_interval),
|
||||||
|
|act, _ctx| {
|
||||||
log::info!("Performing energy refresh operation");
|
log::info!("Performing energy refresh operation");
|
||||||
if let Err(e) = futures::executor::block_on(act.refresh()) {
|
if let Err(e) = futures::executor::block_on(act.refresh()) {
|
||||||
log::error!("Energy refresh failed! {e}")
|
log::error!("Energy refresh failed! {e}")
|
||||||
}
|
}
|
||||||
});
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stopped(&mut self, _ctx: &mut Self::Context) {
|
fn stopped(&mut self, _ctx: &mut Self::Context) {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use crate::app_config::AppConfig;
|
||||||
use prettytable::{row, Table};
|
use prettytable::{row, Table};
|
||||||
|
|
||||||
use crate::constants;
|
use crate::constants;
|
||||||
@ -87,6 +88,20 @@ impl DeviceRelay {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn sum_relays_consumption(state: &RelaysState, devices: &[Device]) -> usize {
|
||||||
|
let mut consumption = 0;
|
||||||
|
|
||||||
|
for d in devices {
|
||||||
|
for r in &d.relays {
|
||||||
|
if matches!(state.get(&r.id).map(|r| r.on), Some(true)) {
|
||||||
|
consumption += r.consumption;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
consumption
|
||||||
|
}
|
||||||
|
|
||||||
impl EnergyEngine {
|
impl EnergyEngine {
|
||||||
pub fn device_state(&mut self, dev_id: &DeviceId) -> &mut DeviceState {
|
pub fn device_state(&mut self, dev_id: &DeviceId) -> &mut DeviceState {
|
||||||
self.devices_state.entry(dev_id.clone()).or_default();
|
self.devices_state.entry(dev_id.clone()).or_default();
|
||||||
@ -102,22 +117,60 @@ impl EnergyEngine {
|
|||||||
log::info!("Current consumption: {curr_consumption}");
|
log::info!("Current consumption: {curr_consumption}");
|
||||||
|
|
||||||
let mut table = Table::new();
|
let mut table = Table::new();
|
||||||
table.add_row(row!["Device", "Relay", "On", "Since"]);
|
table.add_row(row![
|
||||||
|
"Device",
|
||||||
|
"Relay",
|
||||||
|
"Consumption",
|
||||||
|
"Min downtime / uptime",
|
||||||
|
"On",
|
||||||
|
"Since",
|
||||||
|
"Online",
|
||||||
|
"Enabled device / relay"
|
||||||
|
]);
|
||||||
for d in devices {
|
for d in devices {
|
||||||
|
let dev_online = self.device_state(&d.id).is_online();
|
||||||
for r in &d.relays {
|
for r in &d.relays {
|
||||||
let status = self.relay_state(r.id);
|
let status = self.relay_state(r.id);
|
||||||
table.add_row(row![
|
table.add_row(row![
|
||||||
d.name,
|
d.name,
|
||||||
r.name,
|
r.name,
|
||||||
|
r.consumption,
|
||||||
|
format!("{} / {}", r.minimal_downtime, r.minimal_uptime),
|
||||||
status.is_on().to_string(),
|
status.is_on().to_string(),
|
||||||
status.since
|
status.since,
|
||||||
|
match dev_online {
|
||||||
|
true => "Online",
|
||||||
|
false => "Offline",
|
||||||
|
},
|
||||||
|
format!(
|
||||||
|
"{} / {}",
|
||||||
|
match d.enabled {
|
||||||
|
true => "Enabled",
|
||||||
|
false => "Disabled",
|
||||||
|
},
|
||||||
|
match r.enabled {
|
||||||
|
true => "Enabled",
|
||||||
|
false => "Disabled",
|
||||||
|
}
|
||||||
|
)
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
table.printstd();
|
table.printstd();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn estimated_consumption_without_relays(
|
||||||
|
&self,
|
||||||
|
curr_consumption: EnergyConsumption,
|
||||||
|
devices: &[Device],
|
||||||
|
) -> EnergyConsumption {
|
||||||
|
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]) {
|
||||||
|
let base_production = self.estimated_consumption_without_relays(curr_consumption, devices);
|
||||||
|
log::info!("Estimated base production: {base_production}");
|
||||||
|
|
||||||
// Force creation of missing relays state
|
// Force creation of missing relays state
|
||||||
for d in devices {
|
for d in devices {
|
||||||
for r in &d.relays {
|
for r in &d.relays {
|
||||||
@ -238,7 +291,13 @@ impl EnergyEngine {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO : check consumption
|
let new_consumption = base_production
|
||||||
|
+ sum_relays_consumption(&new_relays_state, devices) as EnergyConsumption;
|
||||||
|
|
||||||
|
if new_consumption + relay.consumption as i32 > AppConfig::get().production_margin {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
log::info!("Turn on relay {}", relay.name);
|
log::info!("Turn on relay {}", relay.name);
|
||||||
new_relays_state.get_mut(&relay.id).unwrap().on = true;
|
new_relays_state.get_mut(&relay.id).unwrap().on = true;
|
||||||
changed = true;
|
changed = true;
|
||||||
|
Loading…
Reference in New Issue
Block a user