Home Assistant Unofficial Reference 2024.12.1
number.py
Go to the documentation of this file.
1 """Support for number entities."""
2 
3 from __future__ import annotations
4 
5 from dataclasses import dataclass, field
6 
7 from gardena_bluetooth.const import DeviceConfiguration, Sensor, Valve
8 from gardena_bluetooth.parse import (
9  Characteristic,
10  CharacteristicInt,
11  CharacteristicLong,
12  CharacteristicUInt16,
13 )
14 
16  NumberEntity,
17  NumberEntityDescription,
18  NumberMode,
19 )
20 from homeassistant.const import PERCENTAGE, EntityCategory, UnitOfTime
21 from homeassistant.core import HomeAssistant
22 from homeassistant.helpers.entity_platform import AddEntitiesCallback
23 
24 from . import GardenaBluetoothConfigEntry
25 from .coordinator import GardenaBluetoothCoordinator
26 from .entity import GardenaBluetoothDescriptorEntity, GardenaBluetoothEntity
27 
28 
29 @dataclass(frozen=True)
31  """Description of entity."""
32 
33  char: CharacteristicInt | CharacteristicUInt16 | CharacteristicLong = field(
34  default_factory=lambda: CharacteristicInt("")
35  )
36  connected_state: Characteristic | None = None
37 
38  @property
39  def context(self) -> set[str]:
40  """Context needed for update coordinator."""
41  data = {self.char.uuid}
42  if self.connected_state:
43  data.add(self.connected_state.uuid)
44  return data
45 
46 
47 DESCRIPTIONS = (
49  key=Valve.manual_watering_time.uuid,
50  translation_key="manual_watering_time",
51  native_unit_of_measurement=UnitOfTime.SECONDS,
52  mode=NumberMode.BOX,
53  native_min_value=0.0,
54  native_max_value=24 * 60 * 60,
55  native_step=60,
56  entity_category=EntityCategory.CONFIG,
57  char=Valve.manual_watering_time,
58  ),
60  key=Valve.remaining_open_time.uuid,
61  translation_key="remaining_open_time",
62  native_unit_of_measurement=UnitOfTime.SECONDS,
63  native_min_value=0.0,
64  native_max_value=24 * 60 * 60,
65  native_step=60.0,
66  entity_category=EntityCategory.DIAGNOSTIC,
67  char=Valve.remaining_open_time,
68  ),
70  key=DeviceConfiguration.rain_pause.uuid,
71  translation_key="rain_pause",
72  native_unit_of_measurement=UnitOfTime.MINUTES,
73  mode=NumberMode.BOX,
74  native_min_value=0.0,
75  native_max_value=7 * 24 * 60,
76  native_step=6 * 60.0,
77  entity_category=EntityCategory.CONFIG,
78  char=DeviceConfiguration.rain_pause,
79  ),
81  key=DeviceConfiguration.seasonal_adjust.uuid,
82  translation_key="seasonal_adjust",
83  native_unit_of_measurement=UnitOfTime.DAYS,
84  mode=NumberMode.BOX,
85  native_min_value=-128.0,
86  native_max_value=127.0,
87  native_step=1.0,
88  entity_category=EntityCategory.CONFIG,
89  char=DeviceConfiguration.seasonal_adjust,
90  ),
92  key=Sensor.threshold.uuid,
93  translation_key="sensor_threshold",
94  native_unit_of_measurement=PERCENTAGE,
95  mode=NumberMode.BOX,
96  native_min_value=0.0,
97  native_max_value=100.0,
98  native_step=1.0,
99  entity_category=EntityCategory.CONFIG,
100  char=Sensor.threshold,
101  connected_state=Sensor.connected_state,
102  ),
103 )
104 
105 
107  hass: HomeAssistant,
108  entry: GardenaBluetoothConfigEntry,
109  async_add_entities: AddEntitiesCallback,
110 ) -> None:
111  """Set up entity based on a config entry."""
112  coordinator = entry.runtime_data
113  entities: list[NumberEntity] = [
114  GardenaBluetoothNumber(coordinator, description, description.context)
115  for description in DESCRIPTIONS
116  if description.key in coordinator.characteristics
117  ]
118  if Valve.remaining_open_time.uuid in coordinator.characteristics:
119  entities.append(GardenaBluetoothRemainingOpenSetNumber(coordinator))
120  async_add_entities(entities)
121 
122 
124  """Representation of a number."""
125 
126  entity_description: GardenaBluetoothNumberEntityDescription
127 
128  def _handle_coordinator_update(self) -> None:
129  data = self.coordinator.get_cached(self.entity_descriptionentity_description.char)
130  if data is None:
131  self._attr_native_value_attr_native_value = None
132  else:
133  self._attr_native_value_attr_native_value = float(data)
134 
135  if char := self.entity_descriptionentity_description.connected_state:
136  self._attr_available_attr_available = bool(self.coordinator.get_cached(char))
137  else:
138  self._attr_available_attr_available = True
139 
141 
142  async def async_set_native_value(self, value: float) -> None:
143  """Set new value."""
144  await self.coordinator.write(self.entity_descriptionentity_description.char, int(value))
145  self.async_write_ha_stateasync_write_ha_state()
146 
147 
149  """Representation of a entity with remaining time."""
150 
151  _attr_translation_key = "remaining_open_set"
152  _attr_native_unit_of_measurement = "min"
153  _attr_mode = NumberMode.BOX
154  _attr_native_min_value = 0.0
155  _attr_native_max_value = 24 * 60
156  _attr_native_step = 1.0
157 
158  def __init__(
159  self,
160  coordinator: GardenaBluetoothCoordinator,
161  ) -> None:
162  """Initialize the remaining time entity."""
163  super().__init__(coordinator, {Valve.remaining_open_time.uuid})
164  self._attr_unique_id_attr_unique_id = f"{coordinator.address}-remaining_open_set"
165 
166  async def async_set_native_value(self, value: float) -> None:
167  """Set new value."""
168  await self.coordinator.write(Valve.remaining_open_time, int(value * 60))
169  self.async_write_ha_stateasync_write_ha_state()
CharacteristicType|None get_cached(self, Characteristic[CharacteristicType] char)
Definition: coordinator.py:80
None write(self, Characteristic[CharacteristicType] char, CharacteristicType value)
Definition: coordinator.py:88
None async_setup_entry(HomeAssistant hass, GardenaBluetoothConfigEntry entry, AddEntitiesCallback async_add_entities)
Definition: number.py:110