diff --git a/custom_components/volvo_cars/binary_sensor.py b/custom_components/volvo_cars/binary_sensor.py index e13b222..23acd79 100644 --- a/custom_components/volvo_cars/binary_sensor.py +++ b/custom_components/volvo_cars/binary_sensor.py @@ -12,8 +12,10 @@ from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback +from .entity_description import VolvoCarsDescription + from .coordinator import VolvoCarsConfigEntry, VolvoCarsDataCoordinator -from .entity import VolvoCarsDescription, VolvoCarsEntity, value_to_translation_key +from .entity import VolvoCarsEntity, value_to_translation_key from .volvo.models import VolvoCarsApiBaseModel, VolvoCarsValue PARALLEL_UPDATES = 0 diff --git a/custom_components/volvo_cars/button.py b/custom_components/volvo_cars/button.py index 81b58bc..dc115e9 100644 --- a/custom_components/volvo_cars/button.py +++ b/custom_components/volvo_cars/button.py @@ -10,9 +10,11 @@ from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.entity_platform import AddEntitiesCallback +from .entity_description import VolvoCarsDescription + from .const import ATTR_API_TIMESTAMP, ATTR_LAST_RESULT from .coordinator import VolvoCarsConfigEntry, VolvoCarsDataCoordinator -from .entity import VolvoCarsDescription, VolvoCarsEntity +from .entity import VolvoCarsEntity from .volvo.models import VolvoApiException PARALLEL_UPDATES = 0 diff --git a/custom_components/volvo_cars/coordinator.py b/custom_components/volvo_cars/coordinator.py index 1d9e65d..dd4104e 100644 --- a/custom_components/volvo_cars/coordinator.py +++ b/custom_components/volvo_cars/coordinator.py @@ -18,6 +18,7 @@ from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed from .const import DOMAIN, MANUFACTURER +from .entity_description import VolvoCarsDescription from .entry_data import StoreData, VolvoCarsStore from .volvo.api import VolvoCarsApi from .volvo.auth import VolvoCarsAuthApi @@ -76,6 +77,23 @@ def __init__( self.supports_windows: bool = False self.unsupported_keys: list[str] = [] + def get_api_field( + self, description: VolvoCarsDescription + ) -> VolvoCarsApiBaseModel | None: + """Get the API field based on the entity description.""" + + if isinstance(description.api_field, str): + return ( + self.data.get(description.api_field) if description.api_field else None + ) + + if isinstance(description.api_field, list): + for key in description.api_field: + if (field := self.data.get(key)) is not None: + return field + + return None + async def _async_setup(self) -> None: """Set up the coordinator. diff --git a/custom_components/volvo_cars/device_tracker.py b/custom_components/volvo_cars/device_tracker.py index 7ccc67f..1a8f2b7 100644 --- a/custom_components/volvo_cars/device_tracker.py +++ b/custom_components/volvo_cars/device_tracker.py @@ -10,9 +10,11 @@ from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback +from .entity_description import VolvoCarsDescription + from .const import ATTR_API_TIMESTAMP, ATTR_DIRECTION from .coordinator import VolvoCarsConfigEntry, VolvoCarsDataCoordinator -from .entity import VolvoCarsDescription, VolvoCarsEntity +from .entity import VolvoCarsEntity from .volvo.models import VolvoCarsApiBaseModel, VolvoCarsLocation PARALLEL_UPDATES = 0 diff --git a/custom_components/volvo_cars/entity.py b/custom_components/volvo_cars/entity.py index 7df6260..b39c96a 100644 --- a/custom_components/volvo_cars/entity.py +++ b/custom_components/volvo_cars/entity.py @@ -1,10 +1,8 @@ """Volvo Cars base entity.""" -from dataclasses import dataclass - +from custom_components.volvo_cars.entity_description import VolvoCarsDescription from homeassistant.const import CONF_FRIENDLY_NAME, Platform from homeassistant.core import callback -from homeassistant.helpers.entity import EntityDescription from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import ATTR_API_TIMESTAMP, MANUFACTURER @@ -34,13 +32,6 @@ def value_to_translation_key(value: str) -> str: return value.lower() -@dataclass(frozen=True, kw_only=True) -class VolvoCarsDescription(EntityDescription): - """Describes a Volvo Cars entity.""" - - api_field: str | list[str] - - class VolvoCarsEntity(CoordinatorEntity[VolvoCarsDataCoordinator]): """Volvo Cars base entity.""" @@ -69,19 +60,7 @@ async def async_added_to_hass(self) -> None: @callback def _handle_coordinator_update(self) -> None: """Handle updated data from the coordinator.""" - api_field = None - - if isinstance(self.entity_description.api_field, str): - api_field = ( - self.coordinator.data.get(self.entity_description.api_field) - if self.entity_description.api_field - else None - ) - elif isinstance(self.entity_description.api_field, list): - for key in self.entity_description.api_field: - if (field := self.coordinator.data.get(key)) is not None: - api_field = field - break + api_field = self.coordinator.get_api_field(self.entity_description) if isinstance(api_field, VolvoCarsValueField): self._attr_extra_state_attributes[ATTR_API_TIMESTAMP] = api_field.timestamp diff --git a/custom_components/volvo_cars/entity_description.py b/custom_components/volvo_cars/entity_description.py new file mode 100644 index 0000000..69c307e --- /dev/null +++ b/custom_components/volvo_cars/entity_description.py @@ -0,0 +1,12 @@ +"""Volvo Cars entity description.""" + +from dataclasses import dataclass + +from homeassistant.helpers.entity import EntityDescription + + +@dataclass(frozen=True, kw_only=True) +class VolvoCarsDescription(EntityDescription): + """Describes a Volvo Cars entity.""" + + api_field: str | list[str] diff --git a/custom_components/volvo_cars/image.py b/custom_components/volvo_cars/image.py index 554ebb5..95cd674 100644 --- a/custom_components/volvo_cars/image.py +++ b/custom_components/volvo_cars/image.py @@ -14,8 +14,10 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.httpx_client import get_async_client +from .entity_description import VolvoCarsDescription + from .coordinator import VolvoCarsConfigEntry, VolvoCarsDataCoordinator -from .entity import VolvoCarsDescription, VolvoCarsEntity +from .entity import VolvoCarsEntity from .volvo.models import VolvoCarsApiBaseModel, VolvoCarsVehicle _LOGGER = logging.getLogger(__name__) diff --git a/custom_components/volvo_cars/lock.py b/custom_components/volvo_cars/lock.py index 5d2cdf5..b401f23 100644 --- a/custom_components/volvo_cars/lock.py +++ b/custom_components/volvo_cars/lock.py @@ -11,9 +11,11 @@ from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.entity_platform import AddEntitiesCallback +from .entity_description import VolvoCarsDescription + from .const import ATTR_API_TIMESTAMP, ATTR_LAST_RESULT, DOMAIN from .coordinator import VolvoCarsConfigEntry, VolvoCarsDataCoordinator -from .entity import VolvoCarsDescription, VolvoCarsEntity +from .entity import VolvoCarsEntity from .volvo.models import VolvoApiException, VolvoCarsApiBaseModel, VolvoCarsValue PARALLEL_UPDATES = 0 @@ -132,10 +134,16 @@ async def _async_handle_command(self, command: str, locked: bool) -> None: }, ) + api_field = cast( + VolvoCarsValue, self.coordinator.get_api_field(self.entity_description) + ) + if locked: self._attr_is_locking = False + api_field.value = self.entity_description.api_lock_value else: self._attr_is_unlocking = False + api_field.value = self.entity_description.api_unlock_value self._attr_is_locked = locked self.async_write_ha_state() diff --git a/custom_components/volvo_cars/sensor.py b/custom_components/volvo_cars/sensor.py index d49841b..93bdce8 100644 --- a/custom_components/volvo_cars/sensor.py +++ b/custom_components/volvo_cars/sensor.py @@ -15,9 +15,11 @@ from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback +from .entity_description import VolvoCarsDescription + from .const import OPT_FUEL_CONSUMPTION_UNIT, OPT_UNIT_MPG_UK, OPT_UNIT_MPG_US from .coordinator import VolvoCarsConfigEntry, VolvoCarsDataCoordinator -from .entity import VolvoCarsDescription, VolvoCarsEntity, value_to_translation_key +from .entity import VolvoCarsEntity, value_to_translation_key from .volvo.models import ( VolvoCarsApiBaseModel, VolvoCarsValue,