mirror of
https://github.com/home-assistant/core.git
synced 2025-07-14 00:37:13 +00:00
Check Tessie scopes to fix startup bug (#120710)
* Add scope check * Add tests * Bump Teslemetry
This commit is contained in:
parent
35d145d3bc
commit
3932ce57b9
@ -7,5 +7,5 @@
|
|||||||
"iot_class": "cloud_polling",
|
"iot_class": "cloud_polling",
|
||||||
"loggers": ["tesla-fleet-api"],
|
"loggers": ["tesla-fleet-api"],
|
||||||
"quality_scale": "platinum",
|
"quality_scale": "platinum",
|
||||||
"requirements": ["tesla-fleet-api==0.6.1"]
|
"requirements": ["tesla-fleet-api==0.6.2"]
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import logging
|
|||||||
|
|
||||||
from aiohttp import ClientError, ClientResponseError
|
from aiohttp import ClientError, ClientResponseError
|
||||||
from tesla_fleet_api import EnergySpecific, Tessie
|
from tesla_fleet_api import EnergySpecific, Tessie
|
||||||
|
from tesla_fleet_api.const import Scope
|
||||||
from tesla_fleet_api.exceptions import TeslaFleetError
|
from tesla_fleet_api.exceptions import TeslaFleetError
|
||||||
from tessie_api import get_state_of_all_vehicles
|
from tessie_api import get_state_of_all_vehicles
|
||||||
|
|
||||||
@ -94,41 +95,48 @@ async def async_setup_entry(hass: HomeAssistant, entry: TessieConfigEntry) -> bo
|
|||||||
|
|
||||||
# Energy Sites
|
# Energy Sites
|
||||||
tessie = Tessie(session, api_key)
|
tessie = Tessie(session, api_key)
|
||||||
|
energysites: list[TessieEnergyData] = []
|
||||||
|
|
||||||
try:
|
try:
|
||||||
products = (await tessie.products())["response"]
|
scopes = await tessie.scopes()
|
||||||
except TeslaFleetError as e:
|
except TeslaFleetError as e:
|
||||||
raise ConfigEntryNotReady from e
|
raise ConfigEntryNotReady from e
|
||||||
|
|
||||||
energysites: list[TessieEnergyData] = []
|
if Scope.ENERGY_DEVICE_DATA in scopes:
|
||||||
for product in products:
|
try:
|
||||||
if "energy_site_id" in product:
|
products = (await tessie.products())["response"]
|
||||||
site_id = product["energy_site_id"]
|
except TeslaFleetError as e:
|
||||||
api = EnergySpecific(tessie.energy, site_id)
|
raise ConfigEntryNotReady from e
|
||||||
energysites.append(
|
|
||||||
TessieEnergyData(
|
|
||||||
api=api,
|
|
||||||
id=site_id,
|
|
||||||
live_coordinator=TessieEnergySiteLiveCoordinator(hass, api),
|
|
||||||
info_coordinator=TessieEnergySiteInfoCoordinator(hass, api),
|
|
||||||
device=DeviceInfo(
|
|
||||||
identifiers={(DOMAIN, str(site_id))},
|
|
||||||
manufacturer="Tesla",
|
|
||||||
name=product.get("site_name", "Energy Site"),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
# Populate coordinator data before forwarding to platforms
|
for product in products:
|
||||||
await asyncio.gather(
|
if "energy_site_id" in product:
|
||||||
*(
|
site_id = product["energy_site_id"]
|
||||||
energysite.live_coordinator.async_config_entry_first_refresh()
|
api = EnergySpecific(tessie.energy, site_id)
|
||||||
for energysite in energysites
|
energysites.append(
|
||||||
),
|
TessieEnergyData(
|
||||||
*(
|
api=api,
|
||||||
energysite.info_coordinator.async_config_entry_first_refresh()
|
id=site_id,
|
||||||
for energysite in energysites
|
live_coordinator=TessieEnergySiteLiveCoordinator(hass, api),
|
||||||
),
|
info_coordinator=TessieEnergySiteInfoCoordinator(hass, api),
|
||||||
)
|
device=DeviceInfo(
|
||||||
|
identifiers={(DOMAIN, str(site_id))},
|
||||||
|
manufacturer="Tesla",
|
||||||
|
name=product.get("site_name", "Energy Site"),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Populate coordinator data before forwarding to platforms
|
||||||
|
await asyncio.gather(
|
||||||
|
*(
|
||||||
|
energysite.live_coordinator.async_config_entry_first_refresh()
|
||||||
|
for energysite in energysites
|
||||||
|
),
|
||||||
|
*(
|
||||||
|
energysite.info_coordinator.async_config_entry_first_refresh()
|
||||||
|
for energysite in energysites
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
entry.runtime_data = TessieData(vehicles, energysites)
|
entry.runtime_data = TessieData(vehicles, energysites)
|
||||||
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
||||||
|
@ -6,5 +6,5 @@
|
|||||||
"documentation": "https://www.home-assistant.io/integrations/tessie",
|
"documentation": "https://www.home-assistant.io/integrations/tessie",
|
||||||
"iot_class": "cloud_polling",
|
"iot_class": "cloud_polling",
|
||||||
"loggers": ["tessie"],
|
"loggers": ["tessie"],
|
||||||
"requirements": ["tessie-api==0.0.9", "tesla-fleet-api==0.6.1"]
|
"requirements": ["tessie-api==0.0.9", "tesla-fleet-api==0.6.2"]
|
||||||
}
|
}
|
||||||
|
@ -2711,7 +2711,7 @@ temperusb==1.6.1
|
|||||||
|
|
||||||
# homeassistant.components.teslemetry
|
# homeassistant.components.teslemetry
|
||||||
# homeassistant.components.tessie
|
# homeassistant.components.tessie
|
||||||
tesla-fleet-api==0.6.1
|
tesla-fleet-api==0.6.2
|
||||||
|
|
||||||
# homeassistant.components.powerwall
|
# homeassistant.components.powerwall
|
||||||
tesla-powerwall==0.5.2
|
tesla-powerwall==0.5.2
|
||||||
|
@ -2109,7 +2109,7 @@ temperusb==1.6.1
|
|||||||
|
|
||||||
# homeassistant.components.teslemetry
|
# homeassistant.components.teslemetry
|
||||||
# homeassistant.components.tessie
|
# homeassistant.components.tessie
|
||||||
tesla-fleet-api==0.6.1
|
tesla-fleet-api==0.6.2
|
||||||
|
|
||||||
# homeassistant.components.powerwall
|
# homeassistant.components.powerwall
|
||||||
tesla-powerwall==0.5.2
|
tesla-powerwall==0.5.2
|
||||||
|
@ -54,6 +54,17 @@ LIVE_STATUS = load_json_object_fixture("live_status.json", DOMAIN)
|
|||||||
SITE_INFO = load_json_object_fixture("site_info.json", DOMAIN)
|
SITE_INFO = load_json_object_fixture("site_info.json", DOMAIN)
|
||||||
RESPONSE_OK = {"response": {}, "error": None}
|
RESPONSE_OK = {"response": {}, "error": None}
|
||||||
COMMAND_OK = {"response": {"result": True, "reason": ""}}
|
COMMAND_OK = {"response": {"result": True, "reason": ""}}
|
||||||
|
SCOPES = [
|
||||||
|
"user_data",
|
||||||
|
"vehicle_device_data",
|
||||||
|
"vehicle_cmds",
|
||||||
|
"vehicle_charging_cmds",
|
||||||
|
"energy_device_data",
|
||||||
|
"energy_cmds",
|
||||||
|
"offline_access",
|
||||||
|
"openid",
|
||||||
|
]
|
||||||
|
NO_SCOPES = ["user_data", "offline_access", "openid"]
|
||||||
|
|
||||||
|
|
||||||
async def setup_platform(
|
async def setup_platform(
|
||||||
|
@ -11,6 +11,7 @@ from .common import (
|
|||||||
COMMAND_OK,
|
COMMAND_OK,
|
||||||
LIVE_STATUS,
|
LIVE_STATUS,
|
||||||
PRODUCTS,
|
PRODUCTS,
|
||||||
|
SCOPES,
|
||||||
SITE_INFO,
|
SITE_INFO,
|
||||||
TEST_STATE_OF_ALL_VEHICLES,
|
TEST_STATE_OF_ALL_VEHICLES,
|
||||||
TEST_VEHICLE_STATE_ONLINE,
|
TEST_VEHICLE_STATE_ONLINE,
|
||||||
@ -51,6 +52,16 @@ def mock_get_state_of_all_vehicles():
|
|||||||
|
|
||||||
|
|
||||||
# Fleet API
|
# Fleet API
|
||||||
|
@pytest.fixture(autouse=True)
|
||||||
|
def mock_scopes():
|
||||||
|
"""Mock scopes function."""
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.tessie.Tessie.scopes",
|
||||||
|
return_value=SCOPES,
|
||||||
|
) as mock_scopes:
|
||||||
|
yield mock_scopes
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
def mock_products():
|
def mock_products():
|
||||||
"""Mock Tesla Fleet Api products method."""
|
"""Mock Tesla Fleet Api products method."""
|
||||||
|
@ -50,11 +50,21 @@ async def test_connection_failure(
|
|||||||
assert entry.state is ConfigEntryState.SETUP_RETRY
|
assert entry.state is ConfigEntryState.SETUP_RETRY
|
||||||
|
|
||||||
|
|
||||||
async def test_fleet_error(hass: HomeAssistant) -> None:
|
async def test_products_error(hass: HomeAssistant) -> None:
|
||||||
"""Test init with a fleet error."""
|
"""Test init with a fleet error on products."""
|
||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.tessie.Tessie.products", side_effect=TeslaFleetError
|
"homeassistant.components.tessie.Tessie.products", side_effect=TeslaFleetError
|
||||||
):
|
):
|
||||||
entry = await setup_platform(hass)
|
entry = await setup_platform(hass)
|
||||||
assert entry.state is ConfigEntryState.SETUP_RETRY
|
assert entry.state is ConfigEntryState.SETUP_RETRY
|
||||||
|
|
||||||
|
|
||||||
|
async def test_scopes_error(hass: HomeAssistant) -> None:
|
||||||
|
"""Test init with a fleet error on scopes."""
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.tessie.Tessie.scopes", side_effect=TeslaFleetError
|
||||||
|
):
|
||||||
|
entry = await setup_platform(hass)
|
||||||
|
assert entry.state is ConfigEntryState.SETUP_RETRY
|
||||||
|
Loading…
x
Reference in New Issue
Block a user