Home Assistant Unofficial Reference 2024.12.1
number.py
Go to the documentation of this file.
1 """GoodWe PV inverter numeric settings entities."""
2 
3 from __future__ import annotations
4 
5 from collections.abc import Awaitable, Callable
6 from dataclasses import dataclass
7 import logging
8 
9 from goodwe import Inverter, InverterError
10 
12  NumberDeviceClass,
13  NumberEntity,
14  NumberEntityDescription,
15 )
16 from homeassistant.config_entries import ConfigEntry
17 from homeassistant.const import PERCENTAGE, EntityCategory, UnitOfPower
18 from homeassistant.core import HomeAssistant
19 from homeassistant.helpers.device_registry import DeviceInfo
20 from homeassistant.helpers.entity_platform import AddEntitiesCallback
21 
22 from .const import DOMAIN, KEY_DEVICE_INFO, KEY_INVERTER
23 
24 _LOGGER = logging.getLogger(__name__)
25 
26 
27 @dataclass(frozen=True, kw_only=True)
29  """Class describing Goodwe number entities."""
30 
31  getter: Callable[[Inverter], Awaitable[int]]
32  setter: Callable[[Inverter, int], Awaitable[None]]
33  filter: Callable[[Inverter], bool]
34 
35 
36 def _get_setting_unit(inverter: Inverter, setting: str) -> str:
37  """Return the unit of an inverter setting."""
38  return next((s.unit for s in inverter.settings() if s.id_ == setting), "")
39 
40 
41 NUMBERS = (
42  # Only one of the export limits are added.
43  # Availability is checked in the filter method.
44  # Export limit in W
46  key="grid_export_limit",
47  translation_key="grid_export_limit",
48  entity_category=EntityCategory.CONFIG,
49  device_class=NumberDeviceClass.POWER,
50  native_unit_of_measurement=UnitOfPower.WATT,
51  native_step=100,
52  native_min_value=0,
53  native_max_value=10000,
54  getter=lambda inv: inv.get_grid_export_limit(),
55  setter=lambda inv, val: inv.set_grid_export_limit(val),
56  filter=lambda inv: _get_setting_unit(inv, "grid_export_limit") != "%",
57  ),
58  # Export limit in %
60  key="grid_export_limit",
61  translation_key="grid_export_limit",
62  entity_category=EntityCategory.CONFIG,
63  native_unit_of_measurement=PERCENTAGE,
64  native_step=1,
65  native_min_value=0,
66  native_max_value=200,
67  getter=lambda inv: inv.get_grid_export_limit(),
68  setter=lambda inv, val: inv.set_grid_export_limit(val),
69  filter=lambda inv: _get_setting_unit(inv, "grid_export_limit") == "%",
70  ),
72  key="battery_discharge_depth",
73  translation_key="battery_discharge_depth",
74  icon="mdi:battery-arrow-down",
75  entity_category=EntityCategory.CONFIG,
76  native_unit_of_measurement=PERCENTAGE,
77  native_step=1,
78  native_min_value=0,
79  native_max_value=99,
80  getter=lambda inv: inv.get_ongrid_battery_dod(),
81  setter=lambda inv, val: inv.set_ongrid_battery_dod(val),
82  filter=lambda inv: True,
83  ),
84 )
85 
86 
88  hass: HomeAssistant,
89  config_entry: ConfigEntry,
90  async_add_entities: AddEntitiesCallback,
91 ) -> None:
92  """Set up the inverter select entities from a config entry."""
93  inverter = hass.data[DOMAIN][config_entry.entry_id][KEY_INVERTER]
94  device_info = hass.data[DOMAIN][config_entry.entry_id][KEY_DEVICE_INFO]
95 
96  entities = []
97 
98  for description in filter(lambda dsc: dsc.filter(inverter), NUMBERS):
99  try:
100  current_value = await description.getter(inverter)
101  except (InverterError, ValueError):
102  # Inverter model does not support this setting
103  _LOGGER.debug("Could not read inverter setting %s", description.key)
104  continue
105 
106  entities.append(
107  InverterNumberEntity(device_info, description, inverter, current_value)
108  )
109 
110  async_add_entities(entities)
111 
112 
114  """Inverter numeric setting entity."""
115 
116  _attr_should_poll = False
117  _attr_has_entity_name = True
118  entity_description: GoodweNumberEntityDescription
119 
120  def __init__(
121  self,
122  device_info: DeviceInfo,
123  description: GoodweNumberEntityDescription,
124  inverter: Inverter,
125  current_value: int,
126  ) -> None:
127  """Initialize the number inverter setting entity."""
128  self.entity_descriptionentity_description = description
129  self._attr_unique_id_attr_unique_id = f"{DOMAIN}-{description.key}-{inverter.serial_number}"
130  self._attr_device_info_attr_device_info = device_info
131  self._attr_native_value_attr_native_value = float(current_value)
132  self._inverter: Inverter = inverter
133 
134  async def async_update(self) -> None:
135  """Get the current value from inverter."""
136  value = await self.entity_descriptionentity_description.getter(self._inverter)
137  self._attr_native_value_attr_native_value = float(value)
138 
139  async def async_set_native_value(self, value: float) -> None:
140  """Set new value."""
141  await self.entity_descriptionentity_description.setter(self._inverter, int(value))
142  self._attr_native_value_attr_native_value = value
143  self.async_write_ha_stateasync_write_ha_state()
None __init__(self, DeviceInfo device_info, GoodweNumberEntityDescription description, Inverter inverter, int current_value)
Definition: number.py:126
str _get_setting_unit(Inverter inverter, str setting)
Definition: number.py:36
None async_setup_entry(HomeAssistant hass, ConfigEntry config_entry, AddEntitiesCallback async_add_entities)
Definition: number.py:91