"""FRITZ image integration.""" from __future__ import annotations from io import BytesIO import logging from homeassistant.components.image import ImageEntity from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.util import dt as dt_util, slugify from .common import AvmWrapper, FritzBoxBaseEntity from .const import DOMAIN _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback, ) -> None: """Set up guest WiFi QR code for device.""" avm_wrapper: AvmWrapper = hass.data[DOMAIN][entry.entry_id] guest_wifi_info = await hass.async_add_executor_job( avm_wrapper.fritz_guest_wifi.get_info ) async_add_entities( [ FritzGuestWifiQRImage( hass, avm_wrapper, entry.title, guest_wifi_info["NewSSID"] ) ] ) class FritzGuestWifiQRImage(FritzBoxBaseEntity, ImageEntity): """Implementation of the FritzBox guest wifi QR code image entity.""" _attr_content_type = "image/png" _attr_entity_category = EntityCategory.DIAGNOSTIC _attr_has_entity_name = True _attr_should_poll = True def __init__( self, hass: HomeAssistant, avm_wrapper: AvmWrapper, device_friendly_name: str, ssid: str, ) -> None: """Initialize the image entity.""" self._attr_name = ssid self._attr_unique_id = slugify(f"{avm_wrapper.unique_id}-{ssid}-qr-code") self._current_qr_bytes: bytes | None = None super().__init__(avm_wrapper, device_friendly_name) ImageEntity.__init__(self, hass) async def _fetch_image(self) -> bytes: """Fetch the QR code from the Fritz!Box.""" qr_stream: BytesIO = await self.hass.async_add_executor_job( self._avm_wrapper.fritz_guest_wifi.get_wifi_qr_code, "png" ) qr_bytes = qr_stream.getvalue() _LOGGER.debug("fetched %s bytes", len(qr_bytes)) return qr_bytes async def async_added_to_hass(self) -> None: """Fetch and set initial data and state.""" self._current_qr_bytes = await self._fetch_image() self._attr_image_last_updated = dt_util.utcnow() async def async_update(self) -> None: """Update the image entity data.""" qr_bytes = await self._fetch_image() if self._current_qr_bytes != qr_bytes: dt_now = dt_util.utcnow() _LOGGER.debug("qr code has changed, reset image last updated property") self._attr_image_last_updated = dt_now self._current_qr_bytes = qr_bytes self.async_write_ha_state() async def async_image(self) -> bytes | None: """Return bytes of image.""" return self._current_qr_bytes