matc/clusters/codec/
alarm_base.rs1use crate::tlv;
7use anyhow;
8use serde_json;
9
10
11pub type Alarm = u8;
15
16pub fn encode_reset(alarms: Alarm) -> anyhow::Result<Vec<u8>> {
20 let tlv = tlv::TlvItemEnc {
21 tag: 0,
22 value: tlv::TlvItemValueEnc::StructInvisible(vec![
23 (0, tlv::TlvItemValueEnc::UInt8(alarms)).into(),
24 ]),
25 };
26 Ok(tlv.encode()?)
27}
28
29pub fn encode_modify_enabled_alarms(mask: Alarm) -> anyhow::Result<Vec<u8>> {
31 let tlv = tlv::TlvItemEnc {
32 tag: 0,
33 value: tlv::TlvItemValueEnc::StructInvisible(vec![
34 (0, tlv::TlvItemValueEnc::UInt8(mask)).into(),
35 ]),
36 };
37 Ok(tlv.encode()?)
38}
39
40pub fn decode_mask(inp: &tlv::TlvItemValue) -> anyhow::Result<Alarm> {
44 if let tlv::TlvItemValue::Int(v) = inp {
45 Ok(*v as u8)
46 } else {
47 Err(anyhow::anyhow!("Expected Integer"))
48 }
49}
50
51pub fn decode_latch(inp: &tlv::TlvItemValue) -> anyhow::Result<Alarm> {
53 if let tlv::TlvItemValue::Int(v) = inp {
54 Ok(*v as u8)
55 } else {
56 Err(anyhow::anyhow!("Expected Integer"))
57 }
58}
59
60pub fn decode_state(inp: &tlv::TlvItemValue) -> anyhow::Result<Alarm> {
62 if let tlv::TlvItemValue::Int(v) = inp {
63 Ok(*v as u8)
64 } else {
65 Err(anyhow::anyhow!("Expected Integer"))
66 }
67}
68
69pub fn decode_supported(inp: &tlv::TlvItemValue) -> anyhow::Result<Alarm> {
71 if let tlv::TlvItemValue::Int(v) = inp {
72 Ok(*v as u8)
73 } else {
74 Err(anyhow::anyhow!("Expected Integer"))
75 }
76}
77
78
79pub fn decode_attribute_json(cluster_id: u32, attribute_id: u32, tlv_value: &crate::tlv::TlvItemValue) -> String {
91 if cluster_id != 0x0000 {
93 return format!("{{\"error\": \"Invalid cluster ID. Expected 0x0000, got {}\"}}", cluster_id);
94 }
95
96 match attribute_id {
97 0x0000 => {
98 match decode_mask(tlv_value) {
99 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
100 Err(e) => format!("{{\"error\": \"{}\"}}", e),
101 }
102 }
103 0x0001 => {
104 match decode_latch(tlv_value) {
105 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
106 Err(e) => format!("{{\"error\": \"{}\"}}", e),
107 }
108 }
109 0x0002 => {
110 match decode_state(tlv_value) {
111 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
112 Err(e) => format!("{{\"error\": \"{}\"}}", e),
113 }
114 }
115 0x0003 => {
116 match decode_supported(tlv_value) {
117 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
118 Err(e) => format!("{{\"error\": \"{}\"}}", e),
119 }
120 }
121 _ => format!("{{\"error\": \"Unknown attribute ID: {}\"}}", attribute_id),
122 }
123}
124
125pub fn get_attribute_list() -> Vec<(u32, &'static str)> {
130 vec![
131 (0x0000, "Mask"),
132 (0x0001, "Latch"),
133 (0x0002, "State"),
134 (0x0003, "Supported"),
135 ]
136}
137
138#[derive(Debug, serde::Serialize)]
139pub struct NotifyEvent {
140 pub active: Option<Alarm>,
141 pub inactive: Option<Alarm>,
142 pub state: Option<Alarm>,
143 pub mask: Option<Alarm>,
144}
145
146pub fn decode_notify_event(inp: &tlv::TlvItemValue) -> anyhow::Result<NotifyEvent> {
150 if let tlv::TlvItemValue::List(_fields) = inp {
151 let item = tlv::TlvItem { tag: 0, value: inp.clone() };
152 Ok(NotifyEvent {
153 active: item.get_int(&[0]).map(|v| v as u8),
154 inactive: item.get_int(&[1]).map(|v| v as u8),
155 state: item.get_int(&[2]).map(|v| v as u8),
156 mask: item.get_int(&[3]).map(|v| v as u8),
157 })
158 } else {
159 Err(anyhow::anyhow!("Expected struct fields"))
160 }
161}
162