Home Assistant Unofficial Reference 2024.12.1
switch.py
Go to the documentation of this file.
1 """Support for Netgear switches."""
2 
3 from collections.abc import Callable
4 from dataclasses import dataclass
5 from datetime import timedelta
6 import logging
7 from typing import Any
8 
9 from pynetgear import ALLOW, BLOCK
10 
11 from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription
12 from homeassistant.config_entries import ConfigEntry
13 from homeassistant.const import EntityCategory
14 from homeassistant.core import HomeAssistant, callback
15 from homeassistant.helpers.entity_platform import AddEntitiesCallback
16 from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
17 
18 from .const import DOMAIN, KEY_COORDINATOR, KEY_ROUTER
19 from .entity import NetgearDeviceEntity, NetgearRouterEntity
20 from .router import NetgearRouter
21 
22 _LOGGER = logging.getLogger(__name__)
23 
24 SCAN_INTERVAL = timedelta(seconds=300)
25 
26 SWITCH_TYPES = [
28  key="allow_or_block",
29  translation_key="allowed_on_network",
30  entity_category=EntityCategory.CONFIG,
31  )
32 ]
33 
34 
35 @dataclass(frozen=True)
37  """Required attributes of NetgearSwitchEntityDescription."""
38 
39 
40 @dataclass(frozen=True, kw_only=True)
42  """Class describing Netgear Switch entities."""
43 
44  update: Callable[[NetgearRouter], bool]
45  action: Callable[[NetgearRouter], bool]
46 
47 
48 ROUTER_SWITCH_TYPES = [
50  key="access_control",
51  translation_key="access_control",
52  entity_category=EntityCategory.CONFIG,
53  update=lambda router: router.api.get_block_device_enable_status,
54  action=lambda router: router.api.set_block_device_enable,
55  ),
57  key="traffic_meter",
58  translation_key="traffic_meter",
59  entity_category=EntityCategory.CONFIG,
60  update=lambda router: router.api.get_traffic_meter_enabled,
61  action=lambda router: router.api.enable_traffic_meter,
62  ),
64  key="parental_control",
65  translation_key="parental_control",
66  entity_category=EntityCategory.CONFIG,
67  update=lambda router: router.api.get_parental_control_enable_status,
68  action=lambda router: router.api.enable_parental_control,
69  ),
71  key="qos",
72  translation_key="quality_of_service",
73  entity_category=EntityCategory.CONFIG,
74  update=lambda router: router.api.get_qos_enable_status,
75  action=lambda router: router.api.set_qos_enable_status,
76  ),
78  key="2g_guest_wifi",
79  translation_key="2g_guest_wifi",
80  entity_category=EntityCategory.CONFIG,
81  update=lambda router: router.api.get_2g_guest_access_enabled,
82  action=lambda router: router.api.set_2g_guest_access_enabled,
83  ),
85  key="5g_guest_wifi",
86  translation_key="5g_guest_wifi",
87  entity_category=EntityCategory.CONFIG,
88  update=lambda router: router.api.get_5g_guest_access_enabled,
89  action=lambda router: router.api.set_5g_guest_access_enabled,
90  ),
92  key="smart_connect",
93  translation_key="smart_connect",
94  entity_category=EntityCategory.CONFIG,
95  update=lambda router: router.api.get_smart_connect_enabled,
96  action=lambda router: router.api.set_smart_connect_enabled,
97  ),
98 ]
99 
100 
102  hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
103 ) -> None:
104  """Set up switches for Netgear component."""
105  router = hass.data[DOMAIN][entry.entry_id][KEY_ROUTER]
106 
108  NetgearRouterSwitchEntity(router, description)
109  for description in ROUTER_SWITCH_TYPES
110  )
111 
112  # Entities per network device
113  coordinator = hass.data[DOMAIN][entry.entry_id][KEY_COORDINATOR]
114  tracked = set()
115 
116  @callback
117  def new_device_callback() -> None:
118  """Add new devices if needed."""
119  new_entities = []
120  if not coordinator.data:
121  return
122 
123  for mac, device in router.devices.items():
124  if mac in tracked:
125  continue
126 
127  new_entities.extend(
128  [
129  NetgearAllowBlock(coordinator, router, device, entity_description)
130  for entity_description in SWITCH_TYPES
131  ]
132  )
133  tracked.add(mac)
134 
135  async_add_entities(new_entities)
136 
137  entry.async_on_unload(coordinator.async_add_listener(new_device_callback))
138 
139  coordinator.data = True
140  new_device_callback()
141 
142 
144  """Allow or Block a device from the network."""
145 
146  _attr_entity_registry_enabled_default = False
147 
148  def __init__(
149  self,
150  coordinator: DataUpdateCoordinator,
151  router: NetgearRouter,
152  device: dict,
153  entity_description: SwitchEntityDescription,
154  ) -> None:
155  """Initialize a Netgear device."""
156  super().__init__(coordinator, router, device)
157  self.entity_descriptionentity_description = entity_description
158  self._attr_unique_id_attr_unique_id_attr_unique_id = f"{self._mac}-{entity_description.key}"
159  self.async_update_deviceasync_update_deviceasync_update_device()
160 
161  async def async_turn_on(self, **kwargs: Any) -> None:
162  """Turn the switch on."""
163  await self._router_router.async_allow_block_device(self._mac_mac, ALLOW)
164  await self.coordinator.async_request_refresh()
165 
166  async def async_turn_off(self, **kwargs: Any) -> None:
167  """Turn the switch off."""
168  await self._router_router.async_allow_block_device(self._mac_mac, BLOCK)
169  await self.coordinator.async_request_refresh()
170 
171  @callback
172  def async_update_device(self) -> None:
173  """Update the Netgear device."""
174  self._device_device_device = self._router_router.devices[self._mac_mac]
175  self._active_active_active = self._device_device_device["active"]
176  if self._device_device_device[self.entity_descriptionentity_description.key] is None:
177  self._attr_is_on_attr_is_on = None
178  else:
179  self._attr_is_on_attr_is_on = self._device_device_device[self.entity_descriptionentity_description.key] == "Allow"
180 
181 
183  """Representation of a Netgear router switch."""
184 
185  _attr_entity_registry_enabled_default = False
186  entity_description: NetgearSwitchEntityDescription
187 
188  def __init__(
189  self,
190  router: NetgearRouter,
191  entity_description: NetgearSwitchEntityDescription,
192  ) -> None:
193  """Initialize a Netgear device."""
194  super().__init__(router)
195  self.entity_descriptionentity_description = entity_description
196  self._attr_unique_id_attr_unique_id_attr_unique_id = f"{router.serial_number}-{entity_description.key}"
197 
198  self._attr_is_on_attr_is_on = None
199  self._attr_available_attr_available = False
200 
201  async def async_added_to_hass(self):
202  """Fetch state when entity is added."""
203  await self.async_updateasync_update()
204  await super().async_added_to_hass()
205 
206  async def async_update(self):
207  """Poll the state of the switch."""
208  async with self._router_router.api_lock:
209  response = await self.hasshass.async_add_executor_job(
210  self.entity_descriptionentity_description.update(self._router_router)
211  )
212  if response is None:
213  self._attr_available_attr_available = False
214  else:
215  self._attr_is_on_attr_is_on = response
216  self._attr_available_attr_available = True
217 
218  async def async_turn_on(self, **kwargs):
219  """Turn the switch on."""
220  async with self._router_router.api_lock:
221  await self.hasshass.async_add_executor_job(
222  self.entity_descriptionentity_description.action(self._router_router), True
223  )
224 
225  async def async_turn_off(self, **kwargs):
226  """Turn the switch off."""
227  async with self._router_router.api_lock:
228  await self.hasshass.async_add_executor_job(
229  self.entity_descriptionentity_description.action(self._router_router), False
230  )
None __init__(self, DataUpdateCoordinator coordinator, NetgearRouter router, dict device, SwitchEntityDescription entity_description)
Definition: switch.py:154
None __init__(self, NetgearRouter router, NetgearSwitchEntityDescription entity_description)
Definition: switch.py:192
IssData update(pyiss.ISS iss)
Definition: __init__.py:33
None async_setup_entry(HomeAssistant hass, ConfigEntry entry, AddEntitiesCallback async_add_entities)
Definition: switch.py:103