1use 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 LevelValue {
16 Unknown = 0,
18 Low = 1,
20 Medium = 2,
22 High = 3,
24 Critical = 4,
26}
27
28impl LevelValue {
29 pub fn from_u8(value: u8) -> Option<Self> {
31 match value {
32 0 => Some(LevelValue::Unknown),
33 1 => Some(LevelValue::Low),
34 2 => Some(LevelValue::Medium),
35 3 => Some(LevelValue::High),
36 4 => Some(LevelValue::Critical),
37 _ => None,
38 }
39 }
40
41 pub fn to_u8(self) -> u8 {
43 self as u8
44 }
45}
46
47impl From<LevelValue> for u8 {
48 fn from(val: LevelValue) -> Self {
49 val as u8
50 }
51}
52
53#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
54#[repr(u8)]
55pub enum MeasurementMedium {
56 Air = 0,
58 Water = 1,
60 Soil = 2,
62}
63
64impl MeasurementMedium {
65 pub fn from_u8(value: u8) -> Option<Self> {
67 match value {
68 0 => Some(MeasurementMedium::Air),
69 1 => Some(MeasurementMedium::Water),
70 2 => Some(MeasurementMedium::Soil),
71 _ => None,
72 }
73 }
74
75 pub fn to_u8(self) -> u8 {
77 self as u8
78 }
79}
80
81impl From<MeasurementMedium> for u8 {
82 fn from(val: MeasurementMedium) -> Self {
83 val as u8
84 }
85}
86
87#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
88#[repr(u8)]
89pub enum MeasurementUnit {
90 Ppm = 0,
92 Ppb = 1,
94 Ppt = 2,
96 Mgm3 = 3,
98 Ugm3 = 4,
100 Ngm3 = 5,
102 Pm3 = 6,
104 Bqm3 = 7,
106}
107
108impl MeasurementUnit {
109 pub fn from_u8(value: u8) -> Option<Self> {
111 match value {
112 0 => Some(MeasurementUnit::Ppm),
113 1 => Some(MeasurementUnit::Ppb),
114 2 => Some(MeasurementUnit::Ppt),
115 3 => Some(MeasurementUnit::Mgm3),
116 4 => Some(MeasurementUnit::Ugm3),
117 5 => Some(MeasurementUnit::Ngm3),
118 6 => Some(MeasurementUnit::Pm3),
119 7 => Some(MeasurementUnit::Bqm3),
120 _ => None,
121 }
122 }
123
124 pub fn to_u8(self) -> u8 {
126 self as u8
127 }
128}
129
130impl From<MeasurementUnit> for u8 {
131 fn from(val: MeasurementUnit) -> Self {
132 val as u8
133 }
134}
135
136pub fn decode_measured_value(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
140 if let tlv::TlvItemValue::Int(v) = inp {
141 Ok(Some(*v as u8))
142 } else {
143 Ok(None)
144 }
145}
146
147pub fn decode_min_measured_value(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
149 if let tlv::TlvItemValue::Int(v) = inp {
150 Ok(Some(*v as u8))
151 } else {
152 Ok(None)
153 }
154}
155
156pub fn decode_max_measured_value(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
158 if let tlv::TlvItemValue::Int(v) = inp {
159 Ok(Some(*v as u8))
160 } else {
161 Ok(None)
162 }
163}
164
165pub fn decode_peak_measured_value(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
167 if let tlv::TlvItemValue::Int(v) = inp {
168 Ok(Some(*v as u8))
169 } else {
170 Ok(None)
171 }
172}
173
174pub fn decode_peak_measured_value_window(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
176 if let tlv::TlvItemValue::Int(v) = inp {
177 Ok(*v as u32)
178 } else {
179 Err(anyhow::anyhow!("Expected UInt32"))
180 }
181}
182
183pub fn decode_average_measured_value(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
185 if let tlv::TlvItemValue::Int(v) = inp {
186 Ok(Some(*v as u8))
187 } else {
188 Ok(None)
189 }
190}
191
192pub fn decode_average_measured_value_window(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
194 if let tlv::TlvItemValue::Int(v) = inp {
195 Ok(*v as u32)
196 } else {
197 Err(anyhow::anyhow!("Expected UInt32"))
198 }
199}
200
201pub fn decode_uncertainty(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
203 if let tlv::TlvItemValue::Int(v) = inp {
204 Ok(*v as u8)
205 } else {
206 Err(anyhow::anyhow!("Expected UInt8"))
207 }
208}
209
210pub fn decode_measurement_unit(inp: &tlv::TlvItemValue) -> anyhow::Result<MeasurementUnit> {
212 if let tlv::TlvItemValue::Int(v) = inp {
213 MeasurementUnit::from_u8(*v as u8).ok_or_else(|| anyhow::anyhow!("Invalid enum value"))
214 } else {
215 Err(anyhow::anyhow!("Expected Integer"))
216 }
217}
218
219pub fn decode_measurement_medium(inp: &tlv::TlvItemValue) -> anyhow::Result<MeasurementMedium> {
221 if let tlv::TlvItemValue::Int(v) = inp {
222 MeasurementMedium::from_u8(*v as u8).ok_or_else(|| anyhow::anyhow!("Invalid enum value"))
223 } else {
224 Err(anyhow::anyhow!("Expected Integer"))
225 }
226}
227
228pub fn decode_level_value(inp: &tlv::TlvItemValue) -> anyhow::Result<LevelValue> {
230 if let tlv::TlvItemValue::Int(v) = inp {
231 LevelValue::from_u8(*v as u8).ok_or_else(|| anyhow::anyhow!("Invalid enum value"))
232 } else {
233 Err(anyhow::anyhow!("Expected Integer"))
234 }
235}
236
237
238pub fn decode_attribute_json(cluster_id: u32, attribute_id: u32, tlv_value: &crate::tlv::TlvItemValue) -> String {
250 if cluster_id != 0x0000 {
252 return format!("{{\"error\": \"Invalid cluster ID. Expected 0x0000, got {}\"}}", cluster_id);
253 }
254
255 match attribute_id {
256 0x0000 => {
257 match decode_measured_value(tlv_value) {
258 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
259 Err(e) => format!("{{\"error\": \"{}\"}}", e),
260 }
261 }
262 0x0001 => {
263 match decode_min_measured_value(tlv_value) {
264 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
265 Err(e) => format!("{{\"error\": \"{}\"}}", e),
266 }
267 }
268 0x0002 => {
269 match decode_max_measured_value(tlv_value) {
270 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
271 Err(e) => format!("{{\"error\": \"{}\"}}", e),
272 }
273 }
274 0x0003 => {
275 match decode_peak_measured_value(tlv_value) {
276 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
277 Err(e) => format!("{{\"error\": \"{}\"}}", e),
278 }
279 }
280 0x0004 => {
281 match decode_peak_measured_value_window(tlv_value) {
282 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
283 Err(e) => format!("{{\"error\": \"{}\"}}", e),
284 }
285 }
286 0x0005 => {
287 match decode_average_measured_value(tlv_value) {
288 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
289 Err(e) => format!("{{\"error\": \"{}\"}}", e),
290 }
291 }
292 0x0006 => {
293 match decode_average_measured_value_window(tlv_value) {
294 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
295 Err(e) => format!("{{\"error\": \"{}\"}}", e),
296 }
297 }
298 0x0007 => {
299 match decode_uncertainty(tlv_value) {
300 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
301 Err(e) => format!("{{\"error\": \"{}\"}}", e),
302 }
303 }
304 0x0008 => {
305 match decode_measurement_unit(tlv_value) {
306 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
307 Err(e) => format!("{{\"error\": \"{}\"}}", e),
308 }
309 }
310 0x0009 => {
311 match decode_measurement_medium(tlv_value) {
312 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
313 Err(e) => format!("{{\"error\": \"{}\"}}", e),
314 }
315 }
316 0x000A => {
317 match decode_level_value(tlv_value) {
318 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
319 Err(e) => format!("{{\"error\": \"{}\"}}", e),
320 }
321 }
322 _ => format!("{{\"error\": \"Unknown attribute ID: {}\"}}", attribute_id),
323 }
324}
325
326pub fn get_attribute_list() -> Vec<(u32, &'static str)> {
331 vec![
332 (0x0000, "MeasuredValue"),
333 (0x0001, "MinMeasuredValue"),
334 (0x0002, "MaxMeasuredValue"),
335 (0x0003, "PeakMeasuredValue"),
336 (0x0004, "PeakMeasuredValueWindow"),
337 (0x0005, "AverageMeasuredValue"),
338 (0x0006, "AverageMeasuredValueWindow"),
339 (0x0007, "Uncertainty"),
340 (0x0008, "MeasurementUnit"),
341 (0x0009, "MeasurementMedium"),
342 (0x000A, "LevelValue"),
343 ]
344}
345