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)]
|
#[derive(Debug)]
|
||||||
pub struct MiTempState {
|
pub struct MiTempDevice {
|
||||||
|
pub name: String,
|
||||||
|
pub addr: BDAddr,
|
||||||
temperature: f32,
|
temperature: f32,
|
||||||
humidity: f32,
|
humidity: f32,
|
||||||
dew_point: f32,
|
dew_point: f32,
|
||||||
|
|
@ -16,9 +18,11 @@ pub struct MiTempState {
|
||||||
pub last_seen: Instant,
|
pub last_seen: Instant,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for MiTempState {
|
impl MiTempDevice {
|
||||||
fn default() -> Self {
|
pub fn new(addr: BDAddr, name: String) -> Self {
|
||||||
MiTempState {
|
MiTempDevice {
|
||||||
|
name,
|
||||||
|
addr,
|
||||||
temperature: 0.0,
|
temperature: 0.0,
|
||||||
humidity: 0.0,
|
humidity: 0.0,
|
||||||
dew_point: 0.0,
|
dew_point: 0.0,
|
||||||
|
|
@ -26,9 +30,7 @@ impl Default for MiTempState {
|
||||||
last_seen: Instant::now(),
|
last_seen: Instant::now(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl MiTempState {
|
|
||||||
pub fn update(&mut self, json: &JsonValue) {
|
pub fn update(&mut self, json: &JsonValue) {
|
||||||
self.last_seen = Instant::now();
|
self.last_seen = Instant::now();
|
||||||
if let Some(temperature) = json["Temperature"].as_number().map(f32::from) {
|
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,
|
mut writer: W,
|
||||||
addr: BDAddr,
|
addr: BDAddr,
|
||||||
names: &BTreeMap<BDAddr, String>,
|
names: &BTreeMap<BDAddr, String>,
|
||||||
state: &MiTempState,
|
state: &MiTempDevice,
|
||||||
) -> fmt::Result {
|
) -> fmt::Result {
|
||||||
// sensor_battery{name="Living Room", mac="58:2D:34:39:1D:5B"} 100
|
// 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_temperature{name="Living Room", mac="58:2D:34:39:1D:5B"} 16.2
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
mod mitemp;
|
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 color_eyre::{Report, Result, eyre::WrapErr};
|
||||||
use jzon::JsonValue;
|
use jzon::JsonValue;
|
||||||
use rumqttc::{AsyncClient, QoS};
|
use rumqttc::{AsyncClient, QoS};
|
||||||
|
|
@ -17,14 +17,28 @@ use tokio::task::spawn;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct DeviceStates {
|
pub struct DeviceStates {
|
||||||
|
pub mi_temp_names: BTreeMap<BDAddr, String>,
|
||||||
|
pub rf_temp_names: HashMap<RfDeviceId, String>,
|
||||||
|
|
||||||
pub devices: HashMap<Device, DeviceState>,
|
pub devices: HashMap<Device, DeviceState>,
|
||||||
pub dsmr_devices: HashMap<Device, DsmrState>,
|
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>,
|
pub rf_temp_devices: HashMap<RfDeviceId, TempState>,
|
||||||
active_rf_temp_id: RfDeviceId,
|
active_rf_temp_id: RfDeviceId,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DeviceStates {
|
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)> {
|
pub fn devices(&self) -> impl Iterator<Item = (&Device, &DeviceState)> {
|
||||||
self.devices.iter()
|
self.devices.iter()
|
||||||
}
|
}
|
||||||
|
|
@ -41,9 +55,14 @@ impl DeviceStates {
|
||||||
let addr = addr.trim_start_matches('-');
|
let addr = addr.trim_start_matches('-');
|
||||||
match BDAddr::from_mi_temp_mac_part(addr) {
|
match BDAddr::from_mi_temp_mac_part(addr) {
|
||||||
Ok(addr) => {
|
Ok(addr) => {
|
||||||
let state = self.mi_temp_devices.entry(addr).or_default();
|
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);
|
state.update(value);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Err(e) => eprintln!("Failed to parse mitemp mac: {:#}", e),
|
Err(e) => eprintln!("Failed to parse mitemp mac: {:#}", e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -68,9 +87,15 @@ impl DeviceStates {
|
||||||
|
|
||||||
pub fn update_rf(&mut self, payload: &str) {
|
pub fn update_rf(&mut self, payload: &str) {
|
||||||
if let Some(data) = parse_rf_payload(payload) {
|
if let Some(data) = parse_rf_payload(payload) {
|
||||||
let state = self.rf_temp_devices.entry(data.device_id()).or_default();
|
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.humidity = data.humidity;
|
||||||
state.temperature = data.temperature;
|
state.temperature = data.temperature;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
eprintln!("invalid rf payload: {payload}")
|
eprintln!("invalid rf payload: {payload}")
|
||||||
}
|
}
|
||||||
|
|
@ -92,10 +117,11 @@ impl DeviceStates {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_active_rtl(&mut self, field: &str, payload: &str) {
|
fn update_active_rtl(&mut self, field: &str, payload: &str) {
|
||||||
|
if let Some(name) = self.rf_temp_names.get(&self.active_rf_temp_id) {
|
||||||
let state = self
|
let state = self
|
||||||
.rf_temp_devices
|
.rf_temp_devices
|
||||||
.entry(self.active_rf_temp_id.clone())
|
.entry(self.active_rf_temp_id.clone())
|
||||||
.or_default();
|
.or_insert_with(|| TempState::new(name.clone()));
|
||||||
match field {
|
match field {
|
||||||
"temperature_C" => state.temperature = payload.parse().unwrap_or_default(),
|
"temperature_C" => state.temperature = payload.parse().unwrap_or_default(),
|
||||||
"temperature_F" => {
|
"temperature_F" => {
|
||||||
|
|
@ -108,8 +134,9 @@ impl DeviceStates {
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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()
|
self.mi_temp_devices.iter()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -393,12 +420,23 @@ pub fn format_device_state<W: Write>(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug)]
|
||||||
pub struct TempState {
|
pub struct TempState {
|
||||||
|
name: String,
|
||||||
temperature: f32,
|
temperature: f32,
|
||||||
humidity: u8,
|
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>(
|
pub fn format_rf_temp_state<W: Write>(
|
||||||
mut writer: W,
|
mut writer: W,
|
||||||
channel: &RfDeviceId,
|
channel: &RfDeviceId,
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,9 @@ async fn main() -> Result<()> {
|
||||||
};
|
};
|
||||||
let mqtt_options = config.mqtt()?;
|
let mqtt_options = config.mqtt()?;
|
||||||
|
|
||||||
let device_states = <Arc<Mutex<DeviceStates>>>::default();
|
let device_states =
|
||||||
|
DeviceStates::new(config.names.mi_temp.clone(), config.names.rf_temp.clone());
|
||||||
|
let device_states = Arc::new(Mutex::new(device_states));
|
||||||
|
|
||||||
ctrlc::set_handler(move || {
|
ctrlc::set_handler(move || {
|
||||||
std::process::exit(0);
|
std::process::exit(0);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue