matc/clusters/codec/
boolean_state_configuration.rs

1//! Matter TLV encoders and decoders for Boolean State Configuration Cluster
2//! Cluster ID: 0x0080
3//!
4//! This file is automatically generated from BooleanStateConfiguration.xml
5
6use crate::tlv;
7use anyhow;
8use serde_json;
9
10
11// Bitmap definitions
12
13/// AlarmMode bitmap type
14pub type AlarmMode = u8;
15
16/// Constants for AlarmMode
17pub mod alarmmode {
18    /// Visual alarming
19    pub const VISUAL: u8 = 0x01;
20    /// Audible alarming
21    pub const AUDIBLE: u8 = 0x02;
22}
23
24/// SensorFault bitmap type
25pub type SensorFault = u8;
26
27/// Constants for SensorFault
28pub mod sensorfault {
29    /// Unspecified fault detected
30    pub const GENERAL_FAULT: u8 = 0x01;
31}
32
33// Command encoders
34
35/// Encode SuppressAlarm command (0x00)
36pub 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
46/// Encode EnableDisableAlarm command (0x01)
47pub 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
57// Attribute decoders
58
59/// Decode CurrentSensitivityLevel attribute (0x0000)
60pub 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
68/// Decode SupportedSensitivityLevels attribute (0x0001)
69pub 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
77/// Decode DefaultSensitivityLevel attribute (0x0002)
78pub 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
86/// Decode AlarmsActive attribute (0x0003)
87pub 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
95/// Decode AlarmsSuppressed attribute (0x0004)
96pub 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
104/// Decode AlarmsEnabled attribute (0x0005)
105pub 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
113/// Decode AlarmsSupported attribute (0x0006)
114pub 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
122/// Decode SensorFault attribute (0x0007)
123pub 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
132// JSON dispatcher function
133
134/// Decode attribute value and return as JSON string
135///
136/// # Parameters
137/// * `cluster_id` - The cluster identifier
138/// * `attribute_id` - The attribute identifier
139/// * `tlv_value` - The TLV value to decode
140///
141/// # Returns
142/// JSON string representation of the decoded value or error
143pub fn decode_attribute_json(cluster_id: u32, attribute_id: u32, tlv_value: &crate::tlv::TlvItemValue) -> String {
144    // Verify this is the correct cluster
145    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
202/// Get list of all attributes supported by this cluster
203///
204/// # Returns
205/// Vector of tuples containing (attribute_id, attribute_name)
206pub 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
230// Event decoders
231
232/// Decode AlarmsStateChanged event (0x00, priority: info)
233pub 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
245/// Decode SensorFault event (0x01, priority: info)
246pub 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