Home Assistant Unofficial Reference 2024.12.1
select.py
Go to the documentation of this file.
1 """Matter ModeSelect Cluster Support."""
2 
3 from __future__ import annotations
4 
5 from dataclasses import dataclass
6 from typing import TYPE_CHECKING
7 
8 from chip.clusters import Objects as clusters
9 from chip.clusters.Types import Nullable
10 from matter_server.common.helpers.util import create_attribute_path_from_attribute
11 
12 from homeassistant.components.select import SelectEntity, SelectEntityDescription
13 from homeassistant.config_entries import ConfigEntry
14 from homeassistant.const import EntityCategory, Platform
15 from homeassistant.core import HomeAssistant, callback
16 from homeassistant.helpers.entity_platform import AddEntitiesCallback
17 
18 from .entity import MatterEntity, MatterEntityDescription
19 from .helpers import get_matter
20 from .models import MatterDiscoverySchema
21 
22 type SelectCluster = (
23  clusters.ModeSelect
24  | clusters.OvenMode
25  | clusters.LaundryWasherMode
26  | clusters.RefrigeratorAndTemperatureControlledCabinetMode
27  | clusters.RvcRunMode
28  | clusters.RvcCleanMode
29  | clusters.DishwasherMode
30  | clusters.EnergyEvseMode
31  | clusters.DeviceEnergyManagementMode
32 )
33 
34 
36  hass: HomeAssistant,
37  config_entry: ConfigEntry,
38  async_add_entities: AddEntitiesCallback,
39 ) -> None:
40  """Set up Matter ModeSelect from Config Entry."""
41  matter = get_matter(hass)
42  matter.register_platform_handler(Platform.SELECT, async_add_entities)
43 
44 
45 @dataclass(frozen=True)
47  """Describe Matter select entities."""
48 
49 
51  """Representation of a select entity from Matter Attribute read/write."""
52 
53  entity_description: MatterSelectEntityDescription
54 
55  async def async_select_option(self, option: str) -> None:
56  """Change the selected mode."""
57  value_convert = self.entity_descriptionentity_description.ha_to_native_value
58  if TYPE_CHECKING:
59  assert value_convert is not None
60  await self.matter_clientmatter_client.write_attribute(
61  node_id=self._endpoint_endpoint.node.node_id,
62  attribute_path=create_attribute_path_from_attribute(
63  self._endpoint_endpoint.endpoint_id, self._entity_info_entity_info.primary_attribute
64  ),
65  value=value_convert(option),
66  )
67 
68  @callback
69  def _update_from_device(self) -> None:
70  """Update from device."""
71  value: Nullable | int | None
72  value = self.get_matter_attribute_valueget_matter_attribute_value(self._entity_info_entity_info.primary_attribute)
73  value_convert = self.entity_descriptionentity_description.measurement_to_ha
74  if TYPE_CHECKING:
75  assert value_convert is not None
76  self._attr_current_option_attr_current_option = value_convert(value)
77 
78 
80  """Representation of a select entity from Matter (Mode) Cluster attribute(s)."""
81 
82  async def async_select_option(self, option: str) -> None:
83  """Change the selected mode."""
84  cluster: SelectCluster = self._endpoint_endpoint.get_cluster(
85  self._entity_info_entity_info.primary_attribute.cluster_id
86  )
87  # select the mode ID from the label string
88  for mode in cluster.supportedModes:
89  if mode.label != option:
90  continue
91  await self.matter_clientmatter_client.send_device_command(
92  node_id=self._endpoint_endpoint.node.node_id,
93  endpoint_id=self._endpoint_endpoint.endpoint_id,
94  command=cluster.Commands.ChangeToMode(newMode=mode.mode),
95  )
96  break
97 
98  @callback
99  def _update_from_device(self) -> None:
100  """Update from device."""
101  # NOTE: cluster can be ModeSelect or a variant of that,
102  # such as DishwasherMode. They all have the same characteristics.
103  cluster: SelectCluster = self._endpoint_endpoint.get_cluster(
104  self._entity_info_entity_info.primary_attribute.cluster_id
105  )
106  modes = {mode.mode: mode.label for mode in cluster.supportedModes}
107  self._attr_options_attr_options = list(modes.values())
108  self._attr_current_option_attr_current_option_attr_current_option = modes.get(cluster.currentMode)
109  # handle optional Description attribute as descriptive name for the mode
110  if desc := getattr(cluster, "description", None):
111  self._attr_name_attr_name_attr_name = desc
112 
113 
114 # Discovery schema(s) to map Matter Attributes to HA entities
115 DISCOVERY_SCHEMAS = [
117  platform=Platform.SELECT,
118  entity_description=MatterSelectEntityDescription(
119  key="MatterModeSelect",
120  entity_category=EntityCategory.CONFIG,
121  translation_key="mode",
122  ),
123  entity_class=MatterModeSelectEntity,
124  required_attributes=(
125  clusters.ModeSelect.Attributes.CurrentMode,
126  clusters.ModeSelect.Attributes.SupportedModes,
127  ),
128  ),
130  platform=Platform.SELECT,
131  entity_description=MatterSelectEntityDescription(
132  key="MatterOvenMode",
133  translation_key="mode",
134  ),
135  entity_class=MatterModeSelectEntity,
136  required_attributes=(
137  clusters.OvenMode.Attributes.CurrentMode,
138  clusters.OvenMode.Attributes.SupportedModes,
139  ),
140  ),
142  platform=Platform.SELECT,
143  entity_description=MatterSelectEntityDescription(
144  key="MatterLaundryWasherMode",
145  translation_key="mode",
146  ),
147  entity_class=MatterModeSelectEntity,
148  required_attributes=(
149  clusters.LaundryWasherMode.Attributes.CurrentMode,
150  clusters.LaundryWasherMode.Attributes.SupportedModes,
151  ),
152  ),
154  platform=Platform.SELECT,
155  entity_description=MatterSelectEntityDescription(
156  key="MatterRefrigeratorAndTemperatureControlledCabinetMode",
157  translation_key="mode",
158  ),
159  entity_class=MatterModeSelectEntity,
160  required_attributes=(
161  clusters.RefrigeratorAndTemperatureControlledCabinetMode.Attributes.CurrentMode,
162  clusters.RefrigeratorAndTemperatureControlledCabinetMode.Attributes.SupportedModes,
163  ),
164  ),
166  platform=Platform.SELECT,
167  entity_description=MatterSelectEntityDescription(
168  key="MatterRvcCleanMode",
169  translation_key="clean_mode",
170  ),
171  entity_class=MatterModeSelectEntity,
172  required_attributes=(
173  clusters.RvcCleanMode.Attributes.CurrentMode,
174  clusters.RvcCleanMode.Attributes.SupportedModes,
175  ),
176  ),
178  platform=Platform.SELECT,
179  entity_description=MatterSelectEntityDescription(
180  key="MatterDishwasherMode",
181  translation_key="mode",
182  ),
183  entity_class=MatterModeSelectEntity,
184  required_attributes=(
185  clusters.DishwasherMode.Attributes.CurrentMode,
186  clusters.DishwasherMode.Attributes.SupportedModes,
187  ),
188  ),
190  platform=Platform.SELECT,
191  entity_description=MatterSelectEntityDescription(
192  key="MatterEnergyEvseMode",
193  translation_key="mode",
194  ),
195  entity_class=MatterModeSelectEntity,
196  required_attributes=(
197  clusters.EnergyEvseMode.Attributes.CurrentMode,
198  clusters.EnergyEvseMode.Attributes.SupportedModes,
199  ),
200  ),
202  platform=Platform.SELECT,
203  entity_description=MatterSelectEntityDescription(
204  key="MatterDeviceEnergyManagementMode",
205  translation_key="mode",
206  ),
207  entity_class=MatterModeSelectEntity,
208  required_attributes=(
209  clusters.DeviceEnergyManagementMode.Attributes.CurrentMode,
210  clusters.DeviceEnergyManagementMode.Attributes.SupportedModes,
211  ),
212  ),
214  platform=Platform.SELECT,
215  entity_description=MatterSelectEntityDescription(
216  key="MatterStartUpOnOff",
217  entity_category=EntityCategory.CONFIG,
218  translation_key="startup_on_off",
219  options=["on", "off", "toggle", "previous"],
220  measurement_to_ha={
221  0: "off",
222  1: "on",
223  2: "toggle",
224  None: "previous",
225  }.get,
226  ha_to_native_value={
227  "off": 0,
228  "on": 1,
229  "toggle": 2,
230  "previous": None,
231  }.get,
232  ),
233  entity_class=MatterSelectEntity,
234  required_attributes=(clusters.OnOff.Attributes.StartUpOnOff,),
235  ),
237  platform=Platform.SELECT,
238  entity_description=MatterSelectEntityDescription(
239  key="SmokeCOSmokeSensitivityLevel",
240  entity_category=EntityCategory.CONFIG,
241  translation_key="sensitivity_level",
242  options=["high", "standard", "low"],
243  measurement_to_ha={
244  0: "high",
245  1: "standard",
246  2: "low",
247  }.get,
248  ha_to_native_value={
249  "high": 0,
250  "standard": 1,
251  "low": 2,
252  }.get,
253  ),
254  entity_class=MatterSelectEntity,
255  required_attributes=(clusters.SmokeCoAlarm.Attributes.SmokeSensitivityLevel,),
256  ),
257 ]
Any get_matter_attribute_value(self, type[ClusterAttributeDescriptor] attribute, bool null_as_none=True)
Definition: entity.py:206
MatterAdapter get_matter(HomeAssistant hass)
Definition: helpers.py:35
None async_setup_entry(HomeAssistant hass, ConfigEntry config_entry, AddEntitiesCallback async_add_entities)
Definition: select.py:39