Home Assistant Unofficial Reference 2024.12.1
number.py
Go to the documentation of this file.
1 """Number platform for Tessie 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
11 from tessie_api import set_charge_limit, set_charging_amps, set_speed_limit
12 
14  NumberDeviceClass,
15  NumberEntity,
16  NumberEntityDescription,
17  NumberMode,
18 )
19 from homeassistant.const import (
20  PERCENTAGE,
21  PRECISION_WHOLE,
22  UnitOfElectricCurrent,
23  UnitOfSpeed,
24 )
25 from homeassistant.core import HomeAssistant
26 from homeassistant.helpers.entity_platform import AddEntitiesCallback
27 from homeassistant.helpers.icon import icon_for_battery_level
28 
29 from . import TessieConfigEntry
30 from .entity import TessieEnergyEntity, TessieEntity
31 from .helpers import handle_command
32 from .models import TessieEnergyData, TessieVehicleData
33 
34 PARALLEL_UPDATES = 0
35 
36 
37 @dataclass(frozen=True, kw_only=True)
39  """Describes Tessie Number entity."""
40 
41  func: Callable
42  arg: str
43  native_min_value: float
44  native_max_value: float
45  min_key: str | None = None
46  max_key: str
47 
48 
49 VEHICLE_DESCRIPTIONS: tuple[TessieNumberEntityDescription, ...] = (
51  key="charge_state_charge_current_request",
52  native_step=PRECISION_WHOLE,
53  native_min_value=0,
54  native_max_value=32,
55  native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
56  device_class=NumberDeviceClass.CURRENT,
57  max_key="charge_state_charge_current_request_max",
58  func=lambda: set_charging_amps,
59  arg="amps",
60  ),
62  key="charge_state_charge_limit_soc",
63  native_step=PRECISION_WHOLE,
64  native_min_value=50,
65  native_max_value=100,
66  native_unit_of_measurement=PERCENTAGE,
67  device_class=NumberDeviceClass.BATTERY,
68  min_key="charge_state_charge_limit_soc_min",
69  max_key="charge_state_charge_limit_soc_max",
70  func=lambda: set_charge_limit,
71  arg="percent",
72  ),
74  key="vehicle_state_speed_limit_mode_current_limit_mph",
75  native_step=PRECISION_WHOLE,
76  native_min_value=50,
77  native_max_value=120,
78  native_unit_of_measurement=UnitOfSpeed.MILES_PER_HOUR,
79  device_class=NumberDeviceClass.SPEED,
80  mode=NumberMode.BOX,
81  min_key="vehicle_state_speed_limit_mode_min_limit_mph",
82  max_key="vehicle_state_speed_limit_mode_max_limit_mph",
83  func=lambda: set_speed_limit,
84  arg="mph",
85  ),
86 )
87 
88 
89 @dataclass(frozen=True, kw_only=True)
91  """Describes Tessie Number entity."""
92 
93  func: Callable[[EnergySpecific, float], Awaitable[Any]]
94  requires: str
95 
96 
97 ENERGY_INFO_DESCRIPTIONS: tuple[TessieNumberBatteryEntityDescription, ...] = (
99  key="backup_reserve_percent",
100  func=lambda api, value: api.backup(int(value)),
101  requires="components_battery",
102  ),
104  key="off_grid_vehicle_charging_reserve_percent",
105  func=lambda api, value: api.off_grid_vehicle_charging_reserve(int(value)),
106  requires="components_off_grid_vehicle_charging_reserve_supported",
107  ),
108 )
109 
110 
112  hass: HomeAssistant,
113  entry: TessieConfigEntry,
114  async_add_entities: AddEntitiesCallback,
115 ) -> None:
116  """Set up the Tessie sensor platform from a config entry."""
117  data = entry.runtime_data
118 
120  chain(
121  ( # Add vehicle entities
122  TessieNumberEntity(vehicle, description)
123  for vehicle in data.vehicles
124  for description in VEHICLE_DESCRIPTIONS
125  ),
126  ( # Add energy site entities
127  TessieEnergyInfoNumberSensorEntity(energysite, description)
128  for energysite in entry.runtime_data.energysites
129  for description in ENERGY_INFO_DESCRIPTIONS
130  if energysite.info_coordinator.data.get(description.requires)
131  ),
132  )
133  )
134 
135 
137  """Number entity for current charge."""
138 
139  entity_description: TessieNumberEntityDescription
140 
141  def __init__(
142  self,
143  vehicle: TessieVehicleData,
144  description: TessieNumberEntityDescription,
145  ) -> None:
146  """Initialize the Number entity."""
147  super().__init__(vehicle, description.key)
148  self.entity_descriptionentity_description = description
149 
150  @property
151  def native_value(self) -> float | None:
152  """Return the value reported by the number."""
153  return self._value_value_value
154 
155  @property
156  def native_min_value(self) -> float:
157  """Return the minimum value."""
158  if self.entity_descriptionentity_description.min_key:
159  return self.getget(
160  self.entity_descriptionentity_description.min_key,
161  self.entity_descriptionentity_description.native_min_value,
162  )
163  return self.entity_descriptionentity_description.native_min_value
164 
165  @property
166  def native_max_value(self) -> float:
167  """Return the maximum value."""
168  return self.getget(
169  self.entity_descriptionentity_description.max_key, self.entity_descriptionentity_description.native_max_value
170  )
171 
172  async def async_set_native_value(self, value: float) -> None:
173  """Set new value."""
174  await self.runrun(
175  self.entity_descriptionentity_description.func(), **{self.entity_descriptionentity_description.arg: value}
176  )
177  self.setset((self.keykey, value))
178 
179 
181  """Energy info number entity base class."""
182 
183  entity_description: TessieNumberBatteryEntityDescription
184  _attr_native_step = PRECISION_WHOLE
185  _attr_native_min_value = 0
186  _attr_native_max_value = 100
187  _attr_device_class = NumberDeviceClass.BATTERY
188  _attr_native_unit_of_measurement = PERCENTAGE
189 
190  def __init__(
191  self,
192  data: TessieEnergyData,
193  description: TessieNumberBatteryEntityDescription,
194  ) -> None:
195  """Initialize the number entity."""
196  self.entity_descriptionentity_description = description
197  super().__init__(data, data.info_coordinator, description.key)
198 
199  def _async_update_attrs(self) -> None:
200  """Update the attributes of the entity."""
201  self._attr_native_value_attr_native_value = self._value_value
202  self._attr_icon_attr_icon = icon_for_battery_level(self.native_valuenative_value)
203 
204  async def async_set_native_value(self, value: float) -> None:
205  """Set new value."""
206  value = int(value)
207  await handle_command(self.entity_descriptionentity_description.func(self.apiapiapiapi, value))
208  self._attr_native_value_attr_native_value = value
209  self.async_write_ha_stateasync_write_ha_state()
Any get(self, str|None key=None, Any|None default=None)
Definition: entity.py:52
None run(self, Callable[..., Awaitable[dict[str, Any]]] func, **Any kargs)
Definition: entity.py:96
None __init__(self, TessieEnergyData data, TessieNumberBatteryEntityDescription description)
Definition: number.py:194
None __init__(self, TessieVehicleData vehicle, TessieNumberEntityDescription description)
Definition: number.py:145
dict[str, Any] handle_command(Awaitable command)
Definition: helpers.py:36
None async_setup_entry(HomeAssistant hass, TessieConfigEntry entry, AddEntitiesCallback async_add_entities)
Definition: number.py:115
str icon_for_battery_level(int|None battery_level=None, bool charging=False)
Definition: icon.py:169