1use tracing::debug;
2
3use crate::traits::HandleFrame;
4
5#[derive(Debug, Clone, Default)]
6pub struct BatteryDC {
7 pub dc_power: Option<f64>,
8 pub dc_current: Option<f64>,
9 pub dc_voltage: Option<f64>,
10
11 pub cell_min_voltage: Option<f64>,
12 pub cell_max_voltage: Option<f64>,
13
14 pub temperature: Option<f64>,
15 pub soc: Option<f64>,
16 pub soh: Option<f64>,
17}
18
19#[derive(Debug, Clone, Default)]
20pub struct BatterySummary {
21 pub avg_voltage: Option<f64>,
23 pub avg_temperature: Option<f64>,
24 pub total_power: Option<f64>,
25}
26
27impl HandleFrame for BatteryDC {
28 fn handle_frame(&mut self, parts: &[&str], value: Option<f64>) {
29 match parts {
30 ["Dc", "0", "Temperature"] => self.temperature = value,
31 ["Dc", "0", "Power"] => self.dc_power = value,
32 ["Dc", "0", "Current"] => self.dc_current = value,
33 ["Dc", "0", "Voltage"] => self.dc_voltage = value,
34
35 ["System", "MinCellVoltage"] => self.cell_min_voltage = value,
36 ["System", "MaxCellVoltage"] => self.cell_max_voltage = value,
37 ["Soc"] => self.soc = value,
38 ["Soh"] => self.soh = value,
39 _ => {
40 debug!("Unhandled BatteryDC parts: {:?}, value: {:?}", parts, value);
41 }
42 }
43 }
44}
45
46impl BatterySummary {
47 pub fn from_batteries<'a, I>(batteries: I) -> Self
48 where
49 I: Iterator<Item = &'a BatteryDC> + Clone,
50 {
51 Self {
52 avg_voltage: None, avg_temperature: None, total_power: {
55 let values: Vec<f64> = batteries.clone().filter_map(|b| b.dc_power).collect();
56 if values.is_empty() {
57 None
58 } else {
59 Some(values.into_iter().sum())
60 }
61 },
62 }
63 }
64}