1use crate::tlv;
7use anyhow;
8use serde_json;
9
10
11pub fn decode_max_pressure(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<i16>> {
15 if let tlv::TlvItemValue::Int(v) = inp {
16 Ok(Some(*v as i16))
17 } else {
18 Ok(None)
19 }
20}
21
22pub fn decode_max_speed(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u16>> {
24 if let tlv::TlvItemValue::Int(v) = inp {
25 Ok(Some(*v as u16))
26 } else {
27 Ok(None)
28 }
29}
30
31pub fn decode_max_flow(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u16>> {
33 if let tlv::TlvItemValue::Int(v) = inp {
34 Ok(Some(*v as u16))
35 } else {
36 Ok(None)
37 }
38}
39
40pub fn decode_min_const_pressure(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<i16>> {
42 if let tlv::TlvItemValue::Int(v) = inp {
43 Ok(Some(*v as i16))
44 } else {
45 Ok(None)
46 }
47}
48
49pub fn decode_max_const_pressure(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<i16>> {
51 if let tlv::TlvItemValue::Int(v) = inp {
52 Ok(Some(*v as i16))
53 } else {
54 Ok(None)
55 }
56}
57
58pub fn decode_min_comp_pressure(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<i16>> {
60 if let tlv::TlvItemValue::Int(v) = inp {
61 Ok(Some(*v as i16))
62 } else {
63 Ok(None)
64 }
65}
66
67pub fn decode_max_comp_pressure(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<i16>> {
69 if let tlv::TlvItemValue::Int(v) = inp {
70 Ok(Some(*v as i16))
71 } else {
72 Ok(None)
73 }
74}
75
76pub fn decode_min_const_speed(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u16>> {
78 if let tlv::TlvItemValue::Int(v) = inp {
79 Ok(Some(*v as u16))
80 } else {
81 Ok(None)
82 }
83}
84
85pub fn decode_max_const_speed(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u16>> {
87 if let tlv::TlvItemValue::Int(v) = inp {
88 Ok(Some(*v as u16))
89 } else {
90 Ok(None)
91 }
92}
93
94pub fn decode_min_const_flow(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u16>> {
96 if let tlv::TlvItemValue::Int(v) = inp {
97 Ok(Some(*v as u16))
98 } else {
99 Ok(None)
100 }
101}
102
103pub fn decode_max_const_flow(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u16>> {
105 if let tlv::TlvItemValue::Int(v) = inp {
106 Ok(Some(*v as u16))
107 } else {
108 Ok(None)
109 }
110}
111
112pub fn decode_min_const_temp(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<i16>> {
114 if let tlv::TlvItemValue::Int(v) = inp {
115 Ok(Some(*v as i16))
116 } else {
117 Ok(None)
118 }
119}
120
121pub fn decode_max_const_temp(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<i16>> {
123 if let tlv::TlvItemValue::Int(v) = inp {
124 Ok(Some(*v as i16))
125 } else {
126 Ok(None)
127 }
128}
129
130pub fn decode_pump_status(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
132 if let tlv::TlvItemValue::Int(v) = inp {
133 Ok(*v as u8)
134 } else {
135 Err(anyhow::anyhow!("Expected Integer"))
136 }
137}
138
139pub fn decode_effective_operation_mode(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
141 if let tlv::TlvItemValue::Int(v) = inp {
142 Ok(*v as u8)
143 } else {
144 Err(anyhow::anyhow!("Expected Integer"))
145 }
146}
147
148pub fn decode_effective_control_mode(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
150 if let tlv::TlvItemValue::Int(v) = inp {
151 Ok(*v as u8)
152 } else {
153 Err(anyhow::anyhow!("Expected Integer"))
154 }
155}
156
157pub fn decode_capacity(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<i16>> {
159 if let tlv::TlvItemValue::Int(v) = inp {
160 Ok(Some(*v as i16))
161 } else {
162 Ok(None)
163 }
164}
165
166pub fn decode_speed(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u16>> {
168 if let tlv::TlvItemValue::Int(v) = inp {
169 Ok(Some(*v as u16))
170 } else {
171 Ok(None)
172 }
173}
174
175pub fn decode_lifetime_running_hours(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
177 if let tlv::TlvItemValue::Int(v) = inp {
178 Ok(Some(*v as u8))
179 } else {
180 Ok(None)
181 }
182}
183
184pub fn decode_power(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
186 if let tlv::TlvItemValue::Int(v) = inp {
187 Ok(Some(*v as u8))
188 } else {
189 Ok(None)
190 }
191}
192
193pub fn decode_lifetime_energy_consumed(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u32>> {
195 if let tlv::TlvItemValue::Int(v) = inp {
196 Ok(Some(*v as u32))
197 } else {
198 Ok(None)
199 }
200}
201
202pub fn decode_operation_mode(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
204 if let tlv::TlvItemValue::Int(v) = inp {
205 Ok(*v as u8)
206 } else {
207 Err(anyhow::anyhow!("Expected Integer"))
208 }
209}
210
211pub fn decode_control_mode(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
213 if let tlv::TlvItemValue::Int(v) = inp {
214 Ok(*v as u8)
215 } else {
216 Err(anyhow::anyhow!("Expected Integer"))
217 }
218}
219
220pub fn decode_alarm_mask(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
222 if let tlv::TlvItemValue::Int(v) = inp {
223 Ok(*v as u8)
224 } else {
225 Err(anyhow::anyhow!("Expected Integer"))
226 }
227}
228
229
230pub fn decode_attribute_json(cluster_id: u32, attribute_id: u32, tlv_value: &crate::tlv::TlvItemValue) -> String {
242 if cluster_id != 0x0200 {
244 return format!("{{\"error\": \"Invalid cluster ID. Expected 0x0200, got {}\"}}", cluster_id);
245 }
246
247 match attribute_id {
248 0x0000 => {
249 match decode_max_pressure(tlv_value) {
250 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
251 Err(e) => format!("{{\"error\": \"{}\"}}", e),
252 }
253 }
254 0x0001 => {
255 match decode_max_speed(tlv_value) {
256 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
257 Err(e) => format!("{{\"error\": \"{}\"}}", e),
258 }
259 }
260 0x0002 => {
261 match decode_max_flow(tlv_value) {
262 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
263 Err(e) => format!("{{\"error\": \"{}\"}}", e),
264 }
265 }
266 0x0003 => {
267 match decode_min_const_pressure(tlv_value) {
268 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
269 Err(e) => format!("{{\"error\": \"{}\"}}", e),
270 }
271 }
272 0x0004 => {
273 match decode_max_const_pressure(tlv_value) {
274 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
275 Err(e) => format!("{{\"error\": \"{}\"}}", e),
276 }
277 }
278 0x0005 => {
279 match decode_min_comp_pressure(tlv_value) {
280 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
281 Err(e) => format!("{{\"error\": \"{}\"}}", e),
282 }
283 }
284 0x0006 => {
285 match decode_max_comp_pressure(tlv_value) {
286 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
287 Err(e) => format!("{{\"error\": \"{}\"}}", e),
288 }
289 }
290 0x0007 => {
291 match decode_min_const_speed(tlv_value) {
292 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
293 Err(e) => format!("{{\"error\": \"{}\"}}", e),
294 }
295 }
296 0x0008 => {
297 match decode_max_const_speed(tlv_value) {
298 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
299 Err(e) => format!("{{\"error\": \"{}\"}}", e),
300 }
301 }
302 0x0009 => {
303 match decode_min_const_flow(tlv_value) {
304 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
305 Err(e) => format!("{{\"error\": \"{}\"}}", e),
306 }
307 }
308 0x000A => {
309 match decode_max_const_flow(tlv_value) {
310 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
311 Err(e) => format!("{{\"error\": \"{}\"}}", e),
312 }
313 }
314 0x000B => {
315 match decode_min_const_temp(tlv_value) {
316 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
317 Err(e) => format!("{{\"error\": \"{}\"}}", e),
318 }
319 }
320 0x000C => {
321 match decode_max_const_temp(tlv_value) {
322 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
323 Err(e) => format!("{{\"error\": \"{}\"}}", e),
324 }
325 }
326 0x0010 => {
327 match decode_pump_status(tlv_value) {
328 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
329 Err(e) => format!("{{\"error\": \"{}\"}}", e),
330 }
331 }
332 0x0011 => {
333 match decode_effective_operation_mode(tlv_value) {
334 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
335 Err(e) => format!("{{\"error\": \"{}\"}}", e),
336 }
337 }
338 0x0012 => {
339 match decode_effective_control_mode(tlv_value) {
340 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
341 Err(e) => format!("{{\"error\": \"{}\"}}", e),
342 }
343 }
344 0x0013 => {
345 match decode_capacity(tlv_value) {
346 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
347 Err(e) => format!("{{\"error\": \"{}\"}}", e),
348 }
349 }
350 0x0014 => {
351 match decode_speed(tlv_value) {
352 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
353 Err(e) => format!("{{\"error\": \"{}\"}}", e),
354 }
355 }
356 0x0015 => {
357 match decode_lifetime_running_hours(tlv_value) {
358 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
359 Err(e) => format!("{{\"error\": \"{}\"}}", e),
360 }
361 }
362 0x0016 => {
363 match decode_power(tlv_value) {
364 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
365 Err(e) => format!("{{\"error\": \"{}\"}}", e),
366 }
367 }
368 0x0017 => {
369 match decode_lifetime_energy_consumed(tlv_value) {
370 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
371 Err(e) => format!("{{\"error\": \"{}\"}}", e),
372 }
373 }
374 0x0020 => {
375 match decode_operation_mode(tlv_value) {
376 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
377 Err(e) => format!("{{\"error\": \"{}\"}}", e),
378 }
379 }
380 0x0021 => {
381 match decode_control_mode(tlv_value) {
382 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
383 Err(e) => format!("{{\"error\": \"{}\"}}", e),
384 }
385 }
386 0x0022 => {
387 match decode_alarm_mask(tlv_value) {
388 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
389 Err(e) => format!("{{\"error\": \"{}\"}}", e),
390 }
391 }
392 _ => format!("{{\"error\": \"Unknown attribute ID: {}\"}}", attribute_id),
393 }
394}
395
396pub fn get_attribute_list() -> Vec<(u32, &'static str)> {
401 vec![
402 (0x0000, "MaxPressure"),
403 (0x0001, "MaxSpeed"),
404 (0x0002, "MaxFlow"),
405 (0x0003, "MinConstPressure"),
406 (0x0004, "MaxConstPressure"),
407 (0x0005, "MinCompPressure"),
408 (0x0006, "MaxCompPressure"),
409 (0x0007, "MinConstSpeed"),
410 (0x0008, "MaxConstSpeed"),
411 (0x0009, "MinConstFlow"),
412 (0x000A, "MaxConstFlow"),
413 (0x000B, "MinConstTemp"),
414 (0x000C, "MaxConstTemp"),
415 (0x0010, "PumpStatus"),
416 (0x0011, "EffectiveOperationMode"),
417 (0x0012, "EffectiveControlMode"),
418 (0x0013, "Capacity"),
419 (0x0014, "Speed"),
420 (0x0015, "LifetimeRunningHours"),
421 (0x0016, "Power"),
422 (0x0017, "LifetimeEnergyConsumed"),
423 (0x0020, "OperationMode"),
424 (0x0021, "ControlMode"),
425 (0x0022, "AlarmMask"),
426 ]
427}
428