Home Assistant Unofficial Reference 2024.12.1
number.py
Go to the documentation of this file.
1 """Number platform for Tesla Fleet integration."""
2 
3 from __future__ import annotations
4 
5 from collections.abc import Awaitable, Callable
6 from dataclasses import dataclass
7 from itertools import chain
8 from typing import Any
9 
10 from tesla_fleet_api import EnergySpecific, VehicleSpecific
11 from tesla_fleet_api.const import Scope
12 
14  NumberDeviceClass,
15  NumberEntity,
16  NumberEntityDescription,
17  NumberMode,
18 )
19 from homeassistant.const import PERCENTAGE, PRECISION_WHOLE, UnitOfElectricCurrent
20 from homeassistant.core import HomeAssistant
21 from homeassistant.helpers.entity_platform import AddEntitiesCallback
22 from homeassistant.helpers.icon import icon_for_battery_level
23 
24 from . import TeslaFleetConfigEntry
25 from .entity import TeslaFleetEnergyInfoEntity, TeslaFleetVehicleEntity
26 from .helpers import handle_command, handle_vehicle_command
27 from .models import TeslaFleetEnergyData, TeslaFleetVehicleData
28 
29 PARALLEL_UPDATES = 0
30 
31 
32 @dataclass(frozen=True, kw_only=True)
34  """Describes TeslaFleet Number entity."""
35 
36  func: Callable[[VehicleSpecific, float], Awaitable[Any]]
37  native_min_value: float
38  native_max_value: float
39  min_key: str | None = None
40  max_key: str
41  scopes: list[Scope]
42 
43 
44 VEHICLE_DESCRIPTIONS: tuple[TeslaFleetNumberVehicleEntityDescription, ...] = (
46  key="charge_state_charge_current_request",
47  native_step=PRECISION_WHOLE,
48  native_min_value=0,
49  native_max_value=32,
50  native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
51  device_class=NumberDeviceClass.CURRENT,
52  mode=NumberMode.AUTO,
53  max_key="charge_state_charge_current_request_max",
54  func=lambda api, value: api.set_charging_amps(value),
55  scopes=[Scope.VEHICLE_CHARGING_CMDS],
56  ),
58  key="charge_state_charge_limit_soc",
59  native_step=PRECISION_WHOLE,
60  native_min_value=50,
61  native_max_value=100,
62  native_unit_of_measurement=PERCENTAGE,
63  device_class=NumberDeviceClass.BATTERY,
64  mode=NumberMode.AUTO,
65  min_key="charge_state_charge_limit_soc_min",
66  max_key="charge_state_charge_limit_soc_max",
67  func=lambda api, value: api.set_charge_limit(value),
68  scopes=[Scope.VEHICLE_CHARGING_CMDS, Scope.VEHICLE_CMDS],
69  ),
70 )
71 
72 
73 @dataclass(frozen=True, kw_only=True)
75  """Describes TeslaFleet Number entity."""
76 
77  func: Callable[[EnergySpecific, float], Awaitable[Any]]
78  requires: str | None = None
79 
80 
81 ENERGY_INFO_DESCRIPTIONS: tuple[TeslaFleetNumberBatteryEntityDescription, ...] = (
83  key="backup_reserve_percent",
84  func=lambda api, value: api.backup(int(value)),
85  requires="components_battery",
86  ),
88  key="off_grid_vehicle_charging_reserve_percent",
89  func=lambda api, value: api.off_grid_vehicle_charging_reserve(int(value)),
90  requires="components_off_grid_vehicle_charging_reserve_supported",
91  ),
92 )
93 
94 
96  hass: HomeAssistant,
97  entry: TeslaFleetConfigEntry,
98  async_add_entities: AddEntitiesCallback,
99 ) -> None:
100  """Set up the TeslaFleet number platform from a config entry."""
101 
103  chain(
104  ( # Add vehicle entities
106  vehicle,
107  description,
108  entry.runtime_data.scopes,
109  )
110  for vehicle in entry.runtime_data.vehicles
111  for description in VEHICLE_DESCRIPTIONS
112  ),
113  ( # Add energy site entities
115  energysite,
116  description,
117  entry.runtime_data.scopes,
118  )
119  for energysite in entry.runtime_data.energysites
120  for description in ENERGY_INFO_DESCRIPTIONS
121  if description.requires is None
122  or energysite.info_coordinator.data.get(description.requires)
123  ),
124  )
125  )
126 
127 
129  """Vehicle number entity base class."""
130 
131  entity_description: TeslaFleetNumberVehicleEntityDescription
132 
133  def __init__(
134  self,
135  data: TeslaFleetVehicleData,
136  description: TeslaFleetNumberVehicleEntityDescription,
137  scopes: list[Scope],
138  ) -> None:
139  """Initialize the number entity."""
140  self.scopedscoped = any(scope in scopes for scope in description.scopes)
141  self.entity_descriptionentity_description = description
142  super().__init__(
143  data,
144  description.key,
145  )
146 
147  def _async_update_attrs(self) -> None:
148  """Update the attributes of the entity."""
149  self._attr_native_value_attr_native_value = self._value_value_value
150 
151  if (min_key := self.entity_descriptionentity_description.min_key) is not None:
152  self._attr_native_min_value_attr_native_min_value = self.get_numberget_number(
153  min_key,
154  self.entity_descriptionentity_description.native_min_value,
155  )
156  else:
157  self._attr_native_min_value_attr_native_min_value = self.entity_descriptionentity_description.native_min_value
158 
159  self._attr_native_max_value_attr_native_max_value = self.get_numberget_number(
160  self.entity_descriptionentity_description.max_key,
161  self.entity_descriptionentity_description.native_max_value,
162  )
163 
164  async def async_set_native_value(self, value: float) -> None:
165  """Set new value."""
166  value = int(value)
167  self.raise_for_read_onlyraise_for_read_only(self.entity_descriptionentity_description.scopes[0])
168  await self.wake_up_if_asleepwake_up_if_asleep()
169  await handle_vehicle_command(self.entity_descriptionentity_description.func(self.apiapiapiapiapi, value))
170  self._attr_native_value_attr_native_value = value
171  self.async_write_ha_stateasync_write_ha_state()
172 
173 
175  """Energy info number entity base class."""
176 
177  entity_description: TeslaFleetNumberBatteryEntityDescription
178  _attr_native_step = PRECISION_WHOLE
179  _attr_native_min_value = 0
180  _attr_native_max_value = 100
181  _attr_device_class = NumberDeviceClass.BATTERY
182  _attr_native_unit_of_measurement = PERCENTAGE
183 
184  def __init__(
185  self,
186  data: TeslaFleetEnergyData,
187  description: TeslaFleetNumberBatteryEntityDescription,
188  scopes: list[Scope],
189  ) -> None:
190  """Initialize the number entity."""
191  self.scopedscoped = Scope.ENERGY_CMDS in scopes
192  self.entity_descriptionentity_description = description
193  super().__init__(data, description.key)
194 
195  def _async_update_attrs(self) -> None:
196  """Update the attributes of the entity."""
197  self._attr_native_value_attr_native_value = self._value_value
198  self._attr_icon_attr_icon = icon_for_battery_level(self.native_valuenative_value)
199 
200  async def async_set_native_value(self, value: float) -> None:
201  """Set new value."""
202  value = int(value)
203  self.raise_for_read_onlyraise_for_read_only(Scope.ENERGY_CMDS)
204  await handle_command(self.entity_descriptionentity_description.func(self.apiapiapiapiapi, value))
205  self._attr_native_value_attr_native_value = value
206  self.async_write_ha_stateasync_write_ha_state()
float get_number(self, str key, float default)
Definition: entity.py:65
None __init__(self, TeslaFleetEnergyData data, TeslaFleetNumberBatteryEntityDescription description, list[Scope] scopes)
Definition: number.py:189
None __init__(self, TeslaFleetVehicleData data, TeslaFleetNumberVehicleEntityDescription description, list[Scope] scopes)
Definition: number.py:138
bool handle_vehicle_command(Awaitable command)
Definition: helpers.py:50
dict[str, Any] handle_command(Awaitable command)
Definition: helpers.py:36
None async_setup_entry(HomeAssistant hass, TeslaFleetConfigEntry entry, AddEntitiesCallback async_add_entities)
Definition: number.py:99
str icon_for_battery_level(int|None battery_level=None, bool charging=False)
Definition: icon.py:169