Home Assistant Unofficial Reference 2024.12.1
select.py
Go to the documentation of this file.
1 """Platform for Kostal Plenticore select widgets."""
2 
3 from __future__ import annotations
4 
5 from dataclasses import dataclass
6 from datetime import timedelta
7 import logging
8 
9 from homeassistant.components.select import SelectEntity, SelectEntityDescription
10 from homeassistant.config_entries import ConfigEntry
11 from homeassistant.const import EntityCategory
12 from homeassistant.core import HomeAssistant
13 from homeassistant.helpers.device_registry import DeviceInfo
14 from homeassistant.helpers.entity_platform import AddEntitiesCallback
15 from homeassistant.helpers.update_coordinator import CoordinatorEntity
16 
17 from .const import DOMAIN
18 from .coordinator import Plenticore, SelectDataUpdateCoordinator
19 
20 _LOGGER = logging.getLogger(__name__)
21 
22 
23 @dataclass(frozen=True, kw_only=True)
25  """A class that describes plenticore select entities."""
26 
27  module_id: str
28 
29 
30 SELECT_SETTINGS_DATA = [
32  module_id="devices:local",
33  key="battery_charge",
34  name="Battery Charging / Usage mode",
35  options=[
36  "None",
37  "Battery:SmartBatteryControl:Enable",
38  "Battery:TimeControl:Enable",
39  ],
40  )
41 ]
42 
43 
45  hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
46 ) -> None:
47  """Add kostal plenticore Select widget."""
48  plenticore: Plenticore = hass.data[DOMAIN][entry.entry_id]
49 
50  available_settings_data = await plenticore.client.get_settings()
51  select_data_update_coordinator = SelectDataUpdateCoordinator(
52  hass,
53  _LOGGER,
54  "Settings Data",
55  timedelta(seconds=30),
56  plenticore,
57  )
58 
59  entities = []
60  for description in SELECT_SETTINGS_DATA:
61  assert description.options is not None
62  if description.module_id not in available_settings_data:
63  continue
64  needed_data_ids = {
65  data_id for data_id in description.options if data_id != "None"
66  }
67  available_data_ids = {
68  setting.id for setting in available_settings_data[description.module_id]
69  }
70  if not needed_data_ids <= available_data_ids:
71  continue
72  entities.append(
74  select_data_update_coordinator,
75  description,
76  entry_id=entry.entry_id,
77  platform_name=entry.title,
78  device_info=plenticore.device_info,
79  )
80  )
81 
82  async_add_entities(entities)
83 
84 
86  CoordinatorEntity[SelectDataUpdateCoordinator], SelectEntity
87 ):
88  """Representation of a Plenticore Select."""
89 
90  _attr_entity_category = EntityCategory.CONFIG
91  entity_description: PlenticoreSelectEntityDescription
92 
93  def __init__(
94  self,
95  coordinator: SelectDataUpdateCoordinator,
96  description: PlenticoreSelectEntityDescription,
97  entry_id: str,
98  platform_name: str,
99  device_info: DeviceInfo,
100  ) -> None:
101  """Create a new Select Entity for Plenticore process data."""
102  super().__init__(coordinator)
103  self.entity_descriptionentity_description = description
104  self.entry_identry_id = entry_id
105  self.platform_nameplatform_name = platform_name
106  self.module_idmodule_id = description.module_id
107  self.data_iddata_id = description.key
108  self._attr_device_info_attr_device_info = device_info
109  self._attr_unique_id_attr_unique_id = f"{entry_id}_{description.module_id}"
110 
111  @property
112  def available(self) -> bool:
113  """Return if entity is available."""
114  return (
115  super().available
116  and self.coordinator.data is not None
117  and self.module_idmodule_id in self.coordinator.data
118  and self.data_iddata_id in self.coordinator.data[self.module_idmodule_id]
119  )
120 
121  async def async_added_to_hass(self) -> None:
122  """Register this entity on the Update Coordinator."""
123  await super().async_added_to_hass()
124  self.async_on_removeasync_on_remove(
125  self.coordinator.start_fetch_data(
126  self.module_idmodule_id, self.data_iddata_id, self.optionsoptions
127  )
128  )
129 
130  async def async_will_remove_from_hass(self) -> None:
131  """Unregister this entity from the Update Coordinator."""
132  self.coordinator.stop_fetch_data(self.module_idmodule_id, self.data_iddata_id, self.optionsoptions)
133  await super().async_will_remove_from_hass()
134 
135  async def async_select_option(self, option: str) -> None:
136  """Update the current selected option."""
137  for all_option in self.optionsoptions:
138  if all_option != "None":
139  await self.coordinator.async_write_data(
140  self.module_idmodule_id, {all_option: "0"}
141  )
142  if option != "None":
143  await self.coordinator.async_write_data(self.module_idmodule_id, {option: "1"})
144  self.async_write_ha_stateasync_write_ha_state()
145 
146  @property
147  def current_option(self) -> str | None:
148  """Return the selected entity option to represent the entity state."""
149  if self.availableavailableavailableavailable:
150  return self.coordinator.data[self.module_idmodule_id][self.data_iddata_id]
151 
152  return None
CALLBACK_TYPE start_fetch_data(self, str module_id, str data_id, list[str] all_options)
Definition: coordinator.py:264
None stop_fetch_data(self, str module_id, str data_id, list[str] all_options)
Definition: coordinator.py:278
None __init__(self, SelectDataUpdateCoordinator coordinator, PlenticoreSelectEntityDescription description, str entry_id, str platform_name, DeviceInfo device_info)
Definition: select.py:100
None async_on_remove(self, CALLBACK_TYPE func)
Definition: entity.py:1331
None async_setup_entry(HomeAssistant hass, ConfigEntry entry, AddEntitiesCallback async_add_entities)
Definition: select.py:46