Skip to content

Commit

Permalink
Add Image entities for vehicle status (#437)
Browse files Browse the repository at this point in the history
* Add StatusImage class that sensors can subclass from

* Implement light image

* Remove Dark status image as both are identical

* Force cache invalidation when timestamp changes
  • Loading branch information
WebSpider authored Dec 19, 2024
1 parent e11c638 commit 3140ea7
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 2 deletions.
65 changes: 63 additions & 2 deletions custom_components/myskoda/image.py
Original file line number Diff line number Diff line change
@@ -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]

Expand All @@ -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
Expand Down Expand Up @@ -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."""

Expand Down Expand Up @@ -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
3 changes: 3 additions & 0 deletions custom_components/myskoda/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,9 @@
}
},
"image": {
"render_light_3x": {
"name": "Light Status Render of Vehicle"
},
"render_vehicle_main": {
"name": "Main Render of Vehicle"
}
Expand Down

0 comments on commit 3140ea7

Please sign in to comment.