Home Assistant Unofficial Reference 2024.12.1
light.py
Go to the documentation of this file.
1 """Component providing HA switch support for Ring Door Bell/Chimes."""
2 
3 from datetime import timedelta
4 from enum import StrEnum, auto
5 import logging
6 from typing import Any
7 
8 from ring_doorbell import RingStickUpCam
9 
10 from homeassistant.components.light import ColorMode, LightEntity
11 from homeassistant.core import HomeAssistant, callback
12 from homeassistant.helpers.entity_platform import AddEntitiesCallback
13 import homeassistant.util.dt as dt_util
14 
15 from . import RingConfigEntry
16 from .coordinator import RingDataCoordinator
17 from .entity import RingEntity, exception_wrap
18 
19 _LOGGER = logging.getLogger(__name__)
20 
21 
22 # It takes a few seconds for the API to correctly return an update indicating
23 # that the changes have been made. Once we request a change (i.e. a light
24 # being turned on) we simply wait for this time delta before we allow
25 # updates to take place.
26 
27 SKIP_UPDATES_DELAY = timedelta(seconds=5)
28 
29 
30 class OnOffState(StrEnum):
31  """Enum for allowed on off states."""
32 
33  ON = auto()
34  OFF = auto()
35 
36 
38  hass: HomeAssistant,
39  entry: RingConfigEntry,
40  async_add_entities: AddEntitiesCallback,
41 ) -> None:
42  """Create the lights for the Ring devices."""
43  ring_data = entry.runtime_data
44  devices_coordinator = ring_data.devices_coordinator
45 
47  RingLight(device, devices_coordinator)
48  for device in ring_data.devices.stickup_cams
49  if device.has_capability("light")
50  )
51 
52 
53 class RingLight(RingEntity[RingStickUpCam], LightEntity):
54  """Creates a switch to turn the ring cameras light on and off."""
55 
56  _attr_color_mode = ColorMode.ONOFF
57  _attr_supported_color_modes = {ColorMode.ONOFF}
58  _attr_translation_key = "light"
59 
60  def __init__(
61  self, device: RingStickUpCam, coordinator: RingDataCoordinator
62  ) -> None:
63  """Initialize the light."""
64  super().__init__(device, coordinator)
65  self._attr_unique_id_attr_unique_id = str(device.id)
66  self._attr_is_on_attr_is_on = device.lights == OnOffState.ON
67  self._no_updates_until_no_updates_until = dt_util.utcnow()
68 
69  @callback
70  def _handle_coordinator_update(self) -> None:
71  """Call update method."""
72  if self._no_updates_until_no_updates_until > dt_util.utcnow():
73  return
74  device = self._get_coordinator_data_get_coordinator_data().get_stickup_cam(
75  self._device_device_device.device_api_id
76  )
77  self._attr_is_on_attr_is_on = device.lights == OnOffState.ON
79 
80  @exception_wrap
81  async def _async_set_light(self, new_state: OnOffState) -> None:
82  """Update light state, and causes Home Assistant to correctly update."""
83  await self._device_device_device.async_set_lights(new_state)
84 
85  self._attr_is_on_attr_is_on = new_state == OnOffState.ON
86  self._no_updates_until_no_updates_until = dt_util.utcnow() + SKIP_UPDATES_DELAY
87  self.async_write_ha_stateasync_write_ha_state()
88 
89  async def async_turn_on(self, **kwargs: Any) -> None:
90  """Turn the light on for 30 seconds."""
91  await self._async_set_light_async_set_light(OnOffState.ON)
92 
93  async def async_turn_off(self, **kwargs: Any) -> None:
94  """Turn the light off."""
95  await self._async_set_light_async_set_light(OnOffState.OFF)
None _async_set_light(self, OnOffState new_state)
Definition: light.py:81
None async_turn_on(self, **Any kwargs)
Definition: light.py:89
None __init__(self, RingStickUpCam device, RingDataCoordinator coordinator)
Definition: light.py:62
None async_turn_off(self, **Any kwargs)
Definition: light.py:93
None async_setup_entry(HomeAssistant hass, RingConfigEntry entry, AddEntitiesCallback async_add_entities)
Definition: light.py:41