Home Assistant Unofficial Reference 2024.12.1
binary_sensor.py
Go to the documentation of this file.
1 """Binary Sensor platform for Tesla Fleet integration."""
2 
3 from __future__ import annotations
4 
5 from collections.abc import Callable
6 from dataclasses import dataclass
7 from itertools import chain
8 from typing import cast
9 
11  BinarySensorDeviceClass,
12  BinarySensorEntity,
13  BinarySensorEntityDescription,
14 )
15 from homeassistant.const import EntityCategory
16 from homeassistant.core import HomeAssistant
17 from homeassistant.helpers.entity_platform import AddEntitiesCallback
18 from homeassistant.helpers.typing import StateType
19 
20 from . import TeslaFleetConfigEntry
21 from .const import TeslaFleetState
22 from .entity import (
23  TeslaFleetEnergyInfoEntity,
24  TeslaFleetEnergyLiveEntity,
25  TeslaFleetVehicleEntity,
26 )
27 from .models import TeslaFleetEnergyData, TeslaFleetVehicleData
28 
29 PARALLEL_UPDATES = 0
30 
31 
32 @dataclass(frozen=True, kw_only=True)
34  """Describes Tesla Fleet binary sensor entity."""
35 
36  is_on: Callable[[StateType], bool] = bool
37 
38 
39 VEHICLE_DESCRIPTIONS: tuple[TeslaFleetBinarySensorEntityDescription, ...] = (
41  key="state",
42  device_class=BinarySensorDeviceClass.CONNECTIVITY,
43  is_on=lambda x: x == TeslaFleetState.ONLINE,
44  ),
46  key="charge_state_battery_heater_on",
47  device_class=BinarySensorDeviceClass.HEAT,
48  entity_category=EntityCategory.DIAGNOSTIC,
49  entity_registry_enabled_default=False,
50  ),
52  key="charge_state_charger_phases",
53  is_on=lambda x: cast(int, x) > 1,
54  entity_registry_enabled_default=False,
55  ),
57  key="charge_state_preconditioning_enabled",
58  entity_category=EntityCategory.DIAGNOSTIC,
59  entity_registry_enabled_default=False,
60  ),
62  key="climate_state_is_preconditioning",
63  entity_category=EntityCategory.DIAGNOSTIC,
64  entity_registry_enabled_default=False,
65  ),
67  key="charge_state_scheduled_charging_pending",
68  entity_category=EntityCategory.DIAGNOSTIC,
69  entity_registry_enabled_default=False,
70  ),
72  key="charge_state_trip_charging",
73  entity_category=EntityCategory.DIAGNOSTIC,
74  entity_registry_enabled_default=False,
75  ),
77  key="charge_state_conn_charge_cable",
78  is_on=lambda x: x != "<invalid>",
79  entity_category=EntityCategory.DIAGNOSTIC,
80  device_class=BinarySensorDeviceClass.CONNECTIVITY,
81  ),
83  key="climate_state_cabin_overheat_protection_actively_cooling",
84  device_class=BinarySensorDeviceClass.HEAT,
85  entity_category=EntityCategory.DIAGNOSTIC,
86  entity_registry_enabled_default=False,
87  ),
89  key="vehicle_state_dashcam_state",
90  device_class=BinarySensorDeviceClass.RUNNING,
91  is_on=lambda x: x == "Recording",
92  entity_category=EntityCategory.DIAGNOSTIC,
93  entity_registry_enabled_default=False,
94  ),
96  key="vehicle_state_is_user_present",
97  device_class=BinarySensorDeviceClass.PRESENCE,
98  ),
100  key="vehicle_state_tpms_soft_warning_fl",
101  device_class=BinarySensorDeviceClass.PROBLEM,
102  entity_category=EntityCategory.DIAGNOSTIC,
103  entity_registry_enabled_default=False,
104  ),
106  key="vehicle_state_tpms_soft_warning_fr",
107  device_class=BinarySensorDeviceClass.PROBLEM,
108  entity_category=EntityCategory.DIAGNOSTIC,
109  entity_registry_enabled_default=False,
110  ),
112  key="vehicle_state_tpms_soft_warning_rl",
113  device_class=BinarySensorDeviceClass.PROBLEM,
114  entity_category=EntityCategory.DIAGNOSTIC,
115  entity_registry_enabled_default=False,
116  ),
118  key="vehicle_state_tpms_soft_warning_rr",
119  device_class=BinarySensorDeviceClass.PROBLEM,
120  entity_category=EntityCategory.DIAGNOSTIC,
121  entity_registry_enabled_default=False,
122  ),
124  key="vehicle_state_fd_window",
125  device_class=BinarySensorDeviceClass.WINDOW,
126  entity_category=EntityCategory.DIAGNOSTIC,
127  ),
129  key="vehicle_state_fp_window",
130  device_class=BinarySensorDeviceClass.WINDOW,
131  entity_category=EntityCategory.DIAGNOSTIC,
132  ),
134  key="vehicle_state_rd_window",
135  device_class=BinarySensorDeviceClass.WINDOW,
136  entity_category=EntityCategory.DIAGNOSTIC,
137  ),
139  key="vehicle_state_rp_window",
140  device_class=BinarySensorDeviceClass.WINDOW,
141  entity_category=EntityCategory.DIAGNOSTIC,
142  ),
144  key="vehicle_state_df",
145  device_class=BinarySensorDeviceClass.DOOR,
146  entity_category=EntityCategory.DIAGNOSTIC,
147  ),
149  key="vehicle_state_dr",
150  device_class=BinarySensorDeviceClass.DOOR,
151  entity_category=EntityCategory.DIAGNOSTIC,
152  ),
154  key="vehicle_state_pf",
155  device_class=BinarySensorDeviceClass.DOOR,
156  entity_category=EntityCategory.DIAGNOSTIC,
157  ),
159  key="vehicle_state_pr",
160  device_class=BinarySensorDeviceClass.DOOR,
161  entity_category=EntityCategory.DIAGNOSTIC,
162  ),
163 )
164 
165 ENERGY_LIVE_DESCRIPTIONS: tuple[BinarySensorEntityDescription, ...] = (
166  BinarySensorEntityDescription(key="backup_capable"),
167  BinarySensorEntityDescription(key="grid_services_active"),
168  BinarySensorEntityDescription(key="storm_mode_active"),
169 )
170 
171 
172 ENERGY_INFO_DESCRIPTIONS: tuple[BinarySensorEntityDescription, ...] = (
174  key="components_grid_services_enabled",
175  ),
176 )
177 
178 
180  hass: HomeAssistant,
181  entry: TeslaFleetConfigEntry,
182  async_add_entities: AddEntitiesCallback,
183 ) -> None:
184  """Set up the Tesla Fleet binary sensor platform from a config entry."""
185 
187  chain(
188  ( # Vehicles
189  TeslaFleetVehicleBinarySensorEntity(vehicle, description)
190  for vehicle in entry.runtime_data.vehicles
191  for description in VEHICLE_DESCRIPTIONS
192  ),
193  ( # Energy Site Live
194  TeslaFleetEnergyLiveBinarySensorEntity(energysite, description)
195  for energysite in entry.runtime_data.energysites
196  for description in ENERGY_LIVE_DESCRIPTIONS
197  if energysite.info_coordinator.data.get("components_battery")
198  ),
199  ( # Energy Site Info
200  TeslaFleetEnergyInfoBinarySensorEntity(energysite, description)
201  for energysite in entry.runtime_data.energysites
202  for description in ENERGY_INFO_DESCRIPTIONS
203  if energysite.info_coordinator.data.get("components_battery")
204  ),
205  )
206  )
207 
208 
210  """Base class for Tesla Fleet vehicle binary sensors."""
211 
212  entity_description: TeslaFleetBinarySensorEntityDescription
213 
214  def __init__(
215  self,
216  data: TeslaFleetVehicleData,
217  description: TeslaFleetBinarySensorEntityDescription,
218  ) -> None:
219  """Initialize the binary sensor."""
220  self.entity_descriptionentity_description = description
221  super().__init__(data, description.key)
222 
223  def _async_update_attrs(self) -> None:
224  """Update the attributes of the binary sensor."""
225 
226  if self.coordinator.updated_once:
227  if self._value_value_value is None:
228  self._attr_available_attr_available = False
229  self._attr_is_on_attr_is_on = None
230  else:
231  self._attr_available_attr_available = True
232  self._attr_is_on_attr_is_on = self.entity_descriptionentity_description.is_on(self._value_value_value)
233  else:
234  self._attr_is_on_attr_is_on = None
235 
236 
238  TeslaFleetEnergyLiveEntity, BinarySensorEntity
239 ):
240  """Base class for Tesla Fleet energy live binary sensors."""
241 
242  entity_description: BinarySensorEntityDescription
243 
244  def __init__(
245  self,
246  data: TeslaFleetEnergyData,
247  description: BinarySensorEntityDescription,
248  ) -> None:
249  """Initialize the binary sensor."""
250  self.entity_descriptionentity_description = description
251  super().__init__(data, description.key)
252 
253  def _async_update_attrs(self) -> None:
254  """Update the attributes of the binary sensor."""
255  self._attr_is_on_attr_is_on = self._value_value
256 
257 
259  TeslaFleetEnergyInfoEntity, BinarySensorEntity
260 ):
261  """Base class for Tesla Fleet energy info binary sensors."""
262 
263  entity_description: BinarySensorEntityDescription
264 
265  def __init__(
266  self,
267  data: TeslaFleetEnergyData,
268  description: BinarySensorEntityDescription,
269  ) -> None:
270  """Initialize the binary sensor."""
271  self.entity_descriptionentity_description = description
272  super().__init__(data, description.key)
273 
274  def _async_update_attrs(self) -> None:
275  """Update the attributes of the binary sensor."""
276  self._attr_is_on_attr_is_on = self._value_value
None __init__(self, TeslaFleetEnergyData data, BinarySensorEntityDescription description)
None __init__(self, TeslaFleetEnergyData data, BinarySensorEntityDescription description)
None __init__(self, TeslaFleetVehicleData data, TeslaFleetBinarySensorEntityDescription description)
None async_setup_entry(HomeAssistant hass, TeslaFleetConfigEntry entry, AddEntitiesCallback async_add_entities)