1 """Map Matter Nodes and Attributes to Home Assistant entities."""
3 from __future__
import annotations
5 from collections.abc
import Generator
7 from chip.clusters.Objects
import ClusterAttributeDescriptor
8 from matter_server.client.models.node
import MatterEndpoint
13 from .binary_sensor
import DISCOVERY_SCHEMAS
as BINARY_SENSOR_SCHEMAS
14 from .button
import DISCOVERY_SCHEMAS
as BUTTON_SCHEMAS
15 from .climate
import DISCOVERY_SCHEMAS
as CLIMATE_SENSOR_SCHEMAS
16 from .const
import FEATUREMAP_ATTRIBUTE_ID
17 from .cover
import DISCOVERY_SCHEMAS
as COVER_SCHEMAS
18 from .event
import DISCOVERY_SCHEMAS
as EVENT_SCHEMAS
19 from .fan
import DISCOVERY_SCHEMAS
as FAN_SCHEMAS
20 from .light
import DISCOVERY_SCHEMAS
as LIGHT_SCHEMAS
21 from .lock
import DISCOVERY_SCHEMAS
as LOCK_SCHEMAS
22 from .models
import MatterDiscoverySchema, MatterEntityInfo
23 from .number
import DISCOVERY_SCHEMAS
as NUMBER_SCHEMAS
24 from .select
import DISCOVERY_SCHEMAS
as SELECT_SCHEMAS
25 from .sensor
import DISCOVERY_SCHEMAS
as SENSOR_SCHEMAS
26 from .switch
import DISCOVERY_SCHEMAS
as SWITCH_SCHEMAS
27 from .update
import DISCOVERY_SCHEMAS
as UPDATE_SCHEMAS
28 from .vacuum
import DISCOVERY_SCHEMAS
as VACUUM_SCHEMAS
29 from .valve
import DISCOVERY_SCHEMAS
as VALVE_SCHEMAS
31 DISCOVERY_SCHEMAS: dict[Platform, list[MatterDiscoverySchema]] = {
32 Platform.BINARY_SENSOR: BINARY_SENSOR_SCHEMAS,
33 Platform.BUTTON: BUTTON_SCHEMAS,
34 Platform.CLIMATE: CLIMATE_SENSOR_SCHEMAS,
35 Platform.COVER: COVER_SCHEMAS,
36 Platform.EVENT: EVENT_SCHEMAS,
37 Platform.FAN: FAN_SCHEMAS,
38 Platform.LIGHT: LIGHT_SCHEMAS,
39 Platform.LOCK: LOCK_SCHEMAS,
40 Platform.NUMBER: NUMBER_SCHEMAS,
41 Platform.SELECT: SELECT_SCHEMAS,
42 Platform.SENSOR: SENSOR_SCHEMAS,
43 Platform.SWITCH: SWITCH_SCHEMAS,
44 Platform.UPDATE: UPDATE_SCHEMAS,
45 Platform.VACUUM: VACUUM_SCHEMAS,
46 Platform.VALVE: VALVE_SCHEMAS,
48 SUPPORTED_PLATFORMS =
tuple(DISCOVERY_SCHEMAS)
53 """Iterate over all available discovery schemas."""
54 for platform_schemas
in DISCOVERY_SCHEMAS.values():
55 yield from platform_schemas
60 endpoint: MatterEndpoint,
61 ) -> Generator[MatterEntityInfo]:
62 """Run discovery on MatterEndpoint and return matching MatterEntityInfo(s)."""
63 discovered_attributes: set[type[ClusterAttributeDescriptor]] = set()
64 device_info = endpoint.device_info
67 if any(x
in schema.required_attributes
for x
in discovered_attributes):
72 schema.vendor_id
is not None
73 and device_info.vendorID
not in schema.vendor_id
79 schema.product_name
is not None
80 and device_info.productName
not in schema.product_name
85 if schema.device_type
is not None and not any(
86 x
in schema.device_type
for x
in endpoint.device_types
91 if schema.not_device_type
is not None and any(
92 x
in schema.not_device_type
for x
in endpoint.device_types
98 schema.endpoint_id
is not None
99 and endpoint.endpoint_id
not in schema.endpoint_id
104 if schema.required_attributes
is not None and not all(
105 endpoint.has_attribute(
None, val_schema)
106 for val_schema
in schema.required_attributes
111 if schema.absent_attributes
is not None and any(
112 endpoint.has_attribute(
None, val_schema)
113 for val_schema
in schema.absent_attributes
118 if schema.absent_clusters
is not None and any(
119 endpoint.node.has_cluster(val_schema)
120 for val_schema
in schema.absent_clusters
125 primary_attribute = schema.required_attributes[0]
126 primary_value = endpoint.get_attribute_value(
None, primary_attribute)
127 if schema.value_contains
is not None and (
128 isinstance(primary_value, list)
129 and schema.value_contains
not in primary_value
134 if schema.featuremap_contains
is not None and (
137 endpoint.get_attribute_value(
138 primary_attribute.cluster_id, FEATUREMAP_ATTRIBUTE_ID
141 & schema.featuremap_contains
148 attributes_to_watch =
list(schema.required_attributes)
149 if schema.optional_attributes:
151 for optional_attribute
in schema.optional_attributes:
152 if optional_attribute
in attributes_to_watch:
154 if endpoint.has_attribute(
None, optional_attribute):
155 attributes_to_watch.append(optional_attribute)
159 platform=schema.platform,
160 attributes_to_watch=attributes_to_watch,
161 entity_description=schema.entity_description,
162 entity_class=schema.entity_class,
163 discovery_schema=schema,
167 if not schema.allow_multi:
168 discovered_attributes.update(schema.required_attributes)
Generator[MatterDiscoverySchema] iter_schemas()
Generator[MatterEntityInfo] async_discover_entities(MatterEndpoint endpoint)