monitor power and some drive state variables

This commit is contained in:
Alex Janka 2024-01-18 08:51:44 +11:00
parent 548736c3e1
commit 1b042f6c94
4 changed files with 46 additions and 21 deletions

2
Cargo.lock generated
View file

@ -2256,7 +2256,7 @@ dependencies = [
[[package]] [[package]]
name = "tesla-charge-controller" name = "tesla-charge-controller"
version = "1.0.2" version = "1.0.3"
dependencies = [ dependencies = [
"async-channel", "async-channel",
"chrono", "chrono",

View file

@ -1,6 +1,6 @@
[package] [package]
name = "tesla-charge-controller" name = "tesla-charge-controller"
version = "1.0.2" version = "1.0.3"
edition = "2021" edition = "2021"
license = "MITNFA" license = "MITNFA"
description = "Controls Tesla charge rate based on solar charge data" description = "Controls Tesla charge rate based on solar charge data"

View file

@ -28,6 +28,7 @@ struct Metrics {
remote_heater_control_enabled: Gauge, remote_heater_control_enabled: Gauge,
tesla_online: Gauge, tesla_online: Gauge,
charging_state: ChargingStateGauges, charging_state: ChargingStateGauges,
drive_power: Gauge,
} }
impl Metrics { impl Metrics {
@ -61,6 +62,8 @@ impl Metrics {
let tesla_online = gauge!("tesla_online"); let tesla_online = gauge!("tesla_online");
describe_gauge!("tesla_charging_state", "Tesla charging state"); describe_gauge!("tesla_charging_state", "Tesla charging state");
let charging_state = ChargingStateGauges::new(); let charging_state = ChargingStateGauges::new();
describe_gauge!("tesla_drive_power", "Tesla drive power");
let drive_power = gauge!("tesla_drive_power");
Self { Self {
battery_level, battery_level,
@ -76,6 +79,7 @@ impl Metrics {
remote_heater_control_enabled, remote_heater_control_enabled,
tesla_online, tesla_online,
charging_state, charging_state,
drive_power,
} }
} }
} }
@ -150,10 +154,17 @@ pub struct TeslaInterface {
last_refresh: Instant, last_refresh: Instant,
auth_path: PathBuf, auth_path: PathBuf,
metrics: Metrics, metrics: Metrics,
last_conn_charge_cable: String, monitored_values: MonitoredValues,
last_cop_state: String, }
last_climate_keeper: String,
last_hvac_auto: String, #[derive(Default)]
struct MonitoredValues {
conn_charge_cable: String,
cop_state: String,
climate_keeper: String,
hvac_auto: String,
shift_state: Option<String>,
speed: Option<i64>,
} }
#[derive(Serialize, Deserialize, Clone)] #[derive(Serialize, Deserialize, Clone)]
@ -199,10 +210,7 @@ impl TeslaInterface {
auth_path, auth_path,
vehicle, vehicle,
metrics, metrics,
last_conn_charge_cable: String::new(), monitored_values: Default::default(),
last_cop_state: String::new(),
last_climate_keeper: String::new(),
last_hvac_auto: String::new(),
}; };
interface.save_key()?; interface.save_key()?;
@ -277,6 +285,7 @@ impl TeslaInterface {
} }
if let Some(new_location_data) = new_state.location_data { if let Some(new_location_data) = new_state.location_data {
state.location_data = Some(new_location_data); state.location_data = Some(new_location_data);
self.metrics.drive_power.set(new_location_data.power as f64);
} }
if let Some(new_climate_state) = new_state.climate_state { if let Some(new_climate_state) = new_state.climate_state {
self.metrics.inside_temp.set(new_climate_state.inside_temp); self.metrics.inside_temp.set(new_climate_state.inside_temp);
@ -350,9 +359,9 @@ impl TeslaInterface {
.await? .await?
.charge_state .charge_state
.map(|v| { .map(|v| {
if self.last_conn_charge_cable != v.conn_charge_cable { if self.monitored_values.conn_charge_cable != v.conn_charge_cable {
log::warn!("Current conn charge cable: \"{}\"", v.conn_charge_cable); log::warn!("Current conn charge cable: \"{}\"", v.conn_charge_cable);
self.last_conn_charge_cable = v.conn_charge_cable.clone(); self.monitored_values.conn_charge_cable = v.conn_charge_cable.clone();
} }
v.into() v.into()
}); });
@ -361,11 +370,21 @@ impl TeslaInterface {
.api .api
.vehicle_data(&GetVehicleData { .vehicle_data(&GetVehicleData {
vehicle_id: self.vehicle.id, vehicle_id: self.vehicle.id,
endpoints: vec![Endpoint::LocationData].into(), endpoints: vec![Endpoint::LocationData, Endpoint::DriveState].into(),
}) })
.await? .await?
.drive_state .drive_state
.and_then(|v| v.try_into().ok()); .and_then(|v| {
if self.monitored_values.shift_state != v.shift_state {
log::warn!("Current shift state: \"{:?}\"", v.shift_state);
self.monitored_values.shift_state = v.shift_state.clone();
}
if self.monitored_values.speed != v.speed {
log::warn!("Current speed: \"{:?}\"", v.speed);
self.monitored_values.speed = v.speed;
}
v.try_into().ok()
});
let climate_state = self let climate_state = self
.api .api
@ -376,20 +395,20 @@ impl TeslaInterface {
.await? .await?
.climate_state .climate_state
.and_then(|v| { .and_then(|v| {
if self.last_cop_state != v.cabin_overheat_protection { if self.monitored_values.cop_state != v.cabin_overheat_protection {
log::warn!( log::warn!(
"Current cabin overheat protection state: \"{}\"", "Current cabin overheat protection state: \"{}\"",
v.cabin_overheat_protection v.cabin_overheat_protection
); );
self.last_cop_state = v.cabin_overheat_protection.clone(); self.monitored_values.cop_state = v.cabin_overheat_protection.clone();
} }
if self.last_climate_keeper != v.climate_keeper_mode { if self.monitored_values.climate_keeper != v.climate_keeper_mode {
log::warn!("Current climate keeper mode: \"{}\"", v.climate_keeper_mode); log::warn!("Current climate keeper mode: \"{}\"", v.climate_keeper_mode);
self.last_climate_keeper = v.climate_keeper_mode.clone(); self.monitored_values.climate_keeper = v.climate_keeper_mode.clone();
} }
if self.last_hvac_auto != v.hvac_auto_request { if self.monitored_values.hvac_auto != v.hvac_auto_request {
log::warn!("HVAC auto request set to: \"{}\"", v.hvac_auto_request); log::warn!("HVAC auto request set to: \"{}\"", v.hvac_auto_request);
self.last_hvac_auto = v.hvac_auto_request.clone(); self.monitored_values.hvac_auto = v.hvac_auto_request.clone();
} }
v.try_into().ok() v.try_into().ok()
}); });

View file

@ -86,6 +86,7 @@ impl From<teslatte::vehicles::ChargeState> for ChargeState {
pub struct LocationData { pub struct LocationData {
pub gps_as_of: DateTime<chrono::Utc>, pub gps_as_of: DateTime<chrono::Utc>,
pub home: bool, pub home: bool,
pub power: i64,
} }
impl TryFrom<teslatte::vehicles::DriveState> for LocationData { impl TryFrom<teslatte::vehicles::DriveState> for LocationData {
@ -102,7 +103,12 @@ impl TryFrom<teslatte::vehicles::DriveState> for LocationData {
longitude: value.longitude.ok_or(TeslaStateParseError::NoValue)?, longitude: value.longitude.ok_or(TeslaStateParseError::NoValue)?,
}; };
let home = coords.overlaps(&access_config().coords); let home = coords.overlaps(&access_config().coords);
Ok(Self { gps_as_of, home }) let power = value.power;
Ok(Self {
gps_as_of,
home,
power,
})
} }
} }