1#![allow(clippy::too_many_arguments)]
7
8use crate::tlv;
9use anyhow;
10use serde_json;
11
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
16#[repr(u8)]
17pub enum LevelValue {
18 Unknown = 0,
20 Low = 1,
22 Medium = 2,
24 High = 3,
26 Critical = 4,
28}
29
30impl LevelValue {
31 pub fn from_u8(value: u8) -> Option<Self> {
33 match value {
34 0 => Some(LevelValue::Unknown),
35 1 => Some(LevelValue::Low),
36 2 => Some(LevelValue::Medium),
37 3 => Some(LevelValue::High),
38 4 => Some(LevelValue::Critical),
39 _ => None,
40 }
41 }
42
43 pub fn to_u8(self) -> u8 {
45 self as u8
46 }
47}
48
49impl From<LevelValue> for u8 {
50 fn from(val: LevelValue) -> Self {
51 val as u8
52 }
53}
54
55#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
56#[repr(u8)]
57pub enum MeasurementMedium {
58 Air = 0,
60 Water = 1,
62 Soil = 2,
64}
65
66impl MeasurementMedium {
67 pub fn from_u8(value: u8) -> Option<Self> {
69 match value {
70 0 => Some(MeasurementMedium::Air),
71 1 => Some(MeasurementMedium::Water),
72 2 => Some(MeasurementMedium::Soil),
73 _ => None,
74 }
75 }
76
77 pub fn to_u8(self) -> u8 {
79 self as u8
80 }
81}
82
83impl From<MeasurementMedium> for u8 {
84 fn from(val: MeasurementMedium) -> Self {
85 val as u8
86 }
87}
88
89#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
90#[repr(u8)]
91pub enum MeasurementUnit {
92 Ppm = 0,
94 Ppb = 1,
96 Ppt = 2,
98 Mgm3 = 3,
100 Ugm3 = 4,
102 Ngm3 = 5,
104 Pm3 = 6,
106 Bqm3 = 7,
108}
109
110impl MeasurementUnit {
111 pub fn from_u8(value: u8) -> Option<Self> {
113 match value {
114 0 => Some(MeasurementUnit::Ppm),
115 1 => Some(MeasurementUnit::Ppb),
116 2 => Some(MeasurementUnit::Ppt),
117 3 => Some(MeasurementUnit::Mgm3),
118 4 => Some(MeasurementUnit::Ugm3),
119 5 => Some(MeasurementUnit::Ngm3),
120 6 => Some(MeasurementUnit::Pm3),
121 7 => Some(MeasurementUnit::Bqm3),
122 _ => None,
123 }
124 }
125
126 pub fn to_u8(self) -> u8 {
128 self as u8
129 }
130}
131
132impl From<MeasurementUnit> for u8 {
133 fn from(val: MeasurementUnit) -> Self {
134 val as u8
135 }
136}
137
138pub fn decode_measured_value(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
142 if let tlv::TlvItemValue::Int(v) = inp {
143 Ok(Some(*v as u8))
144 } else {
145 Ok(None)
146 }
147}
148
149pub fn decode_min_measured_value(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
151 if let tlv::TlvItemValue::Int(v) = inp {
152 Ok(Some(*v as u8))
153 } else {
154 Ok(None)
155 }
156}
157
158pub fn decode_max_measured_value(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
160 if let tlv::TlvItemValue::Int(v) = inp {
161 Ok(Some(*v as u8))
162 } else {
163 Ok(None)
164 }
165}
166
167pub fn decode_peak_measured_value(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
169 if let tlv::TlvItemValue::Int(v) = inp {
170 Ok(Some(*v as u8))
171 } else {
172 Ok(None)
173 }
174}
175
176pub fn decode_peak_measured_value_window(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
178 if let tlv::TlvItemValue::Int(v) = inp {
179 Ok(*v as u32)
180 } else {
181 Err(anyhow::anyhow!("Expected UInt32"))
182 }
183}
184
185pub fn decode_average_measured_value(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
187 if let tlv::TlvItemValue::Int(v) = inp {
188 Ok(Some(*v as u8))
189 } else {
190 Ok(None)
191 }
192}
193
194pub fn decode_average_measured_value_window(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
196 if let tlv::TlvItemValue::Int(v) = inp {
197 Ok(*v as u32)
198 } else {
199 Err(anyhow::anyhow!("Expected UInt32"))
200 }
201}
202
203pub fn decode_uncertainty(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
205 if let tlv::TlvItemValue::Int(v) = inp {
206 Ok(*v as u8)
207 } else {
208 Err(anyhow::anyhow!("Expected UInt8"))
209 }
210}
211
212pub fn decode_measurement_unit(inp: &tlv::TlvItemValue) -> anyhow::Result<MeasurementUnit> {
214 if let tlv::TlvItemValue::Int(v) = inp {
215 MeasurementUnit::from_u8(*v as u8).ok_or_else(|| anyhow::anyhow!("Invalid enum value"))
216 } else {
217 Err(anyhow::anyhow!("Expected Integer"))
218 }
219}
220
221pub fn decode_measurement_medium(inp: &tlv::TlvItemValue) -> anyhow::Result<MeasurementMedium> {
223 if let tlv::TlvItemValue::Int(v) = inp {
224 MeasurementMedium::from_u8(*v as u8).ok_or_else(|| anyhow::anyhow!("Invalid enum value"))
225 } else {
226 Err(anyhow::anyhow!("Expected Integer"))
227 }
228}
229
230pub fn decode_level_value(inp: &tlv::TlvItemValue) -> anyhow::Result<LevelValue> {
232 if let tlv::TlvItemValue::Int(v) = inp {
233 LevelValue::from_u8(*v as u8).ok_or_else(|| anyhow::anyhow!("Invalid enum value"))
234 } else {
235 Err(anyhow::anyhow!("Expected Integer"))
236 }
237}
238
239
240pub fn decode_attribute_json(cluster_id: u32, attribute_id: u32, tlv_value: &crate::tlv::TlvItemValue) -> String {
252 if cluster_id != 0x0000 {
254 return format!("{{\"error\": \"Invalid cluster ID. Expected 0x0000, got {}\"}}", cluster_id);
255 }
256
257 match attribute_id {
258 0x0000 => {
259 match decode_measured_value(tlv_value) {
260 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
261 Err(e) => format!("{{\"error\": \"{}\"}}", e),
262 }
263 }
264 0x0001 => {
265 match decode_min_measured_value(tlv_value) {
266 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
267 Err(e) => format!("{{\"error\": \"{}\"}}", e),
268 }
269 }
270 0x0002 => {
271 match decode_max_measured_value(tlv_value) {
272 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
273 Err(e) => format!("{{\"error\": \"{}\"}}", e),
274 }
275 }
276 0x0003 => {
277 match decode_peak_measured_value(tlv_value) {
278 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
279 Err(e) => format!("{{\"error\": \"{}\"}}", e),
280 }
281 }
282 0x0004 => {
283 match decode_peak_measured_value_window(tlv_value) {
284 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
285 Err(e) => format!("{{\"error\": \"{}\"}}", e),
286 }
287 }
288 0x0005 => {
289 match decode_average_measured_value(tlv_value) {
290 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
291 Err(e) => format!("{{\"error\": \"{}\"}}", e),
292 }
293 }
294 0x0006 => {
295 match decode_average_measured_value_window(tlv_value) {
296 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
297 Err(e) => format!("{{\"error\": \"{}\"}}", e),
298 }
299 }
300 0x0007 => {
301 match decode_uncertainty(tlv_value) {
302 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
303 Err(e) => format!("{{\"error\": \"{}\"}}", e),
304 }
305 }
306 0x0008 => {
307 match decode_measurement_unit(tlv_value) {
308 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
309 Err(e) => format!("{{\"error\": \"{}\"}}", e),
310 }
311 }
312 0x0009 => {
313 match decode_measurement_medium(tlv_value) {
314 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
315 Err(e) => format!("{{\"error\": \"{}\"}}", e),
316 }
317 }
318 0x000A => {
319 match decode_level_value(tlv_value) {
320 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
321 Err(e) => format!("{{\"error\": \"{}\"}}", e),
322 }
323 }
324 _ => format!("{{\"error\": \"Unknown attribute ID: {}\"}}", attribute_id),
325 }
326}
327
328pub fn get_attribute_list() -> Vec<(u32, &'static str)> {
333 vec![
334 (0x0000, "MeasuredValue"),
335 (0x0001, "MinMeasuredValue"),
336 (0x0002, "MaxMeasuredValue"),
337 (0x0003, "PeakMeasuredValue"),
338 (0x0004, "PeakMeasuredValueWindow"),
339 (0x0005, "AverageMeasuredValue"),
340 (0x0006, "AverageMeasuredValueWindow"),
341 (0x0007, "Uncertainty"),
342 (0x0008, "MeasurementUnit"),
343 (0x0009, "MeasurementMedium"),
344 (0x000A, "LevelValue"),
345 ]
346}
347
348pub async fn read_measured_value(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Option<u8>> {
352 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_RADON_CONCENTRATION_MEASUREMENT, crate::clusters::defs::CLUSTER_RADON_CONCENTRATION_MEASUREMENT_ATTR_ID_MEASUREDVALUE).await?;
353 decode_measured_value(&tlv)
354}
355
356pub async fn read_min_measured_value(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Option<u8>> {
358 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_RADON_CONCENTRATION_MEASUREMENT, crate::clusters::defs::CLUSTER_RADON_CONCENTRATION_MEASUREMENT_ATTR_ID_MINMEASUREDVALUE).await?;
359 decode_min_measured_value(&tlv)
360}
361
362pub async fn read_max_measured_value(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Option<u8>> {
364 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_RADON_CONCENTRATION_MEASUREMENT, crate::clusters::defs::CLUSTER_RADON_CONCENTRATION_MEASUREMENT_ATTR_ID_MAXMEASUREDVALUE).await?;
365 decode_max_measured_value(&tlv)
366}
367
368pub async fn read_peak_measured_value(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Option<u8>> {
370 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_RADON_CONCENTRATION_MEASUREMENT, crate::clusters::defs::CLUSTER_RADON_CONCENTRATION_MEASUREMENT_ATTR_ID_PEAKMEASUREDVALUE).await?;
371 decode_peak_measured_value(&tlv)
372}
373
374pub async fn read_peak_measured_value_window(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u32> {
376 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_RADON_CONCENTRATION_MEASUREMENT, crate::clusters::defs::CLUSTER_RADON_CONCENTRATION_MEASUREMENT_ATTR_ID_PEAKMEASUREDVALUEWINDOW).await?;
377 decode_peak_measured_value_window(&tlv)
378}
379
380pub async fn read_average_measured_value(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Option<u8>> {
382 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_RADON_CONCENTRATION_MEASUREMENT, crate::clusters::defs::CLUSTER_RADON_CONCENTRATION_MEASUREMENT_ATTR_ID_AVERAGEMEASUREDVALUE).await?;
383 decode_average_measured_value(&tlv)
384}
385
386pub async fn read_average_measured_value_window(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u32> {
388 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_RADON_CONCENTRATION_MEASUREMENT, crate::clusters::defs::CLUSTER_RADON_CONCENTRATION_MEASUREMENT_ATTR_ID_AVERAGEMEASUREDVALUEWINDOW).await?;
389 decode_average_measured_value_window(&tlv)
390}
391
392pub async fn read_uncertainty(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u8> {
394 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_RADON_CONCENTRATION_MEASUREMENT, crate::clusters::defs::CLUSTER_RADON_CONCENTRATION_MEASUREMENT_ATTR_ID_UNCERTAINTY).await?;
395 decode_uncertainty(&tlv)
396}
397
398pub async fn read_measurement_unit(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<MeasurementUnit> {
400 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_RADON_CONCENTRATION_MEASUREMENT, crate::clusters::defs::CLUSTER_RADON_CONCENTRATION_MEASUREMENT_ATTR_ID_MEASUREMENTUNIT).await?;
401 decode_measurement_unit(&tlv)
402}
403
404pub async fn read_measurement_medium(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<MeasurementMedium> {
406 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_RADON_CONCENTRATION_MEASUREMENT, crate::clusters::defs::CLUSTER_RADON_CONCENTRATION_MEASUREMENT_ATTR_ID_MEASUREMENTMEDIUM).await?;
407 decode_measurement_medium(&tlv)
408}
409
410pub async fn read_level_value(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<LevelValue> {
412 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_RADON_CONCENTRATION_MEASUREMENT, crate::clusters::defs::CLUSTER_RADON_CONCENTRATION_MEASUREMENT_ATTR_ID_LEVELVALUE).await?;
413 decode_level_value(&tlv)
414}
415