homekit-logger/homekit-exporter/src/server.rs

66 lines
2.7 KiB
Rust

use homekit_controller::{ConnectedDevice, Data};
use rocket::State;
use std::{collections::HashMap, ops::DerefMut};
use tokio::sync::Mutex;
use crate::SENSORS;
pub fn launch(paired: HashMap<String, ConnectedDevice>) -> rocket::Rocket<rocket::Build> {
rocket::build()
.manage(Mutex::new(paired))
.mount("/", routes![metrics])
}
#[get("/metrics")]
pub async fn metrics(state: &State<Mutex<HashMap<String, ConnectedDevice>>>) -> Option<String> {
let mut s = String::new();
let mut state = state.lock().await;
let mut shown_types = Vec::new();
for (name, connected) in state.deref_mut() {
connected.update_characteristics().await.ok()?;
for (aid, accessory) in &connected.accessories {
for service in accessory.services.values() {
if !SENSORS.contains(&service.service_type) {
continue;
}
for (cid, characteristic) in &service.characteristics {
if let Some(value) = &characteristic.value {
if !shown_types.contains(&characteristic.characteristic_type) {
s.push_str(
format!("# TYPE {} gauge\n", characteristic.characteristic_type)
.as_str(),
);
shown_types.push(characteristic.characteristic_type);
}
s.push_str(
format!(
"{}{{accessory=\"{}.{}.{}\"}} {}\n",
characteristic.characteristic_type,
name,
aid,
cid,
match value {
Data::Bool(v) => format!("{}", if *v { 1 } else { 0 }),
Data::Uint8(v) => format!("{v}"),
Data::Uint16(v) => format!("{v}"),
Data::Uint32(v) => format!("{v}"),
Data::Uint64(v) => format!("{v}"),
Data::Int(v) => format!("{v}"),
Data::Float(v) => format!("{v}"),
Data::String(v) => v.to_string(),
Data::Tlv8(v) => v.to_string(),
Data::Data(v) => v.to_string(),
}
)
.as_str(),
)
}
}
}
}
}
Some(s)
}