matc/clusters/codec/
localization_time_format.rs1#![allow(clippy::too_many_arguments)]
7
8use crate::tlv;
9use anyhow;
10use serde_json;
11
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
16#[repr(u8)]
17pub enum CalendarType {
18 Buddhist = 0,
20 Chinese = 1,
22 Coptic = 2,
24 Ethiopian = 3,
26 Gregorian = 4,
28 Hebrew = 5,
30 Indian = 6,
32 Islamic = 7,
34 Japanese = 8,
36 Korean = 9,
38 Persian = 10,
40 Taiwanese = 11,
42 Useactivelocale = 255,
44}
45
46impl CalendarType {
47 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 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 _12hr = 0,
84 _24hr = 1,
86 Useactivelocale = 255,
88}
89
90impl HourFormat {
91 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 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
113pub 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
124pub 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
133pub 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
149pub fn decode_attribute_json(cluster_id: u32, attribute_id: u32, tlv_value: &crate::tlv::TlvItemValue) -> String {
161 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
189pub fn get_attribute_list() -> Vec<(u32, &'static str)> {
194 vec![
195 (0x0000, "HourFormat"),
196 (0x0001, "ActiveCalendarType"),
197 (0x0002, "SupportedCalendarTypes"),
198 ]
199}
200
201pub 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
209pub 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
215pub 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