Home Assistant Unofficial Reference 2024.12.1
light.py
Go to the documentation of this file.
1 """Support for Belkin WeMo lights."""
2 
3 from __future__ import annotations
4 
5 from typing import Any, cast
6 
7 from pywemo import Bridge, BridgeLight, Dimmer
8 
10  ATTR_BRIGHTNESS,
11  ATTR_COLOR_TEMP,
12  ATTR_HS_COLOR,
13  ATTR_TRANSITION,
14  ColorMode,
15  LightEntity,
16  LightEntityFeature,
17 )
18 from homeassistant.config_entries import ConfigEntry
19 from homeassistant.core import HomeAssistant, callback
20 from homeassistant.helpers.device_registry import CONNECTION_ZIGBEE, DeviceInfo
21 from homeassistant.helpers.entity_platform import AddEntitiesCallback
22 import homeassistant.util.color as color_util
23 
24 from . import async_wemo_dispatcher_connect
25 from .const import DOMAIN as WEMO_DOMAIN
26 from .coordinator import DeviceCoordinator
27 from .entity import WemoBinaryStateEntity, WemoEntity
28 
29 # The WEMO_ constants below come from pywemo itself
30 WEMO_OFF = 0
31 
32 
34  hass: HomeAssistant,
35  config_entry: ConfigEntry,
36  async_add_entities: AddEntitiesCallback,
37 ) -> None:
38  """Set up WeMo lights."""
39 
40  async def _discovered_wemo(coordinator: DeviceCoordinator) -> None:
41  """Handle a discovered Wemo device."""
42  if isinstance(coordinator.wemo, Bridge):
43  async_setup_bridge(hass, config_entry, async_add_entities, coordinator)
44  else:
45  async_add_entities([WemoDimmer(coordinator)])
46 
47  await async_wemo_dispatcher_connect(hass, _discovered_wemo)
48 
49 
50 @callback
52  hass: HomeAssistant,
53  config_entry: ConfigEntry,
54  async_add_entities: AddEntitiesCallback,
55  coordinator: DeviceCoordinator,
56 ) -> None:
57  """Set up a WeMo link."""
58  known_light_ids = set()
59 
60  @callback
61  def async_update_lights() -> None:
62  """Check to see if the bridge has any new lights."""
63  new_lights = []
64 
65  bridge = cast(Bridge, coordinator.wemo)
66  for light_id, light in bridge.Lights.items():
67  if light_id not in known_light_ids:
68  known_light_ids.add(light_id)
69  new_lights.append(WemoLight(coordinator, light))
70 
71  async_add_entities(new_lights)
72 
73  async_update_lights()
74  config_entry.async_on_unload(coordinator.async_add_listener(async_update_lights))
75 
76 
78  """Representation of a WeMo light."""
79 
80  _attr_supported_features = LightEntityFeature.TRANSITION
81 
82  def __init__(self, coordinator: DeviceCoordinator, light: BridgeLight) -> None:
83  """Initialize the WeMo light."""
84  super().__init__(coordinator)
85  self.lightlight = light
86  self._unique_id_unique_id = self.lightlight.uniqueID
87  self._model_name_model_name = type(self.lightlight).__name__
88 
89  @property
90  def name(self) -> str:
91  """Return the name of the device if any."""
92  return self.lightlight.name
93 
94  @property
95  def available(self) -> bool:
96  """Return true if the device is available."""
97  return super().available and self.lightlight.state.get("available", False)
98 
99  @property
100  def unique_id(self) -> str:
101  """Return the ID of this light."""
102  return self.lightlight.uniqueID
103 
104  @property
105  def device_info(self) -> DeviceInfo:
106  """Return the device info."""
107  return DeviceInfo(
108  connections={(CONNECTION_ZIGBEE, self._unique_id_unique_id)},
109  identifiers={(WEMO_DOMAIN, self._unique_id_unique_id)},
110  manufacturer="Belkin",
111  model=self._model_name_model_name,
112  name=self.namenamenamenamename,
113  )
114 
115  @property
116  def brightness(self) -> int:
117  """Return the brightness of this light between 0..255."""
118  return self.lightlight.state.get("level", 255)
119 
120  @property
121  def xy_color(self) -> tuple[float, float] | None:
122  """Return the xy color value [float, float]."""
123  return self.lightlight.state.get("color_xy")
124 
125  @property
126  def color_temp(self) -> int | None:
127  """Return the color temperature of this light in mireds."""
128  return self.lightlight.state.get("temperature_mireds")
129 
130  @property
131  def color_mode(self) -> ColorMode:
132  """Return the color mode of the light."""
133  if (
134  "colorcontrol" in self.lightlight.capabilities
135  and self.lightlight.state.get("color_xy") is not None
136  ):
137  return ColorMode.XY
138  if "colortemperature" in self.lightlight.capabilities:
139  return ColorMode.COLOR_TEMP
140  if "levelcontrol" in self.lightlight.capabilities:
141  return ColorMode.BRIGHTNESS
142  return ColorMode.ONOFF
143 
144  @property
145  def supported_color_modes(self) -> set[ColorMode]:
146  """Flag supported color modes."""
147  modes: set[ColorMode] = set()
148  if "colorcontrol" in self.lightlight.capabilities:
149  modes.add(ColorMode.XY)
150  if "colortemperature" in self.lightlight.capabilities:
151  modes.add(ColorMode.COLOR_TEMP)
152  if "levelcontrol" in self.lightlight.capabilities and not modes:
153  modes.add(ColorMode.BRIGHTNESS)
154  if not modes:
155  modes.add(ColorMode.ONOFF)
156  return modes
157 
158  @property
159  def is_on(self) -> bool:
160  """Return true if device is on."""
161  return self.lightlight.state.get("onoff", WEMO_OFF) != WEMO_OFF
162 
163  def turn_on(self, **kwargs: Any) -> None:
164  """Turn the light on."""
165  xy_color = None
166 
167  brightness = kwargs.get(ATTR_BRIGHTNESS, self.brightnessbrightnessbrightness or 255)
168  color_temp = kwargs.get(ATTR_COLOR_TEMP)
169  hs_color = kwargs.get(ATTR_HS_COLOR)
170  transition_time = int(kwargs.get(ATTR_TRANSITION, 0))
171 
172  if hs_color is not None:
173  xy_color = color_util.color_hs_to_xy(*hs_color)
174 
175  turn_on_kwargs = {
176  "level": brightness,
177  "transition": transition_time,
178  "force_update": False,
179  }
180 
181  with self._wemo_call_wrapper_wemo_call_wrapper("turn on"):
182  if xy_color is not None:
183  self.lightlight.set_color(xy_color, transition=transition_time)
184 
185  if color_temp is not None:
186  self.lightlight.set_temperature(
187  mireds=color_temp, transition=transition_time
188  )
189 
190  self.lightlight.turn_on(**turn_on_kwargs)
191 
192  def turn_off(self, **kwargs: Any) -> None:
193  """Turn the light off."""
194  transition_time = int(kwargs.get(ATTR_TRANSITION, 0))
195 
196  with self._wemo_call_wrapper_wemo_call_wrapper("turn off"):
197  self.lightlight.turn_off(transition=transition_time)
198 
199 
201  """Representation of a WeMo dimmer."""
202 
203  _attr_supported_color_modes = {ColorMode.BRIGHTNESS}
204  _attr_color_mode = ColorMode.BRIGHTNESS
205  wemo: Dimmer
206 
207  @property
208  def brightness(self) -> int:
209  """Return the brightness of this light between 1 and 100."""
210  wemo_brightness: int = self.wemowemowemo.get_brightness()
211  return int((wemo_brightness * 255) / 100)
212 
213  def turn_on(self, **kwargs: Any) -> None:
214  """Turn the dimmer on."""
215  # Wemo dimmer switches use a range of [0, 100] to control
216  # brightness. Level 255 might mean to set it to previous value
217  if ATTR_BRIGHTNESS in kwargs:
218  brightness = kwargs[ATTR_BRIGHTNESS]
219  brightness = int((brightness / 255) * 100)
220  with self._wemo_call_wrapper_wemo_call_wrapper("set brightness"):
221  self.wemowemowemo.set_brightness(brightness)
222  else:
223  with self._wemo_call_wrapper_wemo_call_wrapper("turn on"):
224  self.wemowemowemo.on()
225 
226  def turn_off(self, **kwargs: Any) -> None:
227  """Turn the dimmer off."""
228  with self._wemo_call_wrapper_wemo_call_wrapper("turn off"):
229  self.wemowemowemo.off()
Generator[None] _wemo_call_wrapper(self, str message)
Definition: entity.py:68
None turn_on(self, **Any kwargs)
Definition: light.py:213
None turn_off(self, **Any kwargs)
Definition: light.py:226
set[ColorMode] supported_color_modes(self)
Definition: light.py:145
None turn_on(self, **Any kwargs)
Definition: light.py:163
None turn_off(self, **Any kwargs)
Definition: light.py:192
tuple[float, float]|None xy_color(self)
Definition: light.py:121
None __init__(self, DeviceCoordinator coordinator, BridgeLight light)
Definition: light.py:82
str|UndefinedType|None name(self)
Definition: entity.py:738
None async_setup_bridge(HomeAssistant hass, ConfigEntry config_entry, AddEntitiesCallback async_add_entities, DeviceCoordinator coordinator)
Definition: light.py:56
None async_setup_entry(HomeAssistant hass, ConfigEntry config_entry, AddEntitiesCallback async_add_entities)
Definition: light.py:37
None async_wemo_dispatcher_connect(HomeAssistant hass, DispatchCallback dispatch)
Definition: __init__.py:159