Use shorthand attributes in Twinkly (#99891)

This commit is contained in:
Joost Lekkerkerker 2023-09-12 15:08:18 +02:00 committed by GitHub
parent 1ccf9cc400
commit b5275016d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -2,7 +2,6 @@
from __future__ import annotations from __future__ import annotations
import asyncio import asyncio
from collections.abc import Mapping
import logging import logging
from typing import Any from typing import Any
@ -62,6 +61,8 @@ async def async_setup_entry(
class TwinklyLight(LightEntity): class TwinklyLight(LightEntity):
"""Implementation of the light for the Twinkly service.""" """Implementation of the light for the Twinkly service."""
_attr_icon = "mdi:string-lights"
def __init__( def __init__(
self, self,
conf: ConfigEntry, conf: ConfigEntry,
@ -69,7 +70,7 @@ class TwinklyLight(LightEntity):
device_info, device_info,
) -> None: ) -> None:
"""Initialize a TwinklyLight entity.""" """Initialize a TwinklyLight entity."""
self._id = conf.data[CONF_ID] self._attr_unique_id: str = conf.data[CONF_ID]
self._conf = conf self._conf = conf
if device_info.get(DEV_LED_PROFILE) == DEV_PROFILE_RGBW: if device_info.get(DEV_LED_PROFILE) == DEV_PROFILE_RGBW:
@ -93,64 +94,30 @@ class TwinklyLight(LightEntity):
self._client = client self._client = client
# Set default state before any update # Set default state before any update
self._is_on = False self._attr_is_on = False
self._is_available = False self._attr_available = False
self._attributes: dict[Any, Any] = {}
self._current_movie: dict[Any, Any] = {} self._current_movie: dict[Any, Any] = {}
self._movies: list[Any] = [] self._movies: list[Any] = []
self._software_version = "" self._software_version = ""
# We guess that most devices are "new" and support effects # We guess that most devices are "new" and support effects
self._attr_supported_features = LightEntityFeature.EFFECT self._attr_supported_features = LightEntityFeature.EFFECT
@property
def available(self) -> bool:
"""Get a boolean which indicates if this entity is currently available."""
return self._is_available
@property
def unique_id(self) -> str | None:
"""Id of the device."""
return self._id
@property @property
def name(self) -> str: def name(self) -> str:
"""Name of the device.""" """Name of the device."""
return self._name if self._name else "Twinkly light" return self._name if self._name else "Twinkly light"
@property
def model(self) -> str:
"""Name of the device."""
return self._model
@property
def icon(self) -> str:
"""Icon of the device."""
return "mdi:string-lights"
@property @property
def device_info(self) -> DeviceInfo | None: def device_info(self) -> DeviceInfo | None:
"""Get device specific attributes.""" """Get device specific attributes."""
return DeviceInfo( return DeviceInfo(
identifiers={(DOMAIN, self._id)}, identifiers={(DOMAIN, self._attr_unique_id)},
manufacturer="LEDWORKS", manufacturer="LEDWORKS",
model=self.model, model=self._model,
name=self.name, name=self.name,
sw_version=self._software_version, sw_version=self._software_version,
) )
@property
def is_on(self) -> bool:
"""Return true if light is on."""
return self._is_on
@property
def extra_state_attributes(self) -> Mapping[str, Any]:
"""Return device specific state attributes."""
attributes = self._attributes
return attributes
@property @property
def effect(self) -> str | None: def effect(self) -> str | None:
"""Return the current effect.""" """Return the current effect."""
@ -246,7 +213,7 @@ class TwinklyLight(LightEntity):
await self._client.set_current_movie(int(movie_id)) await self._client.set_current_movie(int(movie_id))
await self._client.set_mode("movie") await self._client.set_mode("movie")
self._client.default_mode = "movie" self._client.default_mode = "movie"
if not self._is_on: if not self._attr_is_on:
await self._client.turn_on() await self._client.turn_on()
async def async_turn_off(self, **kwargs: Any) -> None: async def async_turn_off(self, **kwargs: Any) -> None:
@ -258,7 +225,7 @@ class TwinklyLight(LightEntity):
_LOGGER.debug("Updating '%s'", self._client.host) _LOGGER.debug("Updating '%s'", self._client.host)
try: try:
self._is_on = await self._client.is_on() self._attr_is_on = await self._client.is_on()
brightness = await self._client.get_brightness() brightness = await self._client.get_brightness()
brightness_value = ( brightness_value = (
@ -266,7 +233,7 @@ class TwinklyLight(LightEntity):
) )
self._attr_brightness = ( self._attr_brightness = (
int(round(brightness_value * 2.55)) if self._is_on else 0 int(round(brightness_value * 2.55)) if self._attr_is_on else 0
) )
device_info = await self._client.get_details() device_info = await self._client.get_details()
@ -289,7 +256,7 @@ class TwinklyLight(LightEntity):
self._conf, self._conf,
data={ data={
CONF_HOST: self._client.host, # this cannot change CONF_HOST: self._client.host, # this cannot change
CONF_ID: self._id, # this cannot change CONF_ID: self._attr_unique_id, # this cannot change
CONF_NAME: self._name, CONF_NAME: self._name,
CONF_MODEL: self._model, CONF_MODEL: self._model,
}, },
@ -299,20 +266,20 @@ class TwinklyLight(LightEntity):
await self.async_update_movies() await self.async_update_movies()
await self.async_update_current_movie() await self.async_update_current_movie()
if not self._is_available: if not self._attr_available:
_LOGGER.info("Twinkly '%s' is now available", self._client.host) _LOGGER.info("Twinkly '%s' is now available", self._client.host)
# We don't use the echo API to track the availability since # We don't use the echo API to track the availability since
# we already have to pull the device to get its state. # we already have to pull the device to get its state.
self._is_available = True self._attr_available = True
except (asyncio.TimeoutError, ClientError): except (asyncio.TimeoutError, ClientError):
# We log this as "info" as it's pretty common that the Christmas # We log this as "info" as it's pretty common that the Christmas
# light are not reachable in July # light are not reachable in July
if self._is_available: if self._attr_available:
_LOGGER.info( _LOGGER.info(
"Twinkly '%s' is not reachable (client error)", self._client.host "Twinkly '%s' is not reachable (client error)", self._client.host
) )
self._is_available = False self._attr_available = False
async def async_update_movies(self) -> None: async def async_update_movies(self) -> None:
"""Update the list of movies (effects).""" """Update the list of movies (effects)."""