matc/clusters/codec/
fan_control.rs

1//! Generated Matter TLV encoders and decoders for Fan Control Cluster
2//! Cluster ID: 0x0202
3//! 
4//! This file is automatically generated from FanControl.xml
5
6use crate::tlv;
7use anyhow;
8use serde_json;
9
10
11// Command encoders
12
13/// Encode Step command (0x00)
14pub fn encode_step(direction: u8, wrap: bool, lowest_off: bool) -> anyhow::Result<Vec<u8>> {
15    let tlv = tlv::TlvItemEnc {
16        tag: 0,
17        value: tlv::TlvItemValueEnc::StructInvisible(vec![
18        (0, tlv::TlvItemValueEnc::UInt8(direction)).into(),
19        (1, tlv::TlvItemValueEnc::Bool(wrap)).into(),
20        (2, tlv::TlvItemValueEnc::Bool(lowest_off)).into(),
21        ]),
22    };
23    Ok(tlv.encode()?)
24}
25
26// Attribute decoders
27
28/// Decode FanMode attribute (0x0000)
29pub fn decode_fan_mode(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
30    if let tlv::TlvItemValue::Int(v) = inp {
31        Ok(*v as u8)
32    } else {
33        Err(anyhow::anyhow!("Expected Integer"))
34    }
35}
36
37/// Decode FanModeSequence attribute (0x0001)
38pub fn decode_fan_mode_sequence(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
39    if let tlv::TlvItemValue::Int(v) = inp {
40        Ok(*v as u8)
41    } else {
42        Err(anyhow::anyhow!("Expected Integer"))
43    }
44}
45
46/// Decode PercentSetting attribute (0x0002)
47pub fn decode_percent_setting(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
48    if let tlv::TlvItemValue::Int(v) = inp {
49        Ok(Some(*v as u8))
50    } else {
51        Ok(None)
52    }
53}
54
55/// Decode PercentCurrent attribute (0x0003)
56pub fn decode_percent_current(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
57    if let tlv::TlvItemValue::Int(v) = inp {
58        Ok(*v as u8)
59    } else {
60        Err(anyhow::anyhow!("Expected Integer"))
61    }
62}
63
64/// Decode SpeedMax attribute (0x0004)
65pub fn decode_speed_max(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
66    if let tlv::TlvItemValue::Int(v) = inp {
67        Ok(*v as u8)
68    } else {
69        Err(anyhow::anyhow!("Expected Integer"))
70    }
71}
72
73/// Decode SpeedSetting attribute (0x0005)
74pub fn decode_speed_setting(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
75    if let tlv::TlvItemValue::Int(v) = inp {
76        Ok(Some(*v as u8))
77    } else {
78        Ok(None)
79    }
80}
81
82/// Decode SpeedCurrent attribute (0x0006)
83pub fn decode_speed_current(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
84    if let tlv::TlvItemValue::Int(v) = inp {
85        Ok(*v as u8)
86    } else {
87        Err(anyhow::anyhow!("Expected Integer"))
88    }
89}
90
91/// Decode RockSupport attribute (0x0007)
92pub fn decode_rock_support(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
93    if let tlv::TlvItemValue::Int(v) = inp {
94        Ok(*v as u8)
95    } else {
96        Err(anyhow::anyhow!("Expected Integer"))
97    }
98}
99
100/// Decode RockSetting attribute (0x0008)
101pub fn decode_rock_setting(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
102    if let tlv::TlvItemValue::Int(v) = inp {
103        Ok(*v as u8)
104    } else {
105        Err(anyhow::anyhow!("Expected Integer"))
106    }
107}
108
109/// Decode WindSupport attribute (0x0009)
110pub fn decode_wind_support(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
111    if let tlv::TlvItemValue::Int(v) = inp {
112        Ok(*v as u8)
113    } else {
114        Err(anyhow::anyhow!("Expected Integer"))
115    }
116}
117
118/// Decode WindSetting attribute (0x000A)
119pub fn decode_wind_setting(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
120    if let tlv::TlvItemValue::Int(v) = inp {
121        Ok(*v as u8)
122    } else {
123        Err(anyhow::anyhow!("Expected Integer"))
124    }
125}
126
127/// Decode AirflowDirection attribute (0x000B)
128pub fn decode_airflow_direction(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
129    if let tlv::TlvItemValue::Int(v) = inp {
130        Ok(*v as u8)
131    } else {
132        Err(anyhow::anyhow!("Expected Integer"))
133    }
134}
135
136
137// JSON dispatcher function
138
139/// Decode attribute value and return as JSON string
140/// 
141/// # Parameters
142/// * `cluster_id` - The cluster identifier
143/// * `attribute_id` - The attribute identifier
144/// * `tlv_value` - The TLV value to decode
145/// 
146/// # Returns
147/// JSON string representation of the decoded value or error
148pub fn decode_attribute_json(cluster_id: u32, attribute_id: u32, tlv_value: &crate::tlv::TlvItemValue) -> String {
149    // Verify this is the correct cluster
150    if cluster_id != 0x0202 {
151        return format!("{{\"error\": \"Invalid cluster ID. Expected 0x0202, got {}\"}}", cluster_id);
152    }
153    
154    match attribute_id {
155        0x0000 => {
156            match decode_fan_mode(tlv_value) {
157                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
158                Err(e) => format!("{{\"error\": \"{}\"}}", e),
159            }
160        }
161        0x0001 => {
162            match decode_fan_mode_sequence(tlv_value) {
163                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
164                Err(e) => format!("{{\"error\": \"{}\"}}", e),
165            }
166        }
167        0x0002 => {
168            match decode_percent_setting(tlv_value) {
169                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
170                Err(e) => format!("{{\"error\": \"{}\"}}", e),
171            }
172        }
173        0x0003 => {
174            match decode_percent_current(tlv_value) {
175                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
176                Err(e) => format!("{{\"error\": \"{}\"}}", e),
177            }
178        }
179        0x0004 => {
180            match decode_speed_max(tlv_value) {
181                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
182                Err(e) => format!("{{\"error\": \"{}\"}}", e),
183            }
184        }
185        0x0005 => {
186            match decode_speed_setting(tlv_value) {
187                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
188                Err(e) => format!("{{\"error\": \"{}\"}}", e),
189            }
190        }
191        0x0006 => {
192            match decode_speed_current(tlv_value) {
193                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
194                Err(e) => format!("{{\"error\": \"{}\"}}", e),
195            }
196        }
197        0x0007 => {
198            match decode_rock_support(tlv_value) {
199                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
200                Err(e) => format!("{{\"error\": \"{}\"}}", e),
201            }
202        }
203        0x0008 => {
204            match decode_rock_setting(tlv_value) {
205                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
206                Err(e) => format!("{{\"error\": \"{}\"}}", e),
207            }
208        }
209        0x0009 => {
210            match decode_wind_support(tlv_value) {
211                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
212                Err(e) => format!("{{\"error\": \"{}\"}}", e),
213            }
214        }
215        0x000A => {
216            match decode_wind_setting(tlv_value) {
217                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
218                Err(e) => format!("{{\"error\": \"{}\"}}", e),
219            }
220        }
221        0x000B => {
222            match decode_airflow_direction(tlv_value) {
223                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
224                Err(e) => format!("{{\"error\": \"{}\"}}", e),
225            }
226        }
227        _ => format!("{{\"error\": \"Unknown attribute ID: {}\"}}", attribute_id),
228    }
229}
230
231/// Get list of all attributes supported by this cluster
232/// 
233/// # Returns
234/// Vector of tuples containing (attribute_id, attribute_name)
235pub fn get_attribute_list() -> Vec<(u32, &'static str)> {
236    vec![
237        (0x0000, "FanMode"),
238        (0x0001, "FanModeSequence"),
239        (0x0002, "PercentSetting"),
240        (0x0003, "PercentCurrent"),
241        (0x0004, "SpeedMax"),
242        (0x0005, "SpeedSetting"),
243        (0x0006, "SpeedCurrent"),
244        (0x0007, "RockSupport"),
245        (0x0008, "RockSetting"),
246        (0x0009, "WindSupport"),
247        (0x000A, "WindSetting"),
248        (0x000B, "AirflowDirection"),
249    ]
250}
251