Skip to content

Commit

Permalink
fix: energy_left total_pack_energy` gone. Untagged handling
Browse files Browse the repository at this point in the history
  • Loading branch information
gak committed Apr 11, 2024
1 parent fcc9e63 commit 1e6c1d5
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 15 deletions.
21 changes: 19 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Changed

- `energy_left` and `total_pack_energy` are gone from the API. (#22)
- Don't rely on serde untagged to determine the product type, as any missing
fields will give an unspecified error. Instead directly check known fields
that will probably not be removed. https://github.com/serde-rs/serde/pull/2376

## [0.1.13] - 2023-01-24

### Changed
Expand All @@ -23,31 +32,35 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- go_off_grid_test_banner_enabled
- powerwall_tesla_electric_interested_in
- vpp_tour_enabled
- Components market_type is now Option<String>
- Components market_type is now Option<String>
- LiveWallConnector wall_connector_power is now f32

## [0.1.11] - 2023-11-11

### Changed

- `vehicle_data` now accepts `GetVehicleData` instead of `VehicleId`. (See [6facc27](https://github.com/gak/teslatte/commit/6facc27d8b408d35b98b4c6c0ad3e5df82328d2c))

## [0.1.10] - 2023-11-11

### Changed

- API changes for "api_version 67"

- VehicleData new fields:

- cached_data
- command_signing
- release_notes_supported

- ClimateState new fields:

- auto_steering_wheel_heat
- cop_activation_temperature,
- steering_wheel_heat_level

- DriveState now Optional:

- gps_as_of
- heading
- latitude
Expand All @@ -58,16 +71,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- native_type

- DriveState new fields:

- active_route_traffic_minutes_delay

- GuiSettings new field:

- gui_tirepressure_units

- VehicleConfig new fields:

- cop_user_set_temp_supported
- webcam_selfie_supported

- VehicleState new fields:

- media_info: MediaInfo
- tpms_hard_warning_fl
- tpms_hard_warning_fr
Expand Down
3 changes: 0 additions & 3 deletions src/energy_sites.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ pub struct SiteStatus {
pub battery_power: i64,
pub battery_type: String,
pub breaker_alert_enabled: bool,
pub energy_left: f64,
pub gateway_id: String,
pub percentage_charged: f64,
pub powerwall_onboarding_settings_set: bool,
Expand All @@ -29,14 +28,12 @@ pub struct SiteStatus {
pub site_name: String,
pub storm_mode_enabled: bool,
pub sync_grid_alert_enabled: bool,
pub total_pack_energy: i64,
}

#[derive(Debug, Clone, Deserialize, PartialEq)]
pub struct LiveStatus {
pub backup_capable: bool,
pub battery_power: i64,
pub energy_left: f64,
pub generator_power: i64,
pub grid_power: i64,
pub grid_services_active: bool,
Expand Down
2 changes: 0 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,6 @@ pub trait VehicleApi {
) -> Result<PostResponse, TeslatteError>;
}

trait EnergySitesApi {}

trait ApiValues {
fn format(&self, url: &str) -> String;
}
Expand Down
47 changes: 42 additions & 5 deletions src/products.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ use crate::powerwall::PowerwallId;
use crate::vehicles::VehicleData;
use crate::{pub_get, OwnerApi};
use derive_more::Display;
use serde::{Deserialize, Serialize};
use serde::{Deserialize, Deserializer, Serialize};
use serde_json::Value;
use std::str::FromStr;

#[rustfmt::skip]
Expand All @@ -28,14 +29,44 @@ impl FromStr for EnergySiteId {
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GatewayId(String);

#[derive(Debug, Clone, Deserialize)]
#[serde(untagged)]
#[derive(Debug, Clone)]
pub enum Product {
Vehicle(Box<VehicleData>),
Solar(Box<SolarData>),
Powerwall(Box<PowerwallData>),
}

fn deserialize_product<'de, D>(deserializer: D) -> Result<Product, D::Error>
where
D: Deserializer<'de>,
{
let v = Value::deserialize(deserializer)?;

if v.get("vehicle_id").is_some() {
let vehicle_data = VehicleData::deserialize(v).map_err(serde::de::Error::custom)?;
Ok(Product::Vehicle(Box::new(vehicle_data)))
} else if v.get("solar_type").is_some() {
let solar_data = SolarData::deserialize(v).map_err(serde::de::Error::custom)?;
Ok(Product::Solar(Box::new(solar_data)))
} else if v.get("battery_type").is_some() {
let powerwall_data = PowerwallData::deserialize(v).map_err(serde::de::Error::custom)?;
Ok(Product::Powerwall(Box::new(powerwall_data)))
} else {
Err(serde::de::Error::custom(
"No valid key found to determine the product type",
))
}
}

impl<'de> Deserialize<'de> for Product {
fn deserialize<D>(deserializer: D) -> Result<Product, D::Error>
where
D: Deserializer<'de>,
{
deserialize_product(deserializer)
}
}

/// This is assumed from https://tesla-api.timdorr.com/api-basics/products
#[derive(Debug, Clone, Deserialize)]
pub struct SolarData {
Expand All @@ -61,8 +92,6 @@ pub struct PowerwallData {
pub id: PowerwallId,
pub gateway_id: GatewayId,
pub asset_site_id: String,
pub energy_left: f64,
pub total_pack_energy: i64,
pub percentage_charged: f64,
pub backup_capable: bool,
pub battery_power: i64,
Expand Down Expand Up @@ -239,4 +268,12 @@ mod tests {
OwnerApi::parse_json::<Vec<Product>>(&request_data, s.to_string(), PrintResponses::Pretty)
.unwrap();
}

#[test]
fn json_products_gak_2024_04_12() {
let s = include_str!("../testdata/products_gak_2024_04_12.json");
let request_data = RequestData::Get { url: "" };
OwnerApi::parse_json::<Vec<Product>>(&request_data, s.to_string(), PrintResponses::Pretty)
.unwrap();
}
}
3 changes: 0 additions & 3 deletions src/vehicles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -457,9 +457,6 @@ pub struct GranularAccess {
pub hide_private: bool,
}

#[derive(Debug, Deserialize)]
pub struct Vehicles(Vec<Vehicle>);

#[derive(Debug, Deserialize)]
pub struct Vehicle {
pub id: VehicleId,
Expand Down
70 changes: 70 additions & 0 deletions testdata/products_gak_2024_04_12.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
{
"count": 2,
"response": [
{
"access_type": "OWNER",
"api_version": 73,
"backseat_token": null,
"backseat_token_updated_at": null,
"ble_autopair_enrolled": false,
"cached_data": "",
"calendar_enabled": true,
"color": null,
"command_signing": "required",
"display_name": "Kool Beans",
"granular_access": {
"hide_private": false
},
"id": 123,
"id_s": "123",
"in_service": false,
"option_codes": null,
"release_notes_supported": true,
"state": "online",
"tokens": [],
"user_id": 123,
"vehicle_id": 123,
"vin": "LRW"
},
{
"asset_site_id": "qwfp",
"backup_capable": true,
"battery_power": -1590,
"battery_type": "ac_powerwall",
"breaker_alert_enabled": true,
"components": {
"battery": true,
"battery_type": "ac_powerwall",
"grid": true,
"load_meter": true,
"market_type": "residential",
"solar": true,
"solar_type": "pv_panel",
"wall_connectors": [
{
"device_id": "qwfp",
"din": "qwfp",
"is_active": true,
"part_number": "1529455-02-D"
}
]
},
"energy_site_id": 1234,
"features": {
"rate_plan_manager_no_pricing_constraint": true
},
"gateway_id": "qwfp",
"go_off_grid_test_banner_enabled": null,
"id": "qwfp",
"percentage_charged": 48.872760297620715,
"powerwall_onboarding_settings_set": true,
"powerwall_tesla_electric_interested_in": null,
"resource_type": "battery",
"site_name": "",
"storm_mode_enabled": true,
"sync_grid_alert_enabled": true,
"vpp_tour_enabled": null,
"warp_site_number": ""
}
]
}

0 comments on commit 1e6c1d5

Please sign in to comment.