mirror of
https://github.com/home-assistant/core.git
synced 2025-11-09 10:59:40 +00:00
Handle location scope in Tesla Fleet vehicle coordinator (#154731)
This commit is contained in:
committed by
Franck Nijhof
parent
03abd5d277
commit
6ac4d2dd59
@@ -134,7 +134,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: TeslaFleetConfigEntry) -
|
||||
api = tesla.vehicles.createSigned(vin)
|
||||
else:
|
||||
api = tesla.vehicles.createFleet(vin)
|
||||
coordinator = TeslaFleetVehicleDataCoordinator(hass, entry, api, product)
|
||||
coordinator = TeslaFleetVehicleDataCoordinator(
|
||||
hass, entry, api, product, Scope.VEHICLE_LOCATION in scopes
|
||||
)
|
||||
|
||||
await coordinator.async_config_entry_first_refresh()
|
||||
|
||||
|
||||
@@ -39,9 +39,9 @@ ENDPOINTS = [
|
||||
VehicleDataEndpoint.CHARGE_STATE,
|
||||
VehicleDataEndpoint.CLIMATE_STATE,
|
||||
VehicleDataEndpoint.DRIVE_STATE,
|
||||
VehicleDataEndpoint.LOCATION_DATA,
|
||||
VehicleDataEndpoint.VEHICLE_STATE,
|
||||
VehicleDataEndpoint.VEHICLE_CONFIG,
|
||||
VehicleDataEndpoint.LOCATION_DATA,
|
||||
]
|
||||
|
||||
|
||||
@@ -65,6 +65,7 @@ class TeslaFleetVehicleDataCoordinator(DataUpdateCoordinator[dict[str, Any]]):
|
||||
updated_once: bool
|
||||
pre2021: bool
|
||||
last_active: datetime
|
||||
endpoints: list[VehicleDataEndpoint]
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@@ -72,6 +73,7 @@ class TeslaFleetVehicleDataCoordinator(DataUpdateCoordinator[dict[str, Any]]):
|
||||
config_entry: TeslaFleetConfigEntry,
|
||||
api: VehicleFleet,
|
||||
product: dict,
|
||||
location: bool,
|
||||
) -> None:
|
||||
"""Initialize TeslaFleet Vehicle Update Coordinator."""
|
||||
super().__init__(
|
||||
@@ -85,6 +87,11 @@ class TeslaFleetVehicleDataCoordinator(DataUpdateCoordinator[dict[str, Any]]):
|
||||
self.data = flatten(product)
|
||||
self.updated_once = False
|
||||
self.last_active = datetime.now()
|
||||
self.endpoints = (
|
||||
ENDPOINTS
|
||||
if location
|
||||
else [ep for ep in ENDPOINTS if ep != VehicleDataEndpoint.LOCATION_DATA]
|
||||
)
|
||||
|
||||
async def _async_update_data(self) -> dict[str, Any]:
|
||||
"""Update vehicle data using TeslaFleet API."""
|
||||
@@ -97,7 +104,7 @@ class TeslaFleetVehicleDataCoordinator(DataUpdateCoordinator[dict[str, Any]]):
|
||||
if self.data["state"] != TeslaFleetState.ONLINE:
|
||||
return self.data
|
||||
|
||||
response = await self.api.vehicle_data(endpoints=ENDPOINTS)
|
||||
response = await self.api.vehicle_data(endpoints=self.endpoints)
|
||||
data = response["response"]
|
||||
|
||||
except VehicleOffline:
|
||||
|
||||
@@ -9,6 +9,7 @@ from aiohttp.client_exceptions import ClientResponseError
|
||||
from freezegun.api import FrozenDateTimeFactory
|
||||
import pytest
|
||||
from syrupy.assertion import SnapshotAssertion
|
||||
from tesla_fleet_api.const import Scope, VehicleDataEndpoint
|
||||
from tesla_fleet_api.exceptions import (
|
||||
InvalidRegion,
|
||||
InvalidToken,
|
||||
@@ -36,6 +37,7 @@ from homeassistant.data_entry_flow import FlowResultType
|
||||
from homeassistant.helpers import device_registry as dr
|
||||
|
||||
from . import setup_platform
|
||||
from .conftest import create_config_entry
|
||||
from .const import VEHICLE_ASLEEP, VEHICLE_DATA_ALT
|
||||
|
||||
from tests.common import MockConfigEntry, async_fire_time_changed
|
||||
@@ -497,3 +499,65 @@ async def test_bad_implementation(
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "reauth_confirm"
|
||||
assert not result["errors"]
|
||||
|
||||
|
||||
async def test_vehicle_without_location_scope(
|
||||
hass: HomeAssistant,
|
||||
expires_at: int,
|
||||
mock_vehicle_data: AsyncMock,
|
||||
) -> None:
|
||||
"""Test vehicle setup without VEHICLE_LOCATION scope excludes location endpoint."""
|
||||
|
||||
# Create config entry without VEHICLE_LOCATION scope
|
||||
config_entry = create_config_entry(
|
||||
expires_at,
|
||||
[
|
||||
Scope.OPENID,
|
||||
Scope.OFFLINE_ACCESS,
|
||||
Scope.VEHICLE_DEVICE_DATA,
|
||||
# Deliberately exclude Scope.VEHICLE_LOCATION
|
||||
],
|
||||
)
|
||||
|
||||
await setup_platform(hass, config_entry)
|
||||
assert config_entry.state is ConfigEntryState.LOADED
|
||||
|
||||
# Verify that vehicle_data was called without LOCATION_DATA endpoint
|
||||
mock_vehicle_data.assert_called()
|
||||
call_args = mock_vehicle_data.call_args
|
||||
endpoints = call_args.kwargs.get("endpoints", [])
|
||||
|
||||
# Should not include LOCATION_DATA endpoint
|
||||
assert VehicleDataEndpoint.LOCATION_DATA not in endpoints
|
||||
|
||||
# Should include other endpoints
|
||||
assert VehicleDataEndpoint.CHARGE_STATE in endpoints
|
||||
assert VehicleDataEndpoint.CLIMATE_STATE in endpoints
|
||||
assert VehicleDataEndpoint.DRIVE_STATE in endpoints
|
||||
assert VehicleDataEndpoint.VEHICLE_STATE in endpoints
|
||||
assert VehicleDataEndpoint.VEHICLE_CONFIG in endpoints
|
||||
|
||||
|
||||
async def test_vehicle_with_location_scope(
|
||||
hass: HomeAssistant,
|
||||
normal_config_entry: MockConfigEntry,
|
||||
mock_vehicle_data: AsyncMock,
|
||||
) -> None:
|
||||
"""Test vehicle setup with VEHICLE_LOCATION scope includes location endpoint."""
|
||||
await setup_platform(hass, normal_config_entry)
|
||||
assert normal_config_entry.state is ConfigEntryState.LOADED
|
||||
|
||||
# Verify that vehicle_data was called with LOCATION_DATA endpoint
|
||||
mock_vehicle_data.assert_called()
|
||||
call_args = mock_vehicle_data.call_args
|
||||
endpoints = call_args.kwargs.get("endpoints", [])
|
||||
|
||||
# Should include LOCATION_DATA endpoint when scope is present
|
||||
assert VehicleDataEndpoint.LOCATION_DATA in endpoints
|
||||
|
||||
# Should include all other endpoints
|
||||
assert VehicleDataEndpoint.CHARGE_STATE in endpoints
|
||||
assert VehicleDataEndpoint.CLIMATE_STATE in endpoints
|
||||
assert VehicleDataEndpoint.DRIVE_STATE in endpoints
|
||||
assert VehicleDataEndpoint.VEHICLE_STATE in endpoints
|
||||
assert VehicleDataEndpoint.VEHICLE_CONFIG in endpoints
|
||||
|
||||
Reference in New Issue
Block a user