Skip to main content

matc/clusters/codec/
temperature_alarm.rs

1//! Matter TLV encoders and decoders for Temperature Alarm Cluster
2//! Cluster ID: 0x0064
3//!
4//! This file is automatically generated from TemperatureAlarm.xml
5
6#![allow(clippy::too_many_arguments)]
7
8use crate::tlv;
9use anyhow;
10use serde_json;
11
12
13// Bitmap definitions
14
15/// Alarm bitmap type
16pub type Alarm = u8;
17
18/// Constants for Alarm
19pub mod alarm {
20    /// The measured temperature is above the critical threshold.
21    pub const CRITICAL_OVER_TEMPERATURE_ALARM: u8 = 0x01;
22    /// The measured temperature is above the major threshold.
23    pub const MAJOR_OVER_TEMPERATURE_ALARM: u8 = 0x02;
24    /// The measured temperature is above the minor threshold.
25    pub const MINOR_OVER_TEMPERATURE_ALARM: u8 = 0x04;
26    /// The measured temperature is below the minor threshold.
27    pub const MINOR_UNDER_TEMPERATURE_ALARM: u8 = 0x08;
28    /// The measured temperature is below the major threshold.
29    pub const MAJOR_UNDER_TEMPERATURE_ALARM: u8 = 0x10;
30    /// The measured temperature is below the critical threshold.
31    pub const CRITICAL_UNDER_TEMPERATURE_ALARM: u8 = 0x20;
32}
33
34// Command encoders
35
36/// Encode SetTemperatureAlarmThresholds command (0x80)
37pub fn encode_set_temperature_alarm_thresholds(critical_over_temperature_threshold: Option<i16>, major_over_temperature_threshold: Option<i16>, minor_over_temperature_threshold: Option<i16>, minor_under_temperature_threshold: Option<i16>, major_under_temperature_threshold: Option<i16>, critical_under_temperature_threshold: Option<i16>) -> anyhow::Result<Vec<u8>> {
38    let mut tlv_fields: Vec<tlv::TlvItemEnc> = Vec::new();
39    if let Some(x) = critical_over_temperature_threshold { tlv_fields.push((0, tlv::TlvItemValueEnc::Int16(x)).into()); }
40    if let Some(x) = major_over_temperature_threshold { tlv_fields.push((1, tlv::TlvItemValueEnc::Int16(x)).into()); }
41    if let Some(x) = minor_over_temperature_threshold { tlv_fields.push((2, tlv::TlvItemValueEnc::Int16(x)).into()); }
42    if let Some(x) = minor_under_temperature_threshold { tlv_fields.push((3, tlv::TlvItemValueEnc::Int16(x)).into()); }
43    if let Some(x) = major_under_temperature_threshold { tlv_fields.push((4, tlv::TlvItemValueEnc::Int16(x)).into()); }
44    if let Some(x) = critical_under_temperature_threshold { tlv_fields.push((5, tlv::TlvItemValueEnc::Int16(x)).into()); }
45    let tlv = tlv::TlvItemEnc {
46        tag: 0,
47        value: tlv::TlvItemValueEnc::StructInvisible(tlv_fields),
48    };
49    Ok(tlv.encode()?)
50}
51
52// Attribute decoders
53
54/// Decode CriticalOverTemperatureThreshold attribute (0x0080)
55pub fn decode_critical_over_temperature_threshold(inp: &tlv::TlvItemValue) -> anyhow::Result<i16> {
56    if let tlv::TlvItemValue::Int(v) = inp {
57        Ok(*v as i16)
58    } else {
59        Err(anyhow::anyhow!("Expected Int16"))
60    }
61}
62
63/// Decode MajorOverTemperatureThreshold attribute (0x0081)
64pub fn decode_major_over_temperature_threshold(inp: &tlv::TlvItemValue) -> anyhow::Result<i16> {
65    if let tlv::TlvItemValue::Int(v) = inp {
66        Ok(*v as i16)
67    } else {
68        Err(anyhow::anyhow!("Expected Int16"))
69    }
70}
71
72/// Decode MinorOverTemperatureThreshold attribute (0x0082)
73pub fn decode_minor_over_temperature_threshold(inp: &tlv::TlvItemValue) -> anyhow::Result<i16> {
74    if let tlv::TlvItemValue::Int(v) = inp {
75        Ok(*v as i16)
76    } else {
77        Err(anyhow::anyhow!("Expected Int16"))
78    }
79}
80
81/// Decode MinorUnderTemperatureThreshold attribute (0x0083)
82pub fn decode_minor_under_temperature_threshold(inp: &tlv::TlvItemValue) -> anyhow::Result<i16> {
83    if let tlv::TlvItemValue::Int(v) = inp {
84        Ok(*v as i16)
85    } else {
86        Err(anyhow::anyhow!("Expected Int16"))
87    }
88}
89
90/// Decode MajorUnderTemperatureThreshold attribute (0x0084)
91pub fn decode_major_under_temperature_threshold(inp: &tlv::TlvItemValue) -> anyhow::Result<i16> {
92    if let tlv::TlvItemValue::Int(v) = inp {
93        Ok(*v as i16)
94    } else {
95        Err(anyhow::anyhow!("Expected Int16"))
96    }
97}
98
99/// Decode CriticalUnderTemperatureThreshold attribute (0x0085)
100pub fn decode_critical_under_temperature_threshold(inp: &tlv::TlvItemValue) -> anyhow::Result<i16> {
101    if let tlv::TlvItemValue::Int(v) = inp {
102        Ok(*v as i16)
103    } else {
104        Err(anyhow::anyhow!("Expected Int16"))
105    }
106}
107
108
109// JSON dispatcher function
110
111/// Decode attribute value and return as JSON string
112///
113/// # Parameters
114/// * `cluster_id` - The cluster identifier
115/// * `attribute_id` - The attribute identifier
116/// * `tlv_value` - The TLV value to decode
117///
118/// # Returns
119/// JSON string representation of the decoded value or error
120pub fn decode_attribute_json(cluster_id: u32, attribute_id: u32, tlv_value: &crate::tlv::TlvItemValue) -> String {
121    // Verify this is the correct cluster
122    if cluster_id != 0x0064 {
123        return format!("{{\"error\": \"Invalid cluster ID. Expected 0x0064, got {}\"}}", cluster_id);
124    }
125
126    match attribute_id {
127        0x0080 => {
128            match decode_critical_over_temperature_threshold(tlv_value) {
129                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
130                Err(e) => format!("{{\"error\": \"{}\"}}", e),
131            }
132        }
133        0x0081 => {
134            match decode_major_over_temperature_threshold(tlv_value) {
135                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
136                Err(e) => format!("{{\"error\": \"{}\"}}", e),
137            }
138        }
139        0x0082 => {
140            match decode_minor_over_temperature_threshold(tlv_value) {
141                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
142                Err(e) => format!("{{\"error\": \"{}\"}}", e),
143            }
144        }
145        0x0083 => {
146            match decode_minor_under_temperature_threshold(tlv_value) {
147                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
148                Err(e) => format!("{{\"error\": \"{}\"}}", e),
149            }
150        }
151        0x0084 => {
152            match decode_major_under_temperature_threshold(tlv_value) {
153                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
154                Err(e) => format!("{{\"error\": \"{}\"}}", e),
155            }
156        }
157        0x0085 => {
158            match decode_critical_under_temperature_threshold(tlv_value) {
159                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
160                Err(e) => format!("{{\"error\": \"{}\"}}", e),
161            }
162        }
163        _ => format!("{{\"error\": \"Unknown attribute ID: {}\"}}", attribute_id),
164    }
165}
166
167/// Get list of all attributes supported by this cluster
168///
169/// # Returns
170/// Vector of tuples containing (attribute_id, attribute_name)
171pub fn get_attribute_list() -> Vec<(u32, &'static str)> {
172    vec![
173        (0x0080, "CriticalOverTemperatureThreshold"),
174        (0x0081, "MajorOverTemperatureThreshold"),
175        (0x0082, "MinorOverTemperatureThreshold"),
176        (0x0083, "MinorUnderTemperatureThreshold"),
177        (0x0084, "MajorUnderTemperatureThreshold"),
178        (0x0085, "CriticalUnderTemperatureThreshold"),
179    ]
180}
181
182// Command listing
183
184pub fn get_command_list() -> Vec<(u32, &'static str)> {
185    vec![
186        (0x80, "SetTemperatureAlarmThresholds"),
187    ]
188}
189
190pub fn get_command_name(cmd_id: u32) -> Option<&'static str> {
191    match cmd_id {
192        0x80 => Some("SetTemperatureAlarmThresholds"),
193        _ => None,
194    }
195}
196
197pub fn get_command_schema(cmd_id: u32) -> Option<Vec<crate::clusters::codec::CommandField>> {
198    match cmd_id {
199        0x80 => Some(vec![
200            crate::clusters::codec::CommandField { tag: 0, name: "critical_over_temperature_threshold", kind: crate::clusters::codec::FieldKind::I16, optional: true, nullable: false },
201            crate::clusters::codec::CommandField { tag: 1, name: "major_over_temperature_threshold", kind: crate::clusters::codec::FieldKind::I16, optional: true, nullable: false },
202            crate::clusters::codec::CommandField { tag: 2, name: "minor_over_temperature_threshold", kind: crate::clusters::codec::FieldKind::I16, optional: true, nullable: false },
203            crate::clusters::codec::CommandField { tag: 3, name: "minor_under_temperature_threshold", kind: crate::clusters::codec::FieldKind::I16, optional: true, nullable: false },
204            crate::clusters::codec::CommandField { tag: 4, name: "major_under_temperature_threshold", kind: crate::clusters::codec::FieldKind::I16, optional: true, nullable: false },
205            crate::clusters::codec::CommandField { tag: 5, name: "critical_under_temperature_threshold", kind: crate::clusters::codec::FieldKind::I16, optional: true, nullable: false },
206        ]),
207        _ => None,
208    }
209}
210
211pub fn encode_command_json(cmd_id: u32, args: &serde_json::Value) -> anyhow::Result<Vec<u8>> {
212    match cmd_id {
213        0x80 => {
214        let critical_over_temperature_threshold = crate::clusters::codec::json_util::get_opt_i16(args, "critical_over_temperature_threshold")?;
215        let major_over_temperature_threshold = crate::clusters::codec::json_util::get_opt_i16(args, "major_over_temperature_threshold")?;
216        let minor_over_temperature_threshold = crate::clusters::codec::json_util::get_opt_i16(args, "minor_over_temperature_threshold")?;
217        let minor_under_temperature_threshold = crate::clusters::codec::json_util::get_opt_i16(args, "minor_under_temperature_threshold")?;
218        let major_under_temperature_threshold = crate::clusters::codec::json_util::get_opt_i16(args, "major_under_temperature_threshold")?;
219        let critical_under_temperature_threshold = crate::clusters::codec::json_util::get_opt_i16(args, "critical_under_temperature_threshold")?;
220        encode_set_temperature_alarm_thresholds(critical_over_temperature_threshold, major_over_temperature_threshold, minor_over_temperature_threshold, minor_under_temperature_threshold, major_under_temperature_threshold, critical_under_temperature_threshold)
221        }
222        _ => Err(anyhow::anyhow!("unknown command ID: 0x{:02X}", cmd_id)),
223    }
224}
225
226// Typed facade (invokes + reads)
227
228/// Invoke `SetTemperatureAlarmThresholds` command on cluster `Temperature Alarm`.
229pub async fn set_temperature_alarm_thresholds(conn: &crate::controller::Connection, endpoint: u16, critical_over_temperature_threshold: Option<i16>, major_over_temperature_threshold: Option<i16>, minor_over_temperature_threshold: Option<i16>, minor_under_temperature_threshold: Option<i16>, major_under_temperature_threshold: Option<i16>, critical_under_temperature_threshold: Option<i16>) -> anyhow::Result<()> {
230    conn.invoke_request(endpoint, crate::clusters::defs::CLUSTER_ID_TEMPERATURE_ALARM, crate::clusters::defs::CLUSTER_TEMPERATURE_ALARM_CMD_ID_SETTEMPERATUREALARMTHRESHOLDS, &encode_set_temperature_alarm_thresholds(critical_over_temperature_threshold, major_over_temperature_threshold, minor_over_temperature_threshold, minor_under_temperature_threshold, major_under_temperature_threshold, critical_under_temperature_threshold)?).await?;
231    Ok(())
232}
233
234/// Read `CriticalOverTemperatureThreshold` attribute from cluster `Temperature Alarm`.
235pub async fn read_critical_over_temperature_threshold(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<i16> {
236    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_TEMPERATURE_ALARM, crate::clusters::defs::CLUSTER_TEMPERATURE_ALARM_ATTR_ID_CRITICALOVERTEMPERATURETHRESHOLD).await?;
237    decode_critical_over_temperature_threshold(&tlv)
238}
239
240/// Read `MajorOverTemperatureThreshold` attribute from cluster `Temperature Alarm`.
241pub async fn read_major_over_temperature_threshold(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<i16> {
242    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_TEMPERATURE_ALARM, crate::clusters::defs::CLUSTER_TEMPERATURE_ALARM_ATTR_ID_MAJOROVERTEMPERATURETHRESHOLD).await?;
243    decode_major_over_temperature_threshold(&tlv)
244}
245
246/// Read `MinorOverTemperatureThreshold` attribute from cluster `Temperature Alarm`.
247pub async fn read_minor_over_temperature_threshold(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<i16> {
248    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_TEMPERATURE_ALARM, crate::clusters::defs::CLUSTER_TEMPERATURE_ALARM_ATTR_ID_MINOROVERTEMPERATURETHRESHOLD).await?;
249    decode_minor_over_temperature_threshold(&tlv)
250}
251
252/// Read `MinorUnderTemperatureThreshold` attribute from cluster `Temperature Alarm`.
253pub async fn read_minor_under_temperature_threshold(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<i16> {
254    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_TEMPERATURE_ALARM, crate::clusters::defs::CLUSTER_TEMPERATURE_ALARM_ATTR_ID_MINORUNDERTEMPERATURETHRESHOLD).await?;
255    decode_minor_under_temperature_threshold(&tlv)
256}
257
258/// Read `MajorUnderTemperatureThreshold` attribute from cluster `Temperature Alarm`.
259pub async fn read_major_under_temperature_threshold(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<i16> {
260    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_TEMPERATURE_ALARM, crate::clusters::defs::CLUSTER_TEMPERATURE_ALARM_ATTR_ID_MAJORUNDERTEMPERATURETHRESHOLD).await?;
261    decode_major_under_temperature_threshold(&tlv)
262}
263
264/// Read `CriticalUnderTemperatureThreshold` attribute from cluster `Temperature Alarm`.
265pub async fn read_critical_under_temperature_threshold(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<i16> {
266    let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_TEMPERATURE_ALARM, crate::clusters::defs::CLUSTER_TEMPERATURE_ALARM_ATTR_ID_CRITICALUNDERTEMPERATURETHRESHOLD).await?;
267    decode_critical_under_temperature_threshold(&tlv)
268}
269