Add image platform to Habitica integration (#129009)
parent
8a84abd50f
commit
9f2cb7bf56
homeassistant/components/habitica
|
@ -21,6 +21,7 @@ PLATFORMS = [
|
|||
Platform.BINARY_SENSOR,
|
||||
Platform.BUTTON,
|
||||
Platform.CALENDAR,
|
||||
Platform.IMAGE,
|
||||
Platform.SENSOR,
|
||||
Platform.SWITCH,
|
||||
Platform.TODO,
|
||||
|
|
|
@ -5,6 +5,7 @@ from __future__ import annotations
|
|||
from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
from datetime import timedelta
|
||||
from io import BytesIO
|
||||
import logging
|
||||
from typing import Any
|
||||
|
||||
|
@ -18,6 +19,7 @@ from habiticalib import (
|
|||
TaskFilter,
|
||||
TooManyRequestsError,
|
||||
UserData,
|
||||
UserStyles,
|
||||
)
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
|
@ -130,3 +132,13 @@ class HabiticaDataUpdateCoordinator(DataUpdateCoordinator[HabiticaData]):
|
|||
) from e
|
||||
else:
|
||||
await self.async_request_refresh()
|
||||
|
||||
async def generate_avatar(self, user_styles: UserStyles) -> bytes:
|
||||
"""Generate Avatar."""
|
||||
|
||||
avatar = BytesIO()
|
||||
await self.habitica.generate_avatar(
|
||||
fp=avatar, user_styles=user_styles, fmt="PNG"
|
||||
)
|
||||
|
||||
return avatar.getvalue()
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
"""Image platform for Habitica integration."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import asdict
|
||||
from enum import StrEnum
|
||||
|
||||
from habiticalib import UserStyles
|
||||
|
||||
from homeassistant.components.image import ImageEntity, ImageEntityDescription
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.util import dt as dt_util
|
||||
|
||||
from . import HabiticaConfigEntry
|
||||
from .coordinator import HabiticaDataUpdateCoordinator
|
||||
from .entity import HabiticaBase
|
||||
|
||||
|
||||
class HabiticaImageEntity(StrEnum):
|
||||
"""Image entities."""
|
||||
|
||||
AVATAR = "avatar"
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: HabiticaConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up the habitica image platform."""
|
||||
|
||||
coordinator = config_entry.runtime_data
|
||||
|
||||
async_add_entities([HabiticaImage(hass, coordinator)])
|
||||
|
||||
|
||||
class HabiticaImage(HabiticaBase, ImageEntity):
|
||||
"""A Habitica image entity."""
|
||||
|
||||
entity_description = ImageEntityDescription(
|
||||
key=HabiticaImageEntity.AVATAR,
|
||||
translation_key=HabiticaImageEntity.AVATAR,
|
||||
)
|
||||
_attr_content_type = "image/png"
|
||||
_current_appearance: UserStyles | None = None
|
||||
_cache: bytes | None = None
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
hass: HomeAssistant,
|
||||
coordinator: HabiticaDataUpdateCoordinator,
|
||||
) -> None:
|
||||
"""Initialize the image entity."""
|
||||
super().__init__(coordinator, self.entity_description)
|
||||
ImageEntity.__init__(self, hass)
|
||||
self._attr_image_last_updated = dt_util.utcnow()
|
||||
|
||||
def _handle_coordinator_update(self) -> None:
|
||||
"""Check if equipped gear and other things have changed since last avatar image generation."""
|
||||
new_appearance = UserStyles.from_dict(asdict(self.coordinator.data.user))
|
||||
|
||||
if self._current_appearance != new_appearance:
|
||||
self._current_appearance = new_appearance
|
||||
self._attr_image_last_updated = dt_util.utcnow()
|
||||
self._cache = None
|
||||
|
||||
return super()._handle_coordinator_update()
|
||||
|
||||
async def async_image(self) -> bytes | None:
|
||||
"""Return cached bytes, otherwise generate new avatar."""
|
||||
if not self._cache and self._current_appearance:
|
||||
self._cache = await self.coordinator.generate_avatar(
|
||||
self._current_appearance
|
||||
)
|
||||
return self._cache
|
|
@ -167,6 +167,11 @@
|
|||
"name": "Daily reminders"
|
||||
}
|
||||
},
|
||||
"image": {
|
||||
"avatar": {
|
||||
"name": "Avatar"
|
||||
}
|
||||
},
|
||||
"sensor": {
|
||||
"display_name": {
|
||||
"name": "Display name"
|
||||
|
|
Loading…
Reference in New Issue