Refactor energy management

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

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;