diff options
author | Tomasz Kramkowski <tomasz@kramkow.ski> | 2025-05-03 20:00:17 +0100 |
---|---|---|
committer | Tomasz Kramkowski <tomasz@kramkow.ski> | 2025-05-03 20:00:17 +0100 |
commit | 6b2711c5703c2b724066c88967c1924f1f1dbedf (patch) | |
tree | 4561b0fb47a3429b86e82b19f335b6aed1081e5f /src/device/set_state.rs | |
download | z2m-utils-6b2711c5703c2b724066c88967c1924f1f1dbedf.tar.gz z2m-utils-6b2711c5703c2b724066c88967c1924f1f1dbedf.tar.xz z2m-utils-6b2711c5703c2b724066c88967c1924f1f1dbedf.zip |
Diffstat (limited to 'src/device/set_state.rs')
-rw-r--r-- | src/device/set_state.rs | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/src/device/set_state.rs b/src/device/set_state.rs new file mode 100644 index 0000000..24ed99e --- /dev/null +++ b/src/device/set_state.rs @@ -0,0 +1,64 @@ +use std::{env::ArgsOs, process, str}; + +use rumqttc::{Event::Incoming, Packet::Publish, QoS}; +use serde_json::{json, Value}; + +use crate::config::Config; + +pub fn main(argv0: &str, config: Config, device_name: &str, mut args: ArgsOs) { + let (Some(target_state), None) = (args.next(), args.next()) else { + eprintln!("Usage: {argv0} device <device-name> set-state <target-state>"); + process::exit(1); + }; + + let target_state = if target_state.eq_ignore_ascii_case("on") { + "ON" + } else if target_state.eq_ignore_ascii_case("off") { + "OFF" + } else if target_state.eq_ignore_ascii_case("toggle") { + "TOGGLE" + } else { + eprintln!("{argv0}: error: target-state must be on/off/toggle"); + process::exit(1); + }; + + let (client, mut connection) = config.mqtt_client(); + + let device_topic = format!("zigbee2mqtt/{device_name}"); + client.subscribe(&device_topic, QoS::AtMostOnce).unwrap(); + + client + .publish( + &format!("{device_topic}/get"), + QoS::AtLeastOnce, + false, + json!({"state": "" }).to_string(), + ) + .unwrap(); + client + .publish( + &format!("{device_topic}/set"), + QoS::AtLeastOnce, + false, + json!({"state": target_state}).to_string(), + ) + .unwrap(); + + for notification in connection.iter() { + match notification.unwrap() { + Incoming(Publish(p)) => { + if p.topic == device_topic { + let parsed: Value = + serde_json::from_str(str::from_utf8(&p.payload).unwrap()).unwrap(); + if target_state == "TOGGLE" { + break; + } + if parsed["state"] == target_state { + break; + } + } + } + _ => (), + } + } +} |