matc/clusters/codec/
laundry_washer_controls.rs1use crate::tlv;
7use anyhow;
8use serde_json;
9
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
14#[repr(u8)]
15pub enum NumberOfRinses {
16 None = 0,
18 Normal = 1,
20 Extra = 2,
22 Max = 3,
24}
25
26impl NumberOfRinses {
27 pub fn from_u8(value: u8) -> Option<Self> {
29 match value {
30 0 => Some(NumberOfRinses::None),
31 1 => Some(NumberOfRinses::Normal),
32 2 => Some(NumberOfRinses::Extra),
33 3 => Some(NumberOfRinses::Max),
34 _ => None,
35 }
36 }
37
38 pub fn to_u8(self) -> u8 {
40 self as u8
41 }
42}
43
44impl From<NumberOfRinses> for u8 {
45 fn from(val: NumberOfRinses) -> Self {
46 val as u8
47 }
48}
49
50pub fn decode_spin_speeds(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<String>> {
54 let mut res = Vec::new();
55 if let tlv::TlvItemValue::List(v) = inp {
56 for item in v {
57 if let tlv::TlvItemValue::String(s) = &item.value {
58 res.push(s.clone());
59 }
60 }
61 }
62 Ok(res)
63}
64
65pub fn decode_spin_speed_current(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
67 if let tlv::TlvItemValue::Int(v) = inp {
68 Ok(Some(*v as u8))
69 } else {
70 Ok(None)
71 }
72}
73
74pub fn decode_number_of_rinses(inp: &tlv::TlvItemValue) -> anyhow::Result<NumberOfRinses> {
76 if let tlv::TlvItemValue::Int(v) = inp {
77 NumberOfRinses::from_u8(*v as u8).ok_or_else(|| anyhow::anyhow!("Invalid enum value"))
78 } else {
79 Err(anyhow::anyhow!("Expected Integer"))
80 }
81}
82
83pub fn decode_supported_rinses(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<NumberOfRinses>> {
85 let mut res = Vec::new();
86 if let tlv::TlvItemValue::List(v) = inp {
87 for item in v {
88 if let tlv::TlvItemValue::Int(i) = &item.value {
89 if let Some(enum_val) = NumberOfRinses::from_u8(*i as u8) {
90 res.push(enum_val);
91 }
92 }
93 }
94 }
95 Ok(res)
96}
97
98
99pub fn decode_attribute_json(cluster_id: u32, attribute_id: u32, tlv_value: &crate::tlv::TlvItemValue) -> String {
111 if cluster_id != 0x0053 {
113 return format!("{{\"error\": \"Invalid cluster ID. Expected 0x0053, got {}\"}}", cluster_id);
114 }
115
116 match attribute_id {
117 0x0000 => {
118 match decode_spin_speeds(tlv_value) {
119 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
120 Err(e) => format!("{{\"error\": \"{}\"}}", e),
121 }
122 }
123 0x0001 => {
124 match decode_spin_speed_current(tlv_value) {
125 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
126 Err(e) => format!("{{\"error\": \"{}\"}}", e),
127 }
128 }
129 0x0002 => {
130 match decode_number_of_rinses(tlv_value) {
131 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
132 Err(e) => format!("{{\"error\": \"{}\"}}", e),
133 }
134 }
135 0x0003 => {
136 match decode_supported_rinses(tlv_value) {
137 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
138 Err(e) => format!("{{\"error\": \"{}\"}}", e),
139 }
140 }
141 _ => format!("{{\"error\": \"Unknown attribute ID: {}\"}}", attribute_id),
142 }
143}
144
145pub fn get_attribute_list() -> Vec<(u32, &'static str)> {
150 vec![
151 (0x0000, "SpinSpeeds"),
152 (0x0001, "SpinSpeedCurrent"),
153 (0x0002, "NumberOfRinses"),
154 (0x0003, "SupportedRinses"),
155 ]
156}
157