Store last ping of devices
This commit is contained in:
		@@ -6,6 +6,9 @@ pub const SESSION_COOKIE_NAME: &str = "X-session-cookie";
 | 
			
		||||
/// Energy refresh operations interval
 | 
			
		||||
pub const ENERGY_REFRESH_INTERVAL: Duration = Duration::from_secs(30);
 | 
			
		||||
 | 
			
		||||
/// Maximum time after a ping during which a device is considered "up"
 | 
			
		||||
pub const DEVICE_MAX_PING_TIME: u64 = 30;
 | 
			
		||||
 | 
			
		||||
/// Fallback value to use if production cannot be fetched
 | 
			
		||||
pub const FALLBACK_PRODUCTION_VALUE: i32 = 5000;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -5,12 +5,33 @@ use crate::devices::device::{
 | 
			
		||||
use crate::devices::devices_list::DevicesList;
 | 
			
		||||
use crate::energy::consumption;
 | 
			
		||||
use crate::energy::consumption::EnergyConsumption;
 | 
			
		||||
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>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl EnergyActor {
 | 
			
		||||
@@ -18,9 +39,20 @@ impl EnergyActor {
 | 
			
		||||
        Ok(Self {
 | 
			
		||||
            curr_consumption: consumption::get_curr_consumption().await?,
 | 
			
		||||
            devices: DevicesList::load()?,
 | 
			
		||||
            devices_state: Default::default(),
 | 
			
		||||
            relays_state: Default::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()
 | 
			
		||||
@@ -253,6 +285,9 @@ 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();
 | 
			
		||||
 | 
			
		||||
        // TODO : implement real code
 | 
			
		||||
        let mut v = vec![];
 | 
			
		||||
        for i in 0..msg.1.max_relays {
 | 
			
		||||
@@ -263,3 +298,34 @@ impl Handler<SynchronizeDevice> for EnergyActor {
 | 
			
		||||
        Ok(v)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(serde::Serialize)]
 | 
			
		||||
pub struct ResDevState {
 | 
			
		||||
    id: DeviceId,
 | 
			
		||||
    last_ping: u64,
 | 
			
		||||
    online: bool,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Get the state of devices
 | 
			
		||||
#[derive(Message)]
 | 
			
		||||
#[rtype(result = "Vec<ResDevState>")]
 | 
			
		||||
pub struct GetDevicesState;
 | 
			
		||||
 | 
			
		||||
impl Handler<GetDevicesState> for EnergyActor {
 | 
			
		||||
    type Result = Vec<ResDevState>;
 | 
			
		||||
 | 
			
		||||
    fn handle(&mut self, _msg: GetDevicesState, _ctx: &mut Context<Self>) -> Self::Result {
 | 
			
		||||
        self.devices
 | 
			
		||||
            .full_list()
 | 
			
		||||
            .into_iter()
 | 
			
		||||
            .map(|d| {
 | 
			
		||||
                let s = self.device_state(&d.id);
 | 
			
		||||
                ResDevState {
 | 
			
		||||
                    id: d.id,
 | 
			
		||||
                    last_ping: time_secs() - s.last_ping,
 | 
			
		||||
                    online: s.is_online(),
 | 
			
		||||
                }
 | 
			
		||||
            })
 | 
			
		||||
            .collect()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -144,6 +144,10 @@ pub async fn secure_server(energy_actor: EnergyActorAddr) -> anyhow::Result<()>
 | 
			
		||||
                "/web_api/devices/list_validated",
 | 
			
		||||
                web::get().to(devices_controller::list_validated),
 | 
			
		||||
            )
 | 
			
		||||
            .route(
 | 
			
		||||
                "/web_api/devices/state",
 | 
			
		||||
                web::get().to(devices_controller::devices_state),
 | 
			
		||||
            )
 | 
			
		||||
            .route(
 | 
			
		||||
                "/web_api/device/{id}",
 | 
			
		||||
                web::get().to(devices_controller::get_single),
 | 
			
		||||
 
 | 
			
		||||
@@ -28,6 +28,13 @@ pub async fn list_validated(actor: WebEnergyActor) -> HttpResult {
 | 
			
		||||
    Ok(HttpResponse::Ok().json(list))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Get the state of devices
 | 
			
		||||
pub async fn devices_state(actor: WebEnergyActor) -> HttpResult {
 | 
			
		||||
    let states = actor.send(energy_actor::GetDevicesState).await?;
 | 
			
		||||
 | 
			
		||||
    Ok(HttpResponse::Ok().json(states))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(serde::Deserialize)]
 | 
			
		||||
pub struct DeviceInPath {
 | 
			
		||||
    id: DeviceId,
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user