matc/clusters/codec/
operational_state.rs

1//! Generated Matter TLV encoders and decoders for Operational State Cluster
2//! Cluster ID: 0x0060
3//! 
4//! This file is automatically generated from OperationalState.xml
5
6use crate::tlv;
7use anyhow;
8use serde_json;
9
10
11// Struct definitions
12
13#[derive(Debug, serde::Serialize)]
14pub struct ErrorState {
15    pub error_state_id: Option<u8>,
16    pub error_state_label: Option<String>,
17    pub error_state_details: Option<String>,
18}
19
20#[derive(Debug, serde::Serialize)]
21pub struct OperationalState {
22    pub operational_state_id: Option<u8>,
23    pub operational_state_label: Option<String>,
24}
25
26// Command encoders
27
28// Attribute decoders
29
30/// Decode PhaseList attribute (0x0000)
31pub fn decode_phase_list(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<String>> {
32    let mut res = Vec::new();
33    if let tlv::TlvItemValue::List(v) = inp {
34        for item in v {
35            if let tlv::TlvItemValue::String(s) = &item.value {
36                res.push(s.clone());
37            }
38        }
39    }
40    Ok(res)
41}
42
43/// Decode CurrentPhase attribute (0x0001)
44pub fn decode_current_phase(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
45    if let tlv::TlvItemValue::Int(v) = inp {
46        Ok(Some(*v as u8))
47    } else {
48        Ok(None)
49    }
50}
51
52/// Decode CountdownTime attribute (0x0002)
53pub fn decode_countdown_time(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
54    if let tlv::TlvItemValue::Int(v) = inp {
55        Ok(Some(*v as u8))
56    } else {
57        Ok(None)
58    }
59}
60
61/// Decode OperationalStateList attribute (0x0003)
62pub fn decode_operational_state_list(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<OperationalState>> {
63    let mut res = Vec::new();
64    if let tlv::TlvItemValue::List(v) = inp {
65        for item in v {
66            res.push(OperationalState {
67                operational_state_id: item.get_int(&[0]).map(|v| v as u8),
68                operational_state_label: item.get_string_owned(&[1]),
69            });
70        }
71    }
72    Ok(res)
73}
74
75/// Decode OperationalState attribute (0x0004)
76pub fn decode_operational_state(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
77    if let tlv::TlvItemValue::Int(v) = inp {
78        Ok(*v as u8)
79    } else {
80        Err(anyhow::anyhow!("Expected Integer"))
81    }
82}
83
84/// Decode OperationalError attribute (0x0005)
85pub fn decode_operational_error(inp: &tlv::TlvItemValue) -> anyhow::Result<ErrorState> {
86    if let tlv::TlvItemValue::List(_fields) = inp {
87        // Struct with fields
88        let item = tlv::TlvItem { tag: 0, value: inp.clone() };
89        Ok(ErrorState {
90                error_state_id: item.get_int(&[0]).map(|v| v as u8),
91                error_state_label: item.get_string_owned(&[1]),
92                error_state_details: item.get_string_owned(&[2]),
93        })
94    } else {
95        Err(anyhow::anyhow!("Expected struct fields"))
96    }
97}
98
99
100// JSON dispatcher function
101
102/// Decode attribute value and return as JSON string
103/// 
104/// # Parameters
105/// * `cluster_id` - The cluster identifier
106/// * `attribute_id` - The attribute identifier
107/// * `tlv_value` - The TLV value to decode
108/// 
109/// # Returns
110/// JSON string representation of the decoded value or error
111pub fn decode_attribute_json(cluster_id: u32, attribute_id: u32, tlv_value: &crate::tlv::TlvItemValue) -> String {
112    // Verify this is the correct cluster
113    if cluster_id != 0x0060 {
114        return format!("{{\"error\": \"Invalid cluster ID. Expected 0x0060, got {}\"}}", cluster_id);
115    }
116    
117    match attribute_id {
118        0x0000 => {
119            match decode_phase_list(tlv_value) {
120                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
121                Err(e) => format!("{{\"error\": \"{}\"}}", e),
122            }
123        }
124        0x0001 => {
125            match decode_current_phase(tlv_value) {
126                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
127                Err(e) => format!("{{\"error\": \"{}\"}}", e),
128            }
129        }
130        0x0002 => {
131            match decode_countdown_time(tlv_value) {
132                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
133                Err(e) => format!("{{\"error\": \"{}\"}}", e),
134            }
135        }
136        0x0003 => {
137            match decode_operational_state_list(tlv_value) {
138                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
139                Err(e) => format!("{{\"error\": \"{}\"}}", e),
140            }
141        }
142        0x0004 => {
143            match decode_operational_state(tlv_value) {
144                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
145                Err(e) => format!("{{\"error\": \"{}\"}}", e),
146            }
147        }
148        0x0005 => {
149            match decode_operational_error(tlv_value) {
150                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
151                Err(e) => format!("{{\"error\": \"{}\"}}", e),
152            }
153        }
154        _ => format!("{{\"error\": \"Unknown attribute ID: {}\"}}", attribute_id),
155    }
156}
157
158/// Get list of all attributes supported by this cluster
159/// 
160/// # Returns
161/// Vector of tuples containing (attribute_id, attribute_name)
162pub fn get_attribute_list() -> Vec<(u32, &'static str)> {
163    vec![
164        (0x0000, "PhaseList"),
165        (0x0001, "CurrentPhase"),
166        (0x0002, "CountdownTime"),
167        (0x0003, "OperationalStateList"),
168        (0x0004, "OperationalState"),
169        (0x0005, "OperationalError"),
170    ]
171}
172