diff --git a/src/device/mitemp.rs b/src/device/mitemp.rs new file mode 100644 index 0000000..16daeed --- /dev/null +++ b/src/device/mitemp.rs @@ -0,0 +1,92 @@ +use jzon::JsonValue; + +use crate::device::BDAddr; +use std::{ + collections::BTreeMap, + fmt::{self, Debug, Write}, + time::Instant, +}; + +#[derive(Debug)] +pub struct MiTempState { + temperature: f32, + humidity: f32, + dew_point: f32, + battery: u8, + pub last_seen: Instant, +} + +impl Default for MiTempState { + fn default() -> Self { + MiTempState { + temperature: 0.0, + humidity: 0.0, + dew_point: 0.0, + battery: 0, + last_seen: Instant::now(), + } + } +} + +impl MiTempState { + 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; + } + } +} + +pub fn format_mi_temp_state( + mut writer: W, + addr: BDAddr, + names: &BTreeMap, + state: &MiTempState, +) -> fmt::Result { + // sensor_battery{name="Living Room", mac="58:2D:34:39:1D:5B"} 100 + // sensor_temperature{name="Living Room", mac="58:2D:34:39:1D:5B"} 16.2 + // sensor_humidity{name="Living Room", mac="58:2D:34:39:1D:5B"} 61. + + let name = if let Some(name) = names.get(&addr) { + name + } else { + return Ok(()); + }; + + if state.battery > 0 { + writeln!( + writer, + "sensor_battery{{mac=\"{}\", name=\"{}\"}} {}", + addr, name, state.battery + )?; + } + + if state.temperature > 0.0 { + writeln!( + writer, + "sensor_temperature{{mac=\"{}\", name=\"{}\"}} {}", + addr, name, state.temperature + )?; + } + + if state.humidity > 0.0 { + writeln!( + writer, + "sensor_humidity{{mac=\"{}\", name=\"{}\"}} {}", + addr, name, state.humidity + )?; + } + Ok(()) +} diff --git a/src/device.rs b/src/device/mod.rs similarity index 91% rename from src/device.rs rename to src/device/mod.rs index 458d87c..829de04 100644 --- a/src/device.rs +++ b/src/device/mod.rs @@ -1,3 +1,6 @@ +mod mitemp; + +pub use crate::device::mitemp::{MiTempState, format_mi_temp_state}; use color_eyre::{Report, Result, eyre::WrapErr}; use jzon::JsonValue; use rumqttc::{AsyncClient, QoS}; @@ -287,48 +290,6 @@ impl DeviceState { } } -#[derive(Debug)] -pub struct MiTempState { - temperature: f32, - humidity: f32, - dew_point: f32, - battery: u8, - pub last_seen: Instant, -} - -impl Default for MiTempState { - fn default() -> Self { - MiTempState { - temperature: 0.0, - humidity: 0.0, - dew_point: 0.0, - battery: 0, - last_seen: Instant::now(), - } - } -} - -impl MiTempState { - 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; - } - } -} - pub fn format_device_state( mut writer: W, device: &Device, @@ -432,48 +393,6 @@ pub fn format_device_state( Ok(()) } -pub fn format_mi_temp_state( - mut writer: W, - addr: BDAddr, - names: &BTreeMap, - state: &MiTempState, -) -> fmt::Result { - // sensor_battery{name="Living Room", mac="58:2D:34:39:1D:5B"} 100 - // sensor_temperature{name="Living Room", mac="58:2D:34:39:1D:5B"} 16.2 - // sensor_humidity{name="Living Room", mac="58:2D:34:39:1D:5B"} 61. - - let name = if let Some(name) = names.get(&addr) { - name - } else { - return Ok(()); - }; - - if state.battery > 0 { - writeln!( - writer, - "sensor_battery{{mac=\"{}\", name=\"{}\"}} {}", - addr, name, state.battery - )?; - } - - if state.temperature > 0.0 { - writeln!( - writer, - "sensor_temperature{{mac=\"{}\", name=\"{}\"}} {}", - addr, name, state.temperature - )?; - } - - if state.humidity > 0.0 { - writeln!( - writer, - "sensor_humidity{{mac=\"{}\", name=\"{}\"}} {}", - addr, name, state.humidity - )?; - } - Ok(()) -} - #[derive(Debug, Default)] pub struct TempState { temperature: f32,