matc/clusters/codec/
switch.rs1use crate::tlv;
7use anyhow;
8use serde_json;
9
10
11pub fn decode_number_of_positions(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
15 if let tlv::TlvItemValue::Int(v) = inp {
16 Ok(*v as u8)
17 } else {
18 Err(anyhow::anyhow!("Expected UInt8"))
19 }
20}
21
22pub fn decode_current_position(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
24 if let tlv::TlvItemValue::Int(v) = inp {
25 Ok(*v as u8)
26 } else {
27 Err(anyhow::anyhow!("Expected UInt8"))
28 }
29}
30
31pub fn decode_multi_press_max(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
33 if let tlv::TlvItemValue::Int(v) = inp {
34 Ok(*v as u8)
35 } else {
36 Err(anyhow::anyhow!("Expected UInt8"))
37 }
38}
39
40
41pub fn decode_attribute_json(cluster_id: u32, attribute_id: u32, tlv_value: &crate::tlv::TlvItemValue) -> String {
53 if cluster_id != 0x003B {
55 return format!("{{\"error\": \"Invalid cluster ID. Expected 0x003B, got {}\"}}", cluster_id);
56 }
57
58 match attribute_id {
59 0x0000 => {
60 match decode_number_of_positions(tlv_value) {
61 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
62 Err(e) => format!("{{\"error\": \"{}\"}}", e),
63 }
64 }
65 0x0001 => {
66 match decode_current_position(tlv_value) {
67 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
68 Err(e) => format!("{{\"error\": \"{}\"}}", e),
69 }
70 }
71 0x0002 => {
72 match decode_multi_press_max(tlv_value) {
73 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
74 Err(e) => format!("{{\"error\": \"{}\"}}", e),
75 }
76 }
77 _ => format!("{{\"error\": \"Unknown attribute ID: {}\"}}", attribute_id),
78 }
79}
80
81pub fn get_attribute_list() -> Vec<(u32, &'static str)> {
86 vec![
87 (0x0000, "NumberOfPositions"),
88 (0x0001, "CurrentPosition"),
89 (0x0002, "MultiPressMax"),
90 ]
91}
92
93#[derive(Debug, serde::Serialize)]
94pub struct SwitchLatchedEvent {
95 pub new_position: Option<u8>,
96}
97
98#[derive(Debug, serde::Serialize)]
99pub struct InitialPressEvent {
100 pub new_position: Option<u8>,
101}
102
103#[derive(Debug, serde::Serialize)]
104pub struct LongPressEvent {
105 pub new_position: Option<u8>,
106}
107
108#[derive(Debug, serde::Serialize)]
109pub struct ShortReleaseEvent {
110 pub previous_position: Option<u8>,
111}
112
113#[derive(Debug, serde::Serialize)]
114pub struct LongReleaseEvent {
115 pub previous_position: Option<u8>,
116}
117
118#[derive(Debug, serde::Serialize)]
119pub struct MultiPressOngoingEvent {
120 pub new_position: Option<u8>,
121 pub current_number_of_presses_counted: Option<u8>,
122}
123
124#[derive(Debug, serde::Serialize)]
125pub struct MultiPressCompleteEvent {
126 pub previous_position: Option<u8>,
127 pub total_number_of_presses_counted: Option<u8>,
128}
129
130pub fn decode_switch_latched_event(inp: &tlv::TlvItemValue) -> anyhow::Result<SwitchLatchedEvent> {
134 if let tlv::TlvItemValue::List(_fields) = inp {
135 let item = tlv::TlvItem { tag: 0, value: inp.clone() };
136 Ok(SwitchLatchedEvent {
137 new_position: item.get_int(&[0]).map(|v| v as u8),
138 })
139 } else {
140 Err(anyhow::anyhow!("Expected struct fields"))
141 }
142}
143
144pub fn decode_initial_press_event(inp: &tlv::TlvItemValue) -> anyhow::Result<InitialPressEvent> {
146 if let tlv::TlvItemValue::List(_fields) = inp {
147 let item = tlv::TlvItem { tag: 0, value: inp.clone() };
148 Ok(InitialPressEvent {
149 new_position: item.get_int(&[0]).map(|v| v as u8),
150 })
151 } else {
152 Err(anyhow::anyhow!("Expected struct fields"))
153 }
154}
155
156pub fn decode_long_press_event(inp: &tlv::TlvItemValue) -> anyhow::Result<LongPressEvent> {
158 if let tlv::TlvItemValue::List(_fields) = inp {
159 let item = tlv::TlvItem { tag: 0, value: inp.clone() };
160 Ok(LongPressEvent {
161 new_position: item.get_int(&[0]).map(|v| v as u8),
162 })
163 } else {
164 Err(anyhow::anyhow!("Expected struct fields"))
165 }
166}
167
168pub fn decode_short_release_event(inp: &tlv::TlvItemValue) -> anyhow::Result<ShortReleaseEvent> {
170 if let tlv::TlvItemValue::List(_fields) = inp {
171 let item = tlv::TlvItem { tag: 0, value: inp.clone() };
172 Ok(ShortReleaseEvent {
173 previous_position: item.get_int(&[0]).map(|v| v as u8),
174 })
175 } else {
176 Err(anyhow::anyhow!("Expected struct fields"))
177 }
178}
179
180pub fn decode_long_release_event(inp: &tlv::TlvItemValue) -> anyhow::Result<LongReleaseEvent> {
182 if let tlv::TlvItemValue::List(_fields) = inp {
183 let item = tlv::TlvItem { tag: 0, value: inp.clone() };
184 Ok(LongReleaseEvent {
185 previous_position: item.get_int(&[0]).map(|v| v as u8),
186 })
187 } else {
188 Err(anyhow::anyhow!("Expected struct fields"))
189 }
190}
191
192pub fn decode_multi_press_ongoing_event(inp: &tlv::TlvItemValue) -> anyhow::Result<MultiPressOngoingEvent> {
194 if let tlv::TlvItemValue::List(_fields) = inp {
195 let item = tlv::TlvItem { tag: 0, value: inp.clone() };
196 Ok(MultiPressOngoingEvent {
197 new_position: item.get_int(&[0]).map(|v| v as u8),
198 current_number_of_presses_counted: item.get_int(&[1]).map(|v| v as u8),
199 })
200 } else {
201 Err(anyhow::anyhow!("Expected struct fields"))
202 }
203}
204
205pub fn decode_multi_press_complete_event(inp: &tlv::TlvItemValue) -> anyhow::Result<MultiPressCompleteEvent> {
207 if let tlv::TlvItemValue::List(_fields) = inp {
208 let item = tlv::TlvItem { tag: 0, value: inp.clone() };
209 Ok(MultiPressCompleteEvent {
210 previous_position: item.get_int(&[0]).map(|v| v as u8),
211 total_number_of_presses_counted: item.get_int(&[1]).map(|v| v as u8),
212 })
213 } else {
214 Err(anyhow::anyhow!("Expected struct fields"))
215 }
216}
217