taspromto/src/device/mitemp.rs
2026-06-27 04:02:09 +02:00

90 lines
2.3 KiB
Rust

use jzon::JsonValue;
use crate::device::{BDAddr, FormattableDevice};
use std::{
fmt::{self, Debug, Display},
time::Instant,
};
#[derive(Debug)]
pub struct MiTempDevice {
pub name: String,
pub addr: BDAddr,
temperature: f32,
humidity: f32,
dew_point: f32,
battery: u8,
pub last_seen: Instant,
}
impl MiTempDevice {
pub fn new(addr: BDAddr, name: String) -> Self {
MiTempDevice {
name,
addr,
temperature: 0.0,
humidity: 0.0,
dew_point: 0.0,
battery: 0,
last_seen: Instant::now(),
}
}
pub fn update(&mut self, json: &JsonValue) {
self.last_seen = Instant::now();
if let Some(temperature) = json["Temperature"].as_number().map(f32::from) {
self.temperature = temperature;
}
if let Some(humidity) = json["Humidity"].as_number().map(f32::from) {
self.humidity = humidity;
}
if let Some(battery) = json["Battery"]
.as_number()
.and_then(|num| u8::try_from(num).ok())
{
self.battery = battery;
}
if let Some(dew_point) = json["DewPoint"].as_number().map(f32::from) {
self.dew_point = dew_point;
}
}
}
impl FormattableDevice for MiTempDevice {
fn format_open_metrics(&self) -> impl Display + '_ {
MitempFormatter { device: self }
}
}
struct MitempFormatter<'a> {
device: &'a MiTempDevice,
}
impl Display for MitempFormatter<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if self.device.battery > 0 {
writeln!(
f,
"sensor_battery{{mac=\"{}\", name=\"{}\"}} {}",
self.device.addr, self.device.name, self.device.battery
)?;
}
if self.device.temperature > 0.0 {
writeln!(
f,
"sensor_temperature{{mac=\"{}\", name=\"{}\"}} {}",
self.device.addr, self.device.name, self.device.temperature
)?;
}
if self.device.humidity > 0.0 {
writeln!(
f,
"sensor_humidity{{mac=\"{}\", name=\"{}\"}} {}",
self.device.addr, self.device.name, self.device.humidity
)?;
}
Ok(())
}
}