diff --git a/custom_components/myskoda/image.py b/custom_components/myskoda/image.py index 7d39959..7b3fe18 100644 --- a/custom_components/myskoda/image.py +++ b/custom_components/myskoda/image.py @@ -1,16 +1,18 @@ """Images for the MySkoda integration.""" +import httpx import logging from homeassistant.components.image import ( ImageEntity, ImageEntityDescription, + GET_IMAGE_TIMEOUT, ) from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( EntityCategory, ) -from homeassistant.core import HomeAssistant +from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.typing import DiscoveryInfoType # pyright: ignore [reportAttributeAccessIssue] @@ -31,7 +33,10 @@ async def async_setup_entry( entities = [] for vin in hass.data[DOMAIN][config.entry_id][COORDINATORS]: - for SensorClass in [MainRenderImage]: + for SensorClass in [ + MainRenderImage, + LightStatusImage, + ]: entities.append( SensorClass( hass.data[DOMAIN][config.entry_id][COORDINATORS][vin], vin, hass @@ -59,6 +64,47 @@ def __init__( super().__init__(coordinator, vin) +class StatusImage(MySkodaImage): + """A render of the current status of the vehicle.""" + + async def _fetch_url(self, url: str) -> httpx.Response | None: + """Fetch a URL passing in the MySkoda access token.""" + + try: + response = await self._client.get( + url, + timeout=GET_IMAGE_TIMEOUT, + follow_redirects=True, + headers={ + "authorization": f"Bearer {await self.coordinator.myskoda.authorization.get_access_token()}" + }, + ) + response.raise_for_status() + except httpx.TimeoutException: + _LOGGER.error("%s: Timeout getting image from %s", self.entity_id, url) + return None + except (httpx.RequestError, httpx.HTTPStatusError) as err: + _LOGGER.error( + "%s: Error getting new image from %s: %s", + self.entity_id, + url, + err, + ) + return None + return response + + @callback + def _handle_coordinator_update(self) -> None: + """Handle updated data from the coordinator.""" + if status := self.vehicle.status: + if status.car_captured_timestamp != self._attr_image_last_updated: + _LOGGER.debug("Image updated. Flushing caches.") + + self._cached_image = None + self._attr_image_last_updated = status.car_captured_timestamp + super()._handle_coordinator_update() + + class MainRenderImage(MySkodaImage): """Main render of the vehicle.""" @@ -104,3 +150,18 @@ def extra_state_attributes(self) -> dict: for r in composite_renders: attributes["composite_renders"][r] = composite_renders[r] return attributes + + +class LightStatusImage(StatusImage): + """Light 3x render of the vehicle status.""" + + entity_description = ImageEntityDescription( + key="render_light_3x", + translation_key="render_light_3x", + entity_registry_enabled_default=False, + ) + + @property + def image_url(self) -> str | None: + if status := self.vehicle.status: + return status.renders.light_mode.three_x diff --git a/custom_components/myskoda/translations/en.json b/custom_components/myskoda/translations/en.json index 4150c48..5e9ff56 100644 --- a/custom_components/myskoda/translations/en.json +++ b/custom_components/myskoda/translations/en.json @@ -165,6 +165,9 @@ } }, "image": { + "render_light_3x": { + "name": "Light Status Render of Vehicle" + }, "render_vehicle_main": { "name": "Main Render of Vehicle" }