update & fix clippy lints

This commit is contained in:
Alex Janka 2024-12-23 15:51:09 +11:00
parent 88f23637d9
commit 458d1149e1
8 changed files with 78 additions and 69 deletions

View file

@ -38,3 +38,11 @@ reqwest = "0.12.4"
# [patch."https://git.alexjanka.com/alex/tesla-common"] # [patch."https://git.alexjanka.com/alex/tesla-common"]
# tesla-common = { path = "../tesla-common" } # tesla-common = { path = "../tesla-common" }
[lints.clippy]
pedantic = "warn"
struct-excessive-bools = { level = "allow", priority = 1 }
too-many-lines = { level = "allow", priority = 1 }
default-trait-access = { level = "allow", priority = 1 }
cast-precision-loss = { level = "allow", priority = 1 }
cast-possible-truncation = { level = "allow", priority = 1 }

View file

@ -19,7 +19,7 @@ use teslatte::{
}; };
use crate::{ use crate::{
errors::*, errors::{AuthLoadError, PrintErrors},
types::{CarState, FromDriveState}, types::{CarState, FromDriveState},
}; };
@ -290,11 +290,10 @@ impl TeslaInterface {
.products() .products()
.await? .await?
.into_iter() .into_iter()
.filter_map(|v| match v { .find_map(|v| match v {
teslatte::products::Product::Vehicle(vehicle) => Some(vehicle), teslatte::products::Product::Vehicle(vehicle) => Some(vehicle),
_ => None, _ => None,
}) })
.next()
.ok_or(AuthLoadError::NoVehicles)?; .ok_or(AuthLoadError::NoVehicles)?;
let interface = Self { let interface = Self {
@ -419,18 +418,18 @@ impl TeslaInterface {
} }
Err(e) => { Err(e) => {
TESLA_ONLINE.set(0); TESLA_ONLINE.set(0);
match e { if let teslatte::error::TeslatteError::DecodeJsonError {
teslatte::error::TeslatteError::DecodeJsonError { source,
source, request: _,
request: _, body,
body, } = e
} => { {
if body.contains("vehicle is offline or asleep") { if body.contains("vehicle is offline or asleep") {
return; return;
}
log::error!("Error {source} getting state: {body}")
} }
_ => log::error!("Teslatte error: {e:?}"), log::error!("Error {source} getting state: {body}");
} else {
log::error!("Teslatte error: {e:?}");
} }
} }
} }
@ -485,7 +484,7 @@ impl TeslaInterface {
}) })
.await? .await?
.vehicle_state .vehicle_state
.map(|v| v.into()); .map(std::convert::Into::into);
let (location_data, _) = self let (location_data, _) = self
.api .api
@ -526,11 +525,7 @@ impl TeslaInterface {
} }
fn bi(value: bool) -> i64 { fn bi(value: bool) -> i64 {
if value { i64::from(value)
1
} else {
0
}
} }
fn obi(value: Option<bool>) -> i64 { fn obi(value: Option<bool>) -> i64 {

View file

@ -9,7 +9,10 @@ use serde::{Deserialize, Serialize};
use serialport::SerialPort; use serialport::SerialPort;
use crate::{ use crate::{
charge_controllers::gauges::*, charge_controllers::gauges::{
BATTERY_TEMP, BATTERY_VOLTAGE, CHARGE_STATE, INPUT_CURRENT, PL_DUTY_CYCLE, PL_LOAD_CURRENT,
TARGET_VOLTAGE,
},
errors::{PliError, PrintErrors}, errors::{PliError, PrintErrors},
}; };
@ -67,7 +70,7 @@ impl Default for RegulatorState {
} }
} }
fn set_regulator_gauges(state: &RegulatorState, label: &str) { fn set_regulator_gauges(state: RegulatorState, label: &str) {
let boost = CHARGE_STATE.with_label_values(&[label, "boost"]); let boost = CHARGE_STATE.with_label_values(&[label, "boost"]);
let equalise = CHARGE_STATE.with_label_values(&[label, "equalise"]); let equalise = CHARGE_STATE.with_label_values(&[label, "equalise"]);
let absorption = CHARGE_STATE.with_label_values(&[label, "absorption"]); let absorption = CHARGE_STATE.with_label_values(&[label, "absorption"]);
@ -147,7 +150,7 @@ impl Pli {
.with_label_values(&[&self.port_name]) .with_label_values(&[&self.port_name])
.set(new_state.battery_temp); .set(new_state.battery_temp);
set_regulator_gauges(&new_state.regulator_state, &self.port_name); set_regulator_gauges(new_state.regulator_state, &self.port_name);
*self.state.write().expect("PLI state handler panicked!!") = new_state; *self.state.write().expect("PLI state handler panicked!!") = new_state;
} }
@ -204,12 +207,12 @@ impl Pli {
fn read_state(&mut self) -> Result<PlState, PliError> { fn read_state(&mut self) -> Result<PlState, PliError> {
Ok(PlState { Ok(PlState {
battery_voltage: (self.read_ram(PlRamAddress::Batv)? as f64) * (4. / 10.), battery_voltage: f64::from(self.read_ram(PlRamAddress::Batv)?) * (4. / 10.),
target_voltage: (self.read_ram(PlRamAddress::Vreg)? as f64) * (4. / 10.), target_voltage: f64::from(self.read_ram(PlRamAddress::Vreg)?) * (4. / 10.),
duty_cycle: (self.read_ram(PlRamAddress::Dutycyc)? as f64) / 255., duty_cycle: f64::from(self.read_ram(PlRamAddress::Dutycyc)?) / 255.,
internal_charge_current: (self.read_ram(PlRamAddress::Cint)? as f64) * (4. / 10.), internal_charge_current: f64::from(self.read_ram(PlRamAddress::Cint)?) * (4. / 10.),
internal_load_current: (self.read_ram(PlRamAddress::Lint)? as f64) * (4. / 10.), internal_load_current: f64::from(self.read_ram(PlRamAddress::Lint)?) * (4. / 10.),
battery_temp: self.read_ram(PlRamAddress::Battemp)? as f64, battery_temp: f64::from(self.read_ram(PlRamAddress::Battemp)?),
regulator_state: self.read_ram(PlRamAddress::Rstate)?.into(), regulator_state: self.read_ram(PlRamAddress::Rstate)?.into(),
}) })
} }
@ -225,9 +228,8 @@ impl Pli {
while let Ok(num) = self.port.bytes_to_read() { while let Ok(num) = self.port.bytes_to_read() {
if num == 0 { if num == 0 {
return Ok(()); return Ok(());
} else {
let _ = self.port.read(&mut [0; 8]);
} }
let _ = self.port.read(&mut [0; 8]);
} }
Ok(()) Ok(())
} }

View file

@ -2,7 +2,12 @@ use prometheus::core::{AtomicI64, GenericGauge};
use tokio_modbus::client::Reader; use tokio_modbus::client::Reader;
use crate::{ use crate::{
charge_controllers::gauges::*, charge_controllers::gauges::{
BATTERY_TEMP, BATTERY_VOLTAGE, CHARGE_STATE, INPUT_CURRENT, TARGET_VOLTAGE,
TRISTAR_CHARGE_CURRENT, TRISTAR_INPUT_VOLTAGE, TRISTAR_MAX_ARRAY_POWER,
TRISTAR_MAX_ARRAY_VOLTAGE, TRISTAR_OPEN_CIRCUIT_VOLTAGE, TRISTAR_POWER_IN,
TRISTAR_POWER_OUT,
},
errors::{PrintErrors, TristarError}, errors::{PrintErrors, TristarError},
}; };
@ -10,7 +15,7 @@ const DEVICE_ID: u8 = 0x01;
const RAM_DATA_SIZE: u16 = 0x005B; const RAM_DATA_SIZE: u16 = 0x005B;
const RAM_ARRAY_SIZE: usize = RAM_DATA_SIZE as usize + 1; const RAM_ARRAY_SIZE: usize = RAM_DATA_SIZE as usize + 1;
#[derive(Debug, Clone)] #[derive(Debug, Clone, Copy)]
pub struct Scaling { pub struct Scaling {
pub v_scale: f64, pub v_scale: f64,
pub i_scale: f64, pub i_scale: f64,
@ -23,21 +28,21 @@ impl Scaling {
fn from_internal(v_pu_hi: u16, v_pu_lo: u16, i_pu_hi: u16, i_pu_lo: u16) -> Self { fn from_internal(v_pu_hi: u16, v_pu_lo: u16, i_pu_hi: u16, i_pu_lo: u16) -> Self {
Self { Self {
v_scale: v_pu_hi as f64 + (v_pu_lo as f64 / f64::powf(2., 16.)), v_scale: f64::from(v_pu_hi) + (f64::from(v_pu_lo) / f64::powf(2., 16.)),
i_scale: i_pu_hi as f64 + (i_pu_lo as f64 / f64::powf(2., 16.)), i_scale: f64::from(i_pu_hi) + (f64::from(i_pu_lo) / f64::powf(2., 16.)),
} }
} }
fn get_voltage(&self, data: u16) -> f64 { fn get_voltage(&self, data: u16) -> f64 {
data as f64 * self.v_scale * f64::powf(2., -15.) f64::from(data) * self.v_scale * f64::powf(2., -15.)
} }
fn get_current(&self, data: u16) -> f64 { fn get_current(&self, data: u16) -> f64 {
data as f64 * self.i_scale * f64::powf(2., -15.) f64::from(data) * self.i_scale * f64::powf(2., -15.)
} }
fn get_power(&self, data: u16) -> f64 { fn get_power(&self, data: u16) -> f64 {
data as f64 * self.v_scale * self.i_scale * f64::powf(2., -17.) f64::from(data) * self.v_scale * self.i_scale * f64::powf(2., -17.)
} }
} }

View file

@ -90,13 +90,13 @@ impl<'a> core::ops::Deref for ConfigHandle<'a> {
} }
} }
impl<'a> DerefMut for ConfigHandle<'a> { impl DerefMut for ConfigHandle<'_> {
fn deref_mut(&mut self) -> &mut Self::Target { fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.handle &mut self.handle
} }
} }
impl<'a> Drop for ConfigHandle<'a> { impl Drop for ConfigHandle<'_> {
fn drop(&mut self) { fn drop(&mut self) {
let _ = self.save().some_or_print_with("saving config"); let _ = self.save().some_or_print_with("saving config");
} }

View file

@ -193,7 +193,7 @@ async fn main() {
tokio::select! { tokio::select! {
_ = normal_data_update_interval.tick() => { _ = normal_data_update_interval.tick() => {
if !interface.state.read().unwrap().is_charging_at_home() { if !interface.state.read().unwrap().is_charging_at_home() {
interface.refresh().await interface.refresh().await;
} }
}, },
_ = charge_rate_update_interval.tick() => { _ = charge_rate_update_interval.tick() => {
@ -202,7 +202,7 @@ async fn main() {
if let Some(request) = tesla_charge_rate_controller.control_charge_rate() { if let Some(request) = tesla_charge_rate_controller.control_charge_rate() {
interface.process_request(request).await; interface.process_request(request).await;
} }
interface.refresh().await interface.refresh().await;
} else if was_connected } else if was_connected
&& interface && interface
.state .state

View file

@ -131,9 +131,7 @@ lazy_static::lazy_static! {
mod authentication; mod authentication;
#[get("/reauthenticate")] #[get("/reauthenticate")]
async fn reauthenticate( fn reauthenticate(state: &State<ServerState>) -> Result<rocket::response::Redirect, ServerError> {
state: &State<ServerState>,
) -> Result<rocket::response::Redirect, ServerError> {
let state_random: String = rand::thread_rng() let state_random: String = rand::thread_rng()
.sample_iter(&rand::distributions::Alphanumeric) .sample_iter(&rand::distributions::Alphanumeric)
.take(16) .take(16)
@ -182,7 +180,7 @@ async fn auth(
} }
#[get("/home")] #[get("/home")]
async fn home(state: &State<ServerState>) -> Result<Json<bool>, ServerError> { fn home(state: &State<ServerState>) -> Result<Json<bool>, ServerError> {
let location_data = &state let location_data = &state
.car_state .car_state
.read()? .read()?
@ -192,7 +190,7 @@ async fn home(state: &State<ServerState>) -> Result<Json<bool>, ServerError> {
} }
#[get("/car-state")] #[get("/car-state")]
async fn car_state(state: &State<ServerState>) -> Result<Json<CarState>, ServerError> { fn car_state(state: &State<ServerState>) -> Result<Json<CarState>, ServerError> {
Ok(Json(*state.car_state.read()?)) Ok(Json(*state.car_state.read()?))
} }
@ -205,7 +203,7 @@ struct ControlState {
} }
#[get("/control-state")] #[get("/control-state")]
async fn control_state(state: &State<ServerState>) -> Result<Json<ControlState>, ServerError> { fn control_state(state: &State<ServerState>) -> Result<Json<ControlState>, ServerError> {
let control_enable = state.tcrc_state.read()?.control_enable; let control_enable = state.tcrc_state.read()?.control_enable;
let is_charging_at_home = state.car_state.read()?.is_charging_at_home(); let is_charging_at_home = state.car_state.read()?.is_charging_at_home();
let config = access_config(); let config = access_config();
@ -221,13 +219,13 @@ async fn control_state(state: &State<ServerState>) -> Result<Json<ControlState>,
} }
#[post("/flash")] #[post("/flash")]
async fn flash(state: &State<ServerState>, remote_addr: std::net::IpAddr) { fn flash(state: &State<ServerState>, remote_addr: std::net::IpAddr) {
log::warn!("flash requested: {remote_addr:?}"); log::warn!("flash requested: {remote_addr:?}");
let _ = state.api_requests.send(InterfaceRequest::FlashLights); let _ = state.api_requests.send(InterfaceRequest::FlashLights);
} }
#[post("/disable-control")] #[post("/disable-control")]
async fn disable_control(state: &State<ServerState>, remote_addr: std::net::IpAddr) { fn disable_control(state: &State<ServerState>, remote_addr: std::net::IpAddr) {
log::warn!("disabling control: {remote_addr:?}"); log::warn!("disabling control: {remote_addr:?}");
match state.tcrc_state.write() { match state.tcrc_state.write() {
Ok(mut handle) => handle.set_control_enable(false), Ok(mut handle) => handle.set_control_enable(false),
@ -236,7 +234,7 @@ async fn disable_control(state: &State<ServerState>, remote_addr: std::net::IpAd
} }
#[post("/enable-control")] #[post("/enable-control")]
async fn enable_control(state: &State<ServerState>, remote_addr: std::net::IpAddr) { fn enable_control(state: &State<ServerState>, remote_addr: std::net::IpAddr) {
log::warn!("enabling control: {remote_addr:?}"); log::warn!("enabling control: {remote_addr:?}");
match state.tcrc_state.write() { match state.tcrc_state.write() {
Ok(mut handle) => handle.set_control_enable(true), Ok(mut handle) => handle.set_control_enable(true),
@ -245,14 +243,14 @@ async fn enable_control(state: &State<ServerState>, remote_addr: std::net::IpAdd
} }
#[post("/shutoff/voltage/<voltage>")] #[post("/shutoff/voltage/<voltage>")]
async fn set_shutoff(voltage: f64, remote_addr: std::net::IpAddr) { fn set_shutoff(voltage: f64, remote_addr: std::net::IpAddr) {
log::warn!("setting shutoff voltage: {remote_addr:?}"); log::warn!("setting shutoff voltage: {remote_addr:?}");
let voltage = voltage.clamp(40., 60.); let voltage = voltage.clamp(40., 60.);
write_to_config().shutoff_voltage = voltage; write_to_config().shutoff_voltage = voltage;
} }
#[post("/shutoff/time/<time>")] #[post("/shutoff/time/<time>")]
async fn set_shutoff_time(time: u64, remote_addr: std::net::IpAddr) { fn set_shutoff_time(time: u64, remote_addr: std::net::IpAddr) {
log::warn!("setting shutoff time: {remote_addr:?}"); log::warn!("setting shutoff time: {remote_addr:?}");
let time = time.clamp(5, 120); let time = time.clamp(5, 120);
write_to_config().shutoff_voltage_time_seconds = time; write_to_config().shutoff_voltage_time_seconds = time;
@ -265,7 +263,7 @@ struct ShutoffStatus {
} }
#[get("/shutoff/status")] #[get("/shutoff/status")]
async fn shutoff_status() -> Json<ShutoffStatus> { fn shutoff_status() -> Json<ShutoffStatus> {
let config = access_config(); let config = access_config();
Json(ShutoffStatus { Json(ShutoffStatus {
voltage: config.shutoff_voltage, voltage: config.shutoff_voltage,
@ -274,45 +272,45 @@ async fn shutoff_status() -> Json<ShutoffStatus> {
} }
#[post("/set-max/<limit>")] #[post("/set-max/<limit>")]
async fn set_max(limit: i64, remote_addr: std::net::IpAddr) { fn set_max(limit: i64, remote_addr: std::net::IpAddr) {
log::warn!("setting max: {remote_addr:?}"); log::warn!("setting max: {remote_addr:?}");
let limit = limit.clamp(access_config().min_rate, 32); let limit = limit.clamp(access_config().min_rate, 32);
write_to_config().max_rate = limit; write_to_config().max_rate = limit;
} }
#[post("/set-min/<limit>")] #[post("/set-min/<limit>")]
async fn set_min(limit: i64, remote_addr: std::net::IpAddr) { fn set_min(limit: i64, remote_addr: std::net::IpAddr) {
log::warn!("setting min: {remote_addr:?}"); log::warn!("setting min: {remote_addr:?}");
let limit = limit.clamp(0, access_config().max_rate); let limit = limit.clamp(0, access_config().max_rate);
write_to_config().min_rate = limit; write_to_config().min_rate = limit;
} }
#[post("/pid-settings/proportional/<gain>")] #[post("/pid-settings/proportional/<gain>")]
async fn set_proportional_gain(gain: f64, remote_addr: std::net::IpAddr) { fn set_proportional_gain(gain: f64, remote_addr: std::net::IpAddr) {
log::warn!("setting proportional gain: {remote_addr:?}"); log::warn!("setting proportional gain: {remote_addr:?}");
write_to_config().pid_controls.proportional_gain = gain; write_to_config().pid_controls.proportional_gain = gain;
} }
#[post("/pid-settings/derivative/<gain>")] #[post("/pid-settings/derivative/<gain>")]
async fn set_derivative_gain(gain: f64, remote_addr: std::net::IpAddr) { fn set_derivative_gain(gain: f64, remote_addr: std::net::IpAddr) {
log::warn!("setting derivative gain: {remote_addr:?}"); log::warn!("setting derivative gain: {remote_addr:?}");
write_to_config().pid_controls.derivative_gain = gain; write_to_config().pid_controls.derivative_gain = gain;
} }
#[post("/pid-settings/loop_time_seconds/<time>")] #[post("/pid-settings/loop_time_seconds/<time>")]
async fn set_pid_loop_length(time: u64, remote_addr: std::net::IpAddr) { fn set_pid_loop_length(time: u64, remote_addr: std::net::IpAddr) {
log::warn!("setting pid loop interval: {remote_addr:?}"); log::warn!("setting pid loop interval: {remote_addr:?}");
write_to_config().pid_controls.loop_time_seconds = time; write_to_config().pid_controls.loop_time_seconds = time;
} }
#[post("/pid-settings/load_divisor/<divisor>")] #[post("/pid-settings/load_divisor/<divisor>")]
async fn set_load_divisor(divisor: f64, remote_addr: std::net::IpAddr) { fn set_load_divisor(divisor: f64, remote_addr: std::net::IpAddr) {
log::warn!("setting load divisor interval: {remote_addr:?}"); log::warn!("setting load divisor interval: {remote_addr:?}");
write_to_config().pid_controls.load_divisor = divisor; write_to_config().pid_controls.load_divisor = divisor;
} }
#[get("/pid-settings/status")] #[get("/pid-settings/status")]
async fn pid_settings() -> Json<crate::config::PidControls> { fn pid_settings() -> Json<crate::config::PidControls> {
Json(access_config().pid_controls) Json(access_config().pid_controls)
} }
@ -325,25 +323,25 @@ fn metrics() -> Result<String, ServerError> {
} }
#[get("/sync-time")] #[get("/sync-time")]
async fn sync_time(state: &State<ServerState>) -> String { fn sync_time(state: &State<ServerState>) -> String {
let _ = state.pli_requests.send(PliRequest::SyncTime); let _ = state.pli_requests.send(PliRequest::SyncTime);
String::from("syncing time...") String::from("syncing time...")
} }
#[get("/read-ram/<address>")] #[get("/read-ram/<address>")]
async fn read_ram(address: u8, state: &State<ServerState>) -> String { fn read_ram(address: u8, state: &State<ServerState>) -> String {
let _ = state.pli_requests.send(PliRequest::ReadRam(address)); let _ = state.pli_requests.send(PliRequest::ReadRam(address));
format!("reading at ram address {address}") format!("reading at ram address {address}")
} }
#[get("/read-eeprom/<address>")] #[get("/read-eeprom/<address>")]
async fn read_eeprom(address: u8, state: &State<ServerState>) -> String { fn read_eeprom(address: u8, state: &State<ServerState>) -> String {
let _ = state.pli_requests.send(PliRequest::ReadEeprom(address)); let _ = state.pli_requests.send(PliRequest::ReadEeprom(address));
format!("reading at eeprom address {address}") format!("reading at eeprom address {address}")
} }
#[get("/regulator-state")] #[get("/regulator-state")]
async fn regulator_state(state: &State<ServerState>) -> Result<Json<PlState>, ServerError> { fn regulator_state(state: &State<ServerState>) -> Result<Json<PlState>, ServerError> {
state state
.pl_state .pl_state
.as_ref() .as_ref()
@ -352,7 +350,7 @@ async fn regulator_state(state: &State<ServerState>) -> Result<Json<PlState>, Se
} }
#[post("/set-regulator-state/<regulator_state>")] #[post("/set-regulator-state/<regulator_state>")]
async fn set_regulator_state( fn set_regulator_state(
state: &State<ServerState>, state: &State<ServerState>,
regulator_state: Option<RegulatorState>, regulator_state: Option<RegulatorState>,
) -> Result<(), ServerError> { ) -> Result<(), ServerError> {

View file

@ -42,7 +42,8 @@ pub struct TeslaChargeRateController {
voltage_low: u64, voltage_low: u64,
} }
#[allow(dead_code)] #[derive(Clone, Copy)]
#[expect(dead_code)]
pub enum TcrcRequest { pub enum TcrcRequest {
DisableAutomaticControl, DisableAutomaticControl,
EnableAutomaticControl, EnableAutomaticControl,
@ -56,7 +57,7 @@ pub struct TcrcState {
impl TcrcState { impl TcrcState {
pub fn set_control_enable(&mut self, to: bool) { pub fn set_control_enable(&mut self, to: bool) {
self.control_enable = to; self.control_enable = to;
CONTROL_ENABLE_GAUGE.set(if to { 1 } else { 0 }); CONTROL_ENABLE_GAUGE.set(i64::from(to));
} }
} }
@ -155,7 +156,7 @@ impl PidLoop {
LOAD_GAUGE.set(extra_offsets); LOAD_GAUGE.set(extra_offsets);
CHANGE_REQUEST_GAUGE.set(offset); CHANGE_REQUEST_GAUGE.set(offset);
let new_target = offset + (charge_state.charge_amps as f64); let new_target = offset + charge_state.charge_amps as f64;
self.previous_error = error; self.previous_error = error;