#![allow(
clippy::all,
clippy::pedantic,
dead_code,
unreachable_pub,
unused_imports
)]
use crate::datatypes::SemanticTagStruct;
use crate::error::ClusterError;
use crate::types::Nullable;
use matter_codec::{ContainerKind, Element, Tag, TlvReader, TlvWriter, Value};
pub const CLUSTER_ID: u32 = 0x0091;
pub const CLUSTER_REVISION: u16 = 2;
pub mod command_id {}
pub mod attribute_id {
pub const ACCURACY: u32 = 0x0000;
pub const CUMULATIVE_ENERGY_IMPORTED: u32 = 0x0001;
pub const CUMULATIVE_ENERGY_EXPORTED: u32 = 0x0002;
pub const PERIODIC_ENERGY_IMPORTED: u32 = 0x0003;
pub const PERIODIC_ENERGY_EXPORTED: u32 = 0x0004;
pub const CUMULATIVE_ENERGY_RESET: u32 = 0x0005;
}
bitflags::bitflags! {
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct Feature: u32 {
const IMPE = 1 << 0;
const EXPE = 1 << 1;
const CUME = 1 << 2;
const PERE = 1 << 3;
const APPE = 1 << 4;
const REAE = 1 << 5;
}
}
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
pub struct CumulativeEnergyResetStruct {
pub imported_reset_timestamp: Option<Nullable<u32>>,
pub exported_reset_timestamp: Option<Nullable<u32>>,
pub imported_reset_systime: Option<Nullable<u64>>,
pub exported_reset_systime: Option<Nullable<u64>>,
}
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
pub struct EnergyMeasurementStruct {
pub energy: i64,
pub start_timestamp: Option<u32>,
pub end_timestamp: Option<u32>,
pub start_systime: Option<u64>,
pub end_systime: Option<u64>,
pub apparent_energy: Option<i64>,
pub reactive_energy: Option<i64>,
}
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
pub struct MeasurementAccuracyRangeStruct {
pub range_min: i64,
pub range_max: i64,
pub percent_max: Option<u16>,
pub percent_min: Option<u16>,
pub percent_typical: Option<u16>,
pub fixed_max: Option<u64>,
pub fixed_min: Option<u64>,
pub fixed_typical: Option<u64>,
}
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
pub struct MeasurementAccuracyStruct {
pub measurement_type: MeasurementTypeEnum,
pub measured: bool,
pub min_measured_value: i64,
pub max_measured_value: i64,
pub accuracy_ranges: Vec<MeasurementAccuracyRangeStruct>,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum MeasurementTypeEnum {
Unspecified,
Voltage,
ActiveCurrent,
ReactiveCurrent,
ApparentCurrent,
ActivePower,
ReactivePower,
ApparentPower,
RmsVoltage,
RmsCurrent,
RmsPower,
Frequency,
PowerFactor,
NeutralCurrent,
ElectricalEnergy,
ReactiveEnergy,
ApparentEnergy,
Unknown(u16),
}
impl MeasurementTypeEnum {
#[must_use]
pub fn from_raw(v: u16) -> Self {
match v {
0 => Self::Unspecified,
1 => Self::Voltage,
2 => Self::ActiveCurrent,
3 => Self::ReactiveCurrent,
4 => Self::ApparentCurrent,
5 => Self::ActivePower,
6 => Self::ReactivePower,
7 => Self::ApparentPower,
8 => Self::RmsVoltage,
9 => Self::RmsCurrent,
10 => Self::RmsPower,
11 => Self::Frequency,
12 => Self::PowerFactor,
13 => Self::NeutralCurrent,
14 => Self::ElectricalEnergy,
15 => Self::ReactiveEnergy,
16 => Self::ApparentEnergy,
other => Self::Unknown(other),
}
}
#[must_use]
pub fn to_raw(self) -> u16 {
match self {
Self::Unspecified => 0,
Self::Voltage => 1,
Self::ActiveCurrent => 2,
Self::ReactiveCurrent => 3,
Self::ApparentCurrent => 4,
Self::ActivePower => 5,
Self::ReactivePower => 6,
Self::ApparentPower => 7,
Self::RmsVoltage => 8,
Self::RmsCurrent => 9,
Self::RmsPower => 10,
Self::Frequency => 11,
Self::PowerFactor => 12,
Self::NeutralCurrent => 13,
Self::ElectricalEnergy => 14,
Self::ReactiveEnergy => 15,
Self::ApparentEnergy => 16,
Self::Unknown(v) => v,
}
}
}
impl CumulativeEnergyResetStruct {
pub fn decode_from(r: &mut TlvReader<'_>) -> Result<Self, ClusterError> {
let mut f_imported_reset_timestamp: Option<Nullable<u32>> = None;
let mut f_exported_reset_timestamp: Option<Nullable<u32>> = None;
let mut f_imported_reset_systime: Option<Nullable<u64>> = None;
let mut f_exported_reset_systime: Option<Nullable<u64>> = None;
loop {
match r.next()? {
Some(Element::ContainerEnd) => break,
Some(Element::Scalar {
tag: Tag::Context(0),
value: Value::Null,
}) => f_imported_reset_timestamp = Some(Nullable::Null),
Some(Element::Scalar {
tag: Tag::Context(0),
value: Value::Uint(v),
}) => {
f_imported_reset_timestamp =
Some(Nullable::Value(u32::try_from(v).map_err(|_| {
ClusterError::InvalidLength("ImportedResetTimestamp")
})?))
}
Some(Element::Scalar {
tag: Tag::Context(1),
value: Value::Null,
}) => f_exported_reset_timestamp = Some(Nullable::Null),
Some(Element::Scalar {
tag: Tag::Context(1),
value: Value::Uint(v),
}) => {
f_exported_reset_timestamp =
Some(Nullable::Value(u32::try_from(v).map_err(|_| {
ClusterError::InvalidLength("ExportedResetTimestamp")
})?))
}
Some(Element::Scalar {
tag: Tag::Context(2),
value: Value::Null,
}) => f_imported_reset_systime = Some(Nullable::Null),
Some(Element::Scalar {
tag: Tag::Context(2),
value: Value::Uint(v),
}) => {
f_imported_reset_systime =
Some(Nullable::Value(u64::try_from(v).map_err(|_| {
ClusterError::InvalidLength("ImportedResetSystime")
})?))
}
Some(Element::Scalar {
tag: Tag::Context(3),
value: Value::Null,
}) => f_exported_reset_systime = Some(Nullable::Null),
Some(Element::Scalar {
tag: Tag::Context(3),
value: Value::Uint(v),
}) => {
f_exported_reset_systime =
Some(Nullable::Value(u64::try_from(v).map_err(|_| {
ClusterError::InvalidLength("ExportedResetSystime")
})?))
}
None => return Err(ClusterError::Tlv(matter_codec::Error::UnclosedContainer)),
Some(Element::ContainerStart { .. }) => r.skip_container()?,
Some(_) => {} }
}
Ok(Self {
imported_reset_timestamp: f_imported_reset_timestamp,
exported_reset_timestamp: f_exported_reset_timestamp,
imported_reset_systime: f_imported_reset_systime,
exported_reset_systime: f_exported_reset_systime,
})
}
pub fn decode(tlv: &[u8]) -> Result<Self, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::ContainerStart {
kind: ContainerKind::Structure,
..
}) => {}
_ => {
return Err(ClusterError::UnexpectedType {
context: "CumulativeEnergyResetStruct",
})
}
}
Self::decode_from(&mut r)
}
#[allow(clippy::expect_used)] pub fn write_fields(&self, w: &mut TlvWriter<'_>) {
if let Some(imported_reset_timestamp) = &self.imported_reset_timestamp {
match imported_reset_timestamp {
Nullable::Null => w.put_null(Tag::Context(0)).expect("infallible: vec writer"),
Nullable::Value(imported_reset_timestamp) => {
w.put_uint(Tag::Context(0), u64::from(*imported_reset_timestamp))
.expect("infallible: vec writer");
}
}
}
if let Some(exported_reset_timestamp) = &self.exported_reset_timestamp {
match exported_reset_timestamp {
Nullable::Null => w.put_null(Tag::Context(1)).expect("infallible: vec writer"),
Nullable::Value(exported_reset_timestamp) => {
w.put_uint(Tag::Context(1), u64::from(*exported_reset_timestamp))
.expect("infallible: vec writer");
}
}
}
if let Some(imported_reset_systime) = &self.imported_reset_systime {
match imported_reset_systime {
Nullable::Null => w.put_null(Tag::Context(2)).expect("infallible: vec writer"),
Nullable::Value(imported_reset_systime) => {
w.put_uint(Tag::Context(2), u64::from(*imported_reset_systime))
.expect("infallible: vec writer");
}
}
}
if let Some(exported_reset_systime) = &self.exported_reset_systime {
match exported_reset_systime {
Nullable::Null => w.put_null(Tag::Context(3)).expect("infallible: vec writer"),
Nullable::Value(exported_reset_systime) => {
w.put_uint(Tag::Context(3), u64::from(*exported_reset_systime))
.expect("infallible: vec writer");
}
}
}
}
#[must_use]
#[allow(clippy::expect_used)] pub fn encode(&self) -> Vec<u8> {
let mut buf = Vec::new();
let mut w = TlvWriter::new(&mut buf);
w.start_structure(Tag::Anonymous)
.expect("infallible: vec writer");
self.write_fields(&mut w);
w.end_container().expect("infallible: vec writer");
buf
}
}
impl EnergyMeasurementStruct {
pub fn decode_from(r: &mut TlvReader<'_>) -> Result<Self, ClusterError> {
let mut f_energy: Option<i64> = None;
let mut f_start_timestamp: Option<u32> = None;
let mut f_end_timestamp: Option<u32> = None;
let mut f_start_systime: Option<u64> = None;
let mut f_end_systime: Option<u64> = None;
let mut f_apparent_energy: Option<i64> = None;
let mut f_reactive_energy: Option<i64> = None;
loop {
match r.next()? {
Some(Element::ContainerEnd) => break,
Some(Element::Scalar {
tag: Tag::Context(0),
value: Value::Int(v),
}) => {
f_energy =
Some(i64::try_from(v).map_err(|_| ClusterError::InvalidLength("Energy"))?)
}
Some(Element::Scalar {
tag: Tag::Context(1),
value: Value::Uint(v),
}) => {
f_start_timestamp = Some(
u32::try_from(v)
.map_err(|_| ClusterError::InvalidLength("StartTimestamp"))?,
)
}
Some(Element::Scalar {
tag: Tag::Context(2),
value: Value::Uint(v),
}) => {
f_end_timestamp = Some(
u32::try_from(v)
.map_err(|_| ClusterError::InvalidLength("EndTimestamp"))?,
)
}
Some(Element::Scalar {
tag: Tag::Context(3),
value: Value::Uint(v),
}) => {
f_start_systime = Some(
u64::try_from(v)
.map_err(|_| ClusterError::InvalidLength("StartSystime"))?,
)
}
Some(Element::Scalar {
tag: Tag::Context(4),
value: Value::Uint(v),
}) => {
f_end_systime = Some(
u64::try_from(v).map_err(|_| ClusterError::InvalidLength("EndSystime"))?,
)
}
Some(Element::Scalar {
tag: Tag::Context(5),
value: Value::Int(v),
}) => {
f_apparent_energy = Some(
i64::try_from(v)
.map_err(|_| ClusterError::InvalidLength("ApparentEnergy"))?,
)
}
Some(Element::Scalar {
tag: Tag::Context(6),
value: Value::Int(v),
}) => {
f_reactive_energy = Some(
i64::try_from(v)
.map_err(|_| ClusterError::InvalidLength("ReactiveEnergy"))?,
)
}
None => return Err(ClusterError::Tlv(matter_codec::Error::UnclosedContainer)),
Some(Element::ContainerStart { .. }) => r.skip_container()?,
Some(_) => {} }
}
Ok(Self {
energy: f_energy.ok_or(ClusterError::MissingField("Energy"))?,
start_timestamp: f_start_timestamp,
end_timestamp: f_end_timestamp,
start_systime: f_start_systime,
end_systime: f_end_systime,
apparent_energy: f_apparent_energy,
reactive_energy: f_reactive_energy,
})
}
pub fn decode(tlv: &[u8]) -> Result<Self, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::ContainerStart {
kind: ContainerKind::Structure,
..
}) => {}
_ => {
return Err(ClusterError::UnexpectedType {
context: "EnergyMeasurementStruct",
})
}
}
Self::decode_from(&mut r)
}
#[allow(clippy::expect_used)] pub fn write_fields(&self, w: &mut TlvWriter<'_>) {
w.put_int(Tag::Context(0), i64::from(self.energy))
.expect("infallible: vec writer");
if let Some(start_timestamp) = &self.start_timestamp {
w.put_uint(Tag::Context(1), u64::from(*start_timestamp))
.expect("infallible: vec writer");
}
if let Some(end_timestamp) = &self.end_timestamp {
w.put_uint(Tag::Context(2), u64::from(*end_timestamp))
.expect("infallible: vec writer");
}
if let Some(start_systime) = &self.start_systime {
w.put_uint(Tag::Context(3), u64::from(*start_systime))
.expect("infallible: vec writer");
}
if let Some(end_systime) = &self.end_systime {
w.put_uint(Tag::Context(4), u64::from(*end_systime))
.expect("infallible: vec writer");
}
if let Some(apparent_energy) = &self.apparent_energy {
w.put_int(Tag::Context(5), i64::from(*apparent_energy))
.expect("infallible: vec writer");
}
if let Some(reactive_energy) = &self.reactive_energy {
w.put_int(Tag::Context(6), i64::from(*reactive_energy))
.expect("infallible: vec writer");
}
}
#[must_use]
#[allow(clippy::expect_used)] pub fn encode(&self) -> Vec<u8> {
let mut buf = Vec::new();
let mut w = TlvWriter::new(&mut buf);
w.start_structure(Tag::Anonymous)
.expect("infallible: vec writer");
self.write_fields(&mut w);
w.end_container().expect("infallible: vec writer");
buf
}
}
impl MeasurementAccuracyRangeStruct {
pub fn decode_from(r: &mut TlvReader<'_>) -> Result<Self, ClusterError> {
let mut f_range_min: Option<i64> = None;
let mut f_range_max: Option<i64> = None;
let mut f_percent_max: Option<u16> = None;
let mut f_percent_min: Option<u16> = None;
let mut f_percent_typical: Option<u16> = None;
let mut f_fixed_max: Option<u64> = None;
let mut f_fixed_min: Option<u64> = None;
let mut f_fixed_typical: Option<u64> = None;
loop {
match r.next()? {
Some(Element::ContainerEnd) => break,
Some(Element::Scalar {
tag: Tag::Context(0),
value: Value::Int(v),
}) => {
f_range_min = Some(
i64::try_from(v).map_err(|_| ClusterError::InvalidLength("RangeMin"))?,
)
}
Some(Element::Scalar {
tag: Tag::Context(1),
value: Value::Int(v),
}) => {
f_range_max = Some(
i64::try_from(v).map_err(|_| ClusterError::InvalidLength("RangeMax"))?,
)
}
Some(Element::Scalar {
tag: Tag::Context(2),
value: Value::Uint(v),
}) => {
f_percent_max = Some(
u16::try_from(v).map_err(|_| ClusterError::InvalidLength("PercentMax"))?,
)
}
Some(Element::Scalar {
tag: Tag::Context(3),
value: Value::Uint(v),
}) => {
f_percent_min = Some(
u16::try_from(v).map_err(|_| ClusterError::InvalidLength("PercentMin"))?,
)
}
Some(Element::Scalar {
tag: Tag::Context(4),
value: Value::Uint(v),
}) => {
f_percent_typical = Some(
u16::try_from(v)
.map_err(|_| ClusterError::InvalidLength("PercentTypical"))?,
)
}
Some(Element::Scalar {
tag: Tag::Context(5),
value: Value::Uint(v),
}) => {
f_fixed_max = Some(
u64::try_from(v).map_err(|_| ClusterError::InvalidLength("FixedMax"))?,
)
}
Some(Element::Scalar {
tag: Tag::Context(6),
value: Value::Uint(v),
}) => {
f_fixed_min = Some(
u64::try_from(v).map_err(|_| ClusterError::InvalidLength("FixedMin"))?,
)
}
Some(Element::Scalar {
tag: Tag::Context(7),
value: Value::Uint(v),
}) => {
f_fixed_typical = Some(
u64::try_from(v)
.map_err(|_| ClusterError::InvalidLength("FixedTypical"))?,
)
}
None => return Err(ClusterError::Tlv(matter_codec::Error::UnclosedContainer)),
Some(Element::ContainerStart { .. }) => r.skip_container()?,
Some(_) => {} }
}
Ok(Self {
range_min: f_range_min.ok_or(ClusterError::MissingField("RangeMin"))?,
range_max: f_range_max.ok_or(ClusterError::MissingField("RangeMax"))?,
percent_max: f_percent_max,
percent_min: f_percent_min,
percent_typical: f_percent_typical,
fixed_max: f_fixed_max,
fixed_min: f_fixed_min,
fixed_typical: f_fixed_typical,
})
}
pub fn decode(tlv: &[u8]) -> Result<Self, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::ContainerStart {
kind: ContainerKind::Structure,
..
}) => {}
_ => {
return Err(ClusterError::UnexpectedType {
context: "MeasurementAccuracyRangeStruct",
})
}
}
Self::decode_from(&mut r)
}
#[allow(clippy::expect_used)] pub fn write_fields(&self, w: &mut TlvWriter<'_>) {
w.put_int(Tag::Context(0), i64::from(self.range_min))
.expect("infallible: vec writer");
w.put_int(Tag::Context(1), i64::from(self.range_max))
.expect("infallible: vec writer");
if let Some(percent_max) = &self.percent_max {
w.put_uint(Tag::Context(2), u64::from(*percent_max))
.expect("infallible: vec writer");
}
if let Some(percent_min) = &self.percent_min {
w.put_uint(Tag::Context(3), u64::from(*percent_min))
.expect("infallible: vec writer");
}
if let Some(percent_typical) = &self.percent_typical {
w.put_uint(Tag::Context(4), u64::from(*percent_typical))
.expect("infallible: vec writer");
}
if let Some(fixed_max) = &self.fixed_max {
w.put_uint(Tag::Context(5), u64::from(*fixed_max))
.expect("infallible: vec writer");
}
if let Some(fixed_min) = &self.fixed_min {
w.put_uint(Tag::Context(6), u64::from(*fixed_min))
.expect("infallible: vec writer");
}
if let Some(fixed_typical) = &self.fixed_typical {
w.put_uint(Tag::Context(7), u64::from(*fixed_typical))
.expect("infallible: vec writer");
}
}
#[must_use]
#[allow(clippy::expect_used)] pub fn encode(&self) -> Vec<u8> {
let mut buf = Vec::new();
let mut w = TlvWriter::new(&mut buf);
w.start_structure(Tag::Anonymous)
.expect("infallible: vec writer");
self.write_fields(&mut w);
w.end_container().expect("infallible: vec writer");
buf
}
}
impl MeasurementAccuracyStruct {
pub fn decode_from(r: &mut TlvReader<'_>) -> Result<Self, ClusterError> {
let mut f_measurement_type: Option<MeasurementTypeEnum> = None;
let mut f_measured: Option<bool> = None;
let mut f_min_measured_value: Option<i64> = None;
let mut f_max_measured_value: Option<i64> = None;
let mut f_accuracy_ranges: Option<Vec<MeasurementAccuracyRangeStruct>> = None;
loop {
match r.next()? {
Some(Element::ContainerEnd) => break,
Some(Element::Scalar {
tag: Tag::Context(0),
value: Value::Uint(v),
}) => {
f_measurement_type = Some(MeasurementTypeEnum::from_raw(
u16::try_from(v)
.map_err(|_| ClusterError::InvalidLength("MeasurementType"))?,
))
}
Some(Element::Scalar {
tag: Tag::Context(1),
value: Value::Bool(v),
}) => f_measured = Some(v),
Some(Element::Scalar {
tag: Tag::Context(2),
value: Value::Int(v),
}) => {
f_min_measured_value = Some(
i64::try_from(v)
.map_err(|_| ClusterError::InvalidLength("MinMeasuredValue"))?,
)
}
Some(Element::Scalar {
tag: Tag::Context(3),
value: Value::Int(v),
}) => {
f_max_measured_value = Some(
i64::try_from(v)
.map_err(|_| ClusterError::InvalidLength("MaxMeasuredValue"))?,
)
}
Some(Element::ContainerStart {
tag: Tag::Context(4),
kind: ContainerKind::Array,
}) => {
let mut out = Vec::new();
loop {
match r.next()? {
Some(Element::ContainerEnd) => break,
Some(Element::ContainerStart {
kind: ContainerKind::Structure,
..
}) => {
out.push(MeasurementAccuracyRangeStruct::decode_from(r)?);
}
None => {
return Err(ClusterError::Tlv(
matter_codec::Error::UnclosedContainer,
))
}
Some(Element::ContainerStart { .. }) => r.skip_container()?,
Some(_) => {} }
}
f_accuracy_ranges = Some(out);
}
None => return Err(ClusterError::Tlv(matter_codec::Error::UnclosedContainer)),
Some(Element::ContainerStart { .. }) => r.skip_container()?,
Some(_) => {} }
}
Ok(Self {
measurement_type: f_measurement_type
.ok_or(ClusterError::MissingField("MeasurementType"))?,
measured: f_measured.ok_or(ClusterError::MissingField("Measured"))?,
min_measured_value: f_min_measured_value
.ok_or(ClusterError::MissingField("MinMeasuredValue"))?,
max_measured_value: f_max_measured_value
.ok_or(ClusterError::MissingField("MaxMeasuredValue"))?,
accuracy_ranges: f_accuracy_ranges
.ok_or(ClusterError::MissingField("AccuracyRanges"))?,
})
}
pub fn decode(tlv: &[u8]) -> Result<Self, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::ContainerStart {
kind: ContainerKind::Structure,
..
}) => {}
_ => {
return Err(ClusterError::UnexpectedType {
context: "MeasurementAccuracyStruct",
})
}
}
Self::decode_from(&mut r)
}
}
pub fn decode_accuracy(tlv: &[u8]) -> Result<MeasurementAccuracyStruct, ClusterError> {
MeasurementAccuracyStruct::decode(tlv)
}
pub fn decode_cumulative_energy_imported(
tlv: &[u8],
) -> Result<Nullable<EnergyMeasurementStruct>, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::Scalar {
value: Value::Null, ..
}) => Ok(Nullable::Null),
Some(Element::ContainerStart {
kind: ContainerKind::Structure,
..
}) => Ok(Nullable::Value(EnergyMeasurementStruct::decode_from(
&mut r,
)?)),
_ => Err(ClusterError::UnexpectedType {
context: "CumulativeEnergyImported",
}),
}
}
pub fn decode_cumulative_energy_exported(
tlv: &[u8],
) -> Result<Nullable<EnergyMeasurementStruct>, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::Scalar {
value: Value::Null, ..
}) => Ok(Nullable::Null),
Some(Element::ContainerStart {
kind: ContainerKind::Structure,
..
}) => Ok(Nullable::Value(EnergyMeasurementStruct::decode_from(
&mut r,
)?)),
_ => Err(ClusterError::UnexpectedType {
context: "CumulativeEnergyExported",
}),
}
}
pub fn decode_periodic_energy_imported(
tlv: &[u8],
) -> Result<Nullable<EnergyMeasurementStruct>, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::Scalar {
value: Value::Null, ..
}) => Ok(Nullable::Null),
Some(Element::ContainerStart {
kind: ContainerKind::Structure,
..
}) => Ok(Nullable::Value(EnergyMeasurementStruct::decode_from(
&mut r,
)?)),
_ => Err(ClusterError::UnexpectedType {
context: "PeriodicEnergyImported",
}),
}
}
pub fn decode_periodic_energy_exported(
tlv: &[u8],
) -> Result<Nullable<EnergyMeasurementStruct>, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::Scalar {
value: Value::Null, ..
}) => Ok(Nullable::Null),
Some(Element::ContainerStart {
kind: ContainerKind::Structure,
..
}) => Ok(Nullable::Value(EnergyMeasurementStruct::decode_from(
&mut r,
)?)),
_ => Err(ClusterError::UnexpectedType {
context: "PeriodicEnergyExported",
}),
}
}
pub fn decode_cumulative_energy_reset(
tlv: &[u8],
) -> Result<Nullable<CumulativeEnergyResetStruct>, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::Scalar {
value: Value::Null, ..
}) => Ok(Nullable::Null),
Some(Element::ContainerStart {
kind: ContainerKind::Structure,
..
}) => Ok(Nullable::Value(CumulativeEnergyResetStruct::decode_from(
&mut r,
)?)),
_ => Err(ClusterError::UnexpectedType {
context: "CumulativeEnergyReset",
}),
}
}