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) -> rocket::Rocket { rocket::build() .manage(Mutex::new(paired)) .mount("/", routes![metrics]) } #[get("/metrics")] pub async fn metrics(state: &State>>) -> Option { 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) }