Home Assistant Unofficial Reference 2024.12.1
entity.py
Go to the documentation of this file.
1 """Support for MotionMount sensors."""
2 
3 import logging
4 import socket
5 from typing import TYPE_CHECKING
6 
7 import motionmount
8 
9 from homeassistant.config_entries import ConfigEntry
10 from homeassistant.const import ATTR_CONNECTIONS, ATTR_IDENTIFIERS
11 from homeassistant.helpers import device_registry as dr
12 from homeassistant.helpers.device_registry import DeviceInfo, format_mac
13 from homeassistant.helpers.entity import Entity
14 
15 from .const import DOMAIN, EMPTY_MAC
16 
17 _LOGGER = logging.getLogger(__name__)
18 
19 
21  """Representation of a MotionMount entity."""
22 
23  _attr_should_poll = False
24  _attr_has_entity_name = True
25 
26  def __init__(self, mm: motionmount.MotionMount, config_entry: ConfigEntry) -> None:
27  """Initialize general MotionMount entity."""
28  self.mmmm = mm
29  mac = format_mac(mm.mac.hex())
30 
31  # Create a base unique id
32  if mac == EMPTY_MAC:
33  self._base_unique_id_base_unique_id = config_entry.entry_id
34  else:
35  self._base_unique_id_base_unique_id = mac
36 
37  # Set device info
38  self._attr_device_info_attr_device_info = DeviceInfo(
39  name=mm.name,
40  manufacturer="Vogel's",
41  model="MotionMount SIGNATURE Pro",
42  model_id="TVM 7675 Pro",
43  )
44 
45  if mac == EMPTY_MAC:
46  self._attr_device_info_attr_device_info[ATTR_IDENTIFIERS] = {(DOMAIN, config_entry.entry_id)}
47  else:
48  self._attr_device_info_attr_device_info[ATTR_CONNECTIONS] = {
49  (dr.CONNECTION_NETWORK_MAC, mac)
50  }
51 
52  @property
53  def available(self) -> bool:
54  """Return True if the MotionMount is available (we're connected)."""
55  return self.mmmm.is_connected
56 
57  def update_name(self) -> None:
58  """Update the name of the associated device."""
59  if TYPE_CHECKING:
60  assert self.device_entrydevice_entry
61  # Update the name in the device registry if needed
62  if self.device_entrydevice_entry.name != self.mmmm.name:
63  device_registry = dr.async_get(self.hasshass)
64  device_registry.async_update_device(self.device_entrydevice_entry.id, name=self.mmmm.name)
65 
66  async def async_added_to_hass(self) -> None:
67  """Store register state change callback."""
68  self.mmmm.add_listener(self.async_write_ha_stateasync_write_ha_state)
69  self.mmmm.add_listener(self.update_nameupdate_name)
70  await super().async_added_to_hass()
71 
72  async def async_will_remove_from_hass(self) -> None:
73  """Remove register state change callback."""
74  self.mmmm.remove_listener(self.async_write_ha_stateasync_write_ha_state)
75  self.mmmm.remove_listener(self.update_nameupdate_name)
76  await super().async_will_remove_from_hass()
77 
78  async def _ensure_connected(self) -> bool:
79  """Make sure there is a connection with the MotionMount.
80 
81  Returns false if the connection failed to be ensured.
82  """
83 
84  if self.mmmm.is_connected:
85  return True
86  try:
87  await self.mmmm.connect()
88  except (ConnectionError, TimeoutError, socket.gaierror):
89  # We're not interested in exceptions here. In case of a failed connection
90  # the try/except from the caller will report it.
91  # The purpose of `_ensure_connected()` is only to make sure we try to
92  # reconnect, where failures should not be logged each time
93  return False
94  else:
95  _LOGGER.warning("Successfully reconnected to MotionMount")
96  return True
None __init__(self, motionmount.MotionMount mm, ConfigEntry config_entry)
Definition: entity.py:26