mirror of
https://github.com/home-assistant/core.git
synced 2025-07-14 08:47: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 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)
|
||||
|
||||
|
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%]"
|
||||
}
|
||||
},
|
||||
"select": {
|
||||
"mode": {
|
||||
"name": "Mode"
|
||||
}
|
||||
},
|
||||
"sensor": {
|
||||
"activated_carbon_filter_condition": {
|
||||
"name": "Activated carbon filter condition"
|
||||
|
@ -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": []
|
||||
|
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