Home Assistant Unofficial Reference 2024.12.1
number.py
Go to the documentation of this file.
1 """Number entity for myUplink."""
2 
3 from aiohttp import ClientError
4 from myuplink import DevicePoint
5 
6 from homeassistant.components.number import NumberEntity, NumberEntityDescription
7 from homeassistant.const import Platform
8 from homeassistant.core import HomeAssistant
9 from homeassistant.exceptions import HomeAssistantError
10 from homeassistant.helpers.entity_platform import AddEntitiesCallback
11 
12 from . import MyUplinkConfigEntry, MyUplinkDataCoordinator
13 from .const import F_SERIES
14 from .entity import MyUplinkEntity
15 from .helpers import find_matching_platform, skip_entity, transform_model_series
16 
17 DEVICE_POINT_UNIT_DESCRIPTIONS: dict[str, NumberEntityDescription] = {
19  key="degree_minutes",
20  translation_key="degree_minutes",
21  native_unit_of_measurement="DM",
22  ),
23 }
24 
25 CATEGORY_BASED_DESCRIPTIONS: dict[str, dict[str, NumberEntityDescription]] = {
26  F_SERIES: {
27  "40940": NumberEntityDescription(
28  key="degree_minutes",
29  translation_key="degree_minutes",
30  native_unit_of_measurement="DM",
31  ),
32  },
33  "NIBEF": {
34  "40940": NumberEntityDescription(
35  key="degree_minutes",
36  translation_key="degree_minutes",
37  native_unit_of_measurement="DM",
38  ),
39  },
40 }
41 
42 
43 def get_description(device_point: DevicePoint) -> NumberEntityDescription | None:
44  """Get description for a device point.
45 
46  Priorities:
47  1. Category specific prefix e.g "NIBEF"
48  2. Global parameter_unit e.g. "DM"
49  3. Default to None
50  """
51  prefix, _, _ = device_point.category.partition(" ")
52  prefix = transform_model_series(prefix)
53  description = CATEGORY_BASED_DESCRIPTIONS.get(prefix, {}).get(
54  device_point.parameter_id
55  )
56 
57  if description is None:
58  description = DEVICE_POINT_UNIT_DESCRIPTIONS.get(device_point.parameter_unit)
59 
60  return description
61 
62 
64  hass: HomeAssistant,
65  config_entry: MyUplinkConfigEntry,
66  async_add_entities: AddEntitiesCallback,
67 ) -> None:
68  """Set up myUplink number."""
69  entities: list[NumberEntity] = []
70  coordinator = config_entry.runtime_data
71 
72  # Setup device point number entities
73  for device_id, point_data in coordinator.data.points.items():
74  for point_id, device_point in point_data.items():
75  if skip_entity(device_point.category, device_point):
76  continue
77  description = get_description(device_point)
78  if find_matching_platform(device_point, description) == Platform.NUMBER:
79  entities.append(
81  coordinator=coordinator,
82  device_id=device_id,
83  device_point=device_point,
84  entity_description=description,
85  unique_id_suffix=point_id,
86  )
87  )
88 
89  async_add_entities(entities)
90 
91 
93  """Representation of a myUplink number entity."""
94 
95  def __init__(
96  self,
97  coordinator: MyUplinkDataCoordinator,
98  device_id: str,
99  device_point: DevicePoint,
100  entity_description: NumberEntityDescription | None,
101  unique_id_suffix: str,
102  ) -> None:
103  """Initialize the number."""
104  super().__init__(
105  coordinator=coordinator,
106  device_id=device_id,
107  unique_id_suffix=unique_id_suffix,
108  )
109 
110  # Internal properties
111  self.point_idpoint_id = device_point.parameter_id
112  self._attr_name_attr_name = device_point.parameter_name
113  self._attr_native_min_value_attr_native_min_value = (
114  device_point.raw["minValue"] if device_point.raw["minValue"] else -30000
115  ) * float(device_point.raw.get("scaleValue", 1))
116  self._attr_native_max_value_attr_native_max_value = (
117  device_point.raw["maxValue"] if device_point.raw["maxValue"] else 30000
118  ) * float(device_point.raw.get("scaleValue", 1))
119  self._attr_step_value_attr_step_value = device_point.raw.get("stepValue", 20)
120  if entity_description is not None:
121  self.entity_descriptionentity_description = entity_description
122 
123  @property
124  def native_value(self) -> float:
125  """Number state value."""
126  device_point = self.coordinator.data.points[self.device_iddevice_id][self.point_idpoint_id]
127  return float(device_point.value)
128 
129  async def async_set_native_value(self, value: float) -> None:
130  """Update the current value."""
131  try:
132  await self.coordinator.api.async_set_device_points(
133  self.device_iddevice_id, data={self.point_idpoint_id: str(value)}
134  )
135  except ClientError as err:
136  raise HomeAssistantError(
137  f"Failed to set new value {value} for {self.point_id}/{self.entity_id}"
138  ) from err
139 
140  await self.coordinator.async_request_refresh()
web.Response get(self, web.Request request, str config_key)
Definition: view.py:88