matc/clusters/codec/
commodity_metering.rs

1//! Matter TLV encoders and decoders for Commodity Metering Cluster
2//! Cluster ID: 0x0B07
3//!
4//! This file is automatically generated from CommodityMetering.xml
5
6use crate::tlv;
7use anyhow;
8use serde_json;
9
10
11// Struct definitions
12
13#[derive(Debug, serde::Serialize)]
14pub struct MeteredQuantity {
15    pub tariff_component_i_ds: Option<Vec<u32>>,
16    pub quantity: Option<i64>,
17}
18
19// Attribute decoders
20
21/// Decode MeteredQuantity attribute (0x0000)
22pub fn decode_metered_quantity(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<MeteredQuantity>> {
23    let mut res = Vec::new();
24    if let tlv::TlvItemValue::List(v) = inp {
25        for item in v {
26            res.push(MeteredQuantity {
27                tariff_component_i_ds: {
28                    if let Some(tlv::TlvItemValue::List(l)) = item.get(&[0]) {
29                        let items: Vec<u32> = l.iter().filter_map(|e| { if let tlv::TlvItemValue::Int(v) = &e.value { Some(*v as u32) } else { None } }).collect();
30                        Some(items)
31                    } else {
32                        None
33                    }
34                },
35                quantity: item.get_int(&[1]).map(|v| v as i64),
36            });
37        }
38    }
39    Ok(res)
40}
41
42/// Decode MeteredQuantityTimestamp attribute (0x0001)
43pub fn decode_metered_quantity_timestamp(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u64>> {
44    if let tlv::TlvItemValue::Int(v) = inp {
45        Ok(Some(*v))
46    } else {
47        Ok(None)
48    }
49}
50
51/// Decode TariffUnit attribute (0x0002)
52pub fn decode_tariff_unit(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
53    if let tlv::TlvItemValue::Int(v) = inp {
54        Ok(Some(*v as u8))
55    } else {
56        Ok(None)
57    }
58}
59
60/// Decode MaximumMeteredQuantities attribute (0x0003)
61pub fn decode_maximum_metered_quantities(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u16>> {
62    if let tlv::TlvItemValue::Int(v) = inp {
63        Ok(Some(*v as u16))
64    } else {
65        Ok(None)
66    }
67}
68
69
70// JSON dispatcher function
71
72/// Decode attribute value and return as JSON string
73///
74/// # Parameters
75/// * `cluster_id` - The cluster identifier
76/// * `attribute_id` - The attribute identifier
77/// * `tlv_value` - The TLV value to decode
78///
79/// # Returns
80/// JSON string representation of the decoded value or error
81pub fn decode_attribute_json(cluster_id: u32, attribute_id: u32, tlv_value: &crate::tlv::TlvItemValue) -> String {
82    // Verify this is the correct cluster
83    if cluster_id != 0x0B07 {
84        return format!("{{\"error\": \"Invalid cluster ID. Expected 0x0B07, got {}\"}}", cluster_id);
85    }
86
87    match attribute_id {
88        0x0000 => {
89            match decode_metered_quantity(tlv_value) {
90                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
91                Err(e) => format!("{{\"error\": \"{}\"}}", e),
92            }
93        }
94        0x0001 => {
95            match decode_metered_quantity_timestamp(tlv_value) {
96                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
97                Err(e) => format!("{{\"error\": \"{}\"}}", e),
98            }
99        }
100        0x0002 => {
101            match decode_tariff_unit(tlv_value) {
102                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
103                Err(e) => format!("{{\"error\": \"{}\"}}", e),
104            }
105        }
106        0x0003 => {
107            match decode_maximum_metered_quantities(tlv_value) {
108                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
109                Err(e) => format!("{{\"error\": \"{}\"}}", e),
110            }
111        }
112        _ => format!("{{\"error\": \"Unknown attribute ID: {}\"}}", attribute_id),
113    }
114}
115
116/// Get list of all attributes supported by this cluster
117///
118/// # Returns
119/// Vector of tuples containing (attribute_id, attribute_name)
120pub fn get_attribute_list() -> Vec<(u32, &'static str)> {
121    vec![
122        (0x0000, "MeteredQuantity"),
123        (0x0001, "MeteredQuantityTimestamp"),
124        (0x0002, "TariffUnit"),
125        (0x0003, "MaximumMeteredQuantities"),
126    ]
127}
128