mirror of
https://codeberg.org/icewind/taspromto.git
synced 2026-06-03 08:34:21 +02:00
track firmware versions
This commit is contained in:
parent
bef835007d
commit
d6acb68602
4 changed files with 26 additions and 12 deletions
|
|
@ -100,6 +100,7 @@ pub struct DeviceState {
|
||||||
pub co2: Option<f32>,
|
pub co2: Option<f32>,
|
||||||
pub pms_state: Option<PMSState>,
|
pub pms_state: Option<PMSState>,
|
||||||
pub last_seen: Instant,
|
pub last_seen: Instant,
|
||||||
|
pub firmware: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for DeviceState {
|
impl Default for DeviceState {
|
||||||
|
|
@ -117,6 +118,7 @@ impl Default for DeviceState {
|
||||||
co2: Default::default(),
|
co2: Default::default(),
|
||||||
pms_state: Default::default(),
|
pms_state: Default::default(),
|
||||||
last_seen: Instant::now(),
|
last_seen: Instant::now(),
|
||||||
|
firmware: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -188,6 +190,10 @@ impl DeviceState {
|
||||||
self.gas_total = Some(gas);
|
self.gas_total = Some(gas);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(version) = json["StatusFWR"]["Version"].as_str() {
|
||||||
|
self.firmware = version.into();
|
||||||
|
}
|
||||||
|
|
||||||
if json["PMS5003"].is_object() {
|
if json["PMS5003"].is_object() {
|
||||||
let pms = self.pms_state.get_or_insert(PMSState::default());
|
let pms = self.pms_state.get_or_insert(PMSState::default());
|
||||||
pms.update(&json["PMS5003"]);
|
pms.update(&json["PMS5003"]);
|
||||||
|
|
@ -338,6 +344,14 @@ pub fn format_device_state<W: Write>(
|
||||||
format_pms_state(&mut writer, device, state, pms)?;
|
format_pms_state(&mut writer, device, state, pms)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !state.firmware.is_empty() {
|
||||||
|
writeln!(
|
||||||
|
writer,
|
||||||
|
"tasmota_version{{tasmota_id=\"{}\", name=\"{}\"}} {}",
|
||||||
|
device.hostname, state.name, state.firmware
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
20
src/main.rs
20
src/main.rs
|
|
@ -78,13 +78,13 @@ async fn mqtt_loop(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn command(client: &AsyncClient, device: &Device, command: &str) -> Result<()> {
|
async fn command(client: &AsyncClient, device: &Device, command: &str, body: &str) -> Result<()> {
|
||||||
client
|
client
|
||||||
.publish(
|
.publish(
|
||||||
device.get_topic("cmnd", command),
|
device.get_topic("cmnd", command),
|
||||||
QoS::AtMostOnce,
|
QoS::AtMostOnce,
|
||||||
false,
|
false,
|
||||||
"",
|
body,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
@ -109,23 +109,19 @@ async fn mqtt_client<S: Stream<Item = Result<Publish>>>(
|
||||||
// on discovery, ask the device for it's power state and name
|
// on discovery, ask the device for it's power state and name
|
||||||
let send_client = client.clone();
|
let send_client = client.clone();
|
||||||
spawn(async move {
|
spawn(async move {
|
||||||
if let Err(e) = command(&send_client, &device, "POWER").await {
|
if let Err(e) = command(&send_client, &device, "POWER", "").await {
|
||||||
eprintln!("Failed to ask for power state: {:#}", e);
|
eprintln!("Failed to ask for power state: {:#}", e);
|
||||||
}
|
}
|
||||||
if let Err(e) = command(&send_client, &device, "DeviceName").await {
|
if let Err(e) = command(&send_client, &device, "DeviceName", "").await {
|
||||||
eprintln!("Failed to ask for device name: {:#}", e);
|
eprintln!("Failed to ask for device name: {:#}", e);
|
||||||
}
|
}
|
||||||
|
if let Err(e) = command(&send_client, &device, "Status", "2").await {
|
||||||
|
eprintln!("Failed to ask for firmware state: {:#}", e);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Topic::Power(_) => {}
|
Topic::Power(_) => {}
|
||||||
Topic::Result(device) => {
|
Topic::Result(device) | Topic::Sensor(device) | Topic::Status(device) => {
|
||||||
let payload = std::str::from_utf8(message.payload.as_ref()).unwrap_or_default();
|
|
||||||
if let Ok(json) = json::parse(payload) {
|
|
||||||
let mut device_states = device_states.lock().unwrap();
|
|
||||||
device_states.update(device, json);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Topic::Sensor(device) => {
|
|
||||||
let payload = std::str::from_utf8(message.payload.as_ref()).unwrap_or_default();
|
let payload = std::str::from_utf8(message.payload.as_ref()).unwrap_or_default();
|
||||||
if let Ok(json) = json::parse(payload) {
|
if let Ok(json) = json::parse(payload) {
|
||||||
let mut device_states = device_states.lock().unwrap();
|
let mut device_states = device_states.lock().unwrap();
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ pub async fn mqtt_stream(
|
||||||
client.subscribe("stat/+/POWER", QoS::AtMostOnce).await?;
|
client.subscribe("stat/+/POWER", QoS::AtMostOnce).await?;
|
||||||
client.subscribe("tele/+/SENSOR", QoS::AtMostOnce).await?;
|
client.subscribe("tele/+/SENSOR", QoS::AtMostOnce).await?;
|
||||||
client.subscribe("stat/+/RESULT", QoS::AtMostOnce).await?;
|
client.subscribe("stat/+/RESULT", QoS::AtMostOnce).await?;
|
||||||
|
client.subscribe("stat/+/STATUS2", QoS::AtMostOnce).await?;
|
||||||
|
|
||||||
let stream = event_loop_to_stream(event_loop).filter_map(|event| match event {
|
let stream = event_loop_to_stream(event_loop).filter_map(|event| match event {
|
||||||
Ok(Event::Incoming(Packet::Publish(message))) => Some(Ok(message)),
|
Ok(Event::Incoming(Packet::Publish(message))) => Some(Ok(message)),
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ pub enum Topic {
|
||||||
Sensor(Device),
|
Sensor(Device),
|
||||||
Result(Device),
|
Result(Device),
|
||||||
Other(String),
|
Other(String),
|
||||||
|
Status(Device),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&str> for Topic {
|
impl From<&str> for Topic {
|
||||||
|
|
@ -25,6 +26,8 @@ impl From<&str> for Topic {
|
||||||
("stat", "POWER") => Topic::Power(device),
|
("stat", "POWER") => Topic::Power(device),
|
||||||
("tele", "SENSOR") => Topic::Sensor(device),
|
("tele", "SENSOR") => Topic::Sensor(device),
|
||||||
("stat", "RESULT") => Topic::Result(device),
|
("stat", "RESULT") => Topic::Result(device),
|
||||||
|
("stat", "STATUS") => Topic::Status(device),
|
||||||
|
("stat", "STATUS2") => Topic::Status(device),
|
||||||
_ => Topic::Other(raw.to_string()),
|
_ => Topic::Other(raw.to_string()),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue