matc/clusters/codec/
meter_identification.rs

1//! Matter TLV encoders and decoders for Meter Identification Cluster
2//! Cluster ID: 0x0B06
3//!
4//! This file is automatically generated from MeterIdentification.xml
5
6use crate::tlv;
7use anyhow;
8use serde_json;
9
10
11// Enum definitions
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
14#[repr(u8)]
15pub enum MeterType {
16    /// Utility Meter
17    Utility = 0,
18    /// Private Meter
19    Private = 1,
20    /// Generic Meter
21    Generic = 2,
22}
23
24impl MeterType {
25    /// Convert from u8 value
26    pub fn from_u8(value: u8) -> Option<Self> {
27        match value {
28            0 => Some(MeterType::Utility),
29            1 => Some(MeterType::Private),
30            2 => Some(MeterType::Generic),
31            _ => None,
32        }
33    }
34
35    /// Convert to u8 value
36    pub fn to_u8(self) -> u8 {
37        self as u8
38    }
39}
40
41impl From<MeterType> for u8 {
42    fn from(val: MeterType) -> Self {
43        val as u8
44    }
45}
46
47// Attribute decoders
48
49/// Decode MeterType attribute (0x0000)
50pub fn decode_meter_type(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<MeterType>> {
51    if let tlv::TlvItemValue::Int(v) = inp {
52        Ok(MeterType::from_u8(*v as u8))
53    } else {
54        Ok(None)
55    }
56}
57
58/// Decode PointOfDelivery attribute (0x0001)
59pub fn decode_point_of_delivery(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<String>> {
60    if let tlv::TlvItemValue::String(v) = inp {
61        Ok(Some(v.clone()))
62    } else {
63        Ok(None)
64    }
65}
66
67/// Decode MeterSerialNumber attribute (0x0002)
68pub fn decode_meter_serial_number(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<String>> {
69    if let tlv::TlvItemValue::String(v) = inp {
70        Ok(Some(v.clone()))
71    } else {
72        Ok(None)
73    }
74}
75
76/// Decode ProtocolVersion attribute (0x0003)
77pub fn decode_protocol_version(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<String>> {
78    if let tlv::TlvItemValue::String(v) = inp {
79        Ok(Some(v.clone()))
80    } else {
81        Ok(None)
82    }
83}
84
85/// Decode PowerThreshold attribute (0x0004)
86pub fn decode_power_threshold(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
87    if let tlv::TlvItemValue::Int(v) = inp {
88        Ok(Some(*v as u8))
89    } else {
90        Ok(None)
91    }
92}
93
94
95// JSON dispatcher function
96
97/// Decode attribute value and return as JSON string
98///
99/// # Parameters
100/// * `cluster_id` - The cluster identifier
101/// * `attribute_id` - The attribute identifier
102/// * `tlv_value` - The TLV value to decode
103///
104/// # Returns
105/// JSON string representation of the decoded value or error
106pub fn decode_attribute_json(cluster_id: u32, attribute_id: u32, tlv_value: &crate::tlv::TlvItemValue) -> String {
107    // Verify this is the correct cluster
108    if cluster_id != 0x0B06 {
109        return format!("{{\"error\": \"Invalid cluster ID. Expected 0x0B06, got {}\"}}", cluster_id);
110    }
111
112    match attribute_id {
113        0x0000 => {
114            match decode_meter_type(tlv_value) {
115                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
116                Err(e) => format!("{{\"error\": \"{}\"}}", e),
117            }
118        }
119        0x0001 => {
120            match decode_point_of_delivery(tlv_value) {
121                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
122                Err(e) => format!("{{\"error\": \"{}\"}}", e),
123            }
124        }
125        0x0002 => {
126            match decode_meter_serial_number(tlv_value) {
127                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
128                Err(e) => format!("{{\"error\": \"{}\"}}", e),
129            }
130        }
131        0x0003 => {
132            match decode_protocol_version(tlv_value) {
133                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
134                Err(e) => format!("{{\"error\": \"{}\"}}", e),
135            }
136        }
137        0x0004 => {
138            match decode_power_threshold(tlv_value) {
139                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
140                Err(e) => format!("{{\"error\": \"{}\"}}", e),
141            }
142        }
143        _ => format!("{{\"error\": \"Unknown attribute ID: {}\"}}", attribute_id),
144    }
145}
146
147/// Get list of all attributes supported by this cluster
148///
149/// # Returns
150/// Vector of tuples containing (attribute_id, attribute_name)
151pub fn get_attribute_list() -> Vec<(u32, &'static str)> {
152    vec![
153        (0x0000, "MeterType"),
154        (0x0001, "PointOfDelivery"),
155        (0x0002, "MeterSerialNumber"),
156        (0x0003, "ProtocolVersion"),
157        (0x0004, "PowerThreshold"),
158    ]
159}
160