zigpy icon indicating copy to clipboard operation
zigpy copied to clipboard

MultipleQuirksMatchException when reloading ZHA integration with custom quirks v2

Open vinzent opened this issue 1 year ago • 7 comments

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:

grafik

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.

vinzent avatar Jun 09 '24 16:06 vinzent

I think this is because of how they are loaded. I’ll peek at this tomorrow.

dmulcahey avatar Jun 09 '24 19:06 dmulcahey

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.

vinzent avatar Jun 10 '24 11:06 vinzent

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 avatar Jun 13 '24 11:06 jmanis2

@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

vinzent avatar Jun 13 '24 11:06 vinzent

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

cemizm avatar Jun 23 '24 05:06 cemizm

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'

cemizm avatar Jun 25 '24 20:06 cemizm

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

cemizm avatar Jun 27 '24 17:06 cemizm

@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?

cemizm avatar Aug 14 '24 07:08 cemizm