use std::{ env::ArgsOs, ffi::OsString, process::{self, Command}, str }; use rumqttc::{Event::Incoming, Packet::Publish, QoS}; use serde_json::Value; use crate::config::Config; pub fn main(argv0: &str, config: Config, device_name: &str, mut args: ArgsOs) { let (Some(action_filter), Some(command)) = (args.next(), args.next()) else { eprintln!("Usage: {argv0} device on-action "); process::exit(1); }; let args: Box<[OsString]> = args.collect(); let Ok(action_filter) = action_filter.into_string() else { eprintln!("{argv0}: error: Invalid action-filter"); process::exit(1); }; let (client, mut connection) = config.mqtt_client(); let device_topic = format!("zigbee2mqtt/{device_name}"); client.subscribe(&device_topic, QoS::AtLeastOnce).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 parsed["action"] == action_filter { let mut c = Command::new(&command); c.args(&args); let status = c.status().expect("Unable to execute command"); match status.code() { Some(code) => { if code != 0 { eprintln!("command exited with: {code}"); } } None => { eprintln!("command was killed by a signal: {status:?}"); } } } } } _ => (), } } }