Add support for the Select platform in Matter (#119769)

* Add support for ModeSelect Cluster

* Update discovery.py

* Add files via upload

* refactor part 1

* Update discovery.py

* add remaining mode discovery schemas

* add test

* type alias

---------

Co-authored-by: Marcel van der Veldt <m.vanderveldt@outlook.com>
This commit is contained in:
jvmahon 2024-07-04 12:29:10 -04:00 committed by GitHub
parent 950c72a04c
commit d5135d4956
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 863 additions and 3 deletions

View File

@ -2,10 +2,9 @@
from __future__ import annotations
from collections.abc import Generator
from chip.clusters.Objects import ClusterAttributeDescriptor
from matter_server.client.models.node import MatterEndpoint
from typing_extensions import Generator
from homeassistant.const import Platform
from homeassistant.core import callback
@ -19,6 +18,7 @@ from .light import DISCOVERY_SCHEMAS as LIGHT_SCHEMAS
from .lock import DISCOVERY_SCHEMAS as LOCK_SCHEMAS
from .models import MatterDiscoverySchema, MatterEntityInfo
from .number import DISCOVERY_SCHEMAS as NUMBER_SCHEMAS
from .select import DISCOVERY_SCHEMAS as SELECT_SCHEMAS
from .sensor import DISCOVERY_SCHEMAS as SENSOR_SCHEMAS
from .switch import DISCOVERY_SCHEMAS as SWITCH_SCHEMAS
@ -33,6 +33,7 @@ DISCOVERY_SCHEMAS: dict[Platform, list[MatterDiscoverySchema]] = {
Platform.NUMBER: NUMBER_SCHEMAS,
Platform.SENSOR: SENSOR_SCHEMAS,
Platform.SWITCH: SWITCH_SCHEMAS,
Platform.SELECT: SELECT_SCHEMAS,
}
SUPPORTED_PLATFORMS = tuple(DISCOVERY_SCHEMAS)

View File

@ -0,0 +1,199 @@
"""Matter ModeSelect Cluster Support."""
from __future__ import annotations
from chip.clusters import Objects as clusters
from homeassistant.components.select import SelectEntity, SelectEntityDescription
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import EntityCategory, Platform
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .entity import MatterEntity
from .helpers import get_matter
from .models import MatterDiscoverySchema
type SelectCluster = (
clusters.ModeSelect
| clusters.OvenMode
| clusters.LaundryWasherMode
| clusters.RefrigeratorAndTemperatureControlledCabinetMode
| clusters.RvcRunMode
| clusters.RvcCleanMode
| clusters.DishwasherMode
| clusters.MicrowaveOvenMode
| clusters.EnergyEvseMode
| clusters.DeviceEnergyManagementMode
)
async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up Matter ModeSelect from Config Entry."""
matter = get_matter(hass)
matter.register_platform_handler(Platform.SELECT, async_add_entities)
class MatterModeSelectEntity(MatterEntity, SelectEntity):
"""Representation of a select entity from Matter (Mode) Cluster attribute(s)."""
async def async_select_option(self, option: str) -> None:
"""Change the selected mode."""
cluster: SelectCluster = self._endpoint.get_cluster(
self._entity_info.primary_attribute.cluster_id
)
# select the mode ID from the label string
for mode in cluster.supportedModes:
if mode.label != option:
continue
await self.matter_client.send_device_command(
node_id=self._endpoint.node.node_id,
endpoint_id=self._endpoint.endpoint_id,
command=cluster.Commands.ChangeToMode(newMode=mode.mode),
)
break
@callback
def _update_from_device(self) -> None:
"""Update from device."""
# NOTE: cluster can be ModeSelect or a variant of that,
# such as DishwasherMode. They all have the same characteristics.
cluster: SelectCluster = self._endpoint.get_cluster(
self._entity_info.primary_attribute.cluster_id
)
modes = {mode.mode: mode.label for mode in cluster.supportedModes}
self._attr_options = list(modes.values())
self._attr_current_option = modes[cluster.currentMode]
# handle optional Description attribute as descriptive name for the mode
if desc := getattr(cluster, "description", None):
self._attr_name = desc
# Discovery schema(s) to map Matter Attributes to HA entities
DISCOVERY_SCHEMAS = [
MatterDiscoverySchema(
platform=Platform.SELECT,
entity_description=SelectEntityDescription(
key="MatterModeSelect",
entity_category=EntityCategory.CONFIG,
translation_key="mode",
),
entity_class=MatterModeSelectEntity,
required_attributes=(
clusters.ModeSelect.Attributes.CurrentMode,
clusters.ModeSelect.Attributes.SupportedModes,
),
),
MatterDiscoverySchema(
platform=Platform.SELECT,
entity_description=SelectEntityDescription(
key="MatterOvenMode",
translation_key="mode",
),
entity_class=MatterModeSelectEntity,
required_attributes=(
clusters.OvenMode.Attributes.CurrentMode,
clusters.OvenMode.Attributes.SupportedModes,
),
),
MatterDiscoverySchema(
platform=Platform.SELECT,
entity_description=SelectEntityDescription(
key="MatterLaundryWasherMode",
translation_key="mode",
),
entity_class=MatterModeSelectEntity,
required_attributes=(
clusters.LaundryWasherMode.Attributes.CurrentMode,
clusters.LaundryWasherMode.Attributes.SupportedModes,
),
),
MatterDiscoverySchema(
platform=Platform.SELECT,
entity_description=SelectEntityDescription(
key="MatterRefrigeratorAndTemperatureControlledCabinetMode",
translation_key="mode",
),
entity_class=MatterModeSelectEntity,
required_attributes=(
clusters.RefrigeratorAndTemperatureControlledCabinetMode.Attributes.CurrentMode,
clusters.RefrigeratorAndTemperatureControlledCabinetMode.Attributes.SupportedModes,
),
),
MatterDiscoverySchema(
platform=Platform.SELECT,
entity_description=SelectEntityDescription(
key="MatterRvcRunMode",
translation_key="mode",
),
entity_class=MatterModeSelectEntity,
required_attributes=(
clusters.RvcRunMode.Attributes.CurrentMode,
clusters.RvcRunMode.Attributes.SupportedModes,
),
),
MatterDiscoverySchema(
platform=Platform.SELECT,
entity_description=SelectEntityDescription(
key="MatterRvcCleanMode",
translation_key="mode",
),
entity_class=MatterModeSelectEntity,
required_attributes=(
clusters.RvcCleanMode.Attributes.CurrentMode,
clusters.RvcCleanMode.Attributes.SupportedModes,
),
),
MatterDiscoverySchema(
platform=Platform.SELECT,
entity_description=SelectEntityDescription(
key="MatterDishwasherMode",
translation_key="mode",
),
entity_class=MatterModeSelectEntity,
required_attributes=(
clusters.DishwasherMode.Attributes.CurrentMode,
clusters.DishwasherMode.Attributes.SupportedModes,
),
),
MatterDiscoverySchema(
platform=Platform.SELECT,
entity_description=SelectEntityDescription(
key="MatterMicrowaveOvenMode",
translation_key="mode",
),
entity_class=MatterModeSelectEntity,
required_attributes=(
clusters.MicrowaveOvenMode.Attributes.CurrentMode,
clusters.MicrowaveOvenMode.Attributes.SupportedModes,
),
),
MatterDiscoverySchema(
platform=Platform.SELECT,
entity_description=SelectEntityDescription(
key="MatterEnergyEvseMode",
translation_key="mode",
),
entity_class=MatterModeSelectEntity,
required_attributes=(
clusters.EnergyEvseMode.Attributes.CurrentMode,
clusters.EnergyEvseMode.Attributes.SupportedModes,
),
),
MatterDiscoverySchema(
platform=Platform.SELECT,
entity_description=SelectEntityDescription(
key="MatterDeviceEnergyManagementMode",
translation_key="mode",
),
entity_class=MatterModeSelectEntity,
required_attributes=(
clusters.DeviceEnergyManagementMode.Attributes.CurrentMode,
clusters.DeviceEnergyManagementMode.Attributes.SupportedModes,
),
),
]

View File

@ -125,6 +125,11 @@
"name": "[%key:component::lock::title%]"
}
},
"select": {
"mode": {
"name": "Mode"
}
},
"sensor": {
"activated_carbon_filter_condition": {
"name": "Activated carbon filter condition"

View File

@ -365,7 +365,148 @@
"1/29/65533": 1,
"1/29/65528": [],
"1/29/65529": [],
"1/29/65531": [0, 1, 2, 3, 65528, 65529, 65531, 65532, 65533]
"1/29/65531": [0, 1, 2, 3, 65528, 65529, 65531, 65532, 65533],
"6/80/0": "LED Color",
"6/80/1": 0,
"6/80/2": [
{
"0": "Red",
"1": 0,
"2": [
{
"0": 0,
"1": 0
}
]
},
{
"0": "Orange",
"1": 1,
"2": [
{
"0": 0,
"1": 0
}
]
},
{
"0": "Lemon",
"1": 2,
"2": [
{
"0": 0,
"1": 0
}
]
},
{
"0": "Lime",
"1": 3,
"2": [
{
"0": 0,
"1": 0
}
]
},
{
"0": "Green",
"1": 4,
"2": [
{
"0": 0,
"1": 0
}
]
},
{
"0": "Teal",
"1": 5,
"2": [
{
"0": 0,
"1": 0
}
]
},
{
"0": "Cyan",
"1": 6,
"2": [
{
"0": 0,
"1": 0
}
]
},
{
"0": "Aqua",
"1": 7,
"2": [
{
"0": 0,
"1": 0
}
]
},
{
"0": "Blue",
"1": 8,
"2": [
{
"0": 0,
"1": 0
}
]
},
{
"0": "Violet",
"1": 9,
"2": [
{
"0": 0,
"1": 0
}
]
},
{
"0": "Magenta",
"1": 10,
"2": [
{
"0": 0,
"1": 0
}
]
},
{
"0": "Pink",
"1": 11,
"2": [
{
"0": 0,
"1": 0
}
]
},
{
"0": "White",
"1": 12,
"2": [
{
"0": 0,
"1": 0
}
]
}
],
"6/80/3": 7,
"6/80/65532": 0,
"6/80/65533": 1,
"6/80/65528": [],
"6/80/65529": [0],
"6/80/65530": [],
"6/80/65531": [0, 1, 2, 3, 65528, 65529, 65530, 65531, 65532, 65533]
},
"available": true,
"attribute_subscriptions": []

View File

@ -0,0 +1,405 @@
{
"node_id": 157,
"date_commissioned": "2024-07-04T12:31:22.759270",
"last_interview": "2024-07-04T12:31:22.759275",
"interview_version": 6,
"available": true,
"is_bridge": false,
"attributes": {
"0/29/0": [
{
"0": 22,
"1": 1
}
],
"0/29/1": [29, 31, 40, 44, 48, 49, 51, 54, 60, 62, 63],
"0/29/2": [],
"0/29/3": [1],
"0/29/65532": 0,
"0/29/65533": 2,
"0/29/65528": [],
"0/29/65529": [],
"0/29/65531": [0, 1, 2, 3, 65528, 65529, 65531, 65532, 65533],
"0/31/0": [
{
"1": 5,
"2": 2,
"3": [112233],
"4": null,
"254": 1
}
],
"0/31/1": [],
"0/31/2": 4,
"0/31/3": 3,
"0/31/4": 4,
"0/31/65532": 0,
"0/31/65533": 1,
"0/31/65528": [],
"0/31/65529": [],
"0/31/65531": [0, 1, 2, 3, 4, 65528, 65529, 65531, 65532, 65533],
"0/40/0": 17,
"0/40/1": "Mock",
"0/40/2": 65521,
"0/40/3": "Microwave Oven",
"0/40/4": 32769,
"0/40/5": "",
"0/40/6": "**REDACTED**",
"0/40/7": 0,
"0/40/8": "TEST_VERSION",
"0/40/9": 1,
"0/40/10": "1.0",
"0/40/11": "20200101",
"0/40/12": "",
"0/40/13": "",
"0/40/14": "",
"0/40/15": "TEST_SN",
"0/40/16": false,
"0/40/18": "D5908CF5E1382F42",
"0/40/19": {
"0": 3,
"1": 65535
},
"0/40/20": null,
"0/40/21": 16973824,
"0/40/22": 1,
"0/40/65532": 0,
"0/40/65533": 3,
"0/40/65528": [],
"0/40/65529": [],
"0/40/65531": [
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 19, 20, 21,
22, 65528, 65529, 65531, 65532, 65533
],
"0/44/0": 0,
"0/44/65532": 0,
"0/44/65533": 1,
"0/44/65528": [],
"0/44/65529": [],
"0/44/65531": [0, 65528, 65529, 65531, 65532, 65533],
"0/48/0": 0,
"0/48/1": {
"0": 60,
"1": 900
},
"0/48/2": 0,
"0/48/3": 2,
"0/48/4": true,
"0/48/65532": 0,
"0/48/65533": 1,
"0/48/65528": [1, 3, 5],
"0/48/65529": [0, 2, 4],
"0/48/65531": [0, 1, 2, 3, 4, 65528, 65529, 65531, 65532, 65533],
"0/49/0": 1,
"0/49/1": [
{
"0": "ZW5kMA==",
"1": true
}
],
"0/49/2": 0,
"0/49/3": 0,
"0/49/4": true,
"0/49/5": null,
"0/49/6": null,
"0/49/7": null,
"0/49/65532": 4,
"0/49/65533": 2,
"0/49/65528": [],
"0/49/65529": [],
"0/49/65531": [0, 1, 2, 3, 4, 5, 6, 7, 65528, 65529, 65531, 65532, 65533],
"0/51/0": [
{
"0": "vethd3cc78a",
"1": true,
"2": null,
"3": null,
"4": "RiMoOM7I",
"5": [],
"6": ["/oAAAAAAAABEIyj//jjOyA=="],
"7": 0
},
{
"0": "veth86f4b74",
"1": true,
"2": null,
"3": null,
"4": "ehLA7XI6",
"5": [],
"6": ["/oAAAAAAAAB4EsD//u1yOg=="],
"7": 0
},
{
"0": "veth36c1460",
"1": true,
"2": null,
"3": null,
"4": "0sdiwOO7",
"5": [],
"6": ["/oAAAAAAAADQx2L//sDjuw=="],
"7": 0
},
{
"0": "veth55a0982",
"1": true,
"2": null,
"3": null,
"4": "fuu5VpgB",
"5": [],
"6": ["/oAAAAAAAAB867n//laYAQ=="],
"7": 0
},
{
"0": "vethd446fa5",
"1": true,
"2": null,
"3": null,
"4": "QsY5wCp1",
"5": [],
"6": ["/oAAAAAAAABAxjn//sAqdQ=="],
"7": 0
},
{
"0": "vethfc6e4d6",
"1": true,
"2": null,
"3": null,
"4": "IsHWia4E",
"5": [],
"6": ["/oAAAAAAAAAgwdb//omuBA=="],
"7": 0
},
{
"0": "veth4b35142",
"1": true,
"2": null,
"3": null,
"4": "RizM/XJz",
"5": [],
"6": ["/oAAAAAAAABELMz//v1ycw=="],
"7": 0
},
{
"0": "vetha0a808d",
"1": true,
"2": null,
"3": null,
"4": "JrxkpiTq",
"5": [],
"6": ["/oAAAAAAAAAkvGT//qYk6g=="],
"7": 0
},
{
"0": "hassio",
"1": true,
"2": null,
"3": null,
"4": "AkL+6fKF",
"5": ["rB4gAQ=="],
"6": ["/oAAAAAAAAAAQv7//unyhQ=="],
"7": 0
},
{
"0": "docker0",
"1": true,
"2": null,
"3": null,
"4": "AkKzcIpP",
"5": ["rB7oAQ=="],
"6": ["/oAAAAAAAAAAQrP//nCKTw=="],
"7": 0
},
{
"0": "end0",
"1": true,
"2": null,
"3": null,
"4": "5F8BoroJ",
"5": ["wKgBAg=="],
"6": [
"KgKkZACnAAHGF8Tinim+lQ==",
"/XH1Cm7wY08fhLPRgO32Uw==",
"/oAAAAAAAAAENYnD2gV25w=="
],
"7": 2
},
{
"0": "lo",
"1": true,
"2": null,
"3": null,
"4": "AAAAAAAA",
"5": ["fwAAAQ=="],
"6": ["AAAAAAAAAAAAAAAAAAAAAQ=="],
"7": 0
}
],
"0/51/1": 1,
"0/51/2": 16,
"0/51/3": 0,
"0/51/4": 0,
"0/51/5": [],
"0/51/6": [],
"0/51/7": [],
"0/51/8": false,
"0/51/65532": 0,
"0/51/65533": 2,
"0/51/65528": [2],
"0/51/65529": [0, 1],
"0/51/65531": [
0, 1, 2, 3, 4, 5, 6, 7, 8, 65528, 65529, 65531, 65532, 65533
],
"0/54/0": null,
"0/54/1": null,
"0/54/2": null,
"0/54/3": null,
"0/54/4": null,
"0/54/5": null,
"0/54/6": null,
"0/54/7": null,
"0/54/8": null,
"0/54/9": null,
"0/54/10": null,
"0/54/11": null,
"0/54/12": null,
"0/54/65532": 3,
"0/54/65533": 1,
"0/54/65528": [],
"0/54/65529": [0],
"0/54/65531": [
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 65528, 65529, 65531, 65532,
65533
],
"0/60/0": 0,
"0/60/1": null,
"0/60/2": null,
"0/60/65532": 0,
"0/60/65533": 1,
"0/60/65528": [],
"0/60/65529": [0, 2],
"0/60/65531": [0, 1, 2, 65528, 65529, 65531, 65532, 65533],
"0/62/0": [
{
"1": "FTABAQEkAgE3AyQTAhgmBIAigScmBYAlTTo3BiQVASQRnRgkBwEkCAEwCUEEleMInA+X+lZO6bSa7ysHaAvYS13Fg9GoRuhiFk+wvtjLUrouyH+DUp3p3purrVdfUWTp03damVsxp9Lv48goDzcKNQEoARgkAgE2AwQCBAEYMAQUrD2d44zyVXjKbyYgNaEibaXFI7IwBRTphWiJ/NqGe3Cx3Nj8H02NgGioSRgwC0CaASOOwmsHE8cNw7FhQDtRhh0ztvwdfZKANU93vrX/+ww8UifrTjUIgvobgixpCGxmGvEmk3RN7TX6lgX4Qz7MGA==",
"2": "FTABAQEkAgE3AyQUARgmBIAigScmBYAlTTo3BiQTAhgkBwEkCAEwCUEEYztrLK2UY1ORHUEFLO7PDfVjw/MnMDNX5kjdHHDU7npeITnSyg/kxxUM+pD7ccxfDuHQKHbBq9+qbJi8oGik8DcKNQEpARgkAmAwBBTphWiJ/NqGe3Cx3Nj8H02NgGioSTAFFMnf5ZkBCRaBluhSmLJkvcVXxHxTGDALQOOcZAL8XEktvE5sjrUmFNhkP2g3Ef+4BHtogItdZYyA9E/WbzW25E0UxZInwjjIzH3YimDUZVoEWGML8NV2kCEY",
"254": 1
}
],
"0/62/1": [
{
"1": "BAg5aeR7RuFKZhukCxMGglCd00dKlhxGq8BbjeyZClKz5kN2Ytzav0xWsiWEEb3s9uvMIYFoQYULnSJvOMTcD14=",
"2": 65521,
"3": 1,
"4": 157,
"5": "",
"254": 1
}
],
"0/62/2": 16,
"0/62/3": 1,
"0/62/4": [
"FTABAQEkAgE3AyQUARgmBIAigScmBYAlTTo3BiQUARgkBwEkCAEwCUEECDlp5HtG4UpmG6QLEwaCUJ3TR0qWHEarwFuN7JkKUrPmQ3Zi3Nq/TFayJYQRvez268whgWhBhQudIm84xNwPXjcKNQEpARgkAmAwBBTJ3+WZAQkWgZboUpiyZL3FV8R8UzAFFMnf5ZkBCRaBluhSmLJkvcVXxHxTGDALQO9QSAdvJkM6b/wIc07MCw1ma46lTyGYG8nvpn0ICI73nuD3QeaWwGIQTkVGEpzF+TuDK7gtTz7YUrR+PSnvMk8Y"
],
"0/62/5": 1,
"0/62/65532": 0,
"0/62/65533": 1,
"0/62/65528": [1, 3, 5, 8],
"0/62/65529": [0, 2, 4, 6, 7, 9, 10, 11],
"0/62/65531": [0, 1, 2, 3, 4, 5, 65528, 65529, 65531, 65532, 65533],
"0/63/0": [],
"0/63/1": [],
"0/63/2": 4,
"0/63/3": 3,
"0/63/65532": 0,
"0/63/65533": 2,
"0/63/65528": [2, 5],
"0/63/65529": [0, 1, 3, 4],
"0/63/65531": [0, 1, 2, 3, 65528, 65529, 65531, 65532, 65533],
"1/3/0": 0,
"1/3/1": 0,
"1/3/65532": 0,
"1/3/65533": 4,
"1/3/65528": [],
"1/3/65529": [0, 64],
"1/3/65531": [0, 1, 65528, 65529, 65531, 65532, 65533],
"1/29/0": [
{
"0": 121,
"1": 1
}
],
"1/29/1": [3, 29, 94, 95, 96],
"1/29/2": [],
"1/29/3": [],
"1/29/65532": 0,
"1/29/65533": 2,
"1/29/65528": [],
"1/29/65529": [],
"1/29/65531": [0, 1, 2, 3, 65528, 65529, 65531, 65532, 65533],
"1/94/0": [
{
"0": "Normal",
"1": 0,
"2": [
{
"1": 16384
}
]
},
{
"0": "Defrost",
"1": 1,
"2": [
{
"1": 16385
}
]
}
],
"1/94/1": 0,
"1/94/65532": 0,
"1/94/65533": 1,
"1/94/65528": [],
"1/94/65529": [],
"1/94/65531": [0, 1, 65528, 65529, 65531, 65532, 65533],
"1/95/0": 30,
"1/95/1": 86400,
"1/95/2": 90,
"1/95/3": 20,
"1/95/4": 90,
"1/95/5": 10,
"1/95/8": 1000,
"1/95/65532": 5,
"1/95/65533": 1,
"1/95/65528": [],
"1/95/65529": [0, 1],
"1/95/65531": [0, 1, 2, 3, 4, 5, 8, 65528, 65529, 65531, 65532, 65533],
"1/96/0": null,
"1/96/1": null,
"1/96/2": 30,
"1/96/3": [
{
"0": 0
},
{
"0": 1
},
{
"0": 2
},
{
"0": 3
}
],
"1/96/4": 0,
"1/96/5": {
"0": 0
},
"1/96/65532": 0,
"1/96/65533": 2,
"1/96/65528": [4],
"1/96/65529": [0, 1, 2, 3],
"1/96/65531": [0, 1, 2, 3, 4, 5, 65528, 65529, 65531, 65532, 65533]
},
"attribute_subscriptions": []
}

View File

@ -0,0 +1,109 @@
"""Test Matter select entities."""
from unittest.mock import MagicMock, call
from chip.clusters import Objects as clusters
from matter_server.client.models.node import MatterNode
import pytest
from homeassistant.core import HomeAssistant
from .common import (
set_node_attribute,
setup_integration_with_node_fixture,
trigger_subscription_callback,
)
@pytest.fixture(name="light_node")
async def dimmable_light_node_fixture(
hass: HomeAssistant, matter_client: MagicMock
) -> MatterNode:
"""Fixture for a dimmable light node."""
return await setup_integration_with_node_fixture(
hass, "dimmable-light", matter_client
)
@pytest.fixture(name="microwave_oven_node")
async def microwave_oven_node_fixture(
hass: HomeAssistant, matter_client: MagicMock
) -> MatterNode:
"""Fixture for a microwave oven node."""
return await setup_integration_with_node_fixture(
hass, "microwave-oven", matter_client
)
# This tests needs to be adjusted to remove lingering tasks
@pytest.mark.parametrize("expected_lingering_tasks", [True])
async def test_mode_select_entities(
hass: HomeAssistant,
matter_client: MagicMock,
light_node: MatterNode,
) -> None:
"""Test select entities are created for the ModeSelect cluster attributes."""
state = hass.states.get("select.mock_dimmable_light_led_color")
assert state
assert state.state == "Aqua"
assert state.attributes["options"] == [
"Red",
"Orange",
"Lemon",
"Lime",
"Green",
"Teal",
"Cyan",
"Aqua",
"Blue",
"Violet",
"Magenta",
"Pink",
"White",
]
# name should be derived from description attribute
assert state.attributes["friendly_name"] == "Mock Dimmable Light LED Color"
set_node_attribute(light_node, 6, 80, 3, 1)
await trigger_subscription_callback(hass, matter_client)
state = hass.states.get("select.mock_dimmable_light_led_color")
assert state.state == "Orange"
# test select option
await hass.services.async_call(
"select",
"select_option",
{
"entity_id": "select.mock_dimmable_light_led_color",
"option": "Lime",
},
blocking=True,
)
assert matter_client.send_device_command.call_count == 1
assert matter_client.send_device_command.call_args == call(
node_id=light_node.node_id,
endpoint_id=6,
command=clusters.ModeSelect.Commands.ChangeToMode(newMode=3),
)
# This tests needs to be adjusted to remove lingering tasks
@pytest.mark.parametrize("expected_lingering_tasks", [True])
async def test_microwave_select_entities(
hass: HomeAssistant,
matter_client: MagicMock,
microwave_oven_node: MatterNode,
) -> None:
"""Test select entities are created for the MicrowaveOvenMode cluster attributes."""
state = hass.states.get("select.microwave_oven_mode")
assert state
assert state.state == "Normal"
assert state.attributes["options"] == [
"Normal",
"Defrost",
]
# name should just be Mode (from the translation key)
assert state.attributes["friendly_name"] == "Microwave Oven Mode"
set_node_attribute(microwave_oven_node, 1, 94, 1, 1)
await trigger_subscription_callback(hass, matter_client)
state = hass.states.get("select.microwave_oven_mode")
assert state.state == "Defrost"