Home Assistant Unofficial Reference 2024.12.1
light.py
Go to the documentation of this file.
1 """Support for Fibaro lights."""
2 
3 from __future__ import annotations
4 
5 from contextlib import suppress
6 from typing import Any
7 
8 from pyfibaro.fibaro_device import DeviceModel
9 
11  ATTR_BRIGHTNESS,
12  ATTR_RGB_COLOR,
13  ATTR_RGBW_COLOR,
14  ENTITY_ID_FORMAT,
15  ColorMode,
16  LightEntity,
17  brightness_supported,
18  color_supported,
19 )
20 from homeassistant.config_entries import ConfigEntry
21 from homeassistant.const import Platform
22 from homeassistant.core import HomeAssistant
23 from homeassistant.helpers.entity_platform import AddEntitiesCallback
24 
25 from . import FibaroController
26 from .const import DOMAIN
27 from .entity import FibaroEntity
28 
29 PARALLEL_UPDATES = 2
30 
31 
32 def scaleto255(value: int | None) -> int:
33  """Scale the input value from 0-100 to 0-255."""
34  if value is None:
35  return 0
36  # Fibaro has a funny way of storing brightness either 0-100 or 0-99
37  # depending on device type (e.g. dimmer vs led)
38  if value > 98:
39  value = 100
40  return round(value * 2.55)
41 
42 
43 def scaleto99(value: int | None) -> int:
44  """Scale the input value from 0-255 to 0-99."""
45  if value is None:
46  return 0
47  # Make sure a low but non-zero value is not rounded down to zero
48  if 0 < value < 3:
49  return 1
50  return min(round(value / 2.55), 99)
51 
52 
54  hass: HomeAssistant,
55  entry: ConfigEntry,
56  async_add_entities: AddEntitiesCallback,
57 ) -> None:
58  """Perform the setup for Fibaro controller devices."""
59  controller: FibaroController = hass.data[DOMAIN][entry.entry_id]
61  [FibaroLight(device) for device in controller.fibaro_devices[Platform.LIGHT]],
62  True,
63  )
64 
65 
67  """Representation of a Fibaro Light, including dimmable."""
68 
69  def __init__(self, fibaro_device: DeviceModel) -> None:
70  """Initialize the light."""
71  supports_color = (
72  "color" in fibaro_device.properties
73  or "colorComponents" in fibaro_device.properties
74  or "RGB" in fibaro_device.type
75  or "rgb" in fibaro_device.type
76  or "color" in fibaro_device.base_type
77  ) and (
78  "setColor" in fibaro_device.actions
79  or "setColorComponents" in fibaro_device.actions
80  )
81  supports_white_v = (
82  "setW" in fibaro_device.actions
83  or "RGBW" in fibaro_device.type
84  or "rgbw" in fibaro_device.type
85  )
86  supports_dimming = (
87  fibaro_device.has_interface("levelChange")
88  and "setValue" in fibaro_device.actions
89  )
90 
91  if supports_color and supports_white_v:
92  self._attr_supported_color_modes_attr_supported_color_modes = {ColorMode.RGBW}
93  self._attr_color_mode_attr_color_mode = ColorMode.RGBW
94  elif supports_color:
95  self._attr_supported_color_modes_attr_supported_color_modes = {ColorMode.RGB}
96  self._attr_color_mode_attr_color_mode = ColorMode.RGB
97  elif supports_dimming:
98  self._attr_supported_color_modes_attr_supported_color_modes = {ColorMode.BRIGHTNESS}
99  self._attr_color_mode_attr_color_mode = ColorMode.BRIGHTNESS
100  else:
101  self._attr_supported_color_modes_attr_supported_color_modes = {ColorMode.ONOFF}
102  self._attr_color_mode_attr_color_mode = ColorMode.ONOFF
103 
104  super().__init__(fibaro_device)
105  self.entity_identity_identity_id = ENTITY_ID_FORMAT.format(self.ha_idha_id)
106 
107  def turn_on(self, **kwargs: Any) -> None:
108  """Turn the light on."""
109  if ATTR_BRIGHTNESS in kwargs:
110  self._attr_brightness_attr_brightness = kwargs[ATTR_BRIGHTNESS]
111  self.set_levelset_level(scaleto99(self._attr_brightness_attr_brightness))
112  return
113 
114  if ATTR_RGB_COLOR in kwargs:
115  # Update based on parameters
116  rgb = kwargs[ATTR_RGB_COLOR]
117  self._attr_rgb_color_attr_rgb_color = rgb
118  self.call_set_colorcall_set_color(int(rgb[0]), int(rgb[1]), int(rgb[2]), 0)
119  return
120 
121  if ATTR_RGBW_COLOR in kwargs:
122  # Update based on parameters
123  rgbw = kwargs[ATTR_RGBW_COLOR]
124  self._attr_rgbw_color_attr_rgbw_color = rgbw
125  self.call_set_colorcall_set_color(int(rgbw[0]), int(rgbw[1]), int(rgbw[2]), int(rgbw[3]))
126  return
127 
128  # The simplest case is left for last. No dimming, just switch on
129  self.call_turn_oncall_turn_on()
130 
131  def turn_off(self, **kwargs: Any) -> None:
132  """Turn the light off."""
133  self.call_turn_offcall_turn_off()
134 
135  def update(self) -> None:
136  """Update the state."""
137  super().update()
138 
139  # Dimmable and RGB lights can be on based on different
140  # properties, so we need to check here several values
141  # to see if the light is on.
142  light_is_on = self.current_binary_statecurrent_binary_state
143  with suppress(TypeError):
144  if self.fibaro_devicefibaro_device.brightness != 0:
145  light_is_on = True
146  with suppress(TypeError):
147  if self.fibaro_devicefibaro_device.current_program != 0:
148  light_is_on = True
149  with suppress(TypeError):
150  if self.fibaro_devicefibaro_device.current_program_id != 0:
151  light_is_on = True
152  self._attr_is_on_attr_is_on = light_is_on
153 
154  # Brightness handling
155  if brightness_supported(self.supported_color_modessupported_color_modes):
156  self._attr_brightness_attr_brightness = scaleto255(self.fibaro_devicefibaro_device.value.int_value())
157 
158  # Color handling
159  if (
160  color_supported(self.supported_color_modessupported_color_modes)
161  and self.fibaro_devicefibaro_device.color.has_color
162  ):
163  # Fibaro communicates the color as an 'R, G, B, W' string
164  rgbw = self.fibaro_devicefibaro_device.color.rgbw_color
165  if rgbw == (0, 0, 0, 0) and self.fibaro_devicefibaro_device.last_color_set.has_color:
166  rgbw = self.fibaro_devicefibaro_device.last_color_set.rgbw_color
167 
168  if self.color_modecolor_modecolor_mode == ColorMode.RGB:
169  self._attr_rgb_color_attr_rgb_color = rgbw[:3]
170  else:
171  self._attr_rgbw_color_attr_rgbw_color = rgbw
None call_set_color(self, int red, int green, int blue, int white)
Definition: entity.py:88
None __init__(self, DeviceModel fibaro_device)
Definition: light.py:69
set[ColorMode]|set[str]|None supported_color_modes(self)
Definition: __init__.py:1302
ColorMode|str|None color_mode(self)
Definition: __init__.py:909
None async_setup_entry(HomeAssistant hass, ConfigEntry entry, AddEntitiesCallback async_add_entities)
Definition: light.py:57
int scaleto99(int|None value)
Definition: light.py:43
int scaleto255(int|None value)
Definition: light.py:32
bool color_supported(Iterable[ColorMode|str]|None color_modes)
Definition: __init__.py:162
bool brightness_supported(Iterable[ColorMode|str]|None color_modes)
Definition: __init__.py:155