fix some baaad state management (LOL)
This commit is contained in:
parent
42f249f0f4
commit
5cdda39451
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -2256,7 +2256,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tesla-charge-controller"
|
||||
version = "1.0.0"
|
||||
version = "1.0.1"
|
||||
dependencies = [
|
||||
"async-channel",
|
||||
"chrono",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "tesla-charge-controller"
|
||||
version = "1.0.0"
|
||||
version = "1.0.1"
|
||||
edition = "2021"
|
||||
license = "MITNFA"
|
||||
description = "Controls Tesla charge rate based on solar charge data"
|
||||
|
|
16
src/main.rs
16
src/main.rs
|
@ -10,6 +10,7 @@ use config::{access_config, CONFIG_PATH};
|
|||
use errors::PrintErrors;
|
||||
use std::path::PathBuf;
|
||||
use tesla_charge_rate::TeslaChargeRateController;
|
||||
use teslatte::vehicles::ChargingState;
|
||||
|
||||
use crate::config::Config;
|
||||
|
||||
|
@ -134,6 +135,8 @@ async fn main() {
|
|||
let mut charge_rate_update_interval = tokio::time::interval(
|
||||
std::time::Duration::from_secs(config.charge_rate_update_interval_seconds),
|
||||
);
|
||||
let mut was_connected = false;
|
||||
|
||||
loop {
|
||||
// await either the next interval OR a message from the other thread
|
||||
tokio::select! {
|
||||
|
@ -149,9 +152,22 @@ async fn main() {
|
|||
},
|
||||
_ = charge_rate_update_interval.tick() => {
|
||||
if interface.state.read().unwrap().is_charging_at_home() {
|
||||
was_connected = true;
|
||||
if let Some(request) = tesla_charge_rate_controller.control_charge_rate() {
|
||||
interface.process_request(request).await;
|
||||
}
|
||||
} else if was_connected
|
||||
&& interface
|
||||
.state
|
||||
.read()
|
||||
.unwrap()
|
||||
.charge_state
|
||||
.is_some_and(|v| v.charging_state == ChargingState::Disconnected)
|
||||
{
|
||||
was_connected = false;
|
||||
tesla_charge_rate_controller.process_request(
|
||||
tesla_charge_rate::TcrcRequest::EnableAutomaticControl,
|
||||
);
|
||||
}
|
||||
},
|
||||
api_message = api_receiver.recv() => match api_message {
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
use std::{
|
||||
sync::{Arc, RwLock},
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
use std::sync::{Arc, RwLock};
|
||||
|
||||
use metrics::{describe_gauge, gauge, Gauge};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use teslatte::vehicles::ChargingState;
|
||||
|
||||
use crate::{
|
||||
api_interface::InterfaceRequest,
|
||||
|
@ -18,7 +14,7 @@ pub struct TeslaChargeRateController {
|
|||
pub car_state: Arc<RwLock<CarState>>,
|
||||
pub pl_state: Option<Arc<RwLock<PlState>>>,
|
||||
pub tcrc_state: Arc<RwLock<TcrcState>>,
|
||||
voltage_low: Option<Instant>,
|
||||
voltage_low: u64,
|
||||
control_enable_gauge: Gauge,
|
||||
}
|
||||
|
||||
|
@ -49,7 +45,7 @@ impl TeslaChargeRateController {
|
|||
car_state,
|
||||
pl_state,
|
||||
tcrc_state: Default::default(),
|
||||
voltage_low: None,
|
||||
voltage_low: 0,
|
||||
control_enable_gauge: gauge!("tcrc_control_enable"),
|
||||
}
|
||||
}
|
||||
|
@ -58,35 +54,22 @@ impl TeslaChargeRateController {
|
|||
if let Some(pl_state) = self.pl_state.as_ref().and_then(|v| v.read().ok()) {
|
||||
if let Ok(car_state) = self.car_state.read() {
|
||||
if let Some(charge_state) = car_state.charge_state {
|
||||
// check if we're charging at home
|
||||
if car_state.is_charging_at_home() {
|
||||
// automatic control or not, check if we're below shutoff voltage
|
||||
if pl_state.battery_voltage < access_config().shutoff_voltage {
|
||||
if let Some(low_voltage_time) = self.voltage_low {
|
||||
// if we've been below shutoff for long enough, stop charging
|
||||
if Instant::now().duration_since(low_voltage_time)
|
||||
>= Duration::from_secs(
|
||||
access_config().shutoff_voltage_time_seconds,
|
||||
)
|
||||
{
|
||||
return Some(InterfaceRequest::StopCharge);
|
||||
}
|
||||
} else {
|
||||
self.voltage_low = Some(Instant::now());
|
||||
}
|
||||
} else {
|
||||
self.voltage_low = None;
|
||||
if self.tcrc_state.read().is_ok_and(|v| v.control_enable) {
|
||||
return get_control(&pl_state, &charge_state);
|
||||
}
|
||||
// we don't need to check if we're at home because we only call this when we are
|
||||
// TODO: enforce this through type system
|
||||
|
||||
// automatic control or not, check if we're below shutoff voltage
|
||||
if pl_state.battery_voltage < access_config().shutoff_voltage {
|
||||
self.voltage_low += 1;
|
||||
if (self.voltage_low * access_config().charge_rate_update_interval_seconds)
|
||||
>= access_config().shutoff_voltage_time_seconds
|
||||
{
|
||||
return Some(InterfaceRequest::StopCharge);
|
||||
}
|
||||
} else {
|
||||
self.voltage_low = 0;
|
||||
if self.tcrc_state.read().is_ok_and(|v| v.control_enable) {
|
||||
return get_control(&pl_state, &charge_state);
|
||||
}
|
||||
} else if charge_state.charging_state == ChargingState::Disconnected {
|
||||
// only disable automatic control until the next time we're unplugged
|
||||
self.tcrc_state
|
||||
.write()
|
||||
.expect("failed to write to tcrc state")
|
||||
.control_enable = true;
|
||||
self.control_enable_gauge.set(1.);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue