matc/clusters/codec/
mode_rvc_run.rs

1//! Matter TLV encoders and decoders for RVC Run Mode Cluster
2//! Cluster ID: 0x0054
3//!
4//! This file is automatically generated from Mode_RVCRun.xml
5
6use crate::tlv;
7use anyhow;
8use serde_json;
9
10
11// Enum definitions
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
14#[repr(u16)]
15pub enum ModeTag {
16    Auto = 0,
17    Quick = 1,
18    Quiet = 2,
19    Lownoise = 3,
20    Lowenergy = 4,
21    Vacation = 5,
22    Min = 6,
23    Max = 7,
24    Night = 8,
25    Day = 9,
26    Idle = 16384,
27    Cleaning = 16385,
28    Mapping = 16386,
29}
30
31impl ModeTag {
32    /// Convert from u8 value (promoted to u16)
33    pub fn from_u8(value: u8) -> Option<Self> {
34        Self::from_u16(value as u16)
35    }
36
37    /// Convert from u16 value
38    pub fn from_u16(value: u16) -> Option<Self> {
39        match value {
40            0 => Some(ModeTag::Auto),
41            1 => Some(ModeTag::Quick),
42            2 => Some(ModeTag::Quiet),
43            3 => Some(ModeTag::Lownoise),
44            4 => Some(ModeTag::Lowenergy),
45            5 => Some(ModeTag::Vacation),
46            6 => Some(ModeTag::Min),
47            7 => Some(ModeTag::Max),
48            8 => Some(ModeTag::Night),
49            9 => Some(ModeTag::Day),
50            16384 => Some(ModeTag::Idle),
51            16385 => Some(ModeTag::Cleaning),
52            16386 => Some(ModeTag::Mapping),
53            _ => None,
54        }
55    }
56
57    /// Convert to u8 value (truncated if value > 255)
58    pub fn to_u8(self) -> u8 {
59        self as u8
60    }
61
62    /// Convert to u16 value
63    pub fn to_u16(self) -> u16 {
64        self as u16
65    }
66}
67
68impl From<ModeTag> for u16 {
69    fn from(val: ModeTag) -> Self {
70        val as u16
71    }
72}
73
74#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
75#[repr(u8)]
76pub enum StatusCode {
77    Stuck = 65,
78    Dustbinmissing = 66,
79    Dustbinfull = 67,
80    Watertankempty = 68,
81    Watertankmissing = 69,
82    Watertanklidopen = 70,
83    Mopcleaningpadmissing = 71,
84    Batterylow = 72,
85}
86
87impl StatusCode {
88    /// Convert from u8 value
89    pub fn from_u8(value: u8) -> Option<Self> {
90        match value {
91            65 => Some(StatusCode::Stuck),
92            66 => Some(StatusCode::Dustbinmissing),
93            67 => Some(StatusCode::Dustbinfull),
94            68 => Some(StatusCode::Watertankempty),
95            69 => Some(StatusCode::Watertankmissing),
96            70 => Some(StatusCode::Watertanklidopen),
97            71 => Some(StatusCode::Mopcleaningpadmissing),
98            72 => Some(StatusCode::Batterylow),
99            _ => None,
100        }
101    }
102
103    /// Convert to u8 value
104    pub fn to_u8(self) -> u8 {
105        self as u8
106    }
107}
108
109impl From<StatusCode> for u8 {
110    fn from(val: StatusCode) -> Self {
111        val as u8
112    }
113}
114
115// Struct definitions
116
117#[derive(Debug, serde::Serialize)]
118pub struct ModeOption {
119    pub label: Option<u8>,
120    pub mode: Option<u8>,
121    pub mode_tags: Option<u8>,
122}
123
124// Attribute decoders
125
126/// Decode SupportedModes attribute (0x0000)
127pub fn decode_supported_modes(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
128    if let tlv::TlvItemValue::Int(v) = inp {
129        Ok(*v as u8)
130    } else {
131        Err(anyhow::anyhow!("Expected UInt8"))
132    }
133}
134
135/// Decode CurrentMode attribute (0x0001)
136pub fn decode_current_mode(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
137    if let tlv::TlvItemValue::Int(v) = inp {
138        Ok(*v as u8)
139    } else {
140        Err(anyhow::anyhow!("Expected UInt8"))
141    }
142}
143
144/// Decode StartUpMode attribute (0x0002)
145pub fn decode_start_up_mode(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
146    if let tlv::TlvItemValue::Int(v) = inp {
147        Ok(*v as u8)
148    } else {
149        Err(anyhow::anyhow!("Expected UInt8"))
150    }
151}
152
153/// Decode OnMode attribute (0x0003)
154pub fn decode_on_mode(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
155    if let tlv::TlvItemValue::Int(v) = inp {
156        Ok(*v as u8)
157    } else {
158        Err(anyhow::anyhow!("Expected UInt8"))
159    }
160}
161
162
163// JSON dispatcher function
164
165/// Decode attribute value and return as JSON string
166///
167/// # Parameters
168/// * `cluster_id` - The cluster identifier
169/// * `attribute_id` - The attribute identifier
170/// * `tlv_value` - The TLV value to decode
171///
172/// # Returns
173/// JSON string representation of the decoded value or error
174pub fn decode_attribute_json(cluster_id: u32, attribute_id: u32, tlv_value: &crate::tlv::TlvItemValue) -> String {
175    // Verify this is the correct cluster
176    if cluster_id != 0x0054 {
177        return format!("{{\"error\": \"Invalid cluster ID. Expected 0x0054, got {}\"}}", cluster_id);
178    }
179
180    match attribute_id {
181        0x0000 => {
182            match decode_supported_modes(tlv_value) {
183                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
184                Err(e) => format!("{{\"error\": \"{}\"}}", e),
185            }
186        }
187        0x0001 => {
188            match decode_current_mode(tlv_value) {
189                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
190                Err(e) => format!("{{\"error\": \"{}\"}}", e),
191            }
192        }
193        0x0002 => {
194            match decode_start_up_mode(tlv_value) {
195                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
196                Err(e) => format!("{{\"error\": \"{}\"}}", e),
197            }
198        }
199        0x0003 => {
200            match decode_on_mode(tlv_value) {
201                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
202                Err(e) => format!("{{\"error\": \"{}\"}}", e),
203            }
204        }
205        _ => format!("{{\"error\": \"Unknown attribute ID: {}\"}}", attribute_id),
206    }
207}
208
209/// Get list of all attributes supported by this cluster
210///
211/// # Returns
212/// Vector of tuples containing (attribute_id, attribute_name)
213pub fn get_attribute_list() -> Vec<(u32, &'static str)> {
214    vec![
215        (0x0000, "SupportedModes"),
216        (0x0001, "CurrentMode"),
217        (0x0002, "StartUpMode"),
218        (0x0003, "OnMode"),
219    ]
220}
221