matc/clusters/codec/
power_source_cluster.rs

1//! Matter TLV encoders and decoders for Power Source Cluster
2//! Cluster ID: 0x002F
3//!
4//! This file is automatically generated from PowerSourceCluster.xml
5
6#![allow(clippy::too_many_arguments)]
7
8use crate::tlv;
9use anyhow;
10use serde_json;
11
12
13// Enum definitions
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
16#[repr(u8)]
17pub enum BatApprovedChemistry {
18    /// Cell chemistry is unspecified or unknown
19    Unspecified = 0,
20    /// Cell chemistry is alkaline
21    Alkaline = 1,
22    /// Cell chemistry is lithium carbon fluoride
23    Lithiumcarbonfluoride = 2,
24    /// Cell chemistry is lithium chromium oxide
25    Lithiumchromiumoxide = 3,
26    /// Cell chemistry is lithium copper oxide
27    Lithiumcopperoxide = 4,
28    /// Cell chemistry is lithium iron disulfide
29    Lithiumirondisulfide = 5,
30    /// Cell chemistry is lithium manganese dioxide
31    Lithiummanganesedioxide = 6,
32    /// Cell chemistry is lithium thionyl chloride
33    Lithiumthionylchloride = 7,
34    /// Cell chemistry is magnesium
35    Magnesium = 8,
36    /// Cell chemistry is mercury oxide
37    Mercuryoxide = 9,
38    /// Cell chemistry is nickel oxyhydride
39    Nickeloxyhydride = 10,
40    /// Cell chemistry is silver oxide
41    Silveroxide = 11,
42    /// Cell chemistry is zinc air
43    Zincair = 12,
44    /// Cell chemistry is zinc carbon
45    Zinccarbon = 13,
46    /// Cell chemistry is zinc chloride
47    Zincchloride = 14,
48    /// Cell chemistry is zinc manganese dioxide
49    Zincmanganesedioxide = 15,
50    /// Cell chemistry is lead acid
51    Leadacid = 16,
52    /// Cell chemistry is lithium cobalt oxide
53    Lithiumcobaltoxide = 17,
54    /// Cell chemistry is lithium ion
55    Lithiumion = 18,
56    /// Cell chemistry is lithium ion polymer
57    Lithiumionpolymer = 19,
58    /// Cell chemistry is lithium iron phosphate
59    Lithiumironphosphate = 20,
60    /// Cell chemistry is lithium sulfur
61    Lithiumsulfur = 21,
62    /// Cell chemistry is lithium titanate
63    Lithiumtitanate = 22,
64    /// Cell chemistry is nickel cadmium
65    Nickelcadmium = 23,
66    /// Cell chemistry is nickel hydrogen
67    Nickelhydrogen = 24,
68    /// Cell chemistry is nickel iron
69    Nickeliron = 25,
70    /// Cell chemistry is nickel metal hydride
71    Nickelmetalhydride = 26,
72    /// Cell chemistry is nickel zinc
73    Nickelzinc = 27,
74    /// Cell chemistry is silver zinc
75    Silverzinc = 28,
76    /// Cell chemistry is sodium ion
77    Sodiumion = 29,
78    /// Cell chemistry is sodium sulfur
79    Sodiumsulfur = 30,
80    /// Cell chemistry is zinc bromide
81    Zincbromide = 31,
82    /// Cell chemistry is zinc cerium
83    Zinccerium = 32,
84}
85
86impl BatApprovedChemistry {
87    /// Convert from u8 value
88    pub fn from_u8(value: u8) -> Option<Self> {
89        match value {
90            0 => Some(BatApprovedChemistry::Unspecified),
91            1 => Some(BatApprovedChemistry::Alkaline),
92            2 => Some(BatApprovedChemistry::Lithiumcarbonfluoride),
93            3 => Some(BatApprovedChemistry::Lithiumchromiumoxide),
94            4 => Some(BatApprovedChemistry::Lithiumcopperoxide),
95            5 => Some(BatApprovedChemistry::Lithiumirondisulfide),
96            6 => Some(BatApprovedChemistry::Lithiummanganesedioxide),
97            7 => Some(BatApprovedChemistry::Lithiumthionylchloride),
98            8 => Some(BatApprovedChemistry::Magnesium),
99            9 => Some(BatApprovedChemistry::Mercuryoxide),
100            10 => Some(BatApprovedChemistry::Nickeloxyhydride),
101            11 => Some(BatApprovedChemistry::Silveroxide),
102            12 => Some(BatApprovedChemistry::Zincair),
103            13 => Some(BatApprovedChemistry::Zinccarbon),
104            14 => Some(BatApprovedChemistry::Zincchloride),
105            15 => Some(BatApprovedChemistry::Zincmanganesedioxide),
106            16 => Some(BatApprovedChemistry::Leadacid),
107            17 => Some(BatApprovedChemistry::Lithiumcobaltoxide),
108            18 => Some(BatApprovedChemistry::Lithiumion),
109            19 => Some(BatApprovedChemistry::Lithiumionpolymer),
110            20 => Some(BatApprovedChemistry::Lithiumironphosphate),
111            21 => Some(BatApprovedChemistry::Lithiumsulfur),
112            22 => Some(BatApprovedChemistry::Lithiumtitanate),
113            23 => Some(BatApprovedChemistry::Nickelcadmium),
114            24 => Some(BatApprovedChemistry::Nickelhydrogen),
115            25 => Some(BatApprovedChemistry::Nickeliron),
116            26 => Some(BatApprovedChemistry::Nickelmetalhydride),
117            27 => Some(BatApprovedChemistry::Nickelzinc),
118            28 => Some(BatApprovedChemistry::Silverzinc),
119            29 => Some(BatApprovedChemistry::Sodiumion),
120            30 => Some(BatApprovedChemistry::Sodiumsulfur),
121            31 => Some(BatApprovedChemistry::Zincbromide),
122            32 => Some(BatApprovedChemistry::Zinccerium),
123            _ => None,
124        }
125    }
126
127    /// Convert to u8 value
128    pub fn to_u8(self) -> u8 {
129        self as u8
130    }
131}
132
133impl From<BatApprovedChemistry> for u8 {
134    fn from(val: BatApprovedChemistry) -> Self {
135        val as u8
136    }
137}
138
139#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
140#[repr(u8)]
141pub enum BatChargeFault {
142    /// The Node detects an unspecified fault on this battery source.
143    Unspecified = 0,
144    /// The Node detects the ambient temperature is above the nominal range for this battery source.
145    Ambienttoohot = 1,
146    /// The Node detects the ambient temperature is below the nominal range for this battery source.
147    Ambienttoocold = 2,
148    /// The Node detects the temperature of this battery source is above the nominal range.
149    Batterytoohot = 3,
150    /// The Node detects the temperature of this battery source is below the nominal range.
151    Batterytoocold = 4,
152    /// The Node detects this battery source is not present.
153    Batteryabsent = 5,
154    /// The Node detects this battery source is over voltage.
155    Batteryovervoltage = 6,
156    /// The Node detects this battery source is under voltage.
157    Batteryundervoltage = 7,
158    /// The Node detects the charger for this battery source is over voltage.
159    Chargerovervoltage = 8,
160    /// The Node detects the charger for this battery source is under voltage.
161    Chargerundervoltage = 9,
162    /// The Node detects a charging safety timeout for this battery source.
163    Safetytimeout = 10,
164}
165
166impl BatChargeFault {
167    /// Convert from u8 value
168    pub fn from_u8(value: u8) -> Option<Self> {
169        match value {
170            0 => Some(BatChargeFault::Unspecified),
171            1 => Some(BatChargeFault::Ambienttoohot),
172            2 => Some(BatChargeFault::Ambienttoocold),
173            3 => Some(BatChargeFault::Batterytoohot),
174            4 => Some(BatChargeFault::Batterytoocold),
175            5 => Some(BatChargeFault::Batteryabsent),
176            6 => Some(BatChargeFault::Batteryovervoltage),
177            7 => Some(BatChargeFault::Batteryundervoltage),
178            8 => Some(BatChargeFault::Chargerovervoltage),
179            9 => Some(BatChargeFault::Chargerundervoltage),
180            10 => Some(BatChargeFault::Safetytimeout),
181            _ => None,
182        }
183    }
184
185    /// Convert to u8 value
186    pub fn to_u8(self) -> u8 {
187        self as u8
188    }
189}
190
191impl From<BatChargeFault> for u8 {
192    fn from(val: BatChargeFault) -> Self {
193        val as u8
194    }
195}
196
197#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
198#[repr(u8)]
199pub enum BatChargeLevel {
200    /// Charge level is nominal
201    Ok = 0,
202    /// Charge level is low, intervention may soon be required.
203    Warning = 1,
204    /// Charge level is critical, immediate intervention is required
205    Critical = 2,
206}
207
208impl BatChargeLevel {
209    /// Convert from u8 value
210    pub fn from_u8(value: u8) -> Option<Self> {
211        match value {
212            0 => Some(BatChargeLevel::Ok),
213            1 => Some(BatChargeLevel::Warning),
214            2 => Some(BatChargeLevel::Critical),
215            _ => None,
216        }
217    }
218
219    /// Convert to u8 value
220    pub fn to_u8(self) -> u8 {
221        self as u8
222    }
223}
224
225impl From<BatChargeLevel> for u8 {
226    fn from(val: BatChargeLevel) -> Self {
227        val as u8
228    }
229}
230
231#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
232#[repr(u8)]
233pub enum BatChargeState {
234    /// Unable to determine the charging state
235    Unknown = 0,
236    /// The battery is charging
237    Ischarging = 1,
238    /// The battery is at full charge
239    Isatfullcharge = 2,
240    /// The battery is not charging
241    Isnotcharging = 3,
242}
243
244impl BatChargeState {
245    /// Convert from u8 value
246    pub fn from_u8(value: u8) -> Option<Self> {
247        match value {
248            0 => Some(BatChargeState::Unknown),
249            1 => Some(BatChargeState::Ischarging),
250            2 => Some(BatChargeState::Isatfullcharge),
251            3 => Some(BatChargeState::Isnotcharging),
252            _ => None,
253        }
254    }
255
256    /// Convert to u8 value
257    pub fn to_u8(self) -> u8 {
258        self as u8
259    }
260}
261
262impl From<BatChargeState> for u8 {
263    fn from(val: BatChargeState) -> Self {
264        val as u8
265    }
266}
267
268#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
269#[repr(u8)]
270pub enum BatCommonDesignation {
271    /// Common type is unknown or unspecified
272    Unspecified = 0,
273    /// Common type is as specified
274    Aaa = 1,
275    /// Common type is as specified
276    Aa = 2,
277    /// Common type is as specified
278    C = 3,
279    /// Common type is as specified
280    D = 4,
281    /// Common type is as specified
282    _4v5 = 5,
283    /// Common type is as specified
284    _6v0 = 6,
285    /// Common type is as specified
286    _9v0 = 7,
287    /// Common type is as specified
288    _12aa = 8,
289    /// Common type is as specified
290    Aaaa = 9,
291    /// Common type is as specified
292    A = 10,
293    /// Common type is as specified
294    B = 11,
295    /// Common type is as specified
296    F = 12,
297    /// Common type is as specified
298    N = 13,
299    /// Common type is as specified
300    No6 = 14,
301    /// Common type is as specified
302    Subc = 15,
303    /// Common type is as specified
304    A23 = 16,
305    /// Common type is as specified
306    A27 = 17,
307    /// Common type is as specified
308    Ba5800 = 18,
309    /// Common type is as specified
310    Duplex = 19,
311    /// Common type is as specified
312    _4sr44 = 20,
313    /// Common type is as specified
314    _523 = 21,
315    /// Common type is as specified
316    _531 = 22,
317    /// Common type is as specified
318    _15v0 = 23,
319    /// Common type is as specified
320    _22v5 = 24,
321    /// Common type is as specified
322    _30v0 = 25,
323    /// Common type is as specified
324    _45v0 = 26,
325    /// Common type is as specified
326    _67v5 = 27,
327    /// Common type is as specified
328    J = 28,
329    /// Common type is as specified
330    Cr123a = 29,
331    /// Common type is as specified
332    Cr2 = 30,
333    /// Common type is as specified
334    _2cr5 = 31,
335    /// Common type is as specified
336    CrP2 = 32,
337    /// Common type is as specified
338    CrV3 = 33,
339    /// Common type is as specified
340    Sr41 = 34,
341    /// Common type is as specified
342    Sr43 = 35,
343    /// Common type is as specified
344    Sr44 = 36,
345    /// Common type is as specified
346    Sr45 = 37,
347    /// Common type is as specified
348    Sr48 = 38,
349    /// Common type is as specified
350    Sr54 = 39,
351    /// Common type is as specified
352    Sr55 = 40,
353    /// Common type is as specified
354    Sr57 = 41,
355    /// Common type is as specified
356    Sr58 = 42,
357    /// Common type is as specified
358    Sr59 = 43,
359    /// Common type is as specified
360    Sr60 = 44,
361    /// Common type is as specified
362    Sr63 = 45,
363    /// Common type is as specified
364    Sr64 = 46,
365    /// Common type is as specified
366    Sr65 = 47,
367    /// Common type is as specified
368    Sr66 = 48,
369    /// Common type is as specified
370    Sr67 = 49,
371    /// Common type is as specified
372    Sr68 = 50,
373    /// Common type is as specified
374    Sr69 = 51,
375    /// Common type is as specified
376    Sr516 = 52,
377    /// Common type is as specified
378    Sr731 = 53,
379    /// Common type is as specified
380    Sr712 = 54,
381    /// Common type is as specified
382    Lr932 = 55,
383    /// Common type is as specified
384    A5 = 56,
385    /// Common type is as specified
386    A10 = 57,
387    /// Common type is as specified
388    A13 = 58,
389    /// Common type is as specified
390    A312 = 59,
391    /// Common type is as specified
392    A675 = 60,
393    /// Common type is as specified
394    Ac41e = 61,
395    /// Common type is as specified
396    _10180 = 62,
397    /// Common type is as specified
398    _10280 = 63,
399    /// Common type is as specified
400    _10440 = 64,
401    /// Common type is as specified
402    _14250 = 65,
403    /// Common type is as specified
404    _14430 = 66,
405    /// Common type is as specified
406    _14500 = 67,
407    /// Common type is as specified
408    _14650 = 68,
409    /// Common type is as specified
410    _15270 = 69,
411    /// Common type is as specified
412    _16340 = 70,
413    /// Common type is as specified
414    Rcr123a = 71,
415    /// Common type is as specified
416    _17500 = 72,
417    /// Common type is as specified
418    _17670 = 73,
419    /// Common type is as specified
420    _18350 = 74,
421    /// Common type is as specified
422    _18500 = 75,
423    /// Common type is as specified
424    _18650 = 76,
425    /// Common type is as specified
426    _19670 = 77,
427    /// Common type is as specified
428    _25500 = 78,
429    /// Common type is as specified
430    _26650 = 79,
431    /// Common type is as specified
432    _32600 = 80,
433}
434
435impl BatCommonDesignation {
436    /// Convert from u8 value
437    pub fn from_u8(value: u8) -> Option<Self> {
438        match value {
439            0 => Some(BatCommonDesignation::Unspecified),
440            1 => Some(BatCommonDesignation::Aaa),
441            2 => Some(BatCommonDesignation::Aa),
442            3 => Some(BatCommonDesignation::C),
443            4 => Some(BatCommonDesignation::D),
444            5 => Some(BatCommonDesignation::_4v5),
445            6 => Some(BatCommonDesignation::_6v0),
446            7 => Some(BatCommonDesignation::_9v0),
447            8 => Some(BatCommonDesignation::_12aa),
448            9 => Some(BatCommonDesignation::Aaaa),
449            10 => Some(BatCommonDesignation::A),
450            11 => Some(BatCommonDesignation::B),
451            12 => Some(BatCommonDesignation::F),
452            13 => Some(BatCommonDesignation::N),
453            14 => Some(BatCommonDesignation::No6),
454            15 => Some(BatCommonDesignation::Subc),
455            16 => Some(BatCommonDesignation::A23),
456            17 => Some(BatCommonDesignation::A27),
457            18 => Some(BatCommonDesignation::Ba5800),
458            19 => Some(BatCommonDesignation::Duplex),
459            20 => Some(BatCommonDesignation::_4sr44),
460            21 => Some(BatCommonDesignation::_523),
461            22 => Some(BatCommonDesignation::_531),
462            23 => Some(BatCommonDesignation::_15v0),
463            24 => Some(BatCommonDesignation::_22v5),
464            25 => Some(BatCommonDesignation::_30v0),
465            26 => Some(BatCommonDesignation::_45v0),
466            27 => Some(BatCommonDesignation::_67v5),
467            28 => Some(BatCommonDesignation::J),
468            29 => Some(BatCommonDesignation::Cr123a),
469            30 => Some(BatCommonDesignation::Cr2),
470            31 => Some(BatCommonDesignation::_2cr5),
471            32 => Some(BatCommonDesignation::CrP2),
472            33 => Some(BatCommonDesignation::CrV3),
473            34 => Some(BatCommonDesignation::Sr41),
474            35 => Some(BatCommonDesignation::Sr43),
475            36 => Some(BatCommonDesignation::Sr44),
476            37 => Some(BatCommonDesignation::Sr45),
477            38 => Some(BatCommonDesignation::Sr48),
478            39 => Some(BatCommonDesignation::Sr54),
479            40 => Some(BatCommonDesignation::Sr55),
480            41 => Some(BatCommonDesignation::Sr57),
481            42 => Some(BatCommonDesignation::Sr58),
482            43 => Some(BatCommonDesignation::Sr59),
483            44 => Some(BatCommonDesignation::Sr60),
484            45 => Some(BatCommonDesignation::Sr63),
485            46 => Some(BatCommonDesignation::Sr64),
486            47 => Some(BatCommonDesignation::Sr65),
487            48 => Some(BatCommonDesignation::Sr66),
488            49 => Some(BatCommonDesignation::Sr67),
489            50 => Some(BatCommonDesignation::Sr68),
490            51 => Some(BatCommonDesignation::Sr69),
491            52 => Some(BatCommonDesignation::Sr516),
492            53 => Some(BatCommonDesignation::Sr731),
493            54 => Some(BatCommonDesignation::Sr712),
494            55 => Some(BatCommonDesignation::Lr932),
495            56 => Some(BatCommonDesignation::A5),
496            57 => Some(BatCommonDesignation::A10),
497            58 => Some(BatCommonDesignation::A13),
498            59 => Some(BatCommonDesignation::A312),
499            60 => Some(BatCommonDesignation::A675),
500            61 => Some(BatCommonDesignation::Ac41e),
501            62 => Some(BatCommonDesignation::_10180),
502            63 => Some(BatCommonDesignation::_10280),
503            64 => Some(BatCommonDesignation::_10440),
504            65 => Some(BatCommonDesignation::_14250),
505            66 => Some(BatCommonDesignation::_14430),
506            67 => Some(BatCommonDesignation::_14500),
507            68 => Some(BatCommonDesignation::_14650),
508            69 => Some(BatCommonDesignation::_15270),
509            70 => Some(BatCommonDesignation::_16340),
510            71 => Some(BatCommonDesignation::Rcr123a),
511            72 => Some(BatCommonDesignation::_17500),
512            73 => Some(BatCommonDesignation::_17670),
513            74 => Some(BatCommonDesignation::_18350),
514            75 => Some(BatCommonDesignation::_18500),
515            76 => Some(BatCommonDesignation::_18650),
516            77 => Some(BatCommonDesignation::_19670),
517            78 => Some(BatCommonDesignation::_25500),
518            79 => Some(BatCommonDesignation::_26650),
519            80 => Some(BatCommonDesignation::_32600),
520            _ => None,
521        }
522    }
523
524    /// Convert to u8 value
525    pub fn to_u8(self) -> u8 {
526        self as u8
527    }
528}
529
530impl From<BatCommonDesignation> for u8 {
531    fn from(val: BatCommonDesignation) -> Self {
532        val as u8
533    }
534}
535
536#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
537#[repr(u8)]
538pub enum BatFault {
539    /// The Node detects an unspecified fault on this battery power source.
540    Unspecified = 0,
541    /// The Node detects the temperature of this battery power source is above ideal operating conditions.
542    Overtemp = 1,
543    /// The Node detects the temperature of this battery power source is below ideal operating conditions.
544    Undertemp = 2,
545}
546
547impl BatFault {
548    /// Convert from u8 value
549    pub fn from_u8(value: u8) -> Option<Self> {
550        match value {
551            0 => Some(BatFault::Unspecified),
552            1 => Some(BatFault::Overtemp),
553            2 => Some(BatFault::Undertemp),
554            _ => None,
555        }
556    }
557
558    /// Convert to u8 value
559    pub fn to_u8(self) -> u8 {
560        self as u8
561    }
562}
563
564impl From<BatFault> for u8 {
565    fn from(val: BatFault) -> Self {
566        val as u8
567    }
568}
569
570#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
571#[repr(u8)]
572pub enum BatReplaceability {
573    /// The replaceability is unspecified or unknown.
574    Unspecified = 0,
575    /// The battery is not replaceable.
576    Notreplaceable = 1,
577    /// The battery is replaceable by the user or customer.
578    Userreplaceable = 2,
579    /// The battery is replaceable by an authorized factory technician.
580    Factoryreplaceable = 3,
581}
582
583impl BatReplaceability {
584    /// Convert from u8 value
585    pub fn from_u8(value: u8) -> Option<Self> {
586        match value {
587            0 => Some(BatReplaceability::Unspecified),
588            1 => Some(BatReplaceability::Notreplaceable),
589            2 => Some(BatReplaceability::Userreplaceable),
590            3 => Some(BatReplaceability::Factoryreplaceable),
591            _ => None,
592        }
593    }
594
595    /// Convert to u8 value
596    pub fn to_u8(self) -> u8 {
597        self as u8
598    }
599}
600
601impl From<BatReplaceability> for u8 {
602    fn from(val: BatReplaceability) -> Self {
603        val as u8
604    }
605}
606
607#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
608#[repr(u8)]
609pub enum PowerSourceStatus {
610    /// Indicate the source status is not specified
611    Unspecified = 0,
612    /// Indicate the source is available and currently supplying power
613    Active = 1,
614    /// Indicate the source is available, but is not currently supplying power
615    Standby = 2,
616    /// Indicate the source is not currently available to supply power
617    Unavailable = 3,
618}
619
620impl PowerSourceStatus {
621    /// Convert from u8 value
622    pub fn from_u8(value: u8) -> Option<Self> {
623        match value {
624            0 => Some(PowerSourceStatus::Unspecified),
625            1 => Some(PowerSourceStatus::Active),
626            2 => Some(PowerSourceStatus::Standby),
627            3 => Some(PowerSourceStatus::Unavailable),
628            _ => None,
629        }
630    }
631
632    /// Convert to u8 value
633    pub fn to_u8(self) -> u8 {
634        self as u8
635    }
636}
637
638impl From<PowerSourceStatus> for u8 {
639    fn from(val: PowerSourceStatus) -> Self {
640        val as u8
641    }
642}
643
644#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
645#[repr(u8)]
646pub enum WiredCurrentType {
647    /// Indicates AC current
648    Ac = 0,
649    /// Indicates DC current
650    Dc = 1,
651}
652
653impl WiredCurrentType {
654    /// Convert from u8 value
655    pub fn from_u8(value: u8) -> Option<Self> {
656        match value {
657            0 => Some(WiredCurrentType::Ac),
658            1 => Some(WiredCurrentType::Dc),
659            _ => None,
660        }
661    }
662
663    /// Convert to u8 value
664    pub fn to_u8(self) -> u8 {
665        self as u8
666    }
667}
668
669impl From<WiredCurrentType> for u8 {
670    fn from(val: WiredCurrentType) -> Self {
671        val as u8
672    }
673}
674
675#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
676#[repr(u8)]
677pub enum WiredFault {
678    /// The Node detects an unspecified fault on this wired power source.
679    Unspecified = 0,
680    /// The Node detects the supplied voltage is above maximum supported value for this wired power source.
681    Overvoltage = 1,
682    /// The Node detects the supplied voltage is below maximum supported value for this wired power source.
683    Undervoltage = 2,
684}
685
686impl WiredFault {
687    /// Convert from u8 value
688    pub fn from_u8(value: u8) -> Option<Self> {
689        match value {
690            0 => Some(WiredFault::Unspecified),
691            1 => Some(WiredFault::Overvoltage),
692            2 => Some(WiredFault::Undervoltage),
693            _ => None,
694        }
695    }
696
697    /// Convert to u8 value
698    pub fn to_u8(self) -> u8 {
699        self as u8
700    }
701}
702
703impl From<WiredFault> for u8 {
704    fn from(val: WiredFault) -> Self {
705        val as u8
706    }
707}
708
709// Attribute decoders
710
711/// Decode Status attribute (0x0000)
712pub fn decode_status(inp: &tlv::TlvItemValue) -> anyhow::Result<PowerSourceStatus> {
713    if let tlv::TlvItemValue::Int(v) = inp {
714        PowerSourceStatus::from_u8(*v as u8).ok_or_else(|| anyhow::anyhow!("Invalid enum value"))
715    } else {
716        Err(anyhow::anyhow!("Expected Integer"))
717    }
718}
719
720/// Decode Order attribute (0x0001)
721pub fn decode_order(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
722    if let tlv::TlvItemValue::Int(v) = inp {
723        Ok(*v as u8)
724    } else {
725        Err(anyhow::anyhow!("Expected UInt8"))
726    }
727}
728
729/// Decode Description attribute (0x0002)
730pub fn decode_description(inp: &tlv::TlvItemValue) -> anyhow::Result<String> {
731    if let tlv::TlvItemValue::String(v) = inp {
732        Ok(v.clone())
733    } else {
734        Err(anyhow::anyhow!("Expected String"))
735    }
736}
737
738/// Decode WiredAssessedInputVoltage attribute (0x0003)
739pub fn decode_wired_assessed_input_voltage(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u32>> {
740    if let tlv::TlvItemValue::Int(v) = inp {
741        Ok(Some(*v as u32))
742    } else {
743        Ok(None)
744    }
745}
746
747/// Decode WiredAssessedInputFrequency attribute (0x0004)
748pub fn decode_wired_assessed_input_frequency(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u16>> {
749    if let tlv::TlvItemValue::Int(v) = inp {
750        Ok(Some(*v as u16))
751    } else {
752        Ok(None)
753    }
754}
755
756/// Decode WiredCurrentType attribute (0x0005)
757pub fn decode_wired_current_type(inp: &tlv::TlvItemValue) -> anyhow::Result<WiredCurrentType> {
758    if let tlv::TlvItemValue::Int(v) = inp {
759        WiredCurrentType::from_u8(*v as u8).ok_or_else(|| anyhow::anyhow!("Invalid enum value"))
760    } else {
761        Err(anyhow::anyhow!("Expected Integer"))
762    }
763}
764
765/// Decode WiredAssessedCurrent attribute (0x0006)
766pub fn decode_wired_assessed_current(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u32>> {
767    if let tlv::TlvItemValue::Int(v) = inp {
768        Ok(Some(*v as u32))
769    } else {
770        Ok(None)
771    }
772}
773
774/// Decode WiredNominalVoltage attribute (0x0007)
775pub fn decode_wired_nominal_voltage(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
776    if let tlv::TlvItemValue::Int(v) = inp {
777        Ok(*v as u32)
778    } else {
779        Err(anyhow::anyhow!("Expected UInt32"))
780    }
781}
782
783/// Decode WiredMaximumCurrent attribute (0x0008)
784pub fn decode_wired_maximum_current(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
785    if let tlv::TlvItemValue::Int(v) = inp {
786        Ok(*v as u32)
787    } else {
788        Err(anyhow::anyhow!("Expected UInt32"))
789    }
790}
791
792/// Decode WiredPresent attribute (0x0009)
793pub fn decode_wired_present(inp: &tlv::TlvItemValue) -> anyhow::Result<bool> {
794    if let tlv::TlvItemValue::Bool(v) = inp {
795        Ok(*v)
796    } else {
797        Err(anyhow::anyhow!("Expected Bool"))
798    }
799}
800
801/// Decode ActiveWiredFaults attribute (0x000A)
802pub fn decode_active_wired_faults(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<WiredFault>> {
803    let mut res = Vec::new();
804    if let tlv::TlvItemValue::List(v) = inp {
805        for item in v {
806            if let tlv::TlvItemValue::Int(i) = &item.value {
807                if let Some(enum_val) = WiredFault::from_u8(*i as u8) {
808                    res.push(enum_val);
809                }
810            }
811        }
812    }
813    Ok(res)
814}
815
816/// Decode BatVoltage attribute (0x000B)
817pub fn decode_bat_voltage(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u32>> {
818    if let tlv::TlvItemValue::Int(v) = inp {
819        Ok(Some(*v as u32))
820    } else {
821        Ok(None)
822    }
823}
824
825/// Decode BatPercentRemaining attribute (0x000C)
826pub fn decode_bat_percent_remaining(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
827    if let tlv::TlvItemValue::Int(v) = inp {
828        Ok(Some(*v as u8))
829    } else {
830        Ok(None)
831    }
832}
833
834/// Decode BatTimeRemaining attribute (0x000D)
835pub fn decode_bat_time_remaining(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u32>> {
836    if let tlv::TlvItemValue::Int(v) = inp {
837        Ok(Some(*v as u32))
838    } else {
839        Ok(None)
840    }
841}
842
843/// Decode BatChargeLevel attribute (0x000E)
844pub fn decode_bat_charge_level(inp: &tlv::TlvItemValue) -> anyhow::Result<BatChargeLevel> {
845    if let tlv::TlvItemValue::Int(v) = inp {
846        BatChargeLevel::from_u8(*v as u8).ok_or_else(|| anyhow::anyhow!("Invalid enum value"))
847    } else {
848        Err(anyhow::anyhow!("Expected Integer"))
849    }
850}
851
852/// Decode BatReplacementNeeded attribute (0x000F)
853pub fn decode_bat_replacement_needed(inp: &tlv::TlvItemValue) -> anyhow::Result<bool> {
854    if let tlv::TlvItemValue::Bool(v) = inp {
855        Ok(*v)
856    } else {
857        Err(anyhow::anyhow!("Expected Bool"))
858    }
859}
860
861/// Decode BatReplaceability attribute (0x0010)
862pub fn decode_bat_replaceability(inp: &tlv::TlvItemValue) -> anyhow::Result<BatReplaceability> {
863    if let tlv::TlvItemValue::Int(v) = inp {
864        BatReplaceability::from_u8(*v as u8).ok_or_else(|| anyhow::anyhow!("Invalid enum value"))
865    } else {
866        Err(anyhow::anyhow!("Expected Integer"))
867    }
868}
869
870/// Decode BatPresent attribute (0x0011)
871pub fn decode_bat_present(inp: &tlv::TlvItemValue) -> anyhow::Result<bool> {
872    if let tlv::TlvItemValue::Bool(v) = inp {
873        Ok(*v)
874    } else {
875        Err(anyhow::anyhow!("Expected Bool"))
876    }
877}
878
879/// Decode ActiveBatFaults attribute (0x0012)
880pub fn decode_active_bat_faults(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<BatFault>> {
881    let mut res = Vec::new();
882    if let tlv::TlvItemValue::List(v) = inp {
883        for item in v {
884            if let tlv::TlvItemValue::Int(i) = &item.value {
885                if let Some(enum_val) = BatFault::from_u8(*i as u8) {
886                    res.push(enum_val);
887                }
888            }
889        }
890    }
891    Ok(res)
892}
893
894/// Decode BatReplacementDescription attribute (0x0013)
895pub fn decode_bat_replacement_description(inp: &tlv::TlvItemValue) -> anyhow::Result<String> {
896    if let tlv::TlvItemValue::String(v) = inp {
897        Ok(v.clone())
898    } else {
899        Err(anyhow::anyhow!("Expected String"))
900    }
901}
902
903/// Decode BatCommonDesignation attribute (0x0014)
904pub fn decode_bat_common_designation(inp: &tlv::TlvItemValue) -> anyhow::Result<BatCommonDesignation> {
905    if let tlv::TlvItemValue::Int(v) = inp {
906        BatCommonDesignation::from_u8(*v as u8).ok_or_else(|| anyhow::anyhow!("Invalid enum value"))
907    } else {
908        Err(anyhow::anyhow!("Expected Integer"))
909    }
910}
911
912/// Decode BatANSIDesignation attribute (0x0015)
913pub fn decode_bat_ansi_designation(inp: &tlv::TlvItemValue) -> anyhow::Result<String> {
914    if let tlv::TlvItemValue::String(v) = inp {
915        Ok(v.clone())
916    } else {
917        Err(anyhow::anyhow!("Expected String"))
918    }
919}
920
921/// Decode BatIECDesignation attribute (0x0016)
922pub fn decode_bat_iec_designation(inp: &tlv::TlvItemValue) -> anyhow::Result<String> {
923    if let tlv::TlvItemValue::String(v) = inp {
924        Ok(v.clone())
925    } else {
926        Err(anyhow::anyhow!("Expected String"))
927    }
928}
929
930/// Decode BatApprovedChemistry attribute (0x0017)
931pub fn decode_bat_approved_chemistry(inp: &tlv::TlvItemValue) -> anyhow::Result<BatApprovedChemistry> {
932    if let tlv::TlvItemValue::Int(v) = inp {
933        BatApprovedChemistry::from_u8(*v as u8).ok_or_else(|| anyhow::anyhow!("Invalid enum value"))
934    } else {
935        Err(anyhow::anyhow!("Expected Integer"))
936    }
937}
938
939/// Decode BatCapacity attribute (0x0018)
940pub fn decode_bat_capacity(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
941    if let tlv::TlvItemValue::Int(v) = inp {
942        Ok(*v as u32)
943    } else {
944        Err(anyhow::anyhow!("Expected UInt32"))
945    }
946}
947
948/// Decode BatQuantity attribute (0x0019)
949pub fn decode_bat_quantity(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
950    if let tlv::TlvItemValue::Int(v) = inp {
951        Ok(*v as u8)
952    } else {
953        Err(anyhow::anyhow!("Expected UInt8"))
954    }
955}
956
957/// Decode BatChargeState attribute (0x001A)
958pub fn decode_bat_charge_state(inp: &tlv::TlvItemValue) -> anyhow::Result<BatChargeState> {
959    if let tlv::TlvItemValue::Int(v) = inp {
960        BatChargeState::from_u8(*v as u8).ok_or_else(|| anyhow::anyhow!("Invalid enum value"))
961    } else {
962        Err(anyhow::anyhow!("Expected Integer"))
963    }
964}
965
966/// Decode BatTimeToFullCharge attribute (0x001B)
967pub fn decode_bat_time_to_full_charge(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u32>> {
968    if let tlv::TlvItemValue::Int(v) = inp {
969        Ok(Some(*v as u32))
970    } else {
971        Ok(None)
972    }
973}
974
975/// Decode BatFunctionalWhileCharging attribute (0x001C)
976pub fn decode_bat_functional_while_charging(inp: &tlv::TlvItemValue) -> anyhow::Result<bool> {
977    if let tlv::TlvItemValue::Bool(v) = inp {
978        Ok(*v)
979    } else {
980        Err(anyhow::anyhow!("Expected Bool"))
981    }
982}
983
984/// Decode BatChargingCurrent attribute (0x001D)
985pub fn decode_bat_charging_current(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u32>> {
986    if let tlv::TlvItemValue::Int(v) = inp {
987        Ok(Some(*v as u32))
988    } else {
989        Ok(None)
990    }
991}
992
993/// Decode ActiveBatChargeFaults attribute (0x001E)
994pub fn decode_active_bat_charge_faults(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<BatChargeFault>> {
995    let mut res = Vec::new();
996    if let tlv::TlvItemValue::List(v) = inp {
997        for item in v {
998            if let tlv::TlvItemValue::Int(i) = &item.value {
999                if let Some(enum_val) = BatChargeFault::from_u8(*i as u8) {
1000                    res.push(enum_val);
1001                }
1002            }
1003        }
1004    }
1005    Ok(res)
1006}
1007
1008/// Decode EndpointList attribute (0x001F)
1009pub fn decode_endpoint_list(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<u16>> {
1010    let mut res = Vec::new();
1011    if let tlv::TlvItemValue::List(v) = inp {
1012        for item in v {
1013            if let tlv::TlvItemValue::Int(i) = &item.value {
1014                res.push(*i as u16);
1015            }
1016        }
1017    }
1018    Ok(res)
1019}
1020
1021
1022// JSON dispatcher function
1023
1024/// Decode attribute value and return as JSON string
1025///
1026/// # Parameters
1027/// * `cluster_id` - The cluster identifier
1028/// * `attribute_id` - The attribute identifier
1029/// * `tlv_value` - The TLV value to decode
1030///
1031/// # Returns
1032/// JSON string representation of the decoded value or error
1033pub fn decode_attribute_json(cluster_id: u32, attribute_id: u32, tlv_value: &crate::tlv::TlvItemValue) -> String {
1034    // Verify this is the correct cluster
1035    if cluster_id != 0x002F {
1036        return format!("{{\"error\": \"Invalid cluster ID. Expected 0x002F, got {}\"}}", cluster_id);
1037    }
1038
1039    match attribute_id {
1040        0x0000 => {
1041            match decode_status(tlv_value) {
1042                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1043                Err(e) => format!("{{\"error\": \"{}\"}}", e),
1044            }
1045        }
1046        0x0001 => {
1047            match decode_order(tlv_value) {
1048                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1049                Err(e) => format!("{{\"error\": \"{}\"}}", e),
1050            }
1051        }
1052        0x0002 => {
1053            match decode_description(tlv_value) {
1054                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1055                Err(e) => format!("{{\"error\": \"{}\"}}", e),
1056            }
1057        }
1058        0x0003 => {
1059            match decode_wired_assessed_input_voltage(tlv_value) {
1060                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1061                Err(e) => format!("{{\"error\": \"{}\"}}", e),
1062            }
1063        }
1064        0x0004 => {
1065            match decode_wired_assessed_input_frequency(tlv_value) {
1066                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1067                Err(e) => format!("{{\"error\": \"{}\"}}", e),
1068            }
1069        }
1070        0x0005 => {
1071            match decode_wired_current_type(tlv_value) {
1072                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1073                Err(e) => format!("{{\"error\": \"{}\"}}", e),
1074            }
1075        }
1076        0x0006 => {
1077            match decode_wired_assessed_current(tlv_value) {
1078                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1079                Err(e) => format!("{{\"error\": \"{}\"}}", e),
1080            }
1081        }
1082        0x0007 => {
1083            match decode_wired_nominal_voltage(tlv_value) {
1084                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1085                Err(e) => format!("{{\"error\": \"{}\"}}", e),
1086            }
1087        }
1088        0x0008 => {
1089            match decode_wired_maximum_current(tlv_value) {
1090                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1091                Err(e) => format!("{{\"error\": \"{}\"}}", e),
1092            }
1093        }
1094        0x0009 => {
1095            match decode_wired_present(tlv_value) {
1096                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1097                Err(e) => format!("{{\"error\": \"{}\"}}", e),
1098            }
1099        }
1100        0x000A => {
1101            match decode_active_wired_faults(tlv_value) {
1102                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1103                Err(e) => format!("{{\"error\": \"{}\"}}", e),
1104            }
1105        }
1106        0x000B => {
1107            match decode_bat_voltage(tlv_value) {
1108                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1109                Err(e) => format!("{{\"error\": \"{}\"}}", e),
1110            }
1111        }
1112        0x000C => {
1113            match decode_bat_percent_remaining(tlv_value) {
1114                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1115                Err(e) => format!("{{\"error\": \"{}\"}}", e),
1116            }
1117        }
1118        0x000D => {
1119            match decode_bat_time_remaining(tlv_value) {
1120                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1121                Err(e) => format!("{{\"error\": \"{}\"}}", e),
1122            }
1123        }
1124        0x000E => {
1125            match decode_bat_charge_level(tlv_value) {
1126                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1127                Err(e) => format!("{{\"error\": \"{}\"}}", e),
1128            }
1129        }
1130        0x000F => {
1131            match decode_bat_replacement_needed(tlv_value) {
1132                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1133                Err(e) => format!("{{\"error\": \"{}\"}}", e),
1134            }
1135        }
1136        0x0010 => {
1137            match decode_bat_replaceability(tlv_value) {
1138                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1139                Err(e) => format!("{{\"error\": \"{}\"}}", e),
1140            }
1141        }
1142        0x0011 => {
1143            match decode_bat_present(tlv_value) {
1144                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1145                Err(e) => format!("{{\"error\": \"{}\"}}", e),
1146            }
1147        }
1148        0x0012 => {
1149            match decode_active_bat_faults(tlv_value) {
1150                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1151                Err(e) => format!("{{\"error\": \"{}\"}}", e),
1152            }
1153        }
1154        0x0013 => {
1155            match decode_bat_replacement_description(tlv_value) {
1156                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1157                Err(e) => format!("{{\"error\": \"{}\"}}", e),
1158            }
1159        }
1160        0x0014 => {
1161            match decode_bat_common_designation(tlv_value) {
1162                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1163                Err(e) => format!("{{\"error\": \"{}\"}}", e),
1164            }
1165        }
1166        0x0015 => {
1167            match decode_bat_ansi_designation(tlv_value) {
1168                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1169                Err(e) => format!("{{\"error\": \"{}\"}}", e),
1170            }
1171        }
1172        0x0016 => {
1173            match decode_bat_iec_designation(tlv_value) {
1174                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1175                Err(e) => format!("{{\"error\": \"{}\"}}", e),
1176            }
1177        }
1178        0x0017 => {
1179            match decode_bat_approved_chemistry(tlv_value) {
1180                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1181                Err(e) => format!("{{\"error\": \"{}\"}}", e),
1182            }
1183        }
1184        0x0018 => {
1185            match decode_bat_capacity(tlv_value) {
1186                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1187                Err(e) => format!("{{\"error\": \"{}\"}}", e),
1188            }
1189        }
1190        0x0019 => {
1191            match decode_bat_quantity(tlv_value) {
1192                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1193                Err(e) => format!("{{\"error\": \"{}\"}}", e),
1194            }
1195        }
1196        0x001A => {
1197            match decode_bat_charge_state(tlv_value) {
1198                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1199                Err(e) => format!("{{\"error\": \"{}\"}}", e),
1200            }
1201        }
1202        0x001B => {
1203            match decode_bat_time_to_full_charge(tlv_value) {
1204                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1205                Err(e) => format!("{{\"error\": \"{}\"}}", e),
1206            }
1207        }
1208        0x001C => {
1209            match decode_bat_functional_while_charging(tlv_value) {
1210                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1211                Err(e) => format!("{{\"error\": \"{}\"}}", e),
1212            }
1213        }
1214        0x001D => {
1215            match decode_bat_charging_current(tlv_value) {
1216                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1217                Err(e) => format!("{{\"error\": \"{}\"}}", e),
1218            }
1219        }
1220        0x001E => {
1221            match decode_active_bat_charge_faults(tlv_value) {
1222                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1223                Err(e) => format!("{{\"error\": \"{}\"}}", e),
1224            }
1225        }
1226        0x001F => {
1227            match decode_endpoint_list(tlv_value) {
1228                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1229                Err(e) => format!("{{\"error\": \"{}\"}}", e),
1230            }
1231        }
1232        _ => format!("{{\"error\": \"Unknown attribute ID: {}\"}}", attribute_id),
1233    }
1234}
1235
1236/// Get list of all attributes supported by this cluster
1237///
1238/// # Returns
1239/// Vector of tuples containing (attribute_id, attribute_name)
1240pub fn get_attribute_list() -> Vec<(u32, &'static str)> {
1241    vec![
1242        (0x0000, "Status"),
1243        (0x0001, "Order"),
1244        (0x0002, "Description"),
1245        (0x0003, "WiredAssessedInputVoltage"),
1246        (0x0004, "WiredAssessedInputFrequency"),
1247        (0x0005, "WiredCurrentType"),
1248        (0x0006, "WiredAssessedCurrent"),
1249        (0x0007, "WiredNominalVoltage"),
1250        (0x0008, "WiredMaximumCurrent"),
1251        (0x0009, "WiredPresent"),
1252        (0x000A, "ActiveWiredFaults"),
1253        (0x000B, "BatVoltage"),
1254        (0x000C, "BatPercentRemaining"),
1255        (0x000D, "BatTimeRemaining"),
1256        (0x000E, "BatChargeLevel"),
1257        (0x000F, "BatReplacementNeeded"),
1258        (0x0010, "BatReplaceability"),
1259        (0x0011, "BatPresent"),
1260        (0x0012, "ActiveBatFaults"),
1261        (0x0013, "BatReplacementDescription"),
1262        (0x0014, "BatCommonDesignation"),
1263        (0x0015, "BatANSIDesignation"),
1264        (0x0016, "BatIECDesignation"),
1265        (0x0017, "BatApprovedChemistry"),
1266        (0x0018, "BatCapacity"),
1267        (0x0019, "BatQuantity"),
1268        (0x001A, "BatChargeState"),
1269        (0x001B, "BatTimeToFullCharge"),
1270        (0x001C, "BatFunctionalWhileCharging"),
1271        (0x001D, "BatChargingCurrent"),
1272        (0x001E, "ActiveBatChargeFaults"),
1273        (0x001F, "EndpointList"),
1274    ]
1275}
1276
1277// Typed facade (invokes + reads)
1278
1279/// Read `Status` attribute from cluster `Power Source`.
1280pub async fn read_status(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<PowerSourceStatus> {
1281    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_POWER_SOURCE, crate::clusters::defs::CLUSTER_POWER_SOURCE_ATTR_ID_STATUS).await?;
1282    decode_status(&tlv)
1283}
1284
1285/// Read `Order` attribute from cluster `Power Source`.
1286pub async fn read_order(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u8> {
1287    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_POWER_SOURCE, crate::clusters::defs::CLUSTER_POWER_SOURCE_ATTR_ID_ORDER).await?;
1288    decode_order(&tlv)
1289}
1290
1291/// Read `Description` attribute from cluster `Power Source`.
1292pub async fn read_description(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<String> {
1293    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_POWER_SOURCE, crate::clusters::defs::CLUSTER_POWER_SOURCE_ATTR_ID_DESCRIPTION).await?;
1294    decode_description(&tlv)
1295}
1296
1297/// Read `WiredAssessedInputVoltage` attribute from cluster `Power Source`.
1298pub async fn read_wired_assessed_input_voltage(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Option<u32>> {
1299    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_POWER_SOURCE, crate::clusters::defs::CLUSTER_POWER_SOURCE_ATTR_ID_WIREDASSESSEDINPUTVOLTAGE).await?;
1300    decode_wired_assessed_input_voltage(&tlv)
1301}
1302
1303/// Read `WiredAssessedInputFrequency` attribute from cluster `Power Source`.
1304pub async fn read_wired_assessed_input_frequency(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Option<u16>> {
1305    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_POWER_SOURCE, crate::clusters::defs::CLUSTER_POWER_SOURCE_ATTR_ID_WIREDASSESSEDINPUTFREQUENCY).await?;
1306    decode_wired_assessed_input_frequency(&tlv)
1307}
1308
1309/// Read `WiredCurrentType` attribute from cluster `Power Source`.
1310pub async fn read_wired_current_type(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<WiredCurrentType> {
1311    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_POWER_SOURCE, crate::clusters::defs::CLUSTER_POWER_SOURCE_ATTR_ID_WIREDCURRENTTYPE).await?;
1312    decode_wired_current_type(&tlv)
1313}
1314
1315/// Read `WiredAssessedCurrent` attribute from cluster `Power Source`.
1316pub async fn read_wired_assessed_current(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Option<u32>> {
1317    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_POWER_SOURCE, crate::clusters::defs::CLUSTER_POWER_SOURCE_ATTR_ID_WIREDASSESSEDCURRENT).await?;
1318    decode_wired_assessed_current(&tlv)
1319}
1320
1321/// Read `WiredNominalVoltage` attribute from cluster `Power Source`.
1322pub async fn read_wired_nominal_voltage(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u32> {
1323    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_POWER_SOURCE, crate::clusters::defs::CLUSTER_POWER_SOURCE_ATTR_ID_WIREDNOMINALVOLTAGE).await?;
1324    decode_wired_nominal_voltage(&tlv)
1325}
1326
1327/// Read `WiredMaximumCurrent` attribute from cluster `Power Source`.
1328pub async fn read_wired_maximum_current(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u32> {
1329    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_POWER_SOURCE, crate::clusters::defs::CLUSTER_POWER_SOURCE_ATTR_ID_WIREDMAXIMUMCURRENT).await?;
1330    decode_wired_maximum_current(&tlv)
1331}
1332
1333/// Read `WiredPresent` attribute from cluster `Power Source`.
1334pub async fn read_wired_present(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<bool> {
1335    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_POWER_SOURCE, crate::clusters::defs::CLUSTER_POWER_SOURCE_ATTR_ID_WIREDPRESENT).await?;
1336    decode_wired_present(&tlv)
1337}
1338
1339/// Read `ActiveWiredFaults` attribute from cluster `Power Source`.
1340pub async fn read_active_wired_faults(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Vec<WiredFault>> {
1341    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_POWER_SOURCE, crate::clusters::defs::CLUSTER_POWER_SOURCE_ATTR_ID_ACTIVEWIREDFAULTS).await?;
1342    decode_active_wired_faults(&tlv)
1343}
1344
1345/// Read `BatVoltage` attribute from cluster `Power Source`.
1346pub async fn read_bat_voltage(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Option<u32>> {
1347    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_POWER_SOURCE, crate::clusters::defs::CLUSTER_POWER_SOURCE_ATTR_ID_BATVOLTAGE).await?;
1348    decode_bat_voltage(&tlv)
1349}
1350
1351/// Read `BatPercentRemaining` attribute from cluster `Power Source`.
1352pub async fn read_bat_percent_remaining(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Option<u8>> {
1353    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_POWER_SOURCE, crate::clusters::defs::CLUSTER_POWER_SOURCE_ATTR_ID_BATPERCENTREMAINING).await?;
1354    decode_bat_percent_remaining(&tlv)
1355}
1356
1357/// Read `BatTimeRemaining` attribute from cluster `Power Source`.
1358pub async fn read_bat_time_remaining(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Option<u32>> {
1359    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_POWER_SOURCE, crate::clusters::defs::CLUSTER_POWER_SOURCE_ATTR_ID_BATTIMEREMAINING).await?;
1360    decode_bat_time_remaining(&tlv)
1361}
1362
1363/// Read `BatChargeLevel` attribute from cluster `Power Source`.
1364pub async fn read_bat_charge_level(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<BatChargeLevel> {
1365    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_POWER_SOURCE, crate::clusters::defs::CLUSTER_POWER_SOURCE_ATTR_ID_BATCHARGELEVEL).await?;
1366    decode_bat_charge_level(&tlv)
1367}
1368
1369/// Read `BatReplacementNeeded` attribute from cluster `Power Source`.
1370pub async fn read_bat_replacement_needed(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<bool> {
1371    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_POWER_SOURCE, crate::clusters::defs::CLUSTER_POWER_SOURCE_ATTR_ID_BATREPLACEMENTNEEDED).await?;
1372    decode_bat_replacement_needed(&tlv)
1373}
1374
1375/// Read `BatReplaceability` attribute from cluster `Power Source`.
1376pub async fn read_bat_replaceability(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<BatReplaceability> {
1377    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_POWER_SOURCE, crate::clusters::defs::CLUSTER_POWER_SOURCE_ATTR_ID_BATREPLACEABILITY).await?;
1378    decode_bat_replaceability(&tlv)
1379}
1380
1381/// Read `BatPresent` attribute from cluster `Power Source`.
1382pub async fn read_bat_present(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<bool> {
1383    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_POWER_SOURCE, crate::clusters::defs::CLUSTER_POWER_SOURCE_ATTR_ID_BATPRESENT).await?;
1384    decode_bat_present(&tlv)
1385}
1386
1387/// Read `ActiveBatFaults` attribute from cluster `Power Source`.
1388pub async fn read_active_bat_faults(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Vec<BatFault>> {
1389    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_POWER_SOURCE, crate::clusters::defs::CLUSTER_POWER_SOURCE_ATTR_ID_ACTIVEBATFAULTS).await?;
1390    decode_active_bat_faults(&tlv)
1391}
1392
1393/// Read `BatReplacementDescription` attribute from cluster `Power Source`.
1394pub async fn read_bat_replacement_description(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<String> {
1395    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_POWER_SOURCE, crate::clusters::defs::CLUSTER_POWER_SOURCE_ATTR_ID_BATREPLACEMENTDESCRIPTION).await?;
1396    decode_bat_replacement_description(&tlv)
1397}
1398
1399/// Read `BatCommonDesignation` attribute from cluster `Power Source`.
1400pub async fn read_bat_common_designation(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<BatCommonDesignation> {
1401    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_POWER_SOURCE, crate::clusters::defs::CLUSTER_POWER_SOURCE_ATTR_ID_BATCOMMONDESIGNATION).await?;
1402    decode_bat_common_designation(&tlv)
1403}
1404
1405/// Read `BatANSIDesignation` attribute from cluster `Power Source`.
1406pub async fn read_bat_ansi_designation(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<String> {
1407    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_POWER_SOURCE, crate::clusters::defs::CLUSTER_POWER_SOURCE_ATTR_ID_BATANSIDESIGNATION).await?;
1408    decode_bat_ansi_designation(&tlv)
1409}
1410
1411/// Read `BatIECDesignation` attribute from cluster `Power Source`.
1412pub async fn read_bat_iec_designation(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<String> {
1413    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_POWER_SOURCE, crate::clusters::defs::CLUSTER_POWER_SOURCE_ATTR_ID_BATIECDESIGNATION).await?;
1414    decode_bat_iec_designation(&tlv)
1415}
1416
1417/// Read `BatApprovedChemistry` attribute from cluster `Power Source`.
1418pub async fn read_bat_approved_chemistry(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<BatApprovedChemistry> {
1419    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_POWER_SOURCE, crate::clusters::defs::CLUSTER_POWER_SOURCE_ATTR_ID_BATAPPROVEDCHEMISTRY).await?;
1420    decode_bat_approved_chemistry(&tlv)
1421}
1422
1423/// Read `BatCapacity` attribute from cluster `Power Source`.
1424pub async fn read_bat_capacity(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u32> {
1425    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_POWER_SOURCE, crate::clusters::defs::CLUSTER_POWER_SOURCE_ATTR_ID_BATCAPACITY).await?;
1426    decode_bat_capacity(&tlv)
1427}
1428
1429/// Read `BatQuantity` attribute from cluster `Power Source`.
1430pub async fn read_bat_quantity(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u8> {
1431    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_POWER_SOURCE, crate::clusters::defs::CLUSTER_POWER_SOURCE_ATTR_ID_BATQUANTITY).await?;
1432    decode_bat_quantity(&tlv)
1433}
1434
1435/// Read `BatChargeState` attribute from cluster `Power Source`.
1436pub async fn read_bat_charge_state(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<BatChargeState> {
1437    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_POWER_SOURCE, crate::clusters::defs::CLUSTER_POWER_SOURCE_ATTR_ID_BATCHARGESTATE).await?;
1438    decode_bat_charge_state(&tlv)
1439}
1440
1441/// Read `BatTimeToFullCharge` attribute from cluster `Power Source`.
1442pub async fn read_bat_time_to_full_charge(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Option<u32>> {
1443    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_POWER_SOURCE, crate::clusters::defs::CLUSTER_POWER_SOURCE_ATTR_ID_BATTIMETOFULLCHARGE).await?;
1444    decode_bat_time_to_full_charge(&tlv)
1445}
1446
1447/// Read `BatFunctionalWhileCharging` attribute from cluster `Power Source`.
1448pub async fn read_bat_functional_while_charging(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<bool> {
1449    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_POWER_SOURCE, crate::clusters::defs::CLUSTER_POWER_SOURCE_ATTR_ID_BATFUNCTIONALWHILECHARGING).await?;
1450    decode_bat_functional_while_charging(&tlv)
1451}
1452
1453/// Read `BatChargingCurrent` attribute from cluster `Power Source`.
1454pub async fn read_bat_charging_current(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Option<u32>> {
1455    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_POWER_SOURCE, crate::clusters::defs::CLUSTER_POWER_SOURCE_ATTR_ID_BATCHARGINGCURRENT).await?;
1456    decode_bat_charging_current(&tlv)
1457}
1458
1459/// Read `ActiveBatChargeFaults` attribute from cluster `Power Source`.
1460pub async fn read_active_bat_charge_faults(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Vec<BatChargeFault>> {
1461    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_POWER_SOURCE, crate::clusters::defs::CLUSTER_POWER_SOURCE_ATTR_ID_ACTIVEBATCHARGEFAULTS).await?;
1462    decode_active_bat_charge_faults(&tlv)
1463}
1464
1465/// Read `EndpointList` attribute from cluster `Power Source`.
1466pub async fn read_endpoint_list(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Vec<u16>> {
1467    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_POWER_SOURCE, crate::clusters::defs::CLUSTER_POWER_SOURCE_ATTR_ID_ENDPOINTLIST).await?;
1468    decode_endpoint_list(&tlv)
1469}
1470
1471#[derive(Debug, serde::Serialize)]
1472pub struct WiredFaultChangeEvent {
1473    pub current: Option<Vec<WiredFault>>,
1474    pub previous: Option<Vec<WiredFault>>,
1475}
1476
1477#[derive(Debug, serde::Serialize)]
1478pub struct BatFaultChangeEvent {
1479    pub current: Option<Vec<BatFault>>,
1480    pub previous: Option<Vec<BatFault>>,
1481}
1482
1483#[derive(Debug, serde::Serialize)]
1484pub struct BatChargeFaultChangeEvent {
1485    pub current: Option<Vec<BatChargeFault>>,
1486    pub previous: Option<Vec<BatChargeFault>>,
1487}
1488
1489// Event decoders
1490
1491/// Decode WiredFaultChange event (0x00, priority: info)
1492pub fn decode_wired_fault_change_event(inp: &tlv::TlvItemValue) -> anyhow::Result<WiredFaultChangeEvent> {
1493    if let tlv::TlvItemValue::List(_fields) = inp {
1494        let item = tlv::TlvItem { tag: 0, value: inp.clone() };
1495        Ok(WiredFaultChangeEvent {
1496                                current: {
1497                    if let Some(tlv::TlvItemValue::List(l)) = item.get(&[0]) {
1498                        let items: Vec<WiredFault> = l.iter().filter_map(|e| { if let tlv::TlvItemValue::Int(v) = &e.value { WiredFault::from_u8(*v as u8) } else { None } }).collect();
1499                        Some(items)
1500                    } else {
1501                        None
1502                    }
1503                },
1504                                previous: {
1505                    if let Some(tlv::TlvItemValue::List(l)) = item.get(&[1]) {
1506                        let items: Vec<WiredFault> = l.iter().filter_map(|e| { if let tlv::TlvItemValue::Int(v) = &e.value { WiredFault::from_u8(*v as u8) } else { None } }).collect();
1507                        Some(items)
1508                    } else {
1509                        None
1510                    }
1511                },
1512        })
1513    } else {
1514        Err(anyhow::anyhow!("Expected struct fields"))
1515    }
1516}
1517
1518/// Decode BatFaultChange event (0x01, priority: info)
1519pub fn decode_bat_fault_change_event(inp: &tlv::TlvItemValue) -> anyhow::Result<BatFaultChangeEvent> {
1520    if let tlv::TlvItemValue::List(_fields) = inp {
1521        let item = tlv::TlvItem { tag: 0, value: inp.clone() };
1522        Ok(BatFaultChangeEvent {
1523                                current: {
1524                    if let Some(tlv::TlvItemValue::List(l)) = item.get(&[0]) {
1525                        let items: Vec<BatFault> = l.iter().filter_map(|e| { if let tlv::TlvItemValue::Int(v) = &e.value { BatFault::from_u8(*v as u8) } else { None } }).collect();
1526                        Some(items)
1527                    } else {
1528                        None
1529                    }
1530                },
1531                                previous: {
1532                    if let Some(tlv::TlvItemValue::List(l)) = item.get(&[1]) {
1533                        let items: Vec<BatFault> = l.iter().filter_map(|e| { if let tlv::TlvItemValue::Int(v) = &e.value { BatFault::from_u8(*v as u8) } else { None } }).collect();
1534                        Some(items)
1535                    } else {
1536                        None
1537                    }
1538                },
1539        })
1540    } else {
1541        Err(anyhow::anyhow!("Expected struct fields"))
1542    }
1543}
1544
1545/// Decode BatChargeFaultChange event (0x02, priority: info)
1546pub fn decode_bat_charge_fault_change_event(inp: &tlv::TlvItemValue) -> anyhow::Result<BatChargeFaultChangeEvent> {
1547    if let tlv::TlvItemValue::List(_fields) = inp {
1548        let item = tlv::TlvItem { tag: 0, value: inp.clone() };
1549        Ok(BatChargeFaultChangeEvent {
1550                                current: {
1551                    if let Some(tlv::TlvItemValue::List(l)) = item.get(&[0]) {
1552                        let items: Vec<BatChargeFault> = l.iter().filter_map(|e| { if let tlv::TlvItemValue::Int(v) = &e.value { BatChargeFault::from_u8(*v as u8) } else { None } }).collect();
1553                        Some(items)
1554                    } else {
1555                        None
1556                    }
1557                },
1558                                previous: {
1559                    if let Some(tlv::TlvItemValue::List(l)) = item.get(&[1]) {
1560                        let items: Vec<BatChargeFault> = l.iter().filter_map(|e| { if let tlv::TlvItemValue::Int(v) = &e.value { BatChargeFault::from_u8(*v as u8) } else { None } }).collect();
1561                        Some(items)
1562                    } else {
1563                        None
1564                    }
1565                },
1566        })
1567    } else {
1568        Err(anyhow::anyhow!("Expected struct fields"))
1569    }
1570}
1571