Refactor energy management

This commit is contained in:
Pierre HUBERT 2024-09-10 19:40:06 +02:00
parent 36ba4efd9f
commit c74ed0cfbb
5 changed files with 241 additions and 36 deletions

View File

@ -626,6 +626,7 @@ dependencies = [
"mime_guess",
"openssl",
"openssl-sys",
"prettytable-rs",
"rand",
"reqwest",
"rust-embed",
@ -798,6 +799,27 @@ dependencies = [
"typenum",
]
[[package]]
name = "csv"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac574ff4d437a7b5ad237ef331c17ccca63c46479e5b5453eb8e10bb99a759fe"
dependencies = [
"csv-core",
"itoa",
"ryu",
"serde",
]
[[package]]
name = "csv-core"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5efa2b3d7902f4b634a20cae3c9c4e6209dc4779feb6863329607560143efa70"
dependencies = [
"memchr",
]
[[package]]
name = "ctr"
version = "0.9.2"
@ -840,6 +862,33 @@ dependencies = [
"subtle",
]
[[package]]
name = "dirs-next"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1"
dependencies = [
"cfg-if",
"dirs-sys-next",
]
[[package]]
name = "dirs-sys-next"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d"
dependencies = [
"libc",
"redox_users",
"winapi",
]
[[package]]
name = "encode_unicode"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0"
[[package]]
name = "encoding_rs"
version = "0.8.34"
@ -1118,6 +1167,12 @@ version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
[[package]]
name = "hermit-abi"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc"
[[package]]
name = "hkdf"
version = "0.12.4"
@ -1336,6 +1391,17 @@ version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3"
[[package]]
name = "is-terminal"
version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b"
dependencies = [
"hermit-abi 0.4.0",
"libc",
"windows-sys 0.52.0",
]
[[package]]
name = "is_terminal_polyfill"
version = "1.70.1"
@ -1422,6 +1488,16 @@ version = "0.2.155"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
[[package]]
name = "libredox"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
dependencies = [
"bitflags 2.6.0",
"libc",
]
[[package]]
name = "linux-raw-sys"
version = "0.4.14"
@ -1498,7 +1574,7 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4569e456d394deccd22ce1c1913e6ea0e54519f577285001215d33557431afe4"
dependencies = [
"hermit-abi",
"hermit-abi 0.3.9",
"libc",
"log",
"wasi",
@ -1731,6 +1807,20 @@ dependencies = [
"zerocopy",
]
[[package]]
name = "prettytable-rs"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eea25e07510aa6ab6547308ebe3c036016d162b8da920dbb079e3ba8acf3d95a"
dependencies = [
"csv",
"encode_unicode",
"is-terminal",
"lazy_static",
"term",
"unicode-width",
]
[[package]]
name = "proc-macro2"
version = "1.0.86"
@ -1788,6 +1878,17 @@ dependencies = [
"bitflags 2.6.0",
]
[[package]]
name = "redox_users"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43"
dependencies = [
"getrandom",
"libredox",
"thiserror",
]
[[package]]
name = "regex"
version = "1.10.6"
@ -1983,6 +2084,12 @@ dependencies = [
"untrusted",
]
[[package]]
name = "rustversion"
version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6"
[[package]]
name = "ryu"
version = "1.0.18"
@ -2226,6 +2333,17 @@ dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "term"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f"
dependencies = [
"dirs-next",
"rustversion",
"winapi",
]
[[package]]
name = "thiserror"
version = "1.0.63"
@ -2466,6 +2584,12 @@ dependencies = [
"tinyvec",
]
[[package]]
name = "unicode-width"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d"
[[package]]
name = "universal-hash"
version = "0.5.1"
@ -2622,6 +2746,22 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
version = "0.1.9"
@ -2631,6 +2771,12 @@ dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-core"
version = "0.52.0"

View File

@ -34,4 +34,5 @@ tokio = { version = "1.39.2", features = ["full"] }
tokio_schedule = "0.3.2"
mime_guess = "2.0.5"
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"

View File

@ -5,33 +5,15 @@ use crate::devices::device::{
use crate::devices::devices_list::DevicesList;
use crate::energy::consumption;
use crate::energy::consumption::EnergyConsumption;
use crate::energy::engine::EnergyEngine;
use crate::utils::time_utils::time_secs;
use actix::prelude::*;
use openssl::x509::X509Req;
use std::collections::HashMap;
#[derive(Default)]
struct DeviceState {
last_ping: u64,
}
impl DeviceState {
fn is_online(&self) -> bool {
(time_secs() - self.last_ping) < constants::DEVICE_MAX_PING_TIME
}
}
#[derive(Default)]
struct RelayState {
enabled: bool,
since: usize,
}
pub struct EnergyActor {
curr_consumption: EnergyConsumption,
devices: DevicesList,
devices_state: HashMap<DeviceId, DeviceState>,
relays_state: HashMap<DeviceRelayID, RelayState>,
engine: EnergyEngine,
}
impl EnergyActor {
@ -39,20 +21,10 @@ impl EnergyActor {
Ok(Self {
curr_consumption: consumption::get_curr_consumption().await?,
devices: DevicesList::load()?,
devices_state: Default::default(),
relays_state: Default::default(),
engine: EnergyEngine::default(),
})
}
fn device_state(&mut self, dev_id: &DeviceId) -> &mut DeviceState {
if !self.devices_state.contains_key(dev_id) {
self.devices_state
.insert(dev_id.clone(), Default::default());
}
self.devices_state.get_mut(dev_id).unwrap()
}
async fn refresh(&mut self) -> anyhow::Result<()> {
// Refresh energy
self.curr_consumption = consumption::get_curr_consumption()
@ -64,6 +36,9 @@ impl EnergyActor {
constants::FALLBACK_PRODUCTION_VALUE
});
self.engine
.refresh(self.curr_consumption, &self.devices.full_list());
Ok(())
}
}
@ -285,8 +260,7 @@ impl Handler<SynchronizeDevice> for EnergyActor {
type Result = anyhow::Result<Vec<RelaySyncStatus>>;
fn handle(&mut self, msg: SynchronizeDevice, _ctx: &mut Context<Self>) -> Self::Result {
let s = self.device_state(&msg.0);
s.last_ping = time_secs();
self.engine.device_state(&msg.0).record_ping();
// TODO : implement real code
let mut v = vec![];
@ -319,7 +293,7 @@ impl Handler<GetDevicesState> for EnergyActor {
.full_list()
.into_iter()
.map(|d| {
let s = self.device_state(&d.id);
let s = self.engine.device_state(&d.id);
ResDevState {
id: d.id,
last_ping: time_secs() - s.last_ping,

View File

@ -0,0 +1,83 @@
use crate::constants;
use crate::devices::device::{Device, DeviceId, DeviceRelayID};
use crate::energy::consumption::EnergyConsumption;
use crate::utils::time_utils::time_secs;
use prettytable::{row, Table};
use std::collections::HashMap;
#[derive(Default)]
pub struct DeviceState {
pub last_ping: u64,
}
impl DeviceState {
pub fn record_ping(&mut self) {
self.last_ping = time_secs();
}
pub fn is_online(&self) -> bool {
(time_secs() - self.last_ping) < constants::DEVICE_MAX_PING_TIME
}
}
#[derive(Default, Clone)]
struct RelayState {
on: bool,
since: usize,
}
#[derive(Default)]
pub struct EnergyEngine {
devices_state: HashMap<DeviceId, DeviceState>,
relays_state: HashMap<DeviceRelayID, RelayState>,
}
impl EnergyEngine {
pub fn device_state(&mut self, dev_id: &DeviceId) -> &mut DeviceState {
if !self.devices_state.contains_key(dev_id) {
self.devices_state
.insert(dev_id.clone(), Default::default());
}
self.devices_state.get_mut(dev_id).unwrap()
}
pub fn relay_state(&mut self, relay_id: DeviceRelayID) -> &mut RelayState {
if !self.relays_state.contains_key(&relay_id) {
self.relays_state.insert(relay_id, Default::default());
}
self.relays_state.get_mut(&relay_id).unwrap()
}
fn print_summary(&mut self, curr_consumption: EnergyConsumption, devices: &[Device]) {
log::info!("Current consumption: {curr_consumption}");
let mut table = Table::new();
table.add_row(row!["Device", "Relay", "On", "Since"]);
for d in devices {
for r in &d.relays {
let status = self.relay_state(r.id);
table.add_row(row![d.name, r.name, status.on.to_string(), status.since]);
}
}
table.printstd();
}
pub fn refresh(&mut self, curr_consumption: EnergyConsumption, devices: &[Device]) {
let new_relays_state = self.relays_state.clone();
// Forcefully turn off relays that belongs to offline devices
// Forcefully turn off relays with dependency conflicts
// Virtually turn off all relays that can be stopped
// Turn on relays based on priority / dependencies
// Turn on relays with running constraints
// Commit changes
self.print_summary(curr_consumption, devices); // TODO :replace
}
}

View File

@ -1,2 +1,3 @@
pub mod consumption;
pub mod energy_actor;
pub mod engine;