Elgato refactoring; add base entity (#64034)

pull/64046/head
Franck Nijhof 2022-01-13 13:09:08 +01:00 committed by GitHub
parent bd859f428a
commit 99798223d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 59 additions and 51 deletions

View File

@ -1,7 +1,8 @@
"""Support for Elgato Lights.""" """Support for Elgato Lights."""
import logging import logging
from typing import NamedTuple
from elgato import Elgato, ElgatoConnectionError from elgato import Elgato, ElgatoConnectionError, Info
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_HOST, CONF_PORT, Platform from homeassistant.const import CONF_HOST, CONF_PORT, Platform
@ -14,6 +15,13 @@ from .const import DOMAIN
PLATFORMS = [Platform.BUTTON, Platform.LIGHT] PLATFORMS = [Platform.BUTTON, Platform.LIGHT]
class HomeAssistantElgatoData(NamedTuple):
"""Elgato data stored in the Home Assistant data object."""
client: Elgato
info: Info
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up Elgato Light from a config entry.""" """Set up Elgato Light from a config entry."""
session = async_get_clientsession(hass) session = async_get_clientsession(hass)
@ -25,12 +33,16 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
# Ensure we can connect to it # Ensure we can connect to it
try: try:
await elgato.info() info = await elgato.info()
except ElgatoConnectionError as exception: except ElgatoConnectionError as exception:
logging.getLogger(__name__).debug("Unable to connect: %s", exception) logging.getLogger(__name__).debug("Unable to connect: %s", exception)
raise ConfigEntryNotReady from exception raise ConfigEntryNotReady from exception
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = elgato hass.data.setdefault(DOMAIN, {})[entry.entry_id] = HomeAssistantElgatoData(
client=elgato,
info=info,
)
hass.config_entries.async_setup_platforms(entry, PLATFORMS) hass.config_entries.async_setup_platforms(entry, PLATFORMS)
return True return True
@ -38,9 +50,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Unload Elgato Light config entry.""" """Unload Elgato Light config entry."""
# Unload entities for this entry/device. if unload_ok := await hass.config_entries.async_unload_platforms(entry, PLATFORMS):
unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
if unload_ok:
# Cleanup # Cleanup
del hass.data[DOMAIN][entry.entry_id] del hass.data[DOMAIN][entry.entry_id]
if not hass.data[DOMAIN]: if not hass.data[DOMAIN]:

View File

@ -8,10 +8,12 @@ from elgato import Elgato, ElgatoError, Info
from homeassistant.components.button import ButtonEntity, ButtonEntityDescription from homeassistant.components.button import ButtonEntity, ButtonEntityDescription
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity import DeviceInfo, EntityCategory from homeassistant.helpers.entity import EntityCategory
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import HomeAssistantElgatoData
from .const import DOMAIN from .const import DOMAIN
from .entity import ElgatoEntity
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -22,18 +24,16 @@ async def async_setup_entry(
async_add_entities: AddEntitiesCallback, async_add_entities: AddEntitiesCallback,
) -> None: ) -> None:
"""Set up Elgato button based on a config entry.""" """Set up Elgato button based on a config entry."""
elgato: Elgato = hass.data[DOMAIN][entry.entry_id] data: HomeAssistantElgatoData = hass.data[DOMAIN][entry.entry_id]
info = await elgato.info() async_add_entities([ElgatoIdentifyButton(data.client, data.info)])
async_add_entities([ElgatoIdentifyButton(elgato, info)])
class ElgatoIdentifyButton(ButtonEntity): class ElgatoIdentifyButton(ElgatoEntity, ButtonEntity):
"""Defines an Elgato identify button.""" """Defines an Elgato identify button."""
def __init__(self, elgato: Elgato, info: Info) -> None: def __init__(self, client: Elgato, info: Info) -> None:
"""Initialize the button entity.""" """Initialize the button entity."""
self.elgato = elgato super().__init__(client, info)
self._info = info
self.entity_description = ButtonEntityDescription( self.entity_description = ButtonEntityDescription(
key="identify", key="identify",
name="Identify", name="Identify",
@ -42,20 +42,9 @@ class ElgatoIdentifyButton(ButtonEntity):
) )
self._attr_unique_id = f"{info.serial_number}_{self.entity_description.key}" self._attr_unique_id = f"{info.serial_number}_{self.entity_description.key}"
@property
def device_info(self) -> DeviceInfo:
"""Return device information about this Elgato Light."""
return DeviceInfo(
identifiers={(DOMAIN, self._info.serial_number)},
manufacturer="Elgato",
model=self._info.product_name,
name=self._info.product_name,
sw_version=f"{self._info.firmware_version} ({self._info.firmware_build_number})",
)
async def async_press(self) -> None: async def async_press(self) -> None:
"""Identify the light, will make it blink.""" """Identify the light, will make it blink."""
try: try:
await self.elgato.identify() await self.client.identify()
except ElgatoError: except ElgatoError:
_LOGGER.exception("An error occurred while identifying the Elgato Light") _LOGGER.exception("An error occurred while identifying the Elgato Light")

View File

@ -0,0 +1,22 @@
"""Base entity for the Elgato integration."""
from elgato import Elgato, Info
from homeassistant.helpers.entity import DeviceInfo, Entity
from .const import DOMAIN
class ElgatoEntity(Entity):
"""Defines an Elgato entity."""
def __init__(self, client: Elgato, info: Info) -> None:
"""Initialize an Elgato entity."""
self.client = client
self._attr_device_info = DeviceInfo(
identifiers={(DOMAIN, info.serial_number)},
manufacturer="Elgato",
model=info.product_name,
name=info.product_name,
sw_version=f"{info.firmware_version} ({info.firmware_build_number})",
)

View File

@ -17,13 +17,14 @@ from homeassistant.components.light import (
) )
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.entity_platform import ( from homeassistant.helpers.entity_platform import (
AddEntitiesCallback, AddEntitiesCallback,
async_get_current_platform, async_get_current_platform,
) )
from . import HomeAssistantElgatoData
from .const import DOMAIN, SERVICE_IDENTIFY from .const import DOMAIN, SERVICE_IDENTIFY
from .entity import ElgatoEntity
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -37,10 +38,9 @@ async def async_setup_entry(
async_add_entities: AddEntitiesCallback, async_add_entities: AddEntitiesCallback,
) -> None: ) -> None:
"""Set up Elgato Light based on a config entry.""" """Set up Elgato Light based on a config entry."""
elgato: Elgato = hass.data[DOMAIN][entry.entry_id] data: HomeAssistantElgatoData = hass.data[DOMAIN][entry.entry_id]
info = await elgato.info() settings = await data.client.settings()
settings = await elgato.settings() async_add_entities([ElgatoLight(data.client, data.info, settings)], True)
async_add_entities([ElgatoLight(elgato, info, settings)], True)
platform = async_get_current_platform() platform = async_get_current_platform()
platform.async_register_entity_service( platform.async_register_entity_service(
@ -50,15 +50,13 @@ async def async_setup_entry(
) )
class ElgatoLight(LightEntity): class ElgatoLight(ElgatoEntity, LightEntity):
"""Defines an Elgato Light.""" """Defines an Elgato Light."""
def __init__(self, elgato: Elgato, info: Info, settings: Settings) -> None: def __init__(self, client: Elgato, info: Info, settings: Settings) -> None:
"""Initialize Elgato Light.""" """Initialize Elgato Light."""
self._info = info super().__init__(client, info)
self._settings = settings
self._state: State | None = None self._state: State | None = None
self.elgato = elgato
min_mired = 143 min_mired = 143
max_mired = 344 max_mired = 344
@ -122,7 +120,7 @@ class ElgatoLight(LightEntity):
async def async_turn_off(self, **kwargs: Any) -> None: async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn off the light.""" """Turn off the light."""
try: try:
await self.elgato.light(on=False) await self.client.light(on=False)
except ElgatoError: except ElgatoError:
_LOGGER.error("An error occurred while updating the Elgato Light") _LOGGER.error("An error occurred while updating the Elgato Light")
self._state = None self._state = None
@ -154,7 +152,7 @@ class ElgatoLight(LightEntity):
temperature = self.color_temp temperature = self.color_temp
try: try:
await self.elgato.light( await self.client.light(
on=True, on=True,
brightness=brightness, brightness=brightness,
hue=hue, hue=hue,
@ -169,7 +167,7 @@ class ElgatoLight(LightEntity):
"""Update Elgato entity.""" """Update Elgato entity."""
restoring = self._state is None restoring = self._state is None
try: try:
self._state = await self.elgato.state() self._state = await self.client.state()
if restoring: if restoring:
_LOGGER.info("Connection restored") _LOGGER.info("Connection restored")
except ElgatoError as err: except ElgatoError as err:
@ -177,21 +175,10 @@ class ElgatoLight(LightEntity):
meth("An error occurred while updating the Elgato Light: %s", err) meth("An error occurred while updating the Elgato Light: %s", err)
self._state = None self._state = None
@property
def device_info(self) -> DeviceInfo:
"""Return device information about this Elgato Light."""
return DeviceInfo(
identifiers={(DOMAIN, self._info.serial_number)},
manufacturer="Elgato",
model=self._info.product_name,
name=self._info.product_name,
sw_version=f"{self._info.firmware_version} ({self._info.firmware_build_number})",
)
async def async_identify(self) -> None: async def async_identify(self) -> None:
"""Identify the light, will make it blink.""" """Identify the light, will make it blink."""
try: try:
await self.elgato.identify() await self.client.identify()
except ElgatoError: except ElgatoError:
_LOGGER.exception("An error occurred while identifying the Elgato Light") _LOGGER.exception("An error occurred while identifying the Elgato Light")
self._state = None self._state = None