Home Assistant Unofficial Reference 2024.12.1
button.py
Go to the documentation of this file.
1 """Switcher integration Button platform."""
2 
3 from __future__ import annotations
4 
5 from collections.abc import Callable, Coroutine
6 from dataclasses import dataclass
7 from typing import Any, cast
8 
9 from aioswitcher.api import (
10  DeviceState,
11  SwitcherApi,
12  SwitcherBaseResponse,
13  ThermostatSwing,
14 )
15 from aioswitcher.api.remotes import SwitcherBreezeRemote
16 from aioswitcher.device import DeviceCategory
17 
18 from homeassistant.components.button import ButtonEntity, ButtonEntityDescription
19 from homeassistant.const import EntityCategory
20 from homeassistant.core import HomeAssistant
21 from homeassistant.exceptions import HomeAssistantError
22 from homeassistant.helpers.dispatcher import async_dispatcher_connect
23 from homeassistant.helpers.entity_platform import AddEntitiesCallback
24 
25 from . import SwitcherConfigEntry
26 from .const import SIGNAL_DEVICE_ADD
27 from .coordinator import SwitcherDataUpdateCoordinator
28 from .entity import SwitcherEntity
29 from .utils import get_breeze_remote_manager
30 
31 
32 @dataclass(frozen=True, kw_only=True)
34  """Class to describe a Switcher Thermostat Button entity."""
35 
36  press_fn: Callable[
37  [SwitcherApi, SwitcherBreezeRemote],
38  Coroutine[Any, Any, SwitcherBaseResponse],
39  ]
40  supported: Callable[[SwitcherBreezeRemote], bool]
41 
42 
43 THERMOSTAT_BUTTONS = [
45  key="assume_on",
46  translation_key="assume_on",
47  entity_category=EntityCategory.CONFIG,
48  press_fn=lambda api, remote: api.control_breeze_device(
49  remote, state=DeviceState.ON, update_state=True
50  ),
51  supported=lambda _: True,
52  ),
54  key="assume_off",
55  translation_key="assume_off",
56  entity_category=EntityCategory.CONFIG,
57  press_fn=lambda api, remote: api.control_breeze_device(
58  remote, state=DeviceState.OFF, update_state=True
59  ),
60  supported=lambda _: True,
61  ),
63  key="vertical_swing_on",
64  translation_key="vertical_swing_on",
65  press_fn=lambda api, remote: api.control_breeze_device(
66  remote, swing=ThermostatSwing.ON
67  ),
68  supported=lambda remote: bool(remote.separated_swing_command),
69  ),
71  key="vertical_swing_off",
72  translation_key="vertical_swing_off",
73  press_fn=lambda api, remote: api.control_breeze_device(
74  remote, swing=ThermostatSwing.OFF
75  ),
76  supported=lambda remote: bool(remote.separated_swing_command),
77  ),
78 ]
79 
80 
82  hass: HomeAssistant,
83  config_entry: SwitcherConfigEntry,
84  async_add_entities: AddEntitiesCallback,
85 ) -> None:
86  """Set up Switcher button from config entry."""
87 
88  async def async_add_buttons(coordinator: SwitcherDataUpdateCoordinator) -> None:
89  """Get remote and add button from Switcher device."""
90  data = cast(SwitcherBreezeRemote, coordinator.data)
91  if coordinator.data.device_type.category == DeviceCategory.THERMOSTAT:
92  remote: SwitcherBreezeRemote = await hass.async_add_executor_job(
93  get_breeze_remote_manager(hass).get_remote, data.remote_id
94  )
96  SwitcherThermostatButtonEntity(coordinator, description, remote)
97  for description in THERMOSTAT_BUTTONS
98  if description.supported(remote)
99  )
100 
101  config_entry.async_on_unload(
102  async_dispatcher_connect(hass, SIGNAL_DEVICE_ADD, async_add_buttons)
103  )
104 
105 
107  """Representation of a Switcher climate entity."""
108 
109  entity_description: SwitcherThermostatButtonEntityDescription
110 
111  def __init__(
112  self,
113  coordinator: SwitcherDataUpdateCoordinator,
114  description: SwitcherThermostatButtonEntityDescription,
115  remote: SwitcherBreezeRemote,
116  ) -> None:
117  """Initialize the entity."""
118  super().__init__(coordinator)
119  self.entity_descriptionentity_description = description
120  self._remote_remote = remote
121 
122  self._attr_unique_id_attr_unique_id = f"{coordinator.mac_address}-{description.key}"
123 
124  async def async_press(self) -> None:
125  """Press the button."""
126  response: SwitcherBaseResponse | None = None
127  error = None
128 
129  try:
130  async with SwitcherApi(
131  self.coordinator.data.device_type,
132  self.coordinator.data.ip_address,
133  self.coordinator.data.device_id,
134  self.coordinator.data.device_key,
135  ) as swapi:
136  response = await self.entity_descriptionentity_description.press_fn(swapi, self._remote_remote)
137  except (TimeoutError, OSError, RuntimeError) as err:
138  error = repr(err)
139 
140  if error or not response or not response.successful:
141  self.coordinator.last_update_success = False
142  self.async_write_ha_stateasync_write_ha_state()
143  raise HomeAssistantError(
144  f"Call api for {self.name} failed, response/error: {response or error}"
145  )
None __init__(self, SwitcherDataUpdateCoordinator coordinator, SwitcherThermostatButtonEntityDescription description, SwitcherBreezeRemote remote)
Definition: button.py:116
None async_setup_entry(HomeAssistant hass, SwitcherConfigEntry config_entry, AddEntitiesCallback async_add_entities)
Definition: button.py:85
SwitcherBreezeRemoteManager get_breeze_remote_manager(HomeAssistant hass)
Definition: utils.py:42
Callable[[], None] async_dispatcher_connect(HomeAssistant hass, str signal, Callable[..., Any] target)
Definition: dispatcher.py:103