ccs: tristar: periodically fetch settings
This commit is contained in:
parent
a908490bb0
commit
4905a89b33
2 changed files with 36 additions and 14 deletions
charge-controller-supervisor/src
|
@ -61,7 +61,7 @@ impl Controller {
|
||||||
Self,
|
Self,
|
||||||
Option<tokio::sync::mpsc::UnboundedSender<VoltageCommand>>,
|
Option<tokio::sync::mpsc::UnboundedSender<VoltageCommand>>,
|
||||||
)> {
|
)> {
|
||||||
let mut inner = match config.variant {
|
let inner = match config.variant {
|
||||||
crate::config::ChargeControllerVariant::Tristar => ControllerInner::Tristar(
|
crate::config::ChargeControllerVariant::Tristar => ControllerInner::Tristar(
|
||||||
tristar::Tristar::new(&config.name, &config.transport).await?,
|
tristar::Tristar::new(&config.name, &config.transport).await?,
|
||||||
),
|
),
|
||||||
|
@ -79,15 +79,6 @@ impl Controller {
|
||||||
|
|
||||||
let data = std::sync::Arc::new(ControllerData::new());
|
let data = std::sync::Arc::new(ControllerData::new());
|
||||||
|
|
||||||
if let ControllerInner::Tristar(t) = &mut inner {
|
|
||||||
match t.read_settings().await {
|
|
||||||
Ok(v) => {
|
|
||||||
*data.write_settings().await = Some(ControllerSettings::Tristar(v));
|
|
||||||
}
|
|
||||||
Err(e) => log::error!("couldn't read config from tristar {}: {e:?}", config.name),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let (voltage_tx, voltage_rx) = if config.follow_primary {
|
let (voltage_tx, voltage_rx) = if config.follow_primary {
|
||||||
let (a, b) = tokio::sync::mpsc::unbounded_channel();
|
let (a, b) = tokio::sync::mpsc::unbounded_channel();
|
||||||
(Some(a), Some(b))
|
(Some(a), Some(b))
|
||||||
|
@ -113,7 +104,7 @@ impl Controller {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn refresh(&mut self) -> eyre::Result<()> {
|
pub async fn refresh(&mut self) -> eyre::Result<()> {
|
||||||
let data = self.inner.refresh().await?;
|
let (data, settings) = self.inner.refresh().await?;
|
||||||
|
|
||||||
if let Some(tx) = self.voltage_tx.as_mut() {
|
if let Some(tx) = self.voltage_tx.as_mut() {
|
||||||
if crate::config::access_config()
|
if crate::config::access_config()
|
||||||
|
@ -132,6 +123,9 @@ impl Controller {
|
||||||
}
|
}
|
||||||
|
|
||||||
*self.data.write_state().await = Some(data);
|
*self.data.write_state().await = Some(data);
|
||||||
|
if let Some(settings) = settings {
|
||||||
|
*self.data.write_settings().await = Some(settings);
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -186,17 +180,31 @@ pub enum ControllerInner {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ControllerInner {
|
impl ControllerInner {
|
||||||
pub async fn refresh(&mut self) -> eyre::Result<ControllerState> {
|
pub async fn refresh(&mut self) -> eyre::Result<(ControllerState, Option<ControllerSettings>)> {
|
||||||
match self {
|
match self {
|
||||||
ControllerInner::Pl(pli) => {
|
ControllerInner::Pl(pli) => {
|
||||||
let pl_data = pli.refresh().await?;
|
let pl_data = pli.refresh().await?;
|
||||||
|
|
||||||
Ok(ControllerState::Pl(pl_data))
|
Ok((ControllerState::Pl(pl_data), None))
|
||||||
}
|
}
|
||||||
ControllerInner::Tristar(tristar) => {
|
ControllerInner::Tristar(tristar) => {
|
||||||
|
let settings = if tristar.needs_new_settings() {
|
||||||
|
match tristar.read_settings().await {
|
||||||
|
Ok(v) => Some(ControllerSettings::Tristar(v)),
|
||||||
|
Err(e) => {
|
||||||
|
log::error!(
|
||||||
|
"couldn't read config from tristar {}: {e:?}",
|
||||||
|
tristar.name()
|
||||||
|
);
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
let tristar_data = tristar.refresh().await?;
|
let tristar_data = tristar.refresh().await?;
|
||||||
|
|
||||||
Ok(ControllerState::Tristar(tristar_data))
|
Ok((ControllerState::Tristar(tristar_data), settings))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,7 @@ pub struct Tristar {
|
||||||
charge_state_gauges: ChargeStateGauges,
|
charge_state_gauges: ChargeStateGauges,
|
||||||
consecutive_errors: usize,
|
consecutive_errors: usize,
|
||||||
scaling: Scaling,
|
scaling: Scaling,
|
||||||
|
settings_last_read: Option<std::time::Instant>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ModbusTimeout(tokio_modbus::client::Context);
|
struct ModbusTimeout(tokio_modbus::client::Context);
|
||||||
|
@ -594,6 +595,7 @@ impl Tristar {
|
||||||
charge_state_gauges,
|
charge_state_gauges,
|
||||||
consecutive_errors: 0,
|
consecutive_errors: 0,
|
||||||
scaling,
|
scaling,
|
||||||
|
settings_last_read: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -674,9 +676,17 @@ impl Tristar {
|
||||||
|
|
||||||
let charge = ChargeSettings::from_buf(&charge_data, &self.scaling)?;
|
let charge = ChargeSettings::from_buf(&charge_data, &self.scaling)?;
|
||||||
|
|
||||||
|
self.settings_last_read = Some(std::time::Instant::now());
|
||||||
|
|
||||||
Ok(TristarSettings { network, charge })
|
Ok(TristarSettings { network, charge })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn needs_new_settings(&self) -> bool {
|
||||||
|
self.settings_last_read.is_none_or(|t| {
|
||||||
|
std::time::Instant::now().duration_since(t) >= std::time::Duration::from_secs(60 * 60)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn set_target_voltage(&mut self, target_voltage: f64) -> eyre::Result<()> {
|
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
|
self.modbus
|
||||||
|
@ -691,6 +701,10 @@ impl Tristar {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn name(&self) -> &str {
|
||||||
|
&self.friendly_name
|
||||||
|
}
|
||||||
|
|
||||||
fn scale_voltage(&self, voltage: f64) -> u16 {
|
fn scale_voltage(&self, voltage: f64) -> u16 {
|
||||||
self.scaling.inverse_voltage(voltage)
|
self.scaling.inverse_voltage(voltage)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue