matc/clusters/codec/
thermostat_user_interface_configuration.rs

1//! Matter TLV encoders and decoders for Thermostat User Interface Configuration Cluster
2//! Cluster ID: 0x0204
3//!
4//! This file is automatically generated from ThermostatUserInterfaceConfiguration.xml
5
6use crate::tlv;
7use anyhow;
8use serde_json;
9
10
11// Enum definitions
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
14#[repr(u8)]
15pub enum KeypadLockout {
16    /// All functionality available to the user
17    Nolockout = 0,
18    /// Level 1 reduced functionality
19    Lockout1 = 1,
20    /// Level 2 reduced functionality
21    Lockout2 = 2,
22    /// Level 3 reduced functionality
23    Lockout3 = 3,
24    /// Level 4 reduced functionality
25    Lockout4 = 4,
26    /// Least functionality available to the user
27    Lockout5 = 5,
28}
29
30impl KeypadLockout {
31    /// Convert from u8 value
32    pub fn from_u8(value: u8) -> Option<Self> {
33        match value {
34            0 => Some(KeypadLockout::Nolockout),
35            1 => Some(KeypadLockout::Lockout1),
36            2 => Some(KeypadLockout::Lockout2),
37            3 => Some(KeypadLockout::Lockout3),
38            4 => Some(KeypadLockout::Lockout4),
39            5 => Some(KeypadLockout::Lockout5),
40            _ => None,
41        }
42    }
43
44    /// Convert to u8 value
45    pub fn to_u8(self) -> u8 {
46        self as u8
47    }
48}
49
50impl From<KeypadLockout> for u8 {
51    fn from(val: KeypadLockout) -> Self {
52        val as u8
53    }
54}
55
56#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
57#[repr(u8)]
58pub enum ScheduleProgrammingVisibility {
59    /// Local schedule programming functionality is enabled at the thermostat
60    Scheduleprogrammingpermitted = 0,
61    /// Local schedule programming functionality is disabled at the thermostat
62    Scheduleprogrammingdenied = 1,
63}
64
65impl ScheduleProgrammingVisibility {
66    /// Convert from u8 value
67    pub fn from_u8(value: u8) -> Option<Self> {
68        match value {
69            0 => Some(ScheduleProgrammingVisibility::Scheduleprogrammingpermitted),
70            1 => Some(ScheduleProgrammingVisibility::Scheduleprogrammingdenied),
71            _ => None,
72        }
73    }
74
75    /// Convert to u8 value
76    pub fn to_u8(self) -> u8 {
77        self as u8
78    }
79}
80
81impl From<ScheduleProgrammingVisibility> for u8 {
82    fn from(val: ScheduleProgrammingVisibility) -> Self {
83        val as u8
84    }
85}
86
87#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
88#[repr(u8)]
89pub enum TemperatureDisplayMode {
90    /// Temperature displayed in °C
91    Celsius = 0,
92    /// Temperature displayed in °F
93    Fahrenheit = 1,
94}
95
96impl TemperatureDisplayMode {
97    /// Convert from u8 value
98    pub fn from_u8(value: u8) -> Option<Self> {
99        match value {
100            0 => Some(TemperatureDisplayMode::Celsius),
101            1 => Some(TemperatureDisplayMode::Fahrenheit),
102            _ => None,
103        }
104    }
105
106    /// Convert to u8 value
107    pub fn to_u8(self) -> u8 {
108        self as u8
109    }
110}
111
112impl From<TemperatureDisplayMode> for u8 {
113    fn from(val: TemperatureDisplayMode) -> Self {
114        val as u8
115    }
116}
117
118// Attribute decoders
119
120/// Decode TemperatureDisplayMode attribute (0x0000)
121pub fn decode_temperature_display_mode(inp: &tlv::TlvItemValue) -> anyhow::Result<TemperatureDisplayMode> {
122    if let tlv::TlvItemValue::Int(v) = inp {
123        TemperatureDisplayMode::from_u8(*v as u8).ok_or_else(|| anyhow::anyhow!("Invalid enum value"))
124    } else {
125        Err(anyhow::anyhow!("Expected Integer"))
126    }
127}
128
129/// Decode KeypadLockout attribute (0x0001)
130pub fn decode_keypad_lockout(inp: &tlv::TlvItemValue) -> anyhow::Result<KeypadLockout> {
131    if let tlv::TlvItemValue::Int(v) = inp {
132        KeypadLockout::from_u8(*v as u8).ok_or_else(|| anyhow::anyhow!("Invalid enum value"))
133    } else {
134        Err(anyhow::anyhow!("Expected Integer"))
135    }
136}
137
138/// Decode ScheduleProgrammingVisibility attribute (0x0002)
139pub fn decode_schedule_programming_visibility(inp: &tlv::TlvItemValue) -> anyhow::Result<ScheduleProgrammingVisibility> {
140    if let tlv::TlvItemValue::Int(v) = inp {
141        ScheduleProgrammingVisibility::from_u8(*v as u8).ok_or_else(|| anyhow::anyhow!("Invalid enum value"))
142    } else {
143        Err(anyhow::anyhow!("Expected Integer"))
144    }
145}
146
147
148// JSON dispatcher function
149
150/// Decode attribute value and return as JSON string
151///
152/// # Parameters
153/// * `cluster_id` - The cluster identifier
154/// * `attribute_id` - The attribute identifier
155/// * `tlv_value` - The TLV value to decode
156///
157/// # Returns
158/// JSON string representation of the decoded value or error
159pub fn decode_attribute_json(cluster_id: u32, attribute_id: u32, tlv_value: &crate::tlv::TlvItemValue) -> String {
160    // Verify this is the correct cluster
161    if cluster_id != 0x0204 {
162        return format!("{{\"error\": \"Invalid cluster ID. Expected 0x0204, got {}\"}}", cluster_id);
163    }
164
165    match attribute_id {
166        0x0000 => {
167            match decode_temperature_display_mode(tlv_value) {
168                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
169                Err(e) => format!("{{\"error\": \"{}\"}}", e),
170            }
171        }
172        0x0001 => {
173            match decode_keypad_lockout(tlv_value) {
174                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
175                Err(e) => format!("{{\"error\": \"{}\"}}", e),
176            }
177        }
178        0x0002 => {
179            match decode_schedule_programming_visibility(tlv_value) {
180                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
181                Err(e) => format!("{{\"error\": \"{}\"}}", e),
182            }
183        }
184        _ => format!("{{\"error\": \"Unknown attribute ID: {}\"}}", attribute_id),
185    }
186}
187
188/// Get list of all attributes supported by this cluster
189///
190/// # Returns
191/// Vector of tuples containing (attribute_id, attribute_name)
192pub fn get_attribute_list() -> Vec<(u32, &'static str)> {
193    vec![
194        (0x0000, "TemperatureDisplayMode"),
195        (0x0001, "KeypadLockout"),
196        (0x0002, "ScheduleProgrammingVisibility"),
197    ]
198}
199