From 8f70064b83c0a2b6b6dc78b6173c84bf6ce89ee5 Mon Sep 17 00:00:00 2001 From: TheJulianJES Date: Sat, 21 Feb 2026 05:49:07 +0100 Subject: [PATCH 1/4] Add `not_exposed_features` to discovery --- zha/application/discovery.py | 8 +++++++- zha/application/platforms/__init__.py | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/zha/application/discovery.py b/zha/application/discovery.py index 493b48be4..aec9a259c 100644 --- a/zha/application/discovery.py +++ b/zha/application/discovery.py @@ -390,7 +390,7 @@ def discover_quirks_v2_entities(device: Device) -> Iterator[PlatformEntity]: cluster_handler.BIND = False -def discover_entities_for_endpoint(endpoint: Endpoint) -> Iterator[PlatformEntity]: +def discover_entities_for_endpoint(endpoint: Endpoint) -> Iterator[PlatformEntity]: # noqa: C901 """Discover entities for an endpoint using the new registry-based discovery.""" device = endpoint.device @@ -440,6 +440,12 @@ def discover_entities_for_endpoint(endpoint: Endpoint) -> Iterator[PlatformEntit ): continue + if ( + match.not_exposed_features is not None + and match.not_exposed_features & device.exposes_features + ): + continue + if ( match.manufacturers is not None and device.manufacturer not in match.manufacturers diff --git a/zha/application/platforms/__init__.py b/zha/application/platforms/__init__.py index 410082a28..8a9c5d888 100644 --- a/zha/application/platforms/__init__.py +++ b/zha/application/platforms/__init__.py @@ -88,6 +88,7 @@ class ClusterHandlerMatch: manufacturers: frozenset[str] | None = None models: frozenset[str] | None = None exposed_features: frozenset[str] | None = None + not_exposed_features: frozenset[str] | None = None # If present, device must match one of the given profile and device type combinations. # This will be ignored if `platform_override` is used. From 428884292f2fce2cfec4168f7eec01c989475c7b Mon Sep 17 00:00:00 2001 From: TheJulianJES Date: Sat, 21 Feb 2026 05:50:54 +0100 Subject: [PATCH 2/4] Hide non-ZCL siren select entities for non-`siren_basic` --- zha/application/platforms/select.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/zha/application/platforms/select.py b/zha/application/platforms/select.py index 68cb261e7..5d3555684 100644 --- a/zha/application/platforms/select.py +++ b/zha/application/platforms/select.py @@ -164,7 +164,8 @@ class DefaultToneSelectEntity(NonZCLSelectEntity): _attr_translation_key: str = "default_siren_tone" _cluster_handler_match = ClusterHandlerMatch( - cluster_handlers=frozenset({CLUSTER_HANDLER_IAS_WD}) + cluster_handlers=frozenset({CLUSTER_HANDLER_IAS_WD}), + not_exposed_features=frozenset({"siren_basic"}), ) @@ -177,7 +178,8 @@ class DefaultSirenLevelSelectEntity(NonZCLSelectEntity): _attr_translation_key: str = "default_siren_level" _cluster_handler_match = ClusterHandlerMatch( - cluster_handlers=frozenset({CLUSTER_HANDLER_IAS_WD}) + cluster_handlers=frozenset({CLUSTER_HANDLER_IAS_WD}), + not_exposed_features=frozenset({"siren_basic"}), ) @@ -190,7 +192,8 @@ class DefaultStrobeLevelSelectEntity(NonZCLSelectEntity): _attr_translation_key: str = "default_strobe_level" _cluster_handler_match = ClusterHandlerMatch( - cluster_handlers=frozenset({CLUSTER_HANDLER_IAS_WD}) + cluster_handlers=frozenset({CLUSTER_HANDLER_IAS_WD}), + not_exposed_features=frozenset({"siren_basic"}), ) @@ -203,7 +206,8 @@ class DefaultStrobeSelectEntity(NonZCLSelectEntity): _attr_translation_key: str = "default_strobe" _cluster_handler_match = ClusterHandlerMatch( - cluster_handlers=frozenset({CLUSTER_HANDLER_IAS_WD}) + cluster_handlers=frozenset({CLUSTER_HANDLER_IAS_WD}), + not_exposed_features=frozenset({"siren_basic"}), ) From 49c08c6831465388845206fded69d1c719659a2e Mon Sep 17 00:00:00 2001 From: TheJulianJES Date: Wed, 25 Mar 2026 04:24:44 +0100 Subject: [PATCH 3/4] Use exposed feature constant --- zha/application/platforms/select.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/zha/application/platforms/select.py b/zha/application/platforms/select.py index 5d3555684..9f0336850 100644 --- a/zha/application/platforms/select.py +++ b/zha/application/platforms/select.py @@ -12,6 +12,7 @@ from zhaquirks.danfoss import thermostat as danfoss_thermostat from zhaquirks.quirk_ids import ( DANFOSS_ALLY_THERMOSTAT, + SIREN_BASIC, TUYA_PLUG_MANUFACTURER, TUYA_PLUG_ONOFF, ) @@ -165,7 +166,7 @@ class DefaultToneSelectEntity(NonZCLSelectEntity): _cluster_handler_match = ClusterHandlerMatch( cluster_handlers=frozenset({CLUSTER_HANDLER_IAS_WD}), - not_exposed_features=frozenset({"siren_basic"}), + not_exposed_features=frozenset({SIREN_BASIC}), ) @@ -179,7 +180,7 @@ class DefaultSirenLevelSelectEntity(NonZCLSelectEntity): _cluster_handler_match = ClusterHandlerMatch( cluster_handlers=frozenset({CLUSTER_HANDLER_IAS_WD}), - not_exposed_features=frozenset({"siren_basic"}), + not_exposed_features=frozenset({SIREN_BASIC}), ) @@ -193,7 +194,7 @@ class DefaultStrobeLevelSelectEntity(NonZCLSelectEntity): _cluster_handler_match = ClusterHandlerMatch( cluster_handlers=frozenset({CLUSTER_HANDLER_IAS_WD}), - not_exposed_features=frozenset({"siren_basic"}), + not_exposed_features=frozenset({SIREN_BASIC}), ) @@ -207,7 +208,7 @@ class DefaultStrobeSelectEntity(NonZCLSelectEntity): _cluster_handler_match = ClusterHandlerMatch( cluster_handlers=frozenset({CLUSTER_HANDLER_IAS_WD}), - not_exposed_features=frozenset({"siren_basic"}), + not_exposed_features=frozenset({SIREN_BASIC}), ) From 42b5a3578e87d20c2cbb3f2c94c032e9deb8b296 Mon Sep 17 00:00:00 2001 From: TheJulianJES Date: Wed, 25 Mar 2026 04:25:34 +0100 Subject: [PATCH 4/4] Regenerate diagnostics --- tests/data/devices/frient-a-s-flszb-110.json | 199 ------------------- tests/data/devices/frient-a-s-scazb-141.json | 199 ------------------- tests/data/devices/frient-a-s-smszb-120.json | 199 ------------------- 3 files changed, 597 deletions(-) diff --git a/tests/data/devices/frient-a-s-flszb-110.json b/tests/data/devices/frient-a-s-flszb-110.json index 920b3b557..6a10744b5 100644 --- a/tests/data/devices/frient-a-s-flszb-110.json +++ b/tests/data/devices/frient-a-s-flszb-110.json @@ -392,205 +392,6 @@ } } ], - "select": [ - { - "info_object": { - "fallback_name": null, - "unique_id": "00:15:bc:00:33:00:76:9a-35-1282-SirenLevel", - "migrate_unique_ids": [], - "platform": "select", - "class_name": "DefaultSirenLevelSelectEntity", - "translation_key": "default_siren_level", - "translation_placeholders": null, - "device_class": null, - "state_class": null, - "entity_category": "config", - "entity_registry_enabled_default": true, - "enabled": true, - "primary": false, - "cluster_handlers": [ - { - "class_name": "IasWdClusterHandler", - "generic_id": "cluster_handler_0x0502", - "endpoint_id": 35, - "cluster": { - "id": 1282, - "name": "IAS Warning Device", - "type": "server" - }, - "id": "35:0x0502", - "unique_id": "00:15:bc:00:33:00:76:9a:35:0x0502", - "status": "INITIALIZED", - "value_attribute": null - } - ], - "device_ieee": "00:15:bc:00:33:00:76:9a", - "endpoint_id": 35, - "available": true, - "group_id": null, - "enum": "SirenLevel", - "options": [ - "Low level sound", - "Medium level sound", - "High level sound", - "Very high level sound" - ] - }, - "state": { - "class_name": "DefaultSirenLevelSelectEntity", - "available": true, - "state": null - } - }, - { - "info_object": { - "fallback_name": null, - "unique_id": "00:15:bc:00:33:00:76:9a-35-1282-Strobe", - "migrate_unique_ids": [], - "platform": "select", - "class_name": "DefaultStrobeSelectEntity", - "translation_key": "default_strobe", - "translation_placeholders": null, - "device_class": null, - "state_class": null, - "entity_category": "config", - "entity_registry_enabled_default": true, - "enabled": true, - "primary": false, - "cluster_handlers": [ - { - "class_name": "IasWdClusterHandler", - "generic_id": "cluster_handler_0x0502", - "endpoint_id": 35, - "cluster": { - "id": 1282, - "name": "IAS Warning Device", - "type": "server" - }, - "id": "35:0x0502", - "unique_id": "00:15:bc:00:33:00:76:9a:35:0x0502", - "status": "INITIALIZED", - "value_attribute": null - } - ], - "device_ieee": "00:15:bc:00:33:00:76:9a", - "endpoint_id": 35, - "available": true, - "group_id": null, - "enum": "Strobe", - "options": [ - "No Strobe", - "Strobe" - ] - }, - "state": { - "class_name": "DefaultStrobeSelectEntity", - "available": true, - "state": null - } - }, - { - "info_object": { - "fallback_name": null, - "unique_id": "00:15:bc:00:33:00:76:9a-35-1282-StrobeLevel", - "migrate_unique_ids": [], - "platform": "select", - "class_name": "DefaultStrobeLevelSelectEntity", - "translation_key": "default_strobe_level", - "translation_placeholders": null, - "device_class": null, - "state_class": null, - "entity_category": "config", - "entity_registry_enabled_default": true, - "enabled": true, - "primary": false, - "cluster_handlers": [ - { - "class_name": "IasWdClusterHandler", - "generic_id": "cluster_handler_0x0502", - "endpoint_id": 35, - "cluster": { - "id": 1282, - "name": "IAS Warning Device", - "type": "server" - }, - "id": "35:0x0502", - "unique_id": "00:15:bc:00:33:00:76:9a:35:0x0502", - "status": "INITIALIZED", - "value_attribute": null - } - ], - "device_ieee": "00:15:bc:00:33:00:76:9a", - "endpoint_id": 35, - "available": true, - "group_id": null, - "enum": "StrobeLevel", - "options": [ - "Low level strobe", - "Medium level strobe", - "High level strobe", - "Very high level strobe" - ] - }, - "state": { - "class_name": "DefaultStrobeLevelSelectEntity", - "available": true, - "state": null - } - }, - { - "info_object": { - "fallback_name": null, - "unique_id": "00:15:bc:00:33:00:76:9a-35-1282-WarningMode", - "migrate_unique_ids": [], - "platform": "select", - "class_name": "DefaultToneSelectEntity", - "translation_key": "default_siren_tone", - "translation_placeholders": null, - "device_class": null, - "state_class": null, - "entity_category": "config", - "entity_registry_enabled_default": true, - "enabled": true, - "primary": false, - "cluster_handlers": [ - { - "class_name": "IasWdClusterHandler", - "generic_id": "cluster_handler_0x0502", - "endpoint_id": 35, - "cluster": { - "id": 1282, - "name": "IAS Warning Device", - "type": "server" - }, - "id": "35:0x0502", - "unique_id": "00:15:bc:00:33:00:76:9a:35:0x0502", - "status": "INITIALIZED", - "value_attribute": null - } - ], - "device_ieee": "00:15:bc:00:33:00:76:9a", - "endpoint_id": 35, - "available": true, - "group_id": null, - "enum": "WarningMode", - "options": [ - "Stop", - "Burglar", - "Fire", - "Emergency", - "Police Panic", - "Fire Panic", - "Emergency Panic" - ] - }, - "state": { - "class_name": "DefaultToneSelectEntity", - "available": true, - "state": null - } - } - ], "sensor": [ { "info_object": { diff --git a/tests/data/devices/frient-a-s-scazb-141.json b/tests/data/devices/frient-a-s-scazb-141.json index 9a21e8081..468000fed 100644 --- a/tests/data/devices/frient-a-s-scazb-141.json +++ b/tests/data/devices/frient-a-s-scazb-141.json @@ -686,205 +686,6 @@ } } ], - "select": [ - { - "info_object": { - "fallback_name": null, - "unique_id": "ab:cd:ef:12:18:f2:e7:e6-35-1282-SirenLevel", - "migrate_unique_ids": [], - "platform": "select", - "class_name": "DefaultSirenLevelSelectEntity", - "translation_key": "default_siren_level", - "translation_placeholders": null, - "device_class": null, - "state_class": null, - "entity_category": "config", - "entity_registry_enabled_default": true, - "enabled": true, - "primary": false, - "cluster_handlers": [ - { - "class_name": "IasWdClusterHandler", - "generic_id": "cluster_handler_0x0502", - "endpoint_id": 35, - "cluster": { - "id": 1282, - "name": "IAS Warning Device", - "type": "server" - }, - "id": "35:0x0502", - "unique_id": "ab:cd:ef:12:18:f2:e7:e6:35:0x0502", - "status": "INITIALIZED", - "value_attribute": null - } - ], - "device_ieee": "ab:cd:ef:12:18:f2:e7:e6", - "endpoint_id": 35, - "available": true, - "group_id": null, - "enum": "SirenLevel", - "options": [ - "Low level sound", - "Medium level sound", - "High level sound", - "Very high level sound" - ] - }, - "state": { - "class_name": "DefaultSirenLevelSelectEntity", - "available": true, - "state": null - } - }, - { - "info_object": { - "fallback_name": null, - "unique_id": "ab:cd:ef:12:18:f2:e7:e6-35-1282-Strobe", - "migrate_unique_ids": [], - "platform": "select", - "class_name": "DefaultStrobeSelectEntity", - "translation_key": "default_strobe", - "translation_placeholders": null, - "device_class": null, - "state_class": null, - "entity_category": "config", - "entity_registry_enabled_default": true, - "enabled": true, - "primary": false, - "cluster_handlers": [ - { - "class_name": "IasWdClusterHandler", - "generic_id": "cluster_handler_0x0502", - "endpoint_id": 35, - "cluster": { - "id": 1282, - "name": "IAS Warning Device", - "type": "server" - }, - "id": "35:0x0502", - "unique_id": "ab:cd:ef:12:18:f2:e7:e6:35:0x0502", - "status": "INITIALIZED", - "value_attribute": null - } - ], - "device_ieee": "ab:cd:ef:12:18:f2:e7:e6", - "endpoint_id": 35, - "available": true, - "group_id": null, - "enum": "Strobe", - "options": [ - "No Strobe", - "Strobe" - ] - }, - "state": { - "class_name": "DefaultStrobeSelectEntity", - "available": true, - "state": null - } - }, - { - "info_object": { - "fallback_name": null, - "unique_id": "ab:cd:ef:12:18:f2:e7:e6-35-1282-StrobeLevel", - "migrate_unique_ids": [], - "platform": "select", - "class_name": "DefaultStrobeLevelSelectEntity", - "translation_key": "default_strobe_level", - "translation_placeholders": null, - "device_class": null, - "state_class": null, - "entity_category": "config", - "entity_registry_enabled_default": true, - "enabled": true, - "primary": false, - "cluster_handlers": [ - { - "class_name": "IasWdClusterHandler", - "generic_id": "cluster_handler_0x0502", - "endpoint_id": 35, - "cluster": { - "id": 1282, - "name": "IAS Warning Device", - "type": "server" - }, - "id": "35:0x0502", - "unique_id": "ab:cd:ef:12:18:f2:e7:e6:35:0x0502", - "status": "INITIALIZED", - "value_attribute": null - } - ], - "device_ieee": "ab:cd:ef:12:18:f2:e7:e6", - "endpoint_id": 35, - "available": true, - "group_id": null, - "enum": "StrobeLevel", - "options": [ - "Low level strobe", - "Medium level strobe", - "High level strobe", - "Very high level strobe" - ] - }, - "state": { - "class_name": "DefaultStrobeLevelSelectEntity", - "available": true, - "state": null - } - }, - { - "info_object": { - "fallback_name": null, - "unique_id": "ab:cd:ef:12:18:f2:e7:e6-35-1282-WarningMode", - "migrate_unique_ids": [], - "platform": "select", - "class_name": "DefaultToneSelectEntity", - "translation_key": "default_siren_tone", - "translation_placeholders": null, - "device_class": null, - "state_class": null, - "entity_category": "config", - "entity_registry_enabled_default": true, - "enabled": true, - "primary": false, - "cluster_handlers": [ - { - "class_name": "IasWdClusterHandler", - "generic_id": "cluster_handler_0x0502", - "endpoint_id": 35, - "cluster": { - "id": 1282, - "name": "IAS Warning Device", - "type": "server" - }, - "id": "35:0x0502", - "unique_id": "ab:cd:ef:12:18:f2:e7:e6:35:0x0502", - "status": "INITIALIZED", - "value_attribute": null - } - ], - "device_ieee": "ab:cd:ef:12:18:f2:e7:e6", - "endpoint_id": 35, - "available": true, - "group_id": null, - "enum": "WarningMode", - "options": [ - "Stop", - "Burglar", - "Fire", - "Emergency", - "Police Panic", - "Fire Panic", - "Emergency Panic" - ] - }, - "state": { - "class_name": "DefaultToneSelectEntity", - "available": true, - "state": null - } - } - ], "sensor": [ { "info_object": { diff --git a/tests/data/devices/frient-a-s-smszb-120.json b/tests/data/devices/frient-a-s-smszb-120.json index a547d5cea..d05189cce 100644 --- a/tests/data/devices/frient-a-s-smszb-120.json +++ b/tests/data/devices/frient-a-s-smszb-120.json @@ -415,205 +415,6 @@ } } ], - "select": [ - { - "info_object": { - "fallback_name": null, - "unique_id": "00:15:bc:00:31:01:f8:92-35-1282-SirenLevel", - "migrate_unique_ids": [], - "platform": "select", - "class_name": "DefaultSirenLevelSelectEntity", - "translation_key": "default_siren_level", - "translation_placeholders": null, - "device_class": null, - "state_class": null, - "entity_category": "config", - "entity_registry_enabled_default": true, - "enabled": true, - "primary": false, - "cluster_handlers": [ - { - "class_name": "IasWdClusterHandler", - "generic_id": "cluster_handler_0x0502", - "endpoint_id": 35, - "cluster": { - "id": 1282, - "name": "IAS Warning Device", - "type": "server" - }, - "id": "35:0x0502", - "unique_id": "00:15:bc:00:31:01:f8:92:35:0x0502", - "status": "INITIALIZED", - "value_attribute": null - } - ], - "device_ieee": "00:15:bc:00:31:01:f8:92", - "endpoint_id": 35, - "available": true, - "group_id": null, - "enum": "SirenLevel", - "options": [ - "Low level sound", - "Medium level sound", - "High level sound", - "Very high level sound" - ] - }, - "state": { - "class_name": "DefaultSirenLevelSelectEntity", - "available": true, - "state": null - } - }, - { - "info_object": { - "fallback_name": null, - "unique_id": "00:15:bc:00:31:01:f8:92-35-1282-Strobe", - "migrate_unique_ids": [], - "platform": "select", - "class_name": "DefaultStrobeSelectEntity", - "translation_key": "default_strobe", - "translation_placeholders": null, - "device_class": null, - "state_class": null, - "entity_category": "config", - "entity_registry_enabled_default": true, - "enabled": true, - "primary": false, - "cluster_handlers": [ - { - "class_name": "IasWdClusterHandler", - "generic_id": "cluster_handler_0x0502", - "endpoint_id": 35, - "cluster": { - "id": 1282, - "name": "IAS Warning Device", - "type": "server" - }, - "id": "35:0x0502", - "unique_id": "00:15:bc:00:31:01:f8:92:35:0x0502", - "status": "INITIALIZED", - "value_attribute": null - } - ], - "device_ieee": "00:15:bc:00:31:01:f8:92", - "endpoint_id": 35, - "available": true, - "group_id": null, - "enum": "Strobe", - "options": [ - "No Strobe", - "Strobe" - ] - }, - "state": { - "class_name": "DefaultStrobeSelectEntity", - "available": true, - "state": null - } - }, - { - "info_object": { - "fallback_name": null, - "unique_id": "00:15:bc:00:31:01:f8:92-35-1282-StrobeLevel", - "migrate_unique_ids": [], - "platform": "select", - "class_name": "DefaultStrobeLevelSelectEntity", - "translation_key": "default_strobe_level", - "translation_placeholders": null, - "device_class": null, - "state_class": null, - "entity_category": "config", - "entity_registry_enabled_default": true, - "enabled": true, - "primary": false, - "cluster_handlers": [ - { - "class_name": "IasWdClusterHandler", - "generic_id": "cluster_handler_0x0502", - "endpoint_id": 35, - "cluster": { - "id": 1282, - "name": "IAS Warning Device", - "type": "server" - }, - "id": "35:0x0502", - "unique_id": "00:15:bc:00:31:01:f8:92:35:0x0502", - "status": "INITIALIZED", - "value_attribute": null - } - ], - "device_ieee": "00:15:bc:00:31:01:f8:92", - "endpoint_id": 35, - "available": true, - "group_id": null, - "enum": "StrobeLevel", - "options": [ - "Low level strobe", - "Medium level strobe", - "High level strobe", - "Very high level strobe" - ] - }, - "state": { - "class_name": "DefaultStrobeLevelSelectEntity", - "available": true, - "state": null - } - }, - { - "info_object": { - "fallback_name": null, - "unique_id": "00:15:bc:00:31:01:f8:92-35-1282-WarningMode", - "migrate_unique_ids": [], - "platform": "select", - "class_name": "DefaultToneSelectEntity", - "translation_key": "default_siren_tone", - "translation_placeholders": null, - "device_class": null, - "state_class": null, - "entity_category": "config", - "entity_registry_enabled_default": true, - "enabled": true, - "primary": false, - "cluster_handlers": [ - { - "class_name": "IasWdClusterHandler", - "generic_id": "cluster_handler_0x0502", - "endpoint_id": 35, - "cluster": { - "id": 1282, - "name": "IAS Warning Device", - "type": "server" - }, - "id": "35:0x0502", - "unique_id": "00:15:bc:00:31:01:f8:92:35:0x0502", - "status": "INITIALIZED", - "value_attribute": null - } - ], - "device_ieee": "00:15:bc:00:31:01:f8:92", - "endpoint_id": 35, - "available": true, - "group_id": null, - "enum": "WarningMode", - "options": [ - "Stop", - "Burglar", - "Fire", - "Emergency", - "Police Panic", - "Fire Panic", - "Emergency Panic" - ] - }, - "state": { - "class_name": "DefaultToneSelectEntity", - "available": true, - "state": null - } - } - ], "sensor": [ { "info_object": {