Store relay consumption values
This commit is contained in:
		@@ -2,6 +2,12 @@ use crate::devices::device::{DeviceId, DeviceRelayID};
 | 
			
		||||
use clap::{Parser, Subcommand};
 | 
			
		||||
use std::path::{Path, PathBuf};
 | 
			
		||||
 | 
			
		||||
#[derive(Copy, Clone, Debug)]
 | 
			
		||||
pub enum ConsumptionHistoryType {
 | 
			
		||||
    GridConsumption,
 | 
			
		||||
    RelayConsumption,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Electrical consumption fetcher backend
 | 
			
		||||
#[derive(Subcommand, Debug, Clone)]
 | 
			
		||||
pub enum ConsumptionBackend {
 | 
			
		||||
@@ -262,10 +268,20 @@ impl AppConfig {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Get energy consumption history file path for a given day
 | 
			
		||||
    pub fn energy_consumption_history_day(&self, number: u64) -> PathBuf {
 | 
			
		||||
    pub fn energy_consumption_history_day(
 | 
			
		||||
        &self,
 | 
			
		||||
        number: u64,
 | 
			
		||||
        r#type: ConsumptionHistoryType,
 | 
			
		||||
    ) -> PathBuf {
 | 
			
		||||
        self.storage_path()
 | 
			
		||||
            .join("consumption_history")
 | 
			
		||||
            .join(number.to_string())
 | 
			
		||||
            .join(format!(
 | 
			
		||||
                "{number}-{}",
 | 
			
		||||
                match r#type {
 | 
			
		||||
                    ConsumptionHistoryType::GridConsumption => "grid",
 | 
			
		||||
                    ConsumptionHistoryType::RelayConsumption => "relay-consumption",
 | 
			
		||||
                }
 | 
			
		||||
            ))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
use crate::app_config::AppConfig;
 | 
			
		||||
use crate::app_config::{AppConfig, ConsumptionHistoryType};
 | 
			
		||||
use crate::energy::consumption::EnergyConsumption;
 | 
			
		||||
use crate::utils::time_utils::day_number;
 | 
			
		||||
 | 
			
		||||
@@ -16,13 +16,14 @@ pub enum ConsumptionHistoryError {
 | 
			
		||||
pub struct ConsumptionHistoryFile {
 | 
			
		||||
    day: u64,
 | 
			
		||||
    buff: Vec<EnergyConsumption>,
 | 
			
		||||
    r#type: ConsumptionHistoryType,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl ConsumptionHistoryFile {
 | 
			
		||||
    /// Open consumption history file, if it exists, or create an empty one
 | 
			
		||||
    pub fn open(time: u64) -> anyhow::Result<Self> {
 | 
			
		||||
    pub fn open(time: u64, r#type: ConsumptionHistoryType) -> anyhow::Result<Self> {
 | 
			
		||||
        let day = day_number(time);
 | 
			
		||||
        let path = AppConfig::get().energy_consumption_history_day(day);
 | 
			
		||||
        let path = AppConfig::get().energy_consumption_history_day(day, r#type);
 | 
			
		||||
 | 
			
		||||
        if path.exists() {
 | 
			
		||||
            Ok(Self {
 | 
			
		||||
@@ -32,20 +33,22 @@ impl ConsumptionHistoryFile {
 | 
			
		||||
                    bincode::config::standard(),
 | 
			
		||||
                )?
 | 
			
		||||
                .0,
 | 
			
		||||
                r#type,
 | 
			
		||||
            })
 | 
			
		||||
        } else {
 | 
			
		||||
            log::debug!(
 | 
			
		||||
                "Energy consumption stats for day {day} does not exists yet, creating memory buffer"
 | 
			
		||||
            );
 | 
			
		||||
            Ok(Self::new_memory(day))
 | 
			
		||||
            Ok(Self::new_memory(day, r#type))
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Create a new in memory consumption history
 | 
			
		||||
    fn new_memory(day: u64) -> Self {
 | 
			
		||||
    fn new_memory(day: u64, r#type: ConsumptionHistoryType) -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            day,
 | 
			
		||||
            buff: vec![0; (3600 * 24 / TIME_INTERVAL) + 1],
 | 
			
		||||
            r#type,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -87,7 +90,7 @@ impl ConsumptionHistoryFile {
 | 
			
		||||
 | 
			
		||||
    /// Persist device relay state history
 | 
			
		||||
    pub fn save(&self) -> anyhow::Result<()> {
 | 
			
		||||
        let path = AppConfig::get().energy_consumption_history_day(self.day);
 | 
			
		||||
        let path = AppConfig::get().energy_consumption_history_day(self.day, self.r#type);
 | 
			
		||||
        std::fs::write(
 | 
			
		||||
            path,
 | 
			
		||||
            bincode::encode_to_vec(&self.buff, bincode::config::standard())?,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
use crate::app_config::AppConfig;
 | 
			
		||||
use crate::app_config::{AppConfig, ConsumptionHistoryType};
 | 
			
		||||
use crate::constants;
 | 
			
		||||
use crate::devices::device::{
 | 
			
		||||
    Device, DeviceGeneralInfo, DeviceId, DeviceInfo, DeviceRelay, DeviceRelayID,
 | 
			
		||||
@@ -53,17 +53,26 @@ impl EnergyActor {
 | 
			
		||||
            });
 | 
			
		||||
        self.consumption_cache.add_value(latest_consumption);
 | 
			
		||||
 | 
			
		||||
        let mut history = ConsumptionHistoryFile::open(time_secs())?;
 | 
			
		||||
        let devices_list = self.devices.full_list();
 | 
			
		||||
 | 
			
		||||
        let mut history =
 | 
			
		||||
            ConsumptionHistoryFile::open(time_secs(), ConsumptionHistoryType::GridConsumption)?;
 | 
			
		||||
        history.set_consumption(time_secs(), latest_consumption)?;
 | 
			
		||||
        history.save()?;
 | 
			
		||||
 | 
			
		||||
        let mut relays_consumption =
 | 
			
		||||
            ConsumptionHistoryFile::open(time_secs(), ConsumptionHistoryType::RelayConsumption)?;
 | 
			
		||||
        relays_consumption.set_consumption(
 | 
			
		||||
            time_secs(),
 | 
			
		||||
            self.engine.sum_relays_consumption(&devices_list) as EnergyConsumption,
 | 
			
		||||
        )?;
 | 
			
		||||
        relays_consumption.save()?;
 | 
			
		||||
 | 
			
		||||
        if self.last_engine_refresh + AppConfig::get().refresh_interval > time_secs() {
 | 
			
		||||
            return Ok(());
 | 
			
		||||
        }
 | 
			
		||||
        self.last_engine_refresh = time_secs();
 | 
			
		||||
 | 
			
		||||
        let devices_list = self.devices.full_list();
 | 
			
		||||
 | 
			
		||||
        self.engine
 | 
			
		||||
            .refresh(self.consumption_cache.median_value(), &devices_list);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -115,6 +115,10 @@ impl EnergyEngine {
 | 
			
		||||
        self.relays_state.get_mut(&relay_id).unwrap()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn sum_relays_consumption(&self, devices: &[Device]) -> usize {
 | 
			
		||||
        sum_relays_consumption(&self.relays_state, devices)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn print_summary(&mut self, curr_consumption: EnergyConsumption, devices: &[Device]) {
 | 
			
		||||
        log::info!("Current consumption: {curr_consumption}");
 | 
			
		||||
 | 
			
		||||
@@ -166,7 +170,7 @@ impl EnergyEngine {
 | 
			
		||||
        curr_consumption: EnergyConsumption,
 | 
			
		||||
        devices: &[Device],
 | 
			
		||||
    ) -> EnergyConsumption {
 | 
			
		||||
        curr_consumption - sum_relays_consumption(&self.relays_state, devices) as i32
 | 
			
		||||
        curr_consumption - self.sum_relays_consumption(devices) as i32
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Refresh energy engine; this method shall never fail !
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user