1#![allow(
5 clippy::all,
6 clippy::pedantic,
7 dead_code,
8 unreachable_pub,
9 unused_imports
10)]
11
12use crate::datatypes::SemanticTagStruct;
13use crate::error::ClusterError;
14use crate::types::Nullable;
15use matter_codec::{ContainerKind, Element, Tag, TlvReader, TlvWriter, Value};
16
17pub const CLUSTER_ID: u32 = 0x0090;
19pub const CLUSTER_REVISION: u16 = 3;
21
22pub mod command_id {}
24
25pub mod attribute_id {
27 pub const POWER_MODE: u32 = 0x0000;
29 pub const NUMBER_OF_MEASUREMENT_TYPES: u32 = 0x0001;
31 pub const ACCURACY: u32 = 0x0002;
33 pub const RANGES: u32 = 0x0003;
35 pub const VOLTAGE: u32 = 0x0004;
37 pub const ACTIVE_CURRENT: u32 = 0x0005;
39 pub const REACTIVE_CURRENT: u32 = 0x0006;
41 pub const APPARENT_CURRENT: u32 = 0x0007;
43 pub const ACTIVE_POWER: u32 = 0x0008;
45 pub const REACTIVE_POWER: u32 = 0x0009;
47 pub const APPARENT_POWER: u32 = 0x000A;
49 pub const RMS_VOLTAGE: u32 = 0x000B;
51 pub const RMS_CURRENT: u32 = 0x000C;
53 pub const RMS_POWER: u32 = 0x000D;
55 pub const FREQUENCY: u32 = 0x000E;
57 pub const HARMONIC_CURRENTS: u32 = 0x000F;
59 pub const HARMONIC_PHASES: u32 = 0x0010;
61 pub const POWER_FACTOR: u32 = 0x0011;
63 pub const NEUTRAL_CURRENT: u32 = 0x0012;
65}
66
67bitflags::bitflags! {
68 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
70 pub struct Feature: u32 {
71 const DIRC = 1 << 0;
73 const ALTC = 1 << 1;
75 const POLY = 1 << 2;
77 const HARM = 1 << 3;
79 const PWRQ = 1 << 4;
81 }
82}
83
84#[derive(Clone, Debug, PartialEq)]
86#[non_exhaustive]
87pub struct HarmonicMeasurementStruct {
88 pub order: u8,
90 pub measurement: Nullable<i64>,
92}
93
94#[derive(Clone, Debug, PartialEq)]
96#[non_exhaustive]
97pub struct MeasurementAccuracyRangeStruct {
98 pub range_min: i64,
100 pub range_max: i64,
102 pub percent_max: Option<u16>,
104 pub percent_min: Option<u16>,
106 pub percent_typical: Option<u16>,
108 pub fixed_max: Option<u64>,
110 pub fixed_min: Option<u64>,
112 pub fixed_typical: Option<u64>,
114}
115
116#[derive(Clone, Debug, PartialEq)]
118#[non_exhaustive]
119pub struct MeasurementAccuracyStruct {
120 pub measurement_type: MeasurementTypeEnum,
122 pub measured: bool,
124 pub min_measured_value: i64,
126 pub max_measured_value: i64,
128 pub accuracy_ranges: Vec<MeasurementAccuracyRangeStruct>,
130}
131
132#[derive(Clone, Debug, PartialEq)]
134#[non_exhaustive]
135pub struct MeasurementRangeStruct {
136 pub measurement_type: MeasurementTypeEnum,
138 pub min: i64,
140 pub max: i64,
142 pub start_timestamp: Option<u32>,
144 pub end_timestamp: Option<u32>,
146 pub min_timestamp: Option<u32>,
148 pub max_timestamp: Option<u32>,
150 pub start_systime: Option<u64>,
152 pub end_systime: Option<u64>,
154 pub min_systime: Option<u64>,
156 pub max_systime: Option<u64>,
158}
159
160#[derive(Copy, Clone, Debug, PartialEq, Eq)]
162pub enum MeasurementTypeEnum {
163 Unspecified,
165 Voltage,
167 ActiveCurrent,
169 ReactiveCurrent,
171 ApparentCurrent,
173 ActivePower,
175 ReactivePower,
177 ApparentPower,
179 RmsVoltage,
181 RmsCurrent,
183 RmsPower,
185 Frequency,
187 PowerFactor,
189 NeutralCurrent,
191 ElectricalEnergy,
193 ReactiveEnergy,
195 ApparentEnergy,
197 Unknown(u16),
199}
200
201impl MeasurementTypeEnum {
202 #[must_use]
204 pub fn from_raw(v: u16) -> Self {
205 match v {
206 0 => Self::Unspecified,
207 1 => Self::Voltage,
208 2 => Self::ActiveCurrent,
209 3 => Self::ReactiveCurrent,
210 4 => Self::ApparentCurrent,
211 5 => Self::ActivePower,
212 6 => Self::ReactivePower,
213 7 => Self::ApparentPower,
214 8 => Self::RmsVoltage,
215 9 => Self::RmsCurrent,
216 10 => Self::RmsPower,
217 11 => Self::Frequency,
218 12 => Self::PowerFactor,
219 13 => Self::NeutralCurrent,
220 14 => Self::ElectricalEnergy,
221 15 => Self::ReactiveEnergy,
222 16 => Self::ApparentEnergy,
223 other => Self::Unknown(other),
224 }
225 }
226 #[must_use]
228 pub fn to_raw(self) -> u16 {
229 match self {
230 Self::Unspecified => 0,
231 Self::Voltage => 1,
232 Self::ActiveCurrent => 2,
233 Self::ReactiveCurrent => 3,
234 Self::ApparentCurrent => 4,
235 Self::ActivePower => 5,
236 Self::ReactivePower => 6,
237 Self::ApparentPower => 7,
238 Self::RmsVoltage => 8,
239 Self::RmsCurrent => 9,
240 Self::RmsPower => 10,
241 Self::Frequency => 11,
242 Self::PowerFactor => 12,
243 Self::NeutralCurrent => 13,
244 Self::ElectricalEnergy => 14,
245 Self::ReactiveEnergy => 15,
246 Self::ApparentEnergy => 16,
247 Self::Unknown(v) => v,
248 }
249 }
250}
251
252#[derive(Copy, Clone, Debug, PartialEq, Eq)]
254pub enum PowerModeEnum {
255 Unknown,
257 Dc,
259 Ac,
261 Unrecognized(u8),
263}
264
265impl PowerModeEnum {
266 #[must_use]
268 pub fn from_raw(v: u8) -> Self {
269 match v {
270 0 => Self::Unknown,
271 1 => Self::Dc,
272 2 => Self::Ac,
273 other => Self::Unrecognized(other),
274 }
275 }
276 #[must_use]
278 pub fn to_raw(self) -> u8 {
279 match self {
280 Self::Unknown => 0,
281 Self::Dc => 1,
282 Self::Ac => 2,
283 Self::Unrecognized(v) => v,
284 }
285 }
286}
287
288impl HarmonicMeasurementStruct {
289 pub fn decode_from(r: &mut TlvReader<'_>) -> Result<Self, ClusterError> {
295 let mut f_order: Option<u8> = None;
296 let mut f_measurement: Option<Nullable<i64>> = None;
297 loop {
298 match r.next()? {
299 Some(Element::ContainerEnd) => break,
300 Some(Element::Scalar {
301 tag: Tag::Context(0),
302 value: Value::Uint(v),
303 }) => {
304 f_order =
305 Some(u8::try_from(v).map_err(|_| ClusterError::InvalidLength("Order"))?)
306 }
307 Some(Element::Scalar {
308 tag: Tag::Context(1),
309 value: Value::Null,
310 }) => f_measurement = Some(Nullable::Null),
311 Some(Element::Scalar {
312 tag: Tag::Context(1),
313 value: Value::Int(v),
314 }) => {
315 f_measurement = Some(Nullable::Value(
316 i64::try_from(v).map_err(|_| ClusterError::InvalidLength("Measurement"))?,
317 ))
318 }
319 None => return Err(ClusterError::Tlv(matter_codec::Error::UnclosedContainer)),
320 Some(Element::ContainerStart { .. }) => r.skip_container()?,
321 Some(_) => {} }
323 }
324 Ok(Self {
325 order: f_order.ok_or(ClusterError::MissingField("Order"))?,
326 measurement: f_measurement.ok_or(ClusterError::MissingField("Measurement"))?,
327 })
328 }
329 pub fn decode(tlv: &[u8]) -> Result<Self, ClusterError> {
334 let mut r = TlvReader::new(tlv);
335 match r.next()? {
336 Some(Element::ContainerStart {
337 kind: ContainerKind::Structure,
338 ..
339 }) => {}
340 _ => {
341 return Err(ClusterError::UnexpectedType {
342 context: "HarmonicMeasurementStruct",
343 })
344 }
345 }
346 Self::decode_from(&mut r)
347 }
348 #[allow(clippy::expect_used)] pub fn write_fields(&self, w: &mut TlvWriter<'_>) {
351 w.put_uint(Tag::Context(0), u64::from(self.order))
352 .expect("infallible: vec writer");
353 match &self.measurement {
354 Nullable::Null => w.put_null(Tag::Context(1)).expect("infallible: vec writer"),
355 Nullable::Value(measurement) => {
356 w.put_int(Tag::Context(1), i64::from(*measurement))
357 .expect("infallible: vec writer");
358 }
359 }
360 }
361 #[must_use]
363 #[allow(clippy::expect_used)] pub fn encode(&self) -> Vec<u8> {
365 let mut buf = Vec::new();
366 let mut w = TlvWriter::new(&mut buf);
367 w.start_structure(Tag::Anonymous)
368 .expect("infallible: vec writer");
369 self.write_fields(&mut w);
370 w.end_container().expect("infallible: vec writer");
371 buf
372 }
373}
374
375impl MeasurementAccuracyRangeStruct {
376 pub fn decode_from(r: &mut TlvReader<'_>) -> Result<Self, ClusterError> {
382 let mut f_range_min: Option<i64> = None;
383 let mut f_range_max: Option<i64> = None;
384 let mut f_percent_max: Option<u16> = None;
385 let mut f_percent_min: Option<u16> = None;
386 let mut f_percent_typical: Option<u16> = None;
387 let mut f_fixed_max: Option<u64> = None;
388 let mut f_fixed_min: Option<u64> = None;
389 let mut f_fixed_typical: Option<u64> = None;
390 loop {
391 match r.next()? {
392 Some(Element::ContainerEnd) => break,
393 Some(Element::Scalar {
394 tag: Tag::Context(0),
395 value: Value::Int(v),
396 }) => {
397 f_range_min = Some(
398 i64::try_from(v).map_err(|_| ClusterError::InvalidLength("RangeMin"))?,
399 )
400 }
401 Some(Element::Scalar {
402 tag: Tag::Context(1),
403 value: Value::Int(v),
404 }) => {
405 f_range_max = Some(
406 i64::try_from(v).map_err(|_| ClusterError::InvalidLength("RangeMax"))?,
407 )
408 }
409 Some(Element::Scalar {
410 tag: Tag::Context(2),
411 value: Value::Uint(v),
412 }) => {
413 f_percent_max = Some(
414 u16::try_from(v).map_err(|_| ClusterError::InvalidLength("PercentMax"))?,
415 )
416 }
417 Some(Element::Scalar {
418 tag: Tag::Context(3),
419 value: Value::Uint(v),
420 }) => {
421 f_percent_min = Some(
422 u16::try_from(v).map_err(|_| ClusterError::InvalidLength("PercentMin"))?,
423 )
424 }
425 Some(Element::Scalar {
426 tag: Tag::Context(4),
427 value: Value::Uint(v),
428 }) => {
429 f_percent_typical = Some(
430 u16::try_from(v)
431 .map_err(|_| ClusterError::InvalidLength("PercentTypical"))?,
432 )
433 }
434 Some(Element::Scalar {
435 tag: Tag::Context(5),
436 value: Value::Uint(v),
437 }) => {
438 f_fixed_max = Some(
439 u64::try_from(v).map_err(|_| ClusterError::InvalidLength("FixedMax"))?,
440 )
441 }
442 Some(Element::Scalar {
443 tag: Tag::Context(6),
444 value: Value::Uint(v),
445 }) => {
446 f_fixed_min = Some(
447 u64::try_from(v).map_err(|_| ClusterError::InvalidLength("FixedMin"))?,
448 )
449 }
450 Some(Element::Scalar {
451 tag: Tag::Context(7),
452 value: Value::Uint(v),
453 }) => {
454 f_fixed_typical = Some(
455 u64::try_from(v)
456 .map_err(|_| ClusterError::InvalidLength("FixedTypical"))?,
457 )
458 }
459 None => return Err(ClusterError::Tlv(matter_codec::Error::UnclosedContainer)),
460 Some(Element::ContainerStart { .. }) => r.skip_container()?,
461 Some(_) => {} }
463 }
464 Ok(Self {
465 range_min: f_range_min.ok_or(ClusterError::MissingField("RangeMin"))?,
466 range_max: f_range_max.ok_or(ClusterError::MissingField("RangeMax"))?,
467 percent_max: f_percent_max,
468 percent_min: f_percent_min,
469 percent_typical: f_percent_typical,
470 fixed_max: f_fixed_max,
471 fixed_min: f_fixed_min,
472 fixed_typical: f_fixed_typical,
473 })
474 }
475 pub fn decode(tlv: &[u8]) -> Result<Self, ClusterError> {
480 let mut r = TlvReader::new(tlv);
481 match r.next()? {
482 Some(Element::ContainerStart {
483 kind: ContainerKind::Structure,
484 ..
485 }) => {}
486 _ => {
487 return Err(ClusterError::UnexpectedType {
488 context: "MeasurementAccuracyRangeStruct",
489 })
490 }
491 }
492 Self::decode_from(&mut r)
493 }
494 #[allow(clippy::expect_used)] pub fn write_fields(&self, w: &mut TlvWriter<'_>) {
497 w.put_int(Tag::Context(0), i64::from(self.range_min))
498 .expect("infallible: vec writer");
499 w.put_int(Tag::Context(1), i64::from(self.range_max))
500 .expect("infallible: vec writer");
501 if let Some(percent_max) = &self.percent_max {
502 w.put_uint(Tag::Context(2), u64::from(*percent_max))
503 .expect("infallible: vec writer");
504 }
505 if let Some(percent_min) = &self.percent_min {
506 w.put_uint(Tag::Context(3), u64::from(*percent_min))
507 .expect("infallible: vec writer");
508 }
509 if let Some(percent_typical) = &self.percent_typical {
510 w.put_uint(Tag::Context(4), u64::from(*percent_typical))
511 .expect("infallible: vec writer");
512 }
513 if let Some(fixed_max) = &self.fixed_max {
514 w.put_uint(Tag::Context(5), u64::from(*fixed_max))
515 .expect("infallible: vec writer");
516 }
517 if let Some(fixed_min) = &self.fixed_min {
518 w.put_uint(Tag::Context(6), u64::from(*fixed_min))
519 .expect("infallible: vec writer");
520 }
521 if let Some(fixed_typical) = &self.fixed_typical {
522 w.put_uint(Tag::Context(7), u64::from(*fixed_typical))
523 .expect("infallible: vec writer");
524 }
525 }
526 #[must_use]
528 #[allow(clippy::expect_used)] pub fn encode(&self) -> Vec<u8> {
530 let mut buf = Vec::new();
531 let mut w = TlvWriter::new(&mut buf);
532 w.start_structure(Tag::Anonymous)
533 .expect("infallible: vec writer");
534 self.write_fields(&mut w);
535 w.end_container().expect("infallible: vec writer");
536 buf
537 }
538}
539
540impl MeasurementAccuracyStruct {
541 pub fn decode_from(r: &mut TlvReader<'_>) -> Result<Self, ClusterError> {
547 let mut f_measurement_type: Option<MeasurementTypeEnum> = None;
548 let mut f_measured: Option<bool> = None;
549 let mut f_min_measured_value: Option<i64> = None;
550 let mut f_max_measured_value: Option<i64> = None;
551 let mut f_accuracy_ranges: Option<Vec<MeasurementAccuracyRangeStruct>> = None;
552 loop {
553 match r.next()? {
554 Some(Element::ContainerEnd) => break,
555 Some(Element::Scalar {
556 tag: Tag::Context(0),
557 value: Value::Uint(v),
558 }) => {
559 f_measurement_type = Some(MeasurementTypeEnum::from_raw(
560 u16::try_from(v)
561 .map_err(|_| ClusterError::InvalidLength("MeasurementType"))?,
562 ))
563 }
564 Some(Element::Scalar {
565 tag: Tag::Context(1),
566 value: Value::Bool(v),
567 }) => f_measured = Some(v),
568 Some(Element::Scalar {
569 tag: Tag::Context(2),
570 value: Value::Int(v),
571 }) => {
572 f_min_measured_value = Some(
573 i64::try_from(v)
574 .map_err(|_| ClusterError::InvalidLength("MinMeasuredValue"))?,
575 )
576 }
577 Some(Element::Scalar {
578 tag: Tag::Context(3),
579 value: Value::Int(v),
580 }) => {
581 f_max_measured_value = Some(
582 i64::try_from(v)
583 .map_err(|_| ClusterError::InvalidLength("MaxMeasuredValue"))?,
584 )
585 }
586 Some(Element::ContainerStart {
587 tag: Tag::Context(4),
588 kind: ContainerKind::Array,
589 }) => {
590 let mut out = Vec::new();
591 loop {
592 match r.next()? {
593 Some(Element::ContainerEnd) => break,
594 Some(Element::ContainerStart {
595 kind: ContainerKind::Structure,
596 ..
597 }) => {
598 out.push(MeasurementAccuracyRangeStruct::decode_from(r)?);
599 }
600 None => {
601 return Err(ClusterError::Tlv(
602 matter_codec::Error::UnclosedContainer,
603 ))
604 }
605 Some(Element::ContainerStart { .. }) => r.skip_container()?,
606 Some(_) => {} }
608 }
609 f_accuracy_ranges = Some(out);
610 }
611 None => return Err(ClusterError::Tlv(matter_codec::Error::UnclosedContainer)),
612 Some(Element::ContainerStart { .. }) => r.skip_container()?,
613 Some(_) => {} }
615 }
616 Ok(Self {
617 measurement_type: f_measurement_type
618 .ok_or(ClusterError::MissingField("MeasurementType"))?,
619 measured: f_measured.ok_or(ClusterError::MissingField("Measured"))?,
620 min_measured_value: f_min_measured_value
621 .ok_or(ClusterError::MissingField("MinMeasuredValue"))?,
622 max_measured_value: f_max_measured_value
623 .ok_or(ClusterError::MissingField("MaxMeasuredValue"))?,
624 accuracy_ranges: f_accuracy_ranges
625 .ok_or(ClusterError::MissingField("AccuracyRanges"))?,
626 })
627 }
628 pub fn decode(tlv: &[u8]) -> Result<Self, ClusterError> {
633 let mut r = TlvReader::new(tlv);
634 match r.next()? {
635 Some(Element::ContainerStart {
636 kind: ContainerKind::Structure,
637 ..
638 }) => {}
639 _ => {
640 return Err(ClusterError::UnexpectedType {
641 context: "MeasurementAccuracyStruct",
642 })
643 }
644 }
645 Self::decode_from(&mut r)
646 }
647}
648
649impl MeasurementRangeStruct {
650 pub fn decode_from(r: &mut TlvReader<'_>) -> Result<Self, ClusterError> {
656 let mut f_measurement_type: Option<MeasurementTypeEnum> = None;
657 let mut f_min: Option<i64> = None;
658 let mut f_max: Option<i64> = None;
659 let mut f_start_timestamp: Option<u32> = None;
660 let mut f_end_timestamp: Option<u32> = None;
661 let mut f_min_timestamp: Option<u32> = None;
662 let mut f_max_timestamp: Option<u32> = None;
663 let mut f_start_systime: Option<u64> = None;
664 let mut f_end_systime: Option<u64> = None;
665 let mut f_min_systime: Option<u64> = None;
666 let mut f_max_systime: Option<u64> = None;
667 loop {
668 match r.next()? {
669 Some(Element::ContainerEnd) => break,
670 Some(Element::Scalar {
671 tag: Tag::Context(0),
672 value: Value::Uint(v),
673 }) => {
674 f_measurement_type = Some(MeasurementTypeEnum::from_raw(
675 u16::try_from(v)
676 .map_err(|_| ClusterError::InvalidLength("MeasurementType"))?,
677 ))
678 }
679 Some(Element::Scalar {
680 tag: Tag::Context(1),
681 value: Value::Int(v),
682 }) => {
683 f_min = Some(i64::try_from(v).map_err(|_| ClusterError::InvalidLength("Min"))?)
684 }
685 Some(Element::Scalar {
686 tag: Tag::Context(2),
687 value: Value::Int(v),
688 }) => {
689 f_max = Some(i64::try_from(v).map_err(|_| ClusterError::InvalidLength("Max"))?)
690 }
691 Some(Element::Scalar {
692 tag: Tag::Context(3),
693 value: Value::Uint(v),
694 }) => {
695 f_start_timestamp = Some(
696 u32::try_from(v)
697 .map_err(|_| ClusterError::InvalidLength("StartTimestamp"))?,
698 )
699 }
700 Some(Element::Scalar {
701 tag: Tag::Context(4),
702 value: Value::Uint(v),
703 }) => {
704 f_end_timestamp = Some(
705 u32::try_from(v)
706 .map_err(|_| ClusterError::InvalidLength("EndTimestamp"))?,
707 )
708 }
709 Some(Element::Scalar {
710 tag: Tag::Context(5),
711 value: Value::Uint(v),
712 }) => {
713 f_min_timestamp = Some(
714 u32::try_from(v)
715 .map_err(|_| ClusterError::InvalidLength("MinTimestamp"))?,
716 )
717 }
718 Some(Element::Scalar {
719 tag: Tag::Context(6),
720 value: Value::Uint(v),
721 }) => {
722 f_max_timestamp = Some(
723 u32::try_from(v)
724 .map_err(|_| ClusterError::InvalidLength("MaxTimestamp"))?,
725 )
726 }
727 Some(Element::Scalar {
728 tag: Tag::Context(7),
729 value: Value::Uint(v),
730 }) => {
731 f_start_systime = Some(
732 u64::try_from(v)
733 .map_err(|_| ClusterError::InvalidLength("StartSystime"))?,
734 )
735 }
736 Some(Element::Scalar {
737 tag: Tag::Context(8),
738 value: Value::Uint(v),
739 }) => {
740 f_end_systime = Some(
741 u64::try_from(v).map_err(|_| ClusterError::InvalidLength("EndSystime"))?,
742 )
743 }
744 Some(Element::Scalar {
745 tag: Tag::Context(9),
746 value: Value::Uint(v),
747 }) => {
748 f_min_systime = Some(
749 u64::try_from(v).map_err(|_| ClusterError::InvalidLength("MinSystime"))?,
750 )
751 }
752 Some(Element::Scalar {
753 tag: Tag::Context(10),
754 value: Value::Uint(v),
755 }) => {
756 f_max_systime = Some(
757 u64::try_from(v).map_err(|_| ClusterError::InvalidLength("MaxSystime"))?,
758 )
759 }
760 None => return Err(ClusterError::Tlv(matter_codec::Error::UnclosedContainer)),
761 Some(Element::ContainerStart { .. }) => r.skip_container()?,
762 Some(_) => {} }
764 }
765 Ok(Self {
766 measurement_type: f_measurement_type
767 .ok_or(ClusterError::MissingField("MeasurementType"))?,
768 min: f_min.ok_or(ClusterError::MissingField("Min"))?,
769 max: f_max.ok_or(ClusterError::MissingField("Max"))?,
770 start_timestamp: f_start_timestamp,
771 end_timestamp: f_end_timestamp,
772 min_timestamp: f_min_timestamp,
773 max_timestamp: f_max_timestamp,
774 start_systime: f_start_systime,
775 end_systime: f_end_systime,
776 min_systime: f_min_systime,
777 max_systime: f_max_systime,
778 })
779 }
780 pub fn decode(tlv: &[u8]) -> Result<Self, ClusterError> {
785 let mut r = TlvReader::new(tlv);
786 match r.next()? {
787 Some(Element::ContainerStart {
788 kind: ContainerKind::Structure,
789 ..
790 }) => {}
791 _ => {
792 return Err(ClusterError::UnexpectedType {
793 context: "MeasurementRangeStruct",
794 })
795 }
796 }
797 Self::decode_from(&mut r)
798 }
799 #[allow(clippy::expect_used)] pub fn write_fields(&self, w: &mut TlvWriter<'_>) {
802 w.put_uint(Tag::Context(0), u64::from(self.measurement_type.to_raw()))
803 .expect("infallible: vec writer");
804 w.put_int(Tag::Context(1), i64::from(self.min))
805 .expect("infallible: vec writer");
806 w.put_int(Tag::Context(2), i64::from(self.max))
807 .expect("infallible: vec writer");
808 if let Some(start_timestamp) = &self.start_timestamp {
809 w.put_uint(Tag::Context(3), u64::from(*start_timestamp))
810 .expect("infallible: vec writer");
811 }
812 if let Some(end_timestamp) = &self.end_timestamp {
813 w.put_uint(Tag::Context(4), u64::from(*end_timestamp))
814 .expect("infallible: vec writer");
815 }
816 if let Some(min_timestamp) = &self.min_timestamp {
817 w.put_uint(Tag::Context(5), u64::from(*min_timestamp))
818 .expect("infallible: vec writer");
819 }
820 if let Some(max_timestamp) = &self.max_timestamp {
821 w.put_uint(Tag::Context(6), u64::from(*max_timestamp))
822 .expect("infallible: vec writer");
823 }
824 if let Some(start_systime) = &self.start_systime {
825 w.put_uint(Tag::Context(7), u64::from(*start_systime))
826 .expect("infallible: vec writer");
827 }
828 if let Some(end_systime) = &self.end_systime {
829 w.put_uint(Tag::Context(8), u64::from(*end_systime))
830 .expect("infallible: vec writer");
831 }
832 if let Some(min_systime) = &self.min_systime {
833 w.put_uint(Tag::Context(9), u64::from(*min_systime))
834 .expect("infallible: vec writer");
835 }
836 if let Some(max_systime) = &self.max_systime {
837 w.put_uint(Tag::Context(10), u64::from(*max_systime))
838 .expect("infallible: vec writer");
839 }
840 }
841 #[must_use]
843 #[allow(clippy::expect_used)] pub fn encode(&self) -> Vec<u8> {
845 let mut buf = Vec::new();
846 let mut w = TlvWriter::new(&mut buf);
847 w.start_structure(Tag::Anonymous)
848 .expect("infallible: vec writer");
849 self.write_fields(&mut w);
850 w.end_container().expect("infallible: vec writer");
851 buf
852 }
853}
854
855pub fn decode_power_mode(tlv: &[u8]) -> Result<PowerModeEnum, ClusterError> {
860 let mut r = TlvReader::new(tlv);
861 match r.next()? {
862 Some(Element::Scalar {
863 value: Value::Uint(v),
864 ..
865 }) => Ok(PowerModeEnum::from_raw(
866 u8::try_from(v).map_err(|_| ClusterError::InvalidLength("PowerMode"))?,
867 )),
868 _ => Err(ClusterError::UnexpectedType {
869 context: "PowerMode",
870 }),
871 }
872}
873
874pub fn decode_number_of_measurement_types(tlv: &[u8]) -> Result<u8, ClusterError> {
879 let mut r = TlvReader::new(tlv);
880 match r.next()? {
881 Some(Element::Scalar {
882 value: Value::Uint(v),
883 ..
884 }) => {
885 Ok(u8::try_from(v)
886 .map_err(|_| ClusterError::InvalidLength("NumberOfMeasurementTypes"))?)
887 }
888 _ => Err(ClusterError::UnexpectedType {
889 context: "NumberOfMeasurementTypes",
890 }),
891 }
892}
893
894pub fn decode_accuracy(tlv: &[u8]) -> Result<Vec<MeasurementAccuracyStruct>, ClusterError> {
899 let mut r = TlvReader::new(tlv);
900 match r.next()? {
901 Some(Element::ContainerStart {
902 kind: ContainerKind::Array,
903 ..
904 }) => {}
905 _ => {
906 return Err(ClusterError::UnexpectedType {
907 context: "Accuracy",
908 })
909 }
910 }
911 let r = &mut r;
912 let mut out = Vec::new();
913 loop {
914 match r.next()? {
915 Some(Element::ContainerEnd) => break,
916 Some(Element::ContainerStart {
917 kind: ContainerKind::Structure,
918 ..
919 }) => {
920 out.push(MeasurementAccuracyStruct::decode_from(r)?);
921 }
922 None => return Err(ClusterError::Tlv(matter_codec::Error::UnclosedContainer)),
923 Some(Element::ContainerStart { .. }) => r.skip_container()?,
924 Some(_) => {} }
926 }
927 Ok(out)
928}
929
930pub fn decode_ranges(tlv: &[u8]) -> Result<Vec<MeasurementRangeStruct>, ClusterError> {
935 let mut r = TlvReader::new(tlv);
936 match r.next()? {
937 Some(Element::ContainerStart {
938 kind: ContainerKind::Array,
939 ..
940 }) => {}
941 _ => return Err(ClusterError::UnexpectedType { context: "Ranges" }),
942 }
943 let r = &mut r;
944 let mut out = Vec::new();
945 loop {
946 match r.next()? {
947 Some(Element::ContainerEnd) => break,
948 Some(Element::ContainerStart {
949 kind: ContainerKind::Structure,
950 ..
951 }) => {
952 out.push(MeasurementRangeStruct::decode_from(r)?);
953 }
954 None => return Err(ClusterError::Tlv(matter_codec::Error::UnclosedContainer)),
955 Some(Element::ContainerStart { .. }) => r.skip_container()?,
956 Some(_) => {} }
958 }
959 Ok(out)
960}
961
962pub fn decode_voltage(tlv: &[u8]) -> Result<Nullable<i64>, ClusterError> {
967 let mut r = TlvReader::new(tlv);
968 match r.next()? {
969 Some(Element::Scalar {
970 value: Value::Null, ..
971 }) => Ok(Nullable::Null),
972 Some(Element::Scalar {
973 value: Value::Int(v),
974 ..
975 }) => Ok(Nullable::Value(
976 i64::try_from(v).map_err(|_| ClusterError::InvalidLength("Voltage"))?,
977 )),
978 _ => Err(ClusterError::UnexpectedType { context: "Voltage" }),
979 }
980}
981
982pub fn decode_active_current(tlv: &[u8]) -> Result<Nullable<i64>, ClusterError> {
987 let mut r = TlvReader::new(tlv);
988 match r.next()? {
989 Some(Element::Scalar {
990 value: Value::Null, ..
991 }) => Ok(Nullable::Null),
992 Some(Element::Scalar {
993 value: Value::Int(v),
994 ..
995 }) => {
996 Ok(Nullable::Value(i64::try_from(v).map_err(|_| {
997 ClusterError::InvalidLength("ActiveCurrent")
998 })?))
999 }
1000 _ => Err(ClusterError::UnexpectedType {
1001 context: "ActiveCurrent",
1002 }),
1003 }
1004}
1005
1006pub fn decode_reactive_current(tlv: &[u8]) -> Result<Nullable<i64>, ClusterError> {
1011 let mut r = TlvReader::new(tlv);
1012 match r.next()? {
1013 Some(Element::Scalar {
1014 value: Value::Null, ..
1015 }) => Ok(Nullable::Null),
1016 Some(Element::Scalar {
1017 value: Value::Int(v),
1018 ..
1019 }) => {
1020 Ok(Nullable::Value(i64::try_from(v).map_err(|_| {
1021 ClusterError::InvalidLength("ReactiveCurrent")
1022 })?))
1023 }
1024 _ => Err(ClusterError::UnexpectedType {
1025 context: "ReactiveCurrent",
1026 }),
1027 }
1028}
1029
1030pub fn decode_apparent_current(tlv: &[u8]) -> Result<Nullable<i64>, ClusterError> {
1035 let mut r = TlvReader::new(tlv);
1036 match r.next()? {
1037 Some(Element::Scalar {
1038 value: Value::Null, ..
1039 }) => Ok(Nullable::Null),
1040 Some(Element::Scalar {
1041 value: Value::Int(v),
1042 ..
1043 }) => {
1044 Ok(Nullable::Value(i64::try_from(v).map_err(|_| {
1045 ClusterError::InvalidLength("ApparentCurrent")
1046 })?))
1047 }
1048 _ => Err(ClusterError::UnexpectedType {
1049 context: "ApparentCurrent",
1050 }),
1051 }
1052}
1053
1054pub fn decode_active_power(tlv: &[u8]) -> Result<Nullable<i64>, ClusterError> {
1059 let mut r = TlvReader::new(tlv);
1060 match r.next()? {
1061 Some(Element::Scalar {
1062 value: Value::Null, ..
1063 }) => Ok(Nullable::Null),
1064 Some(Element::Scalar {
1065 value: Value::Int(v),
1066 ..
1067 }) => Ok(Nullable::Value(
1068 i64::try_from(v).map_err(|_| ClusterError::InvalidLength("ActivePower"))?,
1069 )),
1070 _ => Err(ClusterError::UnexpectedType {
1071 context: "ActivePower",
1072 }),
1073 }
1074}
1075
1076pub fn decode_reactive_power(tlv: &[u8]) -> Result<Nullable<i64>, ClusterError> {
1081 let mut r = TlvReader::new(tlv);
1082 match r.next()? {
1083 Some(Element::Scalar {
1084 value: Value::Null, ..
1085 }) => Ok(Nullable::Null),
1086 Some(Element::Scalar {
1087 value: Value::Int(v),
1088 ..
1089 }) => {
1090 Ok(Nullable::Value(i64::try_from(v).map_err(|_| {
1091 ClusterError::InvalidLength("ReactivePower")
1092 })?))
1093 }
1094 _ => Err(ClusterError::UnexpectedType {
1095 context: "ReactivePower",
1096 }),
1097 }
1098}
1099
1100pub fn decode_apparent_power(tlv: &[u8]) -> Result<Nullable<i64>, ClusterError> {
1105 let mut r = TlvReader::new(tlv);
1106 match r.next()? {
1107 Some(Element::Scalar {
1108 value: Value::Null, ..
1109 }) => Ok(Nullable::Null),
1110 Some(Element::Scalar {
1111 value: Value::Int(v),
1112 ..
1113 }) => {
1114 Ok(Nullable::Value(i64::try_from(v).map_err(|_| {
1115 ClusterError::InvalidLength("ApparentPower")
1116 })?))
1117 }
1118 _ => Err(ClusterError::UnexpectedType {
1119 context: "ApparentPower",
1120 }),
1121 }
1122}
1123
1124pub fn decode_rms_voltage(tlv: &[u8]) -> Result<Nullable<i64>, ClusterError> {
1129 let mut r = TlvReader::new(tlv);
1130 match r.next()? {
1131 Some(Element::Scalar {
1132 value: Value::Null, ..
1133 }) => Ok(Nullable::Null),
1134 Some(Element::Scalar {
1135 value: Value::Int(v),
1136 ..
1137 }) => Ok(Nullable::Value(
1138 i64::try_from(v).map_err(|_| ClusterError::InvalidLength("RmsVoltage"))?,
1139 )),
1140 _ => Err(ClusterError::UnexpectedType {
1141 context: "RmsVoltage",
1142 }),
1143 }
1144}
1145
1146pub fn decode_rms_current(tlv: &[u8]) -> Result<Nullable<i64>, ClusterError> {
1151 let mut r = TlvReader::new(tlv);
1152 match r.next()? {
1153 Some(Element::Scalar {
1154 value: Value::Null, ..
1155 }) => Ok(Nullable::Null),
1156 Some(Element::Scalar {
1157 value: Value::Int(v),
1158 ..
1159 }) => Ok(Nullable::Value(
1160 i64::try_from(v).map_err(|_| ClusterError::InvalidLength("RmsCurrent"))?,
1161 )),
1162 _ => Err(ClusterError::UnexpectedType {
1163 context: "RmsCurrent",
1164 }),
1165 }
1166}
1167
1168pub fn decode_rms_power(tlv: &[u8]) -> Result<Nullable<i64>, ClusterError> {
1173 let mut r = TlvReader::new(tlv);
1174 match r.next()? {
1175 Some(Element::Scalar {
1176 value: Value::Null, ..
1177 }) => Ok(Nullable::Null),
1178 Some(Element::Scalar {
1179 value: Value::Int(v),
1180 ..
1181 }) => Ok(Nullable::Value(
1182 i64::try_from(v).map_err(|_| ClusterError::InvalidLength("RmsPower"))?,
1183 )),
1184 _ => Err(ClusterError::UnexpectedType {
1185 context: "RmsPower",
1186 }),
1187 }
1188}
1189
1190pub fn decode_frequency(tlv: &[u8]) -> Result<Nullable<i64>, ClusterError> {
1195 let mut r = TlvReader::new(tlv);
1196 match r.next()? {
1197 Some(Element::Scalar {
1198 value: Value::Null, ..
1199 }) => Ok(Nullable::Null),
1200 Some(Element::Scalar {
1201 value: Value::Int(v),
1202 ..
1203 }) => Ok(Nullable::Value(
1204 i64::try_from(v).map_err(|_| ClusterError::InvalidLength("Frequency"))?,
1205 )),
1206 _ => Err(ClusterError::UnexpectedType {
1207 context: "Frequency",
1208 }),
1209 }
1210}
1211
1212pub fn decode_harmonic_currents(
1217 tlv: &[u8],
1218) -> Result<Nullable<Vec<HarmonicMeasurementStruct>>, ClusterError> {
1219 let mut r = TlvReader::new(tlv);
1220 match r.next()? {
1221 Some(Element::Scalar {
1222 value: Value::Null, ..
1223 }) => return Ok(Nullable::Null),
1224 Some(Element::ContainerStart {
1225 kind: ContainerKind::Array,
1226 ..
1227 }) => {}
1228 _ => {
1229 return Err(ClusterError::UnexpectedType {
1230 context: "HarmonicCurrents",
1231 })
1232 }
1233 }
1234 let r = &mut r;
1235 let mut out = Vec::new();
1236 loop {
1237 match r.next()? {
1238 Some(Element::ContainerEnd) => break,
1239 Some(Element::ContainerStart {
1240 kind: ContainerKind::Structure,
1241 ..
1242 }) => {
1243 out.push(HarmonicMeasurementStruct::decode_from(r)?);
1244 }
1245 None => return Err(ClusterError::Tlv(matter_codec::Error::UnclosedContainer)),
1246 Some(Element::ContainerStart { .. }) => r.skip_container()?,
1247 Some(_) => {} }
1249 }
1250 Ok(Nullable::Value(out))
1251}
1252
1253pub fn decode_harmonic_phases(
1258 tlv: &[u8],
1259) -> Result<Nullable<Vec<HarmonicMeasurementStruct>>, ClusterError> {
1260 let mut r = TlvReader::new(tlv);
1261 match r.next()? {
1262 Some(Element::Scalar {
1263 value: Value::Null, ..
1264 }) => return Ok(Nullable::Null),
1265 Some(Element::ContainerStart {
1266 kind: ContainerKind::Array,
1267 ..
1268 }) => {}
1269 _ => {
1270 return Err(ClusterError::UnexpectedType {
1271 context: "HarmonicPhases",
1272 })
1273 }
1274 }
1275 let r = &mut r;
1276 let mut out = Vec::new();
1277 loop {
1278 match r.next()? {
1279 Some(Element::ContainerEnd) => break,
1280 Some(Element::ContainerStart {
1281 kind: ContainerKind::Structure,
1282 ..
1283 }) => {
1284 out.push(HarmonicMeasurementStruct::decode_from(r)?);
1285 }
1286 None => return Err(ClusterError::Tlv(matter_codec::Error::UnclosedContainer)),
1287 Some(Element::ContainerStart { .. }) => r.skip_container()?,
1288 Some(_) => {} }
1290 }
1291 Ok(Nullable::Value(out))
1292}
1293
1294pub fn decode_power_factor(tlv: &[u8]) -> Result<Nullable<i64>, ClusterError> {
1299 let mut r = TlvReader::new(tlv);
1300 match r.next()? {
1301 Some(Element::Scalar {
1302 value: Value::Null, ..
1303 }) => Ok(Nullable::Null),
1304 Some(Element::Scalar {
1305 value: Value::Int(v),
1306 ..
1307 }) => Ok(Nullable::Value(
1308 i64::try_from(v).map_err(|_| ClusterError::InvalidLength("PowerFactor"))?,
1309 )),
1310 _ => Err(ClusterError::UnexpectedType {
1311 context: "PowerFactor",
1312 }),
1313 }
1314}
1315
1316pub fn decode_neutral_current(tlv: &[u8]) -> Result<Nullable<i64>, ClusterError> {
1321 let mut r = TlvReader::new(tlv);
1322 match r.next()? {
1323 Some(Element::Scalar {
1324 value: Value::Null, ..
1325 }) => Ok(Nullable::Null),
1326 Some(Element::Scalar {
1327 value: Value::Int(v),
1328 ..
1329 }) => {
1330 Ok(Nullable::Value(i64::try_from(v).map_err(|_| {
1331 ClusterError::InvalidLength("NeutralCurrent")
1332 })?))
1333 }
1334 _ => Err(ClusterError::UnexpectedType {
1335 context: "NeutralCurrent",
1336 }),
1337 }
1338}