2024-06-29 09:45:39 +00:00
|
|
|
use crate::constants;
|
2024-07-22 20:19:48 +00:00
|
|
|
use crate::devices::device::{Device, DeviceGeneralInfo, DeviceId, DeviceInfo};
|
2024-07-01 19:10:45 +00:00
|
|
|
use crate::devices::devices_list::DevicesList;
|
2024-06-29 09:45:39 +00:00
|
|
|
use crate::energy::consumption;
|
|
|
|
use crate::energy::consumption::EnergyConsumption;
|
|
|
|
use actix::prelude::*;
|
2024-07-02 20:55:51 +00:00
|
|
|
use openssl::x509::X509Req;
|
2024-06-29 09:45:39 +00:00
|
|
|
|
|
|
|
pub struct EnergyActor {
|
|
|
|
curr_consumption: EnergyConsumption,
|
2024-07-01 19:10:45 +00:00
|
|
|
devices: DevicesList,
|
2024-06-29 09:45:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl EnergyActor {
|
|
|
|
pub async fn new() -> anyhow::Result<Self> {
|
|
|
|
Ok(Self {
|
|
|
|
curr_consumption: consumption::get_curr_consumption().await?,
|
2024-07-01 19:10:45 +00:00
|
|
|
devices: DevicesList::load()?,
|
2024-06-29 09:45:39 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn refresh(&mut self) -> anyhow::Result<()> {
|
|
|
|
// Refresh energy
|
|
|
|
self.curr_consumption = consumption::get_curr_consumption()
|
|
|
|
.await
|
|
|
|
.unwrap_or_else(|e| {
|
|
|
|
log::error!(
|
|
|
|
"Failed to fetch latest consumption value, will use fallback value! {e}"
|
|
|
|
);
|
|
|
|
constants::FALLBACK_PRODUCTION_VALUE
|
|
|
|
});
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Actor for EnergyActor {
|
|
|
|
type Context = Context<Self>;
|
|
|
|
|
|
|
|
fn started(&mut self, ctx: &mut Self::Context) {
|
|
|
|
log::info!("Energy actor successfully started!");
|
|
|
|
|
|
|
|
ctx.run_interval(constants::ENERGY_REFRESH_INTERVAL, |act, _ctx| {
|
|
|
|
log::info!("Performing energy refresh operation");
|
|
|
|
if let Err(e) = futures::executor::block_on(act.refresh()) {
|
|
|
|
log::error!("Energy refresh failed! {e}")
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
fn stopped(&mut self, _ctx: &mut Self::Context) {
|
|
|
|
log::info!("Energy actor successfully stopped!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub type EnergyActorAddr = Addr<EnergyActor>;
|
|
|
|
|
|
|
|
/// Get current consumption
|
|
|
|
#[derive(Message)]
|
|
|
|
#[rtype(result = "EnergyConsumption")]
|
|
|
|
pub struct GetCurrConsumption;
|
|
|
|
|
|
|
|
impl Handler<GetCurrConsumption> for EnergyActor {
|
|
|
|
type Result = EnergyConsumption;
|
|
|
|
|
|
|
|
fn handle(&mut self, _msg: GetCurrConsumption, _ctx: &mut Context<Self>) -> Self::Result {
|
|
|
|
self.curr_consumption
|
|
|
|
}
|
|
|
|
}
|
2024-07-01 19:10:45 +00:00
|
|
|
|
|
|
|
/// Get current consumption
|
|
|
|
#[derive(Message)]
|
|
|
|
#[rtype(result = "bool")]
|
2024-07-01 20:24:03 +00:00
|
|
|
pub struct CheckDeviceExists(pub DeviceId);
|
2024-07-01 19:10:45 +00:00
|
|
|
|
|
|
|
impl Handler<CheckDeviceExists> for EnergyActor {
|
|
|
|
type Result = bool;
|
|
|
|
|
|
|
|
fn handle(&mut self, msg: CheckDeviceExists, _ctx: &mut Context<Self>) -> Self::Result {
|
|
|
|
self.devices.exists(&msg.0)
|
|
|
|
}
|
|
|
|
}
|
2024-07-02 20:55:51 +00:00
|
|
|
|
|
|
|
/// Enroll device
|
|
|
|
#[derive(Message)]
|
|
|
|
#[rtype(result = "anyhow::Result<()>")]
|
|
|
|
pub struct EnrollDevice(pub DeviceId, pub DeviceInfo, pub X509Req);
|
|
|
|
|
|
|
|
impl Handler<EnrollDevice> for EnergyActor {
|
|
|
|
type Result = anyhow::Result<()>;
|
|
|
|
|
|
|
|
fn handle(&mut self, msg: EnrollDevice, _ctx: &mut Context<Self>) -> Self::Result {
|
|
|
|
self.devices.enroll(&msg.0, &msg.1, &msg.2)
|
|
|
|
}
|
|
|
|
}
|
2024-07-03 17:17:47 +00:00
|
|
|
|
2024-07-03 19:32:32 +00:00
|
|
|
/// Validate a device
|
|
|
|
#[derive(Message)]
|
|
|
|
#[rtype(result = "anyhow::Result<()>")]
|
|
|
|
pub struct ValidateDevice(pub DeviceId);
|
|
|
|
|
|
|
|
impl Handler<ValidateDevice> for EnergyActor {
|
|
|
|
type Result = anyhow::Result<()>;
|
|
|
|
|
|
|
|
fn handle(&mut self, msg: ValidateDevice, _ctx: &mut Context<Self>) -> Self::Result {
|
|
|
|
log::info!("Requested to validate device {:?}...", &msg.0);
|
|
|
|
self.devices.validate(&msg.0)?;
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-07-22 20:19:48 +00:00
|
|
|
/// Update a device general information
|
|
|
|
#[derive(Message)]
|
|
|
|
#[rtype(result = "anyhow::Result<()>")]
|
|
|
|
pub struct UpdateDeviceGeneralInfo(pub DeviceId, pub DeviceGeneralInfo);
|
|
|
|
|
|
|
|
impl Handler<UpdateDeviceGeneralInfo> for EnergyActor {
|
|
|
|
type Result = anyhow::Result<()>;
|
|
|
|
|
|
|
|
fn handle(&mut self, msg: UpdateDeviceGeneralInfo, _ctx: &mut Context<Self>) -> Self::Result {
|
|
|
|
log::info!(
|
|
|
|
"Requested to update device general info {:?}... {:#?}",
|
|
|
|
&msg.0,
|
|
|
|
&msg.1
|
|
|
|
);
|
|
|
|
|
|
|
|
self.devices.update_general_info(&msg.0, msg.1)?;
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-07-03 19:10:15 +00:00
|
|
|
/// Delete a device
|
|
|
|
#[derive(Message)]
|
|
|
|
#[rtype(result = "anyhow::Result<()>")]
|
|
|
|
pub struct DeleteDevice(pub DeviceId);
|
|
|
|
|
|
|
|
impl Handler<DeleteDevice> for EnergyActor {
|
|
|
|
type Result = anyhow::Result<()>;
|
|
|
|
|
|
|
|
fn handle(&mut self, msg: DeleteDevice, _ctx: &mut Context<Self>) -> Self::Result {
|
|
|
|
log::info!("Requested to delete device {:?}...", &msg.0);
|
|
|
|
self.devices.delete(&msg.0)?;
|
|
|
|
// TODO : delete energy related information
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-07-03 17:17:47 +00:00
|
|
|
/// Get the list of devices
|
|
|
|
#[derive(Message)]
|
|
|
|
#[rtype(result = "Vec<Device>")]
|
|
|
|
pub struct GetDeviceLists;
|
|
|
|
|
|
|
|
impl Handler<GetDeviceLists> for EnergyActor {
|
|
|
|
type Result = Vec<Device>;
|
|
|
|
|
|
|
|
fn handle(&mut self, _msg: GetDeviceLists, _ctx: &mut Context<Self>) -> Self::Result {
|
|
|
|
self.devices.full_list()
|
|
|
|
}
|
|
|
|
}
|
2024-07-03 20:05:19 +00:00
|
|
|
|
|
|
|
/// Get the information about a single device
|
|
|
|
#[derive(Message)]
|
|
|
|
#[rtype(result = "Option<Device>")]
|
|
|
|
pub struct GetSingleDevice(pub DeviceId);
|
|
|
|
|
|
|
|
impl Handler<GetSingleDevice> for EnergyActor {
|
|
|
|
type Result = Option<Device>;
|
|
|
|
|
|
|
|
fn handle(&mut self, msg: GetSingleDevice, _ctx: &mut Context<Self>) -> Self::Result {
|
|
|
|
self.devices.get_single(&msg.0)
|
|
|
|
}
|
|
|
|
}
|