matc/clusters/codec/
commodity_metering.rs1use crate::tlv;
7use anyhow;
8use serde_json;
9
10
11#[derive(Debug, serde::Serialize)]
14pub struct MeteredQuantity {
15 pub tariff_component_i_ds: Option<Vec<u32>>,
16 pub quantity: Option<i64>,
17}
18
19pub 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
42pub 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
51pub 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
60pub 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
70pub fn decode_attribute_json(cluster_id: u32, attribute_id: u32, tlv_value: &crate::tlv::TlvItemValue) -> String {
82 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
116pub 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