1#![allow(clippy::too_many_arguments)]
7
8use crate::tlv;
9use anyhow;
10use serde_json;
11
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
16#[repr(u8)]
17pub enum BatApprovedChemistry {
18 Unspecified = 0,
20 Alkaline = 1,
22 Lithiumcarbonfluoride = 2,
24 Lithiumchromiumoxide = 3,
26 Lithiumcopperoxide = 4,
28 Lithiumirondisulfide = 5,
30 Lithiummanganesedioxide = 6,
32 Lithiumthionylchloride = 7,
34 Magnesium = 8,
36 Mercuryoxide = 9,
38 Nickeloxyhydride = 10,
40 Silveroxide = 11,
42 Zincair = 12,
44 Zinccarbon = 13,
46 Zincchloride = 14,
48 Zincmanganesedioxide = 15,
50 Leadacid = 16,
52 Lithiumcobaltoxide = 17,
54 Lithiumion = 18,
56 Lithiumionpolymer = 19,
58 Lithiumironphosphate = 20,
60 Lithiumsulfur = 21,
62 Lithiumtitanate = 22,
64 Nickelcadmium = 23,
66 Nickelhydrogen = 24,
68 Nickeliron = 25,
70 Nickelmetalhydride = 26,
72 Nickelzinc = 27,
74 Silverzinc = 28,
76 Sodiumion = 29,
78 Sodiumsulfur = 30,
80 Zincbromide = 31,
82 Zinccerium = 32,
84}
85
86impl BatApprovedChemistry {
87 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 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 Unspecified = 0,
144 Ambienttoohot = 1,
146 Ambienttoocold = 2,
148 Batterytoohot = 3,
150 Batterytoocold = 4,
152 Batteryabsent = 5,
154 Batteryovervoltage = 6,
156 Batteryundervoltage = 7,
158 Chargerovervoltage = 8,
160 Chargerundervoltage = 9,
162 Safetytimeout = 10,
164}
165
166impl BatChargeFault {
167 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 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 Ok = 0,
202 Warning = 1,
204 Critical = 2,
206}
207
208impl BatChargeLevel {
209 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 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 Unknown = 0,
236 Ischarging = 1,
238 Isatfullcharge = 2,
240 Isnotcharging = 3,
242}
243
244impl BatChargeState {
245 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 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 Unspecified = 0,
273 Aaa = 1,
275 Aa = 2,
277 C = 3,
279 D = 4,
281 _4v5 = 5,
283 _6v0 = 6,
285 _9v0 = 7,
287 _12aa = 8,
289 Aaaa = 9,
291 A = 10,
293 B = 11,
295 F = 12,
297 N = 13,
299 No6 = 14,
301 Subc = 15,
303 A23 = 16,
305 A27 = 17,
307 Ba5800 = 18,
309 Duplex = 19,
311 _4sr44 = 20,
313 _523 = 21,
315 _531 = 22,
317 _15v0 = 23,
319 _22v5 = 24,
321 _30v0 = 25,
323 _45v0 = 26,
325 _67v5 = 27,
327 J = 28,
329 Cr123a = 29,
331 Cr2 = 30,
333 _2cr5 = 31,
335 CrP2 = 32,
337 CrV3 = 33,
339 Sr41 = 34,
341 Sr43 = 35,
343 Sr44 = 36,
345 Sr45 = 37,
347 Sr48 = 38,
349 Sr54 = 39,
351 Sr55 = 40,
353 Sr57 = 41,
355 Sr58 = 42,
357 Sr59 = 43,
359 Sr60 = 44,
361 Sr63 = 45,
363 Sr64 = 46,
365 Sr65 = 47,
367 Sr66 = 48,
369 Sr67 = 49,
371 Sr68 = 50,
373 Sr69 = 51,
375 Sr516 = 52,
377 Sr731 = 53,
379 Sr712 = 54,
381 Lr932 = 55,
383 A5 = 56,
385 A10 = 57,
387 A13 = 58,
389 A312 = 59,
391 A675 = 60,
393 Ac41e = 61,
395 _10180 = 62,
397 _10280 = 63,
399 _10440 = 64,
401 _14250 = 65,
403 _14430 = 66,
405 _14500 = 67,
407 _14650 = 68,
409 _15270 = 69,
411 _16340 = 70,
413 Rcr123a = 71,
415 _17500 = 72,
417 _17670 = 73,
419 _18350 = 74,
421 _18500 = 75,
423 _18650 = 76,
425 _19670 = 77,
427 _25500 = 78,
429 _26650 = 79,
431 _32600 = 80,
433}
434
435impl BatCommonDesignation {
436 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 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 Unspecified = 0,
541 Overtemp = 1,
543 Undertemp = 2,
545}
546
547impl BatFault {
548 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 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 Unspecified = 0,
575 Notreplaceable = 1,
577 Userreplaceable = 2,
579 Factoryreplaceable = 3,
581}
582
583impl BatReplaceability {
584 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 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 Unspecified = 0,
612 Active = 1,
614 Standby = 2,
616 Unavailable = 3,
618}
619
620impl PowerSourceStatus {
621 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 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 Ac = 0,
649 Dc = 1,
651}
652
653impl WiredCurrentType {
654 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 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 Unspecified = 0,
680 Overvoltage = 1,
682 Undervoltage = 2,
684}
685
686impl WiredFault {
687 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 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
709pub 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
720pub 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
729pub 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
738pub 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
747pub 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
756pub 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
765pub 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
774pub 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
783pub 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
792pub 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
801pub 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
816pub 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
825pub 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
834pub 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
843pub 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
852pub 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
861pub 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
870pub 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
879pub 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
894pub 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
903pub 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
912pub 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
921pub 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
930pub 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
939pub 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
948pub 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
957pub 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
966pub 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
975pub 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
984pub 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
993pub 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
1008pub 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
1022pub fn decode_attribute_json(cluster_id: u32, attribute_id: u32, tlv_value: &crate::tlv::TlvItemValue) -> String {
1034 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
1236pub 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
1277pub 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
1285pub 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
1291pub 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
1297pub 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
1303pub 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
1309pub 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
1315pub 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
1321pub 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
1327pub 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
1333pub 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
1339pub 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
1345pub 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
1351pub 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
1357pub 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
1363pub 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
1369pub 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
1375pub 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
1381pub 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
1387pub 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
1393pub 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
1399pub 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
1405pub 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
1411pub 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
1417pub 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
1423pub 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
1429pub 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
1435pub 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
1441pub 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
1447pub 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
1453pub 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
1459pub 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
1465pub 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
1489pub 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
1518pub 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
1545pub 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