1use 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 Idle = 16384,
27 Cleaning = 16385,
28 Mapping = 16386,
29}
30
31impl ModeTag {
32 pub fn from_u8(value: u8) -> Option<Self> {
34 Self::from_u16(value as u16)
35 }
36
37 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 pub fn to_u8(self) -> u8 {
59 self as u8
60 }
61
62 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 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 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#[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
124pub 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
135pub 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
144pub 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
153pub 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
163pub fn decode_attribute_json(cluster_id: u32, attribute_id: u32, tlv_value: &crate::tlv::TlvItemValue) -> String {
175 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
209pub 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