matc/clusters/codec/
valve_configuration_control.rs1use crate::tlv;
7use anyhow;
8use serde_json;
9
10
11pub fn encode_open(open_duration: Option<u8>, target_level: u8) -> anyhow::Result<Vec<u8>> {
15 let tlv = tlv::TlvItemEnc {
16 tag: 0,
17 value: tlv::TlvItemValueEnc::StructInvisible(vec![
18 (0, tlv::TlvItemValueEnc::UInt8(open_duration.unwrap_or(0))).into(),
19 (1, tlv::TlvItemValueEnc::UInt8(target_level)).into(),
20 ]),
21 };
22 Ok(tlv.encode()?)
23}
24
25pub fn decode_open_duration(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
29 if let tlv::TlvItemValue::Int(v) = inp {
30 Ok(Some(*v as u8))
31 } else {
32 Ok(None)
33 }
34}
35
36pub fn decode_default_open_duration(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
38 if let tlv::TlvItemValue::Int(v) = inp {
39 Ok(Some(*v as u8))
40 } else {
41 Ok(None)
42 }
43}
44
45pub fn decode_auto_close_time(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
47 if let tlv::TlvItemValue::Int(v) = inp {
48 Ok(Some(*v as u8))
49 } else {
50 Ok(None)
51 }
52}
53
54pub fn decode_remaining_duration(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
56 if let tlv::TlvItemValue::Int(v) = inp {
57 Ok(Some(*v as u8))
58 } else {
59 Ok(None)
60 }
61}
62
63pub fn decode_current_state(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
65 if let tlv::TlvItemValue::Int(v) = inp {
66 Ok(Some(*v as u8))
67 } else {
68 Ok(None)
69 }
70}
71
72pub fn decode_target_state(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
74 if let tlv::TlvItemValue::Int(v) = inp {
75 Ok(Some(*v as u8))
76 } else {
77 Ok(None)
78 }
79}
80
81pub fn decode_current_level(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
83 if let tlv::TlvItemValue::Int(v) = inp {
84 Ok(Some(*v as u8))
85 } else {
86 Ok(None)
87 }
88}
89
90pub fn decode_target_level(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
92 if let tlv::TlvItemValue::Int(v) = inp {
93 Ok(Some(*v as u8))
94 } else {
95 Ok(None)
96 }
97}
98
99pub fn decode_default_open_level(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
101 if let tlv::TlvItemValue::Int(v) = inp {
102 Ok(*v as u8)
103 } else {
104 Err(anyhow::anyhow!("Expected Integer"))
105 }
106}
107
108pub fn decode_valve_fault(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
110 if let tlv::TlvItemValue::Int(v) = inp {
111 Ok(*v as u8)
112 } else {
113 Err(anyhow::anyhow!("Expected Integer"))
114 }
115}
116
117pub fn decode_level_step(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
119 if let tlv::TlvItemValue::Int(v) = inp {
120 Ok(*v as u8)
121 } else {
122 Err(anyhow::anyhow!("Expected Integer"))
123 }
124}
125
126
127pub fn decode_attribute_json(cluster_id: u32, attribute_id: u32, tlv_value: &crate::tlv::TlvItemValue) -> String {
139 if cluster_id != 0x0081 {
141 return format!("{{\"error\": \"Invalid cluster ID. Expected 0x0081, got {}\"}}", cluster_id);
142 }
143
144 match attribute_id {
145 0x0000 => {
146 match decode_open_duration(tlv_value) {
147 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
148 Err(e) => format!("{{\"error\": \"{}\"}}", e),
149 }
150 }
151 0x0001 => {
152 match decode_default_open_duration(tlv_value) {
153 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
154 Err(e) => format!("{{\"error\": \"{}\"}}", e),
155 }
156 }
157 0x0002 => {
158 match decode_auto_close_time(tlv_value) {
159 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
160 Err(e) => format!("{{\"error\": \"{}\"}}", e),
161 }
162 }
163 0x0003 => {
164 match decode_remaining_duration(tlv_value) {
165 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
166 Err(e) => format!("{{\"error\": \"{}\"}}", e),
167 }
168 }
169 0x0004 => {
170 match decode_current_state(tlv_value) {
171 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
172 Err(e) => format!("{{\"error\": \"{}\"}}", e),
173 }
174 }
175 0x0005 => {
176 match decode_target_state(tlv_value) {
177 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
178 Err(e) => format!("{{\"error\": \"{}\"}}", e),
179 }
180 }
181 0x0006 => {
182 match decode_current_level(tlv_value) {
183 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
184 Err(e) => format!("{{\"error\": \"{}\"}}", e),
185 }
186 }
187 0x0007 => {
188 match decode_target_level(tlv_value) {
189 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
190 Err(e) => format!("{{\"error\": \"{}\"}}", e),
191 }
192 }
193 0x0008 => {
194 match decode_default_open_level(tlv_value) {
195 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
196 Err(e) => format!("{{\"error\": \"{}\"}}", e),
197 }
198 }
199 0x0009 => {
200 match decode_valve_fault(tlv_value) {
201 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
202 Err(e) => format!("{{\"error\": \"{}\"}}", e),
203 }
204 }
205 0x000A => {
206 match decode_level_step(tlv_value) {
207 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
208 Err(e) => format!("{{\"error\": \"{}\"}}", e),
209 }
210 }
211 _ => format!("{{\"error\": \"Unknown attribute ID: {}\"}}", attribute_id),
212 }
213}
214
215pub fn get_attribute_list() -> Vec<(u32, &'static str)> {
220 vec![
221 (0x0000, "OpenDuration"),
222 (0x0001, "DefaultOpenDuration"),
223 (0x0002, "AutoCloseTime"),
224 (0x0003, "RemainingDuration"),
225 (0x0004, "CurrentState"),
226 (0x0005, "TargetState"),
227 (0x0006, "CurrentLevel"),
228 (0x0007, "TargetLevel"),
229 (0x0008, "DefaultOpenLevel"),
230 (0x0009, "ValveFault"),
231 (0x000A, "LevelStep"),
232 ]
233}
234