ditch anyhow
This commit is contained in:
parent
904513b71a
commit
7dd4cc43b1
7
Cargo.lock
generated
7
Cargo.lock
generated
|
@ -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",
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -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<RwLock<PlState>>,
|
||||
port: Box<dyn SerialPort>,
|
||||
|
@ -122,7 +123,7 @@ pub enum PliRequest {
|
|||
}
|
||||
|
||||
impl Pli {
|
||||
pub fn new(serial_port: String, baud_rate: u32) -> anyhow::Result<Self> {
|
||||
pub fn new(serial_port: String, baud_rate: u32) -> Result<Self, serialport::Error> {
|
||||
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<PlState> {
|
||||
fn read_state(&mut self) -> Result<PlState, PliError> {
|
||||
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<T>(&mut self, address: T) -> anyhow::Result<u8>
|
||||
fn read_ram<T>(&mut self, address: T) -> Result<u8, PliError>
|
||||
where
|
||||
T: Into<u8>,
|
||||
{
|
||||
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]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
27
src/types.rs
27
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<ChargeState>,
|
||||
|
@ -17,17 +18,13 @@ pub struct ClimateState {
|
|||
}
|
||||
|
||||
impl TryFrom<teslatte::vehicles::ClimateState> for ClimateState {
|
||||
type Error = anyhow::Error;
|
||||
type Error = TeslaStateParseError;
|
||||
|
||||
fn try_from(value: teslatte::vehicles::ClimateState) -> Result<Self, Self::Error> {
|
||||
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<teslatte::vehicles::DriveState> for LocationData {
|
||||
type Error = anyhow::Error;
|
||||
type Error = TeslaStateParseError;
|
||||
|
||||
fn try_from(value: teslatte::vehicles::DriveState) -> Result<Self, Self::Error> {
|
||||
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 })
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue