matc/clusters/codec/
illuminance_measurement.rs

1//! Matter TLV encoders and decoders for Illuminance Measurement Cluster
2//! Cluster ID: 0x0400
3//!
4//! This file is automatically generated from IlluminanceMeasurement.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 LightSensorType {
18    /// Indicates photodiode sensor type
19    Photodiode = 0,
20    /// Indicates CMOS sensor type
21    Cmos = 1,
22}
23
24impl LightSensorType {
25    /// Convert from u8 value
26    pub fn from_u8(value: u8) -> Option<Self> {
27        match value {
28            0 => Some(LightSensorType::Photodiode),
29            1 => Some(LightSensorType::Cmos),
30            _ => None,
31        }
32    }
33
34    /// Convert to u8 value
35    pub fn to_u8(self) -> u8 {
36        self as u8
37    }
38}
39
40impl From<LightSensorType> for u8 {
41    fn from(val: LightSensorType) -> Self {
42        val as u8
43    }
44}
45
46// Attribute decoders
47
48/// Decode MeasuredValue attribute (0x0000)
49pub fn decode_measured_value(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u16>> {
50    if let tlv::TlvItemValue::Int(v) = inp {
51        Ok(Some(*v as u16))
52    } else {
53        Ok(None)
54    }
55}
56
57/// Decode MinMeasuredValue attribute (0x0001)
58pub fn decode_min_measured_value(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u16>> {
59    if let tlv::TlvItemValue::Int(v) = inp {
60        Ok(Some(*v as u16))
61    } else {
62        Ok(None)
63    }
64}
65
66/// Decode MaxMeasuredValue attribute (0x0002)
67pub fn decode_max_measured_value(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u16>> {
68    if let tlv::TlvItemValue::Int(v) = inp {
69        Ok(Some(*v as u16))
70    } else {
71        Ok(None)
72    }
73}
74
75/// Decode Tolerance attribute (0x0003)
76pub fn decode_tolerance(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
77    if let tlv::TlvItemValue::Int(v) = inp {
78        Ok(*v as u16)
79    } else {
80        Err(anyhow::anyhow!("Expected UInt16"))
81    }
82}
83
84/// Decode LightSensorType attribute (0x0004)
85pub fn decode_light_sensor_type(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<LightSensorType>> {
86    if let tlv::TlvItemValue::Int(v) = inp {
87        Ok(LightSensorType::from_u8(*v as u8))
88    } else {
89        Ok(None)
90    }
91}
92
93
94// JSON dispatcher function
95
96/// Decode attribute value and return as JSON string
97///
98/// # Parameters
99/// * `cluster_id` - The cluster identifier
100/// * `attribute_id` - The attribute identifier
101/// * `tlv_value` - The TLV value to decode
102///
103/// # Returns
104/// JSON string representation of the decoded value or error
105pub fn decode_attribute_json(cluster_id: u32, attribute_id: u32, tlv_value: &crate::tlv::TlvItemValue) -> String {
106    // Verify this is the correct cluster
107    if cluster_id != 0x0400 {
108        return format!("{{\"error\": \"Invalid cluster ID. Expected 0x0400, got {}\"}}", cluster_id);
109    }
110
111    match attribute_id {
112        0x0000 => {
113            match decode_measured_value(tlv_value) {
114                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
115                Err(e) => format!("{{\"error\": \"{}\"}}", e),
116            }
117        }
118        0x0001 => {
119            match decode_min_measured_value(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        0x0002 => {
125            match decode_max_measured_value(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        0x0003 => {
131            match decode_tolerance(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        0x0004 => {
137            match decode_light_sensor_type(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        _ => format!("{{\"error\": \"Unknown attribute ID: {}\"}}", attribute_id),
143    }
144}
145
146/// Get list of all attributes supported by this cluster
147///
148/// # Returns
149/// Vector of tuples containing (attribute_id, attribute_name)
150pub fn get_attribute_list() -> Vec<(u32, &'static str)> {
151    vec![
152        (0x0000, "MeasuredValue"),
153        (0x0001, "MinMeasuredValue"),
154        (0x0002, "MaxMeasuredValue"),
155        (0x0003, "Tolerance"),
156        (0x0004, "LightSensorType"),
157    ]
158}
159
160// Typed facade (invokes + reads)
161
162/// Read `MeasuredValue` attribute from cluster `Illuminance Measurement`.
163pub async fn read_measured_value(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Option<u16>> {
164    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_ILLUMINANCE_MEASUREMENT, crate::clusters::defs::CLUSTER_ILLUMINANCE_MEASUREMENT_ATTR_ID_MEASUREDVALUE).await?;
165    decode_measured_value(&tlv)
166}
167
168/// Read `MinMeasuredValue` attribute from cluster `Illuminance Measurement`.
169pub async fn read_min_measured_value(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Option<u16>> {
170    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_ILLUMINANCE_MEASUREMENT, crate::clusters::defs::CLUSTER_ILLUMINANCE_MEASUREMENT_ATTR_ID_MINMEASUREDVALUE).await?;
171    decode_min_measured_value(&tlv)
172}
173
174/// Read `MaxMeasuredValue` attribute from cluster `Illuminance Measurement`.
175pub async fn read_max_measured_value(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Option<u16>> {
176    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_ILLUMINANCE_MEASUREMENT, crate::clusters::defs::CLUSTER_ILLUMINANCE_MEASUREMENT_ATTR_ID_MAXMEASUREDVALUE).await?;
177    decode_max_measured_value(&tlv)
178}
179
180/// Read `Tolerance` attribute from cluster `Illuminance Measurement`.
181pub async fn read_tolerance(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u16> {
182    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_ILLUMINANCE_MEASUREMENT, crate::clusters::defs::CLUSTER_ILLUMINANCE_MEASUREMENT_ATTR_ID_TOLERANCE).await?;
183    decode_tolerance(&tlv)
184}
185
186/// Read `LightSensorType` attribute from cluster `Illuminance Measurement`.
187pub async fn read_light_sensor_type(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Option<LightSensorType>> {
188    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_ILLUMINANCE_MEASUREMENT, crate::clusters::defs::CLUSTER_ILLUMINANCE_MEASUREMENT_ATTR_ID_LIGHTSENSORTYPE).await?;
189    decode_light_sensor_type(&tlv)
190}
191