Home Assistant Unofficial Reference 2024.12.1
light.py
Go to the documentation of this file.
1 """Support for EverLights lights."""
2 
3 from __future__ import annotations
4 
5 from datetime import timedelta
6 import logging
7 from typing import Any
8 
9 import pyeverlights
10 import voluptuous as vol
11 
13  ATTR_BRIGHTNESS,
14  ATTR_EFFECT,
15  ATTR_HS_COLOR,
16  PLATFORM_SCHEMA as LIGHT_PLATFORM_SCHEMA,
17  ColorMode,
18  LightEntity,
19  LightEntityFeature,
20 )
21 from homeassistant.const import CONF_HOSTS
22 from homeassistant.core import HomeAssistant
23 from homeassistant.exceptions import PlatformNotReady
24 from homeassistant.helpers.aiohttp_client import async_get_clientsession
26 from homeassistant.helpers.entity_platform import AddEntitiesCallback
27 from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
28 import homeassistant.util.color as color_util
29 
30 _LOGGER = logging.getLogger(__name__)
31 
32 SCAN_INTERVAL = timedelta(minutes=1)
33 
34 PLATFORM_SCHEMA = LIGHT_PLATFORM_SCHEMA.extend(
35  {vol.Required(CONF_HOSTS): vol.All(cv.ensure_list, [cv.string])}
36 )
37 
38 
39 def color_rgb_to_int(red: int, green: int, blue: int) -> int:
40  """Return a RGB color as an integer."""
41  return red * 256 * 256 + green * 256 + blue
42 
43 
44 def color_int_to_rgb(value: int) -> tuple[int, int, int]:
45  """Return an RGB tuple from an integer."""
46  return (value >> 16, (value >> 8) & 0xFF, value & 0xFF)
47 
48 
50  hass: HomeAssistant,
51  config: ConfigType,
52  async_add_entities: AddEntitiesCallback,
53  discovery_info: DiscoveryInfoType | None = None,
54 ) -> None:
55  """Set up the EverLights lights from configuration.yaml."""
56  lights = []
57 
58  for ipaddr in config[CONF_HOSTS]:
59  api = pyeverlights.EverLights(ipaddr, async_get_clientsession(hass))
60 
61  try:
62  status = await api.get_status()
63 
64  effects = await api.get_all_patterns()
65 
66  except pyeverlights.ConnectionError as err:
67  raise PlatformNotReady from err
68 
69  lights.append(EverLightsLight(api, pyeverlights.ZONE_1, status, effects))
70  lights.append(EverLightsLight(api, pyeverlights.ZONE_2, status, effects))
71 
72  async_add_entities(lights)
73 
74 
76  """Representation of a Flux light."""
77 
78  _attr_color_mode = ColorMode.HS
79  _attr_supported_color_modes = {ColorMode.HS}
80  _attr_supported_features = LightEntityFeature.EFFECT
81 
82  def __init__(
83  self,
84  api: pyeverlights.EverLights,
85  channel: int,
86  status: dict[str, Any],
87  effects,
88  ) -> None:
89  """Initialize the light."""
90  self._api_api = api
91  self._channel_channel = channel
92  self._status_status = status
93  self._attr_effect_list_attr_effect_list = effects
94  self._mac_mac = status["mac"]
95  self._error_reported_error_reported = False
96  self._attr_hs_color_attr_hs_color = (255, 255)
97  self._attr_brightness_attr_brightness = 255
98 
99  self._attr_name_attr_name = f"EverLights {self._mac} Zone {self._channel}"
100  self._attr_unique_id_attr_unique_id = f"{self._mac}-{self._channel}"
101 
102  @property
103  def is_on(self) -> bool:
104  """Return true if device is on."""
105  return self._status_status[f"ch{self._channel}Active"] == 1
106 
107  async def async_turn_on(self, **kwargs: Any) -> None:
108  """Turn the light on."""
109  hs_color = kwargs.get(ATTR_HS_COLOR, self._attr_hs_color_attr_hs_color)
110  brightness = kwargs.get(ATTR_BRIGHTNESS, self._attr_brightness_attr_brightness)
111  effect = kwargs.get(ATTR_EFFECT)
112 
113  if effect is not None:
114  colors = await self._api_api.set_pattern_by_id(self._channel_channel, effect)
115 
116  rgb = color_int_to_rgb(colors[0])
117  hsv = color_util.color_RGB_to_hsv(*rgb)
118  hs_color = hsv[:2]
119  brightness = hsv[2] / 100 * 255
120 
121  else:
122  rgb = color_util.color_hsv_to_RGB(
123  hs_color[0], hs_color[1], brightness / 255 * 100
124  )
125  colors = [color_rgb_to_int(*rgb)]
126 
127  await self._api_api.set_pattern(self._channel_channel, colors)
128 
129  self._attr_hs_color_attr_hs_color = hs_color
130  self._attr_brightness_attr_brightness = brightness
131  self._attr_effect_attr_effect = effect
132 
133  async def async_turn_off(self, **kwargs: Any) -> None:
134  """Turn the light off."""
135  await self._api_api.clear_pattern(self._channel_channel)
136 
137  async def async_update(self) -> None:
138  """Synchronize state with control box."""
139  try:
140  self._status_status = await self._api_api.get_status()
141  except pyeverlights.ConnectionError:
142  if self.availableavailable:
143  _LOGGER.warning("EverLights control box connection lost")
144  self._attr_available_attr_available = False
145  else:
146  if not self.availableavailable:
147  _LOGGER.warning("EverLights control box connection restored")
148  self._attr_available_attr_available = True
None __init__(self, pyeverlights.EverLights api, int channel, dict[str, Any] status, effects)
Definition: light.py:88
tuple[int, int, int] color_int_to_rgb(int value)
Definition: light.py:44
int color_rgb_to_int(int red, int green, int blue)
Definition: light.py:39
None async_setup_platform(HomeAssistant hass, ConfigType config, AddEntitiesCallback async_add_entities, DiscoveryInfoType|None discovery_info=None)
Definition: light.py:54
def get_status(hass, host, port)
Definition: panel.py:387
aiohttp.ClientSession async_get_clientsession(HomeAssistant hass, bool verify_ssl=True, socket.AddressFamily family=socket.AF_UNSPEC, ssl_util.SSLCipherList ssl_cipher=ssl_util.SSLCipherList.PYTHON_DEFAULT)