mirror of
https://codeberg.org/icewind/taspromto.git
synced 2026-08-02 12:14:45 +02:00
143 lines
4.5 KiB
Rust
143 lines
4.5 KiB
Rust
use crate::device::{Device, DsmrMessageType};
|
|
|
|
#[derive(Debug, Eq, PartialEq)]
|
|
pub enum Topic {
|
|
Lwt(Device),
|
|
Power(Device),
|
|
State(Device),
|
|
Sensor(Device),
|
|
Result(Device),
|
|
Other(String),
|
|
Status(Device),
|
|
Msg(Device),
|
|
Water(Device),
|
|
Gas(Device),
|
|
Energy1(Device),
|
|
Energy2(Device),
|
|
DsmrPower(Device),
|
|
Rtl(Device, String),
|
|
}
|
|
|
|
impl Topic {
|
|
pub fn dsmr_type(&self) -> Option<DsmrMessageType> {
|
|
match self {
|
|
Topic::Water(_) => Some(DsmrMessageType::Water),
|
|
Topic::Gas(_) => Some(DsmrMessageType::Gas),
|
|
Topic::Energy1(_) => Some(DsmrMessageType::Energy1),
|
|
Topic::Energy2(_) => Some(DsmrMessageType::Energy2),
|
|
Topic::DsmrPower(_) => Some(DsmrMessageType::Power),
|
|
_ => None,
|
|
}
|
|
}
|
|
|
|
pub fn into_device(self) -> Device {
|
|
match self {
|
|
Topic::Lwt(device) => device,
|
|
Topic::Power(device) => device,
|
|
Topic::State(device) => device,
|
|
Topic::Sensor(device) => device,
|
|
Topic::Result(device) => device,
|
|
Topic::Other(device) => Device { hostname: device },
|
|
Topic::Status(device) => device,
|
|
Topic::Msg(device) => device,
|
|
Topic::Water(device) => device,
|
|
Topic::Gas(device) => device,
|
|
Topic::Energy1(device) => device,
|
|
Topic::Energy2(device) => device,
|
|
Topic::DsmrPower(device) => device,
|
|
Topic::Rtl(device, _) => device,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<&str> for Topic {
|
|
fn from(raw: &str) -> Self {
|
|
if let Some(rf_name) = raw.strip_suffix("/msg") {
|
|
let device = Device {
|
|
hostname: rf_name.to_string(),
|
|
};
|
|
return Topic::Msg(device);
|
|
}
|
|
if let Some((device, topic)) = raw
|
|
.strip_prefix("rtl_433/")
|
|
.and_then(|topic| topic.split_once('/'))
|
|
{
|
|
let device = Device {
|
|
hostname: device.to_string(),
|
|
};
|
|
return Topic::Rtl(device, topic.into());
|
|
}
|
|
if let Some(name) = raw.strip_suffix("/water") {
|
|
let device = Device {
|
|
hostname: name.to_string(),
|
|
};
|
|
return Topic::Water(device);
|
|
}
|
|
if let Some(name) = raw.strip_suffix("/gas_delivered") {
|
|
let device = Device {
|
|
hostname: name.to_string(),
|
|
};
|
|
return Topic::Gas(device);
|
|
}
|
|
if let Some(name) = raw.strip_suffix("/energy_delivered_tariff1") {
|
|
let device = Device {
|
|
hostname: name.to_string(),
|
|
};
|
|
return Topic::Energy1(device);
|
|
}
|
|
if let Some(name) = raw.strip_suffix("/energy_delivered_tariff2") {
|
|
let device = Device {
|
|
hostname: name.to_string(),
|
|
};
|
|
return Topic::Energy2(device);
|
|
}
|
|
if let Some(name) = raw.strip_suffix("/power_delivered_l1") {
|
|
let device = Device {
|
|
hostname: name.to_string(),
|
|
};
|
|
return Topic::DsmrPower(device);
|
|
}
|
|
|
|
let mut parts = raw.split('/');
|
|
if let (Some(prefix), Some(hostname), Some(cmd)) =
|
|
(parts.next(), parts.next(), parts.next())
|
|
{
|
|
let device = Device {
|
|
hostname: hostname.to_string(),
|
|
};
|
|
match (prefix, cmd) {
|
|
("tele", "LWT") => Topic::Lwt(device),
|
|
("tele", "STATE") => Topic::State(device),
|
|
("stat", "POWER") => Topic::Power(device),
|
|
("tele", "SENSOR") => Topic::Sensor(device),
|
|
("stat", "RESULT") => Topic::Result(device),
|
|
("stat", "STATUS") => Topic::Status(device),
|
|
("stat", "STATUS2") => Topic::Status(device),
|
|
_ => Topic::Other(raw.to_string()),
|
|
}
|
|
} else {
|
|
Topic::Other(raw.to_string())
|
|
}
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn parse_topic() {
|
|
let device = Device {
|
|
hostname: "hostname".to_string(),
|
|
};
|
|
assert_eq!(Topic::Lwt(device.clone()), Topic::from("tele/hostname/LWT"));
|
|
assert_eq!(
|
|
Topic::Power(device.clone()),
|
|
Topic::from("stat/hostname/POWER")
|
|
);
|
|
assert_eq!(
|
|
Topic::State(device.clone()),
|
|
Topic::from("tele/hostname/STATE")
|
|
);
|
|
assert_eq!(
|
|
Topic::Sensor(device.clone()),
|
|
Topic::from("tele/hostname/SENSOR")
|
|
);
|
|
assert_eq!(Topic::Result(device), Topic::from("stat/hostname/RESULT"));
|
|
}
|