MultipleQuirksMatchException when reloading ZHA integration with custom quirks v2
I'm on HomeAssistant Green with OS 12.3, HA 2024.6.1 and SkyConnect.
I've created 2 quirks v2:
find /config/custom_zha_quirks/
/config/custom_zha_quirks/
/config/custom_zha_quirks/__pycache__
/config/custom_zha_quirks/__pycache__/zg-204zs.cpython-312.pyc
/config/custom_zha_quirks/__pycache__/zg-204zm.cpython-312.pyc
/config/custom_zha_quirks/zg-204zs.py
/config/custom_zha_quirks/zg-204zm.py
Source: zg-204zs.py, zg-204zm.
After adding one of the custom quirks, I can't reload the ZHA integration anymore. More or less instantly after reloading (ZHA integration -> 3dots -> Reload) it fails:
From /homeassistant/home-assistant.log:
2024-06-09 18:33:47.327 WARNING (ImportExecutor_0) [zhaquirks] Loaded custom quirks. Please contribute them to https://github.com/zigpy/zha-device-handlers
2024-06-09 18:33:47.504 ERROR (MainThread) [homeassistant.config_entries] Error setting up entry Home Assistant SkyConnect for zha
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/config_entries.py", line 594, in async_setup
result = await component.async_setup_entry(hass, self)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/components/zha/__init__.py", line 134, in async_setup_entry
async with radio_mgr.connect_zigpy_app() as app:
File "/usr/local/lib/python3.12/contextlib.py", line 210, in __aenter__
return await anext(self.gen)
^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/components/zha/radio_manager.py", line 182, in connect_zigpy_app
app = await self.radio_type.controller.new(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/zigpy/application.py", line 252, in new
await app._load_db()
File "/usr/local/lib/python3.12/site-packages/zigpy/application.py", line 108, in _load_db
await self._dblistener.load()
File "/usr/local/lib/python3.12/site-packages/zigpy/appdb.py", line 675, in load
device = zigpy.quirks.get_device(device)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/zigpy/quirks/__init__.py", line 41, in get_device
return _DEVICE_REGISTRY.get_device(device)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/zigpy/quirks/registry.py", line 96, in get_device
raise MultipleQuirksMatchException(
zigpy.exceptions.MultipleQuirksMatchException: Multiple matches found for device <Device model='TS0601' manuf='_TZE200_3towulqd' nwk=0x409E ieee=a4:c1:38:8d:03:11:b4:5e is_initialized=True>: [QuirksV2RegistryEntry(registry=<zigpy.quirks.registry.DeviceRegistry object at 0xffff686bacf0>, quirk_location='file[/config/custom_zha_quirks/zg-204zs.py]-line:146', filters=[], custom_device_class=None, device_node_descriptor=None, skip_device_configuration=True, adds_metadata=[AddsMetadata(cluster=<class 'zg-204zs.LuminanceMotionManufCluster'>, endpoint_id=1, cluster_type=<ClusterType.Server: 0>, constant_attributes={}), AddsMetadata(cluster=<class 'zg-204zs.TuyaOccupancySensing'>, endpoint_id=1, cluster_type=<ClusterType.Server: 0>, constant_attributes={})], removes_metadata=[RemovesMetadata(cluster_id=1280, endpoint_id=1, cluster_type=<ClusterType.Server: 0>), RemovesMetadata(cluster_id=3, endpoint_id=1, cluster_type=<ClusterType.Server: 0>)], replaces_metadata=[ReplacesMetadata(remove=RemovesMetadata(cluster_id=1, endpoint_id=1, cluster_type=<ClusterType.Server: 0>), add=AddsMetadata(cluster=<class 'zhaquirks.tuya.TuyaPowerConfigurationCluster2AAA'>, endpoint_id=1, cluster_type=<ClusterType.Server: 0>, constant_attributes={})), ReplacesMetadata(remove=RemovesMetadata(cluster_id=1024, endpoint_id=1, cluster_type=<ClusterType.Server: 0>), add=AddsMetadata(cluster=<class 'zg-204zs.TuyaIlluminanceMeasurement'>, endpoint_id=1, cluster_type=<ClusterType.Server: 0>, constant_attributes={}))], entity_metadata=[ZCLEnumMetadata(entity_platform=<EntityPlatform.SELECT: 'select'>, entity_type=<EntityType.CONFIG: 'config'>, cluster_id=61184, endpoint_id=1, cluster_type=<ClusterType.Server: 0>, initially_disabled=False, attribute_initialized_from_cache=True, translation_key=None, enum=<enum 'PirTime'>, attribute_name='pir_time'), ZCLEnumMetadata(entity_platform=<EntityPlatform.SELECT: 'select'>, entity_type=<EntityType.CONFIG: 'config'>, cluster_id=61184, endpoint_id=1, cluster_type=<ClusterType.Server: 0>, initially_disabled=False, attribute_initialized_from_cache=True, translation_key=None, enum=<enum 'PirSensitivity'>, attribute_name='pir_sensitivity'), NumberMetadata(entity_platform=<EntityPlatform.NUMBER: 'number'>, entity_type=<EntityType.CONFIG: 'config'>, cluster_id=61184, endpoint_id=1, cluster_type=<ClusterType.Server: 0>, initially_disabled=False, attribute_initialized_from_cache=True, translation_key=None, attribute_name='interval_time', min=1, max=720, step=1, unit=None, mode=None, multiplier=None, device_class=None)], device_automation_triggers_metadata={}), QuirksV2RegistryEntry(registry=<zigpy.quirks.registry.DeviceRegistry object at 0xffff686bacf0>, quirk_location='file[/config/custom_zha_quirks/zg-204zs.py]-line:146', filters=[], custom_device_class=None, device_node_descriptor=None, skip_device_configuration=True, adds_metadata=[AddsMetadata(cluster=<class 'zg-204zs.LuminanceMotionManufCluster'>, endpoint_id=1, cluster_type=<ClusterType.Server: 0>, constant_attributes={}), AddsMetadata(cluster=<class 'zg-204zs.TuyaOccupancySensing'>, endpoint_id=1, cluster_type=<ClusterType.Server: 0>, constant_attributes={})], removes_metadata=[RemovesMetadata(cluster_id=1280, endpoint_id=1, cluster_type=<ClusterType.Server: 0>), RemovesMetadata(cluster_id=3, endpoint_id=1, cluster_type=<ClusterType.Server: 0>)], replaces_metadata=[ReplacesMetadata(remove=RemovesMetadata(cluster_id=1, endpoint_id=1, cluster_type=<ClusterType.Server: 0>), add=AddsMetadata(cluster=<class 'zhaquirks.tuya.TuyaPowerConfigurationCluster2AAA'>, endpoint_id=1, cluster_type=<ClusterType.Server: 0>, constant_attributes={})), ReplacesMetadata(remove=RemovesMetadata(cluster_id=1024, endpoint_id=1, cluster_type=<ClusterType.Server: 0>), add=AddsMetadata(cluster=<class 'zg-204zs.TuyaIlluminanceMeasurement'>, endpoint_id=1, cluster_type=<ClusterType.Server: 0>, constant_attributes={}))], entity_metadata=[ZCLEnumMetadata(entity_platform=<EntityPlatform.SELECT: 'select'>, entity_type=<EntityType.CONFIG: 'config'>, cluster_id=61184, endpoint_id=1, cluster_type=<ClusterType.Server: 0>, initially_disabled=False, attribute_initialized_from_cache=True, translation_key=None, enum=<enum 'PirTime'>, attribute_name='pir_time'), ZCLEnumMetadata(entity_platform=<EntityPlatform.SELECT: 'select'>, entity_type=<EntityType.CONFIG: 'config'>, cluster_id=61184, endpoint_id=1, cluster_type=<ClusterType.Server: 0>, initially_disabled=False, attribute_initialized_from_cache=True, translation_key=None, enum=<enum 'PirSensitivity'>, attribute_name='pir_sensitivity'), NumberMetadata(entity_platform=<EntityPlatform.NUMBER: 'number'>, entity_type=<EntityType.CONFIG: 'config'>, cluster_id=61184, endpoint_id=1, cluster_type=<ClusterType.Server: 0>, initially_disabled=False, attribute_initialized_from_cache=True, translation_key=None, attribute_name='interval_time', min=1, max=720, step=1, unit=None, mode=None, multiplier=None, device_class=None)], device_automation_triggers_metadata={})]
Workaround
Manual restart of HA core.
I think this is because of how they are loaded. I’ll peek at this tomorrow.
Now i've got
Traceback (most recent call last):
File "/usr/local/lib/python3.12/site-packages/bellows/ezsp/__init__.py", line 494, in handle_callback
handler(*args)
File "/usr/local/lib/python3.12/site-packages/bellows/zigbee/application.py", line 626, in ezsp_callback_handler
self.connection_lost(args[0])
File "/usr/local/lib/python3.12/site-packages/zigpy/application.py", line 688, in connection_lost
self.listener_event("connection_lost", exc)
File "/usr/local/lib/python3.12/site-packages/zigpy/util.py", line 50, in listener_event
for listener, include_context in self._listeners.values():
RuntimeError: dictionary changed size during iteration
Then:
NCP entered failed state. Requesting APP controller restart
leading to:
Logger: homeassistant.config_entries
Quelle: config_entries.py:594
Erstmals aufgetreten: 13:06:01 (1 Vorkommnisse)
Zuletzt protokolliert: 13:06:01
Error setting up entry Home Assistant SkyConnect for zha
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/config_entries.py", line 594, in async_setup
result = await component.async_setup_entry(hass, self)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/components/zha/__init__.py", line 134, in async_setup_entry
async with radio_mgr.connect_zigpy_app() as app:
File "/usr/local/lib/python3.12/contextlib.py", line 210, in __aenter__
return await anext(self.gen)
^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/components/zha/radio_manager.py", line 182, in connect_zigpy_app
app = await self.radio_type.controller.new(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/zigpy/application.py", line 252, in new
await app._load_db()
File "/usr/local/lib/python3.12/site-packages/zigpy/application.py", line 108, in _load_db
await self._dblistener.load()
File "/usr/local/lib/python3.12/site-packages/zigpy/appdb.py", line 675, in load
device = zigpy.quirks.get_device(device)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/zigpy/quirks/__init__.py", line 41, in get_device
return _DEVICE_REGISTRY.get_device(device)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/zigpy/quirks/registry.py", line 96, in get_device
raise MultipleQuirksMatchException(
zigpy.exceptions.MultipleQuirksMatchException: Multiple matches found for device <Device model='TS0601' manuf='_TZE200_3towulqd' nwk=0x409E ieee=a4:c1:38:8d:03:11:b4:5e is_initialized=True>: [QuirksV2RegistryEntry(registry=<zigpy.quirks.registry.DeviceRegistry object at 0xffff864a6540>, quirk_location='file[/config/custom_zha_quirks/zg-204zs.py]-line:146', filters=[], custom_device_class=None, device_node_descriptor=None, skip_device_configuration=True, adds_metadata=[AddsMetadata(cluster=<class 'zg-204zs.LuminanceMotionManufCluster'>, endpoint_id=1, cluster_type=<ClusterType.Server: 0>, constant_attributes={}), AddsMetadata(cluster=<class 'zg-204zs.TuyaOccupancySensing'>, endpoint_id=1, cluster_type=<ClusterType.Server: 0>, constant_attributes={})], removes_metadata=[RemovesMetadata(cluster_id=1280, endpoint_id=1, cluster_type=<ClusterType.Server: 0>), RemovesMetadata(cluster_id=3, endpoint_id=1, cluster_type=<ClusterType.Server: 0>)], replaces_metadata=[ReplacesMetadata(remove=RemovesMetadata(cluster_id=1, endpoint_id=1, cluster_type=<ClusterType.Server: 0>), add=AddsMetadata(cluster=<class 'zhaquirks.tuya.TuyaPowerConfigurationCluster2AAA'>, endpoint_id=1, cluster_type=<ClusterType.Server: 0>, constant_attributes={})), ReplacesMetadata(remove=RemovesMetadata(cluster_id=1024, endpoint_id=1, cluster_type=<ClusterType.Server: 0>), add=AddsMetadata(cluster=<class 'zg-204zs.TuyaIlluminanceMeasurement'>, endpoint_id=1, cluster_type=<ClusterType.Server: 0>, constant_attributes={}))], entity_metadata=[ZCLEnumMetadata(entity_platform=<EntityPlatform.SELECT: 'select'>, entity_type=<EntityType.CONFIG: 'config'>, cluster_id=61184, endpoint_id=1, cluster_type=<ClusterType.Server: 0>, initially_disabled=False, attribute_initialized_from_cache=True, translation_key=None, enum=<enum 'PirTime'>, attribute_name='pir_time'), ZCLEnumMetadata(entity_platform=<EntityPlatform.SELECT: 'select'>, entity_type=<EntityType.CONFIG: 'config'>, cluster_id=61184, endpoint_id=1, cluster_type=<ClusterType.Server: 0>, initially_disabled=False, attribute_initialized_from_cache=True, translation_key=None, enum=<enum 'PirSensitivity'>, attribute_name='pir_sensitivity'), NumberMetadata(entity_platform=<EntityPlatform.NUMBER: 'number'>, entity_type=<EntityType.CONFIG: 'config'>, cluster_id=61184, endpoint_id=1, cluster_type=<ClusterType.Server: 0>, initially_disabled=False, attribute_initialized_from_cache=True, translation_key=None, attribute_name='interval_time', min=1, max=720, step=1, unit=None, mode=None, multiplier=None, device_class=None)], device_automation_triggers_metadata={}), QuirksV2RegistryEntry(registry=<zigpy.quirks.registry.DeviceRegistry object at 0xffff864a6540>, quirk_location='file[/config/custom_zha_quirks/zg-204zs.py]-line:146', filters=[], custom_device_class=None, device_node_descriptor=None, skip_device_configuration=True, adds_metadata=[AddsMetadata(cluster=<class 'zg-204zs.LuminanceMotionManufCluster'>, endpoint_id=1, cluster_type=<ClusterType.Server: 0>, constant_attributes={}), AddsMetadata(cluster=<class 'zg-204zs.TuyaOccupancySensing'>, endpoint_id=1, cluster_type=<ClusterType.Server: 0>, constant_attributes={})], removes_metadata=[RemovesMetadata(cluster_id=1280, endpoint_id=1, cluster_type=<ClusterType.Server: 0>), RemovesMetadata(cluster_id=3, endpoint_id=1, cluster_type=<ClusterType.Server: 0>)], replaces_metadata=[ReplacesMetadata(remove=RemovesMetadata(cluster_id=1, endpoint_id=1, cluster_type=<ClusterType.Server: 0>), add=AddsMetadata(cluster=<class 'zhaquirks.tuya.TuyaPowerConfigurationCluster2AAA'>, endpoint_id=1, cluster_type=<ClusterType.Server: 0>, constant_attributes={})), ReplacesMetadata(remove=RemovesMetadata(cluster_id=1024, endpoint_id=1, cluster_type=<ClusterType.Server: 0>), add=AddsMetadata(cluster=<class 'zg-204zs.TuyaIlluminanceMeasurement'>, endpoint_id=1, cluster_type=<ClusterType.Server: 0>, constant_attributes={}))], entity_metadata=[ZCLEnumMetadata(entity_platform=<EntityPlatform.SELECT: 'select'>, entity_type=<EntityType.CONFIG: 'config'>, cluster_id=61184, endpoint_id=1, cluster_type=<ClusterType.Server: 0>, initially_disabled=False, attribute_initialized_from_cache=True, translation_key=None, enum=<enum 'PirTime'>, attribute_name='pir_time'), ZCLEnumMetadata(entity_platform=<EntityPlatform.SELECT: 'select'>, entity_type=<EntityType.CONFIG: 'config'>, cluster_id=61184, endpoint_id=1, cluster_type=<ClusterType.Server: 0>, initially_disabled=False, attribute_initialized_from_cache=True, translation_key=None, enum=<enum 'PirSensitivity'>, attribute_name='pir_sensitivity'), NumberMetadata(entity_platform=<EntityPlatform.NUMBER: 'number'>, entity_type=<EntityType.CONFIG: 'config'>, cluster_id=61184, endpoint_id=1, cluster_type=<ClusterType.Server: 0>, initially_disabled=False, attribute_initialized_from_cache=True, translation_key=None, attribute_name='interval_time', min=1, max=720, step=1, unit=None, mode=None, multiplier=None, device_class=None)], device_automation_triggers_metadata={})]
leaving ZHA unvailable. Manual HA core restart required.
Did you have a previous quirk file for this same device and if so have you removed the old quirk? The error implies you have two quirks matching the device and you haven't made any statements that you've checked for old quirks.
@jmanis2 at some point in time I had a "quirk v1" version. I have them removed.
Here is what my custom_zha_quirks folder looks like now (added TS0203_TZ3000_6zvw8ham.py since creating this issue):
$ find /config/custom_zha_quirks/
/config/custom_zha_quirks/
/config/custom_zha_quirks/__pycache__
/config/custom_zha_quirks/__pycache__/zg-204zs.cpython-312.pyc
/config/custom_zha_quirks/__pycache__/TS0203_TZ3000_6zvw8ham.cpython-312.pyc
/config/custom_zha_quirks/__pycache__/zg-204zm.cpython-312.pyc
/config/custom_zha_quirks/zg-204zs.py
/config/custom_zha_quirks/zg-204zm.py
/config/custom_zha_quirks/TS0203_TZ3000_6zvw8ham.py
- I also removed pycache content
- all of the 3 quirks are v2 quirks
- restartet HA core multiple times since replacing quirks v1 with quirks v2
- also rebootet at least once since then
same issue here:
- Core 2024.6.4
- 1x custom quirk (https://gist.github.com/vinzent/2194a8ef531d8e8ec3bc17ea17eab0e9)
2024-06-23 04:13:56.961 ERROR (MainThread) [homeassistant.config_entries] Error setting up entry ZBridge for zha
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/config_entries.py", line 594, in async_setup
result = await component.async_setup_entry(hass, self)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/components/zha/__init__.py", line 134, in async_setup_entry
async with radio_mgr.connect_zigpy_app() as app:
File "/usr/local/lib/python3.12/contextlib.py", line 210, in __aenter__
return await anext(self.gen)
^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/components/zha/radio_manager.py", line 182, in connect_zigpy_app
app = await self.radio_type.controller.new(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/zigpy/application.py", line 252, in new
await app._load_db()
File "/usr/local/lib/python3.12/site-packages/zigpy/application.py", line 108, in _load_db
await self._dblistener.load()
File "/usr/local/lib/python3.12/site-packages/zigpy/appdb.py", line 675, in load
device = zigpy.quirks.get_device(device)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/zigpy/quirks/__init__.py", line 41, in get_device
return _DEVICE_REGISTRY.get_device(device)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/zigpy/quirks/registry.py", line 96, in get_device
raise MultipleQuirksMatchException(
zigpy.exceptions.MultipleQuirksMatchException: Multiple matches found for device <Device model='TS0601' manuf='_TZE200_3towulqd' nwk=0x8ACA ieee=a4:c1:38:4e:12:28:68:26 is_initialized=True>: [QuirksV2RegistryEntry(registry=<zigpy.quirks.registry.DeviceR$
2
here are some extended logs. I do not have any other quirks for this device (or any other device):
2024-06-25 11:02:22.105 ERROR (MainThread) [bellows.ezsp] NCP entered failed state. Requesting APP controller restart
2024-06-25 11:02:25.348 WARNING (ImportExecutor_0) [zhaquirks] Loaded custom quirks. Please contribute them to https://github.com/zigpy/zha-device-handlers
2024-06-25 11:02:27.005 ERROR (Thread-11) [homeassistant] Error doing job: Task exception was never retrieved (None)
Traceback (most recent call last):
File "/usr/local/lib/python3.12/site-packages/bellows/ash.py", line 631, in _send_data_frame
await ack_future
asyncio.exceptions.CancelledError
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/usr/local/lib/python3.12/site-packages/bellows/ash.py", line 630, in _send_data_frame
async with asyncio_timeout(self._t_rx_ack):
File "/usr/local/lib/python3.12/asyncio/timeouts.py", line 115, in __aexit__
raise TimeoutError from exc_val
TimeoutError
2024-06-25 11:02:27.361 ERROR (MainThread) [homeassistant.config_entries] Error setting up entry ZBridge for zha
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/config_entries.py", line 594, in async_setup
result = await component.async_setup_entry(hass, self)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/components/zha/__init__.py", line 134, in async_setup_entry
async with radio_mgr.connect_zigpy_app() as app:
File "/usr/local/lib/python3.12/contextlib.py", line 210, in __aenter__
return await anext(self.gen)
^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/components/zha/radio_manager.py", line 182, in connect_zigpy_app
app = await self.radio_type.controller.new(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/zigpy/application.py", line 252, in new
await app._load_db()
File "/usr/local/lib/python3.12/site-packages/zigpy/application.py", line 108, in _load_db
await self._dblistener.load()
File "/usr/local/lib/python3.12/site-packages/zigpy/appdb.py", line 675, in load
device = zigpy.quirks.get_device(device)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/zigpy/quirks/__init__.py", line 41, in get_device
return _DEVICE_REGISTRY.get_device(device)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/zigpy/quirks/registry.py", line 96, in get_device
raise MultipleQuirksMatchException(
zigpy.exceptions.MultipleQuirksMatchException: Multiple matches found for device <Device model='TS0601' manuf='_TZE200_3towulqd' nwk=0x8ACA ieee=a4:c1:38:4e:12:28:68:26 is_initialized=True>: [QuirksV2RegistryEntry(registry=<zigpy.quirks.registry.DeviceRegistry object at 0x56f9f6a8>, quirk_location='file[/config/custom_zha_quirks/zg-204zs.py]-line:146', filters=[], custom_device_class=None, device_node_descriptor=None, skip_device_configuration=True, adds_metadata=[AddsMetadata(cluster=<class 'zg-204zs.LuminanceMotionManufCluster'>, endpoint_id=1, cluster_type=<ClusterType.Server: 0>, constant_attributes={}), AddsMetadata(cluster=<class 'zg-204zs.TuyaOccupancySensing'>, endpoint_id=1, cluster_type=<ClusterType.Server: 0>, constant_attributes={})], removes_metadata=[RemovesMetadata(cluster_id=1280, endpoint_id=1, cluster_type=<ClusterType.Server: 0>), RemovesMetadata(cluster_id=3, endpoint_id=1, cluster_type=<ClusterType.Server: 0>)], replaces_metadata=[ReplacesMetadata(remove=RemovesMetadata(cluster_id=1, endpoint_id=1, cluster_type=<ClusterType.Server: 0>), add=AddsMetadata(cluster=<class 'zhaquirks.tuya.TuyaPowerConfigurationCluster2AAA'>, endpoint_id=1, cluster_type=<ClusterType.Server: 0>, constant_attributes={})), ReplacesMetadata(remove=RemovesMetadata(cluster_id=1024, endpoint_id=1, cluster_type=<ClusterType.Server: 0>), add=AddsMetadata(cluster=<class 'zg-204zs.TuyaIlluminanceMeasurement'>, endpoint_id=1, cluster_type=<ClusterType.Server: 0>, constant_attributes={}))], entity_metadata=[ZCLEnumMetadata(entity_platform=<EntityPlatform.SELECT: 'select'>, entity_type=<EntityType.CONFIG: 'config'>, cluster_id=61184, endpoint_id=1, cluster_type=<ClusterType.Server: 0>, initially_disabled=False, attribute_initialized_from_cache=True, translation_key=None, enum=<enum 'PirTime'>, attribute_name='pir_time'), ZCLEnumMetadata(entity_platform=<EntityPlatform.SELECT: 'select'>, entity_type=<EntityType.CONFIG: 'config'>, cluster_id=61184, endpoint_id=1, cluster_type=<ClusterType.Server: 0>, initially_disabled=False, attribute_initialized_from_cache=True, translation_key=None, enum=<enum 'PirSensitivity'>, attribute_name='pir_sensitivity'), NumberMetadata(entity_platform=<EntityPlatform.NUMBER: 'number'>, entity_type=<EntityType.CONFIG: 'config'>, cluster_id=61184, endpoint_id=1, cluster_type=<ClusterType.Server: 0>, initially_disabled=False, attribute_initialized_from_cache=True, translation_key=None, attribute_name='interval_time', min=1, max=720, step=1, unit=None, mode=None, multiplier=None, device_class=None)], device_automation_triggers_metadata={}), QuirksV2RegistryEntry(registry=<zigpy.quirks.registry.DeviceRegistry object at 0x56f9f6a8>, quirk_location='file[/config/custom_zha_quirks/zg-204zs.py]-line:146', filters=[], custom_device_class=None, device_node_descriptor=None, skip_device_configuration=True, adds_metadata=[AddsMetadata(cluster=<class 'zg-204zs.LuminanceMotionManufCluster'>, endpoint_id=1, cluster_type=<ClusterType.Server: 0>, constant_attributes={}), AddsMetadata(cluster=<class 'zg-204zs.TuyaOccupancySensing'>, endpoint_id=1, cluster_type=<ClusterType.Server: 0>, constant_attributes={})], removes_metadata=[RemovesMetadata(cluster_id=1280, endpoint_id=1, cluster_type=<ClusterType.Server: 0>), RemovesMetadata(cluster_id=3, endpoint_id=1, cluster_type=<ClusterType.Server: 0>)], replaces_metadata=[ReplacesMetadata(remove=RemovesMetadata(cluster_id=1, endpoint_id=1, cluster_type=<ClusterType.Server: 0>), add=AddsMetadata(cluster=<class 'zhaquirks.tuya.TuyaPowerConfigurationCluster2AAA'>, endpoint_id=1, cluster_type=<ClusterType.Server: 0>, constant_attributes={})), ReplacesMetadata(remove=RemovesMetadata(cluster_id=1024, endpoint_id=1, cluster_type=<ClusterType.Server: 0>), add=AddsMetadata(cluster=<class 'zg-204zs.TuyaIlluminanceMeasurement'>, endpoint_id=1, cluster_type=<ClusterType.Server: 0>, constant_attributes={}))], entity_metadata=[ZCLEnumMetadata(entity_platform=<EntityPlatform.SELECT: 'select'>, entity_type=<EntityType.CONFIG: 'config'>, cluster_id=61184, endpoint_id=1, cluster_type=<ClusterType.Server: 0>, initially_disabled=False, attribute_initialized_from_cache=True, translation_key=None, enum=<enum 'PirTime'>, attribute_name='pir_time'), ZCLEnumMetadata(entity_platform=<EntityPlatform.SELECT: 'select'>, entity_type=<EntityType.CONFIG: 'config'>, cluster_id=61184, endpoint_id=1, cluster_type=<ClusterType.Server: 0>, initially_disabled=False, attribute_initialized_from_cache=True, translation_key=None, enum=<enum 'PirSensitivity'>, attribute_name='pir_sensitivity'), NumberMetadata(entity_platform=<EntityPlatform.NUMBER: 'number'>, entity_type=<EntityType.CONFIG: 'config'>, cluster_id=61184, endpoint_id=1, cluster_type=<ClusterType.Server: 0>, initially_disabled=False, attribute_initialized_from_cache=True, translation_key=None, attribute_name='interval_time', min=1, max=720, step=1, unit=None, mode=None, multiplier=None, device_class=None)], device_automation_triggers_metadata={})]
it seems like the quirk registry contains the same quirk twice:
QuirksV2RegistryEntry(registry=<zigpy.quirks.registry.DeviceRegistry object at 0x56f9f6a8>, quirk_location='file[/config/custom_zha_quirks/zg-204zs.py]-line:146',
QuirksV2RegistryEntry(registry=<zigpy.quirks.registry.DeviceRegistry object at 0x56f9f6a8>, quirk_location='file[/config/custom_zha_quirks/zg-204zs.py]-line:146'
Since this only happens on reload of the ha configuration it appears to me that on reload only the custom quirks folder is reloaded but the zigpy objects (in this case the _DEVICE_REGISTRY) remains the same:
https://github.com/zigpy/zigpy/blob/dev/zigpy/quirks/init.py#L32
this assumption is also supported by the check before add of v1 quirks:
https://github.com/zigpy/zigpy/blob/dev/zigpy/quirks/registry.py#L49
the easiest way to solve this issue would be to extend the v2 add function for the check:
def add_to_registry_v2(
self, manufacturer: str, model: str, entry: QuirksV2RegistryEntry
) -> QuirksV2RegistryEntry:
"""Add an entry to the registry."""
key = (manufacturer, model)
if key not in self._registry_v2:
if not entry.registry:
entry.registry = self
self._registry_v2[key].append(entry)
return self._registry_v2[key]
since also the get_device function assumes that we there can be multiple registry entries for the same manufacturer and model, but throws an exception if this is the case, why we use a list of quirks for this tuple?
https://github.com/zigpy/zigpy/blob/dev/zigpy/quirks/registry.py#L36
@dmulcahey
from what is see this fix should be available with zigpy==0.65.1 and integrated in HA 2024.8.1 which uses zha==0.0.30 and zigpy>=0.65.2 . I still get the same error on reloading the integration.
I also changed the custom quirk to use QuirkBuilder as follows:
(
QuirkBuilder("_TZE200_3towulqd", "TS0601")
.skip_configuration()
.removes(IasZone.cluster_id)
.removes(Identify.cluster_id)
.adds(LuminanceMotionManufCluster)
.adds(TuyaOccupancySensing)
.replaces(TuyaPowerConfigurationCluster2AAA)
.replaces(TuyaIlluminanceMeasurement)
.enum(LuminanceMotionManufCluster.AttributeDefs.pir_time.name, PirTime, LuminanceMotionManufCluster.cluster_id)
.enum(LuminanceMotionManufCluster.AttributeDefs.pir_sensitivity.name,PirSensitivity,LuminanceMotionManufCluster.cluster_id)
.number(LuminanceMotionManufCluster.AttributeDefs.interval_time.name,LuminanceMotionManufCluster.cluster_id,step=1,min_value=1,max_value=720)
.add_to_registry()
)
On reloading of the ingetration I get the following error:
zigpy.exceptions.MultipleQuirksMatchException: Multiple matches found for device
<Device model='TS0601' manuf='_TZE200_3towulqd' nwk=0x8ACA ieee=a4:c1:38:4e:12:28:68:26 is_initialized=True>:
[
QuirksV2RegistryEntry(
quirk_location='file[/config/custom_zha_quirks/zg-204zs.py]-line:146',
....
),
QuirksV2RegistryEntry(
quirk_location='file[/config/custom_zha_quirks/zg-204zs.py]-line:146',
What am I doing wrong?