Home Assistant Unofficial Reference 2024.12.1
light.py
Go to the documentation of this file.
1 """Support for Nanoleaf Lights."""
2 
3 from __future__ import annotations
4 
5 import math
6 from typing import Any
7 
9  ATTR_BRIGHTNESS,
10  ATTR_COLOR_TEMP,
11  ATTR_EFFECT,
12  ATTR_HS_COLOR,
13  ATTR_TRANSITION,
14  ColorMode,
15  LightEntity,
16  LightEntityFeature,
17 )
18 from homeassistant.core import HomeAssistant
19 from homeassistant.helpers.entity_platform import AddEntitiesCallback
20 from homeassistant.util.color import (
21  color_temperature_kelvin_to_mired as kelvin_to_mired,
22  color_temperature_mired_to_kelvin as mired_to_kelvin,
23 )
24 
25 from . import NanoleafConfigEntry
26 from .coordinator import NanoleafCoordinator
27 from .entity import NanoleafEntity
28 
29 RESERVED_EFFECTS = ("*Solid*", "*Static*", "*Dynamic*")
30 DEFAULT_NAME = "Nanoleaf"
31 
32 
34  hass: HomeAssistant,
35  entry: NanoleafConfigEntry,
36  async_add_entities: AddEntitiesCallback,
37 ) -> None:
38  """Set up the Nanoleaf light."""
39  async_add_entities([NanoleafLight(entry.runtime_data)])
40 
41 
43  """Representation of a Nanoleaf Light."""
44 
45  _attr_supported_color_modes = {ColorMode.COLOR_TEMP, ColorMode.HS}
46  _attr_supported_features = LightEntityFeature.EFFECT | LightEntityFeature.TRANSITION
47  _attr_name = None
48  _attr_translation_key = "light"
49 
50  def __init__(self, coordinator: NanoleafCoordinator) -> None:
51  """Initialize the Nanoleaf light."""
52  super().__init__(coordinator)
53  self._attr_unique_id_attr_unique_id = self._nanoleaf_nanoleaf.serial_no
54  self._attr_min_mireds_attr_min_mireds = math.ceil(
55  1000000 / self._nanoleaf_nanoleaf.color_temperature_max
56  )
57  self._attr_max_mireds_attr_max_mireds = kelvin_to_mired(self._nanoleaf_nanoleaf.color_temperature_min)
58 
59  @property
60  def brightness(self) -> int:
61  """Return the brightness of the light."""
62  return int(self._nanoleaf_nanoleaf.brightness * 2.55)
63 
64  @property
65  def color_temp(self) -> int:
66  """Return the current color temperature."""
67  return kelvin_to_mired(self._nanoleaf_nanoleaf.color_temperature)
68 
69  @property
70  def effect(self) -> str | None:
71  """Return the current effect."""
72  # The API returns the *Solid* effect if the Nanoleaf is in HS or CT mode.
73  # The effects *Static* and *Dynamic* are not supported by Home Assistant.
74  # These reserved effects are implicitly set and are not in the effect_list.
75  # https://forum.nanoleaf.me/docs/openapi#_byoot0bams8f
76  return (
77  None if self._nanoleaf_nanoleaf.effect in RESERVED_EFFECTS else self._nanoleaf_nanoleaf.effect
78  )
79 
80  @property
81  def effect_list(self) -> list[str]:
82  """Return the list of supported effects."""
83  return self._nanoleaf_nanoleaf.effects_list
84 
85  @property
86  def is_on(self) -> bool:
87  """Return true if light is on."""
88  return self._nanoleaf_nanoleaf.is_on
89 
90  @property
91  def hs_color(self) -> tuple[int, int]:
92  """Return the color in HS."""
93  return self._nanoleaf_nanoleaf.hue, self._nanoleaf_nanoleaf.saturation
94 
95  @property
96  def color_mode(self) -> ColorMode | None:
97  """Return the color mode of the light."""
98  # According to API docs, color mode is "ct", "effect" or "hs"
99  # https://forum.nanoleaf.me/docs/openapi#_4qgqrz96f44d
100  if self._nanoleaf_nanoleaf.color_mode == "ct":
101  return ColorMode.COLOR_TEMP
102  # Home Assistant does not have an "effect" color mode, just report hs
103  return ColorMode.HS
104 
105  async def async_turn_on(self, **kwargs: Any) -> None:
106  """Instruct the light to turn on."""
107  brightness = kwargs.get(ATTR_BRIGHTNESS)
108  hs_color = kwargs.get(ATTR_HS_COLOR)
109  color_temp_mired = kwargs.get(ATTR_COLOR_TEMP)
110  effect = kwargs.get(ATTR_EFFECT)
111  transition = kwargs.get(ATTR_TRANSITION)
112 
113  if effect:
114  if effect not in self.effect_listeffect_listeffect_list:
115  raise ValueError(
116  f"Attempting to apply effect not in the effect list: '{effect}'"
117  )
118  await self._nanoleaf_nanoleaf.set_effect(effect)
119  elif hs_color:
120  hue, saturation = hs_color
121  await self._nanoleaf_nanoleaf.set_hue(int(hue))
122  await self._nanoleaf_nanoleaf.set_saturation(int(saturation))
123  elif color_temp_mired:
124  await self._nanoleaf_nanoleaf.set_color_temperature(
125  mired_to_kelvin(color_temp_mired)
126  )
127  if transition:
128  if brightness: # tune to the required brightness in n seconds
129  await self._nanoleaf_nanoleaf.set_brightness(
130  int(brightness / 2.55), transition=int(kwargs[ATTR_TRANSITION])
131  )
132  else: # If brightness is not specified, assume full brightness
133  await self._nanoleaf_nanoleaf.set_brightness(100, transition=int(transition))
134  else: # If no transition is occurring, turn on the light
135  await self._nanoleaf_nanoleaf.turn_on()
136  if brightness:
137  await self._nanoleaf_nanoleaf.set_brightness(int(brightness / 2.55))
138 
139  async def async_turn_off(self, **kwargs: Any) -> None:
140  """Instruct the light to turn off."""
141  transition: float | None = kwargs.get(ATTR_TRANSITION)
142  await self._nanoleaf_nanoleaf.turn_off(None if transition is None else int(transition))
None __init__(self, NanoleafCoordinator coordinator)
Definition: light.py:50
None turn_off(self, **Any kwargs)
Definition: entity.py:1705
None turn_on(self, **Any kwargs)
Definition: entity.py:1697
None async_setup_entry(HomeAssistant hass, NanoleafConfigEntry entry, AddEntitiesCallback async_add_entities)
Definition: light.py:37