cdb/src/location.rs
2025-04-16 04:05:29 +02:00

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()
})
}
}