Store runtime data in entry in renault (#116454)
This commit is contained in:
parent
0005f8400d
commit
a440783208
9 changed files with 40 additions and 52 deletions
|
@ -15,6 +15,7 @@ from .renault_hub import RenaultHub
|
|||
from .services import setup_services
|
||||
|
||||
CONFIG_SCHEMA = cv.config_entry_only_config_schema(DOMAIN)
|
||||
RenaultConfigEntry = ConfigEntry[RenaultHub]
|
||||
|
||||
|
||||
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
||||
|
@ -23,7 +24,9 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
|||
return True
|
||||
|
||||
|
||||
async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant, config_entry: RenaultConfigEntry
|
||||
) -> bool:
|
||||
"""Load a config entry."""
|
||||
renault_hub = RenaultHub(hass, config_entry.data[CONF_LOCALE])
|
||||
try:
|
||||
|
@ -36,19 +39,20 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b
|
|||
if not login_success:
|
||||
raise ConfigEntryAuthFailed
|
||||
|
||||
hass.data.setdefault(DOMAIN, {})
|
||||
try:
|
||||
await renault_hub.async_initialise(config_entry)
|
||||
except aiohttp.ClientError as exc:
|
||||
raise ConfigEntryNotReady from exc
|
||||
|
||||
hass.data[DOMAIN][config_entry.entry_id] = renault_hub
|
||||
config_entry.runtime_data = renault_hub
|
||||
|
||||
await hass.config_entries.async_forward_entry_setups(config_entry, PLATFORMS)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
async def async_unload_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
|
||||
async def async_unload_entry(
|
||||
hass: HomeAssistant, config_entry: RenaultConfigEntry
|
||||
) -> bool:
|
||||
"""Unload a config entry."""
|
||||
return await hass.config_entries.async_unload_platforms(config_entry, PLATFORMS)
|
||||
|
|
|
@ -12,14 +12,12 @@ from homeassistant.components.binary_sensor import (
|
|||
BinarySensorEntity,
|
||||
BinarySensorEntityDescription,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.typing import StateType
|
||||
|
||||
from .const import DOMAIN
|
||||
from . import RenaultConfigEntry
|
||||
from .entity import RenaultDataEntity, RenaultDataEntityDescription
|
||||
from .renault_hub import RenaultHub
|
||||
|
||||
|
||||
@dataclass(frozen=True, kw_only=True)
|
||||
|
@ -35,14 +33,13 @@ class RenaultBinarySensorEntityDescription(
|
|||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
config_entry: RenaultConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up the Renault entities from config entry."""
|
||||
proxy: RenaultHub = hass.data[DOMAIN][config_entry.entry_id]
|
||||
entities: list[RenaultBinarySensor] = [
|
||||
RenaultBinarySensor(vehicle, description)
|
||||
for vehicle in proxy.vehicles.values()
|
||||
for vehicle in config_entry.runtime_data.vehicles.values()
|
||||
for description in BINARY_SENSOR_TYPES
|
||||
if description.coordinator in vehicle.coordinators
|
||||
]
|
||||
|
|
|
@ -7,13 +7,11 @@ from dataclasses import dataclass
|
|||
from typing import Any
|
||||
|
||||
from homeassistant.components.button import ButtonEntity, ButtonEntityDescription
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from .const import DOMAIN
|
||||
from . import RenaultConfigEntry
|
||||
from .entity import RenaultEntity
|
||||
from .renault_hub import RenaultHub
|
||||
|
||||
|
||||
@dataclass(frozen=True, kw_only=True)
|
||||
|
@ -26,14 +24,13 @@ class RenaultButtonEntityDescription(ButtonEntityDescription):
|
|||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
config_entry: RenaultConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up the Renault entities from config entry."""
|
||||
proxy: RenaultHub = hass.data[DOMAIN][config_entry.entry_id]
|
||||
entities: list[RenaultButtonEntity] = [
|
||||
RenaultButtonEntity(vehicle, description)
|
||||
for vehicle in proxy.vehicles.values()
|
||||
for vehicle in config_entry.runtime_data.vehicles.values()
|
||||
for description in BUTTON_TYPES
|
||||
if not description.requires_electricity or vehicle.details.uses_electricity()
|
||||
]
|
||||
|
|
|
@ -5,25 +5,22 @@ from __future__ import annotations
|
|||
from renault_api.kamereon.models import KamereonVehicleLocationData
|
||||
|
||||
from homeassistant.components.device_tracker import SourceType, TrackerEntity
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from .const import DOMAIN
|
||||
from . import RenaultConfigEntry
|
||||
from .entity import RenaultDataEntity, RenaultDataEntityDescription
|
||||
from .renault_hub import RenaultHub
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
config_entry: RenaultConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up the Renault entities from config entry."""
|
||||
proxy: RenaultHub = hass.data[DOMAIN][config_entry.entry_id]
|
||||
entities: list[RenaultDeviceTracker] = [
|
||||
RenaultDeviceTracker(vehicle, description)
|
||||
for vehicle in proxy.vehicles.values()
|
||||
for vehicle in config_entry.runtime_data.vehicles.values()
|
||||
for description in DEVICE_TRACKER_TYPES
|
||||
if description.coordinator in vehicle.coordinators
|
||||
]
|
||||
|
|
|
@ -5,13 +5,12 @@ from __future__ import annotations
|
|||
from typing import Any
|
||||
|
||||
from homeassistant.components.diagnostics import async_redact_data
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.device_registry import DeviceEntry
|
||||
|
||||
from . import RenaultHub
|
||||
from .const import CONF_KAMEREON_ACCOUNT_ID, DOMAIN
|
||||
from . import RenaultConfigEntry
|
||||
from .const import CONF_KAMEREON_ACCOUNT_ID
|
||||
from .renault_vehicle import RenaultVehicleProxy
|
||||
|
||||
TO_REDACT = {
|
||||
|
@ -27,11 +26,9 @@ TO_REDACT = {
|
|||
|
||||
|
||||
async def async_get_config_entry_diagnostics(
|
||||
hass: HomeAssistant, entry: ConfigEntry
|
||||
hass: HomeAssistant, entry: RenaultConfigEntry
|
||||
) -> dict[str, Any]:
|
||||
"""Return diagnostics for a config entry."""
|
||||
renault_hub: RenaultHub = hass.data[DOMAIN][entry.entry_id]
|
||||
|
||||
return {
|
||||
"entry": {
|
||||
"title": entry.title,
|
||||
|
@ -39,18 +36,17 @@ async def async_get_config_entry_diagnostics(
|
|||
},
|
||||
"vehicles": [
|
||||
_get_vehicle_diagnostics(vehicle)
|
||||
for vehicle in renault_hub.vehicles.values()
|
||||
for vehicle in entry.runtime_data.vehicles.values()
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
async def async_get_device_diagnostics(
|
||||
hass: HomeAssistant, entry: ConfigEntry, device: DeviceEntry
|
||||
hass: HomeAssistant, entry: RenaultConfigEntry, device: DeviceEntry
|
||||
) -> dict[str, Any]:
|
||||
"""Return diagnostics for a device."""
|
||||
renault_hub: RenaultHub = hass.data[DOMAIN][entry.entry_id]
|
||||
vin = next(iter(device.identifiers))[1]
|
||||
vehicle = renault_hub.vehicles[vin]
|
||||
vehicle = entry.runtime_data.vehicles[vin]
|
||||
|
||||
return _get_vehicle_diagnostics(vehicle)
|
||||
|
||||
|
|
|
@ -8,14 +8,12 @@ from typing import cast
|
|||
from renault_api.kamereon.models import KamereonVehicleBatteryStatusData
|
||||
|
||||
from homeassistant.components.select import SelectEntity, SelectEntityDescription
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.typing import StateType
|
||||
|
||||
from .const import DOMAIN
|
||||
from . import RenaultConfigEntry
|
||||
from .entity import RenaultDataEntity, RenaultDataEntityDescription
|
||||
from .renault_hub import RenaultHub
|
||||
|
||||
|
||||
@dataclass(frozen=True, kw_only=True)
|
||||
|
@ -29,14 +27,13 @@ class RenaultSelectEntityDescription(
|
|||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
config_entry: RenaultConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up the Renault entities from config entry."""
|
||||
proxy: RenaultHub = hass.data[DOMAIN][config_entry.entry_id]
|
||||
entities: list[RenaultSelectEntity] = [
|
||||
RenaultSelectEntity(vehicle, description)
|
||||
for vehicle in proxy.vehicles.values()
|
||||
for vehicle in config_entry.runtime_data.vehicles.values()
|
||||
for description in SENSOR_TYPES
|
||||
if description.coordinator in vehicle.coordinators
|
||||
]
|
||||
|
|
|
@ -21,7 +21,6 @@ from homeassistant.components.sensor import (
|
|||
SensorEntityDescription,
|
||||
SensorStateClass,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import (
|
||||
PERCENTAGE,
|
||||
UnitOfEnergy,
|
||||
|
@ -36,10 +35,9 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
|||
from homeassistant.helpers.typing import StateType
|
||||
from homeassistant.util.dt import as_utc, parse_datetime
|
||||
|
||||
from .const import DOMAIN
|
||||
from . import RenaultConfigEntry
|
||||
from .coordinator import T
|
||||
from .entity import RenaultDataEntity, RenaultDataEntityDescription
|
||||
from .renault_hub import RenaultHub
|
||||
from .renault_vehicle import RenaultVehicleProxy
|
||||
|
||||
|
||||
|
@ -58,14 +56,13 @@ class RenaultSensorEntityDescription(
|
|||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
config_entry: RenaultConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up the Renault entities from config entry."""
|
||||
proxy: RenaultHub = hass.data[DOMAIN][config_entry.entry_id]
|
||||
entities: list[RenaultSensor[Any]] = [
|
||||
description.entity_class(vehicle, description)
|
||||
for vehicle in proxy.vehicles.values()
|
||||
for vehicle in config_entry.runtime_data.vehicles.values()
|
||||
for description in SENSOR_TYPES
|
||||
if description.coordinator in vehicle.coordinators
|
||||
and (not description.requires_fuel or vehicle.details.uses_fuel())
|
||||
|
|
|
@ -9,13 +9,16 @@ from typing import TYPE_CHECKING, Any
|
|||
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.config_entries import ConfigEntryState
|
||||
from homeassistant.core import HomeAssistant, ServiceCall
|
||||
from homeassistant.helpers import config_validation as cv, device_registry as dr
|
||||
|
||||
from .const import DOMAIN
|
||||
from .renault_hub import RenaultHub
|
||||
from .renault_vehicle import RenaultVehicleProxy
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from . import RenaultConfigEntry
|
||||
|
||||
LOGGER = logging.getLogger(__name__)
|
||||
|
||||
ATTR_SCHEDULES = "schedules"
|
||||
|
@ -116,9 +119,13 @@ def setup_services(hass: HomeAssistant) -> None:
|
|||
if device_entry is None:
|
||||
raise ValueError(f"Unable to find device with id: {device_id}")
|
||||
|
||||
proxy: RenaultHub
|
||||
for proxy in hass.data[DOMAIN].values():
|
||||
for vin, vehicle in proxy.vehicles.items():
|
||||
loaded_entries: list[RenaultConfigEntry] = [
|
||||
entry
|
||||
for entry in hass.config_entries.async_entries(DOMAIN)
|
||||
if entry.state == ConfigEntryState.LOADED
|
||||
]
|
||||
for entry in loaded_entries:
|
||||
for vin, vehicle in entry.runtime_data.vehicles.items():
|
||||
if (DOMAIN, vin) in device_entry.identifiers:
|
||||
return vehicle
|
||||
raise ValueError(f"Unable to find vehicle with VIN: {device_entry.identifiers}")
|
||||
|
|
|
@ -57,7 +57,6 @@ async def test_setup_entry_bad_password(
|
|||
|
||||
assert len(hass.config_entries.async_entries(DOMAIN)) == 1
|
||||
assert config_entry.state is ConfigEntryState.SETUP_ERROR
|
||||
assert not hass.data.get(DOMAIN)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("side_effect", [aiohttp.ClientConnectionError, GigyaException])
|
||||
|
@ -76,7 +75,6 @@ async def test_setup_entry_exception(
|
|||
|
||||
assert len(hass.config_entries.async_entries(DOMAIN)) == 1
|
||||
assert config_entry.state is ConfigEntryState.SETUP_RETRY
|
||||
assert not hass.data.get(DOMAIN)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("patch_renault_account")
|
||||
|
@ -95,7 +93,6 @@ async def test_setup_entry_kamereon_exception(
|
|||
|
||||
assert len(hass.config_entries.async_entries(DOMAIN)) == 1
|
||||
assert config_entry.state is ConfigEntryState.SETUP_RETRY
|
||||
assert not hass.data.get(DOMAIN)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("patch_renault_account", "patch_get_vehicles")
|
||||
|
@ -111,4 +108,3 @@ async def test_setup_entry_missing_vehicle_details(
|
|||
|
||||
assert len(hass.config_entries.async_entries(DOMAIN)) == 1
|
||||
assert config_entry.state is ConfigEntryState.SETUP_RETRY
|
||||
assert not hass.data.get(DOMAIN)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue