110 lines
2.8 KiB
Rust
110 lines
2.8 KiB
Rust
use serde::{Deserialize, Serialize};
|
|
use serde_json::json;
|
|
|
|
use crate::{config::get_config, get_locations};
|
|
use based::request::api::ToAPI;
|
|
|
|
/// A Storage Location
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct Location {
|
|
/// UUID
|
|
#[serde(default)]
|
|
pub id: String,
|
|
/// Name
|
|
pub name: String,
|
|
/// Parent
|
|
pub parent: Option<String>,
|
|
/// Storage Conditions
|
|
pub conditions: Option<StorageConditions>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
|
pub struct StorageConditions {
|
|
/// Median temperature
|
|
pub temperature: f64,
|
|
/// Accurate temperature sensor reading
|
|
pub temperature_sensor: Option<String>,
|
|
}
|
|
|
|
impl StorageConditions {
|
|
/// Get a accurate temperature from a sensor endpoint
|
|
pub async fn accurate_temperature(&self) -> Option<f64> {
|
|
let conf = get_config();
|
|
let client = reqwest::Client::new();
|
|
let res: serde_json::Value = client
|
|
.get(self.temperature_sensor.clone()?)
|
|
.bearer_auth(conf.home_assistant?)
|
|
.send()
|
|
.await
|
|
.unwrap()
|
|
.json()
|
|
.await
|
|
.unwrap();
|
|
|
|
res.as_object()?.get("state")?.as_f64()
|
|
}
|
|
}
|
|
|
|
impl Location {
|
|
/// Recursively get the conditions of a location. This inherits from parent locations.
|
|
pub fn conditions_rec(&self) -> Option<StorageConditions> {
|
|
let locations = get_locations!();
|
|
|
|
if let Some(cond) = &self.conditions {
|
|
return Some(cond.clone());
|
|
}
|
|
|
|
if let Some(parent) = &self.parent {
|
|
if let Some(parent_loc) = locations.get(parent) {
|
|
if let Some(cond) = parent_loc.conditions_rec() {
|
|
return Some(cond);
|
|
}
|
|
}
|
|
}
|
|
|
|
None
|
|
}
|
|
|
|
// Get direct children
|
|
pub fn children_direct(&self) -> Vec<Location> {
|
|
let mut ret = Vec::new();
|
|
|
|
let locations = get_locations!();
|
|
for loc in locations.keys() {
|
|
let loc = locations.get(loc).unwrap();
|
|
if let Some(parent) = &loc.parent {
|
|
if *parent == self.id {
|
|
ret.push(loc.clone());
|
|
}
|
|
}
|
|
}
|
|
|
|
ret
|
|
}
|
|
|
|
// Get all children locations
|
|
pub fn children_recursive(&self) -> Vec<Location> {
|
|
let mut all = Vec::new();
|
|
|
|
let direct = self.children_direct();
|
|
all.extend_from_slice(&direct);
|
|
|
|
for loc in direct {
|
|
let sub = loc.children_recursive();
|
|
all.extend_from_slice(&sub);
|
|
}
|
|
|
|
all
|
|
}
|
|
}
|
|
|
|
impl ToAPI for Location {
|
|
async fn api(&self) -> serde_json::Value {
|
|
json!({
|
|
"id": self.id,
|
|
"name": self.name,
|
|
"parent": self.parent,
|
|
"conditions": self.conditions_rec()
|
|
})
|
|
}
|
|
}
|