Home Assistant Unofficial Reference 2024.12.1
light.py
Go to the documentation of this file.
1 """Support for WiLight lights."""
2 
3 from __future__ import annotations
4 
5 from typing import Any
6 
7 from pywilight.const import ITEM_LIGHT, LIGHT_COLOR, LIGHT_DIMMER, LIGHT_ON_OFF
8 from pywilight.wilight_device import PyWiLightDevice
9 
11  ATTR_BRIGHTNESS,
12  ATTR_HS_COLOR,
13  ColorMode,
14  LightEntity,
15 )
16 from homeassistant.config_entries import ConfigEntry
17 from homeassistant.core import HomeAssistant
18 from homeassistant.helpers.entity_platform import AddEntitiesCallback
19 
20 from .const import DOMAIN
21 from .entity import WiLightDevice
22 from .parent_device import WiLightParent
23 
24 
25 def entities_from_discovered_wilight(api_device: PyWiLightDevice) -> list[LightEntity]:
26  """Parse configuration and add WiLight light entities."""
27  entities: list[LightEntity] = []
28  for item in api_device.items:
29  if item["type"] != ITEM_LIGHT:
30  continue
31  index = item["index"]
32  item_name = item["name"]
33  if item["sub_type"] == LIGHT_ON_OFF:
34  entities.append(WiLightLightOnOff(api_device, index, item_name))
35  elif item["sub_type"] == LIGHT_DIMMER:
36  entities.append(WiLightLightDimmer(api_device, index, item_name))
37  elif item["sub_type"] == LIGHT_COLOR:
38  entities.append(WiLightLightColor(api_device, index, item_name))
39 
40  return entities
41 
42 
44  hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
45 ) -> None:
46  """Set up WiLight lights from a config entry."""
47  parent: WiLightParent = hass.data[DOMAIN][entry.entry_id]
48 
49  # Handle a discovered WiLight device.
50  assert parent.api
51  entities = entities_from_discovered_wilight(parent.api)
52  async_add_entities(entities)
53 
54 
56  """Representation of a WiLights light on-off."""
57 
58  _attr_name = None
59  _attr_color_mode = ColorMode.ONOFF
60  _attr_supported_color_modes = {ColorMode.ONOFF}
61 
62  @property
63  def is_on(self) -> bool | None:
64  """Return true if device is on."""
65  return self._status_status.get("on")
66 
67  async def async_turn_on(self, **kwargs: Any) -> None:
68  """Turn the device on."""
69  await self._client_client.turn_on(self._index_index)
70 
71  async def async_turn_off(self, **kwargs: Any) -> None:
72  """Turn the device off."""
73  await self._client_client.turn_off(self._index_index)
74 
75 
77  """Representation of a WiLights light dimmer."""
78 
79  _attr_name = None
80  _attr_color_mode = ColorMode.BRIGHTNESS
81  _attr_supported_color_modes = {ColorMode.BRIGHTNESS}
82 
83  @property
84  def brightness(self) -> int:
85  """Return the brightness of this light between 0..255."""
86  return int(self._status_status.get("brightness", 0))
87 
88  @property
89  def is_on(self) -> bool | None:
90  """Return true if device is on."""
91  return self._status_status.get("on")
92 
93  async def async_turn_on(self, **kwargs: Any) -> None:
94  """Turn the device on,set brightness if needed."""
95  # Dimmer switches use a range of [0, 255] to control
96  # brightness. Level 255 might mean to set it to previous value
97  if ATTR_BRIGHTNESS in kwargs:
98  brightness = kwargs[ATTR_BRIGHTNESS]
99  await self._client_client.set_brightness(self._index_index, brightness)
100  else:
101  await self._client_client.turn_on(self._index_index)
102 
103  async def async_turn_off(self, **kwargs: Any) -> None:
104  """Turn the device off."""
105  await self._client_client.turn_off(self._index_index)
106 
107 
108 def wilight_to_hass_hue(value: int) -> float:
109  """Convert wilight hue 1..255 to hass 0..360 scale."""
110  return min(360, round((value * 360) / 255, 3))
111 
112 
113 def hass_to_wilight_hue(value: float) -> int:
114  """Convert hass hue 0..360 to wilight 1..255 scale."""
115  return min(255, round((value * 255) / 360))
116 
117 
118 def wilight_to_hass_saturation(value: int) -> float:
119  """Convert wilight saturation 1..255 to hass 0..100 scale."""
120  return min(100, round((value * 100) / 255, 3))
121 
122 
123 def hass_to_wilight_saturation(value: float) -> int:
124  """Convert hass saturation 0..100 to wilight 1..255 scale."""
125  return min(255, round((value * 255) / 100))
126 
127 
129  """Representation of a WiLights light rgb."""
130 
131  _attr_name = None
132  _attr_color_mode = ColorMode.HS
133  _attr_supported_color_modes = {ColorMode.HS}
134 
135  @property
136  def brightness(self) -> int:
137  """Return the brightness of this light between 0..255."""
138  return int(self._status_status.get("brightness", 0))
139 
140  @property
141  def hs_color(self) -> tuple[float, float]:
142  """Return the hue and saturation color value [float, float]."""
143  return (
144  wilight_to_hass_hue(int(self._status_status.get("hue", 0))),
145  wilight_to_hass_saturation(int(self._status_status.get("saturation", 0))),
146  )
147 
148  @property
149  def is_on(self) -> bool | None:
150  """Return true if device is on."""
151  return self._status_status.get("on")
152 
153  async def async_turn_on(self, **kwargs: Any) -> None:
154  """Turn the device on,set brightness if needed."""
155  # Brightness use a range of [0, 255] to control
156  # Hue use a range of [0, 360] to control
157  # Saturation use a range of [0, 100] to control
158  if ATTR_BRIGHTNESS in kwargs and ATTR_HS_COLOR in kwargs:
159  brightness = kwargs[ATTR_BRIGHTNESS]
160  hue = hass_to_wilight_hue(kwargs[ATTR_HS_COLOR][0])
161  saturation = hass_to_wilight_saturation(kwargs[ATTR_HS_COLOR][1])
162  await self._client_client.set_hsb_color(self._index_index, hue, saturation, brightness)
163  elif ATTR_BRIGHTNESS in kwargs and ATTR_HS_COLOR not in kwargs:
164  brightness = kwargs[ATTR_BRIGHTNESS]
165  await self._client_client.set_brightness(self._index_index, brightness)
166  elif ATTR_BRIGHTNESS not in kwargs and ATTR_HS_COLOR in kwargs:
167  hue = hass_to_wilight_hue(kwargs[ATTR_HS_COLOR][0])
168  saturation = hass_to_wilight_saturation(kwargs[ATTR_HS_COLOR][1])
169  await self._client_client.set_hs_color(self._index_index, hue, saturation)
170  else:
171  await self._client_client.turn_on(self._index_index)
172 
173  async def async_turn_off(self, **kwargs: Any) -> None:
174  """Turn the device off."""
175  await self._client_client.turn_off(self._index_index)
None turn_off(self, **Any kwargs)
Definition: entity.py:1705
None turn_on(self, **Any kwargs)
Definition: entity.py:1697
web.Response get(self, web.Request request, str config_key)
Definition: view.py:88
list[LightEntity] entities_from_discovered_wilight(PyWiLightDevice api_device)
Definition: light.py:25
float wilight_to_hass_hue(int value)
Definition: light.py:108
float wilight_to_hass_saturation(int value)
Definition: light.py:118
int hass_to_wilight_hue(float value)
Definition: light.py:113
int hass_to_wilight_saturation(float value)
Definition: light.py:123
None async_setup_entry(HomeAssistant hass, ConfigEntry entry, AddEntitiesCallback async_add_entities)
Definition: light.py:45