some cleanup

This commit is contained in:
Alex Janka 2024-01-22 10:38:34 +11:00
parent 7bbd0ed6f7
commit fc3f7103d1
7 changed files with 39 additions and 32 deletions

7
Cargo.lock generated
View file

@ -1072,6 +1072,12 @@ dependencies = [
"unicode-normalization",
]
[[package]]
name = "if_chain"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed"
[[package]]
name = "include_dir"
version = "0.7.3"
@ -2573,6 +2579,7 @@ dependencies = [
"chrono",
"clap 4.4.11",
"env_logger 0.10.1",
"if_chain",
"include_dir",
"libmodbus-rs",
"log 0.4.20",

View file

@ -31,3 +31,4 @@ env_logger = "0.10"
log = "0.4"
serialport = "4.3"
libmodbus-rs = "0.8.3"
if_chain = "1.0.2"

2
control-loop.txt Normal file
View file

@ -0,0 +1,2 @@
targeting pl's target voltage
if load current > 0 or duty cycle < ~0.8 then there is power to spare

View file

@ -39,7 +39,6 @@ enum Commands {
#[tokio::main]
async fn main() {
let args = Args::parse();
env_logger::builder()
.format_module_path(false)
.format_timestamp(
@ -51,10 +50,9 @@ async fn main() {
)
.init();
let args = Args::parse();
let auth_path = args.config_dir.join("auth");
let _ = CONFIG_PATH.set(args.config_dir.join("config.json"));
let _recorder = metrics_prometheus::install();
match args.command {
@ -110,6 +108,8 @@ async fn main() {
}
};
// spawn a loop for each additional charge controller to log
// failed connections will print an error but the program will continue
let _additional_controllers: Vec<_> = access_config()
.additional_charge_controllers
.clone()
@ -165,7 +165,7 @@ async fn main() {
tcrc_requests,
});
// spawn the api loop
// spawn the api / charge rate control loop
tokio::task::spawn(async move {
let mut normal_data_update_interval =
tokio::time::interval(std::time::Duration::from_secs(
@ -208,6 +208,7 @@ async fn main() {
.charge_state
.is_some_and(|v| v.charging_state == ChargingState::Disconnected)
{
// reenable control when charger is disconnected
was_connected = false;
tesla_charge_rate_controller.process_request(
tesla_charge_rate::TcrcRequest::EnableAutomaticControl,

View file

@ -1,3 +1,4 @@
use if_chain::if_chain;
use include_dir::{include_dir, Dir};
use rocket::{
http::{ContentType, Status},
@ -64,8 +65,10 @@ struct RawHtml {
impl<'r> Responder<'r, 'static> for RawHtml {
fn respond_to(self, request: &'r Request<'_>) -> rocket::response::Result<'static> {
let mut response = self.data.respond_to(request)?;
if let Some(ext) = self.name.extension() {
if let Some(ct) = ContentType::from_extension(&ext.to_string_lossy()) {
if_chain! {
if let Some(ext) = self.name.extension();
if let Some(ct) = ContentType::from_extension(&ext.to_string_lossy());
then {
response.set_header(ct);
}
}

View file

@ -1,5 +1,6 @@
use std::sync::{Arc, RwLock};
use if_chain::if_chain;
use metrics::{describe_gauge, gauge, Gauge};
use serde::{Deserialize, Serialize};
@ -49,25 +50,21 @@ impl TeslaChargeRateController {
}
pub fn control_charge_rate(&mut self) -> Option<InterfaceRequest> {
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 {
// 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);
}
if_chain! {
if let Some(pl_state) = self.pl_state.as_ref().and_then(|v| v.read().ok());
if let Some(charge_state) = self.car_state.read().ok().and_then(|v| v.charge_state);
then {
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);
}
}
}
@ -105,6 +102,8 @@ fn get_control(pl_state: &PlState, charge_state: &ChargeState) -> Option<Interfa
return valid_rate(rate, charge_state.charge_amps).map(InterfaceRequest::SetChargeRate);
}
// if max/min charge rate has changed, then the current charge rate might no longer be valid
// and we should move up/down to keep it in the new bounds
valid_rate(charge_state.charge_amps, charge_state.charge_amps)
.map(InterfaceRequest::SetChargeRate)
}

View file

@ -84,13 +84,6 @@ pub struct ChargeState {
pub charge_limit_soc: i64,
}
impl ChargeState {
#[allow(unused)]
pub fn range_km(&self) -> f64 {
self.battery_range * 1.60934
}
}
impl From<teslatte::vehicles::ChargeState> for ChargeState {
fn from(value: teslatte::vehicles::ChargeState) -> Self {
ChargeState {
@ -157,6 +150,7 @@ pub struct Coords {
pub longitude: f64,
}
// ~111 metres
const COORD_PRECISION: f64 = 0.001;
impl Coords {