Home Assistant Unofficial Reference 2024.12.1
entity.py
Go to the documentation of this file.
1 """Support for Freebox base features."""
2 
3 from __future__ import annotations
4 
5 from collections.abc import Callable
6 import logging
7 from typing import Any
8 
9 from homeassistant.core import HomeAssistant
10 from homeassistant.helpers.device_registry import DeviceInfo
11 from homeassistant.helpers.dispatcher import async_dispatcher_connect
12 from homeassistant.helpers.entity import Entity
13 
14 from .const import CATEGORY_TO_MODEL, DOMAIN, FreeboxHomeCategory
15 from .router import FreeboxRouter
16 
17 _LOGGER = logging.getLogger(__name__)
18 
19 
21  """Representation of a Freebox base entity."""
22 
23  def __init__(
24  self,
25  hass: HomeAssistant,
26  router: FreeboxRouter,
27  node: dict[str, Any],
28  sub_node: dict[str, Any] | None = None,
29  ) -> None:
30  """Initialize a Freebox Home entity."""
31  self._hass_hass = hass
32  self._router_router = router
33  self._node_node = node
34  self._sub_node_sub_node = sub_node
35  self._id_id = node["id"]
36  self._attr_name_attr_name = node["label"].strip()
37  self._device_name_device_name = self._attr_name_attr_name
38  self._attr_unique_id_attr_unique_id = f"{self._router.mac}-node_{self._id}"
39 
40  if sub_node is not None:
41  self._attr_name_attr_name += " " + sub_node["label"].strip()
42  self._attr_unique_id_attr_unique_id += "-" + sub_node["name"].strip()
43 
44  self._available_available = True
45  self._firmware_firmware = node["props"].get("FwVersion")
46  self._manufacturer_manufacturer = "Freebox SAS"
47  self._remove_signal_update_remove_signal_update: Callable[[], None] | None = None
48 
49  self._model_model = CATEGORY_TO_MODEL.get(node["category"])
50  if self._model_model is None:
51  if node["type"].get("inherit") == "node::rts":
52  self._manufacturer_manufacturer = "Somfy"
53  self._model_model = CATEGORY_TO_MODEL[FreeboxHomeCategory.RTS]
54  elif node["type"].get("inherit") == "node::ios":
55  self._manufacturer_manufacturer = "Somfy"
56  self._model_model = CATEGORY_TO_MODEL[FreeboxHomeCategory.IOHOME]
57 
58  self._attr_device_info_attr_device_info = DeviceInfo(
59  identifiers={(DOMAIN, self._id_id)},
60  manufacturer=self._manufacturer_manufacturer,
61  model=self._model_model,
62  name=self._device_name_device_name,
63  sw_version=self._firmware_firmware,
64  via_device=(
65  DOMAIN,
66  router.mac,
67  ),
68  )
69 
70  async def async_update_signal(self) -> None:
71  """Update signal."""
72  self._node_node = self._router_router.home_devices[self._id_id]
73  # Update name
74  if self._sub_node_sub_node is None:
75  self._attr_name_attr_name = self._node_node["label"].strip()
76  else:
77  self._attr_name_attr_name = (
78  self._node_node["label"].strip() + " " + self._sub_node_sub_node["label"].strip()
79  )
80  self.async_write_ha_stateasync_write_ha_state()
81 
83  self, command_id: int | None, value: bool | None = None
84  ) -> bool:
85  """Set Home endpoint value."""
86  if command_id is None:
87  _LOGGER.error("Unable to SET a value through the API. Command is None")
88  return False
89 
90  await self._router_router.home.set_home_endpoint_value(
91  self._id_id, command_id, {"value": value}
92  )
93  return True
94 
95  async def get_home_endpoint_value(self, command_id: Any) -> Any | None:
96  """Get Home endpoint value."""
97  if command_id is None:
98  _LOGGER.error("Unable to GET a value through the API. Command is None")
99  return None
100 
101  node = await self._router_router.home.get_home_endpoint_value(self._id_id, command_id)
102  return node.get("value")
103 
104  def get_command_id(self, nodes, ep_type: str, name: str) -> int | None:
105  """Get the command id."""
106  node = next(
107  filter(lambda x: (x["name"] == name and x["ep_type"] == ep_type), nodes),
108  None,
109  )
110  if not node:
111  _LOGGER.warning(
112  "The Freebox Home device has no command value for: %s/%s", name, ep_type
113  )
114  return None
115  return node["id"]
116 
117  async def async_added_to_hass(self) -> None:
118  """Register state update callback."""
119  self.remove_signal_updateremove_signal_update(
121  self._hass_hass,
122  self._router_router.signal_home_device_update,
123  self.async_update_signalasync_update_signal,
124  )
125  )
126 
127  async def async_will_remove_from_hass(self) -> None:
128  """When entity will be removed from hass."""
129  if self._remove_signal_update_remove_signal_update is not None:
130  self._remove_signal_update_remove_signal_update()
131 
132  def remove_signal_update(self, dispatcher: Callable[[], None]) -> None:
133  """Register state update callback."""
134  self._remove_signal_update_remove_signal_update = dispatcher
135 
136  def get_value(self, ep_type: str, name: str):
137  """Get the value."""
138  node = next(
139  (
140  endpoint
141  for endpoint in self._node_node["show_endpoints"]
142  if endpoint["name"] == name and endpoint["ep_type"] == ep_type
143  ),
144  None,
145  )
146  if node is None:
147  _LOGGER.warning(
148  "The Freebox Home device has no node value for: %s/%s", ep_type, name
149  )
150  return None
151  return node.get("value")
None __init__(self, HomeAssistant hass, FreeboxRouter router, dict[str, Any] node, dict[str, Any]|None sub_node=None)
Definition: entity.py:29
None remove_signal_update(self, Callable[[], None] dispatcher)
Definition: entity.py:132
def get_value(self, str ep_type, str name)
Definition: entity.py:136
Any|None get_home_endpoint_value(self, Any command_id)
Definition: entity.py:95
int|None get_command_id(self, nodes, str ep_type, str name)
Definition: entity.py:104
bool set_home_endpoint_value(self, int|None command_id, bool|None value=None)
Definition: entity.py:84
web.Response get(self, web.Request request, str config_key)
Definition: view.py:88
Callable[[], None] async_dispatcher_connect(HomeAssistant hass, str signal, Callable[..., Any] target)
Definition: dispatcher.py:103