Refactor energy management
This commit is contained in:
parent
36ba4efd9f
commit
c74ed0cfbb
148
central_backend/Cargo.lock
generated
148
central_backend/Cargo.lock
generated
@ -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"
|
||||
|
@ -35,3 +35,4 @@ tokio_schedule = "0.3.2"
|
||||
mime_guess = "2.0.5"
|
||||
rust-embed = "8.5.0"
|
||||
jsonwebtoken = { version = "9.3.0", features = ["use_pem"] }
|
||||
prettytable-rs = "0.10.0"
|
@ -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,
|
||||
|
83
central_backend/src/energy/engine.rs
Normal file
83
central_backend/src/energy/engine.rs
Normal 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
|
||||
}
|
||||
}
|
@ -1,2 +1,3 @@
|
||||
pub mod consumption;
|
||||
pub mod energy_actor;
|
||||
pub mod engine;
|
||||
|
Loading…
Reference in New Issue
Block a user