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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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 .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."""

View File

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

View File

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

View File

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

View File

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