Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Image entities for vehicle status #437

Merged
merged 13 commits into from
Dec 19, 2024
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:
WebSpider marked this conversation as resolved.
Show resolved Hide resolved
"""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
Loading