From 04a56eaabe8c56bbe42e59f50191a06d6a446ab3 Mon Sep 17 00:00:00 2001 From: Brett Adams Date: Mon, 25 Dec 2023 22:01:13 +1000 Subject: [PATCH] Add data model to Tessie (#106285) Add data model --- homeassistant/components/tessie/__init__.py | 19 +++++++++++-------- .../components/tessie/binary_sensor.py | 12 ++++++------ homeassistant/components/tessie/button.py | 10 +++++----- homeassistant/components/tessie/climate.py | 10 ++++++---- .../components/tessie/coordinator.py | 2 +- homeassistant/components/tessie/cover.py | 12 ++++++------ .../components/tessie/device_tracker.py | 10 +++++----- homeassistant/components/tessie/entity.py | 6 +++--- homeassistant/components/tessie/lock.py | 8 ++++---- .../components/tessie/media_player.py | 8 ++++---- homeassistant/components/tessie/models.py | 13 +++++++++++++ homeassistant/components/tessie/number.py | 12 ++++++------ homeassistant/components/tessie/select.py | 8 ++++---- homeassistant/components/tessie/sensor.py | 12 ++++++------ homeassistant/components/tessie/switch.py | 12 ++++++------ homeassistant/components/tessie/update.py | 10 ++++++---- 16 files changed, 92 insertions(+), 72 deletions(-) create mode 100644 homeassistant/components/tessie/models.py diff --git a/homeassistant/components/tessie/__init__.py b/homeassistant/components/tessie/__init__.py index f344cef2484..869cd46cf51 100644 --- a/homeassistant/components/tessie/__init__.py +++ b/homeassistant/components/tessie/__init__.py @@ -12,7 +12,8 @@ from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady from homeassistant.helpers.aiohttp_client import async_get_clientsession from .const import DOMAIN -from .coordinator import TessieDataUpdateCoordinator +from .coordinator import TessieStateUpdateCoordinator +from .models import TessieVehicle PLATFORMS = [ Platform.BINARY_SENSOR, @@ -50,18 +51,20 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: except ClientError as e: raise ConfigEntryNotReady from e - coordinators = [ - TessieDataUpdateCoordinator( - hass, - api_key=api_key, - vin=vehicle["vin"], - data=vehicle["last_state"], + data = [ + TessieVehicle( + state_coordinator=TessieStateUpdateCoordinator( + hass, + api_key=api_key, + vin=vehicle["vin"], + data=vehicle["last_state"], + ) ) for vehicle in vehicles["results"] if vehicle["last_state"] is not None ] - hass.data.setdefault(DOMAIN, {})[entry.entry_id] = coordinators + hass.data.setdefault(DOMAIN, {})[entry.entry_id] = data await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) return True diff --git a/homeassistant/components/tessie/binary_sensor.py b/homeassistant/components/tessie/binary_sensor.py index 38473d1076b..aab20763609 100644 --- a/homeassistant/components/tessie/binary_sensor.py +++ b/homeassistant/components/tessie/binary_sensor.py @@ -15,7 +15,7 @@ from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback from .const import DOMAIN, TessieStatus -from .coordinator import TessieDataUpdateCoordinator +from .coordinator import TessieStateUpdateCoordinator from .entity import TessieEntity @@ -117,13 +117,13 @@ async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback ) -> None: """Set up the Tessie binary sensor platform from a config entry.""" - coordinators = hass.data[DOMAIN][entry.entry_id] + data = hass.data[DOMAIN][entry.entry_id] async_add_entities( - TessieBinarySensorEntity(coordinator, description) - for coordinator in coordinators + TessieBinarySensorEntity(vehicle.state_coordinator, description) + for vehicle in data for description in DESCRIPTIONS - if description.key in coordinator.data + if description.key in vehicle.state_coordinator.data ) @@ -134,7 +134,7 @@ class TessieBinarySensorEntity(TessieEntity, BinarySensorEntity): def __init__( self, - coordinator: TessieDataUpdateCoordinator, + coordinator: TessieStateUpdateCoordinator, description: TessieBinarySensorEntityDescription, ) -> None: """Initialize the sensor.""" diff --git a/homeassistant/components/tessie/button.py b/homeassistant/components/tessie/button.py index 5d02d9fe8aa..df918d057a2 100644 --- a/homeassistant/components/tessie/button.py +++ b/homeassistant/components/tessie/button.py @@ -21,7 +21,7 @@ from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback from .const import DOMAIN -from .coordinator import TessieDataUpdateCoordinator +from .coordinator import TessieStateUpdateCoordinator from .entity import TessieEntity @@ -62,11 +62,11 @@ async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback ) -> None: """Set up the Tessie Button platform from a config entry.""" - coordinators = hass.data[DOMAIN][entry.entry_id] + data = hass.data[DOMAIN][entry.entry_id] async_add_entities( - TessieButtonEntity(coordinator, description) - for coordinator in coordinators + TessieButtonEntity(vehicle.state_coordinator, description) + for vehicle in data for description in DESCRIPTIONS ) @@ -78,7 +78,7 @@ class TessieButtonEntity(TessieEntity, ButtonEntity): def __init__( self, - coordinator: TessieDataUpdateCoordinator, + coordinator: TessieStateUpdateCoordinator, description: TessieButtonEntityDescription, ) -> None: """Initialize the Button.""" diff --git a/homeassistant/components/tessie/climate.py b/homeassistant/components/tessie/climate.py index 48fe73919cd..8d27305cb0b 100644 --- a/homeassistant/components/tessie/climate.py +++ b/homeassistant/components/tessie/climate.py @@ -21,7 +21,7 @@ from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback from .const import DOMAIN, TessieClimateKeeper -from .coordinator import TessieDataUpdateCoordinator +from .coordinator import TessieStateUpdateCoordinator from .entity import TessieEntity @@ -29,9 +29,11 @@ async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback ) -> None: """Set up the Tessie Climate platform from a config entry.""" - coordinators = hass.data[DOMAIN][entry.entry_id] + data = hass.data[DOMAIN][entry.entry_id] - async_add_entities(TessieClimateEntity(coordinator) for coordinator in coordinators) + async_add_entities( + TessieClimateEntity(vehicle.state_coordinator) for vehicle in data + ) class TessieClimateEntity(TessieEntity, ClimateEntity): @@ -54,7 +56,7 @@ class TessieClimateEntity(TessieEntity, ClimateEntity): def __init__( self, - coordinator: TessieDataUpdateCoordinator, + coordinator: TessieStateUpdateCoordinator, ) -> None: """Initialize the Climate entity.""" super().__init__(coordinator, "primary") diff --git a/homeassistant/components/tessie/coordinator.py b/homeassistant/components/tessie/coordinator.py index 0fdfbcc5345..c2f53da53bc 100644 --- a/homeassistant/components/tessie/coordinator.py +++ b/homeassistant/components/tessie/coordinator.py @@ -20,7 +20,7 @@ TESSIE_SYNC_INTERVAL = 10 _LOGGER = logging.getLogger(__name__) -class TessieDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]): +class TessieStateUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]): """Class to manage fetching data from the Tessie API.""" def __init__( diff --git a/homeassistant/components/tessie/cover.py b/homeassistant/components/tessie/cover.py index b7834a74766..dddda068d61 100644 --- a/homeassistant/components/tessie/cover.py +++ b/homeassistant/components/tessie/cover.py @@ -20,7 +20,7 @@ from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback from .const import DOMAIN -from .coordinator import TessieDataUpdateCoordinator +from .coordinator import TessieStateUpdateCoordinator from .entity import TessieEntity @@ -28,15 +28,15 @@ async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback ) -> None: """Set up the Tessie sensor platform from a config entry.""" - coordinators = hass.data[DOMAIN][entry.entry_id] + data = hass.data[DOMAIN][entry.entry_id] async_add_entities( - Entity(coordinator) + Entity(vehicle.state_coordinator) for Entity in ( TessieWindowEntity, TessieChargePortEntity, ) - for coordinator in coordinators + for vehicle in data ) @@ -46,7 +46,7 @@ class TessieWindowEntity(TessieEntity, CoverEntity): _attr_device_class = CoverDeviceClass.WINDOW _attr_supported_features = CoverEntityFeature.OPEN | CoverEntityFeature.CLOSE - def __init__(self, coordinator: TessieDataUpdateCoordinator) -> None: + def __init__(self, coordinator: TessieStateUpdateCoordinator) -> None: """Initialize the sensor.""" super().__init__(coordinator, "windows") @@ -87,7 +87,7 @@ class TessieChargePortEntity(TessieEntity, CoverEntity): _attr_device_class = CoverDeviceClass.DOOR _attr_supported_features = CoverEntityFeature.OPEN | CoverEntityFeature.CLOSE - def __init__(self, coordinator: TessieDataUpdateCoordinator) -> None: + def __init__(self, coordinator: TessieStateUpdateCoordinator) -> None: """Initialize the sensor.""" super().__init__(coordinator, "charge_state_charge_port_door_open") diff --git a/homeassistant/components/tessie/device_tracker.py b/homeassistant/components/tessie/device_tracker.py index 330623e55b4..2652a6247c8 100644 --- a/homeassistant/components/tessie/device_tracker.py +++ b/homeassistant/components/tessie/device_tracker.py @@ -9,7 +9,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.typing import StateType from .const import DOMAIN -from .coordinator import TessieDataUpdateCoordinator +from .coordinator import TessieStateUpdateCoordinator from .entity import TessieEntity @@ -17,15 +17,15 @@ async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback ) -> None: """Set up the Tessie device tracker platform from a config entry.""" - coordinators = hass.data[DOMAIN][entry.entry_id] + data = hass.data[DOMAIN][entry.entry_id] async_add_entities( - klass(coordinator) + klass(vehicle.state_coordinator) for klass in ( TessieDeviceTrackerLocationEntity, TessieDeviceTrackerRouteEntity, ) - for coordinator in coordinators + for vehicle in data ) @@ -34,7 +34,7 @@ class TessieDeviceTrackerEntity(TessieEntity, TrackerEntity): def __init__( self, - coordinator: TessieDataUpdateCoordinator, + coordinator: TessieStateUpdateCoordinator, ) -> None: """Initialize the device tracker.""" super().__init__(coordinator, self.key) diff --git a/homeassistant/components/tessie/entity.py b/homeassistant/components/tessie/entity.py index b7c04d35306..ecd7f863542 100644 --- a/homeassistant/components/tessie/entity.py +++ b/homeassistant/components/tessie/entity.py @@ -10,17 +10,17 @@ from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN, MODELS -from .coordinator import TessieDataUpdateCoordinator +from .coordinator import TessieStateUpdateCoordinator -class TessieEntity(CoordinatorEntity[TessieDataUpdateCoordinator]): +class TessieEntity(CoordinatorEntity[TessieStateUpdateCoordinator]): """Parent class for Tessie Entities.""" _attr_has_entity_name = True def __init__( self, - coordinator: TessieDataUpdateCoordinator, + coordinator: TessieStateUpdateCoordinator, key: str, ) -> None: """Initialize common aspects of a Tessie entity.""" diff --git a/homeassistant/components/tessie/lock.py b/homeassistant/components/tessie/lock.py index 3342747a2f9..25b9de4b579 100644 --- a/homeassistant/components/tessie/lock.py +++ b/homeassistant/components/tessie/lock.py @@ -11,7 +11,7 @@ from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback from .const import DOMAIN -from .coordinator import TessieDataUpdateCoordinator +from .coordinator import TessieStateUpdateCoordinator from .entity import TessieEntity @@ -19,9 +19,9 @@ async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback ) -> None: """Set up the Tessie sensor platform from a config entry.""" - coordinators = hass.data[DOMAIN][entry.entry_id] + data = hass.data[DOMAIN][entry.entry_id] - async_add_entities(TessieLockEntity(coordinator) for coordinator in coordinators) + async_add_entities(TessieLockEntity(vehicle.state_coordinator) for vehicle in data) class TessieLockEntity(TessieEntity, LockEntity): @@ -31,7 +31,7 @@ class TessieLockEntity(TessieEntity, LockEntity): def __init__( self, - coordinator: TessieDataUpdateCoordinator, + coordinator: TessieStateUpdateCoordinator, ) -> None: """Initialize the sensor.""" super().__init__(coordinator, "vehicle_state_locked") diff --git a/homeassistant/components/tessie/media_player.py b/homeassistant/components/tessie/media_player.py index ffbb6619668..544290de093 100644 --- a/homeassistant/components/tessie/media_player.py +++ b/homeassistant/components/tessie/media_player.py @@ -11,7 +11,7 @@ from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback from .const import DOMAIN -from .coordinator import TessieDataUpdateCoordinator +from .coordinator import TessieStateUpdateCoordinator from .entity import TessieEntity STATES = { @@ -25,9 +25,9 @@ async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback ) -> None: """Set up the Tessie Media platform from a config entry.""" - coordinators = hass.data[DOMAIN][entry.entry_id] + data = hass.data[DOMAIN][entry.entry_id] - async_add_entities(TessieMediaEntity(coordinator) for coordinator in coordinators) + async_add_entities(TessieMediaEntity(vehicle.state_coordinator) for vehicle in data) class TessieMediaEntity(TessieEntity, MediaPlayerEntity): @@ -38,7 +38,7 @@ class TessieMediaEntity(TessieEntity, MediaPlayerEntity): def __init__( self, - coordinator: TessieDataUpdateCoordinator, + coordinator: TessieStateUpdateCoordinator, ) -> None: """Initialize the media player entity.""" super().__init__(coordinator, "media") diff --git a/homeassistant/components/tessie/models.py b/homeassistant/components/tessie/models.py new file mode 100644 index 00000000000..32466a6b2ac --- /dev/null +++ b/homeassistant/components/tessie/models.py @@ -0,0 +1,13 @@ +"""The Tessie integration models.""" +from __future__ import annotations + +from dataclasses import dataclass + +from .coordinator import TessieStateUpdateCoordinator + + +@dataclass +class TessieVehicle: + """Data for the Tessie integration.""" + + state_coordinator: TessieStateUpdateCoordinator diff --git a/homeassistant/components/tessie/number.py b/homeassistant/components/tessie/number.py index b7c0e145d7b..ada088f1bd2 100644 --- a/homeassistant/components/tessie/number.py +++ b/homeassistant/components/tessie/number.py @@ -23,7 +23,7 @@ from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback from .const import DOMAIN -from .coordinator import TessieDataUpdateCoordinator +from .coordinator import TessieStateUpdateCoordinator from .entity import TessieEntity @@ -83,13 +83,13 @@ async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback ) -> None: """Set up the Tessie sensor platform from a config entry.""" - coordinators = hass.data[DOMAIN][entry.entry_id] + data = hass.data[DOMAIN][entry.entry_id] async_add_entities( - TessieNumberEntity(coordinator, description) - for coordinator in coordinators + TessieNumberEntity(vehicle.state_coordinator, description) + for vehicle in data for description in DESCRIPTIONS - if description.key in coordinator.data + if description.key in vehicle.state_coordinator.data ) @@ -100,7 +100,7 @@ class TessieNumberEntity(TessieEntity, NumberEntity): def __init__( self, - coordinator: TessieDataUpdateCoordinator, + coordinator: TessieStateUpdateCoordinator, description: TessieNumberEntityDescription, ) -> None: """Initialize the Number entity.""" diff --git a/homeassistant/components/tessie/select.py b/homeassistant/components/tessie/select.py index d40abed6478..03436b44cfc 100644 --- a/homeassistant/components/tessie/select.py +++ b/homeassistant/components/tessie/select.py @@ -26,13 +26,13 @@ async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback ) -> None: """Set up the Tessie select platform from a config entry.""" - coordinators = hass.data[DOMAIN][entry.entry_id] + data = hass.data[DOMAIN][entry.entry_id] async_add_entities( - TessieSeatHeaterSelectEntity(coordinator, key) - for coordinator in coordinators + TessieSeatHeaterSelectEntity(vehicle.state_coordinator, key) + for vehicle in data for key in SEAT_HEATERS - if key in coordinator.data + if key in vehicle.state_coordinator.data ) diff --git a/homeassistant/components/tessie/sensor.py b/homeassistant/components/tessie/sensor.py index 9023a3319ea..aaf37e51d61 100644 --- a/homeassistant/components/tessie/sensor.py +++ b/homeassistant/components/tessie/sensor.py @@ -28,7 +28,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.typing import StateType from .const import DOMAIN -from .coordinator import TessieDataUpdateCoordinator +from .coordinator import TessieStateUpdateCoordinator from .entity import TessieEntity @@ -188,13 +188,13 @@ async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback ) -> None: """Set up the Tessie sensor platform from a config entry.""" - coordinators = hass.data[DOMAIN][entry.entry_id] + data = hass.data[DOMAIN][entry.entry_id] async_add_entities( - TessieSensorEntity(coordinator, description) - for coordinator in coordinators + TessieSensorEntity(vehicle.state_coordinator, description) + for vehicle in data for description in DESCRIPTIONS - if description.key in coordinator.data + if description.key in vehicle.state_coordinator.data ) @@ -205,7 +205,7 @@ class TessieSensorEntity(TessieEntity, SensorEntity): def __init__( self, - coordinator: TessieDataUpdateCoordinator, + coordinator: TessieStateUpdateCoordinator, description: TessieSensorEntityDescription, ) -> None: """Initialize the sensor.""" diff --git a/homeassistant/components/tessie/switch.py b/homeassistant/components/tessie/switch.py index 2dd54cf7ed1..595c44e11be 100644 --- a/homeassistant/components/tessie/switch.py +++ b/homeassistant/components/tessie/switch.py @@ -28,7 +28,7 @@ from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback from .const import DOMAIN -from .coordinator import TessieDataUpdateCoordinator +from .coordinator import TessieStateUpdateCoordinator from .entity import TessieEntity @@ -78,14 +78,14 @@ async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback ) -> None: """Set up the Tessie Switch platform from a config entry.""" - coordinators = hass.data[DOMAIN][entry.entry_id] + data = hass.data[DOMAIN][entry.entry_id] async_add_entities( [ - TessieSwitchEntity(coordinator, description) - for coordinator in coordinators + TessieSwitchEntity(vehicle.state_coordinator, description) + for vehicle in data for description in DESCRIPTIONS - if description.key in coordinator.data + if description.key in vehicle.state_coordinator.data ] ) @@ -98,7 +98,7 @@ class TessieSwitchEntity(TessieEntity, SwitchEntity): def __init__( self, - coordinator: TessieDataUpdateCoordinator, + coordinator: TessieStateUpdateCoordinator, description: TessieSwitchEntityDescription, ) -> None: """Initialize the Switch.""" diff --git a/homeassistant/components/tessie/update.py b/homeassistant/components/tessie/update.py index 4a3c06df6e2..9628b580697 100644 --- a/homeassistant/components/tessie/update.py +++ b/homeassistant/components/tessie/update.py @@ -7,7 +7,7 @@ from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback from .const import DOMAIN, TessieUpdateStatus -from .coordinator import TessieDataUpdateCoordinator +from .coordinator import TessieStateUpdateCoordinator from .entity import TessieEntity @@ -15,9 +15,11 @@ async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback ) -> None: """Set up the Tessie Update platform from a config entry.""" - coordinators = hass.data[DOMAIN][entry.entry_id] + data = hass.data[DOMAIN][entry.entry_id] - async_add_entities(TessieUpdateEntity(coordinator) for coordinator in coordinators) + async_add_entities( + TessieUpdateEntity(vehicle.state_coordinator) for vehicle in data + ) class TessieUpdateEntity(TessieEntity, UpdateEntity): @@ -28,7 +30,7 @@ class TessieUpdateEntity(TessieEntity, UpdateEntity): def __init__( self, - coordinator: TessieDataUpdateCoordinator, + coordinator: TessieStateUpdateCoordinator, ) -> None: """Initialize the Update.""" super().__init__(coordinator, "update")