victron_gx/
battery.rs

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    // TODO: add rest of the fields
22    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,     //TODO
53            avg_temperature: None, // TODO
54            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}