cabin overheat protection & hvac metrics

This commit is contained in:
Alex Janka 2024-01-18 16:53:13 +11:00
parent e7cacafa52
commit f1807b2417
5 changed files with 140 additions and 18 deletions

2
Cargo.lock generated
View file

@ -2567,7 +2567,7 @@ dependencies = [
[[package]]
name = "tesla-charge-controller"
version = "1.0.7"
version = "1.0.8"
dependencies = [
"async-channel",
"chrono",

View file

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

View file

@ -8,7 +8,10 @@ use std::{
use teslatte::{
auth::{AccessToken, RefreshToken},
error::TeslatteError,
vehicles::{ChargingState, Endpoint, GetVehicleData, SetChargingAmps},
vehicles::{
CabinOverheatProtection, ChargingState, Endpoint, GetVehicleData, HvacAutoRequest,
SetChargingAmps,
},
FleetApi, FleetVehicleApi,
};
@ -34,6 +37,8 @@ struct Metrics {
passenger_temp_setting: Gauge,
tesla_online: Gauge,
charging_state: ChargingStateGauges,
cabin_overheat_protection: CabinOverheatProtectionGauges,
hvac_auto: HvacAutoRequestGauges,
}
impl Metrics {
@ -73,6 +78,13 @@ impl Metrics {
let tesla_online = gauge!("tesla_online");
describe_gauge!("tesla_charging_state", "Tesla charging state");
let charging_state = ChargingStateGauges::new();
describe_gauge!(
"tesla_cabin_overheat_protection_state",
"Cabin overheat protection state"
);
let cabin_overheat_protection = CabinOverheatProtectionGauges::new();
describe_gauge!("tesla_hvac_auto_request", "HVAC auto");
let hvac_auto = HvacAutoRequestGauges::new();
Self {
battery_level,
@ -91,6 +103,8 @@ impl Metrics {
passenger_temp_setting,
tesla_online,
charging_state,
cabin_overheat_protection,
hvac_auto,
}
}
}
@ -158,6 +172,117 @@ impl ChargingStateGauges {
}
}
struct CabinOverheatProtectionGauges {
off: Gauge,
on: Gauge,
fan_only: Gauge,
unknown: Gauge,
}
impl CabinOverheatProtectionGauges {
fn new() -> Self {
let off = gauge!(
"tesla_cabin_overheat_protection_state",
vec![Label::new("state", String::from("off"))]
);
let on = gauge!(
"tesla_cabin_overheat_protection_state",
vec![Label::new("state", String::from("on"))]
);
let fan_only = gauge!(
"tesla_cabin_overheat_protection_state",
vec![Label::new("state", String::from("fan_only"))]
);
let unknown = gauge!(
"tesla_cabin_overheat_protection_state",
vec![Label::new("state", String::from("unknown"))]
);
Self {
off,
on,
fan_only,
unknown,
}
}
fn set(&mut self, state: CabinOverheatProtection) {
match state {
CabinOverheatProtection::Off => {
self.off.set(1.);
self.on.set(0.);
self.fan_only.set(0.);
self.unknown.set(0.);
}
CabinOverheatProtection::On => {
self.off.set(0.);
self.on.set(1.);
self.fan_only.set(0.);
self.unknown.set(0.);
}
CabinOverheatProtection::FanOnly => {
self.off.set(0.);
self.on.set(0.);
self.fan_only.set(1.);
self.unknown.set(0.);
}
CabinOverheatProtection::Unknown => {
self.off.set(0.);
self.on.set(0.);
self.fan_only.set(0.);
self.unknown.set(1.);
}
}
}
}
struct HvacAutoRequestGauges {
override_g: Gauge,
on: Gauge,
unknown: Gauge,
}
impl HvacAutoRequestGauges {
fn new() -> Self {
let override_g = gauge!(
"tesla_hvac_auto_request",
vec![Label::new("state", String::from("override"))]
);
let on = gauge!(
"tesla_hvac_auto_request",
vec![Label::new("state", String::from("on"))]
);
let unknown = gauge!(
"tesla_hvac_auto_request",
vec![Label::new("state", String::from("unknown"))]
);
Self {
override_g,
on,
unknown,
}
}
fn set(&mut self, state: HvacAutoRequest) {
match state {
HvacAutoRequest::Override => {
self.override_g.set(1.);
self.on.set(0.);
self.unknown.set(0.);
}
HvacAutoRequest::On => {
self.override_g.set(0.);
self.on.set(1.);
self.unknown.set(0.);
}
HvacAutoRequest::Unknown => {
self.override_g.set(0.);
self.on.set(0.);
self.unknown.set(1.);
}
}
}
}
pub struct TeslaInterface {
pub state: Arc<RwLock<CarState>>,
api: FleetApi,
@ -171,9 +296,7 @@ pub struct TeslaInterface {
#[derive(Default)]
struct MonitoredValues {
conn_charge_cable: String,
cop_state: String,
climate_keeper: String,
hvac_auto: String,
speed: Option<i64>,
}
@ -322,6 +445,12 @@ impl TeslaInterface {
self.metrics
.passenger_temp_setting
.set(new_climate_state.passenger_temp_setting);
self.metrics
.cabin_overheat_protection
.set(new_climate_state.cabin_overheat_protection);
self.metrics
.hvac_auto
.set(new_climate_state.hvac_auto_request);
state.climate_state = Some(new_climate_state);
}
@ -410,21 +539,10 @@ impl TeslaInterface {
.await?
.climate_state
.and_then(|v| {
if self.monitored_values.cop_state != v.cabin_overheat_protection {
log::warn!(
"Current cabin overheat protection state: \"{}\"",
v.cabin_overheat_protection
);
self.monitored_values.cop_state = v.cabin_overheat_protection.clone();
}
if self.monitored_values.climate_keeper != v.climate_keeper_mode {
log::warn!("Current climate keeper mode: \"{}\"", v.climate_keeper_mode);
self.monitored_values.climate_keeper = v.climate_keeper_mode.clone();
}
if self.monitored_values.hvac_auto != v.hvac_auto_request {
log::warn!("HVAC auto request set to: \"{}\"", v.hvac_auto_request);
self.monitored_values.hvac_auto = v.hvac_auto_request.clone();
}
v.try_into().ok()
});

View file

@ -1,6 +1,6 @@
use chrono::DateTime;
use serde::{Deserialize, Serialize};
use teslatte::vehicles::{ChargingState, ShiftState};
use teslatte::vehicles::{CabinOverheatProtection, ChargingState, HvacAutoRequest, ShiftState};
use crate::{config::access_config, errors::TeslaStateParseError};
@ -30,6 +30,8 @@ pub struct ClimateState {
pub is_auto_conditioning_on: bool,
pub driver_temp_setting: f64,
pub passenger_temp_setting: f64,
pub cabin_overheat_protection: CabinOverheatProtection,
pub hvac_auto_request: HvacAutoRequest,
}
impl TryFrom<teslatte::vehicles::ClimateState> for ClimateState {
@ -46,6 +48,8 @@ impl TryFrom<teslatte::vehicles::ClimateState> for ClimateState {
is_auto_conditioning_on: value.is_auto_conditioning_on.unwrap_or(false),
driver_temp_setting: value.driver_temp_setting,
passenger_temp_setting: value.passenger_temp_setting,
cabin_overheat_protection: value.cabin_overheat_protection,
hvac_auto_request: value.hvac_auto_request,
})
}
}

@ -1 +1 @@
Subproject commit db77d944cb51f949a0235b7112ca7a5adad84b57
Subproject commit a350280662bfca096ea153903bdc3dcb2652f415