Home Assistant Unofficial Reference 2024.12.1
entity.py
Go to the documentation of this file.
1 """Teslemetry parent entity class."""
2 
3 from abc import abstractmethod
4 from typing import Any
5 
6 from tesla_fleet_api import EnergySpecific, VehicleSpecific
7 from tesla_fleet_api.const import Scope
8 
9 from homeassistant.exceptions import ServiceValidationError
10 from homeassistant.helpers.device_registry import DeviceInfo
11 from homeassistant.helpers.update_coordinator import CoordinatorEntity
12 
13 from .const import DOMAIN
14 from .coordinator import (
15  TeslemetryEnergyHistoryCoordinator,
16  TeslemetryEnergySiteInfoCoordinator,
17  TeslemetryEnergySiteLiveCoordinator,
18  TeslemetryVehicleDataCoordinator,
19 )
20 from .helpers import wake_up_vehicle
21 from .models import TeslemetryEnergyData, TeslemetryVehicleData
22 
23 
25  CoordinatorEntity[
26  TeslemetryVehicleDataCoordinator
27  | TeslemetryEnergyHistoryCoordinator
28  | TeslemetryEnergySiteLiveCoordinator
29  | TeslemetryEnergySiteInfoCoordinator
30  ]
31 ):
32  """Parent class for all Teslemetry entities."""
33 
34  _attr_has_entity_name = True
35  scoped: bool
36 
37  def __init__(
38  self,
39  coordinator: TeslemetryVehicleDataCoordinator
40  | TeslemetryEnergyHistoryCoordinator
41  | TeslemetryEnergySiteLiveCoordinator
42  | TeslemetryEnergySiteInfoCoordinator,
43  key: str,
44  ) -> None:
45  """Initialize common aspects of a Teslemetry entity."""
46  super().__init__(coordinator)
47  self.keykey = key
48  self._attr_translation_key_attr_translation_key = self.keykey
49  self._async_update_attrs_async_update_attrs()
50 
51  @property
52  def available(self) -> bool:
53  """Return if sensor is available."""
54  return self.coordinator.last_update_success and self._attr_available
55 
56  @property
57  def _value(self) -> Any | None:
58  """Return a specific value from coordinator data."""
59  return self.coordinator.data.get(self.keykey)
60 
61  def get(self, key: str, default: Any | None = None) -> Any | None:
62  """Return a specific value from coordinator data."""
63  return self.coordinator.data.get(key, default)
64 
65  def get_number(self, key: str, default: float) -> float:
66  """Return a specific number from coordinator data."""
67  if isinstance(value := self.coordinator.data.get(key), (int, float)):
68  return value
69  return default
70 
71  @property
72  def is_none(self) -> bool:
73  """Return if the value is a literal None."""
74  return self.getget(self.keykey, False) is None
75 
76  @property
77  def has(self) -> bool:
78  """Return True if a specific value is in coordinator data."""
79  return self.keykey in self.coordinator.data
80 
81  def _handle_coordinator_update(self) -> None:
82  """Handle updated data from the coordinator."""
83  self._async_update_attrs_async_update_attrs()
84  self.async_write_ha_state()
85 
86  @abstractmethod
87  def _async_update_attrs(self) -> None:
88  """Update the attributes of the entity."""
89 
90  def raise_for_scope(self, scope: Scope):
91  """Raise an error if a scope is not available."""
92  if not self.scoped:
93  raise ServiceValidationError(
94  translation_domain=DOMAIN,
95  translation_key="missing_scope",
96  translation_placeholders={"scope": scope},
97  )
98 
99 
101  """Parent class for Teslemetry Vehicle entities."""
102 
103  _last_update: int = 0
104  api: VehicleSpecific
105  vehicle: TeslemetryVehicleData
106 
107  def __init__(
108  self,
109  data: TeslemetryVehicleData,
110  key: str,
111  ) -> None:
112  """Initialize common aspects of a Teslemetry entity."""
113 
114  self.apiapiapiapiapiapi = data.api
115  self.vehiclevehicle = data
116  self._attr_unique_id_attr_unique_id = f"{data.vin}-{key}"
117  self._attr_device_info_attr_device_info = data.device
118  super().__init__(data.coordinator, key)
119 
120  @property
121  def _value(self) -> Any | None:
122  """Return a specific value from coordinator data."""
123  return self.coordinator.data.get(self.keykey)
124 
125  async def wake_up_if_asleep(self) -> None:
126  """Wake up the vehicle if its asleep."""
127  await wake_up_vehicle(self.vehiclevehicle)
128 
129 
131  """Parent class for Teslemetry Energy Site Live entities."""
132 
133  api: EnergySpecific
134 
135  def __init__(
136  self,
137  data: TeslemetryEnergyData,
138  key: str,
139  ) -> None:
140  """Initialize common aspects of a Teslemetry Energy Site Live entity."""
141 
142  self.apiapiapiapiapiapi = data.api
143  self._attr_unique_id_attr_unique_id = f"{data.id}-{key}"
144  self._attr_device_info_attr_device_info = data.device
145 
146  super().__init__(data.live_coordinator, key)
147 
148 
150  """Parent class for Teslemetry Energy Site Info Entities."""
151 
152  api: EnergySpecific
153 
154  def __init__(
155  self,
156  data: TeslemetryEnergyData,
157  key: str,
158  ) -> None:
159  """Initialize common aspects of a Teslemetry Energy Site Info entity."""
160 
161  self.apiapiapiapiapiapi = data.api
162  self._attr_unique_id_attr_unique_id = f"{data.id}-{key}"
163  self._attr_device_info_attr_device_info = data.device
164 
165  super().__init__(data.info_coordinator, key)
166 
167 
169  """Parent class for Teslemetry Energy History Entities."""
170 
171  def __init__(
172  self,
173  data: TeslemetryEnergyData,
174  key: str,
175  ) -> None:
176  """Initialize common aspects of a Teslemetry Energy Site Info entity."""
177 
178  assert data.history_coordinator
179 
180  self.apiapiapiapiapiapi = data.api
181  self._attr_unique_id_attr_unique_id = f"{data.id}-{key}"
182  self._attr_device_info_attr_device_info = data.device
183 
184  super().__init__(data.history_coordinator, key)
185 
186 
188  """Parent class for Teslemetry Wall Connector Entities."""
189 
190  _attr_has_entity_name = True
191  api: EnergySpecific
192 
193  def __init__(
194  self,
195  data: TeslemetryEnergyData,
196  din: str,
197  key: str,
198  ) -> None:
199  """Initialize common aspects of a Teslemetry entity."""
200 
201  self.apiapiapiapiapiapi = data.api
202  self.dindin = din
203  self._attr_unique_id_attr_unique_id = f"{data.id}-{din}-{key}"
204 
205  # Find the model from the info coordinator
206  model: str | None = None
207  for wc in data.info_coordinator.data.get("components_wall_connectors", []):
208  if wc["din"] == din:
209  model = wc.get("part_name")
210  break
211 
212  self._attr_device_info_attr_device_info = DeviceInfo(
213  identifiers={(DOMAIN, din)},
214  manufacturer="Tesla",
215  configuration_url="https://teslemetry.com/console",
216  name="Wall Connector",
217  via_device=(DOMAIN, str(data.id)),
218  serial_number=din.split("-")[-1],
219  model=model,
220  )
221 
222  super().__init__(data.live_coordinator, key)
223 
224  @property
225  def _value(self) -> int:
226  """Return a specific wall connector value from coordinator data."""
227  return (
228  self.coordinator.data.get("wall_connectors", {})
229  .get(self.dindin, {})
230  .get(self.keykey)
231  )
232 
233  @property
234  def exists(self) -> bool:
235  """Return True if it exists in the wall connector coordinator data."""
236  return self.keykey in self.coordinator.data.get("wall_connectors", {}).get(
237  self.dindin, {}
238  )
None __init__(self, TeslemetryEnergyData data, str key)
Definition: entity.py:175
None __init__(self, TeslemetryEnergyData data, str key)
Definition: entity.py:158
None __init__(self, TeslemetryEnergyData data, str key)
Definition: entity.py:139
float get_number(self, str key, float default)
Definition: entity.py:65
None __init__(self, TeslemetryVehicleDataCoordinator|TeslemetryEnergyHistoryCoordinator|TeslemetryEnergySiteLiveCoordinator|TeslemetryEnergySiteInfoCoordinator coordinator, str key)
Definition: entity.py:44
Any|None get(self, str key, Any|None default=None)
Definition: entity.py:61
None __init__(self, TeslemetryVehicleData data, str key)
Definition: entity.py:111
None __init__(self, TeslemetryEnergyData data, str din, str key)
Definition: entity.py:198
None wake_up_vehicle(TeslaFleetVehicleData vehicle)
Definition: helpers.py:15