Add data model to Tessie (#106285)

Add data model
This commit is contained in:
Brett Adams 2023-12-25 22:01:13 +10:00 committed by GitHub
parent 123b2669f3
commit 04a56eaabe
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 92 additions and 72 deletions

View file

@ -12,7 +12,8 @@ from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.aiohttp_client import async_get_clientsession
from .const import DOMAIN from .const import DOMAIN
from .coordinator import TessieDataUpdateCoordinator from .coordinator import TessieStateUpdateCoordinator
from .models import TessieVehicle
PLATFORMS = [ PLATFORMS = [
Platform.BINARY_SENSOR, Platform.BINARY_SENSOR,
@ -50,18 +51,20 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
except ClientError as e: except ClientError as e:
raise ConfigEntryNotReady from e raise ConfigEntryNotReady from e
coordinators = [ data = [
TessieDataUpdateCoordinator( TessieVehicle(
hass, state_coordinator=TessieStateUpdateCoordinator(
api_key=api_key, hass,
vin=vehicle["vin"], api_key=api_key,
data=vehicle["last_state"], vin=vehicle["vin"],
data=vehicle["last_state"],
)
) )
for vehicle in vehicles["results"] for vehicle in vehicles["results"]
if vehicle["last_state"] is not None 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) await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
return True return True

View file

@ -15,7 +15,7 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DOMAIN, TessieStatus from .const import DOMAIN, TessieStatus
from .coordinator import TessieDataUpdateCoordinator from .coordinator import TessieStateUpdateCoordinator
from .entity import TessieEntity from .entity import TessieEntity
@ -117,13 +117,13 @@ async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None: ) -> None:
"""Set up the Tessie binary sensor platform from a config entry.""" """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( async_add_entities(
TessieBinarySensorEntity(coordinator, description) TessieBinarySensorEntity(vehicle.state_coordinator, description)
for coordinator in coordinators for vehicle in data
for description in DESCRIPTIONS 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__( def __init__(
self, self,
coordinator: TessieDataUpdateCoordinator, coordinator: TessieStateUpdateCoordinator,
description: TessieBinarySensorEntityDescription, description: TessieBinarySensorEntityDescription,
) -> None: ) -> None:
"""Initialize the sensor.""" """Initialize the sensor."""

View file

@ -21,7 +21,7 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DOMAIN from .const import DOMAIN
from .coordinator import TessieDataUpdateCoordinator from .coordinator import TessieStateUpdateCoordinator
from .entity import TessieEntity from .entity import TessieEntity
@ -62,11 +62,11 @@ async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None: ) -> None:
"""Set up the Tessie Button platform from a config entry.""" """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( async_add_entities(
TessieButtonEntity(coordinator, description) TessieButtonEntity(vehicle.state_coordinator, description)
for coordinator in coordinators for vehicle in data
for description in DESCRIPTIONS for description in DESCRIPTIONS
) )
@ -78,7 +78,7 @@ class TessieButtonEntity(TessieEntity, ButtonEntity):
def __init__( def __init__(
self, self,
coordinator: TessieDataUpdateCoordinator, coordinator: TessieStateUpdateCoordinator,
description: TessieButtonEntityDescription, description: TessieButtonEntityDescription,
) -> None: ) -> None:
"""Initialize the Button.""" """Initialize the Button."""

View file

@ -21,7 +21,7 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DOMAIN, TessieClimateKeeper from .const import DOMAIN, TessieClimateKeeper
from .coordinator import TessieDataUpdateCoordinator from .coordinator import TessieStateUpdateCoordinator
from .entity import TessieEntity from .entity import TessieEntity
@ -29,9 +29,11 @@ async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None: ) -> None:
"""Set up the Tessie Climate platform from a config entry.""" """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): class TessieClimateEntity(TessieEntity, ClimateEntity):
@ -54,7 +56,7 @@ class TessieClimateEntity(TessieEntity, ClimateEntity):
def __init__( def __init__(
self, self,
coordinator: TessieDataUpdateCoordinator, coordinator: TessieStateUpdateCoordinator,
) -> None: ) -> None:
"""Initialize the Climate entity.""" """Initialize the Climate entity."""
super().__init__(coordinator, "primary") super().__init__(coordinator, "primary")

View file

@ -20,7 +20,7 @@ TESSIE_SYNC_INTERVAL = 10
_LOGGER = logging.getLogger(__name__) _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.""" """Class to manage fetching data from the Tessie API."""
def __init__( def __init__(

View file

@ -20,7 +20,7 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DOMAIN from .const import DOMAIN
from .coordinator import TessieDataUpdateCoordinator from .coordinator import TessieStateUpdateCoordinator
from .entity import TessieEntity from .entity import TessieEntity
@ -28,15 +28,15 @@ async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None: ) -> None:
"""Set up the Tessie sensor platform from a config entry.""" """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( async_add_entities(
Entity(coordinator) Entity(vehicle.state_coordinator)
for Entity in ( for Entity in (
TessieWindowEntity, TessieWindowEntity,
TessieChargePortEntity, TessieChargePortEntity,
) )
for coordinator in coordinators for vehicle in data
) )
@ -46,7 +46,7 @@ class TessieWindowEntity(TessieEntity, CoverEntity):
_attr_device_class = CoverDeviceClass.WINDOW _attr_device_class = CoverDeviceClass.WINDOW
_attr_supported_features = CoverEntityFeature.OPEN | CoverEntityFeature.CLOSE _attr_supported_features = CoverEntityFeature.OPEN | CoverEntityFeature.CLOSE
def __init__(self, coordinator: TessieDataUpdateCoordinator) -> None: def __init__(self, coordinator: TessieStateUpdateCoordinator) -> None:
"""Initialize the sensor.""" """Initialize the sensor."""
super().__init__(coordinator, "windows") super().__init__(coordinator, "windows")
@ -87,7 +87,7 @@ class TessieChargePortEntity(TessieEntity, CoverEntity):
_attr_device_class = CoverDeviceClass.DOOR _attr_device_class = CoverDeviceClass.DOOR
_attr_supported_features = CoverEntityFeature.OPEN | CoverEntityFeature.CLOSE _attr_supported_features = CoverEntityFeature.OPEN | CoverEntityFeature.CLOSE
def __init__(self, coordinator: TessieDataUpdateCoordinator) -> None: def __init__(self, coordinator: TessieStateUpdateCoordinator) -> None:
"""Initialize the sensor.""" """Initialize the sensor."""
super().__init__(coordinator, "charge_state_charge_port_door_open") super().__init__(coordinator, "charge_state_charge_port_door_open")

View file

@ -9,7 +9,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import StateType from homeassistant.helpers.typing import StateType
from .const import DOMAIN from .const import DOMAIN
from .coordinator import TessieDataUpdateCoordinator from .coordinator import TessieStateUpdateCoordinator
from .entity import TessieEntity from .entity import TessieEntity
@ -17,15 +17,15 @@ async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None: ) -> None:
"""Set up the Tessie device tracker platform from a config entry.""" """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( async_add_entities(
klass(coordinator) klass(vehicle.state_coordinator)
for klass in ( for klass in (
TessieDeviceTrackerLocationEntity, TessieDeviceTrackerLocationEntity,
TessieDeviceTrackerRouteEntity, TessieDeviceTrackerRouteEntity,
) )
for coordinator in coordinators for vehicle in data
) )
@ -34,7 +34,7 @@ class TessieDeviceTrackerEntity(TessieEntity, TrackerEntity):
def __init__( def __init__(
self, self,
coordinator: TessieDataUpdateCoordinator, coordinator: TessieStateUpdateCoordinator,
) -> None: ) -> None:
"""Initialize the device tracker.""" """Initialize the device tracker."""
super().__init__(coordinator, self.key) super().__init__(coordinator, self.key)

View file

@ -10,17 +10,17 @@ from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.helpers.update_coordinator import CoordinatorEntity
from .const import DOMAIN, MODELS 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.""" """Parent class for Tessie Entities."""
_attr_has_entity_name = True _attr_has_entity_name = True
def __init__( def __init__(
self, self,
coordinator: TessieDataUpdateCoordinator, coordinator: TessieStateUpdateCoordinator,
key: str, key: str,
) -> None: ) -> None:
"""Initialize common aspects of a Tessie entity.""" """Initialize common aspects of a Tessie entity."""

View file

@ -11,7 +11,7 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DOMAIN from .const import DOMAIN
from .coordinator import TessieDataUpdateCoordinator from .coordinator import TessieStateUpdateCoordinator
from .entity import TessieEntity from .entity import TessieEntity
@ -19,9 +19,9 @@ async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None: ) -> None:
"""Set up the Tessie sensor platform from a config entry.""" """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): class TessieLockEntity(TessieEntity, LockEntity):
@ -31,7 +31,7 @@ class TessieLockEntity(TessieEntity, LockEntity):
def __init__( def __init__(
self, self,
coordinator: TessieDataUpdateCoordinator, coordinator: TessieStateUpdateCoordinator,
) -> None: ) -> None:
"""Initialize the sensor.""" """Initialize the sensor."""
super().__init__(coordinator, "vehicle_state_locked") super().__init__(coordinator, "vehicle_state_locked")

View file

@ -11,7 +11,7 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DOMAIN from .const import DOMAIN
from .coordinator import TessieDataUpdateCoordinator from .coordinator import TessieStateUpdateCoordinator
from .entity import TessieEntity from .entity import TessieEntity
STATES = { STATES = {
@ -25,9 +25,9 @@ async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None: ) -> None:
"""Set up the Tessie Media platform from a config entry.""" """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): class TessieMediaEntity(TessieEntity, MediaPlayerEntity):
@ -38,7 +38,7 @@ class TessieMediaEntity(TessieEntity, MediaPlayerEntity):
def __init__( def __init__(
self, self,
coordinator: TessieDataUpdateCoordinator, coordinator: TessieStateUpdateCoordinator,
) -> None: ) -> None:
"""Initialize the media player entity.""" """Initialize the media player entity."""
super().__init__(coordinator, "media") super().__init__(coordinator, "media")

View file

@ -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

View file

@ -23,7 +23,7 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DOMAIN from .const import DOMAIN
from .coordinator import TessieDataUpdateCoordinator from .coordinator import TessieStateUpdateCoordinator
from .entity import TessieEntity from .entity import TessieEntity
@ -83,13 +83,13 @@ async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None: ) -> None:
"""Set up the Tessie sensor platform from a config entry.""" """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( async_add_entities(
TessieNumberEntity(coordinator, description) TessieNumberEntity(vehicle.state_coordinator, description)
for coordinator in coordinators for vehicle in data
for description in DESCRIPTIONS 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__( def __init__(
self, self,
coordinator: TessieDataUpdateCoordinator, coordinator: TessieStateUpdateCoordinator,
description: TessieNumberEntityDescription, description: TessieNumberEntityDescription,
) -> None: ) -> None:
"""Initialize the Number entity.""" """Initialize the Number entity."""

View file

@ -26,13 +26,13 @@ async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None: ) -> None:
"""Set up the Tessie select platform from a config entry.""" """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( async_add_entities(
TessieSeatHeaterSelectEntity(coordinator, key) TessieSeatHeaterSelectEntity(vehicle.state_coordinator, key)
for coordinator in coordinators for vehicle in data
for key in SEAT_HEATERS for key in SEAT_HEATERS
if key in coordinator.data if key in vehicle.state_coordinator.data
) )

View file

@ -28,7 +28,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import StateType from homeassistant.helpers.typing import StateType
from .const import DOMAIN from .const import DOMAIN
from .coordinator import TessieDataUpdateCoordinator from .coordinator import TessieStateUpdateCoordinator
from .entity import TessieEntity from .entity import TessieEntity
@ -188,13 +188,13 @@ async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None: ) -> None:
"""Set up the Tessie sensor platform from a config entry.""" """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( async_add_entities(
TessieSensorEntity(coordinator, description) TessieSensorEntity(vehicle.state_coordinator, description)
for coordinator in coordinators for vehicle in data
for description in DESCRIPTIONS 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__( def __init__(
self, self,
coordinator: TessieDataUpdateCoordinator, coordinator: TessieStateUpdateCoordinator,
description: TessieSensorEntityDescription, description: TessieSensorEntityDescription,
) -> None: ) -> None:
"""Initialize the sensor.""" """Initialize the sensor."""

View file

@ -28,7 +28,7 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DOMAIN from .const import DOMAIN
from .coordinator import TessieDataUpdateCoordinator from .coordinator import TessieStateUpdateCoordinator
from .entity import TessieEntity from .entity import TessieEntity
@ -78,14 +78,14 @@ async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None: ) -> None:
"""Set up the Tessie Switch platform from a config entry.""" """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( async_add_entities(
[ [
TessieSwitchEntity(coordinator, description) TessieSwitchEntity(vehicle.state_coordinator, description)
for coordinator in coordinators for vehicle in data
for description in DESCRIPTIONS 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__( def __init__(
self, self,
coordinator: TessieDataUpdateCoordinator, coordinator: TessieStateUpdateCoordinator,
description: TessieSwitchEntityDescription, description: TessieSwitchEntityDescription,
) -> None: ) -> None:
"""Initialize the Switch.""" """Initialize the Switch."""

View file

@ -7,7 +7,7 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DOMAIN, TessieUpdateStatus from .const import DOMAIN, TessieUpdateStatus
from .coordinator import TessieDataUpdateCoordinator from .coordinator import TessieStateUpdateCoordinator
from .entity import TessieEntity from .entity import TessieEntity
@ -15,9 +15,11 @@ async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None: ) -> None:
"""Set up the Tessie Update platform from a config entry.""" """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): class TessieUpdateEntity(TessieEntity, UpdateEntity):
@ -28,7 +30,7 @@ class TessieUpdateEntity(TessieEntity, UpdateEntity):
def __init__( def __init__(
self, self,
coordinator: TessieDataUpdateCoordinator, coordinator: TessieStateUpdateCoordinator,
) -> None: ) -> None:
"""Initialize the Update.""" """Initialize the Update."""
super().__init__(coordinator, "update") super().__init__(coordinator, "update")