summaryrefslogtreecommitdiffstats
path: root/src/device/set_state.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/device/set_state.rs')
-rw-r--r--src/device/set_state.rs64
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;
+ }
+ }
+ }
+ _ => (),
+ }
+ }
+}