mirror of
https://codeberg.org/icewind/taspromto.git
synced 2026-08-02 12:14:45 +02:00
store rf/mitemp names with device state
This commit is contained in:
parent
2936b3cf22
commit
7335d35c68
3 changed files with 72 additions and 30 deletions
|
|
@ -8,7 +8,9 @@ use std::{
|
|||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct MiTempState {
|
||||
pub struct MiTempDevice {
|
||||
pub name: String,
|
||||
pub addr: BDAddr,
|
||||
temperature: f32,
|
||||
humidity: f32,
|
||||
dew_point: f32,
|
||||
|
|
@ -16,9 +18,11 @@ pub struct MiTempState {
|
|||
pub last_seen: Instant,
|
||||
}
|
||||
|
||||
impl Default for MiTempState {
|
||||
fn default() -> Self {
|
||||
MiTempState {
|
||||
impl MiTempDevice {
|
||||
pub fn new(addr: BDAddr, name: String) -> Self {
|
||||
MiTempDevice {
|
||||
name,
|
||||
addr,
|
||||
temperature: 0.0,
|
||||
humidity: 0.0,
|
||||
dew_point: 0.0,
|
||||
|
|
@ -26,9 +30,7 @@ impl Default for MiTempState {
|
|||
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) {
|
||||
|
|
@ -53,7 +55,7 @@ pub fn format_mi_temp_state<W: Write>(
|
|||
mut writer: W,
|
||||
addr: BDAddr,
|
||||
names: &BTreeMap<BDAddr, String>,
|
||||
state: &MiTempState,
|
||||
state: &MiTempDevice,
|
||||
) -> 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
mod mitemp;
|
||||
|
||||
pub use crate::device::mitemp::{MiTempState, format_mi_temp_state};
|
||||
pub use crate::device::mitemp::{MiTempDevice, format_mi_temp_state};
|
||||
use color_eyre::{Report, Result, eyre::WrapErr};
|
||||
use jzon::JsonValue;
|
||||
use rumqttc::{AsyncClient, QoS};
|
||||
|
|
@ -17,14 +17,28 @@ use tokio::task::spawn;
|
|||
|
||||
#[derive(Default)]
|
||||
pub struct DeviceStates {
|
||||
pub mi_temp_names: BTreeMap<BDAddr, String>,
|
||||
pub rf_temp_names: HashMap<RfDeviceId, String>,
|
||||
|
||||
pub devices: HashMap<Device, DeviceState>,
|
||||
pub dsmr_devices: HashMap<Device, DsmrState>,
|
||||
pub mi_temp_devices: BTreeMap<BDAddr, MiTempState>,
|
||||
pub mi_temp_devices: BTreeMap<BDAddr, MiTempDevice>,
|
||||
pub rf_temp_devices: HashMap<RfDeviceId, TempState>,
|
||||
active_rf_temp_id: RfDeviceId,
|
||||
}
|
||||
|
||||
impl DeviceStates {
|
||||
pub fn new(
|
||||
mi_temp_names: BTreeMap<BDAddr, String>,
|
||||
rf_temp_names: HashMap<RfDeviceId, String>,
|
||||
) -> Self {
|
||||
DeviceStates {
|
||||
mi_temp_names,
|
||||
rf_temp_names,
|
||||
..Self::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn devices(&self) -> impl Iterator<Item = (&Device, &DeviceState)> {
|
||||
self.devices.iter()
|
||||
}
|
||||
|
|
@ -41,8 +55,13 @@ impl DeviceStates {
|
|||
let addr = addr.trim_start_matches('-');
|
||||
match BDAddr::from_mi_temp_mac_part(addr) {
|
||||
Ok(addr) => {
|
||||
let state = self.mi_temp_devices.entry(addr).or_default();
|
||||
state.update(value);
|
||||
if let Some(name) = self.mi_temp_names.get(&addr) {
|
||||
let state = self
|
||||
.mi_temp_devices
|
||||
.entry(addr)
|
||||
.or_insert_with(|| MiTempDevice::new(addr, name.clone()));
|
||||
state.update(value);
|
||||
}
|
||||
}
|
||||
Err(e) => eprintln!("Failed to parse mitemp mac: {:#}", e),
|
||||
}
|
||||
|
|
@ -68,9 +87,15 @@ impl DeviceStates {
|
|||
|
||||
pub fn update_rf(&mut self, payload: &str) {
|
||||
if let Some(data) = parse_rf_payload(payload) {
|
||||
let state = self.rf_temp_devices.entry(data.device_id()).or_default();
|
||||
state.humidity = data.humidity;
|
||||
state.temperature = data.temperature;
|
||||
let id = data.device_id();
|
||||
if let Some(name) = self.rf_temp_names.get(&id) {
|
||||
let state = self
|
||||
.rf_temp_devices
|
||||
.entry(data.device_id())
|
||||
.or_insert_with(|| TempState::new(name.clone()));
|
||||
state.humidity = data.humidity;
|
||||
state.temperature = data.temperature;
|
||||
}
|
||||
} else {
|
||||
eprintln!("invalid rf payload: {payload}")
|
||||
}
|
||||
|
|
@ -92,24 +117,26 @@ impl DeviceStates {
|
|||
}
|
||||
|
||||
fn update_active_rtl(&mut self, field: &str, payload: &str) {
|
||||
let state = self
|
||||
.rf_temp_devices
|
||||
.entry(self.active_rf_temp_id.clone())
|
||||
.or_default();
|
||||
match field {
|
||||
"temperature_C" => state.temperature = payload.parse().unwrap_or_default(),
|
||||
"temperature_F" => {
|
||||
state.temperature = payload
|
||||
.parse()
|
||||
.map(|temp_f: f32| (temp_f - 32.0) * 5.0 / 9.0)
|
||||
.unwrap_or_default()
|
||||
if let Some(name) = self.rf_temp_names.get(&self.active_rf_temp_id) {
|
||||
let state = self
|
||||
.rf_temp_devices
|
||||
.entry(self.active_rf_temp_id.clone())
|
||||
.or_insert_with(|| TempState::new(name.clone()));
|
||||
match field {
|
||||
"temperature_C" => state.temperature = payload.parse().unwrap_or_default(),
|
||||
"temperature_F" => {
|
||||
state.temperature = payload
|
||||
.parse()
|
||||
.map(|temp_f: f32| (temp_f - 32.0) * 5.0 / 9.0)
|
||||
.unwrap_or_default()
|
||||
}
|
||||
"humidity" => state.humidity = payload.parse().unwrap_or_default(),
|
||||
_ => {}
|
||||
}
|
||||
"humidity" => state.humidity = payload.parse().unwrap_or_default(),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mi_temp(&self) -> impl Iterator<Item = (&BDAddr, &MiTempState)> {
|
||||
pub fn mi_temp(&self) -> impl Iterator<Item = (&BDAddr, &MiTempDevice)> {
|
||||
self.mi_temp_devices.iter()
|
||||
}
|
||||
|
||||
|
|
@ -393,12 +420,23 @@ pub fn format_device_state<W: Write>(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
#[derive(Debug)]
|
||||
pub struct TempState {
|
||||
name: String,
|
||||
temperature: f32,
|
||||
humidity: u8,
|
||||
}
|
||||
|
||||
impl TempState {
|
||||
pub fn new(name: String) -> Self {
|
||||
TempState {
|
||||
name,
|
||||
temperature: 0.0,
|
||||
humidity: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn format_rf_temp_state<W: Write>(
|
||||
mut writer: W,
|
||||
channel: &RfDeviceId,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue