Home Assistant Unofficial Reference 2024.12.1
button.py
Go to the documentation of this file.
1 """SFR Box button platform."""
2 
3 from __future__ import annotations
4 
5 from collections.abc import Awaitable, Callable, Coroutine
6 from dataclasses import dataclass
7 from functools import wraps
8 from typing import TYPE_CHECKING, Any, Concatenate
9 
10 from sfrbox_api.bridge import SFRBox
11 from sfrbox_api.exceptions import SFRBoxError
12 from sfrbox_api.models import SystemInfo
13 
15  ButtonDeviceClass,
16  ButtonEntity,
17  ButtonEntityDescription,
18 )
19 from homeassistant.config_entries import ConfigEntry
20 from homeassistant.const import EntityCategory
21 from homeassistant.core import HomeAssistant
22 from homeassistant.exceptions import HomeAssistantError
23 from homeassistant.helpers.device_registry import DeviceInfo
24 from homeassistant.helpers.entity_platform import AddEntitiesCallback
25 
26 from .const import DOMAIN
27 from .models import DomainData
28 
29 
30 def with_error_wrapping[**_P, _R](
31  func: Callable[Concatenate[SFRBoxButton, _P], Awaitable[_R]],
32 ) -> Callable[Concatenate[SFRBoxButton, _P], Coroutine[Any, Any, _R]]:
33  """Catch SFR errors."""
34 
35  @wraps(func)
36  async def wrapper(
37  self: SFRBoxButton,
38  *args: _P.args,
39  **kwargs: _P.kwargs,
40  ) -> _R:
41  """Catch SFRBoxError errors and raise HomeAssistantError."""
42  try:
43  return await func(self, *args, **kwargs)
44  except SFRBoxError as err:
45  raise HomeAssistantError(err) from err
46 
47  return wrapper
48 
49 
50 @dataclass(frozen=True, kw_only=True)
52  """Description for SFR Box buttons."""
53 
54  async_press: Callable[[SFRBox], Coroutine[None, None, None]]
55 
56 
57 BUTTON_TYPES: tuple[SFRBoxButtonEntityDescription, ...] = (
59  async_press=lambda x: x.system_reboot(),
60  device_class=ButtonDeviceClass.RESTART,
61  entity_category=EntityCategory.CONFIG,
62  key="system_reboot",
63  ),
64 )
65 
66 
68  hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
69 ) -> None:
70  """Set up the buttons."""
71  data: DomainData = hass.data[DOMAIN][entry.entry_id]
72  system_info = data.system.data
73  if TYPE_CHECKING:
74  assert system_info is not None
75 
76  entities = [
77  SFRBoxButton(data.box, description, system_info) for description in BUTTON_TYPES
78  ]
79  async_add_entities(entities)
80 
81 
83  """Mixin for button specific attributes."""
84 
85  entity_description: SFRBoxButtonEntityDescription
86  _attr_has_entity_name = True
87 
88  def __init__(
89  self,
90  box: SFRBox,
91  description: SFRBoxButtonEntityDescription,
92  system_info: SystemInfo,
93  ) -> None:
94  """Initialize the sensor."""
95  self.entity_descriptionentity_description = description
96  self._box_box = box
97  self._attr_unique_id_attr_unique_id = f"{system_info.mac_addr}_{description.key}"
98  self._attr_device_info_attr_device_info = DeviceInfo(
99  identifiers={(DOMAIN, system_info.mac_addr)},
100  )
101 
102  @with_error_wrapping
103  async def async_press(self) -> None:
104  """Process the button press."""
105  await self.entity_descriptionentity_description.async_press(self._box_box)
None __init__(self, SFRBox box, SFRBoxButtonEntityDescription description, SystemInfo system_info)
Definition: button.py:93
None async_setup_entry(HomeAssistant hass, ConfigEntry entry, AddEntitiesCallback async_add_entities)
Definition: button.py:69