Refactor energy management
This commit is contained in:
		
							
								
								
									
										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"
 | 
			
		||||
 
 | 
			
		||||
@@ -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"
 | 
			
		||||
@@ -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;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user