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 set-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; } } } _ => (), } } }