matc/clusters/codec/
energy_preference.rs1use crate::tlv;
7use anyhow;
8use serde_json;
9
10
11#[derive(Debug, serde::Serialize)]
14pub struct Balance {
15 pub step: Option<u8>,
16 pub label: Option<String>,
17}
18
19pub fn decode_energy_balances(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<Balance>> {
23 let mut res = Vec::new();
24 if let tlv::TlvItemValue::List(v) = inp {
25 for item in v {
26 res.push(Balance {
27 step: item.get_int(&[0]).map(|v| v as u8),
28 label: item.get_string_owned(&[1]),
29 });
30 }
31 }
32 Ok(res)
33}
34
35pub fn decode_current_energy_balance(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
37 if let tlv::TlvItemValue::Int(v) = inp {
38 Ok(*v as u8)
39 } else {
40 Err(anyhow::anyhow!("Expected Integer"))
41 }
42}
43
44pub fn decode_energy_priorities(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<u8>> {
46 let mut res = Vec::new();
47 if let tlv::TlvItemValue::List(v) = inp {
48 for item in v {
49 if let tlv::TlvItemValue::Int(i) = &item.value {
50 res.push(*i as u8);
51 }
52 }
53 }
54 Ok(res)
55}
56
57pub fn decode_low_power_mode_sensitivities(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<Balance>> {
59 let mut res = Vec::new();
60 if let tlv::TlvItemValue::List(v) = inp {
61 for item in v {
62 res.push(Balance {
63 step: item.get_int(&[0]).map(|v| v as u8),
64 label: item.get_string_owned(&[1]),
65 });
66 }
67 }
68 Ok(res)
69}
70
71pub fn decode_current_low_power_mode_sensitivity(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
73 if let tlv::TlvItemValue::Int(v) = inp {
74 Ok(*v as u8)
75 } else {
76 Err(anyhow::anyhow!("Expected Integer"))
77 }
78}
79
80
81pub fn decode_attribute_json(cluster_id: u32, attribute_id: u32, tlv_value: &crate::tlv::TlvItemValue) -> String {
93 if cluster_id != 0x009B {
95 return format!("{{\"error\": \"Invalid cluster ID. Expected 0x009B, got {}\"}}", cluster_id);
96 }
97
98 match attribute_id {
99 0x0000 => {
100 match decode_energy_balances(tlv_value) {
101 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
102 Err(e) => format!("{{\"error\": \"{}\"}}", e),
103 }
104 }
105 0x0001 => {
106 match decode_current_energy_balance(tlv_value) {
107 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
108 Err(e) => format!("{{\"error\": \"{}\"}}", e),
109 }
110 }
111 0x0002 => {
112 match decode_energy_priorities(tlv_value) {
113 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
114 Err(e) => format!("{{\"error\": \"{}\"}}", e),
115 }
116 }
117 0x0003 => {
118 match decode_low_power_mode_sensitivities(tlv_value) {
119 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
120 Err(e) => format!("{{\"error\": \"{}\"}}", e),
121 }
122 }
123 0x0004 => {
124 match decode_current_low_power_mode_sensitivity(tlv_value) {
125 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
126 Err(e) => format!("{{\"error\": \"{}\"}}", e),
127 }
128 }
129 _ => format!("{{\"error\": \"Unknown attribute ID: {}\"}}", attribute_id),
130 }
131}
132
133pub fn get_attribute_list() -> Vec<(u32, &'static str)> {
138 vec![
139 (0x0000, "EnergyBalances"),
140 (0x0001, "CurrentEnergyBalance"),
141 (0x0002, "EnergyPriorities"),
142 (0x0003, "LowPowerModeSensitivities"),
143 (0x0004, "CurrentLowPowerModeSensitivity"),
144 ]
145}
146