matc/clusters/codec/
power_source_cluster.rs

1//! Generated Matter TLV encoders and decoders for Power Source Cluster
2//! Cluster ID: 0x002F
3//! 
4//! This file is automatically generated from PowerSourceCluster.xml
5
6use crate::tlv;
7use anyhow;
8use serde_json;
9
10
11// Attribute decoders
12
13/// Decode Status attribute (0x0000)
14pub fn decode_status(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
15    if let tlv::TlvItemValue::Int(v) = inp {
16        Ok(*v as u8)
17    } else {
18        Err(anyhow::anyhow!("Expected Integer"))
19    }
20}
21
22/// Decode Order attribute (0x0001)
23pub fn decode_order(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
24    if let tlv::TlvItemValue::Int(v) = inp {
25        Ok(*v as u8)
26    } else {
27        Err(anyhow::anyhow!("Expected Integer"))
28    }
29}
30
31/// Decode Description attribute (0x0002)
32pub fn decode_description(inp: &tlv::TlvItemValue) -> anyhow::Result<String> {
33    if let tlv::TlvItemValue::String(v) = inp {
34        Ok(v.clone())
35    } else {
36        Err(anyhow::anyhow!("Expected String"))
37    }
38}
39
40/// Decode WiredAssessedInputVoltage attribute (0x0003)
41pub fn decode_wired_assessed_input_voltage(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u32>> {
42    if let tlv::TlvItemValue::Int(v) = inp {
43        Ok(Some(*v as u32))
44    } else {
45        Ok(None)
46    }
47}
48
49/// Decode WiredAssessedInputFrequency attribute (0x0004)
50pub fn decode_wired_assessed_input_frequency(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u16>> {
51    if let tlv::TlvItemValue::Int(v) = inp {
52        Ok(Some(*v as u16))
53    } else {
54        Ok(None)
55    }
56}
57
58/// Decode WiredCurrentType attribute (0x0005)
59pub fn decode_wired_current_type(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
60    if let tlv::TlvItemValue::Int(v) = inp {
61        Ok(*v as u8)
62    } else {
63        Err(anyhow::anyhow!("Expected Integer"))
64    }
65}
66
67/// Decode WiredAssessedCurrent attribute (0x0006)
68pub fn decode_wired_assessed_current(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u32>> {
69    if let tlv::TlvItemValue::Int(v) = inp {
70        Ok(Some(*v as u32))
71    } else {
72        Ok(None)
73    }
74}
75
76/// Decode WiredNominalVoltage attribute (0x0007)
77pub fn decode_wired_nominal_voltage(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
78    if let tlv::TlvItemValue::Int(v) = inp {
79        Ok(*v as u32)
80    } else {
81        Err(anyhow::anyhow!("Expected Integer"))
82    }
83}
84
85/// Decode WiredMaximumCurrent attribute (0x0008)
86pub fn decode_wired_maximum_current(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
87    if let tlv::TlvItemValue::Int(v) = inp {
88        Ok(*v as u32)
89    } else {
90        Err(anyhow::anyhow!("Expected Integer"))
91    }
92}
93
94/// Decode WiredPresent attribute (0x0009)
95pub fn decode_wired_present(inp: &tlv::TlvItemValue) -> anyhow::Result<bool> {
96    if let tlv::TlvItemValue::Bool(v) = inp {
97        Ok(*v)
98    } else {
99        Err(anyhow::anyhow!("Expected Bool"))
100    }
101}
102
103/// Decode ActiveWiredFaults attribute (0x000A)
104pub fn decode_active_wired_faults(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<u8>> {
105    let mut res = Vec::new();
106    if let tlv::TlvItemValue::List(v) = inp {
107        for item in v {
108            if let tlv::TlvItemValue::Int(i) = &item.value {
109                res.push(*i as u8);
110            }
111        }
112    }
113    Ok(res)
114}
115
116/// Decode BatVoltage attribute (0x000B)
117pub fn decode_bat_voltage(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u32>> {
118    if let tlv::TlvItemValue::Int(v) = inp {
119        Ok(Some(*v as u32))
120    } else {
121        Ok(None)
122    }
123}
124
125/// Decode BatPercentRemaining attribute (0x000C)
126pub fn decode_bat_percent_remaining(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
127    if let tlv::TlvItemValue::Int(v) = inp {
128        Ok(Some(*v as u8))
129    } else {
130        Ok(None)
131    }
132}
133
134/// Decode BatTimeRemaining attribute (0x000D)
135pub fn decode_bat_time_remaining(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u32>> {
136    if let tlv::TlvItemValue::Int(v) = inp {
137        Ok(Some(*v as u32))
138    } else {
139        Ok(None)
140    }
141}
142
143/// Decode BatChargeLevel attribute (0x000E)
144pub fn decode_bat_charge_level(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
145    if let tlv::TlvItemValue::Int(v) = inp {
146        Ok(*v as u8)
147    } else {
148        Err(anyhow::anyhow!("Expected Integer"))
149    }
150}
151
152/// Decode BatReplacementNeeded attribute (0x000F)
153pub fn decode_bat_replacement_needed(inp: &tlv::TlvItemValue) -> anyhow::Result<bool> {
154    if let tlv::TlvItemValue::Bool(v) = inp {
155        Ok(*v)
156    } else {
157        Err(anyhow::anyhow!("Expected Bool"))
158    }
159}
160
161/// Decode BatReplaceability attribute (0x0010)
162pub fn decode_bat_replaceability(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
163    if let tlv::TlvItemValue::Int(v) = inp {
164        Ok(*v as u8)
165    } else {
166        Err(anyhow::anyhow!("Expected Integer"))
167    }
168}
169
170/// Decode BatPresent attribute (0x0011)
171pub fn decode_bat_present(inp: &tlv::TlvItemValue) -> anyhow::Result<bool> {
172    if let tlv::TlvItemValue::Bool(v) = inp {
173        Ok(*v)
174    } else {
175        Err(anyhow::anyhow!("Expected Bool"))
176    }
177}
178
179/// Decode ActiveBatFaults attribute (0x0012)
180pub fn decode_active_bat_faults(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<u8>> {
181    let mut res = Vec::new();
182    if let tlv::TlvItemValue::List(v) = inp {
183        for item in v {
184            if let tlv::TlvItemValue::Int(i) = &item.value {
185                res.push(*i as u8);
186            }
187        }
188    }
189    Ok(res)
190}
191
192/// Decode BatReplacementDescription attribute (0x0013)
193pub fn decode_bat_replacement_description(inp: &tlv::TlvItemValue) -> anyhow::Result<String> {
194    if let tlv::TlvItemValue::String(v) = inp {
195        Ok(v.clone())
196    } else {
197        Err(anyhow::anyhow!("Expected String"))
198    }
199}
200
201/// Decode BatCommonDesignation attribute (0x0014)
202pub fn decode_bat_common_designation(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
203    if let tlv::TlvItemValue::Int(v) = inp {
204        Ok(*v as u8)
205    } else {
206        Err(anyhow::anyhow!("Expected Integer"))
207    }
208}
209
210/// Decode BatANSIDesignation attribute (0x0015)
211pub fn decode_bat_ansi_designation(inp: &tlv::TlvItemValue) -> anyhow::Result<String> {
212    if let tlv::TlvItemValue::String(v) = inp {
213        Ok(v.clone())
214    } else {
215        Err(anyhow::anyhow!("Expected String"))
216    }
217}
218
219/// Decode BatIECDesignation attribute (0x0016)
220pub fn decode_bat_iec_designation(inp: &tlv::TlvItemValue) -> anyhow::Result<String> {
221    if let tlv::TlvItemValue::String(v) = inp {
222        Ok(v.clone())
223    } else {
224        Err(anyhow::anyhow!("Expected String"))
225    }
226}
227
228/// Decode BatApprovedChemistry attribute (0x0017)
229pub fn decode_bat_approved_chemistry(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
230    if let tlv::TlvItemValue::Int(v) = inp {
231        Ok(*v as u8)
232    } else {
233        Err(anyhow::anyhow!("Expected Integer"))
234    }
235}
236
237/// Decode BatCapacity attribute (0x0018)
238pub fn decode_bat_capacity(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
239    if let tlv::TlvItemValue::Int(v) = inp {
240        Ok(*v as u32)
241    } else {
242        Err(anyhow::anyhow!("Expected Integer"))
243    }
244}
245
246/// Decode BatQuantity attribute (0x0019)
247pub fn decode_bat_quantity(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
248    if let tlv::TlvItemValue::Int(v) = inp {
249        Ok(*v as u8)
250    } else {
251        Err(anyhow::anyhow!("Expected Integer"))
252    }
253}
254
255/// Decode BatChargeState attribute (0x001A)
256pub fn decode_bat_charge_state(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
257    if let tlv::TlvItemValue::Int(v) = inp {
258        Ok(*v as u8)
259    } else {
260        Err(anyhow::anyhow!("Expected Integer"))
261    }
262}
263
264/// Decode BatTimeToFullCharge attribute (0x001B)
265pub fn decode_bat_time_to_full_charge(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u32>> {
266    if let tlv::TlvItemValue::Int(v) = inp {
267        Ok(Some(*v as u32))
268    } else {
269        Ok(None)
270    }
271}
272
273/// Decode BatFunctionalWhileCharging attribute (0x001C)
274pub fn decode_bat_functional_while_charging(inp: &tlv::TlvItemValue) -> anyhow::Result<bool> {
275    if let tlv::TlvItemValue::Bool(v) = inp {
276        Ok(*v)
277    } else {
278        Err(anyhow::anyhow!("Expected Bool"))
279    }
280}
281
282/// Decode BatChargingCurrent attribute (0x001D)
283pub fn decode_bat_charging_current(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u32>> {
284    if let tlv::TlvItemValue::Int(v) = inp {
285        Ok(Some(*v as u32))
286    } else {
287        Ok(None)
288    }
289}
290
291/// Decode ActiveBatChargeFaults attribute (0x001E)
292pub fn decode_active_bat_charge_faults(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<u8>> {
293    let mut res = Vec::new();
294    if let tlv::TlvItemValue::List(v) = inp {
295        for item in v {
296            if let tlv::TlvItemValue::Int(i) = &item.value {
297                res.push(*i as u8);
298            }
299        }
300    }
301    Ok(res)
302}
303
304/// Decode EndpointList attribute (0x001F)
305pub fn decode_endpoint_list(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<u16>> {
306    let mut res = Vec::new();
307    if let tlv::TlvItemValue::List(v) = inp {
308        for item in v {
309            if let tlv::TlvItemValue::Int(i) = &item.value {
310                res.push(*i as u16);
311            }
312        }
313    }
314    Ok(res)
315}
316
317
318// JSON dispatcher function
319
320/// Decode attribute value and return as JSON string
321/// 
322/// # Parameters
323/// * `cluster_id` - The cluster identifier
324/// * `attribute_id` - The attribute identifier
325/// * `tlv_value` - The TLV value to decode
326/// 
327/// # Returns
328/// JSON string representation of the decoded value or error
329pub fn decode_attribute_json(cluster_id: u32, attribute_id: u32, tlv_value: &crate::tlv::TlvItemValue) -> String {
330    // Verify this is the correct cluster
331    if cluster_id != 0x002F {
332        return format!("{{\"error\": \"Invalid cluster ID. Expected 0x002F, got {}\"}}", cluster_id);
333    }
334    
335    match attribute_id {
336        0x0000 => {
337            match decode_status(tlv_value) {
338                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
339                Err(e) => format!("{{\"error\": \"{}\"}}", e),
340            }
341        }
342        0x0001 => {
343            match decode_order(tlv_value) {
344                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
345                Err(e) => format!("{{\"error\": \"{}\"}}", e),
346            }
347        }
348        0x0002 => {
349            match decode_description(tlv_value) {
350                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
351                Err(e) => format!("{{\"error\": \"{}\"}}", e),
352            }
353        }
354        0x0003 => {
355            match decode_wired_assessed_input_voltage(tlv_value) {
356                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
357                Err(e) => format!("{{\"error\": \"{}\"}}", e),
358            }
359        }
360        0x0004 => {
361            match decode_wired_assessed_input_frequency(tlv_value) {
362                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
363                Err(e) => format!("{{\"error\": \"{}\"}}", e),
364            }
365        }
366        0x0005 => {
367            match decode_wired_current_type(tlv_value) {
368                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
369                Err(e) => format!("{{\"error\": \"{}\"}}", e),
370            }
371        }
372        0x0006 => {
373            match decode_wired_assessed_current(tlv_value) {
374                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
375                Err(e) => format!("{{\"error\": \"{}\"}}", e),
376            }
377        }
378        0x0007 => {
379            match decode_wired_nominal_voltage(tlv_value) {
380                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
381                Err(e) => format!("{{\"error\": \"{}\"}}", e),
382            }
383        }
384        0x0008 => {
385            match decode_wired_maximum_current(tlv_value) {
386                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
387                Err(e) => format!("{{\"error\": \"{}\"}}", e),
388            }
389        }
390        0x0009 => {
391            match decode_wired_present(tlv_value) {
392                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
393                Err(e) => format!("{{\"error\": \"{}\"}}", e),
394            }
395        }
396        0x000A => {
397            match decode_active_wired_faults(tlv_value) {
398                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
399                Err(e) => format!("{{\"error\": \"{}\"}}", e),
400            }
401        }
402        0x000B => {
403            match decode_bat_voltage(tlv_value) {
404                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
405                Err(e) => format!("{{\"error\": \"{}\"}}", e),
406            }
407        }
408        0x000C => {
409            match decode_bat_percent_remaining(tlv_value) {
410                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
411                Err(e) => format!("{{\"error\": \"{}\"}}", e),
412            }
413        }
414        0x000D => {
415            match decode_bat_time_remaining(tlv_value) {
416                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
417                Err(e) => format!("{{\"error\": \"{}\"}}", e),
418            }
419        }
420        0x000E => {
421            match decode_bat_charge_level(tlv_value) {
422                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
423                Err(e) => format!("{{\"error\": \"{}\"}}", e),
424            }
425        }
426        0x000F => {
427            match decode_bat_replacement_needed(tlv_value) {
428                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
429                Err(e) => format!("{{\"error\": \"{}\"}}", e),
430            }
431        }
432        0x0010 => {
433            match decode_bat_replaceability(tlv_value) {
434                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
435                Err(e) => format!("{{\"error\": \"{}\"}}", e),
436            }
437        }
438        0x0011 => {
439            match decode_bat_present(tlv_value) {
440                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
441                Err(e) => format!("{{\"error\": \"{}\"}}", e),
442            }
443        }
444        0x0012 => {
445            match decode_active_bat_faults(tlv_value) {
446                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
447                Err(e) => format!("{{\"error\": \"{}\"}}", e),
448            }
449        }
450        0x0013 => {
451            match decode_bat_replacement_description(tlv_value) {
452                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
453                Err(e) => format!("{{\"error\": \"{}\"}}", e),
454            }
455        }
456        0x0014 => {
457            match decode_bat_common_designation(tlv_value) {
458                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
459                Err(e) => format!("{{\"error\": \"{}\"}}", e),
460            }
461        }
462        0x0015 => {
463            match decode_bat_ansi_designation(tlv_value) {
464                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
465                Err(e) => format!("{{\"error\": \"{}\"}}", e),
466            }
467        }
468        0x0016 => {
469            match decode_bat_iec_designation(tlv_value) {
470                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
471                Err(e) => format!("{{\"error\": \"{}\"}}", e),
472            }
473        }
474        0x0017 => {
475            match decode_bat_approved_chemistry(tlv_value) {
476                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
477                Err(e) => format!("{{\"error\": \"{}\"}}", e),
478            }
479        }
480        0x0018 => {
481            match decode_bat_capacity(tlv_value) {
482                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
483                Err(e) => format!("{{\"error\": \"{}\"}}", e),
484            }
485        }
486        0x0019 => {
487            match decode_bat_quantity(tlv_value) {
488                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
489                Err(e) => format!("{{\"error\": \"{}\"}}", e),
490            }
491        }
492        0x001A => {
493            match decode_bat_charge_state(tlv_value) {
494                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
495                Err(e) => format!("{{\"error\": \"{}\"}}", e),
496            }
497        }
498        0x001B => {
499            match decode_bat_time_to_full_charge(tlv_value) {
500                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
501                Err(e) => format!("{{\"error\": \"{}\"}}", e),
502            }
503        }
504        0x001C => {
505            match decode_bat_functional_while_charging(tlv_value) {
506                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
507                Err(e) => format!("{{\"error\": \"{}\"}}", e),
508            }
509        }
510        0x001D => {
511            match decode_bat_charging_current(tlv_value) {
512                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
513                Err(e) => format!("{{\"error\": \"{}\"}}", e),
514            }
515        }
516        0x001E => {
517            match decode_active_bat_charge_faults(tlv_value) {
518                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
519                Err(e) => format!("{{\"error\": \"{}\"}}", e),
520            }
521        }
522        0x001F => {
523            match decode_endpoint_list(tlv_value) {
524                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
525                Err(e) => format!("{{\"error\": \"{}\"}}", e),
526            }
527        }
528        _ => format!("{{\"error\": \"Unknown attribute ID: {}\"}}", attribute_id),
529    }
530}
531
532/// Get list of all attributes supported by this cluster
533/// 
534/// # Returns
535/// Vector of tuples containing (attribute_id, attribute_name)
536pub fn get_attribute_list() -> Vec<(u32, &'static str)> {
537    vec![
538        (0x0000, "Status"),
539        (0x0001, "Order"),
540        (0x0002, "Description"),
541        (0x0003, "WiredAssessedInputVoltage"),
542        (0x0004, "WiredAssessedInputFrequency"),
543        (0x0005, "WiredCurrentType"),
544        (0x0006, "WiredAssessedCurrent"),
545        (0x0007, "WiredNominalVoltage"),
546        (0x0008, "WiredMaximumCurrent"),
547        (0x0009, "WiredPresent"),
548        (0x000A, "ActiveWiredFaults"),
549        (0x000B, "BatVoltage"),
550        (0x000C, "BatPercentRemaining"),
551        (0x000D, "BatTimeRemaining"),
552        (0x000E, "BatChargeLevel"),
553        (0x000F, "BatReplacementNeeded"),
554        (0x0010, "BatReplaceability"),
555        (0x0011, "BatPresent"),
556        (0x0012, "ActiveBatFaults"),
557        (0x0013, "BatReplacementDescription"),
558        (0x0014, "BatCommonDesignation"),
559        (0x0015, "BatANSIDesignation"),
560        (0x0016, "BatIECDesignation"),
561        (0x0017, "BatApprovedChemistry"),
562        (0x0018, "BatCapacity"),
563        (0x0019, "BatQuantity"),
564        (0x001A, "BatChargeState"),
565        (0x001B, "BatTimeToFullCharge"),
566        (0x001C, "BatFunctionalWhileCharging"),
567        (0x001D, "BatChargingCurrent"),
568        (0x001E, "ActiveBatChargeFaults"),
569        (0x001F, "EndpointList"),
570    ]
571}
572