mirror of
https://github.com/home-assistant/core.git
synced 2025-07-15 09:17:10 +00:00
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:
parent
950c72a04c
commit
d5135d4956
@ -2,10 +2,9 @@
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from collections.abc import Generator
|
|
||||||
|
|
||||||
from chip.clusters.Objects import ClusterAttributeDescriptor
|
from chip.clusters.Objects import ClusterAttributeDescriptor
|
||||||
from matter_server.client.models.node import MatterEndpoint
|
from matter_server.client.models.node import MatterEndpoint
|
||||||
|
from typing_extensions import Generator
|
||||||
|
|
||||||
from homeassistant.const import Platform
|
from homeassistant.const import Platform
|
||||||
from homeassistant.core import callback
|
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 .lock import DISCOVERY_SCHEMAS as LOCK_SCHEMAS
|
||||||
from .models import MatterDiscoverySchema, MatterEntityInfo
|
from .models import MatterDiscoverySchema, MatterEntityInfo
|
||||||
from .number import DISCOVERY_SCHEMAS as NUMBER_SCHEMAS
|
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 .sensor import DISCOVERY_SCHEMAS as SENSOR_SCHEMAS
|
||||||
from .switch import DISCOVERY_SCHEMAS as SWITCH_SCHEMAS
|
from .switch import DISCOVERY_SCHEMAS as SWITCH_SCHEMAS
|
||||||
|
|
||||||
@ -33,6 +33,7 @@ DISCOVERY_SCHEMAS: dict[Platform, list[MatterDiscoverySchema]] = {
|
|||||||
Platform.NUMBER: NUMBER_SCHEMAS,
|
Platform.NUMBER: NUMBER_SCHEMAS,
|
||||||
Platform.SENSOR: SENSOR_SCHEMAS,
|
Platform.SENSOR: SENSOR_SCHEMAS,
|
||||||
Platform.SWITCH: SWITCH_SCHEMAS,
|
Platform.SWITCH: SWITCH_SCHEMAS,
|
||||||
|
Platform.SELECT: SELECT_SCHEMAS,
|
||||||
}
|
}
|
||||||
SUPPORTED_PLATFORMS = tuple(DISCOVERY_SCHEMAS)
|
SUPPORTED_PLATFORMS = tuple(DISCOVERY_SCHEMAS)
|
||||||
|
|
||||||
|
199
homeassistant/components/matter/select.py
Normal file
199
homeassistant/components/matter/select.py
Normal 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,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
@ -125,6 +125,11 @@
|
|||||||
"name": "[%key:component::lock::title%]"
|
"name": "[%key:component::lock::title%]"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"select": {
|
||||||
|
"mode": {
|
||||||
|
"name": "Mode"
|
||||||
|
}
|
||||||
|
},
|
||||||
"sensor": {
|
"sensor": {
|
||||||
"activated_carbon_filter_condition": {
|
"activated_carbon_filter_condition": {
|
||||||
"name": "Activated carbon filter condition"
|
"name": "Activated carbon filter condition"
|
||||||
|
@ -365,7 +365,148 @@
|
|||||||
"1/29/65533": 1,
|
"1/29/65533": 1,
|
||||||
"1/29/65528": [],
|
"1/29/65528": [],
|
||||||
"1/29/65529": [],
|
"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,
|
"available": true,
|
||||||
"attribute_subscriptions": []
|
"attribute_subscriptions": []
|
||||||
|
405
tests/components/matter/fixtures/nodes/microwave-oven.json
Normal file
405
tests/components/matter/fixtures/nodes/microwave-oven.json
Normal 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": []
|
||||||
|
}
|
109
tests/components/matter/test_select.py
Normal file
109
tests/components/matter/test_select.py
Normal 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"
|
Loading…
x
Reference in New Issue
Block a user