matc/clusters/codec/
mode_rvc_clean.rs1use crate::tlv;
7use anyhow;
8use serde_json;
9
10
11#[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 Deepclean = 16384,
27 Vacuum = 16385,
28 Mop = 16386,
29 VacuumThenMop = 16387,
30}
31
32impl ModeTag {
33 pub fn from_u8(value: u8) -> Option<Self> {
35 Self::from_u16(value as u16)
36 }
37
38 pub fn from_u16(value: u16) -> Option<Self> {
40 match value {
41 0 => Some(ModeTag::Auto),
42 1 => Some(ModeTag::Quick),
43 2 => Some(ModeTag::Quiet),
44 3 => Some(ModeTag::Lownoise),
45 4 => Some(ModeTag::Lowenergy),
46 5 => Some(ModeTag::Vacation),
47 6 => Some(ModeTag::Min),
48 7 => Some(ModeTag::Max),
49 8 => Some(ModeTag::Night),
50 9 => Some(ModeTag::Day),
51 16384 => Some(ModeTag::Deepclean),
52 16385 => Some(ModeTag::Vacuum),
53 16386 => Some(ModeTag::Mop),
54 16387 => Some(ModeTag::VacuumThenMop),
55 _ => None,
56 }
57 }
58
59 pub fn to_u8(self) -> u8 {
61 self as u8
62 }
63
64 pub fn to_u16(self) -> u16 {
66 self as u16
67 }
68}
69
70impl From<ModeTag> for u16 {
71 fn from(val: ModeTag) -> Self {
72 val as u16
73 }
74}
75
76#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
77#[repr(u8)]
78pub enum StatusCode {
79 Cleaninginprogress = 64,
80}
81
82impl StatusCode {
83 pub fn from_u8(value: u8) -> Option<Self> {
85 match value {
86 64 => Some(StatusCode::Cleaninginprogress),
87 _ => None,
88 }
89 }
90
91 pub fn to_u8(self) -> u8 {
93 self as u8
94 }
95}
96
97impl From<StatusCode> for u8 {
98 fn from(val: StatusCode) -> Self {
99 val as u8
100 }
101}
102
103#[derive(Debug, serde::Serialize)]
106pub struct ModeOption {
107 pub label: Option<u8>,
108 pub mode: Option<u8>,
109 pub mode_tags: Option<u8>,
110}
111
112pub fn decode_supported_modes(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
116 if let tlv::TlvItemValue::Int(v) = inp {
117 Ok(*v as u8)
118 } else {
119 Err(anyhow::anyhow!("Expected UInt8"))
120 }
121}
122
123pub fn decode_current_mode(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
125 if let tlv::TlvItemValue::Int(v) = inp {
126 Ok(*v as u8)
127 } else {
128 Err(anyhow::anyhow!("Expected UInt8"))
129 }
130}
131
132pub fn decode_start_up_mode(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
134 if let tlv::TlvItemValue::Int(v) = inp {
135 Ok(*v as u8)
136 } else {
137 Err(anyhow::anyhow!("Expected UInt8"))
138 }
139}
140
141pub fn decode_on_mode(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
143 if let tlv::TlvItemValue::Int(v) = inp {
144 Ok(*v as u8)
145 } else {
146 Err(anyhow::anyhow!("Expected UInt8"))
147 }
148}
149
150
151pub fn decode_attribute_json(cluster_id: u32, attribute_id: u32, tlv_value: &crate::tlv::TlvItemValue) -> String {
163 if cluster_id != 0x0055 {
165 return format!("{{\"error\": \"Invalid cluster ID. Expected 0x0055, got {}\"}}", cluster_id);
166 }
167
168 match attribute_id {
169 0x0000 => {
170 match decode_supported_modes(tlv_value) {
171 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
172 Err(e) => format!("{{\"error\": \"{}\"}}", e),
173 }
174 }
175 0x0001 => {
176 match decode_current_mode(tlv_value) {
177 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
178 Err(e) => format!("{{\"error\": \"{}\"}}", e),
179 }
180 }
181 0x0002 => {
182 match decode_start_up_mode(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 0x0003 => {
188 match decode_on_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 _ => format!("{{\"error\": \"Unknown attribute ID: {}\"}}", attribute_id),
194 }
195}
196
197pub fn get_attribute_list() -> Vec<(u32, &'static str)> {
202 vec![
203 (0x0000, "SupportedModes"),
204 (0x0001, "CurrentMode"),
205 (0x0002, "StartUpMode"),
206 (0x0003, "OnMode"),
207 ]
208}
209