diff --git a/Cargo.lock b/Cargo.lock index d6014ea..552407a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2567,7 +2567,7 @@ dependencies = [ [[package]] name = "tesla-charge-controller" -version = "1.0.7" +version = "1.0.8" dependencies = [ "async-channel", "chrono", diff --git a/Cargo.toml b/Cargo.toml index 1e4fe99..2f877a3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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" diff --git a/src/api_interface.rs b/src/api_interface.rs index 1c25f1f..66cf2b1 100644 --- a/src/api_interface.rs +++ b/src/api_interface.rs @@ -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>, 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, } @@ -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() }); diff --git a/src/types.rs b/src/types.rs index fd768b1..7c198cb 100644 --- a/src/types.rs +++ b/src/types.rs @@ -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 for ClimateState { @@ -46,6 +48,8 @@ impl TryFrom 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, }) } } diff --git a/vendored/teslatte b/vendored/teslatte index db77d94..a350280 160000 --- a/vendored/teslatte +++ b/vendored/teslatte @@ -1 +1 @@ -Subproject commit db77d944cb51f949a0235b7112ca7a5adad84b57 +Subproject commit a350280662bfca096ea153903bdc3dcb2652f415