Home Assistant Unofficial Reference 2024.12.1
light.py
Go to the documentation of this file.
1 """Support for SwitchBee light."""
2 
3 from __future__ import annotations
4 
5 from typing import Any
6 
7 from switchbee.api.central_unit import SwitchBeeDeviceOfflineError, SwitchBeeError
8 from switchbee.device import ApiStateCommand, DeviceType, SwitchBeeDimmer
9 
10 from homeassistant.components.light import ATTR_BRIGHTNESS, ColorMode, LightEntity
11 from homeassistant.config_entries import ConfigEntry
12 from homeassistant.core import HomeAssistant, callback
13 from homeassistant.exceptions import HomeAssistantError
14 from homeassistant.helpers.entity_platform import AddEntitiesCallback
15 
16 from .const import DOMAIN
17 from .coordinator import SwitchBeeCoordinator
18 from .entity import SwitchBeeDeviceEntity
19 
20 MAX_BRIGHTNESS = 255
21 
22 
23 def _hass_brightness_to_switchbee(value: int) -> int:
24  """Convert hass brightness to SwitchBee."""
25  sb_brightness = int(100 * value / MAX_BRIGHTNESS)
26  # SwitchBee maximum brightness is 99
27  return sb_brightness if sb_brightness != 100 else 99
28 
29 
30 def _switchbee_brightness_to_hass(value: int) -> int:
31  """Convert SwitchBee brightness to hass."""
32  if value == 99:
33  value = 100
34  return round(value * MAX_BRIGHTNESS / 100)
35 
36 
38  hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
39 ) -> None:
40  """Set up SwitchBee light."""
41  coordinator = hass.data[DOMAIN][entry.entry_id]
43  SwitchBeeLightEntity(switchbee_device, coordinator)
44  for switchbee_device in coordinator.data.values()
45  if switchbee_device.type == DeviceType.Dimmer
46  )
47 
48 
49 class SwitchBeeLightEntity(SwitchBeeDeviceEntity[SwitchBeeDimmer], LightEntity):
50  """Representation of a SwitchBee light."""
51 
52  _attr_color_mode = ColorMode.BRIGHTNESS
53  _attr_supported_color_modes = {ColorMode.BRIGHTNESS}
54 
55  def __init__(
56  self,
57  device: SwitchBeeDimmer,
58  coordinator: SwitchBeeCoordinator,
59  ) -> None:
60  """Initialize the SwitchBee light."""
61  super().__init__(device, coordinator)
62  self._attr_is_on_attr_is_on = False
63  self._attr_brightness_attr_brightness = 0
64 
65  self._update_attrs_from_coordinator_update_attrs_from_coordinator()
66 
67  @callback
68  def _handle_coordinator_update(self) -> None:
69  """Handle updated data from the coordinator."""
70  self._update_attrs_from_coordinator_update_attrs_from_coordinator()
72 
73  def _update_attrs_from_coordinator(self) -> None:
74  coordinator_device = self._get_coordinator_device()
75  brightness = coordinator_device.brightness
76 
77  # module is offline
78  if brightness == -1:
79  self._check_if_became_offline()
80  return
81 
82  self._check_if_became_online()
83 
84  self._attr_is_on_attr_is_on = bool(brightness != 0)
85 
86  # 1-99 is the only valid SwitchBee brightness range
87  if 0 < brightness < 100:
88  self._attr_brightness_attr_brightness = _switchbee_brightness_to_hass(brightness)
89 
90  async def async_turn_on(self, **kwargs: Any) -> None:
91  """Async function to set on to light."""
92  if ATTR_BRIGHTNESS in kwargs:
93  state: int | str = _hass_brightness_to_switchbee(kwargs[ATTR_BRIGHTNESS])
94  else:
95  state = ApiStateCommand.ON
96  if self.brightnessbrightness:
97  state = _hass_brightness_to_switchbee(self.brightnessbrightness)
98 
99  try:
100  await self.coordinator.api.set_state(self._device.id, state)
101  except (SwitchBeeError, SwitchBeeDeviceOfflineError) as exp:
102  raise HomeAssistantError(
103  f"Failed to set {self.name} state {state}, {exp!s}"
104  ) from exp
105 
106  if not isinstance(state, int):
107  # We just turned the light on, still don't know the last brightness
108  # known the Central Unit (yet) the brightness will be learned
109  # and updated in the next coordinator refresh
110  return
111 
112  # update the coordinator data manually we already know the Central Unit
113  # brightness data for this light
114  self._get_coordinator_device().brightness = state
115  self.coordinator.async_set_updated_data(self.coordinator.data)
116 
117  async def async_turn_off(self, **kwargs: Any) -> None:
118  """Turn off SwitchBee light."""
119  try:
120  await self.coordinator.api.set_state(self._device.id, ApiStateCommand.OFF)
121  except (SwitchBeeError, SwitchBeeDeviceOfflineError) as exp:
122  raise HomeAssistantError(
123  f"Failed to turn off {self._attr_name}, {exp!s}"
124  ) from exp
125 
126  # update the coordinator manually
127  self._get_coordinator_device().brightness = 0
128  self.coordinator.async_set_updated_data(self.coordinator.data)
None __init__(self, SwitchBeeDimmer device, SwitchBeeCoordinator coordinator)
Definition: light.py:59
None async_setup_entry(HomeAssistant hass, ConfigEntry entry, AddEntitiesCallback async_add_entities)
Definition: light.py:39
int _hass_brightness_to_switchbee(int value)
Definition: light.py:23
int _switchbee_brightness_to_hass(int value)
Definition: light.py:30