mirror of
https://github.com/home-assistant/core.git
synced 2026-09-25 17:04:04 -04:00
191 lines
6.2 KiB
Python
191 lines
6.2 KiB
Python
"""Image platform for the Steam integration."""
|
|
|
|
from collections.abc import Callable
|
|
from dataclasses import dataclass
|
|
from enum import StrEnum
|
|
from typing import TYPE_CHECKING, override
|
|
|
|
from homeassistant.components.image import ImageEntity, ImageEntityDescription
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
|
from homeassistant.util import dt as dt_util
|
|
|
|
from .const import STEAM_API_URL, STEAM_ICON_URL, SUBENTRY_TYPE_FRIEND
|
|
from .coordinator import PlayerData, SteamConfigEntry, SteamDataUpdateCoordinator
|
|
from .entity import SteamEntity
|
|
|
|
PARALLEL_UPDATES = 0
|
|
|
|
|
|
class SteamImage(StrEnum):
|
|
"""Steam images."""
|
|
|
|
AVATAR = "avatar"
|
|
MAIN_CAPSULE = "main_capsule"
|
|
HEADER_CAPSULE = "header_capsule"
|
|
SMALL_CAPSULE = "small_capsule"
|
|
VERTICAL_CAPSULE = "vertical_capsule"
|
|
LIBRARY_CAPSULE = "library_capsule"
|
|
LIBRARY_HERO = "library_hero"
|
|
LIBRARY_LOGO = "library_logo"
|
|
PAGE_BACKGROUND = "page_background"
|
|
APP_ICON = "app_icon"
|
|
|
|
|
|
@dataclass(kw_only=True, frozen=True)
|
|
class SteamImageEntityDescription(ImageEntityDescription):
|
|
"""Steam image description."""
|
|
|
|
image_url_fn: Callable[[PlayerData, dict[str, str]], str | None]
|
|
available_fn: Callable[[PlayerData], bool] = lambda x: x.gameid is not None
|
|
|
|
|
|
IMAGE_DESCRIPTIONS: tuple[SteamImageEntityDescription, ...] = (
|
|
SteamImageEntityDescription(
|
|
key=SteamImage.AVATAR,
|
|
translation_key=SteamImage.AVATAR,
|
|
image_url_fn=lambda x, _: x.avatarfull,
|
|
entity_registry_enabled_default=False,
|
|
available_fn=lambda _: True,
|
|
),
|
|
SteamImageEntityDescription(
|
|
key=SteamImage.MAIN_CAPSULE,
|
|
translation_key=SteamImage.MAIN_CAPSULE,
|
|
image_url_fn=lambda x, _: (
|
|
f"{STEAM_API_URL}{x.gameid}/capsule_616x353.jpg" if x.gameid else None
|
|
),
|
|
),
|
|
SteamImageEntityDescription(
|
|
key=SteamImage.HEADER_CAPSULE,
|
|
translation_key=SteamImage.HEADER_CAPSULE,
|
|
image_url_fn=lambda x, _: (
|
|
f"{STEAM_API_URL}{x.gameid}/header.jpg" if x.gameid else None
|
|
),
|
|
),
|
|
SteamImageEntityDescription(
|
|
key=SteamImage.APP_ICON,
|
|
translation_key=SteamImage.APP_ICON,
|
|
image_url_fn=lambda x, icons: (
|
|
f"{STEAM_ICON_URL}{x.gameid}/{i}.jpg"
|
|
if x.gameid and (i := icons.get(x.gameid))
|
|
else None
|
|
),
|
|
entity_registry_enabled_default=False,
|
|
),
|
|
SteamImageEntityDescription(
|
|
key=SteamImage.SMALL_CAPSULE,
|
|
translation_key=SteamImage.SMALL_CAPSULE,
|
|
image_url_fn=lambda x, _: (
|
|
f"{STEAM_API_URL}{x.gameid}/capsule_231x87.jpg" if x.gameid else None
|
|
),
|
|
entity_registry_enabled_default=False,
|
|
),
|
|
SteamImageEntityDescription(
|
|
key=SteamImage.LIBRARY_CAPSULE,
|
|
translation_key=SteamImage.LIBRARY_CAPSULE,
|
|
image_url_fn=lambda x, _: (
|
|
f"{STEAM_API_URL}{x.gameid}/library_600x900_2x.jpg" if x.gameid else None
|
|
),
|
|
),
|
|
SteamImageEntityDescription(
|
|
key=SteamImage.LIBRARY_HERO,
|
|
translation_key=SteamImage.LIBRARY_HERO,
|
|
image_url_fn=lambda x, _: (
|
|
f"{STEAM_API_URL}{x.gameid}/library_hero.jpg" if x.gameid else None
|
|
),
|
|
),
|
|
SteamImageEntityDescription(
|
|
key=SteamImage.LIBRARY_LOGO,
|
|
translation_key=SteamImage.LIBRARY_LOGO,
|
|
image_url_fn=lambda x, _: (
|
|
f"{STEAM_API_URL}{x.gameid}/logo.png" if x.gameid else None
|
|
),
|
|
),
|
|
SteamImageEntityDescription(
|
|
key=SteamImage.PAGE_BACKGROUND,
|
|
translation_key=SteamImage.PAGE_BACKGROUND,
|
|
image_url_fn=lambda x, _: (
|
|
f"{STEAM_API_URL}{x.gameid}/page_bg_generated_v6b.jpg" if x.gameid else None
|
|
),
|
|
),
|
|
SteamImageEntityDescription(
|
|
key=SteamImage.VERTICAL_CAPSULE,
|
|
translation_key=SteamImage.VERTICAL_CAPSULE,
|
|
image_url_fn=lambda x, _: (
|
|
f"{STEAM_API_URL}{x.gameid}/hero_capsule.jpg" if x.gameid else None
|
|
),
|
|
),
|
|
)
|
|
|
|
|
|
async def async_setup_entry(
|
|
hass: HomeAssistant,
|
|
entry: SteamConfigEntry,
|
|
async_add_entities: AddConfigEntryEntitiesCallback,
|
|
) -> None:
|
|
"""Set up the Steam platform."""
|
|
coordinator = entry.runtime_data
|
|
if TYPE_CHECKING:
|
|
assert entry.unique_id
|
|
|
|
async_add_entities(
|
|
SteamImageEntity(hass, coordinator, entry.unique_id, description)
|
|
for description in IMAGE_DESCRIPTIONS
|
|
if entry.unique_id in coordinator.data
|
|
)
|
|
|
|
for subentry in entry.get_subentries_of_type(SUBENTRY_TYPE_FRIEND):
|
|
async_add_entities(
|
|
[
|
|
SteamImageEntity(hass, coordinator, subentry.unique_id, description)
|
|
for description in IMAGE_DESCRIPTIONS
|
|
if subentry.unique_id in coordinator.data
|
|
],
|
|
config_subentry_id=subentry.subentry_id,
|
|
)
|
|
|
|
|
|
class SteamImageEntity(SteamEntity, ImageEntity):
|
|
"""An image entity."""
|
|
|
|
entity_description: SteamImageEntityDescription
|
|
|
|
def __init__(
|
|
self,
|
|
hass: HomeAssistant,
|
|
coordinator: SteamDataUpdateCoordinator,
|
|
steamid: str,
|
|
entity_description: SteamImageEntityDescription,
|
|
) -> None:
|
|
"""Initialize the image entity."""
|
|
super().__init__(coordinator, steamid, entity_description)
|
|
ImageEntity.__init__(self, hass)
|
|
|
|
self._attr_image_url = self.entity_description.image_url_fn(
|
|
self.coordinator.data[self._steamid], self.coordinator.game_icons
|
|
)
|
|
self._attr_image_last_updated = dt_util.utcnow()
|
|
|
|
@override
|
|
def _handle_coordinator_update(self) -> None:
|
|
"""Handle updated data from the coordinator."""
|
|
|
|
url = self.entity_description.image_url_fn(
|
|
self.coordinator.data[self._steamid], self.coordinator.game_icons
|
|
)
|
|
|
|
if url != self._attr_image_url:
|
|
self._attr_image_url = url
|
|
self._cached_image = None
|
|
self._attr_image_last_updated = dt_util.utcnow()
|
|
|
|
super()._handle_coordinator_update()
|
|
|
|
@property
|
|
@override
|
|
def available(self) -> bool:
|
|
"""Return if entity is available."""
|
|
return super().available and self.entity_description.available_fn(
|
|
self.coordinator.data[self._steamid]
|
|
)
|