1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
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;
}
}
}
_ => (),
}
}
}
|