Home Assistant Unofficial Reference 2024.12.1
button.py
Go to the documentation of this file.
1 """Representation of Z-Wave buttons."""
2 
3 from __future__ import annotations
4 
5 from zwave_js_server.client import Client as ZwaveClient
6 from zwave_js_server.model.driver import Driver
7 from zwave_js_server.model.node import Node as ZwaveNode
8 
9 from homeassistant.components.button import DOMAIN as BUTTON_DOMAIN, ButtonEntity
10 from homeassistant.config_entries import ConfigEntry
11 from homeassistant.const import EntityCategory
12 from homeassistant.core import HomeAssistant, callback
13 from homeassistant.helpers.dispatcher import async_dispatcher_connect
14 from homeassistant.helpers.entity_platform import AddEntitiesCallback
15 
16 from .const import DATA_CLIENT, DOMAIN, LOGGER
17 from .discovery import ZwaveDiscoveryInfo
18 from .entity import ZWaveBaseEntity
19 from .helpers import get_device_info, get_valueless_base_unique_id
20 
21 PARALLEL_UPDATES = 0
22 
23 
25  hass: HomeAssistant,
26  config_entry: ConfigEntry,
27  async_add_entities: AddEntitiesCallback,
28 ) -> None:
29  """Set up Z-Wave button from config entry."""
30  client: ZwaveClient = config_entry.runtime_data[DATA_CLIENT]
31 
32  @callback
33  def async_add_button(info: ZwaveDiscoveryInfo) -> None:
34  """Add Z-Wave Button."""
35  driver = client.driver
36  assert driver is not None # Driver is ready before platforms are loaded.
37  entities: list[ZWaveBaseEntity] = []
38  if info.platform_hint == "notification idle":
39  entities.append(ZWaveNotificationIdleButton(config_entry, driver, info))
40  else:
41  entities.append(ZwaveBooleanNodeButton(config_entry, driver, info))
42 
43  async_add_entities(entities)
44 
45  @callback
46  def async_add_ping_button_entity(node: ZwaveNode) -> None:
47  """Add ping button entity."""
48  driver = client.driver
49  assert driver is not None # Driver is ready before platforms are loaded.
51 
52  config_entry.async_on_unload(
54  hass,
55  f"{DOMAIN}_{config_entry.entry_id}_add_ping_button_entity",
56  async_add_ping_button_entity,
57  )
58  )
59 
60  config_entry.async_on_unload(
62  hass,
63  f"{DOMAIN}_{config_entry.entry_id}_add_{BUTTON_DOMAIN}",
64  async_add_button,
65  )
66  )
67 
68 
70  """Representation of a ZWave button entity for a boolean value."""
71 
72  def __init__(
73  self, config_entry: ConfigEntry, driver: Driver, info: ZwaveDiscoveryInfo
74  ) -> None:
75  """Initialize entity."""
76  super().__init__(config_entry, driver, info)
77  self._attr_name_attr_name_attr_name = self.generate_namegenerate_name(include_value_name=True)
78 
79  async def async_press(self) -> None:
80  """Press the button."""
81  await self._async_set_value_async_set_value(self.infoinfo.primary_value, True)
82 
83 
84 class ZWaveNodePingButton(ButtonEntity):
85  """Representation of a ping button entity."""
86 
87  _attr_should_poll = False
88  _attr_entity_category = EntityCategory.CONFIG
89  _attr_has_entity_name = True
90  _attr_translation_key = "ping"
91 
92  def __init__(self, driver: Driver, node: ZwaveNode) -> None:
93  """Initialize a ping Z-Wave device button entity."""
94  self.nodenode = node
95 
96  # Entity class attributes
97  self._base_unique_id_base_unique_id = get_valueless_base_unique_id(driver, node)
98  self._attr_unique_id_attr_unique_id = f"{self._base_unique_id}.ping"
99  # device may not be precreated in main handler yet
100  self._attr_device_info_attr_device_info = get_device_info(driver, node)
101 
102  async def async_poll_value(self, _: bool) -> None:
103  """Poll a value."""
104  # We log an error instead of raising an exception because this service call occurs
105  # in a separate task since it is called via the dispatcher and we don't want to
106  # raise the exception in that separate task because it is confusing to the user.
107  LOGGER.error(
108  "There is no value to refresh for this entity so the zwave_js.refresh_value"
109  " service won't work for it"
110  )
111 
112  async def async_added_to_hass(self) -> None:
113  """Call when entity is added."""
114  self.async_on_remove(
116  self.hass,
117  f"{DOMAIN}_{self.unique_id}_poll_value",
118  self.async_poll_valueasync_poll_value,
119  )
120  )
121 
122  # we don't listen for `remove_entity_on_ready_node` signal because this entity
123  # is created when the node is added which occurs before ready. It only needs to
124  # be removed if the node is removed from the network.
125  self.async_on_remove(
127  self.hass,
128  f"{DOMAIN}_{self._base_unique_id}_remove_entity",
129  self.async_remove,
130  )
131  )
132 
133  async def async_press(self) -> None:
134  """Press the button."""
135  self.hass.async_create_task(self.nodenode.async_ping())
136 
137 
139  """Button to idle Notification CC values."""
140 
141  _attr_entity_category = EntityCategory.CONFIG
142 
143  def __init__(
144  self, config_entry: ConfigEntry, driver: Driver, info: ZwaveDiscoveryInfo
145  ) -> None:
146  """Initialize a ZWaveNotificationIdleButton entity."""
147  super().__init__(config_entry, driver, info)
148  self._attr_name_attr_name_attr_name = self.generate_namegenerate_name(
149  alternate_value_name=self.infoinfo.primary_value.property_name,
150  additional_info=[self.infoinfo.primary_value.property_key_name],
151  name_prefix="Idle",
152  )
153  self._attr_unique_id_attr_unique_id_attr_unique_id = f"{self._attr_unique_id}.notification_idle"
154 
155  async def async_press(self) -> None:
156  """Press the button."""
157  await self.infoinfo.node.async_manually_idle_notification_value(
158  self.infoinfo.primary_value
159  )
None __init__(self, Driver driver, ZwaveNode node)
Definition: button.py:92
None __init__(self, ConfigEntry config_entry, Driver driver, ZwaveDiscoveryInfo info)
Definition: button.py:145
None __init__(self, ConfigEntry config_entry, Driver driver, ZwaveDiscoveryInfo info)
Definition: button.py:74
str generate_name(self, bool include_value_name=False, str|None alternate_value_name=None, Sequence[str|None]|None additional_info=None, str|None name_prefix=None)
Definition: entity.py:163
SetValueResult|None _async_set_value(self, ZwaveValue value, Any new_value, dict|None options=None, bool|None wait_for_result=None)
Definition: entity.py:330
DeviceInfo get_device_info(str coordinates, str name)
Definition: __init__.py:156
None async_setup_entry(HomeAssistant hass, ConfigEntry config_entry, AddEntitiesCallback async_add_entities)
Definition: button.py:28
str get_valueless_base_unique_id(Driver driver, ZwaveNode node)
Definition: helpers.py:202
Callable[[], None] async_dispatcher_connect(HomeAssistant hass, str signal, Callable[..., Any] target)
Definition: dispatcher.py:103