Repository: bimmerconnected/bimmer_connected
Pull request #591 (2024-01-21 13:22:40)

Adjust URLs
## Proposed change
<!--
  Describe the big picture of your changes here to communicate to the
  maintainers why we should accept this pull request. If it fixes a bug
  or resolves a feature request, be sure to link to that issue in the
  additional information section.
-->
Adjust URLs to MyBMW 3.11. Looks good for ROW/NA.

This should also work for china (provided the login issue #588 is solved).

## Type of change
- [x] Bugfix (non-breaking change which fixes an issue)
- [ ] New feature (which adds functionality to this library)
- [ ] Breaking change (fix/feature causing existing functionality to break)
- [ ] Code quality improvements to existing code or addition of tests

## Additional information
<!--
  Details are important, and help maintainers processing your PR.
  Please be sure to fill out additional details, if applicable.
-->

- This PR fixes or closes issue: fixes #
- This PR is related to issue: 

## Checklist
<!--
  Put an `x` in the boxes that apply. You can also fill these out after
  creating the PR. If you're unsure about any of them, don't hesitate to ask.
  We're here to help! This is simply a reminder of what we are going to look
  for before merging your code.
-->

- [x] The code change is tested and works locally.
- [x] Tests have been added to verify that the new code works.


codecov[bot]: ## [Codecov](https://app.codecov.io/gh/bimmerconnected/bimmer_connected/pull/591?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bimmerconnected) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Comparison is base [(`9d3bd67`)](https://app.codecov.io/gh/bimmerconnected/bimmer_connected/commit/9d3bd673f28f7e997d08faa0cc40464eff7af063?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bimmerconnected) 100.00% compared to head [(`ed2ffd2`)](https://app.codecov.io/gh/bimmerconnected/bimmer_connected/pull/591?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bimmerconnected) 100.00%.
> Report is 1 commits behind head on master.


<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff            @@
##            master      #591   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           17        17           
  Lines         1412      1415    +3     
=========================================
+ Hits          1412      1415    +3     
```

| [Flag](https://app.codecov.io/gh/bimmerconnected/bimmer_connected/pull/591/flags?src=pr&el=flags&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bimmerconnected) | Coverage Δ | |
|---|---|---|
| [3.10](https://app.codecov.io/gh/bimmerconnected/bimmer_connected/pull/591/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bimmerconnected) | `100.00% <100.00%> (ø)` | |
| [3.11](https://app.codecov.io/gh/bimmerconnected/bimmer_connected/pull/591/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bimmerconnected) | `100.00% <100.00%> (ø)` | |
| [3.12](https://app.codecov.io/gh/bimmerconnected/bimmer_connected/pull/591/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bimmerconnected) | `100.00% <100.00%> (ø)` | |
| [3.8](https://app.codecov.io/gh/bimmerconnected/bimmer_connected/pull/591/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bimmerconnected) | `100.00% <100.00%> (ø)` | |
| [3.9](https://app.codecov.io/gh/bimmerconnected/bimmer_connected/pull/591/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bimmerconnected) | `100.00% <100.00%> (ø)` | |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bimmerconnected#carryforward-flags-in-the-pull-request-comment) to find out more.


</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/bimmerconnected/bimmer_connected/pull/591?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bimmerconnected).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bimmerconnected).


Patch:
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 18074a0..1646abc 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,12 +1,12 @@
 repos:
   - repo: https://github.com/charliermarsh/ruff-pre-commit
-    rev: v0.1.5
+    rev: v0.1.14
     hooks:
       - id: ruff
         args:
           - --fix
   - repo: https://github.com/psf/black
-    rev: 23.11.0
+    rev: 23.12.1
     hooks:
       - id: black
         args:
@@ -24,7 +24,7 @@ repos:
         exclude_types: [csv, json]
         exclude: ^test/responses/
   - repo: https://github.com/pre-commit/mirrors-mypy
-    rev: v1.7.0
+    rev: v1.8.0
     hooks: 
       - id: mypy
         name: mypy
diff --git a/bimmer_connected/account.py b/bimmer_connected/account.py
index 0f3d2da..dc1f466 100644
--- a/bimmer_connected/account.py
+++ b/bimmer_connected/account.py
@@ -6,14 +6,14 @@ import logging
 from dataclasses import InitVar, dataclass, field
 from typing import List, Optional
 
-import httpx
-
 from bimmer_connected.api.authentication import MyBMWAuthentication
 from bimmer_connected.api.client import RESPONSE_STORE, MyBMWClient, MyBMWClientConfiguration
 from bimmer_connected.api.regions import Regions
 from bimmer_connected.const import (
+    ATTR_ATTRIBUTES,
     ATTR_CAPABILITIES,
     VEHICLE_CHARGING_DETAILS_URL,
+    VEHICLE_PROFILE_URL,
     VEHICLE_STATE_URL,
     VEHICLES_URL,
     CarBrands,
@@ -76,18 +76,24 @@ class MyBMWAccount:
         fetched_at = datetime.datetime.now(datetime.timezone.utc)
 
         async with MyBMWClient(self.config) as client:
-            vehicles_responses: List[httpx.Response] = [
-                await client.get(
+            for brand in CarBrands:
+                request_headers = client.generate_default_header(brand)
+                vehicle_list_response = await client.post(
                     VEHICLES_URL,
-                    headers={
-                        **client.generate_default_header(brand),
-                    },
+                    headers=request_headers,
                 )
-                for brand in CarBrands
-            ]
 
-            for response in vehicles_responses:
-                for vehicle_base in response.json():
+                for vehicle in vehicle_list_response.json()["mappingInfos"]:
+                    vehicle_profile_response = await client.get(
+                        VEHICLE_PROFILE_URL, headers=dict(request_headers, **{"bmw-vin": vehicle["vin"]})
+                    )
+                    vehicle_profile = vehicle_profile_response.json()
+
+                    vehicle_base = dict(
+                        {ATTR_ATTRIBUTES: {k: v for k, v in vehicle_profile.items() if k != "vin"}},
+                        **{"vin": vehicle_profile["vin"]}
+                    )
+
                     self.add_vehicle(vehicle_base, None, None, fetched_at)
 
     async def get_vehicles(self, force_init: bool = False) -> None:
diff --git a/bimmer_connected/api/authentication.py b/bimmer_connected/api/authentication.py
index ceca479..66c5469 100644
--- a/bimmer_connected/api/authentication.py
+++ b/bimmer_connected/api/authentication.py
@@ -164,16 +164,17 @@ class MyBMWAuthentication(httpx.Auth):
             code_challenge = create_s256_code_challenge(code_verifier)
 
             state = generate_token(22)
+            nonce = generate_token(22)
 
             # Set up authenticate endpoint
             authenticate_url = oauth_settings["tokenEndpoint"].replace("/token", "/authenticate")
             oauth_base_values = {
                 "client_id": oauth_settings["clientId"],
                 "response_type": "code",
+                "scope": " ".join(oauth_settings["scopes"]),
                 "redirect_uri": oauth_settings["returnUrl"],
                 "state": state,
-                "nonce": "login_nonce",
-                "scope": " ".join(oauth_settings["scopes"]),
+                "nonce": nonce,
                 "code_challenge": code_challenge,
                 "code_challenge_method": "S256",
             }
diff --git a/bimmer_connected/api/client.py b/bimmer_connected/api/client.py
index 5c1fa24..007cc49 100644
--- a/bimmer_connected/api/client.py
+++ b/bimmer_connected/api/client.py
@@ -81,6 +81,7 @@ class MyBMWClient(httpx.AsyncClient):
         return {
             "accept": "application/json",
             "accept-language": "en",
+            "x-raw-locale": "en-US",
             "user-agent": get_user_agent(self.config.authentication.region),
             "x-user-agent": X_USER_AGENT.format(
                 brand=(brand or CarBrands.BMW).value,
@@ -88,6 +89,6 @@ class MyBMWClient(httpx.AsyncClient):
                 region=self.config.authentication.region.value,
             ),
             **get_correlation_id(),
-            "bmw-units-preferences": "d=KM;v=L",
+            "bmw-units-preferences": "d=KM;v=L;p=B;ec=KWH100KM;fc=L100KM;em=GKM;",
             "24-hour-format": "true",
         }
diff --git a/bimmer_connected/api/utils.py b/bimmer_connected/api/utils.py
index b8148fa..2b8f978 100644
--- a/bimmer_connected/api/utils.py
+++ b/bimmer_connected/api/utils.py
@@ -23,7 +23,7 @@ from Crypto.Util.Padding import pad
 from bimmer_connected.models import AnonymizedResponse, MyBMWAPIError, MyBMWAuthError, MyBMWQuotaError
 
 UNICODE_CHARACTER_SET = string.ascii_letters + string.digits + "-._~"
-RE_VIN = re.compile(r"(?P<vin>WB[a-zA-Z0-9]{15})")
+RE_VIN = re.compile(r"(?P<vin>\b[(A-H|J-N|P|R-Z|0-9)]{17}\b)")
 ANONYMIZED_VINS: Dict[str, str] = {}
 
 
diff --git a/bimmer_connected/const.py b/bimmer_connected/const.py
index ad2a898..3dde449 100644
--- a/bimmer_connected/const.py
+++ b/bimmer_connected/const.py
@@ -37,17 +37,17 @@ OCP_APIM_KEYS = {
 }
 
 APP_VERSIONS = {
-    Regions.NORTH_AMERICA: "3.9.0(27760)",
-    Regions.REST_OF_WORLD: "3.9.0(27760)",
-    Regions.CHINA: "3.6.1(23634)",
+    Regions.NORTH_AMERICA: "3.11.1(29513)",
+    Regions.REST_OF_WORLD: "3.11.1(29513)",
+    Regions.CHINA: "3.11.1(29513)",
 }
 
 HTTPX_TIMEOUT = 30.0
 
 USER_AGENTS = {
-    Regions.NORTH_AMERICA: "Dart/2.19 (dart:io)",
-    Regions.REST_OF_WORLD: "Dart/2.19 (dart:io)",
-    Regions.CHINA: "Dart/2.18 (dart:io)",
+    Regions.NORTH_AMERICA: "Dart/3.0 (dart:io)",
+    Regions.REST_OF_WORLD: "Dart/3.0 (dart:io)",
+    Regions.CHINA: "Dart/3.0 (dart:io)",
 }
 X_USER_AGENT = "android(TQ2A.230405.003.B2);{brand};{app_version};{region}"
 
@@ -60,8 +60,9 @@ AUTH_CHINA_CAPTCHA_CHECK_URL = "/eadrax-coas/v1/cop/check-captcha"
 
 OAUTH_CONFIG_URL = "/eadrax-ucs/v1/presentation/oauth/config"
 
-VEHICLES_URL = "/eadrax-vcs/v4/vehicles"
-VEHICLE_STATE_URL = VEHICLES_URL + "/state"
+VEHICLES_URL = "/eadrax-vcs/v5/vehicle-list"
+VEHICLE_PROFILE_URL = "/eadrax-vcs/v5/vehicle-data/profile"
+VEHICLE_STATE_URL = "/eadrax-vcs/v4/vehicles/state"
 
 REMOTE_SERVICE_BASE_URL = "/eadrax-vrccs/v3/presentation/remote-commands"
 REMOTE_SERVICE_URL = REMOTE_SERVICE_BASE_URL + "/{vin}/{service_type}"
@@ -74,7 +75,7 @@ VEHICLE_CHARGING_SETTINGS_SET_URL = VEHICLE_CHARGING_BASE_URL + "/charging-setti
 VEHICLE_CHARGING_PROFILE_SET_URL = VEHICLE_CHARGING_BASE_URL + "/charging-profile"
 VEHICLE_CHARGING_START_STOP_URL = VEHICLE_CHARGING_BASE_URL + "/{service_type}"
 
-VEHICLE_IMAGE_URL = "/eadrax-ics/v3/presentation/vehicles/{vin}/images?carView={view}"
+VEHICLE_IMAGE_URL = "/eadrax-ics/v5/presentation/vehicles/images"
 VEHICLE_POI_URL = "/eadrax-dcs/v1/send-to-car/send-to-car"
 
 VEHICLE_CHARGING_STATISTICS_URL = "/eadrax-chs/v1/charging-statistics"
diff --git a/bimmer_connected/models.py b/bimmer_connected/models.py
index b1de927..cd01ff3 100644
--- a/bimmer_connected/models.py
+++ b/bimmer_connected/models.py
@@ -141,10 +141,10 @@ class PointOfInterest:
     def __post_init__(self, lat, lon, street, postal_code, city, country):
         self.coordinates = GPSPosition(lat, lon)
 
-        self.locationAddress = PointOfInterestAddress(street, postal_code, city, country)
+        self.locationAddress = PointOfInterestAddress(str(street), str(postal_code), str(city), str(country))
 
         if not self.formattedAddress:
-            self.formattedAddress = ", ".join([i for i in [street, postal_code, city] if i]) or "Coordinates only"
+            self.formattedAddress = ", ".join([str(i) for i in [street, postal_code, city] if i]) or "Coordinates only"
 
 
 class ValueWithUnit(NamedTuple):
diff --git a/bimmer_connected/vehicle/vehicle.py b/bimmer_connected/vehicle/vehicle.py
index 6a783f2..be2bb6a 100644
--- a/bimmer_connected/vehicle/vehicle.py
+++ b/bimmer_connected/vehicle/vehicle.py
@@ -351,11 +351,11 @@ class MyBMWVehicle:
 
         :returns bytes containing the image in PNG format.
         """
-        url = VEHICLE_IMAGE_URL.format(
-            vin=self.vin,
-            view=direction.value,
-        )
         # the accept field of the header needs to be updated as we want a png not the usual JSON
         async with MyBMWClient(self.account.config, brand=self.brand) as client:
-            response = await client.get(url, headers={"accept": "image/png"})
+            response = await client.get(
+                VEHICLE_IMAGE_URL,
+                params={"carView": direction.value, "toCrop": True},
+                headers={"accept": "image/png", "bmw-app-vehicle-type": "connected", "bmw-vin": self.vin},
+            )
         return response.content


Test patch:
diff --git a/bimmer_connected/tests/__init__.py b/bimmer_connected/tests/__init__.py
index 39a7f5e..d7fe4dd 100644
--- a/bimmer_connected/tests/__init__.py
+++ b/bimmer_connected/tests/__init__.py
@@ -2,7 +2,7 @@
 
 import json
 from pathlib import Path
-from typing import Any, Dict, List, Union
+from typing import Any, Dict, Union
 
 from bimmer_connected.api.regions import Regions
 from bimmer_connected.const import CarBrands
@@ -23,7 +23,8 @@ VIN_I01_NOREX = "WBY000000NOREXI01"
 VIN_I01_REX = "WBY00000000REXI01"
 VIN_I20 = "WBA00000000DEMO01"
 
-ALL_VEHICLES: Dict[str, List[Dict]] = {brand.value: [] for brand in CarBrands}
+ALL_VEHICLES: Dict[str, Dict] = {brand.value: {} for brand in CarBrands}
+ALL_PROFILES: Dict[str, Dict] = {}
 ALL_STATES: Dict[str, Dict] = {}
 ALL_CHARGING_SETTINGS: Dict[str, Dict] = {}
 
@@ -35,14 +36,18 @@ REMOTE_SERVICE_RESPONSE_ERROR = RESPONSE_DIR / "remote_services" / "eadrax_servi
 REMOTE_SERVICE_RESPONSE_EVENTPOSITION = RESPONSE_DIR / "remote_services" / "eadrax_service_eventposition.json"
 
 
-def get_fingerprint_state_count() -> int:
-    """Return number of loaded vehicles."""
-    return sum([len(vehicles) for vehicles in ALL_VEHICLES.values()])
+def get_fingerprint_count(type: str) -> int:
+    """Return number of requests/fingerprints for a given type."""
 
-
-def get_fingerprint_charging_settings_count() -> int:
-    """Return number of loaded vehicles."""
-    return len(ALL_CHARGING_SETTINGS)
+    if type == "vehicles":
+        return len(CarBrands)
+    if type == "states":
+        return len(ALL_STATES)
+    if type == "profiles":
+        return len(ALL_PROFILES)
+    if type == "charging_settings":
+        return len(ALL_CHARGING_SETTINGS)
+    return 0
 
 
 def load_response(path: Union[Path, str]) -> Any:
@@ -53,10 +58,17 @@ def load_response(path: Union[Path, str]) -> Any:
         return file.read().decode("UTF-8")
 
 
-for fingerprint in RESPONSE_DIR.rglob("*-eadrax-vcs_v4_vehicles.json"):
+for fingerprint in RESPONSE_DIR.rglob("*-eadrax-vcs_v5_vehicle-list.json"):
     brand = fingerprint.stem.split("-")[0]
-    for vehicle in load_response(fingerprint):
-        ALL_VEHICLES[brand].append(vehicle)
+    response = load_response(fingerprint)
+
+    if ALL_VEHICLES[brand].get("mappingInfos"):
+        ALL_VEHICLES[brand]["mappingInfos"].extend(response["mappingInfos"])
+    else:
+        ALL_VEHICLES[brand] = response
+
+for profile in RESPONSE_DIR.rglob("*-eadrax-vcs_v5_vehicle-data_profile_*.json"):
+    ALL_PROFILES[profile.stem.split("_")[-1]] = load_response(profile)
 
 for state in RESPONSE_DIR.rglob("*-eadrax-vcs_v4_vehicles_state_*.json"):
     ALL_STATES[state.stem.split("_")[-1]] = load_response(state)
diff --git a/bimmer_connected/tests/common.py b/bimmer_connected/tests/common.py
index 31d30ab..8989065 100644
--- a/bimmer_connected/tests/common.py
+++ b/bimmer_connected/tests/common.py
@@ -61,12 +61,14 @@ class MyBMWMockRouter(respx.MockRouter):
     def __init__(
         self,
         vehicles_to_load: Optional[List[str]] = None,
+        profiles: Optional[Dict[str, Dict]] = None,
         states: Optional[Dict[str, Dict]] = None,
         charging_settings: Optional[Dict[str, Dict]] = None,
     ) -> None:
         """Initialize the MyBMWMockRouter with clean responses."""
         super().__init__(assert_all_called=False)
         self.vehicles_to_load = vehicles_to_load or []
+        self.profiles = deepcopy(profiles) if profiles else {}
         self.states = deepcopy(states) if states else {}
         self.charging_settings = deepcopy(charging_settings) if charging_settings else {}
 
@@ -110,7 +112,8 @@ class MyBMWMockRouter(respx.MockRouter):
     def add_vehicle_routes(self) -> None:
         """Add routes for vehicle requests."""
 
-        self.get("/eadrax-vcs/v4/vehicles").mock(side_effect=self.vehicles_sideeffect)
+        self.post("/eadrax-vcs/v5/vehicle-list").mock(side_effect=self.vehicles_sideeffect)
+        self.get("/eadrax-vcs/v5/vehicle-data/profile").mock(side_effect=self.vehicle_profile_sideeffect)
         self.get("/eadrax-vcs/v4/vehicles/state", name="state").mock(side_effect=self.vehicle_state_sideeffect)
         self.get("/eadrax-crccs/v2/vehicles").mock(side_effect=self.vehicle_charging_settings_sideeffect)
 
@@ -171,15 +174,27 @@ class MyBMWMockRouter(respx.MockRouter):
         # Test if given region is valid
         _ = Regions(x_user_agent[3])
 
-        fingerprints = ALL_VEHICLES.get(brand, [])
+        fingerprints = deepcopy(ALL_VEHICLES.get(brand, {"mappingInfos": []}))
         if self.vehicles_to_load:
-            fingerprints = [f for f in fingerprints if f["vin"] in self.vehicles_to_load]
+            fingerprints["mappingInfos"] = [
+                f for f in fingerprints["mappingInfos"] if f["vin"] in self.vehicles_to_load
+            ]
 
         # Ensure order
-        fingerprints = sorted(fingerprints, key=lambda v: v["vin"])
+        fingerprints["mappingInfos"] = sorted(fingerprints["mappingInfos"], key=lambda v: v["vin"])
 
         return httpx.Response(200, json=fingerprints)
 
+    def vehicle_profile_sideeffect(self, request: httpx.Request) -> httpx.Response:
+        """Return /vehicle-data/profile response based on vin."""
+        x_user_agent = request.headers.get("x-user-agent", "").split(";")
+        assert len(x_user_agent) == 4
+
+        try:
+            return httpx.Response(200, json=self.profiles[request.headers["bmw-vin"]])
+        except KeyError:
+            return httpx.Response(404)
+
     def vehicle_state_sideeffect(self, request: httpx.Request) -> httpx.Response:
         """Return /vehicles response based on x-user-agent."""
         x_user_agent = request.headers.get("x-user-agent", "").split(";")
diff --git a/bimmer_connected/tests/conftest.py b/bimmer_connected/tests/conftest.py
index 035ad90..ca9532b 100644
--- a/bimmer_connected/tests/conftest.py
+++ b/bimmer_connected/tests/conftest.py
@@ -11,6 +11,7 @@ from bimmer_connected.models import AnonymizedResponse
 
 from . import (
     ALL_CHARGING_SETTINGS,
+    ALL_PROFILES,
     ALL_STATES,
     TEST_PASSWORD,
     TEST_REGION,
@@ -25,6 +26,7 @@ def bmw_fixture(request: pytest.FixtureRequest) -> Generator[respx.MockRouter, N
     # Now we can start patching the API calls
     router = MyBMWMockRouter(
         vehicles_to_load=getattr(request, "param", []),
+        profiles=ALL_PROFILES,
         states=ALL_STATES,
         charging_settings=ALL_CHARGING_SETTINGS,
     )
diff --git a/bimmer_connected/tests/responses/F31/bmw-eadrax-vcs_v4_vehicles.json b/bimmer_connected/tests/responses/F31/bmw-eadrax-vcs_v4_vehicles.json
deleted file mode 100644
index d7bd309..0000000
--- a/bimmer_connected/tests/responses/F31/bmw-eadrax-vcs_v4_vehicles.json
+++ /dev/null
@@ -1,45 +0,0 @@
-[
-    {
-        "appVehicleType": "CONNECTED",
-        "attributes": {
-            "a4aType": "USB_ONLY",
-            "bodyType": "F31",
-            "brand": "BMW",
-            "color": 4281545523,
-            "countryOfOrigin": "DE",
-            "driveTrain": "COMBUSTION",
-            "driverGuideInfo": {
-                "androidAppScheme": "com.bmwgroup.driversguide.row",
-                "androidStoreUrl": "https://play.google.com/store/apps/details?id=com.bmwgroup.driversguide.row",
-                "iosAppScheme": "bmwdriversguide:///open",
-                "iosStoreUrl": "https://apps.apple.com/de/app/id714042749?mt=8"
-            },
-            "headUnitType": "NBT",
-            "hmiVersion": "ID4",
-            "lastFetched": "2022-06-01T19:18:52.940Z",
-            "model": "320d xDrive",
-            "softwareVersionCurrent": {
-                "iStep": 502,
-                "puStep": {
-                    "month": 11,
-                    "year": 13
-                },
-                "seriesCluster": "F020"
-            },
-            "softwareVersionExFactory": {
-                "iStep": 502,
-                "puStep": {
-                    "month": 11,
-                    "year": 13
-                },
-                "seriesCluster": "F020"
-            },
-            "year": 2013
-        },
-        "mappingInfo": {
-            "isPrimaryUser": true,
-            "mappingStatus": "CONFIRMED"
-        },
-        "vin": "WBA00000000000F31"
-    }
-]
\ No newline at end of file
diff --git a/bimmer_connected/tests/responses/F31/bmw-eadrax-vcs_v4_vehicles_state_WBA00000000000F31.json b/bimmer_connected/tests/responses/F31/bmw-eadrax-vcs_v4_vehicles_state_WBA00000000000F31.json
index 2361fba..15668a3 100644
--- a/bimmer_connected/tests/responses/F31/bmw-eadrax-vcs_v4_vehicles_state_WBA00000000000F31.json
+++ b/bimmer_connected/tests/responses/F31/bmw-eadrax-vcs_v4_vehicles_state_WBA00000000000F31.json
@@ -1,13 +1,15 @@
 {
     "capabilities": {
         "a4aType": "USB_ONLY",
-        "checkSustainabilityDPP": false,
+        "alarmSystem": false,
         "climateFunction": "VENTILATION",
         "climateNow": true,
         "climateTimerTrigger": "START_TIMER",
         "digitalKey": {
             "bookedServicePackage": "NONE",
-            "state": "NOT_AVAILABLE"
+            "isDigitalKeyFirstSupported": false,
+            "state": "NOT_AVAILABLE",
+            "vehicleSoftwareUpgradeRequired": false
         },
         "horn": true,
         "isBmwChargingSupported": false,
@@ -27,9 +29,12 @@
         "isDataPrivacyEnabled": false,
         "isEasyChargeEnabled": false,
         "isEvGoChargingSupported": false,
+        "isLocationBasedChargingSettingsSupported": false,
         "isMiniChargingSupported": false,
         "isNonLscFeatureEnabled": true,
+        "isOptimizedChargingSupported": false,
         "isPersonalPictureUploadSupported": false,
+        "isPlugAndChargeSupported": false,
         "isRemoteEngineStartSupported": false,
         "isRemoteHistoryDeletionSupported": false,
         "isRemoteHistorySupported": true,
@@ -46,7 +51,7 @@
         "sendPoi": true,
         "specialThemeSupport": [],
         "unlock": true,
-        "vehicleFinder": true,
+        "vehicleFinder": false,
         "vehicleStateSource": "A4A"
     },
     "state": {
@@ -59,76 +64,44 @@
         "climateTimers": [
             {
                 "departureTime": {
-                    "hour": 6,
-                    "minute": 40
+                    "hour": 7,
+                    "minute": 0
                 },
-                "isWeeklyTimer": true,
-                "timerAction": "ACTIVATE",
-                "timerWeekDays": [
-                    "THURSDAY",
-                    "SUNDAY"
-                ]
+                "isWeeklyTimer": false,
+                "timerAction": "DEACTIVATE",
+                "timerWeekDays": []
             },
             {
                 "departureTime": {
-                    "hour": 12,
-                    "minute": 50
+                    "hour": 7,
+                    "minute": 0
                 },
-                "isWeeklyTimer": false,
-                "timerAction": "ACTIVATE",
+                "isWeeklyTimer": true,
+                "timerAction": "DEACTIVATE",
                 "timerWeekDays": [
                     "MONDAY"
                 ]
             },
             {
                 "departureTime": {
-                    "hour": 18,
-                    "minute": 59
+                    "hour": 7,
+                    "minute": 0
                 },
                 "isWeeklyTimer": true,
                 "timerAction": "DEACTIVATE",
                 "timerWeekDays": [
-                    "WEDNESDAY"
+                    "MONDAY"
                 ]
             }
         ],
-        "combustionFuelLevel": {
-            "remainingFuelLiters": 14
-        },
         "driverPreferences": {
             "lscPrivacyMode": "OFF"
         },
         "isLeftSteering": true,
         "isLscSupported": false,
-        "lastFetched": "2022-06-01T19:18:54.528Z",
-        "lastUpdatedAt": "2021-11-01T16:02:44Z",
-        "requiredServices": [
-            {
-                "dateTime": "2021-11-01T00:00:00.000Z",
-                "description": "Wechsel demnächst fällig. Bitte Termin mit Ihrem Servicepartner vereinbaren.",
-                "status": "PENDING",
-                "type": "BRAKE_FLUID"
-            },
-            {
-                "dateTime": "2022-07-01T00:00:00.000Z",
-                "description": "Nächster Service nach der angegebenen Fahrstrecke oder zum angegebenen Termin.",
-                "mileage": 9000,
-                "status": "OK",
-                "type": "OIL"
-            },
-            {
-                "dateTime": "2022-07-01T00:00:00.000Z",
-                "description": "Nächste Sichtprüfung nach der angegebenen Fahrstrecke oder zum angegebenen Termin.",
-                "mileage": 9000,
-                "status": "OK",
-                "type": "VEHICLE_CHECK"
-            },
-            {
-                "dateTime": "2023-02-01T00:00:00.000Z",
-                "description": "Nächste gesetzliche Fahrzeuguntersuchung zum angegebenen Termin.",
-                "status": "OK",
-                "type": "VEHICLE_TUV"
-            }
-        ]
+        "lastFetched": "2024-01-20T10:18:57.283Z",
+        "lastUpdatedAt": "0001-01-01T00:00:00Z",
+        "requiredServices": [],
+        "securityOverviewMode": null
     }
 }
\ No newline at end of file
diff --git a/bimmer_connected/tests/responses/F31/bmw-eadrax-vcs_v5_vehicle-data_profile_WBA00000000000F31.json b/bimmer_connected/tests/responses/F31/bmw-eadrax-vcs_v5_vehicle-data_profile_WBA00000000000F31.json
new file mode 100644
index 0000000..1679d71
--- /dev/null
+++ b/bimmer_connected/tests/responses/F31/bmw-eadrax-vcs_v5_vehicle-data_profile_WBA00000000000F31.json
@@ -0,0 +1,35 @@
+{
+    "bodyType": "F31",
+    "brand": "BMW",
+    "color": 4281545523,
+    "countryOfOrigin": "DE",
+    "driveTrain": "COMBUSTION",
+    "driverGuideInfo": {
+        "androidAppScheme": "com.bmwgroup.driversguide.row",
+        "androidStoreUrl": "https://play.google.com/store/apps/details?id=com.bmwgroup.driversguide.row",
+        "iosAppScheme": "bmwdriversguide:///open",
+        "iosStoreUrl": "https://apps.apple.com/de/app/id714042749?mt=8"
+    },
+    "headUnitRaw": "NBT",
+    "headUnitType": "NBT",
+    "hmiVersion": "ID4",
+    "model": "320d xDrive",
+    "softwareVersionCurrent": {
+        "iStep": 502,
+        "puStep": {
+            "month": 11,
+            "year": 13
+        },
+        "seriesCluster": "F020"
+    },
+    "softwareVersionExFactory": {
+        "iStep": 502,
+        "puStep": {
+            "month": 11,
+            "year": 13
+        },
+        "seriesCluster": "F020"
+    },
+    "vin": "WBA00000000000F31",
+    "year": 2013
+}
\ No newline at end of file
diff --git a/bimmer_connected/tests/responses/F31/bmw-eadrax-vcs_v5_vehicle-list.json b/bimmer_connected/tests/responses/F31/bmw-eadrax-vcs_v5_vehicle-list.json
new file mode 100644
index 0000000..6fe787c
--- /dev/null
+++ b/bimmer_connected/tests/responses/F31/bmw-eadrax-vcs_v5_vehicle-list.json
@@ -0,0 +1,13 @@
+{
+    "gcid": "ceb64158-d2ca-47e9-9ee6-cbffb881434e",
+    "mappingInfos": [
+        {
+            "isAssociated": false,
+            "isLmmEnabled": false,
+            "isPrimaryUser": true,
+            "mappingStatus": "CONFIRMED",
+            "vehicleMappingType": "CONNECTED",
+            "vin": "WBA00000000000F31"
+        }
+    ]
+}
\ No newline at end of file
diff --git a/bimmer_connected/tests/responses/G01/bmw-eadrax-vcs_v4_vehicles.json b/bimmer_connected/tests/responses/G01/bmw-eadrax-vcs_v4_vehicles.json
deleted file mode 100644
index 787623b..0000000
--- a/bimmer_connected/tests/responses/G01/bmw-eadrax-vcs_v4_vehicles.json
+++ /dev/null
@@ -1,32 +0,0 @@
-[
-    {
-        "appVehicleType": "DEMO",
-        "attributes": {
-            "a4aType": "BLUETOOTH",
-            "bodyType": "G01",
-            "brand": "BMW",
-            "color": 4284900966,
-            "countryOfOrigin": "DE",
-            "driveTrain": "PLUGIN_HYBRID",
-            "driverGuideInfo": {
-                "androidAppScheme": "com.bmwgroup.driversguide.row",
-                "androidStoreUrl": "https://play.google.com/store/apps/details?id=com.bmwgroup.driversguide.row",
-                "iosAppScheme": "bmwdriversguide:///open",
-                "iosStoreUrl": "https://apps.apple.com/de/app/id714042749?mt=8"
-            },
-            "headUnitRaw": "MGU",
-            "hmiVersion": "ID7",
-            "lastFetched": "2023-01-04T14:57:06.019Z",
-            "model": "X3 xDrive30e",
-            "year": 2021
-        },
-        "mappingInfo": {
-            "isAssociated": false,
-            "isLmmEnabled": false,
-            "isPrimaryUser": true,
-            "lmmStatusReasons": [],
-            "mappingStatus": "CONFIRMED"
-        },
-        "vin": "WBA00000000DEMO04"
-    }
-]
\ No newline at end of file
diff --git a/bimmer_connected/tests/responses/G01/bmw-eadrax-vcs_v5_vehicle-data_profile_WBA00000000DEMO04.json b/bimmer_connected/tests/responses/G01/bmw-eadrax-vcs_v5_vehicle-data_profile_WBA00000000DEMO04.json
new file mode 100644
index 0000000..dd76b4d
--- /dev/null
+++ b/bimmer_connected/tests/responses/G01/bmw-eadrax-vcs_v5_vehicle-data_profile_WBA00000000DEMO04.json
@@ -0,0 +1,18 @@
+{
+    "bodyType": "G01",
+    "brand": "BMW",
+    "color": 4284900966,
+    "countryOfOrigin": "DE",
+    "driveTrain": "PLUGIN_HYBRID",
+    "driverGuideInfo": {
+        "androidAppScheme": "com.bmwgroup.driversguide.row",
+        "androidStoreUrl": "https://play.google.com/store/apps/details?id=com.bmwgroup.driversguide.row",
+        "iosAppScheme": "bmwdriversguide:///open",
+        "iosStoreUrl": "https://apps.apple.com/de/app/id714042749?mt=8"
+    },
+    "headUnitRaw": "MGU",
+    "hmiVersion": "ID7",
+    "model": "X3 xDrive30e",
+    "vin": "WBA00000000DEMO04",
+    "year": 2021
+}
\ No newline at end of file
diff --git a/bimmer_connected/tests/responses/G01/bmw-eadrax-vcs_v5_vehicle-list.json b/bimmer_connected/tests/responses/G01/bmw-eadrax-vcs_v5_vehicle-list.json
new file mode 100644
index 0000000..f2f0b32
--- /dev/null
+++ b/bimmer_connected/tests/responses/G01/bmw-eadrax-vcs_v5_vehicle-list.json
@@ -0,0 +1,13 @@
+{
+    "gcid": "ceb64158-d2ca-47e9-9ee6-cbffb881434e",
+    "mappingInfos": [
+        {
+            "isAssociated": false,
+            "isLmmEnabled": false,
+            "isPrimaryUser": true,
+            "mappingStatus": "CONFIRMED",
+            "vehicleMappingType": "CONNECTED",
+            "vin": "WBA00000000DEMO04"
+        }
+    ]
+}
\ No newline at end of file
diff --git a/bimmer_connected/tests/responses/G20/bmw-eadrax-vcs_v4_vehicles.json b/bimmer_connected/tests/responses/G20/bmw-eadrax-vcs_v4_vehicles.json
deleted file mode 100644
index 466c5da..0000000
--- a/bimmer_connected/tests/responses/G20/bmw-eadrax-vcs_v4_vehicles.json
+++ /dev/null
@@ -1,50 +0,0 @@
-[
-    {
-        "appVehicleType": "DEMO",
-        "attributes": {
-            "a4aType": "NOT_SUPPORTED",
-            "bodyType": "G20",
-            "brand": "BMW",
-            "color": 4280233344,
-            "countryOfOrigin": "PT",
-            "driveTrain": "COMBUSTION",
-            "driverGuideInfo": {
-                "androidAppScheme": "com.bmwgroup.driversguide.row",
-                "androidStoreUrl": "https://play.google.com/store/apps/details?id=com.bmwgroup.driversguide.row",
-                "iosAppScheme": "bmwdriversguide:///open",
-                "iosStoreUrl": "https://apps.apple.com/de/app/id714042749?mt=8"
-            },
-            "headUnitRaw": "HU_MGU",
-            "headUnitType": "MGU",
-            "hmiVersion": "ID7",
-            "lastFetched": "2023-01-04T14:57:06.019Z",
-            "model": "M340i xDrive",
-            "softwareVersionCurrent": {
-                "iStep": 470,
-                "puStep": {
-                    "month": 7,
-                    "year": 21
-                },
-                "seriesCluster": "S18A"
-            },
-            "softwareVersionExFactory": {
-                "iStep": 420,
-                "puStep": {
-                    "month": 7,
-                    "year": 20
-                },
-                "seriesCluster": "S18A"
-            },
-            "telematicsUnit": "ATM2",
-            "year": 2022
-        },
-        "mappingInfo": {
-            "isAssociated": false,
-            "isLmmEnabled": false,
-            "isPrimaryUser": true,
-            "lmmStatusReasons": [],
-            "mappingStatus": "CONFIRMED"
-        },
-        "vin": "WBA00000000DEMO03"
-    }
-]
\ No newline at end of file
diff --git a/bimmer_connected/tests/responses/G20/bmw-eadrax-vcs_v5_vehicle-data_profile_WBA00000000DEMO03.json b/bimmer_connected/tests/responses/G20/bmw-eadrax-vcs_v5_vehicle-data_profile_WBA00000000DEMO03.json
new file mode 100644
index 0000000..03d5e67
--- /dev/null
+++ b/bimmer_connected/tests/responses/G20/bmw-eadrax-vcs_v5_vehicle-data_profile_WBA00000000DEMO03.json
@@ -0,0 +1,36 @@
+{
+    "bodyType": "G20",
+    "brand": "BMW",
+    "color": 4280233344,
+    "countryOfOrigin": "PT",
+    "driveTrain": "COMBUSTION",
+    "driverGuideInfo": {
+        "androidAppScheme": "com.bmwgroup.driversguide.row",
+        "androidStoreUrl": "https://play.google.com/store/apps/details?id=com.bmwgroup.driversguide.row",
+        "iosAppScheme": "bmwdriversguide:///open",
+        "iosStoreUrl": "https://apps.apple.com/de/app/id714042749?mt=8"
+    },
+    "headUnitRaw": "HU_MGU",
+    "headUnitType": "MGU",
+    "hmiVersion": "ID7",
+    "model": "M340i xDrive",
+    "softwareVersionCurrent": {
+        "iStep": 470,
+        "puStep": {
+            "month": 7,
+            "year": 21
+        },
+        "seriesCluster": "S18A"
+    },
+    "softwareVersionExFactory": {
+        "iStep": 420,
+        "puStep": {
+            "month": 7,
+            "year": 20
+        },
+        "seriesCluster": "S18A"
+    },
+    "telematicsUnit": "ATM2",
+    "vin": "WBA00000000DEMO03",
+    "year": 2022
+}
\ No newline at end of file
diff --git a/bimmer_connected/tests/responses/G20/bmw-eadrax-vcs_v5_vehicle-list.json b/bimmer_connected/tests/responses/G20/bmw-eadrax-vcs_v5_vehicle-list.json
new file mode 100644
index 0000000..63aaa0d
--- /dev/null
+++ b/bimmer_connected/tests/responses/G20/bmw-eadrax-vcs_v5_vehicle-list.json
@@ -0,0 +1,13 @@
+{
+    "gcid": "ceb64158-d2ca-47e9-9ee6-cbffb881434e",
+    "mappingInfos": [
+        {
+            "isAssociated": false,
+            "isLmmEnabled": false,
+            "isPrimaryUser": true,
+            "mappingStatus": "CONFIRMED",
+            "vehicleMappingType": "CONNECTED",
+            "vin": "WBA00000000DEMO03"
+        }
+    ]
+}
\ No newline at end of file
diff --git a/bimmer_connected/tests/responses/G26/bmw-eadrax-vcs_v4_vehicles.json b/bimmer_connected/tests/responses/G26/bmw-eadrax-vcs_v4_vehicles.json
deleted file mode 100644
index e9dac06..0000000
--- a/bimmer_connected/tests/responses/G26/bmw-eadrax-vcs_v4_vehicles.json
+++ /dev/null
@@ -1,50 +0,0 @@
-[
-    {
-        "appVehicleType": "DEMO",
-        "attributes": {
-            "a4aType": "NOT_SUPPORTED",
-            "bodyType": "G26",
-            "brand": "BMW",
-            "color": 4284245350,
-            "countryOfOrigin": "DE",
-            "driveTrain": "ELECTRIC",
-            "driverGuideInfo": {
-                "androidAppScheme": "com.bmwgroup.driversguide.row",
-                "androidStoreUrl": "https://play.google.com/store/apps/details?id=com.bmwgroup.driversguide.row",
-                "iosAppScheme": "bmwdriversguide:///open",
-                "iosStoreUrl": "https://apps.apple.com/de/app/id714042749?mt=8"
-            },
-            "headUnitRaw": "HU_MGU",
-            "headUnitType": "MGU",
-            "hmiVersion": "ID8",
-            "lastFetched": "2023-01-04T14:57:06.019Z",
-            "model": "i4 eDrive40",
-            "softwareVersionCurrent": {
-                "iStep": 470,
-                "puStep": {
-                    "month": 11,
-                    "year": 21
-                },
-                "seriesCluster": "G026"
-            },
-            "softwareVersionExFactory": {
-                "iStep": 470,
-                "puStep": {
-                    "month": 11,
-                    "year": 21
-                },
-                "seriesCluster": "G026"
-            },
-            "telematicsUnit": "WAVE01",
-            "year": 2021
-        },
-        "mappingInfo": {
-            "isAssociated": false,
-            "isLmmEnabled": false,
-            "isPrimaryUser": true,
-            "lmmStatusReasons": [],
-            "mappingStatus": "CONFIRMED"
-        },
-        "vin": "WBA00000000DEMO02"
-    }
-]
\ No newline at end of file
diff --git a/bimmer_connected/tests/responses/G26/bmw-eadrax-vcs_v5_vehicle-data_profile_WBA00000000DEMO02.json b/bimmer_connected/tests/responses/G26/bmw-eadrax-vcs_v5_vehicle-data_profile_WBA00000000DEMO02.json
new file mode 100644
index 0000000..ee4f13d
--- /dev/null
+++ b/bimmer_connected/tests/responses/G26/bmw-eadrax-vcs_v5_vehicle-data_profile_WBA00000000DEMO02.json
@@ -0,0 +1,36 @@
+{
+    "bodyType": "G26",
+    "brand": "BMW",
+    "color": 4284245350,
+    "countryOfOrigin": "DE",
+    "driveTrain": "ELECTRIC",
+    "driverGuideInfo": {
+        "androidAppScheme": "com.bmwgroup.driversguide.row",
+        "androidStoreUrl": "https://play.google.com/store/apps/details?id=com.bmwgroup.driversguide.row",
+        "iosAppScheme": "bmwdriversguide:///open",
+        "iosStoreUrl": "https://apps.apple.com/de/app/id714042749?mt=8"
+    },
+    "headUnitRaw": "HU_MGU",
+    "headUnitType": "MGU",
+    "hmiVersion": "ID8",
+    "model": "i4 eDrive40",
+    "softwareVersionCurrent": {
+        "iStep": 470,
+        "puStep": {
+            "month": 11,
+            "year": 21
+        },
+        "seriesCluster": "G026"
+    },
+    "softwareVersionExFactory": {
+        "iStep": 470,
+        "puStep": {
+            "month": 11,
+            "year": 21
+        },
+        "seriesCluster": "G026"
+    },
+    "telematicsUnit": "WAVE01",
+    "vin": "WBA00000000DEMO02",
+    "year": 2021
+}
\ No newline at end of file
diff --git a/bimmer_connected/tests/responses/G26/bmw-eadrax-vcs_v5_vehicle-list.json b/bimmer_connected/tests/responses/G26/bmw-eadrax-vcs_v5_vehicle-list.json
new file mode 100644
index 0000000..762444b
--- /dev/null
+++ b/bimmer_connected/tests/responses/G26/bmw-eadrax-vcs_v5_vehicle-list.json
@@ -0,0 +1,13 @@
+{
+    "gcid": "ceb64158-d2ca-47e9-9ee6-cbffb881434e",
+    "mappingInfos": [
+        {
+            "isAssociated": false,
+            "isLmmEnabled": false,
+            "isPrimaryUser": true,
+            "mappingStatus": "CONFIRMED",
+            "vehicleMappingType": "CONNECTED",
+            "vin": "WBA00000000DEMO02"
+        }
+    ]
+}
\ No newline at end of file
diff --git a/bimmer_connected/tests/responses/G70/bmw-eadrax-vcs_v4_vehicles.json b/bimmer_connected/tests/responses/G70/bmw-eadrax-vcs_v4_vehicles.json
deleted file mode 100644
index afb1e1f..0000000
--- a/bimmer_connected/tests/responses/G70/bmw-eadrax-vcs_v4_vehicles.json
+++ /dev/null
@@ -1,50 +0,0 @@
-[
-    {
-        "appVehicleType": "DEMO",
-        "attributes": {
-            "a4aType": "BLUETOOTH",
-            "bodyType": "G70",
-            "brand": "BMW",
-            "color": 4284900182,
-            "countryOfOrigin": "DE",
-            "driveTrain": "ELECTRIC",
-            "driverGuideInfo": {
-                "androidAppScheme": "com.bmwgroup.driversguide.row",
-                "androidStoreUrl": "https://play.google.com/store/apps/details?id=com.bmwgroup.driversguide.row",
-                "iosAppScheme": "bmwdriversguide:///open",
-                "iosStoreUrl": "https://apps.apple.com/de/app/id714042749?mt=8"
-            },
-            "headUnitRaw": "MGU_02_L",
-            "headUnitType": "MGU",
-            "hmiVersion": "ID8",
-            "lastFetched": "2023-01-04T15:03:07.150Z",
-            "model": "i7 xDrive60",
-            "softwareVersionCurrent": {
-                "iStep": 505,
-                "puStep": {
-                    "month": 7,
-                    "year": 22
-                },
-                "seriesCluster": "G070"
-            },
-            "softwareVersionExFactory": {
-                "iStep": 450,
-                "puStep": {
-                    "month": 7,
-                    "year": 22
-                },
-                "seriesCluster": "G070"
-            },
-            "telematicsUnit": "WAVE01",
-            "year": 2022
-        },
-        "mappingInfo": {
-            "isAssociated": false,
-            "isLmmEnabled": false,
-            "isPrimaryUser": true,
-            "lmmStatusReasons": [],
-            "mappingStatus": "CONFIRMED"
-        },
-        "vin": "WBA00000000DEMO05"
-    }
-]
\ No newline at end of file
diff --git a/bimmer_connected/tests/responses/G70/bmw-eadrax-vcs_v5_vehicle-data_profile_WBA00000000DEMO05.json b/bimmer_connected/tests/responses/G70/bmw-eadrax-vcs_v5_vehicle-data_profile_WBA00000000DEMO05.json
new file mode 100644
index 0000000..b6273e6
--- /dev/null
+++ b/bimmer_connected/tests/responses/G70/bmw-eadrax-vcs_v5_vehicle-data_profile_WBA00000000DEMO05.json
@@ -0,0 +1,36 @@
+{
+    "bodyType": "G70",
+    "brand": "BMW",
+    "color": 4284900182,
+    "countryOfOrigin": "DE",
+    "driveTrain": "ELECTRIC",
+    "driverGuideInfo": {
+        "androidAppScheme": "com.bmwgroup.driversguide.row",
+        "androidStoreUrl": "https://play.google.com/store/apps/details?id=com.bmwgroup.driversguide.row",
+        "iosAppScheme": "bmwdriversguide:///open",
+        "iosStoreUrl": "https://apps.apple.com/de/app/id714042749?mt=8"
+    },
+    "headUnitRaw": "MGU_02_L",
+    "headUnitType": "MGU",
+    "hmiVersion": "ID8",
+    "model": "i7 xDrive60",
+    "softwareVersionCurrent": {
+        "iStep": 505,
+        "puStep": {
+            "month": 7,
+            "year": 22
+        },
+        "seriesCluster": "G070"
+    },
+    "softwareVersionExFactory": {
+        "iStep": 450,
+        "puStep": {
+            "month": 7,
+            "year": 22
+        },
+        "seriesCluster": "G070"
+    },
+    "telematicsUnit": "WAVE01",
+    "vin": "WBA00000000DEMO05",
+    "year": 2022
+}
\ No newline at end of file
diff --git a/bimmer_connected/tests/responses/G70/bmw-eadrax-vcs_v5_vehicle-list.json b/bimmer_connected/tests/responses/G70/bmw-eadrax-vcs_v5_vehicle-list.json
new file mode 100644
index 0000000..12aa8d4
--- /dev/null
+++ b/bimmer_connected/tests/responses/G70/bmw-eadrax-vcs_v5_vehicle-list.json
@@ -0,0 +1,13 @@
+{
+    "gcid": "ceb64158-d2ca-47e9-9ee6-cbffb881434e",
+    "mappingInfos": [
+        {
+            "isAssociated": false,
+            "isLmmEnabled": false,
+            "isPrimaryUser": true,
+            "mappingStatus": "CONFIRMED",
+            "vehicleMappingType": "CONNECTED",
+            "vin": "WBA00000000DEMO05"
+        }
+    ]
+}
\ No newline at end of file
diff --git a/bimmer_connected/tests/responses/I01_NOREX/bmw-eadrax-vcs_v4_vehicles.json b/bimmer_connected/tests/responses/I01_NOREX/bmw-eadrax-vcs_v4_vehicles.json
deleted file mode 100644
index a95c0b9..0000000
--- a/bimmer_connected/tests/responses/I01_NOREX/bmw-eadrax-vcs_v4_vehicles.json
+++ /dev/null
@@ -1,45 +0,0 @@
-[
-    {
-        "vin": "WBY000000NOREXI01",
-        "mappingInfo": {
-            "mappingStatus": "CONFIRMED",
-            "isPrimaryUser": true
-        },
-        "appVehicleType": "CONNECTED",
-        "attributes": {
-            "lastFetched": "2022-06-01T19:48:46.540Z",
-            "model": "i3",
-            "year": 2015,
-            "color": 4282858822,
-            "brand": "BMW_I",
-            "driveTrain": "ELECTRIC",
-            "headUnitType": "ENTRY",
-            "hmiVersion": "ID4",
-            "softwareVersionCurrent": {
-                "puStep": {
-                    "month": 3,
-                    "year": 21
-                },
-                "iStep": 530,
-                "seriesCluster": "I001"
-            },
-            "softwareVersionExFactory": {
-                "puStep": {
-                    "month": 7,
-                    "year": 15
-                },
-                "iStep": 502,
-                "seriesCluster": "I001"
-            },
-            "bodyType": "I01",
-            "countryOfOrigin": "CZ",
-            "a4aType": "USB_ONLY",
-            "driverGuideInfo": {
-                "androidAppScheme": "com.bmwgroup.driversguide.row",
-                "iosAppScheme": "bmwdriversguide:///open",
-                "androidStoreUrl": "https://play.google.com/store/apps/details?id=com.bmwgroup.driversguide.row",
-                "iosStoreUrl": "https://apps.apple.com/de/app/id714042749?mt=8"
-            }
-        }
-    }
-]
\ No newline at end of file
diff --git a/bimmer_connected/tests/responses/I01_NOREX/bmw-eadrax-vcs_v5_vehicle-data_profile_WBY000000NOREXI01.json b/bimmer_connected/tests/responses/I01_NOREX/bmw-eadrax-vcs_v5_vehicle-data_profile_WBY000000NOREXI01.json
new file mode 100644
index 0000000..2b05a94
--- /dev/null
+++ b/bimmer_connected/tests/responses/I01_NOREX/bmw-eadrax-vcs_v5_vehicle-data_profile_WBY000000NOREXI01.json
@@ -0,0 +1,36 @@
+{
+	"bodyType": "I01",
+	"brand": "BMW_I",
+	"color": 4282858822,
+	"countryOfOrigin": "CZ",
+	"driveTrain": "ELECTRIC",
+	"driverGuideInfo": {
+		"androidAppScheme": "com.bmwgroup.driversguide.row",
+		"iosAppScheme": "bmwdriversguide:///open",
+		"androidStoreUrl": "https://play.google.com/store/apps/details?id=com.bmwgroup.driversguide.row",
+		"iosStoreUrl": "https://apps.apple.com/de/app/id714042749?mt=8"
+	},
+	"headUnitRaw": "MGU_02_L",
+	"headUnitType": "ENTRY",
+	"hmiVersion": "ID4",
+	"model": "i3",
+	"softwareVersionCurrent": {
+		"puStep": {
+			"month": 3,
+			"year": 21
+		},
+		"iStep": 530,
+		"seriesCluster": "I001"
+	},
+	"softwareVersionExFactory": {
+		"puStep": {
+			"month": 7,
+			"year": 15
+		},
+		"iStep": 502,
+		"seriesCluster": "I001"
+	},
+	"telematicsUnit": "WAVE01",
+	"vin": "WBY000000NOREXI01",
+	"year": 2015
+}
\ No newline at end of file
diff --git a/bimmer_connected/tests/responses/I01_NOREX/bmw-eadrax-vcs_v5_vehicle-list.json b/bimmer_connected/tests/responses/I01_NOREX/bmw-eadrax-vcs_v5_vehicle-list.json
new file mode 100644
index 0000000..4f38487
--- /dev/null
+++ b/bimmer_connected/tests/responses/I01_NOREX/bmw-eadrax-vcs_v5_vehicle-list.json
@@ -0,0 +1,13 @@
+{
+    "gcid": "ceb64158-d2ca-47e9-9ee6-cbffb881434e",
+    "mappingInfos": [
+        {
+            "isAssociated": false,
+            "isLmmEnabled": false,
+            "isPrimaryUser": true,
+            "mappingStatus": "CONFIRMED",
+            "vehicleMappingType": "CONNECTED",
+            "vin": "WBY000000NOREXI01"
+        }
+    ]
+}
\ No newline at end of file
diff --git a/bimmer_connected/tests/responses/I01_REX/bmw-eadrax-vcs_v4_vehicles.json b/bimmer_connected/tests/responses/I01_REX/bmw-eadrax-vcs_v4_vehicles.json
deleted file mode 100644
index f0060ec..0000000
--- a/bimmer_connected/tests/responses/I01_REX/bmw-eadrax-vcs_v4_vehicles.json
+++ /dev/null
@@ -1,45 +0,0 @@
-[
-    {
-        "vin": "WBY00000000REXI01",
-        "mappingInfo": {
-            "mappingStatus": "CONFIRMED",
-            "isPrimaryUser": true
-        },
-        "appVehicleType": "CONNECTED",
-        "attributes": {
-            "lastFetched": "2022-06-01T19:48:46.540Z",
-            "model": "i3 (+ REX)",
-            "year": 2015,
-            "color": 4284110934,
-            "brand": "BMW_I",
-            "driveTrain": "ELECTRIC_WITH_RANGE_EXTENDER",
-            "headUnitType": "NBT",
-            "hmiVersion": "ID4",
-            "softwareVersionCurrent": {
-                "puStep": {
-                    "month": 11,
-                    "year": 21
-                },
-                "iStep": 510,
-                "seriesCluster": "I001"
-            },
-            "softwareVersionExFactory": {
-                "puStep": {
-                    "month": 3,
-                    "year": 15
-                },
-                "iStep": 502,
-                "seriesCluster": "I001"
-            },
-            "bodyType": "I01",
-            "countryOfOrigin": "CZ",
-            "a4aType": "USB_ONLY",
-            "driverGuideInfo": {
-                "androidAppScheme": "com.bmwgroup.driversguide.row",
-                "iosAppScheme": "bmwdriversguide:///open",
-                "androidStoreUrl": "https://play.google.com/store/apps/details?id=com.bmwgroup.driversguide.row",
-                "iosStoreUrl": "https://apps.apple.com/de/app/id714042749?mt=8"
-            }
-        }
-    }
-]
\ No newline at end of file
diff --git a/bimmer_connected/tests/responses/I01_REX/bmw-eadrax-vcs_v5_vehicle-data_profile_WBY00000000REXI01.json b/bimmer_connected/tests/responses/I01_REX/bmw-eadrax-vcs_v5_vehicle-data_profile_WBY00000000REXI01.json
new file mode 100644
index 0000000..db6f9e6
--- /dev/null
+++ b/bimmer_connected/tests/responses/I01_REX/bmw-eadrax-vcs_v5_vehicle-data_profile_WBY00000000REXI01.json
@@ -0,0 +1,36 @@
+{
+	"bodyType": "I01",
+	"brand": "BMW_I",
+	"color": 4284110934,
+	"countryOfOrigin": "CZ",
+	"driveTrain": "ELECTRIC_WITH_RANGE_EXTENDER",
+	"driverGuideInfo": {
+		"androidAppScheme": "com.bmwgroup.driversguide.row",
+		"iosAppScheme": "bmwdriversguide:///open",
+		"androidStoreUrl": "https://play.google.com/store/apps/details?id=com.bmwgroup.driversguide.row",
+		"iosStoreUrl": "https://apps.apple.com/de/app/id714042749?mt=8"
+	},
+	"headUnitRaw": "MGU_02_L",
+	"headUnitType": "NBT",
+	"hmiVersion": "ID4",
+	"model": "i3 (+ REX)",
+	"softwareVersionCurrent": {
+		"puStep": {
+			"month": 11,
+			"year": 21
+		},
+		"iStep": 510,
+		"seriesCluster": "I001"
+	},
+	"softwareVersionExFactory": {
+		"puStep": {
+			"month": 3,
+			"year": 15
+		},
+		"iStep": 502,
+		"seriesCluster": "I001"
+	},
+	"telematicsUnit": "WAVE01",
+	"vin": "WBY00000000REXI01",
+	"year": 2015
+}
\ No newline at end of file
diff --git a/bimmer_connected/tests/responses/I01_REX/bmw-eadrax-vcs_v5_vehicle-list.json b/bimmer_connected/tests/responses/I01_REX/bmw-eadrax-vcs_v5_vehicle-list.json
new file mode 100644
index 0000000..7182952
--- /dev/null
+++ b/bimmer_connected/tests/responses/I01_REX/bmw-eadrax-vcs_v5_vehicle-list.json
@@ -0,0 +1,13 @@
+{
+    "gcid": "ceb64158-d2ca-47e9-9ee6-cbffb881434e",
+    "mappingInfos": [
+        {
+            "isAssociated": false,
+            "isLmmEnabled": false,
+            "isPrimaryUser": true,
+            "mappingStatus": "CONFIRMED",
+            "vehicleMappingType": "CONNECTED",
+            "vin": "WBY00000000REXI01"
+        }
+    ]
+}
\ No newline at end of file
diff --git a/bimmer_connected/tests/responses/I20/bmw-eadrax-vcs_v4_vehicles.json b/bimmer_connected/tests/responses/I20/bmw-eadrax-vcs_v4_vehicles.json
deleted file mode 100644
index 480582d..0000000
--- a/bimmer_connected/tests/responses/I20/bmw-eadrax-vcs_v4_vehicles.json
+++ /dev/null
@@ -1,50 +0,0 @@
-[
-    {
-        "appVehicleType": "DEMO",
-        "attributes": {
-            "a4aType": "BLUETOOTH",
-            "bodyType": "I20",
-            "brand": "BMW_I",
-            "color": 4285537312,
-            "countryOfOrigin": "DE",
-            "driveTrain": "ELECTRIC",
-            "driverGuideInfo": {
-                "androidAppScheme": "com.bmwgroup.driversguide.row",
-                "androidStoreUrl": "https://play.google.com/store/apps/details?id=com.bmwgroup.driversguide.row",
-                "iosAppScheme": "bmwdriversguide:///open",
-                "iosStoreUrl": "https://apps.apple.com/de/app/id714042749?mt=8"
-            },
-            "headUnitRaw": "HU_MGU",
-            "headUnitType": "MGU",
-            "hmiVersion": "ID8",
-            "lastFetched": "2023-01-04T14:57:06.019Z",
-            "model": "iX xDrive50",
-            "softwareVersionCurrent": {
-                "iStep": 300,
-                "puStep": {
-                    "month": 7,
-                    "year": 21
-                },
-                "seriesCluster": "S21A"
-            },
-            "softwareVersionExFactory": {
-                "iStep": 300,
-                "puStep": {
-                    "month": 7,
-                    "year": 21
-                },
-                "seriesCluster": "S21A"
-            },
-            "telematicsUnit": "WAVE01",
-            "year": 2021
-        },
-        "mappingInfo": {
-            "isAssociated": false,
-            "isLmmEnabled": false,
-            "isPrimaryUser": true,
-            "lmmStatusReasons": [],
-            "mappingStatus": "CONFIRMED"
-        },
-        "vin": "WBA00000000DEMO01"
-    }
-]
\ No newline at end of file
diff --git a/bimmer_connected/tests/responses/I20/bmw-eadrax-vcs_v5_vehicle-data_profile_WBA00000000DEMO01.json b/bimmer_connected/tests/responses/I20/bmw-eadrax-vcs_v5_vehicle-data_profile_WBA00000000DEMO01.json
new file mode 100644
index 0000000..368ad94
--- /dev/null
+++ b/bimmer_connected/tests/responses/I20/bmw-eadrax-vcs_v5_vehicle-data_profile_WBA00000000DEMO01.json
@@ -0,0 +1,36 @@
+{
+    "bodyType": "I20",
+    "brand": "BMW_I",
+    "color": 4285537312,
+    "countryOfOrigin": "DE",
+    "driveTrain": "ELECTRIC",
+    "driverGuideInfo": {
+        "androidAppScheme": "com.bmwgroup.driversguide.row",
+        "androidStoreUrl": "https://play.google.com/store/apps/details?id=com.bmwgroup.driversguide.row",
+        "iosAppScheme": "bmwdriversguide:///open",
+        "iosStoreUrl": "https://apps.apple.com/de/app/id714042749?mt=8"
+    },
+    "headUnitRaw": "HU_MGU",
+    "headUnitType": "MGU",
+    "hmiVersion": "ID8",
+    "model": "iX xDrive50",
+    "softwareVersionCurrent": {
+        "iStep": 300,
+        "puStep": {
+            "month": 7,
+            "year": 21
+        },
+        "seriesCluster": "S21A"
+    },
+    "softwareVersionExFactory": {
+        "iStep": 300,
+        "puStep": {
+            "month": 7,
+            "year": 21
+        },
+        "seriesCluster": "S21A"
+    },
+    "telematicsUnit": "WAVE01",
+    "vin": "WBA00000000DEMO01",
+    "year": 2021
+}
\ No newline at end of file
diff --git a/bimmer_connected/tests/responses/I20/bmw-eadrax-vcs_v5_vehicle-list.json b/bimmer_connected/tests/responses/I20/bmw-eadrax-vcs_v5_vehicle-list.json
new file mode 100644
index 0000000..dbcbd26
--- /dev/null
+++ b/bimmer_connected/tests/responses/I20/bmw-eadrax-vcs_v5_vehicle-list.json
@@ -0,0 +1,13 @@
+{
+    "gcid": "ceb64158-d2ca-47e9-9ee6-cbffb881434e",
+    "mappingInfos": [
+        {
+            "isAssociated": false,
+            "isLmmEnabled": false,
+            "isPrimaryUser": true,
+            "mappingStatus": "CONFIRMED",
+            "vehicleMappingType": "CONNECTED",
+            "vin": "WBA00000000DEMO01"
+        }
+    ]
+}
\ No newline at end of file
diff --git a/bimmer_connected/tests/responses/bmw-eadrax-vcs_v5_vehicle-list.json b/bimmer_connected/tests/responses/bmw-eadrax-vcs_v5_vehicle-list.json
new file mode 100644
index 0000000..0c54692
--- /dev/null
+++ b/bimmer_connected/tests/responses/bmw-eadrax-vcs_v5_vehicle-list.json
@@ -0,0 +1,4 @@
+{
+    "gcid": "ceb64158-d2ca-47e9-9ee6-cbffb881434e",
+    "mappingInfos": []
+}
\ No newline at end of file
diff --git a/bimmer_connected/tests/responses/mini-eadrax-vcs_v5_vehicle-list.json b/bimmer_connected/tests/responses/mini-eadrax-vcs_v5_vehicle-list.json
new file mode 100644
index 0000000..0c54692
--- /dev/null
+++ b/bimmer_connected/tests/responses/mini-eadrax-vcs_v5_vehicle-list.json
@@ -0,0 +1,4 @@
+{
+    "gcid": "ceb64158-d2ca-47e9-9ee6-cbffb881434e",
+    "mappingInfos": []
+}
\ No newline at end of file
diff --git a/bimmer_connected/tests/test_account.py b/bimmer_connected/tests/test_account.py
index 609d616..c5067eb 100644
--- a/bimmer_connected/tests/test_account.py
+++ b/bimmer_connected/tests/test_account.py
@@ -13,7 +13,7 @@ from bimmer_connected.account import MyBMWAccount
 from bimmer_connected.api.authentication import MyBMWAuthentication, MyBMWLoginRetry
 from bimmer_connected.api.client import MyBMWClient
 from bimmer_connected.api.regions import get_region_from_name
-from bimmer_connected.const import ATTR_CAPABILITIES
+from bimmer_connected.const import ATTR_CAPABILITIES, VEHICLES_URL
 from bimmer_connected.models import GPSPosition, MyBMWAPIError, MyBMWAuthError, MyBMWQuotaError
 
 from . import (
@@ -24,8 +24,7 @@ from . import (
     TEST_USERNAME,
     VIN_G26,
     VIN_I20,
-    get_fingerprint_charging_settings_count,
-    get_fingerprint_state_count,
+    get_fingerprint_count,
     load_response,
 )
 from .conftest import prepare_account_with_vehicles
@@ -177,7 +176,7 @@ async def test_vehicles(bmw_fixture: respx.Router):
     await account.get_vehicles()
 
     assert account.config.authentication.access_token is not None
-    assert get_fingerprint_state_count() == len(account.vehicles)
+    assert get_fingerprint_count("profiles") == len(account.vehicles)
 
     vehicle = account.get_vehicle(VIN_G26)
     assert vehicle is not None
@@ -198,15 +197,15 @@ async def test_vehicle_init(bmw_fixture: respx.Router):
 
         # First call on init
         await account.get_vehicles()
-        assert len(account.vehicles) == get_fingerprint_state_count()
+        assert len(account.vehicles) == get_fingerprint_count("profiles")
 
         # No call to _init_vehicles()
         await account.get_vehicles()
-        assert len(account.vehicles) == get_fingerprint_state_count()
+        assert len(account.vehicles) == get_fingerprint_count("profiles")
 
         # Second, forced call _init_vehicles()
         await account.get_vehicles(force_init=True)
-        assert len(account.vehicles) == get_fingerprint_state_count()
+        assert len(account.vehicles) == get_fingerprint_count("profiles")
 
         assert mock_listener.call_count == 2
 
@@ -259,9 +258,14 @@ async def test_vehicle_search_case(bmw_fixture: respx.Router):
 async def test_get_fingerprints(monkeypatch: pytest.MonkeyPatch, bmw_fixture: respx.Router, bmw_log_all_responses):
     """Test getting fingerprints."""
 
-    # Prepare Number of good responses (vehicle states, charging settings per vehicle)
+    # Prepare Number of good responses (vehicle profiles + vehicle states, charging settings per vehicle)
     # and 2x vehicle list
-    json_count = get_fingerprint_state_count() + get_fingerprint_charging_settings_count() + 2
+    json_count = (
+        get_fingerprint_count("vehicles")
+        + get_fingerprint_count("profiles")
+        + get_fingerprint_count("states")
+        + get_fingerprint_count("charging_settings")
+    )
 
     account = MyBMWAccount(TEST_USERNAME, TEST_PASSWORD, TEST_REGION, log_responses=True)
     await account.get_vehicles()
@@ -339,21 +343,27 @@ async def test_set_use_metric_units(caplog):
     account = MyBMWAccount(TEST_USERNAME, TEST_PASSWORD, TEST_REGION)
     assert len(caplog.records) == 0
     metric_client = MyBMWClient(account.config)
-    assert metric_client.generate_default_header()["bmw-units-preferences"] == "d=KM;v=L"
+    assert (
+        metric_client.generate_default_header()["bmw-units-preferences"] == "d=KM;v=L;p=B;ec=KWH100KM;fc=L100KM;em=GKM;"
+    )
 
     # Set to true
     caplog.clear()
     account = MyBMWAccount(TEST_USERNAME, TEST_PASSWORD, TEST_REGION, use_metric_units=True)
     assert len(caplog.records) == 1
     metric_client = MyBMWClient(account.config)
-    assert metric_client.generate_default_header()["bmw-units-preferences"] == "d=KM;v=L"
+    assert (
+        metric_client.generate_default_header()["bmw-units-preferences"] == "d=KM;v=L;p=B;ec=KWH100KM;fc=L100KM;em=GKM;"
+    )
 
     # Set to false
     caplog.clear()
     account = MyBMWAccount(TEST_USERNAME, TEST_PASSWORD, TEST_REGION, use_metric_units=True)
     assert len(caplog.records) == 1
     metric_client = MyBMWClient(account.config)
-    assert metric_client.generate_default_header()["bmw-units-preferences"] == "d=KM;v=L"
+    assert (
+        metric_client.generate_default_header()["bmw-units-preferences"] == "d=KM;v=L;p=B;ec=KWH100KM;fc=L100KM;em=GKM;"
+    )
 
 
 @pytest.mark.asyncio
@@ -434,11 +444,12 @@ async def test_429_retry_ok_vehicles(caplog, bmw_fixture: respx.Router):
 
     json_429 = {"statusCode": 429, "message": "Rate limit is exceeded. Try again in 2 seconds."}
 
-    bmw_fixture.get("/eadrax-vcs/v4/vehicles").mock(
+    bmw_fixture.post(VEHICLES_URL).mock(
         side_effect=[
             httpx.Response(429, json=json_429),
             httpx.Response(429, json=json_429),
-            *[httpx.Response(200, json=[])] * 2,
+            httpx.Response(200, json=load_response(RESPONSE_DIR / "bmw-eadrax-vcs_v5_vehicle-list.json")),
+            httpx.Response(200, json=load_response(RESPONSE_DIR / "mini-eadrax-vcs_v5_vehicle-list.json")),
         ]
     )
     caplog.set_level(logging.DEBUG)
@@ -461,7 +472,7 @@ async def test_429_retry_raise_vehicles(caplog, bmw_fixture: respx.Router):
 
     json_429 = {"statusCode": 429, "message": "Rate limit is exceeded. Try again in 2 seconds."}
 
-    bmw_fixture.get("/eadrax-vcs/v4/vehicles").mock(return_value=httpx.Response(429, json=json_429))
+    bmw_fixture.post(VEHICLES_URL).mock(return_value=httpx.Response(429, json=json_429))
     caplog.set_level(logging.DEBUG)
 
     with mock.patch("asyncio.sleep", new_callable=mock.AsyncMock):
@@ -483,11 +494,12 @@ async def test_429_retry_with_login_ok_vehicles(bmw_fixture: respx.Router):
 
     json_429 = {"statusCode": 429, "message": "Rate limit is exceeded. Try again in 2 seconds."}
 
-    bmw_fixture.get("/eadrax-vcs/v4/vehicles").mock(
+    bmw_fixture.post(VEHICLES_URL).mock(
         side_effect=[
             httpx.Response(429, json=json_429),
             httpx.Response(429, json=json_429),
-            *[httpx.Response(200, json=[])] * 2,
+            httpx.Response(200, json=load_response(RESPONSE_DIR / "bmw-eadrax-vcs_v5_vehicle-list.json")),
+            httpx.Response(200, json=load_response(RESPONSE_DIR / "mini-eadrax-vcs_v5_vehicle-list.json")),
         ]
     )
 
@@ -502,7 +514,7 @@ async def test_429_retry_with_login_raise_vehicles(bmw_fixture: respx.Router):
 
     json_429 = {"statusCode": 429, "message": "Rate limit is exceeded. Try again in 2 seconds."}
 
-    bmw_fixture.get("/eadrax-vcs/v4/vehicles").mock(
+    bmw_fixture.post(VEHICLES_URL).mock(
         side_effect=[
             httpx.Response(429, json=json_429),
             httpx.Response(401),
@@ -524,7 +536,7 @@ async def test_multiple_401(bmw_fixture: respx.Router):
     """Test the error handling, when multiple 401 are received in sequence."""
     account = MyBMWAccount(TEST_USERNAME, TEST_PASSWORD, TEST_REGION)
 
-    bmw_fixture.get("/eadrax-vcs/v4/vehicles").mock(
+    bmw_fixture.post(VEHICLES_URL).mock(
         side_effect=[
             httpx.Response(401),
             httpx.Response(401),
@@ -545,18 +557,19 @@ async def test_401_after_429_ok(bmw_fixture: respx.Router):
     json_429 = {"statusCode": 429, "message": "Rate limit is exceeded. Try again in 2 seconds."}
 
     # Recover after 3 429 and 1 401
-    bmw_fixture.get("/eadrax-vcs/v4/vehicles").mock(
+    bmw_fixture.post(VEHICLES_URL).mock(
         side_effect=[
             httpx.Response(429, json=json_429),
             httpx.Response(429, json=json_429),
             httpx.Response(429, json=json_429),
             httpx.Response(401),
-            *[httpx.Response(200, json={})] * 100,  # Just simulate OK responses from now on
+            # Just simulate OK responses from now on
+            *[httpx.Response(200, json=load_response(RESPONSE_DIR / "bmw-eadrax-vcs_v5_vehicle-list.json"))] * 100,
         ]
     )
     with mock.patch("asyncio.sleep", new_callable=mock.AsyncMock):
         await account.get_vehicles()
-    assert len(account.vehicles) == get_fingerprint_state_count()
+    assert len(account.vehicles) == get_fingerprint_count("profiles")
 
 
 @pytest.mark.asyncio
@@ -567,7 +580,7 @@ async def test_401_after_429_fail(bmw_fixture: respx.Router):
     json_429 = {"statusCode": 429, "message": "Rate limit is exceeded. Try again in 2 seconds."}
 
     # Fail after 3 429 and 1 401 with another 429
-    bmw_fixture.get("/eadrax-vcs/v4/vehicles").mock(
+    bmw_fixture.post(VEHICLES_URL).mock(
         side_effect=[
             httpx.Response(429, json=json_429),
             httpx.Response(429, json=json_429),
@@ -647,7 +660,7 @@ async def test_no_vehicle_details(caplog, bmw_fixture: respx.Router):
         await account.get_vehicles()
 
     log_error = [r for r in caplog.records if "Unable to get details" in r.message]
-    assert len(log_error) == get_fingerprint_state_count()
+    assert len(log_error) == get_fingerprint_count("profiles")
 
 
 @pytest.mark.asyncio
diff --git a/bimmer_connected/tests/test_api.py b/bimmer_connected/tests/test_api.py
index 1a4c98a..c910278 100644
--- a/bimmer_connected/tests/test_api.py
+++ b/bimmer_connected/tests/test_api.py
@@ -17,9 +17,7 @@ from . import (
     TEST_REGION,
     TEST_USERNAME,
     VIN_G26,
-    get_fingerprint_charging_settings_count,
-    get_fingerprint_state_count,
-    # get_fingerprint_count,
+    get_fingerprint_count,
     load_response,
 )
 
@@ -47,7 +45,7 @@ def test_anonymize_data():
         "licensePlate": "secret",
         "public": "public_data",
         "a_list": [
-            {"vin": "WBA000000SECRET01"},
+            {"vin": "4US000000SECRET01"},
             {
                 "lon": 666,
                 "public": "more_public_data",
@@ -85,22 +83,21 @@ async def test_storing_fingerprints(tmp_path, bmw_fixture: respx.Router, bmw_log
     json_files = [f for f in files if f.suffix == ".json"]
     txt_files = [f for f in files if f.suffix == ".txt"]
 
-    assert len(json_files) == (get_fingerprint_state_count() + get_fingerprint_charging_settings_count() + 2 - 2)
-    assert len(txt_files) == 1
+    assert len(json_files) == (
+        get_fingerprint_count("vehicles")
+        + get_fingerprint_count("profiles")
+        + get_fingerprint_count("states")
+        - 1  # state with error 500
+        + get_fingerprint_count("charging_settings")
+        - 1  # not loaded due to state with error 500
+    )
+    assert len(txt_files) == 1  # state with error 500
 
 
 @pytest.mark.asyncio
 async def test_fingerprint_deque(monkeypatch: pytest.MonkeyPatch, bmw_fixture: respx.Router):
     """Test storing fingerprints to file."""
-    # Increase length of response store for local testing
-
-    # temp_store = deque(maxlen=100)
-    # monkeypatch.setattr("bimmer_connected.api.client.RESPONSE_STORE", temp_store)
-    # monkeypatch.setattr("bimmer_connected.account.RESPONSE_STORE", temp_store)
-
-    # Prepare Number of good responses (vehicle states, charging settings per vehicle)
-    # # and 2x vehicle list
-    # json_count = get_fingerprint_state_count() + get_fingerprint_charging_settings_count() + 2
+    # Prepare Number of good responses
 
     account = MyBMWAccount(TEST_USERNAME, TEST_PASSWORD, TEST_REGION, log_responses=True)
     await account.get_vehicles()
diff --git a/bimmer_connected/tests/test_remote_services.py b/bimmer_connected/tests/test_remote_services.py
index f886888..a8bd9cc 100644
--- a/bimmer_connected/tests/test_remote_services.py
+++ b/bimmer_connected/tests/test_remote_services.py
@@ -399,3 +399,10 @@ def test_poi_parsing():
     assert poi_data.coordinates.longitude == POI_DATA["lon"]
     assert poi_data.name == "Sent with ♥ by bimmer_connected"
     assert poi_data.formattedAddress == "Somewhere over rainbow"
+
+    # Check parsing with numeric postal code
+    poi_data = PointOfInterest(lat=POI_DATA["lat"], lon=POI_DATA["lon"], postal_code=1234)
+    assert poi_data.coordinates.latitude == POI_DATA["lat"]
+    assert poi_data.coordinates.longitude == POI_DATA["lon"]
+    assert poi_data.name == "Sent with ♥ by bimmer_connected"
+    assert poi_data.locationAddress.postalCode == "1234"
diff --git a/bimmer_connected/tests/test_vehicle.py b/bimmer_connected/tests/test_vehicle.py
index 38b7370..fc18340 100644
--- a/bimmer_connected/tests/test_vehicle.py
+++ b/bimmer_connected/tests/test_vehicle.py
@@ -130,7 +130,7 @@ async def test_get_is_tracking_enabled(caplog, bmw_fixture: respx.Router):
     vehicle = account.get_vehicle(VIN_I01_REX)
     assert vehicle.is_vehicle_tracking_enabled is False
 
-    vehicle = account.get_vehicle(VIN_F31)
+    vehicle = account.get_vehicle(VIN_G20)
     assert vehicle.is_vehicle_tracking_enabled is True
 
     assert len(get_deprecation_warning_count(caplog)) == 0
@@ -212,9 +212,9 @@ async def test_vehicle_image(caplog, bmw_fixture: respx.Router):
     vehicle = (await prepare_account_with_vehicles()).get_vehicle(VIN_G01)
 
     bmw_fixture.get(
-        path__regex=r"(.*)/eadrax-ics/v3/presentation/vehicles/\w*/images",
+        path="/eadrax-ics/v5/presentation/vehicles/images",
         params={"carView": "FrontView"},
-        headers={"accept": "image/png"},
+        headers={"accept": "image/png", "bmw-app-vehicle-type": "connected", "bmw-vin": VIN_G01},
     ).respond(200, content="png_image")
     assert b"png_image" == await vehicle.get_vehicle_image(VehicleViewDirection.FRONT)
 
@@ -225,8 +225,8 @@ async def test_vehicle_image(caplog, bmw_fixture: respx.Router):
 async def test_no_timestamp(bmw_fixture: respx.Router):
     """Test no timestamp available."""
     vehicle = (await prepare_account_with_vehicles()).get_vehicle(VIN_F31)
-    vehicle.data[ATTR_STATE].pop("lastFetched")
-    vehicle.data[ATTR_ATTRIBUTES].pop("lastFetched")
+    vehicle.data[ATTR_STATE].pop("lastFetched", None)
+    vehicle.data[ATTR_ATTRIBUTES].pop("lastFetched", None)
 
     assert vehicle.timestamp is None
 
diff --git a/bimmer_connected/tests/test_vehicle_status.py b/bimmer_connected/tests/test_vehicle_status.py
index 3f9ebbc..491071e 100644
--- a/bimmer_connected/tests/test_vehicle_status.py
+++ b/bimmer_connected/tests/test_vehicle_status.py
@@ -81,11 +81,11 @@ async def test_generic_error_handling(caplog, bmw_fixture: respx.Router):
 
 @pytest.mark.asyncio
 async def test_range_combustion_no_info(caplog, bmw_fixture: respx.Router):
-    """Test if the parsing of mileage and range is working."""
+    """Test if the parsing of very old vehicles."""
     vehicle = (await prepare_account_with_vehicles()).get_vehicle(VIN_F31)
     status = vehicle.fuel_and_battery
 
-    assert (14, "L") == status.remaining_fuel
+    assert status.remaining_fuel == (None, None)
     assert status.remaining_range_fuel == (None, None)
     assert status.remaining_fuel_percent is None
 
@@ -94,18 +94,14 @@ async def test_range_combustion_no_info(caplog, bmw_fixture: respx.Router):
 
     assert status.remaining_range_total == (None, None)
 
-    status_from_vehicle_data = FuelAndBattery.from_vehicle_data(vehicle.data)
-    status_from_vehicle_data.account_timezone = status.account_timezone
-    assert status_from_vehicle_data == status
-    assert FuelAndBattery.from_vehicle_data({}) is None
-
     assert len(get_deprecation_warning_count(caplog)) == 0
 
 
 @pytest.mark.asyncio
 async def test_range_combustion(caplog, bmw_fixture: respx.Router):
     """Test if the parsing of mileage and range is working."""
-    status = (await prepare_account_with_vehicles()).get_vehicle(VIN_G20).fuel_and_battery
+    vehicle = (await prepare_account_with_vehicles()).get_vehicle(VIN_G20)
+    status = vehicle.fuel_and_battery
 
     assert (40, "L") == status.remaining_fuel
     assert (629, "km") == status.remaining_range_fuel
@@ -116,6 +112,11 @@ async def test_range_combustion(caplog, bmw_fixture: respx.Router):
 
     assert (629, "km") == status.remaining_range_total
 
+    status_from_vehicle_data = FuelAndBattery.from_vehicle_data(vehicle.data)
+    status_from_vehicle_data.account_timezone = status.account_timezone
+    assert status_from_vehicle_data == status
+    assert FuelAndBattery.from_vehicle_data({}) is None
+
     assert len(get_deprecation_warning_count(caplog)) == 0