matc/clusters/codec/
boolean_state_configuration.rs1use crate::tlv;
7use anyhow;
8use serde_json;
9
10
11pub type AlarmMode = u8;
15
16pub mod alarmmode {
18 pub const VISUAL: u8 = 0x01;
20 pub const AUDIBLE: u8 = 0x02;
22}
23
24pub type SensorFault = u8;
26
27pub mod sensorfault {
29 pub const GENERAL_FAULT: u8 = 0x01;
31}
32
33pub fn encode_suppress_alarm(alarms_to_suppress: AlarmMode) -> anyhow::Result<Vec<u8>> {
37 let tlv = tlv::TlvItemEnc {
38 tag: 0,
39 value: tlv::TlvItemValueEnc::StructInvisible(vec![
40 (0, tlv::TlvItemValueEnc::UInt8(alarms_to_suppress)).into(),
41 ]),
42 };
43 Ok(tlv.encode()?)
44}
45
46pub fn encode_enable_disable_alarm(alarms_to_enable_disable: AlarmMode) -> anyhow::Result<Vec<u8>> {
48 let tlv = tlv::TlvItemEnc {
49 tag: 0,
50 value: tlv::TlvItemValueEnc::StructInvisible(vec![
51 (0, tlv::TlvItemValueEnc::UInt8(alarms_to_enable_disable)).into(),
52 ]),
53 };
54 Ok(tlv.encode()?)
55}
56
57pub fn decode_current_sensitivity_level(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
61 if let tlv::TlvItemValue::Int(v) = inp {
62 Ok(*v as u8)
63 } else {
64 Err(anyhow::anyhow!("Expected UInt8"))
65 }
66}
67
68pub fn decode_supported_sensitivity_levels(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
70 if let tlv::TlvItemValue::Int(v) = inp {
71 Ok(*v as u8)
72 } else {
73 Err(anyhow::anyhow!("Expected UInt8"))
74 }
75}
76
77pub fn decode_default_sensitivity_level(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
79 if let tlv::TlvItemValue::Int(v) = inp {
80 Ok(*v as u8)
81 } else {
82 Err(anyhow::anyhow!("Expected UInt8"))
83 }
84}
85
86pub fn decode_alarms_active(inp: &tlv::TlvItemValue) -> anyhow::Result<AlarmMode> {
88 if let tlv::TlvItemValue::Int(v) = inp {
89 Ok(*v as u8)
90 } else {
91 Err(anyhow::anyhow!("Expected Integer"))
92 }
93}
94
95pub fn decode_alarms_suppressed(inp: &tlv::TlvItemValue) -> anyhow::Result<AlarmMode> {
97 if let tlv::TlvItemValue::Int(v) = inp {
98 Ok(*v as u8)
99 } else {
100 Err(anyhow::anyhow!("Expected Integer"))
101 }
102}
103
104pub fn decode_alarms_enabled(inp: &tlv::TlvItemValue) -> anyhow::Result<AlarmMode> {
106 if let tlv::TlvItemValue::Int(v) = inp {
107 Ok(*v as u8)
108 } else {
109 Err(anyhow::anyhow!("Expected Integer"))
110 }
111}
112
113pub fn decode_alarms_supported(inp: &tlv::TlvItemValue) -> anyhow::Result<AlarmMode> {
115 if let tlv::TlvItemValue::Int(v) = inp {
116 Ok(*v as u8)
117 } else {
118 Err(anyhow::anyhow!("Expected Integer"))
119 }
120}
121
122pub fn decode_sensor_fault(inp: &tlv::TlvItemValue) -> anyhow::Result<SensorFault> {
124 if let tlv::TlvItemValue::Int(v) = inp {
125 Ok(*v as u8)
126 } else {
127 Err(anyhow::anyhow!("Expected Integer"))
128 }
129}
130
131
132pub fn decode_attribute_json(cluster_id: u32, attribute_id: u32, tlv_value: &crate::tlv::TlvItemValue) -> String {
144 if cluster_id != 0x0080 {
146 return format!("{{\"error\": \"Invalid cluster ID. Expected 0x0080, got {}\"}}", cluster_id);
147 }
148
149 match attribute_id {
150 0x0000 => {
151 match decode_current_sensitivity_level(tlv_value) {
152 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
153 Err(e) => format!("{{\"error\": \"{}\"}}", e),
154 }
155 }
156 0x0001 => {
157 match decode_supported_sensitivity_levels(tlv_value) {
158 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
159 Err(e) => format!("{{\"error\": \"{}\"}}", e),
160 }
161 }
162 0x0002 => {
163 match decode_default_sensitivity_level(tlv_value) {
164 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
165 Err(e) => format!("{{\"error\": \"{}\"}}", e),
166 }
167 }
168 0x0003 => {
169 match decode_alarms_active(tlv_value) {
170 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
171 Err(e) => format!("{{\"error\": \"{}\"}}", e),
172 }
173 }
174 0x0004 => {
175 match decode_alarms_suppressed(tlv_value) {
176 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
177 Err(e) => format!("{{\"error\": \"{}\"}}", e),
178 }
179 }
180 0x0005 => {
181 match decode_alarms_enabled(tlv_value) {
182 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
183 Err(e) => format!("{{\"error\": \"{}\"}}", e),
184 }
185 }
186 0x0006 => {
187 match decode_alarms_supported(tlv_value) {
188 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
189 Err(e) => format!("{{\"error\": \"{}\"}}", e),
190 }
191 }
192 0x0007 => {
193 match decode_sensor_fault(tlv_value) {
194 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
195 Err(e) => format!("{{\"error\": \"{}\"}}", e),
196 }
197 }
198 _ => format!("{{\"error\": \"Unknown attribute ID: {}\"}}", attribute_id),
199 }
200}
201
202pub fn get_attribute_list() -> Vec<(u32, &'static str)> {
207 vec![
208 (0x0000, "CurrentSensitivityLevel"),
209 (0x0001, "SupportedSensitivityLevels"),
210 (0x0002, "DefaultSensitivityLevel"),
211 (0x0003, "AlarmsActive"),
212 (0x0004, "AlarmsSuppressed"),
213 (0x0005, "AlarmsEnabled"),
214 (0x0006, "AlarmsSupported"),
215 (0x0007, "SensorFault"),
216 ]
217}
218
219#[derive(Debug, serde::Serialize)]
220pub struct AlarmsStateChangedEvent {
221 pub alarms_active: Option<AlarmMode>,
222 pub alarms_suppressed: Option<AlarmMode>,
223}
224
225#[derive(Debug, serde::Serialize)]
226pub struct SensorFaultEvent {
227 pub sensor_fault: Option<SensorFault>,
228}
229
230pub fn decode_alarms_state_changed_event(inp: &tlv::TlvItemValue) -> anyhow::Result<AlarmsStateChangedEvent> {
234 if let tlv::TlvItemValue::List(_fields) = inp {
235 let item = tlv::TlvItem { tag: 0, value: inp.clone() };
236 Ok(AlarmsStateChangedEvent {
237 alarms_active: item.get_int(&[0]).map(|v| v as u8),
238 alarms_suppressed: item.get_int(&[1]).map(|v| v as u8),
239 })
240 } else {
241 Err(anyhow::anyhow!("Expected struct fields"))
242 }
243}
244
245pub fn decode_sensor_fault_event(inp: &tlv::TlvItemValue) -> anyhow::Result<SensorFaultEvent> {
247 if let tlv::TlvItemValue::List(_fields) = inp {
248 let item = tlv::TlvItem { tag: 0, value: inp.clone() };
249 Ok(SensorFaultEvent {
250 sensor_fault: item.get_int(&[0]).map(|v| v as u8),
251 })
252 } else {
253 Err(anyhow::anyhow!("Expected struct fields"))
254 }
255}
256