From 7dd4cc43b18b7fd4e725788f84a74fd92e5be74e Mon Sep 17 00:00:00 2001 From: Alex Janka Date: Fri, 12 Jan 2024 08:47:21 +1100 Subject: [PATCH] ditch anyhow --- Cargo.lock | 7 ------- Cargo.toml | 1 - src/api_interface.rs | 3 +-- src/errors.rs | 20 +++++++++++++++++--- src/pl_interface.rs | 39 +++++++++++++++++++++++---------------- src/types.rs | 27 +++++++++++++-------------- 6 files changed, 54 insertions(+), 43 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ce76b2e..57ff20b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -101,12 +101,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "anyhow" -version = "1.0.79" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" - [[package]] name = "arc-swap" version = "1.6.0" @@ -2264,7 +2258,6 @@ dependencies = [ name = "tesla-charge-controller" version = "0.1.17-prerelease" dependencies = [ - "anyhow", "async-channel", "chrono", "clap", diff --git a/Cargo.toml b/Cargo.toml index bade861..35517a6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,6 @@ tokio = { version = "1.35.1", features = ["full"] } teslatte = { path = "./vendored/teslatte" } thiserror = "1.0" rocket = { version = "0.5", features = ["json"] } -anyhow = "1.0" include_dir = "0.7" chrono = "0.4" async-channel = "2.1" diff --git a/src/api_interface.rs b/src/api_interface.rs index e47fbc1..bea2e27 100644 --- a/src/api_interface.rs +++ b/src/api_interface.rs @@ -1,4 +1,3 @@ -use anyhow::{Context, Result}; use metrics::{describe_gauge, gauge, Gauge, Unit}; use serde::{Deserialize, Serialize}; use std::{ @@ -93,7 +92,7 @@ impl TeslaInterface { _ => None, }) .next() - .context("No vehicles attached to account!")?; + .ok_or(AuthLoadError::NoVehicles)?; let metrics = Metrics::new(); diff --git a/src/errors.rs b/src/errors.rs index c2c6139..0683823 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -27,8 +27,8 @@ pub enum AuthLoadError { Teslatte(#[from] teslatte::error::TeslatteError), #[error("save error")] Save(#[from] SaveError), - #[error("other error")] - Anyhow(#[from] anyhow::Error), + #[error("no vehicles")] + NoVehicles, } impl AuthLoadError { @@ -38,7 +38,7 @@ impl AuthLoadError { AuthLoadError::StdIo(e) => format!("Error reading access token from disk: {e:?}"), AuthLoadError::RonSpanned(e) => format!("Error deserialising access token: {e:?}"), AuthLoadError::Save(e) => e.error_string(), - AuthLoadError::Anyhow(e) => e.to_string(), + AuthLoadError::NoVehicles => String::from("No vehicles attached to account"), } } } @@ -54,3 +54,17 @@ pub enum RequestError { #[error("save error")] Save(#[from] SaveError), } + +#[derive(Error, Debug)] +pub enum PliError { + #[error("read error")] + ReadError(u8), +} + +#[derive(Error, Debug)] +pub enum TeslaStateParseError { + #[error("No associated value")] + NoValue, + #[error("Invalid timestamp")] + InvalidTimestamp, +} diff --git a/src/pl_interface.rs b/src/pl_interface.rs index dfd8668..9c5433f 100644 --- a/src/pl_interface.rs +++ b/src/pl_interface.rs @@ -4,12 +4,13 @@ use std::{ time::Duration, }; -use anyhow::Context; use metrics::{describe_gauge, gauge, Gauge}; use serde::{Deserialize, Serialize}; use serialport::SerialPort; use termcolor::WriteColor; +use crate::errors::PliError; + pub struct Pli { pub state: Arc>, port: Box, @@ -122,7 +123,7 @@ pub enum PliRequest { } impl Pli { - pub fn new(serial_port: String, baud_rate: u32) -> anyhow::Result { + pub fn new(serial_port: String, baud_rate: u32) -> Result { let port = serialport::new(serial_port, baud_rate) .timeout(Duration::from_millis(250)) .open()?; @@ -151,17 +152,20 @@ impl Pli { } pub fn refresh(&mut self) { - if let Ok(new_state) = self.read_state() { - self.voltage_gauge.set(new_state.battery_voltage); - self.target_voltage_gauge.set(new_state.target_voltage); - self.duty_cycle.set(new_state.duty_cycle); - self.internal_charge_current - .set(new_state.internal_charge_current); - self.internal_load_current - .set(new_state.internal_load_current); - self.regulator_gauges.set(&new_state.regulator_state); + match self.read_state() { + Ok(new_state) => { + self.voltage_gauge.set(new_state.battery_voltage); + self.target_voltage_gauge.set(new_state.target_voltage); + self.duty_cycle.set(new_state.duty_cycle); + self.internal_charge_current + .set(new_state.internal_charge_current); + self.internal_load_current + .set(new_state.internal_load_current); + self.regulator_gauges.set(&new_state.regulator_state); - *self.state.write().expect("PLI state handler panicked!!") = new_state; + *self.state.write().expect("PLI state handler panicked!!") = new_state; + } + Err(e) => log::error!("State read error: {e:#?}"), } } @@ -185,7 +189,7 @@ impl Pli { } } - fn read_state(&mut self) -> anyhow::Result { + fn read_state(&mut self) -> Result { Ok(PlState { battery_voltage: (self.read_ram(PlRamAddress::Batv)? as f64) * (4. / 10.), target_voltage: (self.read_ram(PlRamAddress::Vreg)? as f64) * (4. / 10.), @@ -211,14 +215,17 @@ impl Pli { buf } - fn read_ram(&mut self, address: T) -> anyhow::Result + fn read_ram(&mut self, address: T) -> Result where T: Into, { self.send_command(command(20, address.into(), 0)); let buf: [u8; 2] = self.receive(); - if buf[0] == 200 { Some(buf[1]) } else { None } - .context(format!("Error from PLI: {}", buf[0])) + if buf[0] == 200 { + Ok(buf[1]) + } else { + Err(PliError::ReadError(buf[0])) + } } } diff --git a/src/types.rs b/src/types.rs index 127a2b3..f8e1eb3 100644 --- a/src/types.rs +++ b/src/types.rs @@ -1,7 +1,8 @@ -use anyhow::Context; use chrono::DateTime; use serde::{Deserialize, Serialize}; +use crate::errors::TeslaStateParseError; + #[derive(Default)] pub struct CarState { pub charge_state: Option, @@ -17,17 +18,13 @@ pub struct ClimateState { } impl TryFrom for ClimateState { - type Error = anyhow::Error; + type Error = TeslaStateParseError; fn try_from(value: teslatte::vehicles::ClimateState) -> Result { Ok(Self { - inside_temp: value - .inside_temp - .context("no inside temperature in climate data")?, + inside_temp: value.inside_temp.ok_or(TeslaStateParseError::NoValue)?, - outside_temp: value - .outside_temp - .context("no outside temperature in climate data")?, + outside_temp: value.outside_temp.ok_or(TeslaStateParseError::NoValue)?, battery_heater: value.battery_heater, }) } @@ -74,15 +71,17 @@ pub struct LocationData { } impl TryFrom for LocationData { - type Error = anyhow::Error; + type Error = TeslaStateParseError; fn try_from(value: teslatte::vehicles::DriveState) -> Result { - let gps_as_of = - chrono::DateTime::from_timestamp(value.gps_as_of.context("no gps timestamp!")?, 0) - .context("could not process timestamp!")?; + let gps_as_of = chrono::DateTime::from_timestamp( + value.gps_as_of.ok_or(TeslaStateParseError::NoValue)?, + 0, + ) + .ok_or(TeslaStateParseError::InvalidTimestamp)?; let coords = Coords { - latitude: value.latitude.context("no longitude provided!")?, - longitude: value.longitude.context("no latitude provided!")?, + latitude: value.latitude.ok_or(TeslaStateParseError::NoValue)?, + longitude: value.longitude.ok_or(TeslaStateParseError::NoValue)?, }; Ok(Self { coords, gps_as_of }) }