summaryrefslogtreecommitdiffstats
path: root/src/device/on_action.rs
diff options
context:
space:
mode:
authorTomasz Kramkowski <tomasz@kramkow.ski>2025-05-03 20:00:17 +0100
committerTomasz Kramkowski <tomasz@kramkow.ski>2025-05-03 20:00:17 +0100
commit6b2711c5703c2b724066c88967c1924f1f1dbedf (patch)
tree4561b0fb47a3429b86e82b19f335b6aed1081e5f /src/device/on_action.rs
downloadz2m-utils-6b2711c5703c2b724066c88967c1924f1f1dbedf.tar.gz
z2m-utils-6b2711c5703c2b724066c88967c1924f1f1dbedf.tar.xz
z2m-utils-6b2711c5703c2b724066c88967c1924f1f1dbedf.zip
basic z2m-utilsHEADmaster
Diffstat (limited to 'src/device/on_action.rs')
-rw-r--r--src/device/on_action.rs54
1 files changed, 54 insertions, 0 deletions
diff --git a/src/device/on_action.rs b/src/device/on_action.rs
new file mode 100644
index 0000000..5425086
--- /dev/null
+++ b/src/device/on_action.rs
@@ -0,0 +1,54 @@
+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 <device-name> on-action <action-filter> <command...>");
+ 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:?}");
+ }
+ }
+ }
+ }
+ }
+ _ => (),
+ }
+ }
+}