Start to check device relay information
This commit is contained in:
parent
5497c36c75
commit
48a2f728de
@ -36,6 +36,10 @@ impl SizeConstraint {
|
|||||||
let len = val.trim().len();
|
let len = val.trim().len();
|
||||||
len >= self.min && len <= self.max
|
len >= self.min && len <= self.max
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn validate_usize(&self, val: usize) -> bool {
|
||||||
|
val >= self.min && val <= self.max
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Backend static constraints
|
/// Backend static constraints
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
//! # Devices entities definition
|
//! # Devices entities definition
|
||||||
|
|
||||||
use crate::constants::StaticConstraints;
|
use crate::constants::StaticConstraints;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
/// Device information provided directly by the device during syncrhonisation.
|
/// Device information provided directly by the device during syncrhonisation.
|
||||||
///
|
///
|
||||||
@ -75,13 +76,20 @@ pub struct DailyMinRuntime {
|
|||||||
pub catch_up_hours: Vec<usize>,
|
pub catch_up_hours: Vec<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, serde::Serialize, serde::Deserialize, Eq, PartialEq)]
|
#[derive(Clone, Copy, Debug, serde::Serialize, serde::Deserialize, Eq, PartialEq, Hash)]
|
||||||
pub struct DeviceRelayID(uuid::Uuid);
|
pub struct DeviceRelayID(uuid::Uuid);
|
||||||
|
|
||||||
|
impl Default for DeviceRelayID {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self(uuid::Uuid::new_v4())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Single device relay information
|
/// Single device relay information
|
||||||
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
|
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize, Default)]
|
||||||
pub struct DeviceRelay {
|
pub struct DeviceRelay {
|
||||||
/// Device relay id. Should be unique across the whole application
|
/// Device relay id. Should be unique across the whole application
|
||||||
|
#[serde(default)]
|
||||||
id: DeviceRelayID,
|
id: DeviceRelayID,
|
||||||
/// Human-readable name for the relay
|
/// Human-readable name for the relay
|
||||||
name: String,
|
name: String,
|
||||||
@ -103,6 +111,80 @@ pub struct DeviceRelay {
|
|||||||
conflicts_with: Vec<DeviceRelayID>,
|
conflicts_with: Vec<DeviceRelayID>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl DeviceRelay {
|
||||||
|
/// Check device relay for errors
|
||||||
|
pub fn error(&self, list: &[DeviceRelay]) -> Option<&'static str> {
|
||||||
|
let constraints = StaticConstraints::default();
|
||||||
|
if !constraints.relay_name_len.validate(&self.name) {
|
||||||
|
return Some("Invalid relay name length!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if !constraints.relay_priority.validate_usize(self.priority) {
|
||||||
|
return Some("Invalid relay priority!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if !constraints
|
||||||
|
.relay_consumption
|
||||||
|
.validate_usize(self.consumption)
|
||||||
|
{
|
||||||
|
return Some("Invalid consumption!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if !constraints
|
||||||
|
.relay_minimal_uptime
|
||||||
|
.validate_usize(self.minimal_uptime)
|
||||||
|
{
|
||||||
|
return Some("Invalid minimal uptime!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if !constraints
|
||||||
|
.relay_minimal_downtime
|
||||||
|
.validate_usize(self.minimal_downtime)
|
||||||
|
{
|
||||||
|
return Some("Invalid minimal uptime!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(daily) = &self.daily_runtime {
|
||||||
|
if !constraints
|
||||||
|
.relay_daily_minimal_runtime
|
||||||
|
.validate_usize(daily.min_runtime)
|
||||||
|
{
|
||||||
|
return Some("Invalid minimal daily runtime!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if daily.reset_time > 3600 * 24 {
|
||||||
|
return Some("Invalid daily reset time!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if daily.catch_up_hours.is_empty() {
|
||||||
|
return Some("No catchup hours defined!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if daily.catch_up_hours.iter().any(|h| h > &23) {
|
||||||
|
return Some("At least one catch up hour is invalid!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let relays_map = list.iter().map(|r| (r.id, r)).collect::<HashMap<_, _>>();
|
||||||
|
|
||||||
|
if self.depends_on.iter().any(|d| !relays_map.contains_key(d)) {
|
||||||
|
return Some("A specified dependent relay does not exists!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if self
|
||||||
|
.conflicts_with
|
||||||
|
.iter()
|
||||||
|
.any(|d| !relays_map.contains_key(d))
|
||||||
|
{
|
||||||
|
return Some("A specified conflicting relay does not exists!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO : check for loops
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Device general information
|
/// Device general information
|
||||||
///
|
///
|
||||||
/// This structure is used to update device information
|
/// This structure is used to update device information
|
||||||
@ -128,3 +210,33 @@ impl DeviceGeneralInfo {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::devices::device::DeviceRelay;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_device_relay_error() {
|
||||||
|
let unitary = DeviceRelay {
|
||||||
|
name: "unitary".to_string(),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let bad_name = DeviceRelay {
|
||||||
|
name: "".to_string(),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let dep_on_unitary = DeviceRelay {
|
||||||
|
name: "dep_on_unitary".to_string(),
|
||||||
|
depends_on: vec![unitary.id],
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(unitary.error(&[]), None);
|
||||||
|
assert_eq!(unitary.error(&[unitary.clone(), bad_name.clone()]), None);
|
||||||
|
assert!(bad_name.error(&[]).is_some());
|
||||||
|
assert_eq!(dep_on_unitary.error(&[unitary.clone()]), None);
|
||||||
|
assert!(dep_on_unitary.error(&[]).is_some());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user