Home Assistant Unofficial Reference 2024.12.1
number.py
Go to the documentation of this file.
1 """Support for a ScreenLogic number entity."""
2 
3 from dataclasses import dataclass
4 import logging
5 
6 from screenlogicpy.const.common import ScreenLogicCommunicationError, ScreenLogicError
7 from screenlogicpy.const.data import ATTR, DEVICE, GROUP, VALUE
8 from screenlogicpy.const.msg import CODE
9 from screenlogicpy.device_const.system import EQUIPMENT_FLAG
10 
12  DOMAIN as NUMBER_DOMAIN,
13  NumberEntity,
14  NumberEntityDescription,
15  NumberMode,
16 )
17 from homeassistant.const import EntityCategory
18 from homeassistant.core import HomeAssistant
19 from homeassistant.exceptions import HomeAssistantError
20 from homeassistant.helpers.entity_platform import AddEntitiesCallback
21 
22 from .coordinator import ScreenlogicDataUpdateCoordinator
23 from .entity import (
24  ScreenLogicEntity,
25  ScreenLogicEntityDescription,
26  ScreenLogicPushEntity,
27  ScreenLogicPushEntityDescription,
28 )
29 from .types import ScreenLogicConfigEntry
30 from .util import cleanup_excluded_entity, get_ha_unit
31 
32 _LOGGER = logging.getLogger(__name__)
33 
34 PARALLEL_UPDATES = 1
35 
36 
37 @dataclass(frozen=True, kw_only=True)
39  NumberEntityDescription,
40  ScreenLogicEntityDescription,
41 ):
42  """Describes a ScreenLogic number entity."""
43 
44 
45 @dataclass(frozen=True, kw_only=True)
47  ScreenLogicNumberDescription,
48  ScreenLogicPushEntityDescription,
49 ):
50  """Describes a ScreenLogic push number entity."""
51 
52 
53 SUPPORTED_INTELLICHEM_NUMBERS = [
55  subscription_code=CODE.CHEMISTRY_CHANGED,
56  data_root=(DEVICE.INTELLICHEM, GROUP.CONFIGURATION),
57  key=VALUE.CALCIUM_HARDNESS,
58  entity_category=EntityCategory.CONFIG,
59  mode=NumberMode.BOX,
60  ),
62  subscription_code=CODE.CHEMISTRY_CHANGED,
63  data_root=(DEVICE.INTELLICHEM, GROUP.CONFIGURATION),
64  key=VALUE.CYA,
65  entity_category=EntityCategory.CONFIG,
66  mode=NumberMode.BOX,
67  ),
69  subscription_code=CODE.CHEMISTRY_CHANGED,
70  data_root=(DEVICE.INTELLICHEM, GROUP.CONFIGURATION),
71  key=VALUE.TOTAL_ALKALINITY,
72  entity_category=EntityCategory.CONFIG,
73  mode=NumberMode.BOX,
74  ),
76  subscription_code=CODE.CHEMISTRY_CHANGED,
77  data_root=(DEVICE.INTELLICHEM, GROUP.CONFIGURATION),
78  key=VALUE.SALT_TDS_PPM,
79  entity_category=EntityCategory.CONFIG,
80  mode=NumberMode.BOX,
81  ),
82 ]
83 
84 SUPPORTED_SCG_NUMBERS = [
86  data_root=(DEVICE.SCG, GROUP.CONFIGURATION),
87  key=VALUE.POOL_SETPOINT,
88  entity_category=EntityCategory.CONFIG,
89  ),
91  data_root=(DEVICE.SCG, GROUP.CONFIGURATION),
92  key=VALUE.SPA_SETPOINT,
93  entity_category=EntityCategory.CONFIG,
94  ),
95 ]
96 
97 
99  hass: HomeAssistant,
100  config_entry: ScreenLogicConfigEntry,
101  async_add_entities: AddEntitiesCallback,
102 ) -> None:
103  """Set up entry."""
104  entities: list[ScreenLogicNumber] = []
105  coordinator = config_entry.runtime_data
106  gateway = coordinator.gateway
107 
108  for chem_number_description in SUPPORTED_INTELLICHEM_NUMBERS:
109  chem_number_data_path = (
110  *chem_number_description.data_root,
111  chem_number_description.key,
112  )
113  if EQUIPMENT_FLAG.INTELLICHEM not in gateway.equipment_flags:
114  cleanup_excluded_entity(coordinator, NUMBER_DOMAIN, chem_number_data_path)
115  continue
116  if gateway.get_data(*chem_number_data_path):
117  entities.append(
118  ScreenLogicChemistryNumber(coordinator, chem_number_description)
119  )
120 
121  for scg_number_description in SUPPORTED_SCG_NUMBERS:
122  scg_number_data_path = (
123  *scg_number_description.data_root,
124  scg_number_description.key,
125  )
126  if EQUIPMENT_FLAG.CHLORINATOR not in gateway.equipment_flags:
127  cleanup_excluded_entity(coordinator, NUMBER_DOMAIN, scg_number_data_path)
128  continue
129  if gateway.get_data(*scg_number_data_path):
130  entities.append(ScreenLogicSCGNumber(coordinator, scg_number_description))
131 
132  async_add_entities(entities)
133 
134 
136  """Base class to represent a ScreenLogic Number entity."""
137 
138  entity_description: ScreenLogicNumberDescription
139 
140  def __init__(
141  self,
142  coordinator: ScreenlogicDataUpdateCoordinator,
143  entity_description: ScreenLogicNumberDescription,
144  ) -> None:
145  """Initialize a ScreenLogic number entity."""
146  super().__init__(coordinator, entity_description)
147 
148  self._attr_native_unit_of_measurement_attr_native_unit_of_measurement = get_ha_unit(
149  self.entity_dataentity_data.get(ATTR.UNIT)
150  )
151  if entity_description.native_max_value is None and isinstance(
152  max_val := self.entity_dataentity_data.get(ATTR.MAX_SETPOINT), int | float
153  ):
154  self._attr_native_max_value_attr_native_max_value = max_val
155  if entity_description.native_min_value is None and isinstance(
156  min_val := self.entity_dataentity_data.get(ATTR.MIN_SETPOINT), int | float
157  ):
158  self._attr_native_min_value_attr_native_min_value = min_val
159  if entity_description.native_step is None and isinstance(
160  step := self.entity_dataentity_data.get(ATTR.STEP), int | float
161  ):
162  self._attr_native_step_attr_native_step = step
163 
164  @property
165  def native_value(self) -> float:
166  """Return the current value."""
167  return self.entity_dataentity_data[ATTR.VALUE]
168 
169  async def async_set_native_value(self, value: float) -> None:
170  """Update the current value."""
171  raise NotImplementedError
172 
173 
175  """Base class to preresent a ScreenLogic Push Number entity."""
176 
177  entity_description: ScreenLogicPushNumberDescription
178 
179 
181  """Class to represent a ScreenLogic Chemistry Number entity."""
182 
183  async def async_set_native_value(self, value: float) -> None:
184  """Update the current value."""
185 
186  # Current API requires int values for the currently supported numbers.
187  value = int(value)
188 
189  try:
190  await self.gatewaygatewaygateway.async_set_chem_data(**{self._data_key_data_key: value})
191  except (ScreenLogicCommunicationError, ScreenLogicError) as sle:
192  raise HomeAssistantError(
193  f"Failed to set '{self._data_key}' to {value}: {sle.msg}"
194  ) from sle
195  _LOGGER.debug("Set '%s' to %s", self._data_key_data_key, value)
196  await self._async_refresh_async_refresh_async_refresh()
197 
198 
200  """Class to represent a ScreenLoigic SCG Number entity."""
201 
202  async def async_set_native_value(self, value: float) -> None:
203  """Update the current value."""
204 
205  # Current API requires int values for the currently supported numbers.
206  value = int(value)
207 
208  try:
209  await self.gatewaygatewaygateway.async_set_scg_config(**{self._data_key_data_key: value})
210  except (ScreenLogicCommunicationError, ScreenLogicError) as sle:
211  raise HomeAssistantError(
212  f"Failed to set '{self._data_key}' to {value}: {sle.msg}"
213  ) from sle
214  _LOGGER.debug("Set '%s' to %s", self._data_key_data_key, value)
215  await self._async_refresh_async_refresh_async_refresh()
None __init__(self, ScreenlogicDataUpdateCoordinator coordinator, ScreenLogicNumberDescription entity_description)
Definition: number.py:144
None _async_refresh(self, bool log_failures=True, bool raise_on_auth_failed=False, bool scheduled=False, bool raise_on_entry_error=False)
web.Response get(self, web.Request request, str config_key)
Definition: view.py:88
None async_setup_entry(HomeAssistant hass, ScreenLogicConfigEntry config_entry, AddEntitiesCallback async_add_entities)
Definition: number.py:102
None cleanup_excluded_entity(ScreenlogicDataUpdateCoordinator coordinator, str platform_domain, ScreenLogicDataPath data_path)
Definition: util.py:38