diff --git a/teslajsonpy/car.py b/teslajsonpy/car.py index 1493e408..fb9b8a0a 100644 --- a/teslajsonpy/car.py +++ b/teslajsonpy/car.py @@ -79,7 +79,8 @@ def data_available(self) -> bool: """Return if data from VEHICLE_DATA endpoint is available.""" # self._vehicle_data gets updated with some data from VEHICLE_LIST endpoint # Only return True if data specifically from VEHICLE_DATA endpoint is available - if self._vehicle_data.get("vehicle_config", {}): + # vehicle_state is only from the VEHICLE_DATA endpoint + if self._vehicle_data.get("vehicle_state", {}): return True return None @@ -445,7 +446,7 @@ def power(self) -> int: @property def powered_lift_gate(self) -> bool: """Return True if car has power lift gate.""" - return self._vehicle_data.get("vehicle_config", {}).get("plg") + return self._car.get("vehicle_config", {}).get("plg") @property def rear_seat_heaters(self) -> int: @@ -455,7 +456,7 @@ def rear_seat_heaters(self) -> int: int: 0 (no rear heated seats), int: ? (rear heated seats) """ - return self._vehicle_data.get("vehicle_config", {}).get("rear_seat_heaters") + return self._car.get("vehicle_config", {}).get("rear_seat_heaters") @property def sentry_mode(self) -> bool: @@ -485,7 +486,7 @@ def software_update(self) -> dict: @property def steering_wheel_heater(self) -> bool: """Return steering wheel heater option.""" - return self._vehicle_data.get("climate_state", {}).get("steering_wheel_heater") + return self._vehicle_data.get("climate_state", {}).get("steering_wheel_heater") is not None @property def tpms_pressure_fl(self) -> float: @@ -515,7 +516,7 @@ def third_row_seats(self) -> str: str: None """ - return self._vehicle_data.get("vehicle_config", {}).get("third_row_seats") + return self._car.get("vehicle_config", {}).get("third_row_seats") @property def time_to_full_charge(self) -> float: @@ -579,6 +580,16 @@ def _get_lat_long(self) -> float: return lat, long + def update_car_info(self, car: dict) -> None: + """Update the car info dict from the vehicle_list api.""" + if not car: + _LOGGER.debug("Attempted to update car id %d with empty car info", self.id) + return + if car["vin"] != self.vin: + _LOGGER.error("Failed updating car info: new VIN (%s) doesn't match existing vin (%s)", car["vin"][-5:], self.vin[-5:]) + return + self._car.update(car) + async def change_charge_limit(self, value: float) -> None: """Send command to change charge limit.""" data = await self._send_command( diff --git a/teslajsonpy/controller.py b/teslajsonpy/controller.py index 182e6d9b..ce55ece0 100644 --- a/teslajsonpy/controller.py +++ b/teslajsonpy/controller.py @@ -342,12 +342,12 @@ def __init__( self._include_energysites: bool = True self._product_list: List[dict] = [] self._vehicle_list: List[dict] = [] - self._vehicle_data: Dict[str:dict] = {} + self._vehicle_data: Dict[str, dict] = {} self._energysite_list: List[dict] = [] - self._site_config: Dict[int:dict] = {} - self._site_data: Dict[int:dict] = {} - self._battery_data: Dict[int:dict] = {} - self._battery_summary: Dict[int:dict] = {} + self._site_config: Dict[int, dict] = {} + self._site_data: Dict[int, dict] = {} + self._battery_data: Dict[int, dict] = {} + self._battery_summary: Dict[int, dict] = {} self._grid_status_unknown: Dict[int, bool] = {} self.cars: Dict[str, TeslaCar] = {} self.energysites: Dict[int, EnergySite] = {} @@ -893,7 +893,7 @@ async def _get_and_process_battery_summary( self.set_car_online( vin=car["vin"], online_status=car["state"] == "online" ) - self._vehicle_data[car["vin"]].update(car) + self.cars[car["vin"]].update_car_info(car) self._last_attempted_update_time = cur_time # Only update online vehicles that haven't been updated recently diff --git a/tests/tesla_mock.py b/tests/tesla_mock.py index 5c356240..51191e03 100644 --- a/tests/tesla_mock.py +++ b/tests/tesla_mock.py @@ -304,6 +304,43 @@ def command_ok(): "api_version": 36, "backseat_token": None, "backseat_token_updated_at": None, + "vehicle_config": { + "can_accept_navigation_requests": True, + "can_actuate_trunks": True, + "car_special_type": "base", + "car_type": "models", + "charge_port_type": "US", + "dashcam_clip_save_supported": False, + "default_charge_to_max": False, + "driver_assist": "MonoCam", + "ece_restrictions": False, + "efficiency_package": "Default", + "eu_vehicle": False, + "exterior_color": "White", + "front_drive_unit": "NoneOrSmall", + "has_air_suspension": False, + "has_ludicrous_mode": False, + "has_seat_cooling": False, + "headlamp_type": "Hid", + "interior_trim_type": "AllBlack", + "motorized_charge_port": True, + "plg": True, + "pws": False, + "rear_drive_unit": "Small", + "rear_seat_heaters": 0, + "rear_seat_type": 1, + "rhd": False, + "roof_color": "Colored", + "seat_type": 1, + "spoiler_type": "None", + "sun_roof_installed": 0, + "third_row_seats": "None", + "timestamp": 1661641175269, + "trim_badging": "85d", + "use_range_badging": False, + "utc_offset": -25200, + "wheel_type": "Base19", + } }, { "energy_site_id": 12345, diff --git a/tests/unit_tests/test_car.py b/tests/unit_tests/test_car.py index 86570ba7..9dbca47a 100644 --- a/tests/unit_tests/test_car.py +++ b/tests/unit_tests/test_car.py @@ -226,9 +226,9 @@ async def test_car_properties(monkeypatch): assert _car.software_update == VEHICLE_DATA["vehicle_state"]["software_update"] - assert _car.steering_wheel_heater == VEHICLE_DATA["climate_state"].get( + assert _car.steering_wheel_heater == (VEHICLE_DATA["climate_state"].get( "steering_wheel_heater" - ) + ) is not None) assert _car.third_row_seats == str( VEHICLE_DATA["vehicle_state"].get("third_row_seats")