mirror of
https://github.com/home-assistant/core.git
synced 2026-04-20 15:55:14 +00:00
Use runtime_data in Subaru integration (#167747)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -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):
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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]],
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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]
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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():
|
||||
|
||||
@@ -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,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user