taspromto/src/device/dsmr.rs
2026-06-27 03:43:50 +02:00

98 lines
2.4 KiB
Rust

use std::{
fmt::{self, Display},
time::Instant,
};
pub enum DsmrMessageType {
Water,
Gas,
Energy1,
Energy2,
Power,
}
#[derive(Debug)]
pub struct DsmrState {
pub name: String,
pub power: Option<f32>,
pub power_total_tariff_1: Option<f32>,
pub power_total_tariff_2: Option<f32>,
pub gas_total: Option<f32>,
pub water_total: Option<f32>,
pub last_seen: Instant,
}
impl DsmrState {
pub fn new(name: String) -> Self {
DsmrState {
name,
power: None,
power_total_tariff_1: None,
power_total_tariff_2: None,
gas_total: None,
water_total: None,
last_seen: Instant::now(),
}
}
pub fn format_open_metrics(&self) -> impl Display + '_ {
DsmrFormatter { device: self }
}
}
struct DsmrFormatter<'a> {
device: &'a DsmrState,
}
impl Display for DsmrFormatter<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let power_total = self.device.power_total_tariff_1.unwrap_or_default()
+ self.device.power_total_tariff_2.unwrap_or_default();
if power_total > 0.0 {
writeln!(
f,
"power_total_kwh{{name=\"{}\"}} {}",
self.device.name, power_total
)?;
}
if let Some(power) = self.device.power_total_tariff_1 {
writeln!(
f,
"power_total_low_kwh{{name=\"{}\"}} {}",
self.device.name, power
)?;
}
if let Some(power) = self.device.power_total_tariff_2 {
writeln!(
f,
"power_total_high_kwh{{name=\"{}\"}} {}",
self.device.name, power
)?;
}
if let Some(power) = self.device.power {
writeln!(
f,
"power_watts{{name=\"{}\"}} {}",
self.device.name,
power * 1000.0
)?;
}
if let Some(gas) = self.device.gas_total {
writeln!(f, "gas_total_m3{{name=\"{}\"}} {}", self.device.name, gas)?;
}
if let Some(water) = self.device.water_total {
writeln!(
f,
"water_total_m3{{name=\"{}\"}} {}",
self.device.name, water
)?;
}
Ok(())
}
}