from flickerstrip_py import Flickerstrip from typing import Any from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.components.light import ( LightEntity, ATTR_BRIGHTNESS, ATTR_RGB_COLOR, ATTR_EFFECT, SUPPORT_BRIGHTNESS, SUPPORT_COLOR, SUPPORT_EFFECT, ColorMode ) from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.entity import DeviceInfo from homeassistant.helpers.entity_platform import AddEntitiesCallback from .common import FlickerstripEntity from .const import ( DOMAIN, DATA_UPDATED, DEFAULT_NAME, ) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, async_add_devices: AddEntitiesCallback, ): """Initialize flickerstrip light config entry.""" strip_data = hass.data[DOMAIN][config_entry.entry_id] async_add_devices([ FlickerstripLight(hass, strip_data.strip) ]) class FlickerstripLight(FlickerstripEntity, LightEntity): """Flickerstrip class.""" def __init__( self, hass: HomeAssistant, strip: Flickerstrip, ): super().__init__(strip) self.hass = hass @property def device_info(self) -> DeviceInfo: sw_version = None if self.strip.status is not None: sw_version = self.strip.status.firmware return DeviceInfo( identifiers={ (DOMAIN, self.strip.host), }, name=self.name, default_name=DEFAULT_NAME, manufacturer="HOhmBody", model="Flickerstrip LED Strip", sw_version=sw_version, ) @property def unique_id(self) -> str | None: """Return the unique id of this light.""" if self.strip.status is None: return None return self.strip.status.mac @property def color_mode(self) -> ColorMode | str | None: """Return the color mode of this light.""" return ColorMode.RGB @property def supported_color_modes(self) -> set[ColorMode] | set[str] | None: """Return the supported color modes of this light.""" return [ColorMode.RGB] @property def supported_features(self) -> int | None: """Return the supported features of this light.""" return SUPPORT_COLOR | SUPPORT_BRIGHTNESS | SUPPORT_EFFECT @property def effect(self) -> str | None: """Return the current effect of this light.""" if self.strip.status is None: return None return self.strip.status.get_current_pattern().name @property def effect_list(self) -> list[str] | None: """Return the effect list of this light.""" if self.strip.status is None: return [] return [p.name for p in self.strip.status.patterns] @property def name(self) -> str | None: """Return the display name of this light.""" if self.strip.status is None: return DEFAULT_NAME return self.strip.status.name if len(self.strip.status.name) > 0 else DEFAULT_NAME @property def brightness(self) -> int | None: """Return the brightness of the light.""" if self.strip.status is None: return 0 return self.strip.status.brightness @property def is_on(self) -> bool | None: """Return true if light is on.""" if self.strip.status is None: return False return self.strip.status.power async def async_turn_on(self, **kwargs: Any) -> None: """Instruct the light to turn on.""" if ATTR_EFFECT in kwargs: for i, pattern in enumerate(self.strip.status.patterns): if pattern.name == kwargs[ATTR_EFFECT]: await self.strip.select_pattern(i) break elif ATTR_RGB_COLOR in kwargs: [r, g, b] = kwargs[ATTR_RGB_COLOR] await self.strip.set_color(r, g, b) if ATTR_BRIGHTNESS in kwargs: brightness = kwargs[ATTR_BRIGHTNESS] await self.strip.set_brightness(brightness) await self.strip.power_on() await self.strip.force_update() async def async_turn_off(self, **kwargs: Any) -> None: """Instruct the light to turn off.""" await self.strip.power_off() await self.strip.force_update() async def async_added_to_hass(self) -> None: """Update initial state.""" async_dispatcher_connect( self.hass, DATA_UPDATED, self._schedule_immediate_update ) @callback def _schedule_immediate_update(self): self.async_schedule_update_ha_state(True) async def async_update(self) -> None: """Fetch new state data for this light. This is the only method that should fetch new data for Home Assistant. """ await self.strip.force_update()