Skip to content

Commit

Permalink
Add image platform to Habitica integration (home-assistant#129009)
Browse files Browse the repository at this point in the history
  • Loading branch information
tr4nt0r authored Jan 3, 2025
1 parent 8a84abd commit 9f2cb7b
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 0 deletions.
1 change: 1 addition & 0 deletions homeassistant/components/habitica/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
Platform.BINARY_SENSOR,
Platform.BUTTON,
Platform.CALENDAR,
Platform.IMAGE,
Platform.SENSOR,
Platform.SWITCH,
Platform.TODO,
Expand Down
12 changes: 12 additions & 0 deletions homeassistant/components/habitica/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from collections.abc import Callable
from dataclasses import dataclass
from datetime import timedelta
from io import BytesIO
import logging
from typing import Any

Expand All @@ -18,6 +19,7 @@
TaskFilter,
TooManyRequestsError,
UserData,
UserStyles,
)

from homeassistant.config_entries import ConfigEntry
Expand Down Expand Up @@ -130,3 +132,13 @@ async def execute(
) 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()
76 changes: 76 additions & 0 deletions homeassistant/components/habitica/image.py
Original file line number Diff line number Diff line change
@@ -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
5 changes: 5 additions & 0 deletions homeassistant/components/habitica/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,11 @@
"name": "Daily reminders"
}
},
"image": {
"avatar": {
"name": "Avatar"
}
},
"sensor": {
"display_name": {
"name": "Display name"
Expand Down

0 comments on commit 9f2cb7b

Please sign in to comment.