//! # Devices entities definition use crate::constants::StaticConstraints; /// Device information provided directly by the device during syncrhonisation. /// /// It should not be editable fro the Web UI #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)] pub struct DeviceInfo { /// Device reference reference: String, /// Device firmware / software version version: semver::Version, /// Maximum number of relay that the device can support max_relays: usize, } impl DeviceInfo { /// Identify errors in device information definition pub fn error(&self) -> Option<&str> { if self.reference.trim().is_empty() { return Some("Given device reference is empty or blank!"); } if self.max_relays == 0 { return Some("Given device cannot handle any relay!"); } None } } /// Device identifier #[derive(Clone, Debug, serde::Serialize, serde::Deserialize, Eq, PartialEq, Hash)] pub struct DeviceId(pub String); /// Single device information #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)] pub struct Device { /// The device ID pub id: DeviceId, /// Information about the device /// /// These information shall not be editable from the webui. They are automatically updated during /// device synchronization pub info: DeviceInfo, /// Time at which device was initially enrolled pub time_create: u64, /// Time at which device was last updated pub time_update: u64, /// Name given to the device on the Web UI pub name: String, /// Description given to the device on the Web UI pub description: String, /// Specify whether the device has been validated or not. Validated devices are given a /// certificate pub validated: bool, /// Specify whether the device is enabled or not pub enabled: bool, /// Information about the relays handled by the device /// /// There cannot be more than [info.max_relays] relays pub relays: Vec, } /// Structure that contains information about the minimal expected execution /// time of a device #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)] pub struct DailyMinRuntime { /// Minimum time, in seconds, that this relay should run each day pub min_runtime: usize, /// The seconds in the days (from 00:00) where the counter is reset pub reset_time: usize, /// The hours during which the relay should be turned on to reach expected runtime pub catch_up_hours: Vec, } #[derive(Clone, Copy, Debug, serde::Serialize, serde::Deserialize, Eq, PartialEq)] pub struct DeviceRelayID(uuid::Uuid); /// Single device relay information #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)] pub struct DeviceRelay { /// Device relay id. Should be unique across the whole application id: DeviceRelayID, /// Human-readable name for the relay name: String, /// Whether this relay can be turned on or not enabled: bool, /// Relay priority when selecting relays to turn on. 0 = lowest priority priority: usize, /// Estimated consumption of the electrical equipment triggered by the relay consumption: usize, /// Minimal time this relay shall be left on before it can be turned off (in seconds) minimal_uptime: usize, /// Minimal time this relay shall be left off before it can be turned on again (in seconds) minimal_downtime: usize, /// Optional minimal runtime requirements for this relay daily_runtime: Option, /// Specify relay that must be turned on before this relay can be started depends_on: Vec, /// Specify relays that must be turned off before this relay can be started conflicts_with: Vec, } /// Device general information /// /// This structure is used to update device information #[derive(serde::Deserialize, Debug, Clone)] pub struct DeviceGeneralInfo { pub name: String, pub description: String, pub enabled: bool, } impl DeviceGeneralInfo { /// Check for errors in the structure pub fn error(&self) -> Option<&'static str> { let constraints = StaticConstraints::default(); if !constraints.dev_name_len.validate(&self.name) { return Some("Invalid device name length!"); } if !constraints.dev_description_len.validate(&self.description) { return Some("Invalid device description length!"); } None } }