Home Assistant Unofficial Reference 2024.12.1
switch.py
Go to the documentation of this file.
1 """Platform for switch integration."""
2 
3 from __future__ import annotations
4 
5 from collections.abc import Awaitable, Callable
6 from dataclasses import dataclass
7 from typing import Any
8 
9 from devolo_plc_api.device import Device
10 from devolo_plc_api.device_api import WifiGuestAccessGet
11 from devolo_plc_api.exceptions.device import DevicePasswordProtected, DeviceUnavailable
12 
13 from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription
14 from homeassistant.const import EntityCategory
15 from homeassistant.core import HomeAssistant
16 from homeassistant.exceptions import HomeAssistantError
17 from homeassistant.helpers.entity_platform import AddEntitiesCallback
18 
19 from . import DevoloHomeNetworkConfigEntry
20 from .const import DOMAIN, SWITCH_GUEST_WIFI, SWITCH_LEDS
21 from .coordinator import DevoloDataUpdateCoordinator
22 from .entity import DevoloCoordinatorEntity
23 
24 PARALLEL_UPDATES = 0
25 
26 type _DataType = WifiGuestAccessGet | bool
27 
28 
29 @dataclass(frozen=True, kw_only=True)
30 class DevoloSwitchEntityDescription[_DataT: _DataType](SwitchEntityDescription):
31  """Describes devolo switch entity."""
32 
33  is_on_func: Callable[[_DataT], bool]
34  turn_on_func: Callable[[Device], Awaitable[bool]]
35  turn_off_func: Callable[[Device], Awaitable[bool]]
36 
37 
38 SWITCH_TYPES: dict[str, DevoloSwitchEntityDescription[Any]] = {
39  SWITCH_GUEST_WIFI: DevoloSwitchEntityDescription[WifiGuestAccessGet](
40  key=SWITCH_GUEST_WIFI,
41  is_on_func=lambda data: data.enabled is True,
42  turn_on_func=lambda device: device.device.async_set_wifi_guest_access(True), # type: ignore[union-attr]
43  turn_off_func=lambda device: device.device.async_set_wifi_guest_access(False), # type: ignore[union-attr]
44  ),
45  SWITCH_LEDS: DevoloSwitchEntityDescription[bool](
46  key=SWITCH_LEDS,
47  entity_category=EntityCategory.CONFIG,
48  is_on_func=bool,
49  turn_on_func=lambda device: device.device.async_set_led_setting(True), # type: ignore[union-attr]
50  turn_off_func=lambda device: device.device.async_set_led_setting(False), # type: ignore[union-attr]
51  ),
52 }
53 
54 
56  hass: HomeAssistant,
57  entry: DevoloHomeNetworkConfigEntry,
58  async_add_entities: AddEntitiesCallback,
59 ) -> None:
60  """Get all devices and sensors and setup them via config entry."""
61  device = entry.runtime_data.device
62  coordinators = entry.runtime_data.coordinators
63 
64  entities: list[DevoloSwitchEntity[Any]] = []
65  if device.device and "led" in device.device.features:
66  entities.append(
68  entry,
69  coordinators[SWITCH_LEDS],
70  SWITCH_TYPES[SWITCH_LEDS],
71  )
72  )
73  if device.device and "wifi1" in device.device.features:
74  entities.append(
76  entry,
77  coordinators[SWITCH_GUEST_WIFI],
78  SWITCH_TYPES[SWITCH_GUEST_WIFI],
79  )
80  )
81  async_add_entities(entities)
82 
83 
84 class DevoloSwitchEntity[_DataT: _DataType](
85  DevoloCoordinatorEntity[_DataT], SwitchEntity
86 ):
87  """Representation of a devolo switch."""
88 
89  entity_description: DevoloSwitchEntityDescription[_DataT]
90 
91  def __init__(
92  self,
93  entry: DevoloHomeNetworkConfigEntry,
94  coordinator: DevoloDataUpdateCoordinator[_DataT],
95  description: DevoloSwitchEntityDescription[_DataT],
96  ) -> None:
97  """Initialize entity."""
98  self.entity_description = description
99  super().__init__(entry, coordinator)
100 
101  @property
102  def is_on(self) -> bool:
103  """State of the switch."""
104  return self.entity_description.is_on_func(self.coordinator.data)
105 
106  async def async_turn_on(self, **kwargs: Any) -> None:
107  """Turn the entity on."""
108  try:
109  await self.entity_description.turn_on_func(self.device)
110  except DevicePasswordProtected as ex:
111  self.entry.async_start_reauth(self.hass)
112  raise HomeAssistantError(
113  translation_domain=DOMAIN,
114  translation_key="password_protected",
115  translation_placeholders={"title": self.entry.title},
116  ) from ex
117  except DeviceUnavailable:
118  pass # The coordinator will handle this
119  await self.coordinator.async_request_refresh()
120 
121  async def async_turn_off(self, **kwargs: Any) -> None:
122  """Turn the entity off."""
123  try:
124  await self.entity_description.turn_off_func(self.device)
125  except DevicePasswordProtected as ex:
126  self.entry.async_start_reauth(self.hass)
127  raise HomeAssistantError(
128  translation_domain=DOMAIN,
129  translation_key="password_protected",
130  translation_placeholders={"title": self.entry.title},
131  ) from ex
132  except DeviceUnavailable:
133  pass # The coordinator will handle this
134  await self.coordinator.async_request_refresh()
None async_setup_entry(HomeAssistant hass, DevoloHomeNetworkConfigEntry entry, AddEntitiesCallback async_add_entities)
Definition: switch.py:59
None __init__(self, DevoloHomeNetworkConfigEntry entry, DevoloDataUpdateCoordinator[_DataT] coordinator, DevoloSwitchEntityDescription[_DataT] description)
Definition: switch.py:96