matc/clusters/codec/
on_off.rs1use crate::tlv;
7use anyhow;
8use serde_json;
9
10
11pub fn encode_off_with_effect(effect_identifier: u8, effect_variant: u8) -> anyhow::Result<Vec<u8>> {
15 let tlv = tlv::TlvItemEnc {
16 tag: 0,
17 value: tlv::TlvItemValueEnc::StructInvisible(vec![
18 (0, tlv::TlvItemValueEnc::UInt8(effect_identifier)).into(),
19 (1, tlv::TlvItemValueEnc::UInt8(effect_variant)).into(),
20 ]),
21 };
22 Ok(tlv.encode()?)
23}
24
25pub fn encode_on_with_timed_off(on_off_control: u8, on_time: u16, off_wait_time: u16) -> anyhow::Result<Vec<u8>> {
27 let tlv = tlv::TlvItemEnc {
28 tag: 0,
29 value: tlv::TlvItemValueEnc::StructInvisible(vec![
30 (0, tlv::TlvItemValueEnc::UInt8(on_off_control)).into(),
31 (1, tlv::TlvItemValueEnc::UInt16(on_time)).into(),
32 (2, tlv::TlvItemValueEnc::UInt16(off_wait_time)).into(),
33 ]),
34 };
35 Ok(tlv.encode()?)
36}
37
38pub fn decode_on_off(inp: &tlv::TlvItemValue) -> anyhow::Result<bool> {
42 if let tlv::TlvItemValue::Bool(v) = inp {
43 Ok(*v)
44 } else {
45 Err(anyhow::anyhow!("Expected Bool"))
46 }
47}
48
49pub fn decode_global_scene_control(inp: &tlv::TlvItemValue) -> anyhow::Result<bool> {
51 if let tlv::TlvItemValue::Bool(v) = inp {
52 Ok(*v)
53 } else {
54 Err(anyhow::anyhow!("Expected Bool"))
55 }
56}
57
58pub fn decode_on_time(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
60 if let tlv::TlvItemValue::Int(v) = inp {
61 Ok(*v as u16)
62 } else {
63 Err(anyhow::anyhow!("Expected Integer"))
64 }
65}
66
67pub fn decode_off_wait_time(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
69 if let tlv::TlvItemValue::Int(v) = inp {
70 Ok(*v as u16)
71 } else {
72 Err(anyhow::anyhow!("Expected Integer"))
73 }
74}
75
76pub fn decode_start_up_on_off(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
78 if let tlv::TlvItemValue::Int(v) = inp {
79 Ok(Some(*v as u8))
80 } else {
81 Ok(None)
82 }
83}
84
85
86pub fn decode_attribute_json(cluster_id: u32, attribute_id: u32, tlv_value: &crate::tlv::TlvItemValue) -> String {
98 if cluster_id != 0x0006 {
100 return format!("{{\"error\": \"Invalid cluster ID. Expected 0x0006, got {}\"}}", cluster_id);
101 }
102
103 match attribute_id {
104 0x0000 => {
105 match decode_on_off(tlv_value) {
106 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
107 Err(e) => format!("{{\"error\": \"{}\"}}", e),
108 }
109 }
110 0x4000 => {
111 match decode_global_scene_control(tlv_value) {
112 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
113 Err(e) => format!("{{\"error\": \"{}\"}}", e),
114 }
115 }
116 0x4001 => {
117 match decode_on_time(tlv_value) {
118 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
119 Err(e) => format!("{{\"error\": \"{}\"}}", e),
120 }
121 }
122 0x4002 => {
123 match decode_off_wait_time(tlv_value) {
124 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
125 Err(e) => format!("{{\"error\": \"{}\"}}", e),
126 }
127 }
128 0x4003 => {
129 match decode_start_up_on_off(tlv_value) {
130 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
131 Err(e) => format!("{{\"error\": \"{}\"}}", e),
132 }
133 }
134 _ => format!("{{\"error\": \"Unknown attribute ID: {}\"}}", attribute_id),
135 }
136}
137
138pub fn get_attribute_list() -> Vec<(u32, &'static str)> {
143 vec![
144 (0x0000, "OnOff"),
145 (0x4000, "GlobalSceneControl"),
146 (0x4001, "OnTime"),
147 (0x4002, "OffWaitTime"),
148 (0x4003, "StartUpOnOff"),
149 ]
150}
151