diff --git a/homeassistant/components/subaru/__init__.py b/homeassistant/components/subaru/__init__.py index 247618a8dcd..8ecf33e8f48 100644 --- a/homeassistant/components/subaru/__init__.py +++ b/homeassistant/components/subaru/__init__.py @@ -4,7 +4,6 @@ import logging from subarulink import Controller as SubaruAPI, InvalidCredentials, SubaruException -from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( CONF_COUNTRY, CONF_DEVICE_ID, @@ -19,9 +18,6 @@ from homeassistant.helpers.device_registry import DeviceInfo from .const import ( DOMAIN, - ENTRY_CONTROLLER, - ENTRY_COORDINATOR, - ENTRY_VEHICLES, FETCH_INTERVAL, MANUFACTURER, PLATFORMS, @@ -37,12 +33,16 @@ from .const import ( VEHICLE_NAME, VEHICLE_VIN, ) -from .coordinator import SubaruDataUpdateCoordinator +from .coordinator import ( + SubaruConfigEntry, + SubaruDataUpdateCoordinator, + SubaruRuntimeData, +) _LOGGER = logging.getLogger(__name__) -async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: +async def async_setup_entry(hass: HomeAssistant, entry: SubaruConfigEntry) -> bool: """Set up Subaru from a config entry.""" config = entry.data websession = aiohttp_client.async_create_clientsession(hass) @@ -77,24 +77,20 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: await coordinator.async_refresh() - hass.data.setdefault(DOMAIN, {}) - hass.data[DOMAIN][entry.entry_id] = { - ENTRY_CONTROLLER: controller, - ENTRY_COORDINATOR: coordinator, - ENTRY_VEHICLES: vehicle_info, - } + entry.runtime_data = SubaruRuntimeData( + controller=controller, + coordinator=coordinator, + vehicles=vehicle_info, + ) await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) return True -async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: +async def async_unload_entry(hass: HomeAssistant, entry: SubaruConfigEntry) -> bool: """Unload a config entry.""" - unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS) - if unload_ok: - hass.data[DOMAIN].pop(entry.entry_id) - return unload_ok + return await hass.config_entries.async_unload_platforms(entry, PLATFORMS) def get_vehicle_info(controller, vin): diff --git a/homeassistant/components/subaru/config_flow.py b/homeassistant/components/subaru/config_flow.py index 0ef4ed29941..035931677c0 100644 --- a/homeassistant/components/subaru/config_flow.py +++ b/homeassistant/components/subaru/config_flow.py @@ -15,12 +15,7 @@ from subarulink import ( from subarulink.const import COUNTRY_CAN, COUNTRY_USA import voluptuous as vol -from homeassistant.config_entries import ( - ConfigEntry, - ConfigFlow, - ConfigFlowResult, - OptionsFlow, -) +from homeassistant.config_entries import ConfigFlow, ConfigFlowResult, OptionsFlow from homeassistant.const import ( CONF_COUNTRY, CONF_DEVICE_ID, @@ -32,6 +27,7 @@ from homeassistant.core import callback from homeassistant.helpers import aiohttp_client, config_validation as cv from .const import CONF_UPDATE_ENABLED, DOMAIN +from .coordinator import SubaruConfigEntry _LOGGER = logging.getLogger(__name__) CONF_CONTACT_METHOD = "contact_method" @@ -103,7 +99,7 @@ class SubaruConfigFlow(ConfigFlow, domain=DOMAIN): @staticmethod @callback def async_get_options_flow( - config_entry: ConfigEntry, + config_entry: SubaruConfigEntry, ) -> OptionsFlowHandler: """Get the options flow for this handler.""" return OptionsFlowHandler() diff --git a/homeassistant/components/subaru/const.py b/homeassistant/components/subaru/const.py index d8692e6a8bc..c9a02e09f62 100644 --- a/homeassistant/components/subaru/const.py +++ b/homeassistant/components/subaru/const.py @@ -9,11 +9,6 @@ FETCH_INTERVAL = 300 UPDATE_INTERVAL = 7200 CONF_UPDATE_ENABLED = "update_enabled" -# entry fields -ENTRY_CONTROLLER = "controller" -ENTRY_COORDINATOR = "coordinator" -ENTRY_VEHICLES = "vehicles" - # update coordinator name COORDINATOR_NAME = "subaru_data" diff --git a/homeassistant/components/subaru/coordinator.py b/homeassistant/components/subaru/coordinator.py index 73aec22250a..c23c6eef506 100644 --- a/homeassistant/components/subaru/coordinator.py +++ b/homeassistant/components/subaru/coordinator.py @@ -2,6 +2,7 @@ from __future__ import annotations +from dataclasses import dataclass from datetime import timedelta import logging import time @@ -23,16 +24,27 @@ from .const import ( _LOGGER = logging.getLogger(__name__) +type SubaruConfigEntry = ConfigEntry[SubaruRuntimeData] + + +@dataclass +class SubaruRuntimeData: + """Runtime data for Subaru.""" + + controller: SubaruAPI + coordinator: SubaruDataUpdateCoordinator + vehicles: dict[str, dict[str, Any]] + class SubaruDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]): """Class to manage fetching Subaru data.""" - config_entry: ConfigEntry + config_entry: SubaruConfigEntry def __init__( self, hass: HomeAssistant, - config_entry: ConfigEntry, + config_entry: SubaruConfigEntry, *, controller: SubaruAPI, vehicle_info: dict[str, dict[str, Any]], diff --git a/homeassistant/components/subaru/device_tracker.py b/homeassistant/components/subaru/device_tracker.py index 3c5d6487cb5..fa3dc95f354 100644 --- a/homeassistant/components/subaru/device_tracker.py +++ b/homeassistant/components/subaru/device_tracker.py @@ -7,32 +7,23 @@ from typing import Any from subarulink.const import LATITUDE, LONGITUDE, TIMESTAMP from homeassistant.components.device_tracker import TrackerEntity -from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from . import get_device_info -from .const import ( - DOMAIN, - ENTRY_COORDINATOR, - ENTRY_VEHICLES, - VEHICLE_HAS_REMOTE_SERVICE, - VEHICLE_STATUS, - VEHICLE_VIN, -) -from .coordinator import SubaruDataUpdateCoordinator +from .const import VEHICLE_HAS_REMOTE_SERVICE, VEHICLE_STATUS, VEHICLE_VIN +from .coordinator import SubaruConfigEntry, SubaruDataUpdateCoordinator async def async_setup_entry( hass: HomeAssistant, - config_entry: ConfigEntry, + config_entry: SubaruConfigEntry, async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Subaru device tracker by config_entry.""" - entry: dict = hass.data[DOMAIN][config_entry.entry_id] - coordinator: SubaruDataUpdateCoordinator = entry[ENTRY_COORDINATOR] - vehicle_info: dict = entry[ENTRY_VEHICLES] + coordinator = config_entry.runtime_data.coordinator + vehicle_info = config_entry.runtime_data.vehicles async_add_entities( SubaruDeviceTracker(vehicle, coordinator) for vehicle in vehicle_info.values() diff --git a/homeassistant/components/subaru/diagnostics.py b/homeassistant/components/subaru/diagnostics.py index eec5b01ab56..60f54b993e5 100644 --- a/homeassistant/components/subaru/diagnostics.py +++ b/homeassistant/components/subaru/diagnostics.py @@ -13,23 +13,23 @@ from subarulink.const import ( ) from homeassistant.components.diagnostics import async_redact_data -from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_DEVICE_ID, CONF_PASSWORD, CONF_PIN, CONF_USERNAME from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.device_registry import DeviceEntry -from .const import DOMAIN, ENTRY_CONTROLLER, ENTRY_COORDINATOR, VEHICLE_VIN +from .const import VEHICLE_VIN +from .coordinator import SubaruConfigEntry CONFIG_FIELDS_TO_REDACT = [CONF_USERNAME, CONF_PASSWORD, CONF_PIN, CONF_DEVICE_ID] DATA_FIELDS_TO_REDACT = [VEHICLE_VIN, VEHICLE_NAME, LATITUDE, LONGITUDE, ODOMETER] async def async_get_config_entry_diagnostics( - hass: HomeAssistant, config_entry: ConfigEntry + hass: HomeAssistant, config_entry: SubaruConfigEntry ) -> dict[str, Any]: """Return diagnostics for a config entry.""" - coordinator = hass.data[DOMAIN][config_entry.entry_id][ENTRY_COORDINATOR] + coordinator = config_entry.runtime_data.coordinator return { "config_entry": async_redact_data(config_entry.data, CONFIG_FIELDS_TO_REDACT), @@ -42,12 +42,11 @@ async def async_get_config_entry_diagnostics( async def async_get_device_diagnostics( - hass: HomeAssistant, config_entry: ConfigEntry, device: DeviceEntry + hass: HomeAssistant, config_entry: SubaruConfigEntry, device: DeviceEntry ) -> dict[str, Any]: """Return diagnostics for a device.""" - entry = hass.data[DOMAIN][config_entry.entry_id] - coordinator = entry[ENTRY_COORDINATOR] - controller = entry[ENTRY_CONTROLLER] + coordinator = config_entry.runtime_data.coordinator + controller = config_entry.runtime_data.controller vin = next(iter(device.identifiers))[1] diff --git a/homeassistant/components/subaru/lock.py b/homeassistant/components/subaru/lock.py index 07caa0d6367..8af699fb45f 100644 --- a/homeassistant/components/subaru/lock.py +++ b/homeassistant/components/subaru/lock.py @@ -6,17 +6,14 @@ from typing import Any import voluptuous as vol from homeassistant.components.lock import LockEntity -from homeassistant.config_entries import ConfigEntry from homeassistant.const import SERVICE_LOCK, SERVICE_UNLOCK from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_platform from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import DOMAIN, get_device_info +from . import get_device_info from .const import ( ATTR_DOOR, - ENTRY_CONTROLLER, - ENTRY_VEHICLES, SERVICE_UNLOCK_SPECIFIC_DOOR, UNLOCK_DOOR_ALL, UNLOCK_VALID_DOORS, @@ -24,6 +21,7 @@ from .const import ( VEHICLE_NAME, VEHICLE_VIN, ) +from .coordinator import SubaruConfigEntry from .remote_service import async_call_remote_service _LOGGER = logging.getLogger(__name__) @@ -31,13 +29,12 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, - config_entry: ConfigEntry, + config_entry: SubaruConfigEntry, async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Subaru locks by config_entry.""" - entry = hass.data[DOMAIN][config_entry.entry_id] - controller = entry[ENTRY_CONTROLLER] - vehicle_info = entry[ENTRY_VEHICLES] + controller = config_entry.runtime_data.controller + vehicle_info = config_entry.runtime_data.vehicles async_add_entities( SubaruLock(vehicle, controller) for vehicle in vehicle_info.values() diff --git a/homeassistant/components/subaru/sensor.py b/homeassistant/components/subaru/sensor.py index 880e0043fa8..1d9d50dc020 100644 --- a/homeassistant/components/subaru/sensor.py +++ b/homeassistant/components/subaru/sensor.py @@ -26,15 +26,12 @@ from . import get_device_info from .const import ( API_GEN_2, API_GEN_3, - DOMAIN, - ENTRY_COORDINATOR, - ENTRY_VEHICLES, VEHICLE_API_GEN, VEHICLE_HAS_EV, VEHICLE_STATUS, VEHICLE_VIN, ) -from .coordinator import SubaruDataUpdateCoordinator +from .coordinator import SubaruConfigEntry, SubaruDataUpdateCoordinator _LOGGER = logging.getLogger(__name__) @@ -138,13 +135,12 @@ EV_SENSORS = [ async def async_setup_entry( hass: HomeAssistant, - config_entry: ConfigEntry, + config_entry: SubaruConfigEntry, async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Subaru sensors by config_entry.""" - entry = hass.data[DOMAIN][config_entry.entry_id] - coordinator = entry[ENTRY_COORDINATOR] - vehicle_info = entry[ENTRY_VEHICLES] + coordinator = config_entry.runtime_data.coordinator + vehicle_info = config_entry.runtime_data.vehicles entities = [] await _async_migrate_entries(hass, config_entry) for info in vehicle_info.values(): diff --git a/tests/components/subaru/test_sensor.py b/tests/components/subaru/test_sensor.py index f133b46d3d3..73c06b4d86e 100644 --- a/tests/components/subaru/test_sensor.py +++ b/tests/components/subaru/test_sensor.py @@ -6,9 +6,9 @@ from unittest.mock import patch import pytest from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN +from homeassistant.components.subaru.const import DOMAIN from homeassistant.components.subaru.sensor import ( API_GEN_2_SENSORS, - DOMAIN, EV_SENSORS, SAFETY_SENSORS, )