mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 08:47:57 +00:00
Refactor Tessie for future PR (#120406)
* Bump tessie-api * Refactor * revert bump * Fix cover * Apply suggestions from code review Co-authored-by: G Johansson <goran.johansson@shiftit.se> --------- Co-authored-by: G Johansson <goran.johansson@shiftit.se>
This commit is contained in:
parent
a8bf671663
commit
d4dc7d76d9
@ -11,9 +11,11 @@ from homeassistant.const import CONF_ACCESS_TOKEN, Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
|
||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
from homeassistant.helpers.device_registry import DeviceInfo
|
||||
|
||||
from .const import DOMAIN, MODELS
|
||||
from .coordinator import TessieStateUpdateCoordinator
|
||||
from .models import TessieData
|
||||
from .models import TessieData, TessieVehicleData
|
||||
|
||||
PLATFORMS = [
|
||||
Platform.BINARY_SENSOR,
|
||||
@ -40,7 +42,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: TessieConfigEntry) -> bo
|
||||
api_key = entry.data[CONF_ACCESS_TOKEN]
|
||||
|
||||
try:
|
||||
vehicles = await get_state_of_all_vehicles(
|
||||
state_of_all_vehicles = await get_state_of_all_vehicles(
|
||||
session=async_get_clientsession(hass),
|
||||
api_key=api_key,
|
||||
only_active=True,
|
||||
@ -54,13 +56,31 @@ async def async_setup_entry(hass: HomeAssistant, entry: TessieConfigEntry) -> bo
|
||||
raise ConfigEntryNotReady from e
|
||||
|
||||
vehicles = [
|
||||
TessieStateUpdateCoordinator(
|
||||
hass,
|
||||
api_key=api_key,
|
||||
TessieVehicleData(
|
||||
vin=vehicle["vin"],
|
||||
data=vehicle["last_state"],
|
||||
data_coordinator=TessieStateUpdateCoordinator(
|
||||
hass,
|
||||
api_key=api_key,
|
||||
vin=vehicle["vin"],
|
||||
data=vehicle["last_state"],
|
||||
),
|
||||
device=DeviceInfo(
|
||||
identifiers={(DOMAIN, vehicle["vin"])},
|
||||
manufacturer="Tesla",
|
||||
configuration_url="https://my.tessie.com/",
|
||||
name=vehicle["last_state"]["display_name"],
|
||||
model=MODELS.get(
|
||||
vehicle["last_state"]["vehicle_config"]["car_type"],
|
||||
vehicle["last_state"]["vehicle_config"]["car_type"],
|
||||
),
|
||||
sw_version=vehicle["last_state"]["vehicle_state"]["car_version"].split(
|
||||
" "
|
||||
)[0],
|
||||
hw_version=vehicle["last_state"]["vehicle_config"]["driver_assist"],
|
||||
serial_number=vehicle["vin"],
|
||||
),
|
||||
)
|
||||
for vehicle in vehicles["results"]
|
||||
for vehicle in state_of_all_vehicles["results"]
|
||||
if vehicle["last_state"] is not None
|
||||
]
|
||||
|
||||
|
@ -16,8 +16,8 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from . import TessieConfigEntry
|
||||
from .const import TessieState
|
||||
from .coordinator import TessieStateUpdateCoordinator
|
||||
from .entity import TessieEntity
|
||||
from .models import TessieVehicleData
|
||||
|
||||
|
||||
@dataclass(frozen=True, kw_only=True)
|
||||
@ -180,11 +180,11 @@ class TessieBinarySensorEntity(TessieEntity, BinarySensorEntity):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
coordinator: TessieStateUpdateCoordinator,
|
||||
vehicle: TessieVehicleData,
|
||||
description: TessieBinarySensorEntityDescription,
|
||||
) -> None:
|
||||
"""Initialize the sensor."""
|
||||
super().__init__(coordinator, description.key)
|
||||
super().__init__(vehicle, description.key)
|
||||
self.entity_description = description
|
||||
|
||||
@property
|
||||
|
@ -19,8 +19,8 @@ from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from . import TessieConfigEntry
|
||||
from .coordinator import TessieStateUpdateCoordinator
|
||||
from .entity import TessieEntity
|
||||
from .models import TessieVehicleData
|
||||
|
||||
|
||||
@dataclass(frozen=True, kw_only=True)
|
||||
@ -67,11 +67,11 @@ class TessieButtonEntity(TessieEntity, ButtonEntity):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
coordinator: TessieStateUpdateCoordinator,
|
||||
vehicle: TessieVehicleData,
|
||||
description: TessieButtonEntityDescription,
|
||||
) -> None:
|
||||
"""Initialize the Button."""
|
||||
super().__init__(coordinator, description.key)
|
||||
super().__init__(vehicle, description.key)
|
||||
self.entity_description = description
|
||||
|
||||
async def async_press(self) -> None:
|
||||
|
@ -23,8 +23,8 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from . import TessieConfigEntry
|
||||
from .const import TessieClimateKeeper
|
||||
from .coordinator import TessieStateUpdateCoordinator
|
||||
from .entity import TessieEntity
|
||||
from .models import TessieVehicleData
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
@ -62,10 +62,10 @@ class TessieClimateEntity(TessieEntity, ClimateEntity):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
coordinator: TessieStateUpdateCoordinator,
|
||||
vehicle: TessieVehicleData,
|
||||
) -> None:
|
||||
"""Initialize the Climate entity."""
|
||||
super().__init__(coordinator, "primary")
|
||||
super().__init__(vehicle, "primary")
|
||||
|
||||
@property
|
||||
def hvac_mode(self) -> HVACMode | None:
|
||||
|
@ -23,8 +23,8 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from . import TessieConfigEntry
|
||||
from .const import TessieCoverStates
|
||||
from .coordinator import TessieStateUpdateCoordinator
|
||||
from .entity import TessieEntity
|
||||
from .models import TessieVehicleData
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
@ -53,9 +53,9 @@ class TessieWindowEntity(TessieEntity, CoverEntity):
|
||||
_attr_device_class = CoverDeviceClass.WINDOW
|
||||
_attr_supported_features = CoverEntityFeature.OPEN | CoverEntityFeature.CLOSE
|
||||
|
||||
def __init__(self, coordinator: TessieStateUpdateCoordinator) -> None:
|
||||
def __init__(self, vehicle: TessieVehicleData) -> None:
|
||||
"""Initialize the sensor."""
|
||||
super().__init__(coordinator, "windows")
|
||||
super().__init__(vehicle, "windows")
|
||||
|
||||
@property
|
||||
def is_closed(self) -> bool | None:
|
||||
@ -94,9 +94,9 @@ class TessieChargePortEntity(TessieEntity, CoverEntity):
|
||||
_attr_device_class = CoverDeviceClass.DOOR
|
||||
_attr_supported_features = CoverEntityFeature.OPEN | CoverEntityFeature.CLOSE
|
||||
|
||||
def __init__(self, coordinator: TessieStateUpdateCoordinator) -> None:
|
||||
def __init__(self, vehicle: TessieVehicleData) -> None:
|
||||
"""Initialize the sensor."""
|
||||
super().__init__(coordinator, "charge_state_charge_port_door_open")
|
||||
super().__init__(vehicle, "charge_state_charge_port_door_open")
|
||||
|
||||
@property
|
||||
def is_closed(self) -> bool | None:
|
||||
@ -120,9 +120,9 @@ class TessieFrontTrunkEntity(TessieEntity, CoverEntity):
|
||||
_attr_device_class = CoverDeviceClass.DOOR
|
||||
_attr_supported_features = CoverEntityFeature.OPEN
|
||||
|
||||
def __init__(self, coordinator: TessieStateUpdateCoordinator) -> None:
|
||||
def __init__(self, vehicle: TessieVehicleData) -> None:
|
||||
"""Initialize the sensor."""
|
||||
super().__init__(coordinator, "vehicle_state_ft")
|
||||
super().__init__(vehicle, "vehicle_state_ft")
|
||||
|
||||
@property
|
||||
def is_closed(self) -> bool | None:
|
||||
@ -141,9 +141,9 @@ class TessieRearTrunkEntity(TessieEntity, CoverEntity):
|
||||
_attr_device_class = CoverDeviceClass.DOOR
|
||||
_attr_supported_features = CoverEntityFeature.OPEN | CoverEntityFeature.CLOSE
|
||||
|
||||
def __init__(self, coordinator: TessieStateUpdateCoordinator) -> None:
|
||||
def __init__(self, vehicle: TessieVehicleData) -> None:
|
||||
"""Initialize the sensor."""
|
||||
super().__init__(coordinator, "vehicle_state_rt")
|
||||
super().__init__(vehicle, "vehicle_state_rt")
|
||||
|
||||
@property
|
||||
def is_closed(self) -> bool | None:
|
||||
|
@ -9,8 +9,8 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.typing import StateType
|
||||
|
||||
from . import TessieConfigEntry
|
||||
from .coordinator import TessieStateUpdateCoordinator
|
||||
from .entity import TessieEntity
|
||||
from .models import TessieVehicleData
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
@ -36,10 +36,10 @@ class TessieDeviceTrackerEntity(TessieEntity, TrackerEntity):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
coordinator: TessieStateUpdateCoordinator,
|
||||
vehicle: TessieVehicleData,
|
||||
) -> None:
|
||||
"""Initialize the device tracker."""
|
||||
super().__init__(coordinator, self.key)
|
||||
super().__init__(vehicle, self.key)
|
||||
|
||||
@property
|
||||
def source_type(self) -> SourceType | str:
|
||||
|
@ -6,11 +6,11 @@ from typing import Any
|
||||
from aiohttp import ClientResponseError
|
||||
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers.device_registry import DeviceInfo
|
||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||
|
||||
from .const import DOMAIN, MODELS
|
||||
from .const import DOMAIN
|
||||
from .coordinator import TessieStateUpdateCoordinator
|
||||
from .models import TessieVehicleData
|
||||
|
||||
|
||||
class TessieEntity(CoordinatorEntity[TessieStateUpdateCoordinator]):
|
||||
@ -20,28 +20,17 @@ class TessieEntity(CoordinatorEntity[TessieStateUpdateCoordinator]):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
coordinator: TessieStateUpdateCoordinator,
|
||||
vehicle: TessieVehicleData,
|
||||
key: str,
|
||||
) -> None:
|
||||
"""Initialize common aspects of a Tessie entity."""
|
||||
super().__init__(coordinator)
|
||||
self.vin = coordinator.vin
|
||||
super().__init__(vehicle.data_coordinator)
|
||||
self.vin = vehicle.vin
|
||||
self.key = key
|
||||
|
||||
car_type = coordinator.data["vehicle_config_car_type"]
|
||||
|
||||
self._attr_translation_key = key
|
||||
self._attr_unique_id = f"{self.vin}-{key}"
|
||||
self._attr_device_info = DeviceInfo(
|
||||
identifiers={(DOMAIN, self.vin)},
|
||||
manufacturer="Tesla",
|
||||
configuration_url="https://my.tessie.com/",
|
||||
name=coordinator.data["display_name"],
|
||||
model=MODELS.get(car_type, car_type),
|
||||
sw_version=coordinator.data["vehicle_state_car_version"].split(" ")[0],
|
||||
hw_version=coordinator.data["vehicle_config_driver_assist"],
|
||||
serial_number=self.vin,
|
||||
)
|
||||
self._attr_unique_id = f"{vehicle.vin}-{key}"
|
||||
self._attr_device_info = vehicle.device
|
||||
|
||||
@property
|
||||
def _value(self) -> Any:
|
||||
|
@ -23,8 +23,8 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from . import TessieConfigEntry
|
||||
from .const import DOMAIN, TessieChargeCableLockStates
|
||||
from .coordinator import TessieStateUpdateCoordinator
|
||||
from .entity import TessieEntity
|
||||
from .models import TessieVehicleData
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
@ -82,10 +82,10 @@ class TessieLockEntity(TessieEntity, LockEntity):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
coordinator: TessieStateUpdateCoordinator,
|
||||
vehicle: TessieVehicleData,
|
||||
) -> None:
|
||||
"""Initialize the sensor."""
|
||||
super().__init__(coordinator, "vehicle_state_locked")
|
||||
super().__init__(vehicle, "vehicle_state_locked")
|
||||
|
||||
@property
|
||||
def is_locked(self) -> bool | None:
|
||||
@ -110,10 +110,10 @@ class TessieSpeedLimitEntity(TessieEntity, LockEntity):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
coordinator: TessieStateUpdateCoordinator,
|
||||
vehicle: TessieVehicleData,
|
||||
) -> None:
|
||||
"""Initialize the sensor."""
|
||||
super().__init__(coordinator, "vehicle_state_speed_limit_mode_active")
|
||||
super().__init__(vehicle, "vehicle_state_speed_limit_mode_active")
|
||||
|
||||
@property
|
||||
def is_locked(self) -> bool | None:
|
||||
@ -160,10 +160,10 @@ class TessieCableLockEntity(TessieEntity, LockEntity):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
coordinator: TessieStateUpdateCoordinator,
|
||||
vehicle: TessieVehicleData,
|
||||
) -> None:
|
||||
"""Initialize the sensor."""
|
||||
super().__init__(coordinator, "charge_state_charge_port_latch")
|
||||
super().__init__(vehicle, "charge_state_charge_port_latch")
|
||||
|
||||
@property
|
||||
def is_locked(self) -> bool | None:
|
||||
|
@ -11,8 +11,8 @@ from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from . import TessieConfigEntry
|
||||
from .coordinator import TessieStateUpdateCoordinator
|
||||
from .entity import TessieEntity
|
||||
from .models import TessieVehicleData
|
||||
|
||||
STATES = {
|
||||
"Playing": MediaPlayerState.PLAYING,
|
||||
@ -39,10 +39,10 @@ class TessieMediaEntity(TessieEntity, MediaPlayerEntity):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
coordinator: TessieStateUpdateCoordinator,
|
||||
vehicle: TessieVehicleData,
|
||||
) -> None:
|
||||
"""Initialize the media player entity."""
|
||||
super().__init__(coordinator, "media")
|
||||
super().__init__(vehicle, "media")
|
||||
|
||||
@property
|
||||
def state(self) -> MediaPlayerState:
|
||||
|
@ -4,6 +4,8 @@ from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
|
||||
from homeassistant.helpers.device_registry import DeviceInfo
|
||||
|
||||
from .coordinator import TessieStateUpdateCoordinator
|
||||
|
||||
|
||||
@ -11,4 +13,13 @@ from .coordinator import TessieStateUpdateCoordinator
|
||||
class TessieData:
|
||||
"""Data for the Tessie integration."""
|
||||
|
||||
vehicles: list[TessieStateUpdateCoordinator]
|
||||
vehicles: list[TessieVehicleData]
|
||||
|
||||
|
||||
@dataclass
|
||||
class TessieVehicleData:
|
||||
"""Data for a Tessie vehicle."""
|
||||
|
||||
data_coordinator: TessieStateUpdateCoordinator
|
||||
device: DeviceInfo
|
||||
vin: str
|
||||
|
@ -23,8 +23,8 @@ from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from . import TessieConfigEntry
|
||||
from .coordinator import TessieStateUpdateCoordinator
|
||||
from .entity import TessieEntity
|
||||
from .models import TessieVehicleData
|
||||
|
||||
|
||||
@dataclass(frozen=True, kw_only=True)
|
||||
@ -101,11 +101,11 @@ class TessieNumberEntity(TessieEntity, NumberEntity):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
coordinator: TessieStateUpdateCoordinator,
|
||||
vehicle: TessieVehicleData,
|
||||
description: TessieNumberEntityDescription,
|
||||
) -> None:
|
||||
"""Initialize the Number entity."""
|
||||
super().__init__(coordinator, description.key)
|
||||
super().__init__(vehicle, description.key)
|
||||
self.entity_description = description
|
||||
|
||||
@property
|
||||
|
@ -35,7 +35,8 @@ async def async_setup_entry(
|
||||
TessieSeatHeaterSelectEntity(vehicle, key)
|
||||
for vehicle in data.vehicles
|
||||
for key in SEAT_HEATERS
|
||||
if key in vehicle.data # not all vehicles have rear center or third row
|
||||
if key
|
||||
in vehicle.data_coordinator.data # not all vehicles have rear center or third row
|
||||
)
|
||||
|
||||
|
||||
|
@ -34,8 +34,8 @@ from homeassistant.util.variance import ignore_variance
|
||||
|
||||
from . import TessieConfigEntry
|
||||
from .const import TessieChargeStates
|
||||
from .coordinator import TessieStateUpdateCoordinator
|
||||
from .entity import TessieEntity
|
||||
from .models import TessieVehicleData
|
||||
|
||||
|
||||
@callback
|
||||
@ -280,11 +280,11 @@ class TessieSensorEntity(TessieEntity, SensorEntity):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
coordinator: TessieStateUpdateCoordinator,
|
||||
vehicle: TessieVehicleData,
|
||||
description: TessieSensorEntityDescription,
|
||||
) -> None:
|
||||
"""Initialize the sensor."""
|
||||
super().__init__(coordinator, description.key)
|
||||
super().__init__(vehicle, description.key)
|
||||
self.entity_description = description
|
||||
|
||||
@property
|
||||
|
@ -29,8 +29,8 @@ from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from . import TessieConfigEntry
|
||||
from .coordinator import TessieStateUpdateCoordinator
|
||||
from .entity import TessieEntity
|
||||
from .models import TessieVehicleData
|
||||
|
||||
|
||||
@dataclass(frozen=True, kw_only=True)
|
||||
@ -84,7 +84,7 @@ async def async_setup_entry(
|
||||
TessieSwitchEntity(vehicle, description)
|
||||
for vehicle in entry.runtime_data.vehicles
|
||||
for description in DESCRIPTIONS
|
||||
if description.key in vehicle.data
|
||||
if description.key in vehicle.data_coordinator.data
|
||||
),
|
||||
(
|
||||
TessieChargeSwitchEntity(vehicle, CHARGE_DESCRIPTION)
|
||||
@ -102,11 +102,11 @@ class TessieSwitchEntity(TessieEntity, SwitchEntity):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
coordinator: TessieStateUpdateCoordinator,
|
||||
vehicle: TessieVehicleData,
|
||||
description: TessieSwitchEntityDescription,
|
||||
) -> None:
|
||||
"""Initialize the Switch."""
|
||||
super().__init__(coordinator, description.key)
|
||||
super().__init__(vehicle, description.key)
|
||||
self.entity_description = description
|
||||
|
||||
@property
|
||||
|
@ -12,8 +12,8 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from . import TessieConfigEntry
|
||||
from .const import TessieUpdateStatus
|
||||
from .coordinator import TessieStateUpdateCoordinator
|
||||
from .entity import TessieEntity
|
||||
from .models import TessieVehicleData
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
@ -34,10 +34,10 @@ class TessieUpdateEntity(TessieEntity, UpdateEntity):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
coordinator: TessieStateUpdateCoordinator,
|
||||
vehicle: TessieVehicleData,
|
||||
) -> None:
|
||||
"""Initialize the Update."""
|
||||
super().__init__(coordinator, "update")
|
||||
super().__init__(vehicle, "update")
|
||||
|
||||
@property
|
||||
def supported_features(self) -> UpdateEntityFeature:
|
||||
|
Loading…
x
Reference in New Issue
Block a user