matc/clusters/codec/
localization_time_format.rs

1//! Matter TLV encoders and decoders for Time Format Localization Cluster
2//! Cluster ID: 0x002C
3//!
4//! This file is automatically generated from LocalizationTimeFormat.xml
5
6#![allow(clippy::too_many_arguments)]
7
8use crate::tlv;
9use anyhow;
10use serde_json;
11
12
13// Enum definitions
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
16#[repr(u8)]
17pub enum CalendarType {
18    /// Dates conveyed using the Buddhist calendar
19    Buddhist = 0,
20    /// Dates conveyed using the Chinese calendar
21    Chinese = 1,
22    /// Dates conveyed using the Coptic calendar
23    Coptic = 2,
24    /// Dates conveyed using the Ethiopian calendar
25    Ethiopian = 3,
26    /// Dates conveyed using the Gregorian calendar
27    Gregorian = 4,
28    /// Dates conveyed using the Hebrew calendar
29    Hebrew = 5,
30    /// Dates conveyed using the Indian calendar
31    Indian = 6,
32    /// Dates conveyed using the Islamic calendar
33    Islamic = 7,
34    /// Dates conveyed using the Japanese calendar
35    Japanese = 8,
36    /// Dates conveyed using the Korean calendar
37    Korean = 9,
38    /// Dates conveyed using the Persian calendar
39    Persian = 10,
40    /// Dates conveyed using the Taiwanese calendar
41    Taiwanese = 11,
42    /// calendar implied from active locale
43    Useactivelocale = 255,
44}
45
46impl CalendarType {
47    /// Convert from u8 value
48    pub fn from_u8(value: u8) -> Option<Self> {
49        match value {
50            0 => Some(CalendarType::Buddhist),
51            1 => Some(CalendarType::Chinese),
52            2 => Some(CalendarType::Coptic),
53            3 => Some(CalendarType::Ethiopian),
54            4 => Some(CalendarType::Gregorian),
55            5 => Some(CalendarType::Hebrew),
56            6 => Some(CalendarType::Indian),
57            7 => Some(CalendarType::Islamic),
58            8 => Some(CalendarType::Japanese),
59            9 => Some(CalendarType::Korean),
60            10 => Some(CalendarType::Persian),
61            11 => Some(CalendarType::Taiwanese),
62            255 => Some(CalendarType::Useactivelocale),
63            _ => None,
64        }
65    }
66
67    /// Convert to u8 value
68    pub fn to_u8(self) -> u8 {
69        self as u8
70    }
71}
72
73impl From<CalendarType> for u8 {
74    fn from(val: CalendarType) -> Self {
75        val as u8
76    }
77}
78
79#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
80#[repr(u8)]
81pub enum HourFormat {
82    /// Time conveyed with a 12-hour clock
83    _12hr = 0,
84    /// Time conveyed with a 24-hour clock
85    _24hr = 1,
86    /// Use active locale clock
87    Useactivelocale = 255,
88}
89
90impl HourFormat {
91    /// Convert from u8 value
92    pub fn from_u8(value: u8) -> Option<Self> {
93        match value {
94            0 => Some(HourFormat::_12hr),
95            1 => Some(HourFormat::_24hr),
96            255 => Some(HourFormat::Useactivelocale),
97            _ => None,
98        }
99    }
100
101    /// Convert to u8 value
102    pub fn to_u8(self) -> u8 {
103        self as u8
104    }
105}
106
107impl From<HourFormat> for u8 {
108    fn from(val: HourFormat) -> Self {
109        val as u8
110    }
111}
112
113// Attribute decoders
114
115/// Decode HourFormat attribute (0x0000)
116pub fn decode_hour_format(inp: &tlv::TlvItemValue) -> anyhow::Result<HourFormat> {
117    if let tlv::TlvItemValue::Int(v) = inp {
118        HourFormat::from_u8(*v as u8).ok_or_else(|| anyhow::anyhow!("Invalid enum value"))
119    } else {
120        Err(anyhow::anyhow!("Expected Integer"))
121    }
122}
123
124/// Decode ActiveCalendarType attribute (0x0001)
125pub fn decode_active_calendar_type(inp: &tlv::TlvItemValue) -> anyhow::Result<CalendarType> {
126    if let tlv::TlvItemValue::Int(v) = inp {
127        CalendarType::from_u8(*v as u8).ok_or_else(|| anyhow::anyhow!("Invalid enum value"))
128    } else {
129        Err(anyhow::anyhow!("Expected Integer"))
130    }
131}
132
133/// Decode SupportedCalendarTypes attribute (0x0002)
134pub fn decode_supported_calendar_types(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<CalendarType>> {
135    let mut res = Vec::new();
136    if let tlv::TlvItemValue::List(v) = inp {
137        for item in v {
138            if let tlv::TlvItemValue::Int(i) = &item.value {
139                if let Some(enum_val) = CalendarType::from_u8(*i as u8) {
140                    res.push(enum_val);
141                }
142            }
143        }
144    }
145    Ok(res)
146}
147
148
149// JSON dispatcher function
150
151/// Decode attribute value and return as JSON string
152///
153/// # Parameters
154/// * `cluster_id` - The cluster identifier
155/// * `attribute_id` - The attribute identifier
156/// * `tlv_value` - The TLV value to decode
157///
158/// # Returns
159/// JSON string representation of the decoded value or error
160pub fn decode_attribute_json(cluster_id: u32, attribute_id: u32, tlv_value: &crate::tlv::TlvItemValue) -> String {
161    // Verify this is the correct cluster
162    if cluster_id != 0x002C {
163        return format!("{{\"error\": \"Invalid cluster ID. Expected 0x002C, got {}\"}}", cluster_id);
164    }
165
166    match attribute_id {
167        0x0000 => {
168            match decode_hour_format(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        0x0001 => {
174            match decode_active_calendar_type(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        0x0002 => {
180            match decode_supported_calendar_types(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        _ => format!("{{\"error\": \"Unknown attribute ID: {}\"}}", attribute_id),
186    }
187}
188
189/// Get list of all attributes supported by this cluster
190///
191/// # Returns
192/// Vector of tuples containing (attribute_id, attribute_name)
193pub fn get_attribute_list() -> Vec<(u32, &'static str)> {
194    vec![
195        (0x0000, "HourFormat"),
196        (0x0001, "ActiveCalendarType"),
197        (0x0002, "SupportedCalendarTypes"),
198    ]
199}
200
201// Typed facade (invokes + reads)
202
203/// Read `HourFormat` attribute from cluster `Time Format Localization`.
204pub async fn read_hour_format(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<HourFormat> {
205    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_TIME_FORMAT_LOCALIZATION, crate::clusters::defs::CLUSTER_TIME_FORMAT_LOCALIZATION_ATTR_ID_HOURFORMAT).await?;
206    decode_hour_format(&tlv)
207}
208
209/// Read `ActiveCalendarType` attribute from cluster `Time Format Localization`.
210pub async fn read_active_calendar_type(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<CalendarType> {
211    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_TIME_FORMAT_LOCALIZATION, crate::clusters::defs::CLUSTER_TIME_FORMAT_LOCALIZATION_ATTR_ID_ACTIVECALENDARTYPE).await?;
212    decode_active_calendar_type(&tlv)
213}
214
215/// Read `SupportedCalendarTypes` attribute from cluster `Time Format Localization`.
216pub async fn read_supported_calendar_types(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Vec<CalendarType>> {
217    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_TIME_FORMAT_LOCALIZATION, crate::clusters::defs::CLUSTER_TIME_FORMAT_LOCALIZATION_ATTR_ID_SUPPORTEDCALENDARTYPES).await?;
218    decode_supported_calendar_types(&tlv)
219}
220