matc/clusters/codec/
application_basic.rs

1//! Matter TLV encoders and decoders for Application Basic Cluster
2//! Cluster ID: 0x050D
3//!
4//! This file is automatically generated from ApplicationBasic.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 ApplicationStatus {
18    /// Application is not running.
19    Stopped = 0,
20    /// Application is running, is visible to the user, and is the active target for input.
21    Activevisiblefocus = 1,
22    /// Application is running but not visible to the user.
23    Activehidden = 2,
24    /// Application is running and visible, but is not the active target for input.
25    Activevisiblenotfocus = 3,
26}
27
28impl ApplicationStatus {
29    /// Convert from u8 value
30    pub fn from_u8(value: u8) -> Option<Self> {
31        match value {
32            0 => Some(ApplicationStatus::Stopped),
33            1 => Some(ApplicationStatus::Activevisiblefocus),
34            2 => Some(ApplicationStatus::Activehidden),
35            3 => Some(ApplicationStatus::Activevisiblenotfocus),
36            _ => None,
37        }
38    }
39
40    /// Convert to u8 value
41    pub fn to_u8(self) -> u8 {
42        self as u8
43    }
44}
45
46impl From<ApplicationStatus> for u8 {
47    fn from(val: ApplicationStatus) -> Self {
48        val as u8
49    }
50}
51
52// Struct definitions
53
54#[derive(Debug, serde::Serialize)]
55pub struct Application {
56    pub catalog_vendor_id: Option<u16>,
57    pub application_id: Option<String>,
58}
59
60// Attribute decoders
61
62/// Decode VendorName attribute (0x0000)
63pub fn decode_vendor_name(inp: &tlv::TlvItemValue) -> anyhow::Result<String> {
64    if let tlv::TlvItemValue::String(v) = inp {
65        Ok(v.clone())
66    } else {
67        Err(anyhow::anyhow!("Expected String"))
68    }
69}
70
71/// Decode VendorID attribute (0x0001)
72pub fn decode_vendor_id(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
73    if let tlv::TlvItemValue::Int(v) = inp {
74        Ok(*v as u16)
75    } else {
76        Err(anyhow::anyhow!("Expected UInt16"))
77    }
78}
79
80/// Decode ApplicationName attribute (0x0002)
81pub fn decode_application_name(inp: &tlv::TlvItemValue) -> anyhow::Result<String> {
82    if let tlv::TlvItemValue::String(v) = inp {
83        Ok(v.clone())
84    } else {
85        Err(anyhow::anyhow!("Expected String"))
86    }
87}
88
89/// Decode ProductID attribute (0x0003)
90pub fn decode_product_id(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
91    if let tlv::TlvItemValue::Int(v) = inp {
92        Ok(*v as u16)
93    } else {
94        Err(anyhow::anyhow!("Expected UInt16"))
95    }
96}
97
98/// Decode Application attribute (0x0004)
99pub fn decode_application(inp: &tlv::TlvItemValue) -> anyhow::Result<Application> {
100    if let tlv::TlvItemValue::List(_fields) = inp {
101        // Struct with fields
102        let item = tlv::TlvItem { tag: 0, value: inp.clone() };
103        Ok(Application {
104                catalog_vendor_id: item.get_int(&[0]).map(|v| v as u16),
105                application_id: item.get_string_owned(&[1]),
106        })
107    } else {
108        Err(anyhow::anyhow!("Expected struct fields"))
109    }
110}
111
112/// Decode Status attribute (0x0005)
113pub fn decode_status(inp: &tlv::TlvItemValue) -> anyhow::Result<ApplicationStatus> {
114    if let tlv::TlvItemValue::Int(v) = inp {
115        ApplicationStatus::from_u8(*v as u8).ok_or_else(|| anyhow::anyhow!("Invalid enum value"))
116    } else {
117        Err(anyhow::anyhow!("Expected Integer"))
118    }
119}
120
121/// Decode ApplicationVersion attribute (0x0006)
122pub fn decode_application_version(inp: &tlv::TlvItemValue) -> anyhow::Result<String> {
123    if let tlv::TlvItemValue::String(v) = inp {
124        Ok(v.clone())
125    } else {
126        Err(anyhow::anyhow!("Expected String"))
127    }
128}
129
130/// Decode AllowedVendorList attribute (0x0007)
131pub fn decode_allowed_vendor_list(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<u16>> {
132    let mut res = Vec::new();
133    if let tlv::TlvItemValue::List(v) = inp {
134        for item in v {
135            if let tlv::TlvItemValue::Int(i) = &item.value {
136                res.push(*i as u16);
137            }
138        }
139    }
140    Ok(res)
141}
142
143
144// JSON dispatcher function
145
146/// Decode attribute value and return as JSON string
147///
148/// # Parameters
149/// * `cluster_id` - The cluster identifier
150/// * `attribute_id` - The attribute identifier
151/// * `tlv_value` - The TLV value to decode
152///
153/// # Returns
154/// JSON string representation of the decoded value or error
155pub fn decode_attribute_json(cluster_id: u32, attribute_id: u32, tlv_value: &crate::tlv::TlvItemValue) -> String {
156    // Verify this is the correct cluster
157    if cluster_id != 0x050D {
158        return format!("{{\"error\": \"Invalid cluster ID. Expected 0x050D, got {}\"}}", cluster_id);
159    }
160
161    match attribute_id {
162        0x0000 => {
163            match decode_vendor_name(tlv_value) {
164                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
165                Err(e) => format!("{{\"error\": \"{}\"}}", e),
166            }
167        }
168        0x0001 => {
169            match decode_vendor_id(tlv_value) {
170                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
171                Err(e) => format!("{{\"error\": \"{}\"}}", e),
172            }
173        }
174        0x0002 => {
175            match decode_application_name(tlv_value) {
176                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
177                Err(e) => format!("{{\"error\": \"{}\"}}", e),
178            }
179        }
180        0x0003 => {
181            match decode_product_id(tlv_value) {
182                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
183                Err(e) => format!("{{\"error\": \"{}\"}}", e),
184            }
185        }
186        0x0004 => {
187            match decode_application(tlv_value) {
188                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
189                Err(e) => format!("{{\"error\": \"{}\"}}", e),
190            }
191        }
192        0x0005 => {
193            match decode_status(tlv_value) {
194                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
195                Err(e) => format!("{{\"error\": \"{}\"}}", e),
196            }
197        }
198        0x0006 => {
199            match decode_application_version(tlv_value) {
200                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
201                Err(e) => format!("{{\"error\": \"{}\"}}", e),
202            }
203        }
204        0x0007 => {
205            match decode_allowed_vendor_list(tlv_value) {
206                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
207                Err(e) => format!("{{\"error\": \"{}\"}}", e),
208            }
209        }
210        _ => format!("{{\"error\": \"Unknown attribute ID: {}\"}}", attribute_id),
211    }
212}
213
214/// Get list of all attributes supported by this cluster
215///
216/// # Returns
217/// Vector of tuples containing (attribute_id, attribute_name)
218pub fn get_attribute_list() -> Vec<(u32, &'static str)> {
219    vec![
220        (0x0000, "VendorName"),
221        (0x0001, "VendorID"),
222        (0x0002, "ApplicationName"),
223        (0x0003, "ProductID"),
224        (0x0004, "Application"),
225        (0x0005, "Status"),
226        (0x0006, "ApplicationVersion"),
227        (0x0007, "AllowedVendorList"),
228    ]
229}
230
231// Typed facade (invokes + reads)
232
233/// Read `VendorName` attribute from cluster `Application Basic`.
234pub async fn read_vendor_name(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<String> {
235    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_APPLICATION_BASIC, crate::clusters::defs::CLUSTER_APPLICATION_BASIC_ATTR_ID_VENDORNAME).await?;
236    decode_vendor_name(&tlv)
237}
238
239/// Read `VendorID` attribute from cluster `Application Basic`.
240pub async fn read_vendor_id(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u16> {
241    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_APPLICATION_BASIC, crate::clusters::defs::CLUSTER_APPLICATION_BASIC_ATTR_ID_VENDORID).await?;
242    decode_vendor_id(&tlv)
243}
244
245/// Read `ApplicationName` attribute from cluster `Application Basic`.
246pub async fn read_application_name(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<String> {
247    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_APPLICATION_BASIC, crate::clusters::defs::CLUSTER_APPLICATION_BASIC_ATTR_ID_APPLICATIONNAME).await?;
248    decode_application_name(&tlv)
249}
250
251/// Read `ProductID` attribute from cluster `Application Basic`.
252pub async fn read_product_id(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u16> {
253    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_APPLICATION_BASIC, crate::clusters::defs::CLUSTER_APPLICATION_BASIC_ATTR_ID_PRODUCTID).await?;
254    decode_product_id(&tlv)
255}
256
257/// Read `Application` attribute from cluster `Application Basic`.
258pub async fn read_application(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Application> {
259    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_APPLICATION_BASIC, crate::clusters::defs::CLUSTER_APPLICATION_BASIC_ATTR_ID_APPLICATION).await?;
260    decode_application(&tlv)
261}
262
263/// Read `Status` attribute from cluster `Application Basic`.
264pub async fn read_status(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<ApplicationStatus> {
265    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_APPLICATION_BASIC, crate::clusters::defs::CLUSTER_APPLICATION_BASIC_ATTR_ID_STATUS).await?;
266    decode_status(&tlv)
267}
268
269/// Read `ApplicationVersion` attribute from cluster `Application Basic`.
270pub async fn read_application_version(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<String> {
271    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_APPLICATION_BASIC, crate::clusters::defs::CLUSTER_APPLICATION_BASIC_ATTR_ID_APPLICATIONVERSION).await?;
272    decode_application_version(&tlv)
273}
274
275/// Read `AllowedVendorList` attribute from cluster `Application Basic`.
276pub async fn read_allowed_vendor_list(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Vec<u16>> {
277    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_APPLICATION_BASIC, crate::clusters::defs::CLUSTER_APPLICATION_BASIC_ATTR_ID_ALLOWEDVENDORLIST).await?;
278    decode_allowed_vendor_list(&tlv)
279}
280