1use crate::tlv;
7use anyhow;
8use serde_json;
9
10
11#[derive(Debug, serde::Serialize)]
14pub struct HarmonicMeasurement {
15 pub order: Option<u8>,
16 pub measurement: Option<i64>,
17}
18
19#[derive(Debug, serde::Serialize)]
20pub struct MeasurementRange {
21 pub measurement_type: Option<u8>,
22 pub min: Option<i64>,
23 pub max: Option<i64>,
24 pub start_timestamp: Option<u64>,
25 pub end_timestamp: Option<u64>,
26 pub min_timestamp: Option<u64>,
27 pub max_timestamp: Option<u64>,
28 pub start_systime: Option<u8>,
29 pub end_systime: Option<u8>,
30 pub min_systime: Option<u8>,
31 pub max_systime: Option<u8>,
32}
33
34pub fn decode_power_mode(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
38 if let tlv::TlvItemValue::Int(v) = inp {
39 Ok(*v as u8)
40 } else {
41 Err(anyhow::anyhow!("Expected Integer"))
42 }
43}
44
45pub fn decode_number_of_measurement_types(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
47 if let tlv::TlvItemValue::Int(v) = inp {
48 Ok(*v as u8)
49 } else {
50 Err(anyhow::anyhow!("Expected Integer"))
51 }
52}
53
54pub fn decode_accuracy(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<String>> {
56 let mut res = Vec::new();
57 if let tlv::TlvItemValue::List(v) = inp {
58 for item in v {
59 if let tlv::TlvItemValue::String(s) = &item.value {
60 res.push(s.clone());
61 }
62 }
63 }
64 Ok(res)
65}
66
67pub fn decode_ranges(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<MeasurementRange>> {
69 let mut res = Vec::new();
70 if let tlv::TlvItemValue::List(v) = inp {
71 for item in v {
72 res.push(MeasurementRange {
73 measurement_type: item.get_int(&[0]).map(|v| v as u8),
74 min: item.get_int(&[1]).map(|v| v as i64),
75 max: item.get_int(&[2]).map(|v| v as i64),
76 start_timestamp: item.get_int(&[3]),
77 end_timestamp: item.get_int(&[4]),
78 min_timestamp: item.get_int(&[5]),
79 max_timestamp: item.get_int(&[6]),
80 start_systime: item.get_int(&[7]).map(|v| v as u8),
81 end_systime: item.get_int(&[8]).map(|v| v as u8),
82 min_systime: item.get_int(&[9]).map(|v| v as u8),
83 max_systime: item.get_int(&[10]).map(|v| v as u8),
84 });
85 }
86 }
87 Ok(res)
88}
89
90pub fn decode_voltage(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
92 if let tlv::TlvItemValue::Int(v) = inp {
93 Ok(Some(*v as u8))
94 } else {
95 Ok(None)
96 }
97}
98
99pub fn decode_active_current(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
101 if let tlv::TlvItemValue::Int(v) = inp {
102 Ok(Some(*v as u8))
103 } else {
104 Ok(None)
105 }
106}
107
108pub fn decode_reactive_current(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
110 if let tlv::TlvItemValue::Int(v) = inp {
111 Ok(Some(*v as u8))
112 } else {
113 Ok(None)
114 }
115}
116
117pub fn decode_apparent_current(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
119 if let tlv::TlvItemValue::Int(v) = inp {
120 Ok(Some(*v as u8))
121 } else {
122 Ok(None)
123 }
124}
125
126pub fn decode_active_power(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
128 if let tlv::TlvItemValue::Int(v) = inp {
129 Ok(Some(*v as u8))
130 } else {
131 Ok(None)
132 }
133}
134
135pub fn decode_reactive_power(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
137 if let tlv::TlvItemValue::Int(v) = inp {
138 Ok(Some(*v as u8))
139 } else {
140 Ok(None)
141 }
142}
143
144pub fn decode_apparent_power(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
146 if let tlv::TlvItemValue::Int(v) = inp {
147 Ok(Some(*v as u8))
148 } else {
149 Ok(None)
150 }
151}
152
153pub fn decode_rms_voltage(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
155 if let tlv::TlvItemValue::Int(v) = inp {
156 Ok(Some(*v as u8))
157 } else {
158 Ok(None)
159 }
160}
161
162pub fn decode_rms_current(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
164 if let tlv::TlvItemValue::Int(v) = inp {
165 Ok(Some(*v as u8))
166 } else {
167 Ok(None)
168 }
169}
170
171pub fn decode_rms_power(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
173 if let tlv::TlvItemValue::Int(v) = inp {
174 Ok(Some(*v as u8))
175 } else {
176 Ok(None)
177 }
178}
179
180pub fn decode_frequency(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<i64>> {
182 if let tlv::TlvItemValue::Int(v) = inp {
183 Ok(Some(*v as i64))
184 } else {
185 Ok(None)
186 }
187}
188
189pub fn decode_harmonic_currents(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<HarmonicMeasurement>> {
191 let mut res = Vec::new();
192 if let tlv::TlvItemValue::List(v) = inp {
193 for item in v {
194 res.push(HarmonicMeasurement {
195 order: item.get_int(&[0]).map(|v| v as u8),
196 measurement: item.get_int(&[1]).map(|v| v as i64),
197 });
198 }
199 }
200 Ok(res)
201}
202
203pub fn decode_harmonic_phases(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<HarmonicMeasurement>> {
205 let mut res = Vec::new();
206 if let tlv::TlvItemValue::List(v) = inp {
207 for item in v {
208 res.push(HarmonicMeasurement {
209 order: item.get_int(&[0]).map(|v| v as u8),
210 measurement: item.get_int(&[1]).map(|v| v as i64),
211 });
212 }
213 }
214 Ok(res)
215}
216
217pub fn decode_power_factor(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<i64>> {
219 if let tlv::TlvItemValue::Int(v) = inp {
220 Ok(Some(*v as i64))
221 } else {
222 Ok(None)
223 }
224}
225
226pub fn decode_neutral_current(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
228 if let tlv::TlvItemValue::Int(v) = inp {
229 Ok(Some(*v as u8))
230 } else {
231 Ok(None)
232 }
233}
234
235
236pub fn decode_attribute_json(cluster_id: u32, attribute_id: u32, tlv_value: &crate::tlv::TlvItemValue) -> String {
248 if cluster_id != 0x0090 {
250 return format!("{{\"error\": \"Invalid cluster ID. Expected 0x0090, got {}\"}}", cluster_id);
251 }
252
253 match attribute_id {
254 0x0000 => {
255 match decode_power_mode(tlv_value) {
256 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
257 Err(e) => format!("{{\"error\": \"{}\"}}", e),
258 }
259 }
260 0x0001 => {
261 match decode_number_of_measurement_types(tlv_value) {
262 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
263 Err(e) => format!("{{\"error\": \"{}\"}}", e),
264 }
265 }
266 0x0002 => {
267 match decode_accuracy(tlv_value) {
268 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
269 Err(e) => format!("{{\"error\": \"{}\"}}", e),
270 }
271 }
272 0x0003 => {
273 match decode_ranges(tlv_value) {
274 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
275 Err(e) => format!("{{\"error\": \"{}\"}}", e),
276 }
277 }
278 0x0004 => {
279 match decode_voltage(tlv_value) {
280 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
281 Err(e) => format!("{{\"error\": \"{}\"}}", e),
282 }
283 }
284 0x0005 => {
285 match decode_active_current(tlv_value) {
286 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
287 Err(e) => format!("{{\"error\": \"{}\"}}", e),
288 }
289 }
290 0x0006 => {
291 match decode_reactive_current(tlv_value) {
292 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
293 Err(e) => format!("{{\"error\": \"{}\"}}", e),
294 }
295 }
296 0x0007 => {
297 match decode_apparent_current(tlv_value) {
298 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
299 Err(e) => format!("{{\"error\": \"{}\"}}", e),
300 }
301 }
302 0x0008 => {
303 match decode_active_power(tlv_value) {
304 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
305 Err(e) => format!("{{\"error\": \"{}\"}}", e),
306 }
307 }
308 0x0009 => {
309 match decode_reactive_power(tlv_value) {
310 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
311 Err(e) => format!("{{\"error\": \"{}\"}}", e),
312 }
313 }
314 0x000A => {
315 match decode_apparent_power(tlv_value) {
316 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
317 Err(e) => format!("{{\"error\": \"{}\"}}", e),
318 }
319 }
320 0x000B => {
321 match decode_rms_voltage(tlv_value) {
322 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
323 Err(e) => format!("{{\"error\": \"{}\"}}", e),
324 }
325 }
326 0x000C => {
327 match decode_rms_current(tlv_value) {
328 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
329 Err(e) => format!("{{\"error\": \"{}\"}}", e),
330 }
331 }
332 0x000D => {
333 match decode_rms_power(tlv_value) {
334 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
335 Err(e) => format!("{{\"error\": \"{}\"}}", e),
336 }
337 }
338 0x000E => {
339 match decode_frequency(tlv_value) {
340 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
341 Err(e) => format!("{{\"error\": \"{}\"}}", e),
342 }
343 }
344 0x000F => {
345 match decode_harmonic_currents(tlv_value) {
346 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
347 Err(e) => format!("{{\"error\": \"{}\"}}", e),
348 }
349 }
350 0x0010 => {
351 match decode_harmonic_phases(tlv_value) {
352 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
353 Err(e) => format!("{{\"error\": \"{}\"}}", e),
354 }
355 }
356 0x0011 => {
357 match decode_power_factor(tlv_value) {
358 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
359 Err(e) => format!("{{\"error\": \"{}\"}}", e),
360 }
361 }
362 0x0012 => {
363 match decode_neutral_current(tlv_value) {
364 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
365 Err(e) => format!("{{\"error\": \"{}\"}}", e),
366 }
367 }
368 _ => format!("{{\"error\": \"Unknown attribute ID: {}\"}}", attribute_id),
369 }
370}
371
372pub fn get_attribute_list() -> Vec<(u32, &'static str)> {
377 vec![
378 (0x0000, "PowerMode"),
379 (0x0001, "NumberOfMeasurementTypes"),
380 (0x0002, "Accuracy"),
381 (0x0003, "Ranges"),
382 (0x0004, "Voltage"),
383 (0x0005, "ActiveCurrent"),
384 (0x0006, "ReactiveCurrent"),
385 (0x0007, "ApparentCurrent"),
386 (0x0008, "ActivePower"),
387 (0x0009, "ReactivePower"),
388 (0x000A, "ApparentPower"),
389 (0x000B, "RMSVoltage"),
390 (0x000C, "RMSCurrent"),
391 (0x000D, "RMSPower"),
392 (0x000E, "Frequency"),
393 (0x000F, "HarmonicCurrents"),
394 (0x0010, "HarmonicPhases"),
395 (0x0011, "PowerFactor"),
396 (0x0012, "NeutralCurrent"),
397 ]
398}
399