ccs: tristar: get scaling on launch

this should also make Tristar::new return an error if the port exists
but doesn't have a modbus device there - previously this would fail
later when it times out reading registers
This commit is contained in:
Alex Janka 2025-01-09 11:32:02 +11:00
parent 20a7ad6ddd
commit c28802c3d8

View file

@ -52,7 +52,7 @@ pub struct Tristar {
modbus: tokio_modbus::client::Context,
charge_state_gauges: ChargeStateGauges,
consecutive_errors: usize,
scaling: Option<Scaling>,
scaling: Scaling,
}
#[derive(Debug, Clone, Copy)]
@ -261,7 +261,7 @@ impl Tristar {
) -> eyre::Result<Self> {
let slave = tokio_modbus::Slave(DEVICE_ID);
let modbus = match transport {
let mut modbus = match transport {
crate::config::Transport::Serial { port, baud_rate } => {
let modbus_serial = tokio_serial::SerialStream::open(
&tokio_serial::new(port, *baud_rate).timeout(std::time::Duration::from_secs(3)),
@ -274,6 +274,13 @@ impl Tristar {
}
};
let scaling = {
let scaling_data = modbus
.read_holding_registers(0x0000, RAM_DATA_SIZE + 1)
.await??;
Scaling::from(&scaling_data)
};
let charge_state_gauges = ChargeStateGauges::new(friendly_name);
Ok(Self {
@ -281,14 +288,14 @@ impl Tristar {
modbus,
charge_state_gauges,
consecutive_errors: 0,
scaling: None,
scaling,
})
}
pub async fn refresh(&mut self) -> eyre::Result<crate::controller::CommonData> {
let new_state = self.get_data().await?;
self.scaling = Some(new_state.scaling);
self.scaling = new_state.scaling;
self.consecutive_errors = 0;
BATTERY_VOLTAGE
.with_label_values(&[&self.friendly_name])
@ -343,7 +350,7 @@ impl Tristar {
}
pub async fn set_target_voltage(&mut self, target_voltage: f64) -> eyre::Result<()> {
let scaled_voltage: u16 = self.scale_voltage(target_voltage)?;
let scaled_voltage: u16 = self.scale_voltage(target_voltage);
self.modbus
.write_single_register(TristarRamAddress::VbRefSlave as u16, scaled_voltage)
.await??;
@ -356,11 +363,8 @@ impl Tristar {
Ok(())
}
fn scale_voltage(&self, voltage: f64) -> eyre::Result<u16> {
let Some(scaling) = &self.scaling else {
return Err(eyre::eyre!("no scaling data present"));
};
Ok(scaling.inverse_voltage(voltage))
fn scale_voltage(&self, voltage: f64) -> u16 {
self.scaling.inverse_voltage(voltage)
}
async fn get_data(&mut self) -> eyre::Result<TristarState> {