diff --git a/pyproject.toml b/pyproject.toml index 45d530d626..90572b4b9c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,7 @@ authors = [{ name = "David F. Mulcahey", email = "david.mulcahey@icloud.com" }] readme = "README.md" license = { text = "Apache-2.0" } requires-python = ">=3.12" -dependencies = ["zigpy>=0.85.0"] +dependencies = ["zigpy>=0.86.0"] [tool.setuptools.packages.find] exclude = ["tests", "tests.*"] diff --git a/tests/conftest.py b/tests/conftest.py index 52e9486528..c8a1063705 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -234,6 +234,8 @@ def _dev( for cluster_id in out_clusters: ep.add_output_cluster(cluster_id) return raw_device + else: + assert isinstance(quirked, zigpy.quirks.BaseCustomDevice) MockAppController.devices[ieee] = quirked diff --git a/tests/test_danfoss.py b/tests/test_danfoss.py index 7031984918..8d60f722eb 100644 --- a/tests/test_danfoss.py +++ b/tests/test_danfoss.py @@ -14,42 +14,10 @@ zhaquirks.setup() -def test_popp_signature(assert_signature_matches_quirk): - """Test the signature matching the Device Class.""" - signature = { - "node_descriptor": "NodeDescriptor(logical_type=, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=, mac_capability_flags=, manufacturer_code=4678, maximum_buffer_size=82, maximum_incoming_transfer_size=82, server_mask=11264, maximum_outgoing_transfer_size=82, descriptor_capability_field=, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=True, *is_full_function_device=False, *is_mains_powered=False, *is_receiver_on_when_idle=False, *is_router=False, *is_security_capable=False)", - # SizePrefixedSimpleDescriptor(endpoint=1, profile=260, device_type=769, device_version=1, input_clusters=[0, 1, 3, 10, 32, 513, 516, 2821], output_clusters=[0, 25]) - "endpoints": { - "1": { - "profile_id": 260, - "device_type": "0x0301", - "in_clusters": [ - "0x0000", - "0x0001", - "0x0003", - "0x000a", - "0x0020", - "0x0201", - "0x0204", - "0x0b05", - ], - "out_clusters": ["0x0000", "0x0019"], - } - }, - "manufacturer": "D5X84YU", - "model": "eT093WRO", - "class": "danfoss.thermostat.DanfossThermostat", - } - - assert_signature_matches_quirk( - zhaquirks.danfoss.thermostat.DanfossThermostat, signature - ) - - @mock.patch("zigpy.zcl.Cluster.bind", mock.AsyncMock()) -async def test_danfoss_time_bind(zigpy_device_from_quirk): +async def test_danfoss_time_bind(zigpy_device_from_v2_quirk): """Test the time being set when binding the Time cluster.""" - device = zigpy_device_from_quirk(zhaquirks.danfoss.thermostat.DanfossThermostat) + device = zigpy_device_from_v2_quirk("Danfoss", "eTRV0103") danfoss_time_cluster = device.endpoints[1].time danfoss_thermostat_cluster = device.endpoints[1].thermostat @@ -74,9 +42,9 @@ def mock_write(attributes, manufacturer=None): assert 0x0002 in danfoss_time_cluster._attr_cache -async def test_danfoss_thermostat_write_attributes(zigpy_device_from_quirk): +async def test_danfoss_thermostat_write_attributes(zigpy_device_from_v2_quirk): """Test the Thermostat writes behaving correctly, in particular regarding setpoint.""" - device = zigpy_device_from_quirk(zhaquirks.danfoss.thermostat.DanfossThermostat) + device = zigpy_device_from_v2_quirk("Danfoss", "eTRV0103") danfoss_thermostat_cluster = device.endpoints[1].thermostat @@ -144,12 +112,12 @@ def mock_setpoint(oper, sett, manufacturer=None): assert setting == 5 -async def test_customized_standardcluster(zigpy_device_from_quirk): +async def test_customized_standardcluster(zigpy_device_from_v2_quirk): """Test customized standard cluster class correctly separating zigbee operations. This is regarding manufacturer specific attributes. """ - device = zigpy_device_from_quirk(zhaquirks.danfoss.thermostat.DanfossThermostat) + device = zigpy_device_from_v2_quirk("Danfoss", "eTRV0103") danfoss_thermostat_cluster = device.endpoints[1].in_clusters[Thermostat.cluster_id] diff --git a/tests/test_gledopto.py b/tests/test_gledopto.py index 79ec8a668d..1bf5d137e7 100644 --- a/tests/test_gledopto.py +++ b/tests/test_gledopto.py @@ -1,37 +1 @@ """Tests for GLEDOPTO quirks.""" - -import zhaquirks.gledopto.glc009 - - -def test_gledopto_glc009_signature(assert_signature_matches_quirk): - """Test GLEDOPTO GL-C-009 signature is matched to its quirk.""" - signature = { - "node_descriptor": "NodeDescriptor(logical_type=, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=, mac_capability_flags=, manufacturer_code=0, maximum_buffer_size=80, maximum_incoming_transfer_size=160, server_mask=0, maximum_outgoing_transfer_size=160, descriptor_capability_field=, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=False, *is_full_function_device=True, *is_mains_powered=True, *is_receiver_on_when_idle=True, *is_router=True, *is_security_capable=False)", - "endpoints": { - "11": { - "profile_id": 49246, - "device_type": "0x0100", - "in_clusters": [ - "0x0000", - "0x0003", - "0x0004", - "0x0005", - "0x0006", - "0x0008", - "0x0300", - ], - "out_clusters": [], - }, - "13": { - "profile_id": 49246, - "device_type": "0x0100", - "in_clusters": ["0x1000"], - "out_clusters": ["0x1000"], - }, - }, - "manufacturer": "GLEDOPTO", - "model": "GL-C-009", - "class": "zigpy.device.Device", - } - - assert_signature_matches_quirk(zhaquirks.gledopto.glc009.GLC009, signature) diff --git a/tests/test_ikea.py b/tests/test_ikea.py index 88b1e4643e..d4e045c322 100644 --- a/tests/test_ikea.py +++ b/tests/test_ikea.py @@ -15,77 +15,6 @@ zhaquirks.setup() -def test_ikea_starkvind(assert_signature_matches_quirk): - """Test new 'STARKVIND Air purifier table' signature is matched to its quirk.""" - - signature = { - "node_descriptor": "NodeDescriptor(logical_type=, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=, mac_capability_flags=, manufacturer_code=4476, maximum_buffer_size=82, maximum_incoming_transfer_size=82, server_mask=11264, maximum_outgoing_transfer_size=82, descriptor_capability_field=, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=False, *is_full_function_device=True, *is_mains_powered=True, *is_receiver_on_when_idle=True, *is_router=True, *is_security_capable=False)", - "endpoints": { - "1": { - "profile_id": 260, - "device_type": "0x0007", - "in_clusters": [ - "0x0000", - "0x0003", - "0x0004", - "0x0005", - "0x0202", - "0xfc57", - "0xfc7d", - ], - "out_clusters": ["0x0019", "0x0400", "0x042a"], - }, - "242": { - "profile_id": 41440, - "device_type": "0x0061", - "in_clusters": [], - "out_clusters": ["0x0021"], - }, - }, - "manufacturer": "IKEA of Sweden", - "model": "STARKVIND Air purifier", - "class": "ikea.starkvind.IkeaSTARKVIND", - } - - assert_signature_matches_quirk(zhaquirks.ikea.starkvind.IkeaSTARKVIND, signature) - - -def test_ikea_starkvind_v2(assert_signature_matches_quirk): - """Test new 'STARKVIND Air purifier table' signature is matched to its quirk.""" - - signature = { - "node_descriptor": "NodeDescriptor(logical_type=, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=, mac_capability_flags=, manufacturer_code=4476, maximum_buffer_size=82, maximum_incoming_transfer_size=82, server_mask=11264, maximum_outgoing_transfer_size=82, descriptor_capability_field=, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=False, *is_full_function_device=True, *is_mains_powered=True, *is_receiver_on_when_idle=True, *is_router=True, *is_security_capable=False)", - "endpoints": { - "1": { - "profile_id": 260, - "device_type": "0x0007", - "in_clusters": [ - "0x0000", - "0x0003", - "0x0004", - "0x0005", - "0x0202", - "0xfc57", - "0xfc7c", - "0xfc7d", - ], - "out_clusters": ["0x0019", "0x0400", "0x042a"], - }, - "242": { - "profile_id": 41440, - "device_type": "0x0061", - "in_clusters": [], - "out_clusters": ["0x0021"], - }, - }, - "manufacturer": "IKEA of Sweden", - "model": "STARKVIND Air purifier table", - "class": "ikea.starkvind.IkeaSTARKVIND_v2", - } - - assert_signature_matches_quirk(zhaquirks.ikea.starkvind.IkeaSTARKVIND_v2, signature) - - @pytest.mark.parametrize("attribute", ["fan_speed", "fan_mode"]) @pytest.mark.parametrize( "value,expected", @@ -98,11 +27,13 @@ def test_ikea_starkvind_v2(assert_signature_matches_quirk): ], ) async def test_fan_speed_mode_update( - zigpy_device_from_quirk, attribute, value, expected + zigpy_device_from_v2_quirk, attribute, value, expected ): """Test reading the fan speed and mode.""" - starkvind_device = zigpy_device_from_quirk(zhaquirks.ikea.starkvind.IkeaSTARKVIND) + starkvind_device = zigpy_device_from_v2_quirk( + "IKEA of Sweden", "STARKVIND Air purifier" + ) assert starkvind_device.model == "STARKVIND Air purifier" ikea_cluster = starkvind_device.endpoints[1].in_clusters[ @@ -117,10 +48,12 @@ async def test_fan_speed_mode_update( assert ikea_listener.attribute_updates[0] == (attr_id, expected) -async def test_pm25_cluster_read(zigpy_device_from_quirk): +async def test_pm25_cluster_read(zigpy_device_from_v2_quirk): """Test reading from PM25 cluster.""" - starkvind_device = zigpy_device_from_quirk(zhaquirks.ikea.starkvind.IkeaSTARKVIND) + starkvind_device = zigpy_device_from_v2_quirk( + "IKEA of Sweden", "STARKVIND Air purifier" + ) assert starkvind_device.model == "STARKVIND Air purifier" pm25_cluster = starkvind_device.endpoints[1].in_clusters[PM25.cluster_id] @@ -175,7 +108,7 @@ def mock_read(attributes, manufacturer=None): ) async def test_double_power_config_firmware( caplog, - zigpy_device_from_quirk, + zigpy_device_from_v2_quirk, firmware, pct_device, pct_correct, @@ -184,7 +117,7 @@ async def test_double_power_config_firmware( ): """Test battery percentage remaining is doubled for old firmware.""" - device = zigpy_device_from_quirk(zhaquirks.ikea.fivebtnremote.IkeaTradfriRemote1) + device = zigpy_device_from_v2_quirk("IKEA of Sweden", "TRADFRI remote control") basic_cluster = device.endpoints[1].basic ClusterListener(basic_cluster) diff --git a/tests/test_konke.py b/tests/test_konke.py index f1eb4f6eb6..e55457da81 100644 --- a/tests/test_konke.py +++ b/tests/test_konke.py @@ -24,12 +24,12 @@ @pytest.mark.parametrize( - "quirk", (zhaquirks.konke.motion.KonkeMotion, zhaquirks.konke.motion.KonkeMotionB) + "model", ("3AFE28010402000D", "3AFE14010402000D", "3AFE27010402000D") ) -async def test_konke_motion(zigpy_device_from_quirk, quirk): +async def test_konke_motion(zigpy_device_from_v2_quirk, model): """Test konke motion sensor.""" - motion_dev = zigpy_device_from_quirk(quirk) + motion_dev = zigpy_device_from_v2_quirk("Konke", model) motion_cluster = motion_dev.endpoints[1].ias_zone motion_listener = ClusterListener(motion_cluster) @@ -67,16 +67,16 @@ async def test_konke_motion(zigpy_device_from_quirk, quirk): @pytest.mark.parametrize( - "quirk", + "model", ( - zhaquirks.konke.button.KonkeButtonRemote1, - zhaquirks.konke.button.KonkeButtonRemote2, + "3AFE170100510001", + "3AFE280100510001", ), ) -async def test_konke_button(zigpy_device_from_quirk, quirk): +async def test_konke_button(zigpy_device_from_v2_quirk, model): """Test Konke button remotes.""" - device = zigpy_device_from_quirk(quirk) + device = zigpy_device_from_v2_quirk("Konke", model) cluster = device.endpoints[1].konke_on_off listener = mock.MagicMock() diff --git a/tests/test_legrand.py b/tests/test_legrand.py index e10539f901..4135c6721f 100644 --- a/tests/test_legrand.py +++ b/tests/test_legrand.py @@ -23,10 +23,10 @@ (24.0, 0), # below min ), ) -async def test_legrand_battery(zigpy_device_from_quirk, voltage, bpr): +async def test_legrand_battery(zigpy_device_from_v2_quirk, voltage, bpr): """Test Legrand battery voltage to % battery left.""" - device = zigpy_device_from_quirk(zhaquirks.legrand.dimmer.RemoteDimmer) + device = zigpy_device_from_v2_quirk(f" {LEGRAND}", " Remote dimmer switch") power_cluster = device.endpoints[1].power power_cluster.update_attribute(0x0020, voltage) assert power_cluster["battery_percentage_remaining"] == bpr diff --git a/tests/test_linkind.py b/tests/test_linkind.py index 3f77cb48ca..eb26a7f399 100644 --- a/tests/test_linkind.py +++ b/tests/test_linkind.py @@ -9,10 +9,12 @@ zhaquirks.setup() -@pytest.mark.parametrize("quirk", (zhaquirks.linkind.motion.LinkindD0003,)) -async def test_linkind_motion_ignore_alarm_2(zigpy_device_from_quirk, quirk): +@pytest.mark.parametrize("manufacturer,model", [("lk", "ZB-MotionSensor-D0003")]) +async def test_linkind_motion_ignore_alarm_2( + zigpy_device_from_v2_quirk, manufacturer, model +): """Test that the quirk for the Linkind motion sensor ignores the IasZone Alarm_2 bit.""" - device = zigpy_device_from_quirk(quirk) + device = zigpy_device_from_v2_quirk(manufacturer, model) ias_zone_cluster = device.endpoints[1].ias_zone ias_zone_listener = ClusterListener(ias_zone_cluster) diff --git a/tests/test_linxura.py b/tests/test_linxura.py index e4fd778113..9be44efefd 100644 --- a/tests/test_linxura.py +++ b/tests/test_linxura.py @@ -12,10 +12,10 @@ zhaquirks.setup() -async def test_button_ias(zigpy_device_from_quirk): +async def test_button_ias(zigpy_device_from_v2_quirk): """Test Linxura button remotes.""" - device = zigpy_device_from_quirk(zhaquirks.linxura.button.LinxuraButton) + device = zigpy_device_from_v2_quirk("Linxura", "Smart Controller") ias_zone_status_attr_id = IasZone.AttributeDefs.zone_status.id cluster = device.endpoints[1].ias_zone listener = mock.MagicMock() @@ -99,9 +99,9 @@ async def test_button_ias(zigpy_device_from_quirk): ), ], ) -async def test_button_triggers(zigpy_device_from_quirk, message, button, press_type): +async def test_button_triggers(zigpy_device_from_v2_quirk, message, button, press_type): """Test ZHA_SEND_EVENT case.""" - device = zigpy_device_from_quirk(zhaquirks.linxura.button.LinxuraButton) + device = zigpy_device_from_v2_quirk("Linxura", "Smart Controller") cluster = device.endpoints[1].ias_zone listener = mock.MagicMock() cluster.add_listener(listener) diff --git a/tests/test_orvibo.py b/tests/test_orvibo.py index ad363502a9..fa5a3783c0 100644 --- a/tests/test_orvibo.py +++ b/tests/test_orvibo.py @@ -13,11 +13,11 @@ zhaquirks.setup() -@pytest.mark.parametrize("quirk", (zhaquirks.orvibo.motion.SN10ZW,)) -async def test_orvibo_motion(zigpy_device_from_quirk, quirk): +@pytest.mark.parametrize("model", ("895a2d80097f4ae2b2d40500d5e03dcc",)) +async def test_orvibo_motion(zigpy_device_from_v2_quirk, model): """Test Orvibo motion sensor.""" - motion_dev = zigpy_device_from_quirk(quirk) + motion_dev = zigpy_device_from_v2_quirk("ORVIBO", model) motion_cluster = motion_dev.endpoints[1].ias_zone motion_listener = ClusterListener(motion_cluster) diff --git a/tests/test_paulmann.py b/tests/test_paulmann.py index baac77935e..0f85dd7302 100644 --- a/tests/test_paulmann.py +++ b/tests/test_paulmann.py @@ -1,52 +1 @@ """Tests for Paulmann quirks.""" - -import pytest - -import zhaquirks.paulmann.fourbtnremote - - -@pytest.mark.parametrize("manufacturer", ("Paulmann LichtGmbH", "Paulmann Licht GmbH")) -def test_fourbtnremote_signature(assert_signature_matches_quirk, manufacturer): - """Test PaulmannRemote4Btn signature is matched to its quirk.""" - signature = { - "node_descriptor": "NodeDescriptor(logical_type=, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=, mac_capability_flags=, manufacturer_code=4644, maximum_buffer_size=82, maximum_incoming_transfer_size=82, server_mask=11264, maximum_outgoing_transfer_size=82, descriptor_capability_field=, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=True, *is_full_function_device=False, *is_mains_powered=False, *is_receiver_on_when_idle=False, *is_router=False, *is_security_capable=False)", - "endpoints": { - "1": { - "profile_id": 260, - "device_type": "0x0001", - "in_clusters": ["0x0000", "0x0001", "0x0003", "0x0b05", "0x1000"], - "out_clusters": [ - "0x0003", - "0x0004", - "0x0005", - "0x0006", - "0x0008", - "0x0019", - "0x0300", - "0x1000", - ], - }, - "2": { - "profile_id": 260, - "device_type": "0x0001", - "in_clusters": ["0x0000", "0x0001", "0x0003", "0x0b05", "0x1000"], - "out_clusters": [ - "0x0003", - "0x0004", - "0x0005", - "0x0006", - "0x0008", - "0x0019", - "0x0300", - "0x1000", - ], - }, - }, - "manufacturer": manufacturer, - "model": "501.34", - "class": "paulmann.fourbtnremote.PaulmannRemote4Btn", - } - - assert_signature_matches_quirk( - zhaquirks.paulmann.fourbtnremote.PaulmannRemote4Btn, signature - ) diff --git a/tests/test_philips.py b/tests/test_philips.py index c91da9d9c0..7337789955 100644 --- a/tests/test_philips.py +++ b/tests/test_philips.py @@ -35,21 +35,27 @@ TURN_ON, ) import zhaquirks.philips -from zhaquirks.philips import Button, ButtonPressQueue, PhilipsRemoteCluster, PressType -from zhaquirks.philips.rdm002 import PhilipsRDM002 -from zhaquirks.philips.rom001 import PhilipsROM001 -from zhaquirks.philips.rwl022 import PhilipsRWL022 -from zhaquirks.philips.rwlfirstgen import PhilipsRWLFirstGen, PhilipsRWLFirstGen2 -from zhaquirks.philips.wall_switch import PhilipsWallSwitch +from zhaquirks.philips import ( + PHILIPS, + SIGNIFY, + Button, + ButtonPressQueue, + PhilipsRemoteCluster, + PhilipsRwlRemoteCluster, + PressType, +) +from zhaquirks.philips.rdm002 import DIAL_TRIGGERS, PhilipsRdm002RemoteCluster +from zhaquirks.philips.rom001 import PhilipsRom001RemoteCluster +from zhaquirks.philips.wall_switch import PhilipsWallSwitchRemoteCluster zhaquirks.setup() @pytest.mark.parametrize( - "classes, triggers", + "cluster_class, triggers", ( ( - [PhilipsRWLFirstGen, PhilipsRWLFirstGen2, PhilipsRWL022], + PhilipsRwlRemoteCluster, { (SHORT_PRESS, TURN_ON): {COMMAND: "on_press"}, (SHORT_PRESS, TURN_OFF): {COMMAND: "off_press"}, @@ -86,7 +92,7 @@ }, ), ( - [PhilipsROM001], + PhilipsRom001RemoteCluster, { (SHORT_PRESS, TURN_ON): {COMMAND: "on_press"}, (LONG_PRESS, TURN_ON): {COMMAND: "on_hold"}, @@ -99,7 +105,7 @@ }, ), ( - [PhilipsWallSwitch], + PhilipsWallSwitchRemoteCluster, { (SHORT_PRESS, TURN_ON): {COMMAND: "left_press"}, (LONG_PRESS, TURN_ON): {COMMAND: "left_hold"}, @@ -121,11 +127,10 @@ ), ), ) -def test_legacy_remote_automation_triggers(classes, triggers): +def test_legacy_remote_automation_triggers(cluster_class, triggers): """Ensure we don't break any automation triggers by changing their values.""" - for cls in classes: - assert cls.device_automation_triggers == triggers + assert cluster_class.generate_device_automation_triggers() == triggers class _SimpleRemote(PhilipsRemoteCluster): @@ -327,34 +332,39 @@ def press(self, callback): @pytest.mark.parametrize( - "dev, ep, button, events", + "manufacturer, model, ep, button, events", ( ( - PhilipsWallSwitch, + SIGNIFY, + "RDM001", 1, "left", ["press", "short_release"], ), ( - PhilipsROM001, + SIGNIFY, + "ROM001", 1, "on", ["press", "short_release"], ), ( - PhilipsRWLFirstGen, + PHILIPS, + "RWL020", 2, "on", ["press", "short_release"], ), ( - PhilipsRWLFirstGen2, + PHILIPS, + "RWL021", 2, "on", ["press", "short_release"], ), ( - PhilipsRWL022, + SIGNIFY, + "RWL022", 1, "on", ["press", "short_release"], @@ -362,11 +372,11 @@ def press(self, callback): ), ) def test_PhilipsRemoteCluster_short_press( - zigpy_device_from_quirk, dev, ep, button, events + zigpy_device_from_v2_quirk, manufacturer, model, ep, button, events ): """Test PhilipsRemoteCluster short button press logic.""" - device = zigpy_device_from_quirk(dev) + device = zigpy_device_from_v2_quirk(manufacturer, model, endpoint_ids=[1, 2]) cluster = device.endpoints[ep].philips_remote_cluster listener = mock.MagicMock() @@ -409,30 +419,35 @@ def test_PhilipsRemoteCluster_short_press( @pytest.mark.parametrize( - "dev, ep, button", + "manufacturer, model, ep, button", ( ( - PhilipsROM001, + PHILIPS, + "ROM001", 1, "on", ), ( - PhilipsWallSwitch, + PHILIPS, + "RDM001", 1, "left", ), ( - PhilipsRWLFirstGen, + PHILIPS, + "RWL020", 2, "on", ), ( - PhilipsRWLFirstGen2, + PHILIPS, + "RWL021", 2, "on", ), ( - PhilipsRWL022, + SIGNIFY, + "RWL022", 1, "on", ), @@ -448,8 +463,9 @@ def test_PhilipsRemoteCluster_short_press( ), ) def test_PhilipsRemoteCluster_multi_press( - zigpy_device_from_quirk, - dev, + zigpy_device_from_v2_quirk, + manufacturer, + model, ep, button, count, @@ -457,7 +473,7 @@ def test_PhilipsRemoteCluster_multi_press( ): """Test PhilipsRemoteCluster button multi-press logic.""" - device = zigpy_device_from_quirk(dev) + device = zigpy_device_from_v2_quirk(manufacturer, model, endpoint_ids=[1, 2]) cluster = device.endpoints[ep].philips_remote_cluster listener = mock.MagicMock() @@ -493,19 +509,21 @@ def test_PhilipsRemoteCluster_multi_press( @pytest.mark.parametrize( - "dev, ep", + "manufacturer, model, ep", ( - (PhilipsWallSwitch, 1), - (PhilipsROM001, 1), - (PhilipsRWLFirstGen, 2), - (PhilipsRWLFirstGen2, 2), - (PhilipsRWL022, 1), + (PHILIPS, "RDM001", 1), + (PHILIPS, "ROM001", 1), + (PHILIPS, "RWL020", 2), + (PHILIPS, "RWL021", 2), + (SIGNIFY, "RWL022", 1), ), ) -def test_PhilipsRemoteCluster_ignore_unknown_buttons(zigpy_device_from_quirk, dev, ep): +def test_PhilipsRemoteCluster_ignore_unknown_buttons( + zigpy_device_from_v2_quirk, manufacturer, model, ep +): """Ensure PhilipsRemoteCluster ignores unknown buttons.""" - device = zigpy_device_from_quirk(dev) + device = zigpy_device_from_v2_quirk(manufacturer, model, endpoint_ids=[1, 2]) cluster = device.endpoints[ep].philips_remote_cluster listener = mock.MagicMock() @@ -517,11 +535,12 @@ def test_PhilipsRemoteCluster_ignore_unknown_buttons(zigpy_device_from_quirk, de @pytest.mark.parametrize( - "dev, ep, button, hold_press_type, release_press_type, release_press_type_arg", + "manufacturer, model, ep, button, hold_press_type, release_press_type, release_press_type_arg", ( - (PhilipsROM001, 1, "on", "hold", "long_release", "hold_release"), + (PHILIPS, "ROM001", 1, "on", "hold", "long_release", "hold_release"), ( - PhilipsWallSwitch, + PHILIPS, + "RDM001", 1, "left", "hold", @@ -529,7 +548,8 @@ def test_PhilipsRemoteCluster_ignore_unknown_buttons(zigpy_device_from_quirk, de "hold_release", ), ( - PhilipsRWLFirstGen, + PHILIPS, + "RWL020", 2, "on", "hold", @@ -537,7 +557,8 @@ def test_PhilipsRemoteCluster_ignore_unknown_buttons(zigpy_device_from_quirk, de "long_release", ), ( - PhilipsRWLFirstGen2, + PHILIPS, + "RWL021", 2, "on", "hold", @@ -545,7 +566,8 @@ def test_PhilipsRemoteCluster_ignore_unknown_buttons(zigpy_device_from_quirk, de "long_release", ), ( - PhilipsRWL022, + SIGNIFY, + "RWL022", 1, "on", "hold", @@ -563,8 +585,9 @@ def test_PhilipsRemoteCluster_ignore_unknown_buttons(zigpy_device_from_quirk, de ), ) def test_PhilipsRemoteCluster_long_press( - zigpy_device_from_quirk, - dev, + zigpy_device_from_v2_quirk, + manufacturer, + model, ep, button, hold_press_type, @@ -574,7 +597,7 @@ def test_PhilipsRemoteCluster_long_press( ): """Test PhilipsRemoteCluster button long press logic.""" - device = zigpy_device_from_quirk(dev) + device = zigpy_device_from_v2_quirk(manufacturer, model, endpoint_ids=[1, 2]) cluster = device.endpoints[ep].philips_remote_cluster listener = mock.MagicMock() @@ -715,7 +738,9 @@ def test_rdm002_triggers(): } ) - actual_triggers = PhilipsRDM002.device_automation_triggers + actual_triggers = PhilipsRdm002RemoteCluster.generate_device_automation_triggers( + DIAL_TRIGGERS + ) assert actual_triggers == expected_triggers @@ -749,10 +774,11 @@ def test_contact_sensor(zigpy_device_from_v2_quirk): @pytest.mark.parametrize( - "dev, ep, button_events, expected_actions", + "manufacturer, model, ep, button_events, expected_actions", ( ( - PhilipsWallSwitch, + PHILIPS, + "RDM001", 1, ( [ @@ -769,11 +795,11 @@ def test_contact_sensor(zigpy_device_from_v2_quirk): ), ) def test_PhilipsRemoteCluster_multi_button_press( - zigpy_device_from_quirk, dev, ep, button_events, expected_actions + zigpy_device_from_v2_quirk, manufacturer, model, ep, button_events, expected_actions ): """Test PhilipsRemoteCluster short button press logic.""" - device = zigpy_device_from_quirk(dev) + device = zigpy_device_from_v2_quirk(manufacturer, model, endpoint_ids=[1, 2]) remote_cluster = device.endpoints[ep].philips_remote_cluster remote_cluster.button_press_queue = { @@ -818,10 +844,10 @@ def listen_to_all(device) -> mock.MagicMock: return listener -async def test_RDM002_no_levelcontrol_on_long_press(zigpy_device_from_quirk): +async def test_RDM002_no_levelcontrol_on_long_press(zigpy_device_from_v2_quirk): """Button long-presses shouldn't trigger LevelControl events.""" - device = zigpy_device_from_quirk(PhilipsRDM002) + device = zigpy_device_from_v2_quirk(PHILIPS, "RDM002") listener = listen_to_all(device) # All below messages are triggered when long pressing button 1 for ~1.5 seconds @@ -865,10 +891,10 @@ async def test_RDM002_no_levelcontrol_on_long_press(zigpy_device_from_quirk): assert listener.cluster_command.call_count == 3 -async def test_RDM002_levelcontrol_on_dial_rotary_event(zigpy_device_from_quirk): +async def test_RDM002_levelcontrol_on_dial_rotary_event(zigpy_device_from_v2_quirk): """Dial rotary events shouldn't be muted by PhilipsRdm002LevelControl.""" - device = zigpy_device_from_quirk(PhilipsRDM002) + device = zigpy_device_from_v2_quirk(PHILIPS, "RDM002") listener = listen_to_all(device) # All below messages are triggered when quickly rotating the dial counterclockwise diff --git a/tests/test_quirks.py b/tests/test_quirks.py index 639bbd0fd4..a00c7dab76 100644 --- a/tests/test_quirks.py +++ b/tests/test_quirks.py @@ -21,7 +21,6 @@ import zigpy.zdo.types import zhaquirks -from zhaquirks import const import zhaquirks.bosch.motion import zhaquirks.centralite.cl_3310S from zhaquirks.const import ( @@ -408,10 +407,6 @@ def _check_range(cluster: zcl.Cluster) -> bool: zhaquirks.xbee.xbee_io.XBeeSensor, zhaquirks.xbee.xbee3_io.XBee3Sensor, zhaquirks.tuya.ts0201.MoesTemperatureHumidtySensorWithScreen, - zhaquirks.smartthings.tag_v4.SmartThingsTagV4, - zhaquirks.smartthings.multi.SmartthingsMultiPurposeSensor, - zhaquirks.netvox.z308e3ed.Z308E3ED, - zhaquirks.gledopto.soposhgu10.SoposhGU10, ) ], ) @@ -473,102 +468,6 @@ def test_quirk_loading_error(tmp_path: Path, caplog) -> None: assert "cannot import name 'foobarbaz7' from 'os'" in caplog.text -def test_custom_quirk_loading( - zigpy_device_from_quirk: CustomDevice, tmp_path: Path -) -> None: - """Make sure custom quirks take priority over regular quirks.""" - - device = zigpy_device_from_quirk( - zhaquirks.bosch.motion.ISWZPR1WP13, apply_quirk=False - ) - assert type(device) is zigpy.device.Device - - # Make sure our target quirk will load after we re-setup zhaquirks - zhaquirks.setup() - assert type(zq.get_device(device)) is zhaquirks.bosch.motion.ISWZPR1WP13 - - custom_quirks = tmp_path / "custom_zha_quirks" - custom_quirks.mkdir() - - # Make our own custom quirk - (custom_quirks / "__init__.py").touch() - - (custom_quirks / "bosch").mkdir() - (custom_quirks / "bosch/__init__.py").touch() - (custom_quirks / "bosch/custom_quirk.py").write_text( - ''' -"""Device handler for Bosch motion sensors.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import Basic, Identify, Ota, PollControl -from zigpy.zcl.clusters.homeautomation import Diagnostic -from zigpy.zcl.clusters.measurement import TemperatureMeasurement -from zigpy.zcl.clusters.security import IasZone - -from zhaquirks import PowerConfigurationCluster - -from zhaquirks.bosch import BOSCH -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) - -class TestReplacementISWZPR1WP13(CustomDevice): - """Custom device representing Bosch motion sensors.""" - - signature = { - # - MODELS_INFO: [(BOSCH, "ISW-ZPR1-WP13")], - ENDPOINTS: { - 5: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfigurationCluster.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - IasZone.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - }, - } - - replacement = { - ENDPOINTS: { - 5: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfigurationCluster.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - IasZone.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - } - } -''' - ) - - zhaquirks.setup(custom_quirks_path=str(custom_quirks)) - - assert not isinstance(zq.get_device(device), zhaquirks.bosch.motion.ISWZPR1WP13) - assert type(zq.get_device(device)).__name__ == "TestReplacementISWZPR1WP13" - - def test_zigpy_custom_cluster_pollution() -> None: """Ensure all quirks subclass `CustomCluster`.""" non_zigpy_clusters = { @@ -640,33 +539,7 @@ def test_migrated_lighting_automation_triggers(quirk: CustomDevice) -> None: KNOWN_DUPLICATE_TRIGGERS = { - zhaquirks.aurora.aurora_dimmer.AuroraDimmerBatteryPowered: [ - [ - # XXX: why is this constant defined in the module? - (zhaquirks.aurora.aurora_dimmer.COLOR_UP, const.RIGHT), - (zhaquirks.aurora.aurora_dimmer.COLOR_UP, const.LEFT), - ], - [ - (zhaquirks.aurora.aurora_dimmer.COLOR_DOWN, const.RIGHT), - (zhaquirks.aurora.aurora_dimmer.COLOR_DOWN, const.LEFT), - ], - ], - zhaquirks.paulmann.fourbtnremote.PaulmannRemote4Btn: [ - [ - (const.LONG_RELEASE, const.BUTTON_1), - (const.LONG_RELEASE, const.BUTTON_2), - ], - [ - (const.LONG_RELEASE, const.BUTTON_3), - (const.LONG_RELEASE, const.BUTTON_4), - ], - ], - zhaquirks.thirdreality.button.Button: [ - [ - (const.LONG_PRESS, const.LONG_PRESS), - (const.LONG_RELEASE, const.LONG_RELEASE), - ] - ], + # v2 quirks removed: aurora.aurora_dimmer, paulmann.fourbtnremote, thirdreality.button } @@ -871,8 +744,6 @@ def check_for_duplicate_cluster_ids(clusters) -> None: zhaquirks.xiaomi.aqara.cube_aqgl01.CubeAQGL01, # also add OTA input cluster (Aqara cube): zhaquirks.xiaomi.aqara.cube_aqgl01.CubeCAGL02, - # remove custom Xiaomi output cluster (E1 curtain driver): - zhaquirks.xiaomi.aqara.driver_curtain_e1.DriverE1, # remove random AnalogInput input cluster (Aqara remote + temp sensor): zhaquirks.xiaomi.aqara.remote_b186acn01.RemoteB186ACN01, zhaquirks.xiaomi.aqara.remote_b286acn01.RemoteB286ACN01, @@ -885,8 +756,6 @@ def check_for_duplicate_cluster_ids(clusters) -> None: # remove OTA input cluster (Aqara remote + motion sensor): zhaquirks.xiaomi.mija.motion.Motion, zhaquirks.xiaomi.mija.sensor_switch.MijaButton, - # remove a bunch of incorrect output clusters (LUMI/Keen temp sensor): - zhaquirks.keenhome.weather.TemperatureHumidtyPressureSensor, # this just exposed all ZCL clusters, remove a lot (Aqara light): zhaquirks.xiaomi.aqara.light_aqcn2.LightAqcn02, # DoorLock cluster that's actually a MultistateInput cluster @@ -896,23 +765,8 @@ def check_for_duplicate_cluster_ids(clusters) -> None: # -- IKEA devices -- # swap PM25 cluster from output to input cluster (IKEA Starkvind): zhaquirks.ikea.starkvind.IkeaSTARKVIND, - zhaquirks.ikea.starkvind.IkeaSTARKVIND_v2, - # removes Group input cluster (IKEA remote): - zhaquirks.ikea.twobtnremote.IkeaRodretRemote2BtnNew, - # remove WindowCovering input cluster (IKEA remote): - zhaquirks.ikea.twobtnremote.IkeaTradfriRemote2BtnZLL, # # -- other devices -- - # adds DoorLock cluster to output clusters (Yale door locks): - zhaquirks.yale.realliving.YRD210PBDB220TSLL, - zhaquirks.yale.realliving.YRD220240TSDB, - # remove LevelControl input cluster (Adurolight remote): - zhaquirks.aduro.adurolightncc.AdurolightNCC, - # add a bunch of output clusters (Zhongxing motion sensor): - zhaquirks.zhongxing.motion.SN10ZW, - # remove Tuya clusters from input and output clusters (ZLinky): - zhaquirks.lixee.zlinky.ZLinkyTICFWV14, - zhaquirks.lixee.zlinky.ZLinkyTICFWV15, ) ], ) diff --git a/tests/test_quirks_v2.py b/tests/test_quirks_v2.py index 3df5f0da9f..d7e1c9a64d 100644 --- a/tests/test_quirks_v2.py +++ b/tests/test_quirks_v2.py @@ -65,8 +65,8 @@ def test_manufacturer_model_metadata_unique() -> None: ) for quirk in ALL_QUIRK_V2_CLASSES: - if quirk.fw_version_filter is not None: - # skip quirks with firmware filter, as they can share manufacturer/model + if quirk.fw_version_filter is not None or quirk.filters: + # skip quirks with firmware filter or general filters, as they can share manufacturer/model continue for metadata in quirk.manufacturer_model_metadata: man_model_quirk_map[(metadata.manufacturer, metadata.model)].append( diff --git a/tests/test_schneiderelectric.py b/tests/test_schneiderelectric.py index 00c8cc050b..fd333d5bbb 100644 --- a/tests/test_schneiderelectric.py +++ b/tests/test_schneiderelectric.py @@ -2,14 +2,13 @@ from unittest import mock -import pytest from zigpy.zcl import foundation from zigpy.zcl.clusters.closures import WindowCovering from zigpy.zcl.clusters.smartenergy import Metering from tests.common import ClusterListener +import zhaquirks from zhaquirks.schneiderelectric import SE_MANUF_NAME -import zhaquirks.schneiderelectric.outlet zhaquirks.setup() @@ -86,10 +85,13 @@ async def test_1gang_shutter_1_lift_percentage_updates(zigpy_device_from_v2_quir assert len(cluster_listener.cluster_commands) == 0 -@pytest.mark.parametrize("quirk", (zhaquirks.schneiderelectric.outlet.SocketOutlet,)) -async def test_schneider_device_temp(zigpy_device_from_quirk, quirk): +async def test_schneider_device_temp(zigpy_device_from_v2_quirk): """Test that instant demand is divided by 1000.""" - device = zigpy_device_from_quirk(quirk) + device = zigpy_device_from_v2_quirk( + manufacturer=SE_MANUF_NAME, + model="SOCKET/OUTLET/1", + endpoint_ids=[6], + ) metering_cluster = device.endpoints[6].smartenergy_metering metering_listener = ClusterListener(metering_cluster) diff --git a/tests/test_sinope.py b/tests/test_sinope.py index 72b3e69abd..3a60d8c93f 100644 --- a/tests/test_sinope.py +++ b/tests/test_sinope.py @@ -20,11 +20,7 @@ TURN_ON, ) from zhaquirks.sinope import SINOPE_MANUFACTURER_CLUSTER_ID -from zhaquirks.sinope.light import ( - SinopeTechnologieslight, - SinopeTechnologiesManufacturerCluster, -) -from zhaquirks.sinope.switch import SinopeTechnologiesCalypso, SinopeTechnologiesValveG2 +from zhaquirks.sinope.light import SinopeTechnologiesManufacturerCluster zhaquirks.setup() @@ -33,10 +29,11 @@ SINOPE_MANUFACTURER_ID = 4508 # 0x119C -@pytest.mark.parametrize("quirk", (SinopeTechnologiesCalypso,)) -async def test_sinope_device_temp(zigpy_device_from_quirk, quirk): +async def test_sinope_device_temp(zigpy_device_from_v2_quirk): """Test that device temperature is multiplied.""" - device = zigpy_device_from_quirk(quirk) + device = zigpy_device_from_v2_quirk( + manufacturer="Sinope Technologies", model="RM3500ZB" + ) dev_temp_cluster = device.endpoints[1].device_temperature dev_temp_listener = ClusterListener(dev_temp_cluster) @@ -56,10 +53,11 @@ async def test_sinope_device_temp(zigpy_device_from_quirk, quirk): assert dev_temp_listener.attribute_updates[1][1] == 25 # not modified -@pytest.mark.parametrize("quirk", (SinopeTechnologiesValveG2,)) -async def test_sinope_flow_measurement(zigpy_device_from_quirk, quirk): +async def test_sinope_flow_measurement(zigpy_device_from_v2_quirk): """Test that flow measurement measured value is divided.""" - device = zigpy_device_from_quirk(quirk) + device = zigpy_device_from_v2_quirk( + manufacturer="Sinope Technologies", model="VA4220ZB" + ) flow_measurement_cluster = device.endpoints[1].flow flow_measurement_listener = ClusterListener(flow_measurement_cluster) @@ -97,7 +95,6 @@ def _get_packet_data( return t.SerializableBytes(hdr + cmd).serialize() -@pytest.mark.parametrize("quirk", (SinopeTechnologieslight,)) @pytest.mark.parametrize( "press_type,button,exp_event", ( @@ -114,10 +111,12 @@ def _get_packet_data( ), ) async def test_sinope_light_switch( - zigpy_device_from_quirk, quirk, press_type, button, exp_event + zigpy_device_from_v2_quirk, press_type, button, exp_event ): """Test that button presses are sent as events.""" - device: Device = zigpy_device_from_quirk(quirk) + device: Device = zigpy_device_from_v2_quirk( + manufacturer="Sinope Technologies", model="SW2500ZB" + ) cluster_id = SINOPE_MANUFACTURER_CLUSTER_ID endpoint_id = 1 @@ -162,15 +161,16 @@ class Listener: ) -@pytest.mark.parametrize("quirk", (SinopeTechnologieslight,)) -async def test_sinope_light_switch_non_action_report(zigpy_device_from_quirk, quirk): +async def test_sinope_light_switch_non_action_report(zigpy_device_from_v2_quirk): """Test commands not handled by custom handler. Make sure that non attribute report commands and attribute reports that don't concern action_report are passed through to base class. """ - device: Device = zigpy_device_from_quirk(quirk) + device: Device = zigpy_device_from_v2_quirk( + manufacturer="Sinope Technologies", model="SW2500ZB" + ) cluster_id = SINOPE_MANUFACTURER_CLUSTER_ID endpoint_id = 1 @@ -216,10 +216,11 @@ class Listener: assert cluster_listener.zha_send_event.call_count == 1 -@pytest.mark.parametrize("quirk", (SinopeTechnologieslight,)) -async def test_sinope_light_switch_reporting(zigpy_device_from_quirk, quirk): +async def test_sinope_light_switch_reporting(zigpy_device_from_v2_quirk): """Test that configuring reporting for action_report works.""" - device: Device = zigpy_device_from_quirk(quirk) + device: Device = zigpy_device_from_v2_quirk( + manufacturer="Sinope Technologies", model="SW2500ZB" + ) manu_cluster = device.endpoints[1].in_clusters[SINOPE_MANUFACTURER_CLUSTER_ID] @@ -241,14 +242,14 @@ async def test_sinope_light_switch_reporting(zigpy_device_from_quirk, quirk): assert len(bind_mock.mock_calls) == 1 -@pytest.mark.parametrize("quirk", (SinopeTechnologieslight,)) -async def test_sinope_light_device_triggers_def(zigpy_device_from_quirk, quirk): +@pytest.mark.parametrize("model", ("SW2500ZB",)) +async def test_sinope_light_device_triggers_def(zigpy_device_from_v2_quirk, model): """Test device automation triggers. Make sure that values are actual ints and not instances of an enum class. """ - device: Device = zigpy_device_from_quirk(quirk) + device: Device = zigpy_device_from_v2_quirk("Sinope Technologies", model) for config in device.device_automation_triggers.values(): val = config.get("args", {}).get("value") diff --git a/tests/test_smartwings.py b/tests/test_smartwings.py index e3941bb150..b092406f7f 100644 --- a/tests/test_smartwings.py +++ b/tests/test_smartwings.py @@ -5,14 +5,12 @@ import pytest from zigpy.zcl.clusters.closures import WindowCovering -from zhaquirks.smartwings.wm25lz import WM25LBlinds - -@pytest.mark.parametrize("quirk", (WM25LBlinds,)) -async def test_smartwings_inverted_commands(zigpy_device_from_quirk, quirk): +@pytest.mark.parametrize("model", ("WM25/L-Z",)) +async def test_smartwings_inverted_commands(zigpy_device_from_v2_quirk, model): """Test that the Smartwings WM25/L-Z blind quirk inverts the up/down commands.""" - device = zigpy_device_from_quirk(quirk) + device = zigpy_device_from_v2_quirk("Smartwings", model) device.request = mock.AsyncMock() covering_cluster = device.endpoints[1].window_covering diff --git a/tests/test_thirdreality.py b/tests/test_thirdreality.py index 6d0f31fe71..e0dcf5a23e 100644 --- a/tests/test_thirdreality.py +++ b/tests/test_thirdreality.py @@ -1,20 +1,22 @@ """Tests for Third Reality quirks.""" -import pytest +from zigpy.zcl import ClusterType from zigpy.zcl.clusters.security import IasZone from tests.common import ClusterListener import zhaquirks -import zhaquirks.thirdreality.night_light zhaquirks.setup() -@pytest.mark.parametrize("quirk", (zhaquirks.thirdreality.night_light.Nightlight,)) -async def test_third_reality_nightlight(zigpy_device_from_quirk, quirk): +async def test_third_reality_nightlight(zigpy_device_from_v2_quirk): """Test Third Reality night light forwarding motion attribute to IasZone cluster.""" - device = zigpy_device_from_quirk(quirk) + device = zigpy_device_from_v2_quirk( + "Third Reality, Inc", + "3RSNL02043Z", + cluster_ids={1: {0xFC00: ClusterType.Server}}, + ) ias_zone_cluster = device.endpoints[1].ias_zone ias_zone_listener = ClusterListener(ias_zone_cluster) diff --git a/tests/test_xiaomi.py b/tests/test_xiaomi.py index 37c566799c..bd1e3ec662 100644 --- a/tests/test_xiaomi.py +++ b/tests/test_xiaomi.py @@ -1583,10 +1583,10 @@ async def test_xiaomi_t1_door_sensor( ], ) async def test_xiaomi_e1_driver_commands( - zigpy_device_from_quirk, command, command_id, value + zigpy_device_from_v2_quirk, command, command_id, value ): """Test Aqara E1 driver commands for basic movement functions using WindowCovering cluster.""" - device = zigpy_device_from_quirk(zhaquirks.xiaomi.aqara.driver_curtain_e1.DriverE1) + device = zigpy_device_from_v2_quirk("LUMI", "lumi.curtain.agl001") window_covering_cluster = device.endpoints[1].window_covering p = mock.patch.object(window_covering_cluster, "request", mock.AsyncMock()) @@ -1611,10 +1611,10 @@ async def test_xiaomi_e1_driver_commands( ], ) async def test_xiaomi_e1_driver_light_level( - zigpy_device_from_quirk, device_level, converted_level + zigpy_device_from_v2_quirk, device_level, converted_level ): """Test Aqara E1 driver light level cluster conversion.""" - device = zigpy_device_from_quirk(zhaquirks.xiaomi.aqara.driver_curtain_e1.DriverE1) + device = zigpy_device_from_v2_quirk("LUMI", "lumi.curtain.agl001") opple_cluster = device.endpoints[1].opple_cluster opple_listener = ClusterListener(opple_cluster) diff --git a/uv.lock b/uv.lock index 0c18d852fa..93f3bb486b 100644 --- a/uv.lock +++ b/uv.lock @@ -1,5 +1,5 @@ version = 1 -revision = 1 +revision = 3 requires-python = ">=3.12" resolution-markers = [ "sys_platform != 'win32'", @@ -10,9 +10,9 @@ resolution-markers = [ name = "aiohappyeyeballs" version = "2.6.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/26/30/f84a107a9c4331c14b2b586036f40965c128aa4fee4dda5d3d51cb14ad54/aiohappyeyeballs-2.6.1.tar.gz", hash = "sha256:c3f9d0113123803ccadfdf3f0faa505bc78e6a72d1cc4806cbd719826e943558", size = 22760 } +sdist = { url = "https://files.pythonhosted.org/packages/26/30/f84a107a9c4331c14b2b586036f40965c128aa4fee4dda5d3d51cb14ad54/aiohappyeyeballs-2.6.1.tar.gz", hash = "sha256:c3f9d0113123803ccadfdf3f0faa505bc78e6a72d1cc4806cbd719826e943558", size = 22760, upload-time = "2025-03-12T01:42:48.764Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl", hash = "sha256:f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8", size = 15265 }, + { url = "https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl", hash = "sha256:f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8", size = 15265, upload-time = "2025-03-12T01:42:47.083Z" }, ] [[package]] @@ -28,42 +28,42 @@ dependencies = [ { name = "propcache" }, { name = "yarl" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9b/e7/d92a237d8802ca88483906c388f7c201bbe96cd80a165ffd0ac2f6a8d59f/aiohttp-3.12.15.tar.gz", hash = "sha256:4fc61385e9c98d72fcdf47e6dd81833f47b2f77c114c29cd64a361be57a763a2", size = 7823716 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/63/97/77cb2450d9b35f517d6cf506256bf4f5bda3f93a66b4ad64ba7fc917899c/aiohttp-3.12.15-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:802d3868f5776e28f7bf69d349c26fc0efadb81676d0afa88ed00d98a26340b7", size = 702333 }, - { url = "https://files.pythonhosted.org/packages/83/6d/0544e6b08b748682c30b9f65640d006e51f90763b41d7c546693bc22900d/aiohttp-3.12.15-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f2800614cd560287be05e33a679638e586a2d7401f4ddf99e304d98878c29444", size = 476948 }, - { url = "https://files.pythonhosted.org/packages/3a/1d/c8c40e611e5094330284b1aea8a4b02ca0858f8458614fa35754cab42b9c/aiohttp-3.12.15-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8466151554b593909d30a0a125d638b4e5f3836e5aecde85b66b80ded1cb5b0d", size = 469787 }, - { url = "https://files.pythonhosted.org/packages/38/7d/b76438e70319796bfff717f325d97ce2e9310f752a267bfdf5192ac6082b/aiohttp-3.12.15-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e5a495cb1be69dae4b08f35a6c4579c539e9b5706f606632102c0f855bcba7c", size = 1716590 }, - { url = "https://files.pythonhosted.org/packages/79/b1/60370d70cdf8b269ee1444b390cbd72ce514f0d1cd1a715821c784d272c9/aiohttp-3.12.15-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6404dfc8cdde35c69aaa489bb3542fb86ef215fc70277c892be8af540e5e21c0", size = 1699241 }, - { url = "https://files.pythonhosted.org/packages/a3/2b/4968a7b8792437ebc12186db31523f541943e99bda8f30335c482bea6879/aiohttp-3.12.15-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3ead1c00f8521a5c9070fcb88f02967b1d8a0544e6d85c253f6968b785e1a2ab", size = 1754335 }, - { url = "https://files.pythonhosted.org/packages/fb/c1/49524ed553f9a0bec1a11fac09e790f49ff669bcd14164f9fab608831c4d/aiohttp-3.12.15-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6990ef617f14450bc6b34941dba4f12d5613cbf4e33805932f853fbd1cf18bfb", size = 1800491 }, - { url = "https://files.pythonhosted.org/packages/de/5e/3bf5acea47a96a28c121b167f5ef659cf71208b19e52a88cdfa5c37f1fcc/aiohttp-3.12.15-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd736ed420f4db2b8148b52b46b88ed038d0354255f9a73196b7bbce3ea97545", size = 1719929 }, - { url = "https://files.pythonhosted.org/packages/39/94/8ae30b806835bcd1cba799ba35347dee6961a11bd507db634516210e91d8/aiohttp-3.12.15-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c5092ce14361a73086b90c6efb3948ffa5be2f5b6fbcf52e8d8c8b8848bb97c", size = 1635733 }, - { url = "https://files.pythonhosted.org/packages/7a/46/06cdef71dd03acd9da7f51ab3a9107318aee12ad38d273f654e4f981583a/aiohttp-3.12.15-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:aaa2234bb60c4dbf82893e934d8ee8dea30446f0647e024074237a56a08c01bd", size = 1696790 }, - { url = "https://files.pythonhosted.org/packages/02/90/6b4cfaaf92ed98d0ec4d173e78b99b4b1a7551250be8937d9d67ecb356b4/aiohttp-3.12.15-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:6d86a2fbdd14192e2f234a92d3b494dd4457e683ba07e5905a0b3ee25389ac9f", size = 1718245 }, - { url = "https://files.pythonhosted.org/packages/2e/e6/2593751670fa06f080a846f37f112cbe6f873ba510d070136a6ed46117c6/aiohttp-3.12.15-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a041e7e2612041a6ddf1c6a33b883be6a421247c7afd47e885969ee4cc58bd8d", size = 1658899 }, - { url = "https://files.pythonhosted.org/packages/8f/28/c15bacbdb8b8eb5bf39b10680d129ea7410b859e379b03190f02fa104ffd/aiohttp-3.12.15-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5015082477abeafad7203757ae44299a610e89ee82a1503e3d4184e6bafdd519", size = 1738459 }, - { url = "https://files.pythonhosted.org/packages/00/de/c269cbc4faa01fb10f143b1670633a8ddd5b2e1ffd0548f7aa49cb5c70e2/aiohttp-3.12.15-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:56822ff5ddfd1b745534e658faba944012346184fbfe732e0d6134b744516eea", size = 1766434 }, - { url = "https://files.pythonhosted.org/packages/52/b0/4ff3abd81aa7d929b27d2e1403722a65fc87b763e3a97b3a2a494bfc63bc/aiohttp-3.12.15-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b2acbbfff69019d9014508c4ba0401822e8bae5a5fdc3b6814285b71231b60f3", size = 1726045 }, - { url = "https://files.pythonhosted.org/packages/71/16/949225a6a2dd6efcbd855fbd90cf476052e648fb011aa538e3b15b89a57a/aiohttp-3.12.15-cp312-cp312-win32.whl", hash = "sha256:d849b0901b50f2185874b9a232f38e26b9b3d4810095a7572eacea939132d4e1", size = 423591 }, - { url = "https://files.pythonhosted.org/packages/2b/d8/fa65d2a349fe938b76d309db1a56a75c4fb8cc7b17a398b698488a939903/aiohttp-3.12.15-cp312-cp312-win_amd64.whl", hash = "sha256:b390ef5f62bb508a9d67cb3bba9b8356e23b3996da7062f1a57ce1a79d2b3d34", size = 450266 }, - { url = "https://files.pythonhosted.org/packages/f2/33/918091abcf102e39d15aba2476ad9e7bd35ddb190dcdd43a854000d3da0d/aiohttp-3.12.15-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:9f922ffd05034d439dde1c77a20461cf4a1b0831e6caa26151fe7aa8aaebc315", size = 696741 }, - { url = "https://files.pythonhosted.org/packages/b5/2a/7495a81e39a998e400f3ecdd44a62107254803d1681d9189be5c2e4530cd/aiohttp-3.12.15-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:2ee8a8ac39ce45f3e55663891d4b1d15598c157b4d494a4613e704c8b43112cd", size = 474407 }, - { url = "https://files.pythonhosted.org/packages/49/fc/a9576ab4be2dcbd0f73ee8675d16c707cfc12d5ee80ccf4015ba543480c9/aiohttp-3.12.15-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3eae49032c29d356b94eee45a3f39fdf4b0814b397638c2f718e96cfadf4c4e4", size = 466703 }, - { url = "https://files.pythonhosted.org/packages/09/2f/d4bcc8448cf536b2b54eed48f19682031ad182faa3a3fee54ebe5b156387/aiohttp-3.12.15-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b97752ff12cc12f46a9b20327104448042fce5c33a624f88c18f66f9368091c7", size = 1705532 }, - { url = "https://files.pythonhosted.org/packages/f1/f3/59406396083f8b489261e3c011aa8aee9df360a96ac8fa5c2e7e1b8f0466/aiohttp-3.12.15-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:894261472691d6fe76ebb7fcf2e5870a2ac284c7406ddc95823c8598a1390f0d", size = 1686794 }, - { url = "https://files.pythonhosted.org/packages/dc/71/164d194993a8d114ee5656c3b7ae9c12ceee7040d076bf7b32fb98a8c5c6/aiohttp-3.12.15-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5fa5d9eb82ce98959fc1031c28198b431b4d9396894f385cb63f1e2f3f20ca6b", size = 1738865 }, - { url = "https://files.pythonhosted.org/packages/1c/00/d198461b699188a93ead39cb458554d9f0f69879b95078dce416d3209b54/aiohttp-3.12.15-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f0fa751efb11a541f57db59c1dd821bec09031e01452b2b6217319b3a1f34f3d", size = 1788238 }, - { url = "https://files.pythonhosted.org/packages/85/b8/9e7175e1fa0ac8e56baa83bf3c214823ce250d0028955dfb23f43d5e61fd/aiohttp-3.12.15-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5346b93e62ab51ee2a9d68e8f73c7cf96ffb73568a23e683f931e52450e4148d", size = 1710566 }, - { url = "https://files.pythonhosted.org/packages/59/e4/16a8eac9df39b48ae102ec030fa9f726d3570732e46ba0c592aeeb507b93/aiohttp-3.12.15-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:049ec0360f939cd164ecbfd2873eaa432613d5e77d6b04535e3d1fbae5a9e645", size = 1624270 }, - { url = "https://files.pythonhosted.org/packages/1f/f8/cd84dee7b6ace0740908fd0af170f9fab50c2a41ccbc3806aabcb1050141/aiohttp-3.12.15-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b52dcf013b57464b6d1e51b627adfd69a8053e84b7103a7cd49c030f9ca44461", size = 1677294 }, - { url = "https://files.pythonhosted.org/packages/ce/42/d0f1f85e50d401eccd12bf85c46ba84f947a84839c8a1c2c5f6e8ab1eb50/aiohttp-3.12.15-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:9b2af240143dd2765e0fb661fd0361a1b469cab235039ea57663cda087250ea9", size = 1708958 }, - { url = "https://files.pythonhosted.org/packages/d5/6b/f6fa6c5790fb602538483aa5a1b86fcbad66244997e5230d88f9412ef24c/aiohttp-3.12.15-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ac77f709a2cde2cc71257ab2d8c74dd157c67a0558a0d2799d5d571b4c63d44d", size = 1651553 }, - { url = "https://files.pythonhosted.org/packages/04/36/a6d36ad545fa12e61d11d1932eef273928b0495e6a576eb2af04297fdd3c/aiohttp-3.12.15-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:47f6b962246f0a774fbd3b6b7be25d59b06fdb2f164cf2513097998fc6a29693", size = 1727688 }, - { url = "https://files.pythonhosted.org/packages/aa/c8/f195e5e06608a97a4e52c5d41c7927301bf757a8e8bb5bbf8cef6c314961/aiohttp-3.12.15-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:760fb7db442f284996e39cf9915a94492e1896baac44f06ae551974907922b64", size = 1761157 }, - { url = "https://files.pythonhosted.org/packages/05/6a/ea199e61b67f25ba688d3ce93f63b49b0a4e3b3d380f03971b4646412fc6/aiohttp-3.12.15-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ad702e57dc385cae679c39d318def49aef754455f237499d5b99bea4ef582e51", size = 1710050 }, - { url = "https://files.pythonhosted.org/packages/b4/2e/ffeb7f6256b33635c29dbed29a22a723ff2dd7401fff42ea60cf2060abfb/aiohttp-3.12.15-cp313-cp313-win32.whl", hash = "sha256:f813c3e9032331024de2eb2e32a88d86afb69291fbc37a3a3ae81cc9917fb3d0", size = 422647 }, - { url = "https://files.pythonhosted.org/packages/1b/8e/78ee35774201f38d5e1ba079c9958f7629b1fd079459aea9467441dbfbf5/aiohttp-3.12.15-cp313-cp313-win_amd64.whl", hash = "sha256:1a649001580bdb37c6fdb1bebbd7e3bc688e8ec2b5c6f52edbb664662b17dc84", size = 449067 }, +sdist = { url = "https://files.pythonhosted.org/packages/9b/e7/d92a237d8802ca88483906c388f7c201bbe96cd80a165ffd0ac2f6a8d59f/aiohttp-3.12.15.tar.gz", hash = "sha256:4fc61385e9c98d72fcdf47e6dd81833f47b2f77c114c29cd64a361be57a763a2", size = 7823716, upload-time = "2025-07-29T05:52:32.215Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/63/97/77cb2450d9b35f517d6cf506256bf4f5bda3f93a66b4ad64ba7fc917899c/aiohttp-3.12.15-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:802d3868f5776e28f7bf69d349c26fc0efadb81676d0afa88ed00d98a26340b7", size = 702333, upload-time = "2025-07-29T05:50:46.507Z" }, + { url = "https://files.pythonhosted.org/packages/83/6d/0544e6b08b748682c30b9f65640d006e51f90763b41d7c546693bc22900d/aiohttp-3.12.15-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f2800614cd560287be05e33a679638e586a2d7401f4ddf99e304d98878c29444", size = 476948, upload-time = "2025-07-29T05:50:48.067Z" }, + { url = "https://files.pythonhosted.org/packages/3a/1d/c8c40e611e5094330284b1aea8a4b02ca0858f8458614fa35754cab42b9c/aiohttp-3.12.15-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8466151554b593909d30a0a125d638b4e5f3836e5aecde85b66b80ded1cb5b0d", size = 469787, upload-time = "2025-07-29T05:50:49.669Z" }, + { url = "https://files.pythonhosted.org/packages/38/7d/b76438e70319796bfff717f325d97ce2e9310f752a267bfdf5192ac6082b/aiohttp-3.12.15-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e5a495cb1be69dae4b08f35a6c4579c539e9b5706f606632102c0f855bcba7c", size = 1716590, upload-time = "2025-07-29T05:50:51.368Z" }, + { url = "https://files.pythonhosted.org/packages/79/b1/60370d70cdf8b269ee1444b390cbd72ce514f0d1cd1a715821c784d272c9/aiohttp-3.12.15-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6404dfc8cdde35c69aaa489bb3542fb86ef215fc70277c892be8af540e5e21c0", size = 1699241, upload-time = "2025-07-29T05:50:53.628Z" }, + { url = "https://files.pythonhosted.org/packages/a3/2b/4968a7b8792437ebc12186db31523f541943e99bda8f30335c482bea6879/aiohttp-3.12.15-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3ead1c00f8521a5c9070fcb88f02967b1d8a0544e6d85c253f6968b785e1a2ab", size = 1754335, upload-time = "2025-07-29T05:50:55.394Z" }, + { url = "https://files.pythonhosted.org/packages/fb/c1/49524ed553f9a0bec1a11fac09e790f49ff669bcd14164f9fab608831c4d/aiohttp-3.12.15-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6990ef617f14450bc6b34941dba4f12d5613cbf4e33805932f853fbd1cf18bfb", size = 1800491, upload-time = "2025-07-29T05:50:57.202Z" }, + { url = "https://files.pythonhosted.org/packages/de/5e/3bf5acea47a96a28c121b167f5ef659cf71208b19e52a88cdfa5c37f1fcc/aiohttp-3.12.15-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd736ed420f4db2b8148b52b46b88ed038d0354255f9a73196b7bbce3ea97545", size = 1719929, upload-time = "2025-07-29T05:50:59.192Z" }, + { url = "https://files.pythonhosted.org/packages/39/94/8ae30b806835bcd1cba799ba35347dee6961a11bd507db634516210e91d8/aiohttp-3.12.15-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c5092ce14361a73086b90c6efb3948ffa5be2f5b6fbcf52e8d8c8b8848bb97c", size = 1635733, upload-time = "2025-07-29T05:51:01.394Z" }, + { url = "https://files.pythonhosted.org/packages/7a/46/06cdef71dd03acd9da7f51ab3a9107318aee12ad38d273f654e4f981583a/aiohttp-3.12.15-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:aaa2234bb60c4dbf82893e934d8ee8dea30446f0647e024074237a56a08c01bd", size = 1696790, upload-time = "2025-07-29T05:51:03.657Z" }, + { url = "https://files.pythonhosted.org/packages/02/90/6b4cfaaf92ed98d0ec4d173e78b99b4b1a7551250be8937d9d67ecb356b4/aiohttp-3.12.15-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:6d86a2fbdd14192e2f234a92d3b494dd4457e683ba07e5905a0b3ee25389ac9f", size = 1718245, upload-time = "2025-07-29T05:51:05.911Z" }, + { url = "https://files.pythonhosted.org/packages/2e/e6/2593751670fa06f080a846f37f112cbe6f873ba510d070136a6ed46117c6/aiohttp-3.12.15-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a041e7e2612041a6ddf1c6a33b883be6a421247c7afd47e885969ee4cc58bd8d", size = 1658899, upload-time = "2025-07-29T05:51:07.753Z" }, + { url = "https://files.pythonhosted.org/packages/8f/28/c15bacbdb8b8eb5bf39b10680d129ea7410b859e379b03190f02fa104ffd/aiohttp-3.12.15-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5015082477abeafad7203757ae44299a610e89ee82a1503e3d4184e6bafdd519", size = 1738459, upload-time = "2025-07-29T05:51:09.56Z" }, + { url = "https://files.pythonhosted.org/packages/00/de/c269cbc4faa01fb10f143b1670633a8ddd5b2e1ffd0548f7aa49cb5c70e2/aiohttp-3.12.15-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:56822ff5ddfd1b745534e658faba944012346184fbfe732e0d6134b744516eea", size = 1766434, upload-time = "2025-07-29T05:51:11.423Z" }, + { url = "https://files.pythonhosted.org/packages/52/b0/4ff3abd81aa7d929b27d2e1403722a65fc87b763e3a97b3a2a494bfc63bc/aiohttp-3.12.15-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b2acbbfff69019d9014508c4ba0401822e8bae5a5fdc3b6814285b71231b60f3", size = 1726045, upload-time = "2025-07-29T05:51:13.689Z" }, + { url = "https://files.pythonhosted.org/packages/71/16/949225a6a2dd6efcbd855fbd90cf476052e648fb011aa538e3b15b89a57a/aiohttp-3.12.15-cp312-cp312-win32.whl", hash = "sha256:d849b0901b50f2185874b9a232f38e26b9b3d4810095a7572eacea939132d4e1", size = 423591, upload-time = "2025-07-29T05:51:15.452Z" }, + { url = "https://files.pythonhosted.org/packages/2b/d8/fa65d2a349fe938b76d309db1a56a75c4fb8cc7b17a398b698488a939903/aiohttp-3.12.15-cp312-cp312-win_amd64.whl", hash = "sha256:b390ef5f62bb508a9d67cb3bba9b8356e23b3996da7062f1a57ce1a79d2b3d34", size = 450266, upload-time = "2025-07-29T05:51:17.239Z" }, + { url = "https://files.pythonhosted.org/packages/f2/33/918091abcf102e39d15aba2476ad9e7bd35ddb190dcdd43a854000d3da0d/aiohttp-3.12.15-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:9f922ffd05034d439dde1c77a20461cf4a1b0831e6caa26151fe7aa8aaebc315", size = 696741, upload-time = "2025-07-29T05:51:19.021Z" }, + { url = "https://files.pythonhosted.org/packages/b5/2a/7495a81e39a998e400f3ecdd44a62107254803d1681d9189be5c2e4530cd/aiohttp-3.12.15-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:2ee8a8ac39ce45f3e55663891d4b1d15598c157b4d494a4613e704c8b43112cd", size = 474407, upload-time = "2025-07-29T05:51:21.165Z" }, + { url = "https://files.pythonhosted.org/packages/49/fc/a9576ab4be2dcbd0f73ee8675d16c707cfc12d5ee80ccf4015ba543480c9/aiohttp-3.12.15-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3eae49032c29d356b94eee45a3f39fdf4b0814b397638c2f718e96cfadf4c4e4", size = 466703, upload-time = "2025-07-29T05:51:22.948Z" }, + { url = "https://files.pythonhosted.org/packages/09/2f/d4bcc8448cf536b2b54eed48f19682031ad182faa3a3fee54ebe5b156387/aiohttp-3.12.15-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b97752ff12cc12f46a9b20327104448042fce5c33a624f88c18f66f9368091c7", size = 1705532, upload-time = "2025-07-29T05:51:25.211Z" }, + { url = "https://files.pythonhosted.org/packages/f1/f3/59406396083f8b489261e3c011aa8aee9df360a96ac8fa5c2e7e1b8f0466/aiohttp-3.12.15-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:894261472691d6fe76ebb7fcf2e5870a2ac284c7406ddc95823c8598a1390f0d", size = 1686794, upload-time = "2025-07-29T05:51:27.145Z" }, + { url = "https://files.pythonhosted.org/packages/dc/71/164d194993a8d114ee5656c3b7ae9c12ceee7040d076bf7b32fb98a8c5c6/aiohttp-3.12.15-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5fa5d9eb82ce98959fc1031c28198b431b4d9396894f385cb63f1e2f3f20ca6b", size = 1738865, upload-time = "2025-07-29T05:51:29.366Z" }, + { url = "https://files.pythonhosted.org/packages/1c/00/d198461b699188a93ead39cb458554d9f0f69879b95078dce416d3209b54/aiohttp-3.12.15-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f0fa751efb11a541f57db59c1dd821bec09031e01452b2b6217319b3a1f34f3d", size = 1788238, upload-time = "2025-07-29T05:51:31.285Z" }, + { url = "https://files.pythonhosted.org/packages/85/b8/9e7175e1fa0ac8e56baa83bf3c214823ce250d0028955dfb23f43d5e61fd/aiohttp-3.12.15-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5346b93e62ab51ee2a9d68e8f73c7cf96ffb73568a23e683f931e52450e4148d", size = 1710566, upload-time = "2025-07-29T05:51:33.219Z" }, + { url = "https://files.pythonhosted.org/packages/59/e4/16a8eac9df39b48ae102ec030fa9f726d3570732e46ba0c592aeeb507b93/aiohttp-3.12.15-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:049ec0360f939cd164ecbfd2873eaa432613d5e77d6b04535e3d1fbae5a9e645", size = 1624270, upload-time = "2025-07-29T05:51:35.195Z" }, + { url = "https://files.pythonhosted.org/packages/1f/f8/cd84dee7b6ace0740908fd0af170f9fab50c2a41ccbc3806aabcb1050141/aiohttp-3.12.15-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b52dcf013b57464b6d1e51b627adfd69a8053e84b7103a7cd49c030f9ca44461", size = 1677294, upload-time = "2025-07-29T05:51:37.215Z" }, + { url = "https://files.pythonhosted.org/packages/ce/42/d0f1f85e50d401eccd12bf85c46ba84f947a84839c8a1c2c5f6e8ab1eb50/aiohttp-3.12.15-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:9b2af240143dd2765e0fb661fd0361a1b469cab235039ea57663cda087250ea9", size = 1708958, upload-time = "2025-07-29T05:51:39.328Z" }, + { url = "https://files.pythonhosted.org/packages/d5/6b/f6fa6c5790fb602538483aa5a1b86fcbad66244997e5230d88f9412ef24c/aiohttp-3.12.15-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ac77f709a2cde2cc71257ab2d8c74dd157c67a0558a0d2799d5d571b4c63d44d", size = 1651553, upload-time = "2025-07-29T05:51:41.356Z" }, + { url = "https://files.pythonhosted.org/packages/04/36/a6d36ad545fa12e61d11d1932eef273928b0495e6a576eb2af04297fdd3c/aiohttp-3.12.15-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:47f6b962246f0a774fbd3b6b7be25d59b06fdb2f164cf2513097998fc6a29693", size = 1727688, upload-time = "2025-07-29T05:51:43.452Z" }, + { url = "https://files.pythonhosted.org/packages/aa/c8/f195e5e06608a97a4e52c5d41c7927301bf757a8e8bb5bbf8cef6c314961/aiohttp-3.12.15-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:760fb7db442f284996e39cf9915a94492e1896baac44f06ae551974907922b64", size = 1761157, upload-time = "2025-07-29T05:51:45.643Z" }, + { url = "https://files.pythonhosted.org/packages/05/6a/ea199e61b67f25ba688d3ce93f63b49b0a4e3b3d380f03971b4646412fc6/aiohttp-3.12.15-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ad702e57dc385cae679c39d318def49aef754455f237499d5b99bea4ef582e51", size = 1710050, upload-time = "2025-07-29T05:51:48.203Z" }, + { url = "https://files.pythonhosted.org/packages/b4/2e/ffeb7f6256b33635c29dbed29a22a723ff2dd7401fff42ea60cf2060abfb/aiohttp-3.12.15-cp313-cp313-win32.whl", hash = "sha256:f813c3e9032331024de2eb2e32a88d86afb69291fbc37a3a3ae81cc9917fb3d0", size = 422647, upload-time = "2025-07-29T05:51:50.718Z" }, + { url = "https://files.pythonhosted.org/packages/1b/8e/78ee35774201f38d5e1ba079c9958f7629b1fd079459aea9467441dbfbf5/aiohttp-3.12.15-cp313-cp313-win_amd64.whl", hash = "sha256:1a649001580bdb37c6fdb1bebbd7e3bc688e8ec2b5c6f52edbb664662b17dc84", size = 449067, upload-time = "2025-07-29T05:51:52.549Z" }, ] [[package]] @@ -74,9 +74,9 @@ dependencies = [ { name = "frozenlist" }, { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/61/62/06741b579156360248d1ec624842ad0edf697050bbaf7c3e46394e106ad1/aiosignal-1.4.0.tar.gz", hash = "sha256:f47eecd9468083c2029cc99945502cb7708b082c232f9aca65da147157b251c7", size = 25007 } +sdist = { url = "https://files.pythonhosted.org/packages/61/62/06741b579156360248d1ec624842ad0edf697050bbaf7c3e46394e106ad1/aiosignal-1.4.0.tar.gz", hash = "sha256:f47eecd9468083c2029cc99945502cb7708b082c232f9aca65da147157b251c7", size = 25007, upload-time = "2025-07-03T22:54:43.528Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl", hash = "sha256:053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e", size = 7490 }, + { url = "https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl", hash = "sha256:053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e", size = 7490, upload-time = "2025-07-03T22:54:42.156Z" }, ] [[package]] @@ -86,36 +86,36 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/13/7d/8bca2bf9a247c2c5dfeec1d7a5f40db6518f88d314b8bca9da29670d2671/aiosqlite-0.21.0.tar.gz", hash = "sha256:131bb8056daa3bc875608c631c678cda73922a2d4ba8aec373b19f18c17e7aa3", size = 13454 } +sdist = { url = "https://files.pythonhosted.org/packages/13/7d/8bca2bf9a247c2c5dfeec1d7a5f40db6518f88d314b8bca9da29670d2671/aiosqlite-0.21.0.tar.gz", hash = "sha256:131bb8056daa3bc875608c631c678cda73922a2d4ba8aec373b19f18c17e7aa3", size = 13454, upload-time = "2025-02-03T07:30:16.235Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f5/10/6c25ed6de94c49f88a91fa5018cb4c0f3625f31d5be9f771ebe5cc7cd506/aiosqlite-0.21.0-py3-none-any.whl", hash = "sha256:2549cf4057f95f53dcba16f2b64e8e2791d7e1adedb13197dd8ed77bb226d7d0", size = 15792 }, + { url = "https://files.pythonhosted.org/packages/f5/10/6c25ed6de94c49f88a91fa5018cb4c0f3625f31d5be9f771ebe5cc7cd506/aiosqlite-0.21.0-py3-none-any.whl", hash = "sha256:2549cf4057f95f53dcba16f2b64e8e2791d7e1adedb13197dd8ed77bb226d7d0", size = 15792, upload-time = "2025-02-03T07:30:13.6Z" }, ] [[package]] name = "astroid" version = "3.3.11" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/18/74/dfb75f9ccd592bbedb175d4a32fc643cf569d7c218508bfbd6ea7ef9c091/astroid-3.3.11.tar.gz", hash = "sha256:1e5a5011af2920c7c67a53f65d536d65bfa7116feeaf2354d8b94f29573bb0ce", size = 400439 } +sdist = { url = "https://files.pythonhosted.org/packages/18/74/dfb75f9ccd592bbedb175d4a32fc643cf569d7c218508bfbd6ea7ef9c091/astroid-3.3.11.tar.gz", hash = "sha256:1e5a5011af2920c7c67a53f65d536d65bfa7116feeaf2354d8b94f29573bb0ce", size = 400439, upload-time = "2025-07-13T18:04:23.177Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/af/0f/3b8fdc946b4d9cc8cc1e8af42c4e409468c84441b933d037e101b3d72d86/astroid-3.3.11-py3-none-any.whl", hash = "sha256:54c760ae8322ece1abd213057c4b5bba7c49818853fc901ef09719a60dbf9dec", size = 275612 }, + { url = "https://files.pythonhosted.org/packages/af/0f/3b8fdc946b4d9cc8cc1e8af42c4e409468c84441b933d037e101b3d72d86/astroid-3.3.11-py3-none-any.whl", hash = "sha256:54c760ae8322ece1abd213057c4b5bba7c49818853fc901ef09719a60dbf9dec", size = 275612, upload-time = "2025-07-13T18:04:21.07Z" }, ] [[package]] name = "attrs" version = "25.3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/5a/b0/1367933a8532ee6ff8d63537de4f1177af4bff9f3e829baf7331f595bb24/attrs-25.3.0.tar.gz", hash = "sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b", size = 812032 } +sdist = { url = "https://files.pythonhosted.org/packages/5a/b0/1367933a8532ee6ff8d63537de4f1177af4bff9f3e829baf7331f595bb24/attrs-25.3.0.tar.gz", hash = "sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b", size = 812032, upload-time = "2025-03-13T11:10:22.779Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/77/06/bb80f5f86020c4551da315d78b3ab75e8228f89f0162f2c3a819e407941a/attrs-25.3.0-py3-none-any.whl", hash = "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3", size = 63815 }, + { url = "https://files.pythonhosted.org/packages/77/06/bb80f5f86020c4551da315d78b3ab75e8228f89f0162f2c3a819e407941a/attrs-25.3.0-py3-none-any.whl", hash = "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3", size = 63815, upload-time = "2025-03-13T11:10:21.14Z" }, ] [[package]] name = "certifi" version = "2025.8.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/dc/67/960ebe6bf230a96cda2e0abcf73af550ec4f090005363542f0765df162e0/certifi-2025.8.3.tar.gz", hash = "sha256:e564105f78ded564e3ae7c923924435e1daa7463faeab5bb932bc53ffae63407", size = 162386 } +sdist = { url = "https://files.pythonhosted.org/packages/dc/67/960ebe6bf230a96cda2e0abcf73af550ec4f090005363542f0765df162e0/certifi-2025.8.3.tar.gz", hash = "sha256:e564105f78ded564e3ae7c923924435e1daa7463faeab5bb932bc53ffae63407", size = 162386, upload-time = "2025-08-03T03:07:47.08Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e5/48/1549795ba7742c948d2ad169c1c8cdbae65bc450d6cd753d124b17c8cd32/certifi-2025.8.3-py3-none-any.whl", hash = "sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5", size = 161216 }, + { url = "https://files.pythonhosted.org/packages/e5/48/1549795ba7742c948d2ad169c1c8cdbae65bc450d6cd753d124b17c8cd32/certifi-2025.8.3-py3-none-any.whl", hash = "sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5", size = 161216, upload-time = "2025-08-03T03:07:45.777Z" }, ] [[package]] @@ -125,74 +125,74 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pycparser" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fc/97/c783634659c2920c3fc70419e3af40972dbaf758daa229a7d6ea6135c90d/cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", size = 516621 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5a/84/e94227139ee5fb4d600a7a4927f322e1d4aea6fdc50bd3fca8493caba23f/cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4", size = 183178 }, - { url = "https://files.pythonhosted.org/packages/da/ee/fb72c2b48656111c4ef27f0f91da355e130a923473bf5ee75c5643d00cca/cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c", size = 178840 }, - { url = "https://files.pythonhosted.org/packages/cc/b6/db007700f67d151abadf508cbfd6a1884f57eab90b1bb985c4c8c02b0f28/cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36", size = 454803 }, - { url = "https://files.pythonhosted.org/packages/1a/df/f8d151540d8c200eb1c6fba8cd0dfd40904f1b0682ea705c36e6c2e97ab3/cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5", size = 478850 }, - { url = "https://files.pythonhosted.org/packages/28/c0/b31116332a547fd2677ae5b78a2ef662dfc8023d67f41b2a83f7c2aa78b1/cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff", size = 485729 }, - { url = "https://files.pythonhosted.org/packages/91/2b/9a1ddfa5c7f13cab007a2c9cc295b70fbbda7cb10a286aa6810338e60ea1/cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99", size = 471256 }, - { url = "https://files.pythonhosted.org/packages/b2/d5/da47df7004cb17e4955df6a43d14b3b4ae77737dff8bf7f8f333196717bf/cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93", size = 479424 }, - { url = "https://files.pythonhosted.org/packages/0b/ac/2a28bcf513e93a219c8a4e8e125534f4f6db03e3179ba1c45e949b76212c/cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3", size = 484568 }, - { url = "https://files.pythonhosted.org/packages/d4/38/ca8a4f639065f14ae0f1d9751e70447a261f1a30fa7547a828ae08142465/cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8", size = 488736 }, - { url = "https://files.pythonhosted.org/packages/86/c5/28b2d6f799ec0bdecf44dced2ec5ed43e0eb63097b0f58c293583b406582/cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65", size = 172448 }, - { url = "https://files.pythonhosted.org/packages/50/b9/db34c4755a7bd1cb2d1603ac3863f22bcecbd1ba29e5ee841a4bc510b294/cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903", size = 181976 }, - { url = "https://files.pythonhosted.org/packages/8d/f8/dd6c246b148639254dad4d6803eb6a54e8c85c6e11ec9df2cffa87571dbe/cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e", size = 182989 }, - { url = "https://files.pythonhosted.org/packages/8b/f1/672d303ddf17c24fc83afd712316fda78dc6fce1cd53011b839483e1ecc8/cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2", size = 178802 }, - { url = "https://files.pythonhosted.org/packages/0e/2d/eab2e858a91fdff70533cab61dcff4a1f55ec60425832ddfdc9cd36bc8af/cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3", size = 454792 }, - { url = "https://files.pythonhosted.org/packages/75/b2/fbaec7c4455c604e29388d55599b99ebcc250a60050610fadde58932b7ee/cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683", size = 478893 }, - { url = "https://files.pythonhosted.org/packages/4f/b7/6e4a2162178bf1935c336d4da8a9352cccab4d3a5d7914065490f08c0690/cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5", size = 485810 }, - { url = "https://files.pythonhosted.org/packages/c7/8a/1d0e4a9c26e54746dc08c2c6c037889124d4f59dffd853a659fa545f1b40/cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4", size = 471200 }, - { url = "https://files.pythonhosted.org/packages/26/9f/1aab65a6c0db35f43c4d1b4f580e8df53914310afc10ae0397d29d697af4/cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd", size = 479447 }, - { url = "https://files.pythonhosted.org/packages/5f/e4/fb8b3dd8dc0e98edf1135ff067ae070bb32ef9d509d6cb0f538cd6f7483f/cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed", size = 484358 }, - { url = "https://files.pythonhosted.org/packages/f1/47/d7145bf2dc04684935d57d67dff9d6d795b2ba2796806bb109864be3a151/cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9", size = 488469 }, - { url = "https://files.pythonhosted.org/packages/bf/ee/f94057fa6426481d663b88637a9a10e859e492c73d0384514a17d78ee205/cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d", size = 172475 }, - { url = "https://files.pythonhosted.org/packages/7c/fc/6a8cb64e5f0324877d503c854da15d76c1e50eb722e320b15345c4d0c6de/cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a", size = 182009 }, +sdist = { url = "https://files.pythonhosted.org/packages/fc/97/c783634659c2920c3fc70419e3af40972dbaf758daa229a7d6ea6135c90d/cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", size = 516621, upload-time = "2024-09-04T20:45:21.852Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5a/84/e94227139ee5fb4d600a7a4927f322e1d4aea6fdc50bd3fca8493caba23f/cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4", size = 183178, upload-time = "2024-09-04T20:44:12.232Z" }, + { url = "https://files.pythonhosted.org/packages/da/ee/fb72c2b48656111c4ef27f0f91da355e130a923473bf5ee75c5643d00cca/cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c", size = 178840, upload-time = "2024-09-04T20:44:13.739Z" }, + { url = "https://files.pythonhosted.org/packages/cc/b6/db007700f67d151abadf508cbfd6a1884f57eab90b1bb985c4c8c02b0f28/cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36", size = 454803, upload-time = "2024-09-04T20:44:15.231Z" }, + { url = "https://files.pythonhosted.org/packages/1a/df/f8d151540d8c200eb1c6fba8cd0dfd40904f1b0682ea705c36e6c2e97ab3/cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5", size = 478850, upload-time = "2024-09-04T20:44:17.188Z" }, + { url = "https://files.pythonhosted.org/packages/28/c0/b31116332a547fd2677ae5b78a2ef662dfc8023d67f41b2a83f7c2aa78b1/cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff", size = 485729, upload-time = "2024-09-04T20:44:18.688Z" }, + { url = "https://files.pythonhosted.org/packages/91/2b/9a1ddfa5c7f13cab007a2c9cc295b70fbbda7cb10a286aa6810338e60ea1/cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99", size = 471256, upload-time = "2024-09-04T20:44:20.248Z" }, + { url = "https://files.pythonhosted.org/packages/b2/d5/da47df7004cb17e4955df6a43d14b3b4ae77737dff8bf7f8f333196717bf/cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93", size = 479424, upload-time = "2024-09-04T20:44:21.673Z" }, + { url = "https://files.pythonhosted.org/packages/0b/ac/2a28bcf513e93a219c8a4e8e125534f4f6db03e3179ba1c45e949b76212c/cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3", size = 484568, upload-time = "2024-09-04T20:44:23.245Z" }, + { url = "https://files.pythonhosted.org/packages/d4/38/ca8a4f639065f14ae0f1d9751e70447a261f1a30fa7547a828ae08142465/cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8", size = 488736, upload-time = "2024-09-04T20:44:24.757Z" }, + { url = "https://files.pythonhosted.org/packages/86/c5/28b2d6f799ec0bdecf44dced2ec5ed43e0eb63097b0f58c293583b406582/cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65", size = 172448, upload-time = "2024-09-04T20:44:26.208Z" }, + { url = "https://files.pythonhosted.org/packages/50/b9/db34c4755a7bd1cb2d1603ac3863f22bcecbd1ba29e5ee841a4bc510b294/cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903", size = 181976, upload-time = "2024-09-04T20:44:27.578Z" }, + { url = "https://files.pythonhosted.org/packages/8d/f8/dd6c246b148639254dad4d6803eb6a54e8c85c6e11ec9df2cffa87571dbe/cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e", size = 182989, upload-time = "2024-09-04T20:44:28.956Z" }, + { url = "https://files.pythonhosted.org/packages/8b/f1/672d303ddf17c24fc83afd712316fda78dc6fce1cd53011b839483e1ecc8/cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2", size = 178802, upload-time = "2024-09-04T20:44:30.289Z" }, + { url = "https://files.pythonhosted.org/packages/0e/2d/eab2e858a91fdff70533cab61dcff4a1f55ec60425832ddfdc9cd36bc8af/cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3", size = 454792, upload-time = "2024-09-04T20:44:32.01Z" }, + { url = "https://files.pythonhosted.org/packages/75/b2/fbaec7c4455c604e29388d55599b99ebcc250a60050610fadde58932b7ee/cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683", size = 478893, upload-time = "2024-09-04T20:44:33.606Z" }, + { url = "https://files.pythonhosted.org/packages/4f/b7/6e4a2162178bf1935c336d4da8a9352cccab4d3a5d7914065490f08c0690/cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5", size = 485810, upload-time = "2024-09-04T20:44:35.191Z" }, + { url = "https://files.pythonhosted.org/packages/c7/8a/1d0e4a9c26e54746dc08c2c6c037889124d4f59dffd853a659fa545f1b40/cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4", size = 471200, upload-time = "2024-09-04T20:44:36.743Z" }, + { url = "https://files.pythonhosted.org/packages/26/9f/1aab65a6c0db35f43c4d1b4f580e8df53914310afc10ae0397d29d697af4/cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd", size = 479447, upload-time = "2024-09-04T20:44:38.492Z" }, + { url = "https://files.pythonhosted.org/packages/5f/e4/fb8b3dd8dc0e98edf1135ff067ae070bb32ef9d509d6cb0f538cd6f7483f/cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed", size = 484358, upload-time = "2024-09-04T20:44:40.046Z" }, + { url = "https://files.pythonhosted.org/packages/f1/47/d7145bf2dc04684935d57d67dff9d6d795b2ba2796806bb109864be3a151/cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9", size = 488469, upload-time = "2024-09-04T20:44:41.616Z" }, + { url = "https://files.pythonhosted.org/packages/bf/ee/f94057fa6426481d663b88637a9a10e859e492c73d0384514a17d78ee205/cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d", size = 172475, upload-time = "2024-09-04T20:44:43.733Z" }, + { url = "https://files.pythonhosted.org/packages/7c/fc/6a8cb64e5f0324877d503c854da15d76c1e50eb722e320b15345c4d0c6de/cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a", size = 182009, upload-time = "2024-09-04T20:44:45.309Z" }, ] [[package]] name = "cfgv" version = "3.4.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/11/74/539e56497d9bd1d484fd863dd69cbbfa653cd2aa27abfe35653494d85e94/cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560", size = 7114 } +sdist = { url = "https://files.pythonhosted.org/packages/11/74/539e56497d9bd1d484fd863dd69cbbfa653cd2aa27abfe35653494d85e94/cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560", size = 7114, upload-time = "2023-08-12T20:38:17.776Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c5/55/51844dd50c4fc7a33b653bfaba4c2456f06955289ca770a5dbd5fd267374/cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9", size = 7249 }, + { url = "https://files.pythonhosted.org/packages/c5/55/51844dd50c4fc7a33b653bfaba4c2456f06955289ca770a5dbd5fd267374/cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9", size = 7249, upload-time = "2023-08-12T20:38:16.269Z" }, ] [[package]] name = "charset-normalizer" version = "3.4.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e4/33/89c2ced2b67d1c2a61c19c6751aa8902d46ce3dacb23600a283619f5a12d/charset_normalizer-3.4.2.tar.gz", hash = "sha256:5baececa9ecba31eff645232d59845c07aa030f0c81ee70184a90d35099a0e63", size = 126367 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d7/a4/37f4d6035c89cac7930395a35cc0f1b872e652eaafb76a6075943754f095/charset_normalizer-3.4.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0c29de6a1a95f24b9a1aa7aefd27d2487263f00dfd55a77719b530788f75cff7", size = 199936 }, - { url = "https://files.pythonhosted.org/packages/ee/8a/1a5e33b73e0d9287274f899d967907cd0bf9c343e651755d9307e0dbf2b3/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cddf7bd982eaa998934a91f69d182aec997c6c468898efe6679af88283b498d3", size = 143790 }, - { url = "https://files.pythonhosted.org/packages/66/52/59521f1d8e6ab1482164fa21409c5ef44da3e9f653c13ba71becdd98dec3/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcbe676a55d7445b22c10967bceaaf0ee69407fbe0ece4d032b6eb8d4565982a", size = 153924 }, - { url = "https://files.pythonhosted.org/packages/86/2d/fb55fdf41964ec782febbf33cb64be480a6b8f16ded2dbe8db27a405c09f/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d41c4d287cfc69060fa91cae9683eacffad989f1a10811995fa309df656ec214", size = 146626 }, - { url = "https://files.pythonhosted.org/packages/8c/73/6ede2ec59bce19b3edf4209d70004253ec5f4e319f9a2e3f2f15601ed5f7/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e594135de17ab3866138f496755f302b72157d115086d100c3f19370839dd3a", size = 148567 }, - { url = "https://files.pythonhosted.org/packages/09/14/957d03c6dc343c04904530b6bef4e5efae5ec7d7990a7cbb868e4595ee30/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cf713fe9a71ef6fd5adf7a79670135081cd4431c2943864757f0fa3a65b1fafd", size = 150957 }, - { url = "https://files.pythonhosted.org/packages/0d/c8/8174d0e5c10ccebdcb1b53cc959591c4c722a3ad92461a273e86b9f5a302/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a370b3e078e418187da8c3674eddb9d983ec09445c99a3a263c2011993522981", size = 145408 }, - { url = "https://files.pythonhosted.org/packages/58/aa/8904b84bc8084ac19dc52feb4f5952c6df03ffb460a887b42615ee1382e8/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a955b438e62efdf7e0b7b52a64dc5c3396e2634baa62471768a64bc2adb73d5c", size = 153399 }, - { url = "https://files.pythonhosted.org/packages/c2/26/89ee1f0e264d201cb65cf054aca6038c03b1a0c6b4ae998070392a3ce605/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:7222ffd5e4de8e57e03ce2cef95a4c43c98fcb72ad86909abdfc2c17d227fc1b", size = 156815 }, - { url = "https://files.pythonhosted.org/packages/fd/07/68e95b4b345bad3dbbd3a8681737b4338ff2c9df29856a6d6d23ac4c73cb/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:bee093bf902e1d8fc0ac143c88902c3dfc8941f7ea1d6a8dd2bcb786d33db03d", size = 154537 }, - { url = "https://files.pythonhosted.org/packages/77/1a/5eefc0ce04affb98af07bc05f3bac9094513c0e23b0562d64af46a06aae4/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dedb8adb91d11846ee08bec4c8236c8549ac721c245678282dcb06b221aab59f", size = 149565 }, - { url = "https://files.pythonhosted.org/packages/37/a0/2410e5e6032a174c95e0806b1a6585eb21e12f445ebe239fac441995226a/charset_normalizer-3.4.2-cp312-cp312-win32.whl", hash = "sha256:db4c7bf0e07fc3b7d89ac2a5880a6a8062056801b83ff56d8464b70f65482b6c", size = 98357 }, - { url = "https://files.pythonhosted.org/packages/6c/4f/c02d5c493967af3eda9c771ad4d2bbc8df6f99ddbeb37ceea6e8716a32bc/charset_normalizer-3.4.2-cp312-cp312-win_amd64.whl", hash = "sha256:5a9979887252a82fefd3d3ed2a8e3b937a7a809f65dcb1e068b090e165bbe99e", size = 105776 }, - { url = "https://files.pythonhosted.org/packages/ea/12/a93df3366ed32db1d907d7593a94f1fe6293903e3e92967bebd6950ed12c/charset_normalizer-3.4.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:926ca93accd5d36ccdabd803392ddc3e03e6d4cd1cf17deff3b989ab8e9dbcf0", size = 199622 }, - { url = "https://files.pythonhosted.org/packages/04/93/bf204e6f344c39d9937d3c13c8cd5bbfc266472e51fc8c07cb7f64fcd2de/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eba9904b0f38a143592d9fc0e19e2df0fa2e41c3c3745554761c5f6447eedabf", size = 143435 }, - { url = "https://files.pythonhosted.org/packages/22/2a/ea8a2095b0bafa6c5b5a55ffdc2f924455233ee7b91c69b7edfcc9e02284/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3fddb7e2c84ac87ac3a947cb4e66d143ca5863ef48e4a5ecb83bd48619e4634e", size = 153653 }, - { url = "https://files.pythonhosted.org/packages/b6/57/1b090ff183d13cef485dfbe272e2fe57622a76694061353c59da52c9a659/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98f862da73774290f251b9df8d11161b6cf25b599a66baf087c1ffe340e9bfd1", size = 146231 }, - { url = "https://files.pythonhosted.org/packages/e2/28/ffc026b26f441fc67bd21ab7f03b313ab3fe46714a14b516f931abe1a2d8/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c9379d65defcab82d07b2a9dfbfc2e95bc8fe0ebb1b176a3190230a3ef0e07c", size = 148243 }, - { url = "https://files.pythonhosted.org/packages/c0/0f/9abe9bd191629c33e69e47c6ef45ef99773320e9ad8e9cb08b8ab4a8d4cb/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e635b87f01ebc977342e2697d05b56632f5f879a4f15955dfe8cef2448b51691", size = 150442 }, - { url = "https://files.pythonhosted.org/packages/67/7c/a123bbcedca91d5916c056407f89a7f5e8fdfce12ba825d7d6b9954a1a3c/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1c95a1e2902a8b722868587c0e1184ad5c55631de5afc0eb96bc4b0d738092c0", size = 145147 }, - { url = "https://files.pythonhosted.org/packages/ec/fe/1ac556fa4899d967b83e9893788e86b6af4d83e4726511eaaad035e36595/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ef8de666d6179b009dce7bcb2ad4c4a779f113f12caf8dc77f0162c29d20490b", size = 153057 }, - { url = "https://files.pythonhosted.org/packages/2b/ff/acfc0b0a70b19e3e54febdd5301a98b72fa07635e56f24f60502e954c461/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:32fc0341d72e0f73f80acb0a2c94216bd704f4f0bce10aedea38f30502b271ff", size = 156454 }, - { url = "https://files.pythonhosted.org/packages/92/08/95b458ce9c740d0645feb0e96cea1f5ec946ea9c580a94adfe0b617f3573/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:289200a18fa698949d2b39c671c2cc7a24d44096784e76614899a7ccf2574b7b", size = 154174 }, - { url = "https://files.pythonhosted.org/packages/78/be/8392efc43487ac051eee6c36d5fbd63032d78f7728cb37aebcc98191f1ff/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4a476b06fbcf359ad25d34a057b7219281286ae2477cc5ff5e3f70a246971148", size = 149166 }, - { url = "https://files.pythonhosted.org/packages/44/96/392abd49b094d30b91d9fbda6a69519e95802250b777841cf3bda8fe136c/charset_normalizer-3.4.2-cp313-cp313-win32.whl", hash = "sha256:aaeeb6a479c7667fbe1099af9617c83aaca22182d6cf8c53966491a0f1b7ffb7", size = 98064 }, - { url = "https://files.pythonhosted.org/packages/e9/b0/0200da600134e001d91851ddc797809e2fe0ea72de90e09bec5a2fbdaccb/charset_normalizer-3.4.2-cp313-cp313-win_amd64.whl", hash = "sha256:aa6af9e7d59f9c12b33ae4e9450619cf2488e2bbe9b44030905877f0b2324980", size = 105641 }, - { url = "https://files.pythonhosted.org/packages/20/94/c5790835a017658cbfabd07f3bfb549140c3ac458cfc196323996b10095a/charset_normalizer-3.4.2-py3-none-any.whl", hash = "sha256:7f56930ab0abd1c45cd15be65cc741c28b1c9a34876ce8c17a2fa107810c0af0", size = 52626 }, +sdist = { url = "https://files.pythonhosted.org/packages/e4/33/89c2ced2b67d1c2a61c19c6751aa8902d46ce3dacb23600a283619f5a12d/charset_normalizer-3.4.2.tar.gz", hash = "sha256:5baececa9ecba31eff645232d59845c07aa030f0c81ee70184a90d35099a0e63", size = 126367, upload-time = "2025-05-02T08:34:42.01Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d7/a4/37f4d6035c89cac7930395a35cc0f1b872e652eaafb76a6075943754f095/charset_normalizer-3.4.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0c29de6a1a95f24b9a1aa7aefd27d2487263f00dfd55a77719b530788f75cff7", size = 199936, upload-time = "2025-05-02T08:32:33.712Z" }, + { url = "https://files.pythonhosted.org/packages/ee/8a/1a5e33b73e0d9287274f899d967907cd0bf9c343e651755d9307e0dbf2b3/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cddf7bd982eaa998934a91f69d182aec997c6c468898efe6679af88283b498d3", size = 143790, upload-time = "2025-05-02T08:32:35.768Z" }, + { url = "https://files.pythonhosted.org/packages/66/52/59521f1d8e6ab1482164fa21409c5ef44da3e9f653c13ba71becdd98dec3/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcbe676a55d7445b22c10967bceaaf0ee69407fbe0ece4d032b6eb8d4565982a", size = 153924, upload-time = "2025-05-02T08:32:37.284Z" }, + { url = "https://files.pythonhosted.org/packages/86/2d/fb55fdf41964ec782febbf33cb64be480a6b8f16ded2dbe8db27a405c09f/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d41c4d287cfc69060fa91cae9683eacffad989f1a10811995fa309df656ec214", size = 146626, upload-time = "2025-05-02T08:32:38.803Z" }, + { url = "https://files.pythonhosted.org/packages/8c/73/6ede2ec59bce19b3edf4209d70004253ec5f4e319f9a2e3f2f15601ed5f7/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e594135de17ab3866138f496755f302b72157d115086d100c3f19370839dd3a", size = 148567, upload-time = "2025-05-02T08:32:40.251Z" }, + { url = "https://files.pythonhosted.org/packages/09/14/957d03c6dc343c04904530b6bef4e5efae5ec7d7990a7cbb868e4595ee30/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cf713fe9a71ef6fd5adf7a79670135081cd4431c2943864757f0fa3a65b1fafd", size = 150957, upload-time = "2025-05-02T08:32:41.705Z" }, + { url = "https://files.pythonhosted.org/packages/0d/c8/8174d0e5c10ccebdcb1b53cc959591c4c722a3ad92461a273e86b9f5a302/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a370b3e078e418187da8c3674eddb9d983ec09445c99a3a263c2011993522981", size = 145408, upload-time = "2025-05-02T08:32:43.709Z" }, + { url = "https://files.pythonhosted.org/packages/58/aa/8904b84bc8084ac19dc52feb4f5952c6df03ffb460a887b42615ee1382e8/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a955b438e62efdf7e0b7b52a64dc5c3396e2634baa62471768a64bc2adb73d5c", size = 153399, upload-time = "2025-05-02T08:32:46.197Z" }, + { url = "https://files.pythonhosted.org/packages/c2/26/89ee1f0e264d201cb65cf054aca6038c03b1a0c6b4ae998070392a3ce605/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:7222ffd5e4de8e57e03ce2cef95a4c43c98fcb72ad86909abdfc2c17d227fc1b", size = 156815, upload-time = "2025-05-02T08:32:48.105Z" }, + { url = "https://files.pythonhosted.org/packages/fd/07/68e95b4b345bad3dbbd3a8681737b4338ff2c9df29856a6d6d23ac4c73cb/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:bee093bf902e1d8fc0ac143c88902c3dfc8941f7ea1d6a8dd2bcb786d33db03d", size = 154537, upload-time = "2025-05-02T08:32:49.719Z" }, + { url = "https://files.pythonhosted.org/packages/77/1a/5eefc0ce04affb98af07bc05f3bac9094513c0e23b0562d64af46a06aae4/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dedb8adb91d11846ee08bec4c8236c8549ac721c245678282dcb06b221aab59f", size = 149565, upload-time = "2025-05-02T08:32:51.404Z" }, + { url = "https://files.pythonhosted.org/packages/37/a0/2410e5e6032a174c95e0806b1a6585eb21e12f445ebe239fac441995226a/charset_normalizer-3.4.2-cp312-cp312-win32.whl", hash = "sha256:db4c7bf0e07fc3b7d89ac2a5880a6a8062056801b83ff56d8464b70f65482b6c", size = 98357, upload-time = "2025-05-02T08:32:53.079Z" }, + { url = "https://files.pythonhosted.org/packages/6c/4f/c02d5c493967af3eda9c771ad4d2bbc8df6f99ddbeb37ceea6e8716a32bc/charset_normalizer-3.4.2-cp312-cp312-win_amd64.whl", hash = "sha256:5a9979887252a82fefd3d3ed2a8e3b937a7a809f65dcb1e068b090e165bbe99e", size = 105776, upload-time = "2025-05-02T08:32:54.573Z" }, + { url = "https://files.pythonhosted.org/packages/ea/12/a93df3366ed32db1d907d7593a94f1fe6293903e3e92967bebd6950ed12c/charset_normalizer-3.4.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:926ca93accd5d36ccdabd803392ddc3e03e6d4cd1cf17deff3b989ab8e9dbcf0", size = 199622, upload-time = "2025-05-02T08:32:56.363Z" }, + { url = "https://files.pythonhosted.org/packages/04/93/bf204e6f344c39d9937d3c13c8cd5bbfc266472e51fc8c07cb7f64fcd2de/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eba9904b0f38a143592d9fc0e19e2df0fa2e41c3c3745554761c5f6447eedabf", size = 143435, upload-time = "2025-05-02T08:32:58.551Z" }, + { url = "https://files.pythonhosted.org/packages/22/2a/ea8a2095b0bafa6c5b5a55ffdc2f924455233ee7b91c69b7edfcc9e02284/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3fddb7e2c84ac87ac3a947cb4e66d143ca5863ef48e4a5ecb83bd48619e4634e", size = 153653, upload-time = "2025-05-02T08:33:00.342Z" }, + { url = "https://files.pythonhosted.org/packages/b6/57/1b090ff183d13cef485dfbe272e2fe57622a76694061353c59da52c9a659/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98f862da73774290f251b9df8d11161b6cf25b599a66baf087c1ffe340e9bfd1", size = 146231, upload-time = "2025-05-02T08:33:02.081Z" }, + { url = "https://files.pythonhosted.org/packages/e2/28/ffc026b26f441fc67bd21ab7f03b313ab3fe46714a14b516f931abe1a2d8/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c9379d65defcab82d07b2a9dfbfc2e95bc8fe0ebb1b176a3190230a3ef0e07c", size = 148243, upload-time = "2025-05-02T08:33:04.063Z" }, + { url = "https://files.pythonhosted.org/packages/c0/0f/9abe9bd191629c33e69e47c6ef45ef99773320e9ad8e9cb08b8ab4a8d4cb/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e635b87f01ebc977342e2697d05b56632f5f879a4f15955dfe8cef2448b51691", size = 150442, upload-time = "2025-05-02T08:33:06.418Z" }, + { url = "https://files.pythonhosted.org/packages/67/7c/a123bbcedca91d5916c056407f89a7f5e8fdfce12ba825d7d6b9954a1a3c/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1c95a1e2902a8b722868587c0e1184ad5c55631de5afc0eb96bc4b0d738092c0", size = 145147, upload-time = "2025-05-02T08:33:08.183Z" }, + { url = "https://files.pythonhosted.org/packages/ec/fe/1ac556fa4899d967b83e9893788e86b6af4d83e4726511eaaad035e36595/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ef8de666d6179b009dce7bcb2ad4c4a779f113f12caf8dc77f0162c29d20490b", size = 153057, upload-time = "2025-05-02T08:33:09.986Z" }, + { url = "https://files.pythonhosted.org/packages/2b/ff/acfc0b0a70b19e3e54febdd5301a98b72fa07635e56f24f60502e954c461/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:32fc0341d72e0f73f80acb0a2c94216bd704f4f0bce10aedea38f30502b271ff", size = 156454, upload-time = "2025-05-02T08:33:11.814Z" }, + { url = "https://files.pythonhosted.org/packages/92/08/95b458ce9c740d0645feb0e96cea1f5ec946ea9c580a94adfe0b617f3573/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:289200a18fa698949d2b39c671c2cc7a24d44096784e76614899a7ccf2574b7b", size = 154174, upload-time = "2025-05-02T08:33:13.707Z" }, + { url = "https://files.pythonhosted.org/packages/78/be/8392efc43487ac051eee6c36d5fbd63032d78f7728cb37aebcc98191f1ff/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4a476b06fbcf359ad25d34a057b7219281286ae2477cc5ff5e3f70a246971148", size = 149166, upload-time = "2025-05-02T08:33:15.458Z" }, + { url = "https://files.pythonhosted.org/packages/44/96/392abd49b094d30b91d9fbda6a69519e95802250b777841cf3bda8fe136c/charset_normalizer-3.4.2-cp313-cp313-win32.whl", hash = "sha256:aaeeb6a479c7667fbe1099af9617c83aaca22182d6cf8c53966491a0f1b7ffb7", size = 98064, upload-time = "2025-05-02T08:33:17.06Z" }, + { url = "https://files.pythonhosted.org/packages/e9/b0/0200da600134e001d91851ddc797809e2fe0ea72de90e09bec5a2fbdaccb/charset_normalizer-3.4.2-cp313-cp313-win_amd64.whl", hash = "sha256:aa6af9e7d59f9c12b33ae4e9450619cf2488e2bbe9b44030905877f0b2324980", size = 105641, upload-time = "2025-05-02T08:33:18.753Z" }, + { url = "https://files.pythonhosted.org/packages/20/94/c5790835a017658cbfabd07f3bfb549140c3ac458cfc196323996b10095a/charset_normalizer-3.4.2-py3-none-any.whl", hash = "sha256:7f56930ab0abd1c45cd15be65cc741c28b1c9a34876ce8c17a2fa107810c0af0", size = 52626, upload-time = "2025-05-02T08:34:40.053Z" }, ] [[package]] @@ -203,27 +203,27 @@ dependencies = [ { name = "coverage" }, { name = "requests" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/2c/bb/594b26d2c85616be6195a64289c578662678afa4910cef2d3ce8417cf73e/codecov-2.1.13.tar.gz", hash = "sha256:2362b685633caeaf45b9951a9b76ce359cd3581dd515b430c6c3f5dfb4d92a8c", size = 21416 } +sdist = { url = "https://files.pythonhosted.org/packages/2c/bb/594b26d2c85616be6195a64289c578662678afa4910cef2d3ce8417cf73e/codecov-2.1.13.tar.gz", hash = "sha256:2362b685633caeaf45b9951a9b76ce359cd3581dd515b430c6c3f5dfb4d92a8c", size = 21416, upload-time = "2023-04-17T23:11:39.779Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/af/02/18785edcdf6266cdd6c6dc7635f1cbeefd9a5b4c3bb8aff8bd681e9dd095/codecov-2.1.13-py2.py3-none-any.whl", hash = "sha256:c2ca5e51bba9ebb43644c43d0690148a55086f7f5e6fd36170858fa4206744d5", size = 16512 }, + { url = "https://files.pythonhosted.org/packages/af/02/18785edcdf6266cdd6c6dc7635f1cbeefd9a5b4c3bb8aff8bd681e9dd095/codecov-2.1.13-py2.py3-none-any.whl", hash = "sha256:c2ca5e51bba9ebb43644c43d0690148a55086f7f5e6fd36170858fa4206744d5", size = 16512, upload-time = "2023-04-17T23:11:37.344Z" }, ] [[package]] name = "codespell" version = "2.4.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/15/e0/709453393c0ea77d007d907dd436b3ee262e28b30995ea1aa36c6ffbccaf/codespell-2.4.1.tar.gz", hash = "sha256:299fcdcb09d23e81e35a671bbe746d5ad7e8385972e65dbb833a2eaac33c01e5", size = 344740 } +sdist = { url = "https://files.pythonhosted.org/packages/15/e0/709453393c0ea77d007d907dd436b3ee262e28b30995ea1aa36c6ffbccaf/codespell-2.4.1.tar.gz", hash = "sha256:299fcdcb09d23e81e35a671bbe746d5ad7e8385972e65dbb833a2eaac33c01e5", size = 344740, upload-time = "2025-01-28T18:52:39.411Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/20/01/b394922252051e97aab231d416c86da3d8a6d781eeadcdca1082867de64e/codespell-2.4.1-py3-none-any.whl", hash = "sha256:3dadafa67df7e4a3dbf51e0d7315061b80d265f9552ebd699b3dd6834b47e425", size = 344501 }, + { url = "https://files.pythonhosted.org/packages/20/01/b394922252051e97aab231d416c86da3d8a6d781eeadcdca1082867de64e/codespell-2.4.1-py3-none-any.whl", hash = "sha256:3dadafa67df7e4a3dbf51e0d7315061b80d265f9552ebd699b3dd6834b47e425", size = 344501, upload-time = "2025-01-28T18:52:37.057Z" }, ] [[package]] name = "colorama" version = "0.4.6" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, ] [[package]] @@ -233,73 +233,73 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d3/7a/359f4d5df2353f26172b3cc39ea32daa39af8de522205f512f458923e677/colorlog-6.9.0.tar.gz", hash = "sha256:bfba54a1b93b94f54e1f4fe48395725a3d92fd2a4af702f6bd70946bdc0c6ac2", size = 16624 } +sdist = { url = "https://files.pythonhosted.org/packages/d3/7a/359f4d5df2353f26172b3cc39ea32daa39af8de522205f512f458923e677/colorlog-6.9.0.tar.gz", hash = "sha256:bfba54a1b93b94f54e1f4fe48395725a3d92fd2a4af702f6bd70946bdc0c6ac2", size = 16624, upload-time = "2024-10-29T18:34:51.011Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e3/51/9b208e85196941db2f0654ad0357ca6388ab3ed67efdbfc799f35d1f83aa/colorlog-6.9.0-py3-none-any.whl", hash = "sha256:5906e71acd67cb07a71e779c47c4bcb45fb8c2993eebe9e5adcd6a6f1b283eff", size = 11424 }, + { url = "https://files.pythonhosted.org/packages/e3/51/9b208e85196941db2f0654ad0357ca6388ab3ed67efdbfc799f35d1f83aa/colorlog-6.9.0-py3-none-any.whl", hash = "sha256:5906e71acd67cb07a71e779c47c4bcb45fb8c2993eebe9e5adcd6a6f1b283eff", size = 11424, upload-time = "2024-10-29T18:34:49.815Z" }, ] [[package]] name = "coverage" version = "7.10.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ee/76/17780846fc7aade1e66712e1e27dd28faa0a5d987a1f433610974959eaa8/coverage-7.10.2.tar.gz", hash = "sha256:5d6e6d84e6dd31a8ded64759626627247d676a23c1b892e1326f7c55c8d61055", size = 820754 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/4e/1e/2c752bdbbf6f1199c59b1a10557fbb6fb3dc96b3c0077b30bd41a5922c1f/coverage-7.10.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:890ad3a26da9ec7bf69255b9371800e2a8da9bc223ae5d86daeb940b42247c83", size = 215311 }, - { url = "https://files.pythonhosted.org/packages/68/6a/84277d73a2cafb96e24be81b7169372ba7ff28768ebbf98e55c85a491b0f/coverage-7.10.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:38fd1ccfca7838c031d7a7874d4353e2f1b98eb5d2a80a2fe5732d542ae25e9c", size = 215550 }, - { url = "https://files.pythonhosted.org/packages/b5/e7/5358b73b46ac76f56cc2de921eeabd44fabd0b7ff82ea4f6b8c159c4d5dc/coverage-7.10.2-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:76c1ffaaf4f6f0f6e8e9ca06f24bb6454a7a5d4ced97a1bc466f0d6baf4bd518", size = 246564 }, - { url = "https://files.pythonhosted.org/packages/7c/0e/b0c901dd411cb7fc0cfcb28ef0dc6f3049030f616bfe9fc4143aecd95901/coverage-7.10.2-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:86da8a3a84b79ead5c7d0e960c34f580bc3b231bb546627773a3f53c532c2f21", size = 248993 }, - { url = "https://files.pythonhosted.org/packages/0e/4e/a876db272072a9e0df93f311e187ccdd5f39a190c6d1c1f0b6e255a0d08e/coverage-7.10.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:99cef9731c8a39801830a604cc53c93c9e57ea8b44953d26589499eded9576e0", size = 250454 }, - { url = "https://files.pythonhosted.org/packages/64/d6/1222dc69f8dd1be208d55708a9f4a450ad582bf4fa05320617fea1eaa6d8/coverage-7.10.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ea58b112f2966a8b91eb13f5d3b1f8bb43c180d624cd3283fb33b1cedcc2dd75", size = 248365 }, - { url = "https://files.pythonhosted.org/packages/62/e3/40fd71151064fc315c922dd9a35e15b30616f00146db1d6a0b590553a75a/coverage-7.10.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:20f405188d28da9522b7232e51154e1b884fc18d0b3a10f382d54784715bbe01", size = 246562 }, - { url = "https://files.pythonhosted.org/packages/fc/14/8aa93ddcd6623ddaef5d8966268ac9545b145bce4fe7b1738fd1c3f0d957/coverage-7.10.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:64586ce42bbe0da4d9f76f97235c545d1abb9b25985a8791857690f96e23dc3b", size = 247772 }, - { url = "https://files.pythonhosted.org/packages/07/4e/dcb1c01490623c61e2f2ea85cb185fa6a524265bb70eeb897d3c193efeb9/coverage-7.10.2-cp312-cp312-win32.whl", hash = "sha256:bc2e69b795d97ee6d126e7e22e78a509438b46be6ff44f4dccbb5230f550d340", size = 217710 }, - { url = "https://files.pythonhosted.org/packages/79/16/e8aab4162b5f80ad2e5e1f54b1826e2053aa2f4db508b864af647f00c239/coverage-7.10.2-cp312-cp312-win_amd64.whl", hash = "sha256:adda2268b8cf0d11f160fad3743b4dfe9813cd6ecf02c1d6397eceaa5b45b388", size = 218499 }, - { url = "https://files.pythonhosted.org/packages/06/7f/c112ec766e8f1131ce8ce26254be028772757b2d1e63e4f6a4b0ad9a526c/coverage-7.10.2-cp312-cp312-win_arm64.whl", hash = "sha256:164429decd0d6b39a0582eaa30c67bf482612c0330572343042d0ed9e7f15c20", size = 217154 }, - { url = "https://files.pythonhosted.org/packages/8d/04/9b7a741557f93c0ed791b854d27aa8d9fe0b0ce7bb7c52ca1b0f2619cb74/coverage-7.10.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:aca7b5645afa688de6d4f8e89d30c577f62956fefb1bad021490d63173874186", size = 215337 }, - { url = "https://files.pythonhosted.org/packages/02/a4/8d1088cd644750c94bc305d3cf56082b4cdf7fb854a25abb23359e74892f/coverage-7.10.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:96e5921342574a14303dfdb73de0019e1ac041c863743c8fe1aa6c2b4a257226", size = 215596 }, - { url = "https://files.pythonhosted.org/packages/01/2f/643a8d73343f70e162d8177a3972b76e306b96239026bc0c12cfde4f7c7a/coverage-7.10.2-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:11333094c1bff621aa811b67ed794865cbcaa99984dedea4bd9cf780ad64ecba", size = 246145 }, - { url = "https://files.pythonhosted.org/packages/1f/4a/722098d1848db4072cda71b69ede1e55730d9063bf868375264d0d302bc9/coverage-7.10.2-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:6eb586fa7d2aee8d65d5ae1dd71414020b2f447435c57ee8de8abea0a77d5074", size = 248492 }, - { url = "https://files.pythonhosted.org/packages/3f/b0/8a6d7f326f6e3e6ed398cde27f9055e860a1e858317001835c521673fb60/coverage-7.10.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2d358f259d8019d4ef25d8c5b78aca4c7af25e28bd4231312911c22a0e824a57", size = 249927 }, - { url = "https://files.pythonhosted.org/packages/bb/21/1aaadd3197b54d1e61794475379ecd0f68d8fc5c2ebd352964dc6f698a3d/coverage-7.10.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5250bda76e30382e0a2dcd68d961afcab92c3a7613606e6269855c6979a1b0bb", size = 248138 }, - { url = "https://files.pythonhosted.org/packages/48/65/be75bafb2bdd22fd8bf9bf63cd5873b91bb26ec0d68f02d4b8b09c02decb/coverage-7.10.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:a91e027d66eff214d88d9afbe528e21c9ef1ecdf4956c46e366c50f3094696d0", size = 246111 }, - { url = "https://files.pythonhosted.org/packages/5e/30/a4f0c5e249c3cc60e6c6f30d8368e372f2d380eda40e0434c192ac27ccf5/coverage-7.10.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:228946da741558904e2c03ce870ba5efd9cd6e48cbc004d9a27abee08100a15a", size = 247493 }, - { url = "https://files.pythonhosted.org/packages/85/99/f09b9493e44a75cf99ca834394c12f8cb70da6c1711ee296534f97b52729/coverage-7.10.2-cp313-cp313-win32.whl", hash = "sha256:95e23987b52d02e7c413bf2d6dc6288bd5721beb518052109a13bfdc62c8033b", size = 217756 }, - { url = "https://files.pythonhosted.org/packages/2d/bb/cbcb09103be330c7d26ff0ab05c4a8861dd2e254656fdbd3eb7600af4336/coverage-7.10.2-cp313-cp313-win_amd64.whl", hash = "sha256:f35481d42c6d146d48ec92d4e239c23f97b53a3f1fbd2302e7c64336f28641fe", size = 218526 }, - { url = "https://files.pythonhosted.org/packages/37/8f/8bfb4e0bca52c00ab680767c0dd8cfd928a2a72d69897d9b2d5d8b5f63f5/coverage-7.10.2-cp313-cp313-win_arm64.whl", hash = "sha256:65b451949cb789c346f9f9002441fc934d8ccedcc9ec09daabc2139ad13853f7", size = 217176 }, - { url = "https://files.pythonhosted.org/packages/1e/25/d458ba0bf16a8204a88d74dbb7ec5520f29937ffcbbc12371f931c11efd2/coverage-7.10.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:e8415918856a3e7d57a4e0ad94651b761317de459eb74d34cc1bb51aad80f07e", size = 216058 }, - { url = "https://files.pythonhosted.org/packages/0b/1c/af4dfd2d7244dc7610fed6d59d57a23ea165681cd764445dc58d71ed01a6/coverage-7.10.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f287a25a8ca53901c613498e4a40885b19361a2fe8fbfdbb7f8ef2cad2a23f03", size = 216273 }, - { url = "https://files.pythonhosted.org/packages/8e/67/ec5095d4035c6e16368226fa9cb15f77f891194c7e3725aeefd08e7a3e5a/coverage-7.10.2-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:75cc1a3f8c88c69bf16a871dab1fe5a7303fdb1e9f285f204b60f1ee539b8fc0", size = 257513 }, - { url = "https://files.pythonhosted.org/packages/1c/47/be5550b57a3a8ba797de4236b0fd31031f88397b2afc84ab3c2d4cf265f6/coverage-7.10.2-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:ca07fa78cc9d26bc8c4740de1abd3489cf9c47cc06d9a8ab3d552ff5101af4c0", size = 259377 }, - { url = "https://files.pythonhosted.org/packages/37/50/b12a4da1382e672305c2d17cd3029dc16b8a0470de2191dbf26b91431378/coverage-7.10.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c2e117e64c26300032755d4520cd769f2623cde1a1d1c3515b05a3b8add0ade1", size = 261516 }, - { url = "https://files.pythonhosted.org/packages/db/41/4d3296dbd33dd8da178171540ca3391af7c0184c0870fd4d4574ac290290/coverage-7.10.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:daaf98009977f577b71f8800208f4d40d4dcf5c2db53d4d822787cdc198d76e1", size = 259110 }, - { url = "https://files.pythonhosted.org/packages/ea/f1/b409959ecbc0cec0e61e65683b22bacaa4a3b11512f834e16dd8ffbc37db/coverage-7.10.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:ea8d8fe546c528535c761ba424410bbeb36ba8a0f24be653e94b70c93fd8a8ca", size = 257248 }, - { url = "https://files.pythonhosted.org/packages/48/ab/7076dc1c240412e9267d36ec93e9e299d7659f6a5c1e958f87e998b0fb6d/coverage-7.10.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:fe024d40ac31eb8d5aae70215b41dafa264676caa4404ae155f77d2fa95c37bb", size = 258063 }, - { url = "https://files.pythonhosted.org/packages/1e/77/f6b51a0288f8f5f7dcc7c89abdd22cf514f3bc5151284f5cd628917f8e10/coverage-7.10.2-cp313-cp313t-win32.whl", hash = "sha256:8f34b09f68bdadec122ffad312154eda965ade433559cc1eadd96cca3de5c824", size = 218433 }, - { url = "https://files.pythonhosted.org/packages/7b/6d/547a86493e25270ce8481543e77f3a0aa3aa872c1374246b7b76273d66eb/coverage-7.10.2-cp313-cp313t-win_amd64.whl", hash = "sha256:71d40b3ac0f26fa9ffa6ee16219a714fed5c6ec197cdcd2018904ab5e75bcfa3", size = 219523 }, - { url = "https://files.pythonhosted.org/packages/ff/d5/3c711e38eaf9ab587edc9bed232c0298aed84e751a9f54aaa556ceaf7da6/coverage-7.10.2-cp313-cp313t-win_arm64.whl", hash = "sha256:abb57fdd38bf6f7dcc66b38dafb7af7c5fdc31ac6029ce373a6f7f5331d6f60f", size = 217739 }, - { url = "https://files.pythonhosted.org/packages/71/53/83bafa669bb9d06d4c8c6a055d8d05677216f9480c4698fb183ba7ec5e47/coverage-7.10.2-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:a3e853cc04987c85ec410905667eed4bf08b1d84d80dfab2684bb250ac8da4f6", size = 215328 }, - { url = "https://files.pythonhosted.org/packages/1d/6c/30827a9c5a48a813e865fbaf91e2db25cce990bd223a022650ef2293fe11/coverage-7.10.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0100b19f230df72c90fdb36db59d3f39232391e8d89616a7de30f677da4f532b", size = 215608 }, - { url = "https://files.pythonhosted.org/packages/bb/a0/c92d85948056ddc397b72a3d79d36d9579c53cb25393ed3c40db7d33b193/coverage-7.10.2-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:9c1cd71483ea78331bdfadb8dcec4f4edfb73c7002c1206d8e0af6797853f5be", size = 246111 }, - { url = "https://files.pythonhosted.org/packages/c2/cf/d695cf86b2559aadd072c91720a7844be4fb82cb4a3b642a2c6ce075692d/coverage-7.10.2-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9f75dbf4899e29a37d74f48342f29279391668ef625fdac6d2f67363518056a1", size = 248419 }, - { url = "https://files.pythonhosted.org/packages/ce/0a/03206aec4a05986e039418c038470d874045f6e00426b0c3879adc1f9251/coverage-7.10.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a7df481e7508de1c38b9b8043da48d94931aefa3e32b47dd20277e4978ed5b95", size = 250038 }, - { url = "https://files.pythonhosted.org/packages/ab/9b/b3bd6bd52118c12bc4cf319f5baba65009c9beea84e665b6b9f03fa3f180/coverage-7.10.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:835f39e618099325e7612b3406f57af30ab0a0af350490eff6421e2e5f608e46", size = 248066 }, - { url = "https://files.pythonhosted.org/packages/80/cc/bfa92e261d3e055c851a073e87ba6a3bff12a1f7134233e48a8f7d855875/coverage-7.10.2-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:12e52b5aa00aa720097d6947d2eb9e404e7c1101ad775f9661ba165ed0a28303", size = 245909 }, - { url = "https://files.pythonhosted.org/packages/12/80/c8df15db4847710c72084164f615ae900af1ec380dce7f74a5678ccdf5e1/coverage-7.10.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:718044729bf1fe3e9eb9f31b52e44ddae07e434ec050c8c628bf5adc56fe4bdd", size = 247329 }, - { url = "https://files.pythonhosted.org/packages/04/6f/cb66e1f7124d5dd9ced69f889f02931419cb448125e44a89a13f4e036124/coverage-7.10.2-cp314-cp314-win32.whl", hash = "sha256:f256173b48cc68486299d510a3e729a96e62c889703807482dbf56946befb5c8", size = 218007 }, - { url = "https://files.pythonhosted.org/packages/8c/e1/3d4be307278ce32c1b9d95cc02ee60d54ddab784036101d053ec9e4fe7f5/coverage-7.10.2-cp314-cp314-win_amd64.whl", hash = "sha256:2e980e4179f33d9b65ac4acb86c9c0dde904098853f27f289766657ed16e07b3", size = 218802 }, - { url = "https://files.pythonhosted.org/packages/ec/66/1e43bbeb66c55a5a5efec70f1c153cf90cfc7f1662ab4ebe2d844de9122c/coverage-7.10.2-cp314-cp314-win_arm64.whl", hash = "sha256:14fb5b6641ab5b3c4161572579f0f2ea8834f9d3af2f7dd8fbaecd58ef9175cc", size = 217397 }, - { url = "https://files.pythonhosted.org/packages/81/01/ae29c129217f6110dc694a217475b8aecbb1b075d8073401f868c825fa99/coverage-7.10.2-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:e96649ac34a3d0e6491e82a2af71098e43be2874b619547c3282fc11d3840a4b", size = 216068 }, - { url = "https://files.pythonhosted.org/packages/a2/50/6e9221d4139f357258f36dfa1d8cac4ec56d9d5acf5fdcc909bb016954d7/coverage-7.10.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1a2e934e9da26341d342d30bfe91422bbfdb3f1f069ec87f19b2909d10d8dcc4", size = 216285 }, - { url = "https://files.pythonhosted.org/packages/eb/ec/89d1d0c0ece0d296b4588e0ef4df185200456d42a47f1141335f482c2fc5/coverage-7.10.2-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:651015dcd5fd9b5a51ca79ece60d353cacc5beaf304db750407b29c89f72fe2b", size = 257603 }, - { url = "https://files.pythonhosted.org/packages/82/06/c830af66734671c778fc49d35b58339e8f0687fbd2ae285c3f96c94da092/coverage-7.10.2-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:81bf6a32212f9f66da03d63ecb9cd9bd48e662050a937db7199dbf47d19831de", size = 259568 }, - { url = "https://files.pythonhosted.org/packages/60/57/f280dd6f1c556ecc744fbf39e835c33d3ae987d040d64d61c6f821e87829/coverage-7.10.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d800705f6951f75a905ea6feb03fff8f3ea3468b81e7563373ddc29aa3e5d1ca", size = 261691 }, - { url = "https://files.pythonhosted.org/packages/54/2b/c63a0acbd19d99ec32326164c23df3a4e18984fb86e902afdd66ff7b3d83/coverage-7.10.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:248b5394718e10d067354448dc406d651709c6765669679311170da18e0e9af8", size = 259166 }, - { url = "https://files.pythonhosted.org/packages/fd/c5/cd2997dcfcbf0683634da9df52d3967bc1f1741c1475dd0e4722012ba9ef/coverage-7.10.2-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:5c61675a922b569137cf943770d7ad3edd0202d992ce53ac328c5ff68213ccf4", size = 257241 }, - { url = "https://files.pythonhosted.org/packages/16/26/c9e30f82fdad8d47aee90af4978b18c88fa74369ae0f0ba0dbf08cee3a80/coverage-7.10.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:52d708b5fd65589461381fa442d9905f5903d76c086c6a4108e8e9efdca7a7ed", size = 258139 }, - { url = "https://files.pythonhosted.org/packages/c9/99/bdb7bd00bebcd3dedfb895fa9af8e46b91422993e4a37ac634a5f1113790/coverage-7.10.2-cp314-cp314t-win32.whl", hash = "sha256:916369b3b914186b2c5e5ad2f7264b02cff5df96cdd7cdad65dccd39aa5fd9f0", size = 218809 }, - { url = "https://files.pythonhosted.org/packages/eb/5e/56a7852e38a04d1520dda4dfbfbf74a3d6dec932c20526968f7444763567/coverage-7.10.2-cp314-cp314t-win_amd64.whl", hash = "sha256:5b9d538e8e04916a5df63052d698b30c74eb0174f2ca9cd942c981f274a18eaf", size = 219926 }, - { url = "https://files.pythonhosted.org/packages/e0/12/7fbe6b9c52bb9d627e9556f9f2edfdbe88b315e084cdecc9afead0c3b36a/coverage-7.10.2-cp314-cp314t-win_arm64.whl", hash = "sha256:04c74f9ef1f925456a9fd23a7eef1103126186d0500ef9a0acb0bd2514bdc7cc", size = 217925 }, - { url = "https://files.pythonhosted.org/packages/18/d8/9b768ac73a8ac2d10c080af23937212434a958c8d2a1c84e89b450237942/coverage-7.10.2-py3-none-any.whl", hash = "sha256:95db3750dd2e6e93d99fa2498f3a1580581e49c494bddccc6f85c5c21604921f", size = 206973 }, +sdist = { url = "https://files.pythonhosted.org/packages/ee/76/17780846fc7aade1e66712e1e27dd28faa0a5d987a1f433610974959eaa8/coverage-7.10.2.tar.gz", hash = "sha256:5d6e6d84e6dd31a8ded64759626627247d676a23c1b892e1326f7c55c8d61055", size = 820754, upload-time = "2025-08-04T00:35:17.511Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4e/1e/2c752bdbbf6f1199c59b1a10557fbb6fb3dc96b3c0077b30bd41a5922c1f/coverage-7.10.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:890ad3a26da9ec7bf69255b9371800e2a8da9bc223ae5d86daeb940b42247c83", size = 215311, upload-time = "2025-08-04T00:33:35.524Z" }, + { url = "https://files.pythonhosted.org/packages/68/6a/84277d73a2cafb96e24be81b7169372ba7ff28768ebbf98e55c85a491b0f/coverage-7.10.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:38fd1ccfca7838c031d7a7874d4353e2f1b98eb5d2a80a2fe5732d542ae25e9c", size = 215550, upload-time = "2025-08-04T00:33:37.109Z" }, + { url = "https://files.pythonhosted.org/packages/b5/e7/5358b73b46ac76f56cc2de921eeabd44fabd0b7ff82ea4f6b8c159c4d5dc/coverage-7.10.2-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:76c1ffaaf4f6f0f6e8e9ca06f24bb6454a7a5d4ced97a1bc466f0d6baf4bd518", size = 246564, upload-time = "2025-08-04T00:33:38.33Z" }, + { url = "https://files.pythonhosted.org/packages/7c/0e/b0c901dd411cb7fc0cfcb28ef0dc6f3049030f616bfe9fc4143aecd95901/coverage-7.10.2-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:86da8a3a84b79ead5c7d0e960c34f580bc3b231bb546627773a3f53c532c2f21", size = 248993, upload-time = "2025-08-04T00:33:39.555Z" }, + { url = "https://files.pythonhosted.org/packages/0e/4e/a876db272072a9e0df93f311e187ccdd5f39a190c6d1c1f0b6e255a0d08e/coverage-7.10.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:99cef9731c8a39801830a604cc53c93c9e57ea8b44953d26589499eded9576e0", size = 250454, upload-time = "2025-08-04T00:33:41.023Z" }, + { url = "https://files.pythonhosted.org/packages/64/d6/1222dc69f8dd1be208d55708a9f4a450ad582bf4fa05320617fea1eaa6d8/coverage-7.10.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ea58b112f2966a8b91eb13f5d3b1f8bb43c180d624cd3283fb33b1cedcc2dd75", size = 248365, upload-time = "2025-08-04T00:33:42.376Z" }, + { url = "https://files.pythonhosted.org/packages/62/e3/40fd71151064fc315c922dd9a35e15b30616f00146db1d6a0b590553a75a/coverage-7.10.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:20f405188d28da9522b7232e51154e1b884fc18d0b3a10f382d54784715bbe01", size = 246562, upload-time = "2025-08-04T00:33:43.663Z" }, + { url = "https://files.pythonhosted.org/packages/fc/14/8aa93ddcd6623ddaef5d8966268ac9545b145bce4fe7b1738fd1c3f0d957/coverage-7.10.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:64586ce42bbe0da4d9f76f97235c545d1abb9b25985a8791857690f96e23dc3b", size = 247772, upload-time = "2025-08-04T00:33:45.068Z" }, + { url = "https://files.pythonhosted.org/packages/07/4e/dcb1c01490623c61e2f2ea85cb185fa6a524265bb70eeb897d3c193efeb9/coverage-7.10.2-cp312-cp312-win32.whl", hash = "sha256:bc2e69b795d97ee6d126e7e22e78a509438b46be6ff44f4dccbb5230f550d340", size = 217710, upload-time = "2025-08-04T00:33:46.378Z" }, + { url = "https://files.pythonhosted.org/packages/79/16/e8aab4162b5f80ad2e5e1f54b1826e2053aa2f4db508b864af647f00c239/coverage-7.10.2-cp312-cp312-win_amd64.whl", hash = "sha256:adda2268b8cf0d11f160fad3743b4dfe9813cd6ecf02c1d6397eceaa5b45b388", size = 218499, upload-time = "2025-08-04T00:33:48.048Z" }, + { url = "https://files.pythonhosted.org/packages/06/7f/c112ec766e8f1131ce8ce26254be028772757b2d1e63e4f6a4b0ad9a526c/coverage-7.10.2-cp312-cp312-win_arm64.whl", hash = "sha256:164429decd0d6b39a0582eaa30c67bf482612c0330572343042d0ed9e7f15c20", size = 217154, upload-time = "2025-08-04T00:33:49.299Z" }, + { url = "https://files.pythonhosted.org/packages/8d/04/9b7a741557f93c0ed791b854d27aa8d9fe0b0ce7bb7c52ca1b0f2619cb74/coverage-7.10.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:aca7b5645afa688de6d4f8e89d30c577f62956fefb1bad021490d63173874186", size = 215337, upload-time = "2025-08-04T00:33:50.61Z" }, + { url = "https://files.pythonhosted.org/packages/02/a4/8d1088cd644750c94bc305d3cf56082b4cdf7fb854a25abb23359e74892f/coverage-7.10.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:96e5921342574a14303dfdb73de0019e1ac041c863743c8fe1aa6c2b4a257226", size = 215596, upload-time = "2025-08-04T00:33:52.33Z" }, + { url = "https://files.pythonhosted.org/packages/01/2f/643a8d73343f70e162d8177a3972b76e306b96239026bc0c12cfde4f7c7a/coverage-7.10.2-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:11333094c1bff621aa811b67ed794865cbcaa99984dedea4bd9cf780ad64ecba", size = 246145, upload-time = "2025-08-04T00:33:53.641Z" }, + { url = "https://files.pythonhosted.org/packages/1f/4a/722098d1848db4072cda71b69ede1e55730d9063bf868375264d0d302bc9/coverage-7.10.2-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:6eb586fa7d2aee8d65d5ae1dd71414020b2f447435c57ee8de8abea0a77d5074", size = 248492, upload-time = "2025-08-04T00:33:55.366Z" }, + { url = "https://files.pythonhosted.org/packages/3f/b0/8a6d7f326f6e3e6ed398cde27f9055e860a1e858317001835c521673fb60/coverage-7.10.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2d358f259d8019d4ef25d8c5b78aca4c7af25e28bd4231312911c22a0e824a57", size = 249927, upload-time = "2025-08-04T00:33:57.042Z" }, + { url = "https://files.pythonhosted.org/packages/bb/21/1aaadd3197b54d1e61794475379ecd0f68d8fc5c2ebd352964dc6f698a3d/coverage-7.10.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5250bda76e30382e0a2dcd68d961afcab92c3a7613606e6269855c6979a1b0bb", size = 248138, upload-time = "2025-08-04T00:33:58.329Z" }, + { url = "https://files.pythonhosted.org/packages/48/65/be75bafb2bdd22fd8bf9bf63cd5873b91bb26ec0d68f02d4b8b09c02decb/coverage-7.10.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:a91e027d66eff214d88d9afbe528e21c9ef1ecdf4956c46e366c50f3094696d0", size = 246111, upload-time = "2025-08-04T00:33:59.899Z" }, + { url = "https://files.pythonhosted.org/packages/5e/30/a4f0c5e249c3cc60e6c6f30d8368e372f2d380eda40e0434c192ac27ccf5/coverage-7.10.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:228946da741558904e2c03ce870ba5efd9cd6e48cbc004d9a27abee08100a15a", size = 247493, upload-time = "2025-08-04T00:34:01.619Z" }, + { url = "https://files.pythonhosted.org/packages/85/99/f09b9493e44a75cf99ca834394c12f8cb70da6c1711ee296534f97b52729/coverage-7.10.2-cp313-cp313-win32.whl", hash = "sha256:95e23987b52d02e7c413bf2d6dc6288bd5721beb518052109a13bfdc62c8033b", size = 217756, upload-time = "2025-08-04T00:34:03.277Z" }, + { url = "https://files.pythonhosted.org/packages/2d/bb/cbcb09103be330c7d26ff0ab05c4a8861dd2e254656fdbd3eb7600af4336/coverage-7.10.2-cp313-cp313-win_amd64.whl", hash = "sha256:f35481d42c6d146d48ec92d4e239c23f97b53a3f1fbd2302e7c64336f28641fe", size = 218526, upload-time = "2025-08-04T00:34:04.635Z" }, + { url = "https://files.pythonhosted.org/packages/37/8f/8bfb4e0bca52c00ab680767c0dd8cfd928a2a72d69897d9b2d5d8b5f63f5/coverage-7.10.2-cp313-cp313-win_arm64.whl", hash = "sha256:65b451949cb789c346f9f9002441fc934d8ccedcc9ec09daabc2139ad13853f7", size = 217176, upload-time = "2025-08-04T00:34:05.973Z" }, + { url = "https://files.pythonhosted.org/packages/1e/25/d458ba0bf16a8204a88d74dbb7ec5520f29937ffcbbc12371f931c11efd2/coverage-7.10.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:e8415918856a3e7d57a4e0ad94651b761317de459eb74d34cc1bb51aad80f07e", size = 216058, upload-time = "2025-08-04T00:34:07.368Z" }, + { url = "https://files.pythonhosted.org/packages/0b/1c/af4dfd2d7244dc7610fed6d59d57a23ea165681cd764445dc58d71ed01a6/coverage-7.10.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f287a25a8ca53901c613498e4a40885b19361a2fe8fbfdbb7f8ef2cad2a23f03", size = 216273, upload-time = "2025-08-04T00:34:09.073Z" }, + { url = "https://files.pythonhosted.org/packages/8e/67/ec5095d4035c6e16368226fa9cb15f77f891194c7e3725aeefd08e7a3e5a/coverage-7.10.2-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:75cc1a3f8c88c69bf16a871dab1fe5a7303fdb1e9f285f204b60f1ee539b8fc0", size = 257513, upload-time = "2025-08-04T00:34:10.403Z" }, + { url = "https://files.pythonhosted.org/packages/1c/47/be5550b57a3a8ba797de4236b0fd31031f88397b2afc84ab3c2d4cf265f6/coverage-7.10.2-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:ca07fa78cc9d26bc8c4740de1abd3489cf9c47cc06d9a8ab3d552ff5101af4c0", size = 259377, upload-time = "2025-08-04T00:34:12.138Z" }, + { url = "https://files.pythonhosted.org/packages/37/50/b12a4da1382e672305c2d17cd3029dc16b8a0470de2191dbf26b91431378/coverage-7.10.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c2e117e64c26300032755d4520cd769f2623cde1a1d1c3515b05a3b8add0ade1", size = 261516, upload-time = "2025-08-04T00:34:13.608Z" }, + { url = "https://files.pythonhosted.org/packages/db/41/4d3296dbd33dd8da178171540ca3391af7c0184c0870fd4d4574ac290290/coverage-7.10.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:daaf98009977f577b71f8800208f4d40d4dcf5c2db53d4d822787cdc198d76e1", size = 259110, upload-time = "2025-08-04T00:34:15.089Z" }, + { url = "https://files.pythonhosted.org/packages/ea/f1/b409959ecbc0cec0e61e65683b22bacaa4a3b11512f834e16dd8ffbc37db/coverage-7.10.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:ea8d8fe546c528535c761ba424410bbeb36ba8a0f24be653e94b70c93fd8a8ca", size = 257248, upload-time = "2025-08-04T00:34:16.501Z" }, + { url = "https://files.pythonhosted.org/packages/48/ab/7076dc1c240412e9267d36ec93e9e299d7659f6a5c1e958f87e998b0fb6d/coverage-7.10.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:fe024d40ac31eb8d5aae70215b41dafa264676caa4404ae155f77d2fa95c37bb", size = 258063, upload-time = "2025-08-04T00:34:18.338Z" }, + { url = "https://files.pythonhosted.org/packages/1e/77/f6b51a0288f8f5f7dcc7c89abdd22cf514f3bc5151284f5cd628917f8e10/coverage-7.10.2-cp313-cp313t-win32.whl", hash = "sha256:8f34b09f68bdadec122ffad312154eda965ade433559cc1eadd96cca3de5c824", size = 218433, upload-time = "2025-08-04T00:34:19.71Z" }, + { url = "https://files.pythonhosted.org/packages/7b/6d/547a86493e25270ce8481543e77f3a0aa3aa872c1374246b7b76273d66eb/coverage-7.10.2-cp313-cp313t-win_amd64.whl", hash = "sha256:71d40b3ac0f26fa9ffa6ee16219a714fed5c6ec197cdcd2018904ab5e75bcfa3", size = 219523, upload-time = "2025-08-04T00:34:21.171Z" }, + { url = "https://files.pythonhosted.org/packages/ff/d5/3c711e38eaf9ab587edc9bed232c0298aed84e751a9f54aaa556ceaf7da6/coverage-7.10.2-cp313-cp313t-win_arm64.whl", hash = "sha256:abb57fdd38bf6f7dcc66b38dafb7af7c5fdc31ac6029ce373a6f7f5331d6f60f", size = 217739, upload-time = "2025-08-04T00:34:22.514Z" }, + { url = "https://files.pythonhosted.org/packages/71/53/83bafa669bb9d06d4c8c6a055d8d05677216f9480c4698fb183ba7ec5e47/coverage-7.10.2-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:a3e853cc04987c85ec410905667eed4bf08b1d84d80dfab2684bb250ac8da4f6", size = 215328, upload-time = "2025-08-04T00:34:23.991Z" }, + { url = "https://files.pythonhosted.org/packages/1d/6c/30827a9c5a48a813e865fbaf91e2db25cce990bd223a022650ef2293fe11/coverage-7.10.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0100b19f230df72c90fdb36db59d3f39232391e8d89616a7de30f677da4f532b", size = 215608, upload-time = "2025-08-04T00:34:25.437Z" }, + { url = "https://files.pythonhosted.org/packages/bb/a0/c92d85948056ddc397b72a3d79d36d9579c53cb25393ed3c40db7d33b193/coverage-7.10.2-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:9c1cd71483ea78331bdfadb8dcec4f4edfb73c7002c1206d8e0af6797853f5be", size = 246111, upload-time = "2025-08-04T00:34:26.857Z" }, + { url = "https://files.pythonhosted.org/packages/c2/cf/d695cf86b2559aadd072c91720a7844be4fb82cb4a3b642a2c6ce075692d/coverage-7.10.2-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9f75dbf4899e29a37d74f48342f29279391668ef625fdac6d2f67363518056a1", size = 248419, upload-time = "2025-08-04T00:34:28.726Z" }, + { url = "https://files.pythonhosted.org/packages/ce/0a/03206aec4a05986e039418c038470d874045f6e00426b0c3879adc1f9251/coverage-7.10.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a7df481e7508de1c38b9b8043da48d94931aefa3e32b47dd20277e4978ed5b95", size = 250038, upload-time = "2025-08-04T00:34:30.061Z" }, + { url = "https://files.pythonhosted.org/packages/ab/9b/b3bd6bd52118c12bc4cf319f5baba65009c9beea84e665b6b9f03fa3f180/coverage-7.10.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:835f39e618099325e7612b3406f57af30ab0a0af350490eff6421e2e5f608e46", size = 248066, upload-time = "2025-08-04T00:34:31.53Z" }, + { url = "https://files.pythonhosted.org/packages/80/cc/bfa92e261d3e055c851a073e87ba6a3bff12a1f7134233e48a8f7d855875/coverage-7.10.2-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:12e52b5aa00aa720097d6947d2eb9e404e7c1101ad775f9661ba165ed0a28303", size = 245909, upload-time = "2025-08-04T00:34:32.943Z" }, + { url = "https://files.pythonhosted.org/packages/12/80/c8df15db4847710c72084164f615ae900af1ec380dce7f74a5678ccdf5e1/coverage-7.10.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:718044729bf1fe3e9eb9f31b52e44ddae07e434ec050c8c628bf5adc56fe4bdd", size = 247329, upload-time = "2025-08-04T00:34:34.388Z" }, + { url = "https://files.pythonhosted.org/packages/04/6f/cb66e1f7124d5dd9ced69f889f02931419cb448125e44a89a13f4e036124/coverage-7.10.2-cp314-cp314-win32.whl", hash = "sha256:f256173b48cc68486299d510a3e729a96e62c889703807482dbf56946befb5c8", size = 218007, upload-time = "2025-08-04T00:34:35.846Z" }, + { url = "https://files.pythonhosted.org/packages/8c/e1/3d4be307278ce32c1b9d95cc02ee60d54ddab784036101d053ec9e4fe7f5/coverage-7.10.2-cp314-cp314-win_amd64.whl", hash = "sha256:2e980e4179f33d9b65ac4acb86c9c0dde904098853f27f289766657ed16e07b3", size = 218802, upload-time = "2025-08-04T00:34:37.35Z" }, + { url = "https://files.pythonhosted.org/packages/ec/66/1e43bbeb66c55a5a5efec70f1c153cf90cfc7f1662ab4ebe2d844de9122c/coverage-7.10.2-cp314-cp314-win_arm64.whl", hash = "sha256:14fb5b6641ab5b3c4161572579f0f2ea8834f9d3af2f7dd8fbaecd58ef9175cc", size = 217397, upload-time = "2025-08-04T00:34:39.15Z" }, + { url = "https://files.pythonhosted.org/packages/81/01/ae29c129217f6110dc694a217475b8aecbb1b075d8073401f868c825fa99/coverage-7.10.2-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:e96649ac34a3d0e6491e82a2af71098e43be2874b619547c3282fc11d3840a4b", size = 216068, upload-time = "2025-08-04T00:34:40.648Z" }, + { url = "https://files.pythonhosted.org/packages/a2/50/6e9221d4139f357258f36dfa1d8cac4ec56d9d5acf5fdcc909bb016954d7/coverage-7.10.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1a2e934e9da26341d342d30bfe91422bbfdb3f1f069ec87f19b2909d10d8dcc4", size = 216285, upload-time = "2025-08-04T00:34:42.441Z" }, + { url = "https://files.pythonhosted.org/packages/eb/ec/89d1d0c0ece0d296b4588e0ef4df185200456d42a47f1141335f482c2fc5/coverage-7.10.2-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:651015dcd5fd9b5a51ca79ece60d353cacc5beaf304db750407b29c89f72fe2b", size = 257603, upload-time = "2025-08-04T00:34:43.899Z" }, + { url = "https://files.pythonhosted.org/packages/82/06/c830af66734671c778fc49d35b58339e8f0687fbd2ae285c3f96c94da092/coverage-7.10.2-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:81bf6a32212f9f66da03d63ecb9cd9bd48e662050a937db7199dbf47d19831de", size = 259568, upload-time = "2025-08-04T00:34:45.519Z" }, + { url = "https://files.pythonhosted.org/packages/60/57/f280dd6f1c556ecc744fbf39e835c33d3ae987d040d64d61c6f821e87829/coverage-7.10.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d800705f6951f75a905ea6feb03fff8f3ea3468b81e7563373ddc29aa3e5d1ca", size = 261691, upload-time = "2025-08-04T00:34:47.019Z" }, + { url = "https://files.pythonhosted.org/packages/54/2b/c63a0acbd19d99ec32326164c23df3a4e18984fb86e902afdd66ff7b3d83/coverage-7.10.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:248b5394718e10d067354448dc406d651709c6765669679311170da18e0e9af8", size = 259166, upload-time = "2025-08-04T00:34:48.792Z" }, + { url = "https://files.pythonhosted.org/packages/fd/c5/cd2997dcfcbf0683634da9df52d3967bc1f1741c1475dd0e4722012ba9ef/coverage-7.10.2-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:5c61675a922b569137cf943770d7ad3edd0202d992ce53ac328c5ff68213ccf4", size = 257241, upload-time = "2025-08-04T00:34:51.038Z" }, + { url = "https://files.pythonhosted.org/packages/16/26/c9e30f82fdad8d47aee90af4978b18c88fa74369ae0f0ba0dbf08cee3a80/coverage-7.10.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:52d708b5fd65589461381fa442d9905f5903d76c086c6a4108e8e9efdca7a7ed", size = 258139, upload-time = "2025-08-04T00:34:52.533Z" }, + { url = "https://files.pythonhosted.org/packages/c9/99/bdb7bd00bebcd3dedfb895fa9af8e46b91422993e4a37ac634a5f1113790/coverage-7.10.2-cp314-cp314t-win32.whl", hash = "sha256:916369b3b914186b2c5e5ad2f7264b02cff5df96cdd7cdad65dccd39aa5fd9f0", size = 218809, upload-time = "2025-08-04T00:34:54.075Z" }, + { url = "https://files.pythonhosted.org/packages/eb/5e/56a7852e38a04d1520dda4dfbfbf74a3d6dec932c20526968f7444763567/coverage-7.10.2-cp314-cp314t-win_amd64.whl", hash = "sha256:5b9d538e8e04916a5df63052d698b30c74eb0174f2ca9cd942c981f274a18eaf", size = 219926, upload-time = "2025-08-04T00:34:55.643Z" }, + { url = "https://files.pythonhosted.org/packages/e0/12/7fbe6b9c52bb9d627e9556f9f2edfdbe88b315e084cdecc9afead0c3b36a/coverage-7.10.2-cp314-cp314t-win_arm64.whl", hash = "sha256:04c74f9ef1f925456a9fd23a7eef1103126186d0500ef9a0acb0bd2514bdc7cc", size = 217925, upload-time = "2025-08-04T00:34:57.564Z" }, + { url = "https://files.pythonhosted.org/packages/18/d8/9b768ac73a8ac2d10c080af23937212434a958c8d2a1c84e89b450237942/coverage-7.10.2-py3-none-any.whl", hash = "sha256:95db3750dd2e6e93d99fa2498f3a1580581e49c494bddccc6f85c5c21604921f", size = 206973, upload-time = "2025-08-04T00:35:15.918Z" }, ] [[package]] @@ -311,18 +311,18 @@ dependencies = [ { name = "docopt" }, { name = "requests" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/61/75/a454fb443eb6a053833f61603a432ffbd7dd6ae53a11159bacfadb9d6219/coveralls-4.0.1.tar.gz", hash = "sha256:7b2a0a2bcef94f295e3cf28dcc55ca40b71c77d1c2446b538e85f0f7bc21aa69", size = 12419 } +sdist = { url = "https://files.pythonhosted.org/packages/61/75/a454fb443eb6a053833f61603a432ffbd7dd6ae53a11159bacfadb9d6219/coveralls-4.0.1.tar.gz", hash = "sha256:7b2a0a2bcef94f295e3cf28dcc55ca40b71c77d1c2446b538e85f0f7bc21aa69", size = 12419, upload-time = "2024-05-15T12:56:14.297Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/63/e5/6708c75e2a4cfca929302d4d9b53b862c6dc65bd75e6933ea3d20016d41d/coveralls-4.0.1-py3-none-any.whl", hash = "sha256:7a6b1fa9848332c7b2221afb20f3df90272ac0167060f41b5fe90429b30b1809", size = 13599 }, + { url = "https://files.pythonhosted.org/packages/63/e5/6708c75e2a4cfca929302d4d9b53b862c6dc65bd75e6933ea3d20016d41d/coveralls-4.0.1-py3-none-any.whl", hash = "sha256:7a6b1fa9848332c7b2221afb20f3df90272ac0167060f41b5fe90429b30b1809", size = 13599, upload-time = "2024-05-15T12:56:12.342Z" }, ] [[package]] name = "crccheck" version = "1.3.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/3c/d1/a943f4f1ca899917cc3fe1cb89d59348edd1b407503e4b02608e8d6b421e/crccheck-1.3.1.tar.gz", hash = "sha256:1544c0110bf0a697d875d4f29dc40d7079f9d4d402a9317383f55f90ca72563a", size = 41696 } +sdist = { url = "https://files.pythonhosted.org/packages/3c/d1/a943f4f1ca899917cc3fe1cb89d59348edd1b407503e4b02608e8d6b421e/crccheck-1.3.1.tar.gz", hash = "sha256:1544c0110bf0a697d875d4f29dc40d7079f9d4d402a9317383f55f90ca72563a", size = 41696, upload-time = "2025-07-10T07:01:08.683Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/01/b5/68a9054be852e61f31de1be4e8d95802646b93344ce17c2380a1748706fa/crccheck-1.3.1-py3-none-any.whl", hash = "sha256:1680c9a7bb1ca4bec45fa19b8ca64319f10d2ce4eb8b0d25d51cb99a20ca0108", size = 24608 }, + { url = "https://files.pythonhosted.org/packages/01/b5/68a9054be852e61f31de1be4e8d95802646b93344ce17c2380a1748706fa/crccheck-1.3.1-py3-none-any.whl", hash = "sha256:1680c9a7bb1ca4bec45fa19b8ca64319f10d2ce4eb8b0d25d51cb99a20ca0108", size = 24608, upload-time = "2025-07-10T07:01:07.25Z" }, ] [[package]] @@ -332,181 +332,181 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cffi", marker = "platform_python_implementation != 'PyPy'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d6/0d/d13399c94234ee8f3df384819dc67e0c5ce215fb751d567a55a1f4b028c7/cryptography-45.0.6.tar.gz", hash = "sha256:5c966c732cf6e4a276ce83b6e4c729edda2df6929083a952cc7da973c539c719", size = 744949 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/8c/29/2793d178d0eda1ca4a09a7c4e09a5185e75738cc6d526433e8663b460ea6/cryptography-45.0.6-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:048e7ad9e08cf4c0ab07ff7f36cc3115924e22e2266e034450a890d9e312dd74", size = 7042702 }, - { url = "https://files.pythonhosted.org/packages/b3/b6/cabd07410f222f32c8d55486c464f432808abaa1f12af9afcbe8f2f19030/cryptography-45.0.6-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:44647c5d796f5fc042bbc6d61307d04bf29bccb74d188f18051b635f20a9c75f", size = 4206483 }, - { url = "https://files.pythonhosted.org/packages/8b/9e/f9c7d36a38b1cfeb1cc74849aabe9bf817990f7603ff6eb485e0d70e0b27/cryptography-45.0.6-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e40b80ecf35ec265c452eea0ba94c9587ca763e739b8e559c128d23bff7ebbbf", size = 4429679 }, - { url = "https://files.pythonhosted.org/packages/9c/2a/4434c17eb32ef30b254b9e8b9830cee4e516f08b47fdd291c5b1255b8101/cryptography-45.0.6-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:00e8724bdad672d75e6f069b27970883179bd472cd24a63f6e620ca7e41cc0c5", size = 4210553 }, - { url = "https://files.pythonhosted.org/packages/ef/1d/09a5df8e0c4b7970f5d1f3aff1b640df6d4be28a64cae970d56c6cf1c772/cryptography-45.0.6-cp311-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7a3085d1b319d35296176af31c90338eeb2ddac8104661df79f80e1d9787b8b2", size = 3894499 }, - { url = "https://files.pythonhosted.org/packages/79/62/120842ab20d9150a9d3a6bdc07fe2870384e82f5266d41c53b08a3a96b34/cryptography-45.0.6-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:1b7fa6a1c1188c7ee32e47590d16a5a0646270921f8020efc9a511648e1b2e08", size = 4458484 }, - { url = "https://files.pythonhosted.org/packages/fd/80/1bc3634d45ddfed0871bfba52cf8f1ad724761662a0c792b97a951fb1b30/cryptography-45.0.6-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:275ba5cc0d9e320cd70f8e7b96d9e59903c815ca579ab96c1e37278d231fc402", size = 4210281 }, - { url = "https://files.pythonhosted.org/packages/7d/fe/ffb12c2d83d0ee625f124880a1f023b5878f79da92e64c37962bbbe35f3f/cryptography-45.0.6-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:f4028f29a9f38a2025abedb2e409973709c660d44319c61762202206ed577c42", size = 4456890 }, - { url = "https://files.pythonhosted.org/packages/8c/8e/b3f3fe0dc82c77a0deb5f493b23311e09193f2268b77196ec0f7a36e3f3e/cryptography-45.0.6-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ee411a1b977f40bd075392c80c10b58025ee5c6b47a822a33c1198598a7a5f05", size = 4333247 }, - { url = "https://files.pythonhosted.org/packages/b3/a6/c3ef2ab9e334da27a1d7b56af4a2417d77e7806b2e0f90d6267ce120d2e4/cryptography-45.0.6-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:e2a21a8eda2d86bb604934b6b37691585bd095c1f788530c1fcefc53a82b3453", size = 4565045 }, - { url = "https://files.pythonhosted.org/packages/31/c3/77722446b13fa71dddd820a5faab4ce6db49e7e0bf8312ef4192a3f78e2f/cryptography-45.0.6-cp311-abi3-win32.whl", hash = "sha256:d063341378d7ee9c91f9d23b431a3502fc8bfacd54ef0a27baa72a0843b29159", size = 2928923 }, - { url = "https://files.pythonhosted.org/packages/38/63/a025c3225188a811b82932a4dcc8457a26c3729d81578ccecbcce2cb784e/cryptography-45.0.6-cp311-abi3-win_amd64.whl", hash = "sha256:833dc32dfc1e39b7376a87b9a6a4288a10aae234631268486558920029b086ec", size = 3403805 }, - { url = "https://files.pythonhosted.org/packages/5b/af/bcfbea93a30809f126d51c074ee0fac5bd9d57d068edf56c2a73abedbea4/cryptography-45.0.6-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:3436128a60a5e5490603ab2adbabc8763613f638513ffa7d311c900a8349a2a0", size = 7020111 }, - { url = "https://files.pythonhosted.org/packages/98/c6/ea5173689e014f1a8470899cd5beeb358e22bb3cf5a876060f9d1ca78af4/cryptography-45.0.6-cp37-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0d9ef57b6768d9fa58e92f4947cea96ade1233c0e236db22ba44748ffedca394", size = 4198169 }, - { url = "https://files.pythonhosted.org/packages/ba/73/b12995edc0c7e2311ffb57ebd3b351f6b268fed37d93bfc6f9856e01c473/cryptography-45.0.6-cp37-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ea3c42f2016a5bbf71825537c2ad753f2870191134933196bee408aac397b3d9", size = 4421273 }, - { url = "https://files.pythonhosted.org/packages/f7/6e/286894f6f71926bc0da67408c853dd9ba953f662dcb70993a59fd499f111/cryptography-45.0.6-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:20ae4906a13716139d6d762ceb3e0e7e110f7955f3bc3876e3a07f5daadec5f3", size = 4199211 }, - { url = "https://files.pythonhosted.org/packages/de/34/a7f55e39b9623c5cb571d77a6a90387fe557908ffc44f6872f26ca8ae270/cryptography-45.0.6-cp37-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2dac5ec199038b8e131365e2324c03d20e97fe214af051d20c49db129844e8b3", size = 3883732 }, - { url = "https://files.pythonhosted.org/packages/f9/b9/c6d32edbcba0cd9f5df90f29ed46a65c4631c4fbe11187feb9169c6ff506/cryptography-45.0.6-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:18f878a34b90d688982e43f4b700408b478102dd58b3e39de21b5ebf6509c301", size = 4450655 }, - { url = "https://files.pythonhosted.org/packages/77/2d/09b097adfdee0227cfd4c699b3375a842080f065bab9014248933497c3f9/cryptography-45.0.6-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:5bd6020c80c5b2b2242d6c48487d7b85700f5e0038e67b29d706f98440d66eb5", size = 4198956 }, - { url = "https://files.pythonhosted.org/packages/55/66/061ec6689207d54effdff535bbdf85cc380d32dd5377173085812565cf38/cryptography-45.0.6-cp37-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:eccddbd986e43014263eda489abbddfbc287af5cddfd690477993dbb31e31016", size = 4449859 }, - { url = "https://files.pythonhosted.org/packages/41/ff/e7d5a2ad2d035e5a2af116e1a3adb4d8fcd0be92a18032917a089c6e5028/cryptography-45.0.6-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:550ae02148206beb722cfe4ef0933f9352bab26b087af00e48fdfb9ade35c5b3", size = 4320254 }, - { url = "https://files.pythonhosted.org/packages/82/27/092d311af22095d288f4db89fcaebadfb2f28944f3d790a4cf51fe5ddaeb/cryptography-45.0.6-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:5b64e668fc3528e77efa51ca70fadcd6610e8ab231e3e06ae2bab3b31c2b8ed9", size = 4554815 }, - { url = "https://files.pythonhosted.org/packages/7e/01/aa2f4940262d588a8fdf4edabe4cda45854d00ebc6eaac12568b3a491a16/cryptography-45.0.6-cp37-abi3-win32.whl", hash = "sha256:780c40fb751c7d2b0c6786ceee6b6f871e86e8718a8ff4bc35073ac353c7cd02", size = 2912147 }, - { url = "https://files.pythonhosted.org/packages/0a/bc/16e0276078c2de3ceef6b5a34b965f4436215efac45313df90d55f0ba2d2/cryptography-45.0.6-cp37-abi3-win_amd64.whl", hash = "sha256:20d15aed3ee522faac1a39fbfdfee25d17b1284bafd808e1640a74846d7c4d1b", size = 3390459 }, +sdist = { url = "https://files.pythonhosted.org/packages/d6/0d/d13399c94234ee8f3df384819dc67e0c5ce215fb751d567a55a1f4b028c7/cryptography-45.0.6.tar.gz", hash = "sha256:5c966c732cf6e4a276ce83b6e4c729edda2df6929083a952cc7da973c539c719", size = 744949, upload-time = "2025-08-05T23:59:27.93Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8c/29/2793d178d0eda1ca4a09a7c4e09a5185e75738cc6d526433e8663b460ea6/cryptography-45.0.6-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:048e7ad9e08cf4c0ab07ff7f36cc3115924e22e2266e034450a890d9e312dd74", size = 7042702, upload-time = "2025-08-05T23:58:23.464Z" }, + { url = "https://files.pythonhosted.org/packages/b3/b6/cabd07410f222f32c8d55486c464f432808abaa1f12af9afcbe8f2f19030/cryptography-45.0.6-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:44647c5d796f5fc042bbc6d61307d04bf29bccb74d188f18051b635f20a9c75f", size = 4206483, upload-time = "2025-08-05T23:58:27.132Z" }, + { url = "https://files.pythonhosted.org/packages/8b/9e/f9c7d36a38b1cfeb1cc74849aabe9bf817990f7603ff6eb485e0d70e0b27/cryptography-45.0.6-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e40b80ecf35ec265c452eea0ba94c9587ca763e739b8e559c128d23bff7ebbbf", size = 4429679, upload-time = "2025-08-05T23:58:29.152Z" }, + { url = "https://files.pythonhosted.org/packages/9c/2a/4434c17eb32ef30b254b9e8b9830cee4e516f08b47fdd291c5b1255b8101/cryptography-45.0.6-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:00e8724bdad672d75e6f069b27970883179bd472cd24a63f6e620ca7e41cc0c5", size = 4210553, upload-time = "2025-08-05T23:58:30.596Z" }, + { url = "https://files.pythonhosted.org/packages/ef/1d/09a5df8e0c4b7970f5d1f3aff1b640df6d4be28a64cae970d56c6cf1c772/cryptography-45.0.6-cp311-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7a3085d1b319d35296176af31c90338eeb2ddac8104661df79f80e1d9787b8b2", size = 3894499, upload-time = "2025-08-05T23:58:32.03Z" }, + { url = "https://files.pythonhosted.org/packages/79/62/120842ab20d9150a9d3a6bdc07fe2870384e82f5266d41c53b08a3a96b34/cryptography-45.0.6-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:1b7fa6a1c1188c7ee32e47590d16a5a0646270921f8020efc9a511648e1b2e08", size = 4458484, upload-time = "2025-08-05T23:58:33.526Z" }, + { url = "https://files.pythonhosted.org/packages/fd/80/1bc3634d45ddfed0871bfba52cf8f1ad724761662a0c792b97a951fb1b30/cryptography-45.0.6-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:275ba5cc0d9e320cd70f8e7b96d9e59903c815ca579ab96c1e37278d231fc402", size = 4210281, upload-time = "2025-08-05T23:58:35.445Z" }, + { url = "https://files.pythonhosted.org/packages/7d/fe/ffb12c2d83d0ee625f124880a1f023b5878f79da92e64c37962bbbe35f3f/cryptography-45.0.6-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:f4028f29a9f38a2025abedb2e409973709c660d44319c61762202206ed577c42", size = 4456890, upload-time = "2025-08-05T23:58:36.923Z" }, + { url = "https://files.pythonhosted.org/packages/8c/8e/b3f3fe0dc82c77a0deb5f493b23311e09193f2268b77196ec0f7a36e3f3e/cryptography-45.0.6-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ee411a1b977f40bd075392c80c10b58025ee5c6b47a822a33c1198598a7a5f05", size = 4333247, upload-time = "2025-08-05T23:58:38.781Z" }, + { url = "https://files.pythonhosted.org/packages/b3/a6/c3ef2ab9e334da27a1d7b56af4a2417d77e7806b2e0f90d6267ce120d2e4/cryptography-45.0.6-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:e2a21a8eda2d86bb604934b6b37691585bd095c1f788530c1fcefc53a82b3453", size = 4565045, upload-time = "2025-08-05T23:58:40.415Z" }, + { url = "https://files.pythonhosted.org/packages/31/c3/77722446b13fa71dddd820a5faab4ce6db49e7e0bf8312ef4192a3f78e2f/cryptography-45.0.6-cp311-abi3-win32.whl", hash = "sha256:d063341378d7ee9c91f9d23b431a3502fc8bfacd54ef0a27baa72a0843b29159", size = 2928923, upload-time = "2025-08-05T23:58:41.919Z" }, + { url = "https://files.pythonhosted.org/packages/38/63/a025c3225188a811b82932a4dcc8457a26c3729d81578ccecbcce2cb784e/cryptography-45.0.6-cp311-abi3-win_amd64.whl", hash = "sha256:833dc32dfc1e39b7376a87b9a6a4288a10aae234631268486558920029b086ec", size = 3403805, upload-time = "2025-08-05T23:58:43.792Z" }, + { url = "https://files.pythonhosted.org/packages/5b/af/bcfbea93a30809f126d51c074ee0fac5bd9d57d068edf56c2a73abedbea4/cryptography-45.0.6-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:3436128a60a5e5490603ab2adbabc8763613f638513ffa7d311c900a8349a2a0", size = 7020111, upload-time = "2025-08-05T23:58:45.316Z" }, + { url = "https://files.pythonhosted.org/packages/98/c6/ea5173689e014f1a8470899cd5beeb358e22bb3cf5a876060f9d1ca78af4/cryptography-45.0.6-cp37-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0d9ef57b6768d9fa58e92f4947cea96ade1233c0e236db22ba44748ffedca394", size = 4198169, upload-time = "2025-08-05T23:58:47.121Z" }, + { url = "https://files.pythonhosted.org/packages/ba/73/b12995edc0c7e2311ffb57ebd3b351f6b268fed37d93bfc6f9856e01c473/cryptography-45.0.6-cp37-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ea3c42f2016a5bbf71825537c2ad753f2870191134933196bee408aac397b3d9", size = 4421273, upload-time = "2025-08-05T23:58:48.557Z" }, + { url = "https://files.pythonhosted.org/packages/f7/6e/286894f6f71926bc0da67408c853dd9ba953f662dcb70993a59fd499f111/cryptography-45.0.6-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:20ae4906a13716139d6d762ceb3e0e7e110f7955f3bc3876e3a07f5daadec5f3", size = 4199211, upload-time = "2025-08-05T23:58:50.139Z" }, + { url = "https://files.pythonhosted.org/packages/de/34/a7f55e39b9623c5cb571d77a6a90387fe557908ffc44f6872f26ca8ae270/cryptography-45.0.6-cp37-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2dac5ec199038b8e131365e2324c03d20e97fe214af051d20c49db129844e8b3", size = 3883732, upload-time = "2025-08-05T23:58:52.253Z" }, + { url = "https://files.pythonhosted.org/packages/f9/b9/c6d32edbcba0cd9f5df90f29ed46a65c4631c4fbe11187feb9169c6ff506/cryptography-45.0.6-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:18f878a34b90d688982e43f4b700408b478102dd58b3e39de21b5ebf6509c301", size = 4450655, upload-time = "2025-08-05T23:58:53.848Z" }, + { url = "https://files.pythonhosted.org/packages/77/2d/09b097adfdee0227cfd4c699b3375a842080f065bab9014248933497c3f9/cryptography-45.0.6-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:5bd6020c80c5b2b2242d6c48487d7b85700f5e0038e67b29d706f98440d66eb5", size = 4198956, upload-time = "2025-08-05T23:58:55.209Z" }, + { url = "https://files.pythonhosted.org/packages/55/66/061ec6689207d54effdff535bbdf85cc380d32dd5377173085812565cf38/cryptography-45.0.6-cp37-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:eccddbd986e43014263eda489abbddfbc287af5cddfd690477993dbb31e31016", size = 4449859, upload-time = "2025-08-05T23:58:56.639Z" }, + { url = "https://files.pythonhosted.org/packages/41/ff/e7d5a2ad2d035e5a2af116e1a3adb4d8fcd0be92a18032917a089c6e5028/cryptography-45.0.6-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:550ae02148206beb722cfe4ef0933f9352bab26b087af00e48fdfb9ade35c5b3", size = 4320254, upload-time = "2025-08-05T23:58:58.833Z" }, + { url = "https://files.pythonhosted.org/packages/82/27/092d311af22095d288f4db89fcaebadfb2f28944f3d790a4cf51fe5ddaeb/cryptography-45.0.6-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:5b64e668fc3528e77efa51ca70fadcd6610e8ab231e3e06ae2bab3b31c2b8ed9", size = 4554815, upload-time = "2025-08-05T23:59:00.283Z" }, + { url = "https://files.pythonhosted.org/packages/7e/01/aa2f4940262d588a8fdf4edabe4cda45854d00ebc6eaac12568b3a491a16/cryptography-45.0.6-cp37-abi3-win32.whl", hash = "sha256:780c40fb751c7d2b0c6786ceee6b6f871e86e8718a8ff4bc35073ac353c7cd02", size = 2912147, upload-time = "2025-08-05T23:59:01.716Z" }, + { url = "https://files.pythonhosted.org/packages/0a/bc/16e0276078c2de3ceef6b5a34b965f4436215efac45313df90d55f0ba2d2/cryptography-45.0.6-cp37-abi3-win_amd64.whl", hash = "sha256:20d15aed3ee522faac1a39fbfdfee25d17b1284bafd808e1640a74846d7c4d1b", size = 3390459, upload-time = "2025-08-05T23:59:03.358Z" }, ] [[package]] name = "dill" version = "0.4.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/12/80/630b4b88364e9a8c8c5797f4602d0f76ef820909ee32f0bacb9f90654042/dill-0.4.0.tar.gz", hash = "sha256:0633f1d2df477324f53a895b02c901fb961bdbf65a17122586ea7019292cbcf0", size = 186976 } +sdist = { url = "https://files.pythonhosted.org/packages/12/80/630b4b88364e9a8c8c5797f4602d0f76ef820909ee32f0bacb9f90654042/dill-0.4.0.tar.gz", hash = "sha256:0633f1d2df477324f53a895b02c901fb961bdbf65a17122586ea7019292cbcf0", size = 186976, upload-time = "2025-04-16T00:41:48.867Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/50/3d/9373ad9c56321fdab5b41197068e1d8c25883b3fea29dd361f9b55116869/dill-0.4.0-py3-none-any.whl", hash = "sha256:44f54bf6412c2c8464c14e8243eb163690a9800dbe2c367330883b19c7561049", size = 119668 }, + { url = "https://files.pythonhosted.org/packages/50/3d/9373ad9c56321fdab5b41197068e1d8c25883b3fea29dd361f9b55116869/dill-0.4.0-py3-none-any.whl", hash = "sha256:44f54bf6412c2c8464c14e8243eb163690a9800dbe2c367330883b19c7561049", size = 119668, upload-time = "2025-04-16T00:41:47.671Z" }, ] [[package]] name = "distlib" version = "0.4.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/96/8e/709914eb2b5749865801041647dc7f4e6d00b549cfe88b65ca192995f07c/distlib-0.4.0.tar.gz", hash = "sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d", size = 614605 } +sdist = { url = "https://files.pythonhosted.org/packages/96/8e/709914eb2b5749865801041647dc7f4e6d00b549cfe88b65ca192995f07c/distlib-0.4.0.tar.gz", hash = "sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d", size = 614605, upload-time = "2025-07-17T16:52:00.465Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl", hash = "sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16", size = 469047 }, + { url = "https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl", hash = "sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16", size = 469047, upload-time = "2025-07-17T16:51:58.613Z" }, ] [[package]] name = "docopt" version = "0.6.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a2/55/8f8cab2afd404cf578136ef2cc5dfb50baa1761b68c9da1fb1e4eed343c9/docopt-0.6.2.tar.gz", hash = "sha256:49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491", size = 25901 } +sdist = { url = "https://files.pythonhosted.org/packages/a2/55/8f8cab2afd404cf578136ef2cc5dfb50baa1761b68c9da1fb1e4eed343c9/docopt-0.6.2.tar.gz", hash = "sha256:49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491", size = 25901, upload-time = "2014-06-16T11:18:57.406Z" } [[package]] name = "execnet" version = "2.1.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/bb/ff/b4c0dc78fbe20c3e59c0c7334de0c27eb4001a2b2017999af398bf730817/execnet-2.1.1.tar.gz", hash = "sha256:5189b52c6121c24feae288166ab41b32549c7e2348652736540b9e6e7d4e72e3", size = 166524 } +sdist = { url = "https://files.pythonhosted.org/packages/bb/ff/b4c0dc78fbe20c3e59c0c7334de0c27eb4001a2b2017999af398bf730817/execnet-2.1.1.tar.gz", hash = "sha256:5189b52c6121c24feae288166ab41b32549c7e2348652736540b9e6e7d4e72e3", size = 166524, upload-time = "2024-04-08T09:04:19.245Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/43/09/2aea36ff60d16dd8879bdb2f5b3ee0ba8d08cbbdcdfe870e695ce3784385/execnet-2.1.1-py3-none-any.whl", hash = "sha256:26dee51f1b80cebd6d0ca8e74dd8745419761d3bef34163928cbebbdc4749fdc", size = 40612 }, + { url = "https://files.pythonhosted.org/packages/43/09/2aea36ff60d16dd8879bdb2f5b3ee0ba8d08cbbdcdfe870e695ce3784385/execnet-2.1.1-py3-none-any.whl", hash = "sha256:26dee51f1b80cebd6d0ca8e74dd8745419761d3bef34163928cbebbdc4749fdc", size = 40612, upload-time = "2024-04-08T09:04:17.414Z" }, ] [[package]] name = "filelock" version = "3.18.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/0a/10/c23352565a6544bdc5353e0b15fc1c563352101f30e24bf500207a54df9a/filelock-3.18.0.tar.gz", hash = "sha256:adbc88eabb99d2fec8c9c1b229b171f18afa655400173ddc653d5d01501fb9f2", size = 18075 } +sdist = { url = "https://files.pythonhosted.org/packages/0a/10/c23352565a6544bdc5353e0b15fc1c563352101f30e24bf500207a54df9a/filelock-3.18.0.tar.gz", hash = "sha256:adbc88eabb99d2fec8c9c1b229b171f18afa655400173ddc653d5d01501fb9f2", size = 18075, upload-time = "2025-03-14T07:11:40.47Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4d/36/2a115987e2d8c300a974597416d9de88f2444426de9571f4b59b2cca3acc/filelock-3.18.0-py3-none-any.whl", hash = "sha256:c401f4f8377c4464e6db25fff06205fd89bdd83b65eb0488ed1b160f780e21de", size = 16215 }, + { url = "https://files.pythonhosted.org/packages/4d/36/2a115987e2d8c300a974597416d9de88f2444426de9571f4b59b2cca3acc/filelock-3.18.0-py3-none-any.whl", hash = "sha256:c401f4f8377c4464e6db25fff06205fd89bdd83b65eb0488ed1b160f780e21de", size = 16215, upload-time = "2025-03-14T07:11:39.145Z" }, ] [[package]] name = "frozendict" version = "2.4.6" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/bb/59/19eb300ba28e7547538bdf603f1c6c34793240a90e1a7b61b65d8517e35e/frozendict-2.4.6.tar.gz", hash = "sha256:df7cd16470fbd26fc4969a208efadc46319334eb97def1ddf48919b351192b8e", size = 316416 } +sdist = { url = "https://files.pythonhosted.org/packages/bb/59/19eb300ba28e7547538bdf603f1c6c34793240a90e1a7b61b65d8517e35e/frozendict-2.4.6.tar.gz", hash = "sha256:df7cd16470fbd26fc4969a208efadc46319334eb97def1ddf48919b351192b8e", size = 316416, upload-time = "2024-10-13T12:15:32.449Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/04/13/d9839089b900fa7b479cce495d62110cddc4bd5630a04d8469916c0e79c5/frozendict-2.4.6-py311-none-any.whl", hash = "sha256:d065db6a44db2e2375c23eac816f1a022feb2fa98cbb50df44a9e83700accbea", size = 16148 }, - { url = "https://files.pythonhosted.org/packages/ba/d0/d482c39cee2ab2978a892558cf130681d4574ea208e162da8958b31e9250/frozendict-2.4.6-py312-none-any.whl", hash = "sha256:49344abe90fb75f0f9fdefe6d4ef6d4894e640fadab71f11009d52ad97f370b9", size = 16146 }, - { url = "https://files.pythonhosted.org/packages/a5/8e/b6bf6a0de482d7d7d7a2aaac8fdc4a4d0bb24a809f5ddd422aa7060eb3d2/frozendict-2.4.6-py313-none-any.whl", hash = "sha256:7134a2bb95d4a16556bb5f2b9736dceb6ea848fa5b6f3f6c2d6dba93b44b4757", size = 16146 }, + { url = "https://files.pythonhosted.org/packages/04/13/d9839089b900fa7b479cce495d62110cddc4bd5630a04d8469916c0e79c5/frozendict-2.4.6-py311-none-any.whl", hash = "sha256:d065db6a44db2e2375c23eac816f1a022feb2fa98cbb50df44a9e83700accbea", size = 16148, upload-time = "2024-10-13T12:15:26.839Z" }, + { url = "https://files.pythonhosted.org/packages/ba/d0/d482c39cee2ab2978a892558cf130681d4574ea208e162da8958b31e9250/frozendict-2.4.6-py312-none-any.whl", hash = "sha256:49344abe90fb75f0f9fdefe6d4ef6d4894e640fadab71f11009d52ad97f370b9", size = 16146, upload-time = "2024-10-13T12:15:28.16Z" }, + { url = "https://files.pythonhosted.org/packages/a5/8e/b6bf6a0de482d7d7d7a2aaac8fdc4a4d0bb24a809f5ddd422aa7060eb3d2/frozendict-2.4.6-py313-none-any.whl", hash = "sha256:7134a2bb95d4a16556bb5f2b9736dceb6ea848fa5b6f3f6c2d6dba93b44b4757", size = 16146, upload-time = "2024-10-13T12:15:29.495Z" }, ] [[package]] name = "frozenlist" version = "1.7.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/79/b1/b64018016eeb087db503b038296fd782586432b9c077fc5c7839e9cb6ef6/frozenlist-1.7.0.tar.gz", hash = "sha256:2e310d81923c2437ea8670467121cc3e9b0f76d3043cc1d2331d56c7fb7a3a8f", size = 45078 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ef/a2/c8131383f1e66adad5f6ecfcce383d584ca94055a34d683bbb24ac5f2f1c/frozenlist-1.7.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:3dbf9952c4bb0e90e98aec1bd992b3318685005702656bc6f67c1a32b76787f2", size = 81424 }, - { url = "https://files.pythonhosted.org/packages/4c/9d/02754159955088cb52567337d1113f945b9e444c4960771ea90eb73de8db/frozenlist-1.7.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:1f5906d3359300b8a9bb194239491122e6cf1444c2efb88865426f170c262cdb", size = 47952 }, - { url = "https://files.pythonhosted.org/packages/01/7a/0046ef1bd6699b40acd2067ed6d6670b4db2f425c56980fa21c982c2a9db/frozenlist-1.7.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3dabd5a8f84573c8d10d8859a50ea2dec01eea372031929871368c09fa103478", size = 46688 }, - { url = "https://files.pythonhosted.org/packages/d6/a2/a910bafe29c86997363fb4c02069df4ff0b5bc39d33c5198b4e9dd42d8f8/frozenlist-1.7.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa57daa5917f1738064f302bf2626281a1cb01920c32f711fbc7bc36111058a8", size = 243084 }, - { url = "https://files.pythonhosted.org/packages/64/3e/5036af9d5031374c64c387469bfcc3af537fc0f5b1187d83a1cf6fab1639/frozenlist-1.7.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c193dda2b6d49f4c4398962810fa7d7c78f032bf45572b3e04dd5249dff27e08", size = 233524 }, - { url = "https://files.pythonhosted.org/packages/06/39/6a17b7c107a2887e781a48ecf20ad20f1c39d94b2a548c83615b5b879f28/frozenlist-1.7.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bfe2b675cf0aaa6d61bf8fbffd3c274b3c9b7b1623beb3809df8a81399a4a9c4", size = 248493 }, - { url = "https://files.pythonhosted.org/packages/be/00/711d1337c7327d88c44d91dd0f556a1c47fb99afc060ae0ef66b4d24793d/frozenlist-1.7.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8fc5d5cda37f62b262405cf9652cf0856839c4be8ee41be0afe8858f17f4c94b", size = 244116 }, - { url = "https://files.pythonhosted.org/packages/24/fe/74e6ec0639c115df13d5850e75722750adabdc7de24e37e05a40527ca539/frozenlist-1.7.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b0d5ce521d1dd7d620198829b87ea002956e4319002ef0bc8d3e6d045cb4646e", size = 224557 }, - { url = "https://files.pythonhosted.org/packages/8d/db/48421f62a6f77c553575201e89048e97198046b793f4a089c79a6e3268bd/frozenlist-1.7.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:488d0a7d6a0008ca0db273c542098a0fa9e7dfaa7e57f70acef43f32b3f69dca", size = 241820 }, - { url = "https://files.pythonhosted.org/packages/1d/fa/cb4a76bea23047c8462976ea7b7a2bf53997a0ca171302deae9d6dd12096/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:15a7eaba63983d22c54d255b854e8108e7e5f3e89f647fc854bd77a237e767df", size = 236542 }, - { url = "https://files.pythonhosted.org/packages/5d/32/476a4b5cfaa0ec94d3f808f193301debff2ea42288a099afe60757ef6282/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:1eaa7e9c6d15df825bf255649e05bd8a74b04a4d2baa1ae46d9c2d00b2ca2cb5", size = 249350 }, - { url = "https://files.pythonhosted.org/packages/8d/ba/9a28042f84a6bf8ea5dbc81cfff8eaef18d78b2a1ad9d51c7bc5b029ad16/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e4389e06714cfa9d47ab87f784a7c5be91d3934cd6e9a7b85beef808297cc025", size = 225093 }, - { url = "https://files.pythonhosted.org/packages/bc/29/3a32959e68f9cf000b04e79ba574527c17e8842e38c91d68214a37455786/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:73bd45e1488c40b63fe5a7df892baf9e2a4d4bb6409a2b3b78ac1c6236178e01", size = 245482 }, - { url = "https://files.pythonhosted.org/packages/80/e8/edf2f9e00da553f07f5fa165325cfc302dead715cab6ac8336a5f3d0adc2/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:99886d98e1643269760e5fe0df31e5ae7050788dd288947f7f007209b8c33f08", size = 249590 }, - { url = "https://files.pythonhosted.org/packages/1c/80/9a0eb48b944050f94cc51ee1c413eb14a39543cc4f760ed12657a5a3c45a/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:290a172aae5a4c278c6da8a96222e6337744cd9c77313efe33d5670b9f65fc43", size = 237785 }, - { url = "https://files.pythonhosted.org/packages/f3/74/87601e0fb0369b7a2baf404ea921769c53b7ae00dee7dcfe5162c8c6dbf0/frozenlist-1.7.0-cp312-cp312-win32.whl", hash = "sha256:426c7bc70e07cfebc178bc4c2bf2d861d720c4fff172181eeb4a4c41d4ca2ad3", size = 39487 }, - { url = "https://files.pythonhosted.org/packages/0b/15/c026e9a9fc17585a9d461f65d8593d281fedf55fbf7eb53f16c6df2392f9/frozenlist-1.7.0-cp312-cp312-win_amd64.whl", hash = "sha256:563b72efe5da92e02eb68c59cb37205457c977aa7a449ed1b37e6939e5c47c6a", size = 43874 }, - { url = "https://files.pythonhosted.org/packages/24/90/6b2cebdabdbd50367273c20ff6b57a3dfa89bd0762de02c3a1eb42cb6462/frozenlist-1.7.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ee80eeda5e2a4e660651370ebffd1286542b67e268aa1ac8d6dbe973120ef7ee", size = 79791 }, - { url = "https://files.pythonhosted.org/packages/83/2e/5b70b6a3325363293fe5fc3ae74cdcbc3e996c2a11dde2fd9f1fb0776d19/frozenlist-1.7.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d1a81c85417b914139e3a9b995d4a1c84559afc839a93cf2cb7f15e6e5f6ed2d", size = 47165 }, - { url = "https://files.pythonhosted.org/packages/f4/25/a0895c99270ca6966110f4ad98e87e5662eab416a17e7fd53c364bf8b954/frozenlist-1.7.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cbb65198a9132ebc334f237d7b0df163e4de83fb4f2bdfe46c1e654bdb0c5d43", size = 45881 }, - { url = "https://files.pythonhosted.org/packages/19/7c/71bb0bbe0832793c601fff68cd0cf6143753d0c667f9aec93d3c323f4b55/frozenlist-1.7.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dab46c723eeb2c255a64f9dc05b8dd601fde66d6b19cdb82b2e09cc6ff8d8b5d", size = 232409 }, - { url = "https://files.pythonhosted.org/packages/c0/45/ed2798718910fe6eb3ba574082aaceff4528e6323f9a8570be0f7028d8e9/frozenlist-1.7.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6aeac207a759d0dedd2e40745575ae32ab30926ff4fa49b1635def65806fddee", size = 225132 }, - { url = "https://files.pythonhosted.org/packages/ba/e2/8417ae0f8eacb1d071d4950f32f229aa6bf68ab69aab797b72a07ea68d4f/frozenlist-1.7.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bd8c4e58ad14b4fa7802b8be49d47993182fdd4023393899632c88fd8cd994eb", size = 237638 }, - { url = "https://files.pythonhosted.org/packages/f8/b7/2ace5450ce85f2af05a871b8c8719b341294775a0a6c5585d5e6170f2ce7/frozenlist-1.7.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:04fb24d104f425da3540ed83cbfc31388a586a7696142004c577fa61c6298c3f", size = 233539 }, - { url = "https://files.pythonhosted.org/packages/46/b9/6989292c5539553dba63f3c83dc4598186ab2888f67c0dc1d917e6887db6/frozenlist-1.7.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6a5c505156368e4ea6b53b5ac23c92d7edc864537ff911d2fb24c140bb175e60", size = 215646 }, - { url = "https://files.pythonhosted.org/packages/72/31/bc8c5c99c7818293458fe745dab4fd5730ff49697ccc82b554eb69f16a24/frozenlist-1.7.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8bd7eb96a675f18aa5c553eb7ddc24a43c8c18f22e1f9925528128c052cdbe00", size = 232233 }, - { url = "https://files.pythonhosted.org/packages/59/52/460db4d7ba0811b9ccb85af996019f5d70831f2f5f255f7cc61f86199795/frozenlist-1.7.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:05579bf020096fe05a764f1f84cd104a12f78eaab68842d036772dc6d4870b4b", size = 227996 }, - { url = "https://files.pythonhosted.org/packages/ba/c9/f4b39e904c03927b7ecf891804fd3b4df3db29b9e487c6418e37988d6e9d/frozenlist-1.7.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:376b6222d114e97eeec13d46c486facd41d4f43bab626b7c3f6a8b4e81a5192c", size = 242280 }, - { url = "https://files.pythonhosted.org/packages/b8/33/3f8d6ced42f162d743e3517781566b8481322be321b486d9d262adf70bfb/frozenlist-1.7.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:0aa7e176ebe115379b5b1c95b4096fb1c17cce0847402e227e712c27bdb5a949", size = 217717 }, - { url = "https://files.pythonhosted.org/packages/3e/e8/ad683e75da6ccef50d0ab0c2b2324b32f84fc88ceee778ed79b8e2d2fe2e/frozenlist-1.7.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3fbba20e662b9c2130dc771e332a99eff5da078b2b2648153a40669a6d0e36ca", size = 236644 }, - { url = "https://files.pythonhosted.org/packages/b2/14/8d19ccdd3799310722195a72ac94ddc677541fb4bef4091d8e7775752360/frozenlist-1.7.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:f3f4410a0a601d349dd406b5713fec59b4cee7e71678d5b17edda7f4655a940b", size = 238879 }, - { url = "https://files.pythonhosted.org/packages/ce/13/c12bf657494c2fd1079a48b2db49fa4196325909249a52d8f09bc9123fd7/frozenlist-1.7.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e2cdfaaec6a2f9327bf43c933c0319a7c429058e8537c508964a133dffee412e", size = 232502 }, - { url = "https://files.pythonhosted.org/packages/d7/8b/e7f9dfde869825489382bc0d512c15e96d3964180c9499efcec72e85db7e/frozenlist-1.7.0-cp313-cp313-win32.whl", hash = "sha256:5fc4df05a6591c7768459caba1b342d9ec23fa16195e744939ba5914596ae3e1", size = 39169 }, - { url = "https://files.pythonhosted.org/packages/35/89/a487a98d94205d85745080a37860ff5744b9820a2c9acbcdd9440bfddf98/frozenlist-1.7.0-cp313-cp313-win_amd64.whl", hash = "sha256:52109052b9791a3e6b5d1b65f4b909703984b770694d3eb64fad124c835d7cba", size = 43219 }, - { url = "https://files.pythonhosted.org/packages/56/d5/5c4cf2319a49eddd9dd7145e66c4866bdc6f3dbc67ca3d59685149c11e0d/frozenlist-1.7.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:a6f86e4193bb0e235ef6ce3dde5cbabed887e0b11f516ce8a0f4d3b33078ec2d", size = 84345 }, - { url = "https://files.pythonhosted.org/packages/a4/7d/ec2c1e1dc16b85bc9d526009961953df9cec8481b6886debb36ec9107799/frozenlist-1.7.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:82d664628865abeb32d90ae497fb93df398a69bb3434463d172b80fc25b0dd7d", size = 48880 }, - { url = "https://files.pythonhosted.org/packages/69/86/f9596807b03de126e11e7d42ac91e3d0b19a6599c714a1989a4e85eeefc4/frozenlist-1.7.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:912a7e8375a1c9a68325a902f3953191b7b292aa3c3fb0d71a216221deca460b", size = 48498 }, - { url = "https://files.pythonhosted.org/packages/5e/cb/df6de220f5036001005f2d726b789b2c0b65f2363b104bbc16f5be8084f8/frozenlist-1.7.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9537c2777167488d539bc5de2ad262efc44388230e5118868e172dd4a552b146", size = 292296 }, - { url = "https://files.pythonhosted.org/packages/83/1f/de84c642f17c8f851a2905cee2dae401e5e0daca9b5ef121e120e19aa825/frozenlist-1.7.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:f34560fb1b4c3e30ba35fa9a13894ba39e5acfc5f60f57d8accde65f46cc5e74", size = 273103 }, - { url = "https://files.pythonhosted.org/packages/88/3c/c840bfa474ba3fa13c772b93070893c6e9d5c0350885760376cbe3b6c1b3/frozenlist-1.7.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:acd03d224b0175f5a850edc104ac19040d35419eddad04e7cf2d5986d98427f1", size = 292869 }, - { url = "https://files.pythonhosted.org/packages/a6/1c/3efa6e7d5a39a1d5ef0abeb51c48fb657765794a46cf124e5aca2c7a592c/frozenlist-1.7.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f2038310bc582f3d6a09b3816ab01737d60bf7b1ec70f5356b09e84fb7408ab1", size = 291467 }, - { url = "https://files.pythonhosted.org/packages/4f/00/d5c5e09d4922c395e2f2f6b79b9a20dab4b67daaf78ab92e7729341f61f6/frozenlist-1.7.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b8c05e4c8e5f36e5e088caa1bf78a687528f83c043706640a92cb76cd6999384", size = 266028 }, - { url = "https://files.pythonhosted.org/packages/4e/27/72765be905619dfde25a7f33813ac0341eb6b076abede17a2e3fbfade0cb/frozenlist-1.7.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:765bb588c86e47d0b68f23c1bee323d4b703218037765dcf3f25c838c6fecceb", size = 284294 }, - { url = "https://files.pythonhosted.org/packages/88/67/c94103a23001b17808eb7dd1200c156bb69fb68e63fcf0693dde4cd6228c/frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:32dc2e08c67d86d0969714dd484fd60ff08ff81d1a1e40a77dd34a387e6ebc0c", size = 281898 }, - { url = "https://files.pythonhosted.org/packages/42/34/a3e2c00c00f9e2a9db5653bca3fec306349e71aff14ae45ecc6d0951dd24/frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:c0303e597eb5a5321b4de9c68e9845ac8f290d2ab3f3e2c864437d3c5a30cd65", size = 290465 }, - { url = "https://files.pythonhosted.org/packages/bb/73/f89b7fbce8b0b0c095d82b008afd0590f71ccb3dee6eee41791cf8cd25fd/frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:a47f2abb4e29b3a8d0b530f7c3598badc6b134562b1a5caee867f7c62fee51e3", size = 266385 }, - { url = "https://files.pythonhosted.org/packages/cd/45/e365fdb554159462ca12df54bc59bfa7a9a273ecc21e99e72e597564d1ae/frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:3d688126c242a6fabbd92e02633414d40f50bb6002fa4cf995a1d18051525657", size = 288771 }, - { url = "https://files.pythonhosted.org/packages/00/11/47b6117002a0e904f004d70ec5194fe9144f117c33c851e3d51c765962d0/frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:4e7e9652b3d367c7bd449a727dc79d5043f48b88d0cbfd4f9f1060cf2b414104", size = 288206 }, - { url = "https://files.pythonhosted.org/packages/40/37/5f9f3c3fd7f7746082ec67bcdc204db72dad081f4f83a503d33220a92973/frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:1a85e345b4c43db8b842cab1feb41be5cc0b10a1830e6295b69d7310f99becaf", size = 282620 }, - { url = "https://files.pythonhosted.org/packages/0b/31/8fbc5af2d183bff20f21aa743b4088eac4445d2bb1cdece449ae80e4e2d1/frozenlist-1.7.0-cp313-cp313t-win32.whl", hash = "sha256:3a14027124ddb70dfcee5148979998066897e79f89f64b13328595c4bdf77c81", size = 43059 }, - { url = "https://files.pythonhosted.org/packages/bb/ed/41956f52105b8dbc26e457c5705340c67c8cc2b79f394b79bffc09d0e938/frozenlist-1.7.0-cp313-cp313t-win_amd64.whl", hash = "sha256:3bf8010d71d4507775f658e9823210b7427be36625b387221642725b515dcf3e", size = 47516 }, - { url = "https://files.pythonhosted.org/packages/ee/45/b82e3c16be2182bff01179db177fe144d58b5dc787a7d4492c6ed8b9317f/frozenlist-1.7.0-py3-none-any.whl", hash = "sha256:9a5af342e34f7e97caf8c995864c7a396418ae2859cc6fdf1b1073020d516a7e", size = 13106 }, +sdist = { url = "https://files.pythonhosted.org/packages/79/b1/b64018016eeb087db503b038296fd782586432b9c077fc5c7839e9cb6ef6/frozenlist-1.7.0.tar.gz", hash = "sha256:2e310d81923c2437ea8670467121cc3e9b0f76d3043cc1d2331d56c7fb7a3a8f", size = 45078, upload-time = "2025-06-09T23:02:35.538Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/a2/c8131383f1e66adad5f6ecfcce383d584ca94055a34d683bbb24ac5f2f1c/frozenlist-1.7.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:3dbf9952c4bb0e90e98aec1bd992b3318685005702656bc6f67c1a32b76787f2", size = 81424, upload-time = "2025-06-09T23:00:42.24Z" }, + { url = "https://files.pythonhosted.org/packages/4c/9d/02754159955088cb52567337d1113f945b9e444c4960771ea90eb73de8db/frozenlist-1.7.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:1f5906d3359300b8a9bb194239491122e6cf1444c2efb88865426f170c262cdb", size = 47952, upload-time = "2025-06-09T23:00:43.481Z" }, + { url = "https://files.pythonhosted.org/packages/01/7a/0046ef1bd6699b40acd2067ed6d6670b4db2f425c56980fa21c982c2a9db/frozenlist-1.7.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3dabd5a8f84573c8d10d8859a50ea2dec01eea372031929871368c09fa103478", size = 46688, upload-time = "2025-06-09T23:00:44.793Z" }, + { url = "https://files.pythonhosted.org/packages/d6/a2/a910bafe29c86997363fb4c02069df4ff0b5bc39d33c5198b4e9dd42d8f8/frozenlist-1.7.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa57daa5917f1738064f302bf2626281a1cb01920c32f711fbc7bc36111058a8", size = 243084, upload-time = "2025-06-09T23:00:46.125Z" }, + { url = "https://files.pythonhosted.org/packages/64/3e/5036af9d5031374c64c387469bfcc3af537fc0f5b1187d83a1cf6fab1639/frozenlist-1.7.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c193dda2b6d49f4c4398962810fa7d7c78f032bf45572b3e04dd5249dff27e08", size = 233524, upload-time = "2025-06-09T23:00:47.73Z" }, + { url = "https://files.pythonhosted.org/packages/06/39/6a17b7c107a2887e781a48ecf20ad20f1c39d94b2a548c83615b5b879f28/frozenlist-1.7.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bfe2b675cf0aaa6d61bf8fbffd3c274b3c9b7b1623beb3809df8a81399a4a9c4", size = 248493, upload-time = "2025-06-09T23:00:49.742Z" }, + { url = "https://files.pythonhosted.org/packages/be/00/711d1337c7327d88c44d91dd0f556a1c47fb99afc060ae0ef66b4d24793d/frozenlist-1.7.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8fc5d5cda37f62b262405cf9652cf0856839c4be8ee41be0afe8858f17f4c94b", size = 244116, upload-time = "2025-06-09T23:00:51.352Z" }, + { url = "https://files.pythonhosted.org/packages/24/fe/74e6ec0639c115df13d5850e75722750adabdc7de24e37e05a40527ca539/frozenlist-1.7.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b0d5ce521d1dd7d620198829b87ea002956e4319002ef0bc8d3e6d045cb4646e", size = 224557, upload-time = "2025-06-09T23:00:52.855Z" }, + { url = "https://files.pythonhosted.org/packages/8d/db/48421f62a6f77c553575201e89048e97198046b793f4a089c79a6e3268bd/frozenlist-1.7.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:488d0a7d6a0008ca0db273c542098a0fa9e7dfaa7e57f70acef43f32b3f69dca", size = 241820, upload-time = "2025-06-09T23:00:54.43Z" }, + { url = "https://files.pythonhosted.org/packages/1d/fa/cb4a76bea23047c8462976ea7b7a2bf53997a0ca171302deae9d6dd12096/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:15a7eaba63983d22c54d255b854e8108e7e5f3e89f647fc854bd77a237e767df", size = 236542, upload-time = "2025-06-09T23:00:56.409Z" }, + { url = "https://files.pythonhosted.org/packages/5d/32/476a4b5cfaa0ec94d3f808f193301debff2ea42288a099afe60757ef6282/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:1eaa7e9c6d15df825bf255649e05bd8a74b04a4d2baa1ae46d9c2d00b2ca2cb5", size = 249350, upload-time = "2025-06-09T23:00:58.468Z" }, + { url = "https://files.pythonhosted.org/packages/8d/ba/9a28042f84a6bf8ea5dbc81cfff8eaef18d78b2a1ad9d51c7bc5b029ad16/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e4389e06714cfa9d47ab87f784a7c5be91d3934cd6e9a7b85beef808297cc025", size = 225093, upload-time = "2025-06-09T23:01:00.015Z" }, + { url = "https://files.pythonhosted.org/packages/bc/29/3a32959e68f9cf000b04e79ba574527c17e8842e38c91d68214a37455786/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:73bd45e1488c40b63fe5a7df892baf9e2a4d4bb6409a2b3b78ac1c6236178e01", size = 245482, upload-time = "2025-06-09T23:01:01.474Z" }, + { url = "https://files.pythonhosted.org/packages/80/e8/edf2f9e00da553f07f5fa165325cfc302dead715cab6ac8336a5f3d0adc2/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:99886d98e1643269760e5fe0df31e5ae7050788dd288947f7f007209b8c33f08", size = 249590, upload-time = "2025-06-09T23:01:02.961Z" }, + { url = "https://files.pythonhosted.org/packages/1c/80/9a0eb48b944050f94cc51ee1c413eb14a39543cc4f760ed12657a5a3c45a/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:290a172aae5a4c278c6da8a96222e6337744cd9c77313efe33d5670b9f65fc43", size = 237785, upload-time = "2025-06-09T23:01:05.095Z" }, + { url = "https://files.pythonhosted.org/packages/f3/74/87601e0fb0369b7a2baf404ea921769c53b7ae00dee7dcfe5162c8c6dbf0/frozenlist-1.7.0-cp312-cp312-win32.whl", hash = "sha256:426c7bc70e07cfebc178bc4c2bf2d861d720c4fff172181eeb4a4c41d4ca2ad3", size = 39487, upload-time = "2025-06-09T23:01:06.54Z" }, + { url = "https://files.pythonhosted.org/packages/0b/15/c026e9a9fc17585a9d461f65d8593d281fedf55fbf7eb53f16c6df2392f9/frozenlist-1.7.0-cp312-cp312-win_amd64.whl", hash = "sha256:563b72efe5da92e02eb68c59cb37205457c977aa7a449ed1b37e6939e5c47c6a", size = 43874, upload-time = "2025-06-09T23:01:07.752Z" }, + { url = "https://files.pythonhosted.org/packages/24/90/6b2cebdabdbd50367273c20ff6b57a3dfa89bd0762de02c3a1eb42cb6462/frozenlist-1.7.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ee80eeda5e2a4e660651370ebffd1286542b67e268aa1ac8d6dbe973120ef7ee", size = 79791, upload-time = "2025-06-09T23:01:09.368Z" }, + { url = "https://files.pythonhosted.org/packages/83/2e/5b70b6a3325363293fe5fc3ae74cdcbc3e996c2a11dde2fd9f1fb0776d19/frozenlist-1.7.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d1a81c85417b914139e3a9b995d4a1c84559afc839a93cf2cb7f15e6e5f6ed2d", size = 47165, upload-time = "2025-06-09T23:01:10.653Z" }, + { url = "https://files.pythonhosted.org/packages/f4/25/a0895c99270ca6966110f4ad98e87e5662eab416a17e7fd53c364bf8b954/frozenlist-1.7.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cbb65198a9132ebc334f237d7b0df163e4de83fb4f2bdfe46c1e654bdb0c5d43", size = 45881, upload-time = "2025-06-09T23:01:12.296Z" }, + { url = "https://files.pythonhosted.org/packages/19/7c/71bb0bbe0832793c601fff68cd0cf6143753d0c667f9aec93d3c323f4b55/frozenlist-1.7.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dab46c723eeb2c255a64f9dc05b8dd601fde66d6b19cdb82b2e09cc6ff8d8b5d", size = 232409, upload-time = "2025-06-09T23:01:13.641Z" }, + { url = "https://files.pythonhosted.org/packages/c0/45/ed2798718910fe6eb3ba574082aaceff4528e6323f9a8570be0f7028d8e9/frozenlist-1.7.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6aeac207a759d0dedd2e40745575ae32ab30926ff4fa49b1635def65806fddee", size = 225132, upload-time = "2025-06-09T23:01:15.264Z" }, + { url = "https://files.pythonhosted.org/packages/ba/e2/8417ae0f8eacb1d071d4950f32f229aa6bf68ab69aab797b72a07ea68d4f/frozenlist-1.7.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bd8c4e58ad14b4fa7802b8be49d47993182fdd4023393899632c88fd8cd994eb", size = 237638, upload-time = "2025-06-09T23:01:16.752Z" }, + { url = "https://files.pythonhosted.org/packages/f8/b7/2ace5450ce85f2af05a871b8c8719b341294775a0a6c5585d5e6170f2ce7/frozenlist-1.7.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:04fb24d104f425da3540ed83cbfc31388a586a7696142004c577fa61c6298c3f", size = 233539, upload-time = "2025-06-09T23:01:18.202Z" }, + { url = "https://files.pythonhosted.org/packages/46/b9/6989292c5539553dba63f3c83dc4598186ab2888f67c0dc1d917e6887db6/frozenlist-1.7.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6a5c505156368e4ea6b53b5ac23c92d7edc864537ff911d2fb24c140bb175e60", size = 215646, upload-time = "2025-06-09T23:01:19.649Z" }, + { url = "https://files.pythonhosted.org/packages/72/31/bc8c5c99c7818293458fe745dab4fd5730ff49697ccc82b554eb69f16a24/frozenlist-1.7.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8bd7eb96a675f18aa5c553eb7ddc24a43c8c18f22e1f9925528128c052cdbe00", size = 232233, upload-time = "2025-06-09T23:01:21.175Z" }, + { url = "https://files.pythonhosted.org/packages/59/52/460db4d7ba0811b9ccb85af996019f5d70831f2f5f255f7cc61f86199795/frozenlist-1.7.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:05579bf020096fe05a764f1f84cd104a12f78eaab68842d036772dc6d4870b4b", size = 227996, upload-time = "2025-06-09T23:01:23.098Z" }, + { url = "https://files.pythonhosted.org/packages/ba/c9/f4b39e904c03927b7ecf891804fd3b4df3db29b9e487c6418e37988d6e9d/frozenlist-1.7.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:376b6222d114e97eeec13d46c486facd41d4f43bab626b7c3f6a8b4e81a5192c", size = 242280, upload-time = "2025-06-09T23:01:24.808Z" }, + { url = "https://files.pythonhosted.org/packages/b8/33/3f8d6ced42f162d743e3517781566b8481322be321b486d9d262adf70bfb/frozenlist-1.7.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:0aa7e176ebe115379b5b1c95b4096fb1c17cce0847402e227e712c27bdb5a949", size = 217717, upload-time = "2025-06-09T23:01:26.28Z" }, + { url = "https://files.pythonhosted.org/packages/3e/e8/ad683e75da6ccef50d0ab0c2b2324b32f84fc88ceee778ed79b8e2d2fe2e/frozenlist-1.7.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3fbba20e662b9c2130dc771e332a99eff5da078b2b2648153a40669a6d0e36ca", size = 236644, upload-time = "2025-06-09T23:01:27.887Z" }, + { url = "https://files.pythonhosted.org/packages/b2/14/8d19ccdd3799310722195a72ac94ddc677541fb4bef4091d8e7775752360/frozenlist-1.7.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:f3f4410a0a601d349dd406b5713fec59b4cee7e71678d5b17edda7f4655a940b", size = 238879, upload-time = "2025-06-09T23:01:29.524Z" }, + { url = "https://files.pythonhosted.org/packages/ce/13/c12bf657494c2fd1079a48b2db49fa4196325909249a52d8f09bc9123fd7/frozenlist-1.7.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e2cdfaaec6a2f9327bf43c933c0319a7c429058e8537c508964a133dffee412e", size = 232502, upload-time = "2025-06-09T23:01:31.287Z" }, + { url = "https://files.pythonhosted.org/packages/d7/8b/e7f9dfde869825489382bc0d512c15e96d3964180c9499efcec72e85db7e/frozenlist-1.7.0-cp313-cp313-win32.whl", hash = "sha256:5fc4df05a6591c7768459caba1b342d9ec23fa16195e744939ba5914596ae3e1", size = 39169, upload-time = "2025-06-09T23:01:35.503Z" }, + { url = "https://files.pythonhosted.org/packages/35/89/a487a98d94205d85745080a37860ff5744b9820a2c9acbcdd9440bfddf98/frozenlist-1.7.0-cp313-cp313-win_amd64.whl", hash = "sha256:52109052b9791a3e6b5d1b65f4b909703984b770694d3eb64fad124c835d7cba", size = 43219, upload-time = "2025-06-09T23:01:36.784Z" }, + { url = "https://files.pythonhosted.org/packages/56/d5/5c4cf2319a49eddd9dd7145e66c4866bdc6f3dbc67ca3d59685149c11e0d/frozenlist-1.7.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:a6f86e4193bb0e235ef6ce3dde5cbabed887e0b11f516ce8a0f4d3b33078ec2d", size = 84345, upload-time = "2025-06-09T23:01:38.295Z" }, + { url = "https://files.pythonhosted.org/packages/a4/7d/ec2c1e1dc16b85bc9d526009961953df9cec8481b6886debb36ec9107799/frozenlist-1.7.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:82d664628865abeb32d90ae497fb93df398a69bb3434463d172b80fc25b0dd7d", size = 48880, upload-time = "2025-06-09T23:01:39.887Z" }, + { url = "https://files.pythonhosted.org/packages/69/86/f9596807b03de126e11e7d42ac91e3d0b19a6599c714a1989a4e85eeefc4/frozenlist-1.7.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:912a7e8375a1c9a68325a902f3953191b7b292aa3c3fb0d71a216221deca460b", size = 48498, upload-time = "2025-06-09T23:01:41.318Z" }, + { url = "https://files.pythonhosted.org/packages/5e/cb/df6de220f5036001005f2d726b789b2c0b65f2363b104bbc16f5be8084f8/frozenlist-1.7.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9537c2777167488d539bc5de2ad262efc44388230e5118868e172dd4a552b146", size = 292296, upload-time = "2025-06-09T23:01:42.685Z" }, + { url = "https://files.pythonhosted.org/packages/83/1f/de84c642f17c8f851a2905cee2dae401e5e0daca9b5ef121e120e19aa825/frozenlist-1.7.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:f34560fb1b4c3e30ba35fa9a13894ba39e5acfc5f60f57d8accde65f46cc5e74", size = 273103, upload-time = "2025-06-09T23:01:44.166Z" }, + { url = "https://files.pythonhosted.org/packages/88/3c/c840bfa474ba3fa13c772b93070893c6e9d5c0350885760376cbe3b6c1b3/frozenlist-1.7.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:acd03d224b0175f5a850edc104ac19040d35419eddad04e7cf2d5986d98427f1", size = 292869, upload-time = "2025-06-09T23:01:45.681Z" }, + { url = "https://files.pythonhosted.org/packages/a6/1c/3efa6e7d5a39a1d5ef0abeb51c48fb657765794a46cf124e5aca2c7a592c/frozenlist-1.7.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f2038310bc582f3d6a09b3816ab01737d60bf7b1ec70f5356b09e84fb7408ab1", size = 291467, upload-time = "2025-06-09T23:01:47.234Z" }, + { url = "https://files.pythonhosted.org/packages/4f/00/d5c5e09d4922c395e2f2f6b79b9a20dab4b67daaf78ab92e7729341f61f6/frozenlist-1.7.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b8c05e4c8e5f36e5e088caa1bf78a687528f83c043706640a92cb76cd6999384", size = 266028, upload-time = "2025-06-09T23:01:48.819Z" }, + { url = "https://files.pythonhosted.org/packages/4e/27/72765be905619dfde25a7f33813ac0341eb6b076abede17a2e3fbfade0cb/frozenlist-1.7.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:765bb588c86e47d0b68f23c1bee323d4b703218037765dcf3f25c838c6fecceb", size = 284294, upload-time = "2025-06-09T23:01:50.394Z" }, + { url = "https://files.pythonhosted.org/packages/88/67/c94103a23001b17808eb7dd1200c156bb69fb68e63fcf0693dde4cd6228c/frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:32dc2e08c67d86d0969714dd484fd60ff08ff81d1a1e40a77dd34a387e6ebc0c", size = 281898, upload-time = "2025-06-09T23:01:52.234Z" }, + { url = "https://files.pythonhosted.org/packages/42/34/a3e2c00c00f9e2a9db5653bca3fec306349e71aff14ae45ecc6d0951dd24/frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:c0303e597eb5a5321b4de9c68e9845ac8f290d2ab3f3e2c864437d3c5a30cd65", size = 290465, upload-time = "2025-06-09T23:01:53.788Z" }, + { url = "https://files.pythonhosted.org/packages/bb/73/f89b7fbce8b0b0c095d82b008afd0590f71ccb3dee6eee41791cf8cd25fd/frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:a47f2abb4e29b3a8d0b530f7c3598badc6b134562b1a5caee867f7c62fee51e3", size = 266385, upload-time = "2025-06-09T23:01:55.769Z" }, + { url = "https://files.pythonhosted.org/packages/cd/45/e365fdb554159462ca12df54bc59bfa7a9a273ecc21e99e72e597564d1ae/frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:3d688126c242a6fabbd92e02633414d40f50bb6002fa4cf995a1d18051525657", size = 288771, upload-time = "2025-06-09T23:01:57.4Z" }, + { url = "https://files.pythonhosted.org/packages/00/11/47b6117002a0e904f004d70ec5194fe9144f117c33c851e3d51c765962d0/frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:4e7e9652b3d367c7bd449a727dc79d5043f48b88d0cbfd4f9f1060cf2b414104", size = 288206, upload-time = "2025-06-09T23:01:58.936Z" }, + { url = "https://files.pythonhosted.org/packages/40/37/5f9f3c3fd7f7746082ec67bcdc204db72dad081f4f83a503d33220a92973/frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:1a85e345b4c43db8b842cab1feb41be5cc0b10a1830e6295b69d7310f99becaf", size = 282620, upload-time = "2025-06-09T23:02:00.493Z" }, + { url = "https://files.pythonhosted.org/packages/0b/31/8fbc5af2d183bff20f21aa743b4088eac4445d2bb1cdece449ae80e4e2d1/frozenlist-1.7.0-cp313-cp313t-win32.whl", hash = "sha256:3a14027124ddb70dfcee5148979998066897e79f89f64b13328595c4bdf77c81", size = 43059, upload-time = "2025-06-09T23:02:02.072Z" }, + { url = "https://files.pythonhosted.org/packages/bb/ed/41956f52105b8dbc26e457c5705340c67c8cc2b79f394b79bffc09d0e938/frozenlist-1.7.0-cp313-cp313t-win_amd64.whl", hash = "sha256:3bf8010d71d4507775f658e9823210b7427be36625b387221642725b515dcf3e", size = 47516, upload-time = "2025-06-09T23:02:03.779Z" }, + { url = "https://files.pythonhosted.org/packages/ee/45/b82e3c16be2182bff01179db177fe144d58b5dc787a7d4492c6ed8b9317f/frozenlist-1.7.0-py3-none-any.whl", hash = "sha256:9a5af342e34f7e97caf8c995864c7a396418ae2859cc6fdf1b1073020d516a7e", size = 13106, upload-time = "2025-06-09T23:02:34.204Z" }, ] [[package]] name = "identify" version = "2.6.12" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a2/88/d193a27416618628a5eea64e3223acd800b40749a96ffb322a9b55a49ed1/identify-2.6.12.tar.gz", hash = "sha256:d8de45749f1efb108badef65ee8386f0f7bb19a7f26185f74de6367bffbaf0e6", size = 99254 } +sdist = { url = "https://files.pythonhosted.org/packages/a2/88/d193a27416618628a5eea64e3223acd800b40749a96ffb322a9b55a49ed1/identify-2.6.12.tar.gz", hash = "sha256:d8de45749f1efb108badef65ee8386f0f7bb19a7f26185f74de6367bffbaf0e6", size = 99254, upload-time = "2025-05-23T20:37:53.3Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7a/cd/18f8da995b658420625f7ef13f037be53ae04ec5ad33f9b718240dcfd48c/identify-2.6.12-py2.py3-none-any.whl", hash = "sha256:ad9672d5a72e0d2ff7c5c8809b62dfa60458626352fb0eb7b55e69bdc45334a2", size = 99145 }, + { url = "https://files.pythonhosted.org/packages/7a/cd/18f8da995b658420625f7ef13f037be53ae04ec5ad33f9b718240dcfd48c/identify-2.6.12-py2.py3-none-any.whl", hash = "sha256:ad9672d5a72e0d2ff7c5c8809b62dfa60458626352fb0eb7b55e69bdc45334a2", size = 99145, upload-time = "2025-05-23T20:37:51.495Z" }, ] [[package]] name = "idna" version = "3.10" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490 } +sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490, upload-time = "2024-09-15T18:07:39.745Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442 }, + { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442, upload-time = "2024-09-15T18:07:37.964Z" }, ] [[package]] name = "iniconfig" version = "2.1.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f2/97/ebf4da567aa6827c909642694d71c9fcf53e5b504f2d96afea02718862f3/iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", size = 4793 } +sdist = { url = "https://files.pythonhosted.org/packages/f2/97/ebf4da567aa6827c909642694d71c9fcf53e5b504f2d96afea02718862f3/iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", size = 4793, upload-time = "2025-03-19T20:09:59.721Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760", size = 6050 }, + { url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760", size = 6050, upload-time = "2025-03-19T20:10:01.071Z" }, ] [[package]] name = "isort" version = "6.0.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b8/21/1e2a441f74a653a144224d7d21afe8f4169e6c7c20bb13aec3a2dc3815e0/isort-6.0.1.tar.gz", hash = "sha256:1cb5df28dfbc742e490c5e41bad6da41b805b0a8be7bc93cd0fb2a8a890ac450", size = 821955 } +sdist = { url = "https://files.pythonhosted.org/packages/b8/21/1e2a441f74a653a144224d7d21afe8f4169e6c7c20bb13aec3a2dc3815e0/isort-6.0.1.tar.gz", hash = "sha256:1cb5df28dfbc742e490c5e41bad6da41b805b0a8be7bc93cd0fb2a8a890ac450", size = 821955, upload-time = "2025-02-26T21:13:16.955Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c1/11/114d0a5f4dabbdcedc1125dee0888514c3c3b16d3e9facad87ed96fad97c/isort-6.0.1-py3-none-any.whl", hash = "sha256:2dc5d7f65c9678d94c88dfc29161a320eec67328bc97aad576874cb4be1e9615", size = 94186 }, + { url = "https://files.pythonhosted.org/packages/c1/11/114d0a5f4dabbdcedc1125dee0888514c3c3b16d3e9facad87ed96fad97c/isort-6.0.1-py3-none-any.whl", hash = "sha256:2dc5d7f65c9678d94c88dfc29161a320eec67328bc97aad576874cb4be1e9615", size = 94186, upload-time = "2025-02-26T21:13:14.911Z" }, ] [[package]] @@ -519,9 +519,9 @@ dependencies = [ { name = "referencing" }, { name = "rpds-py" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d5/00/a297a868e9d0784450faa7365c2172a7d6110c763e30ba861867c32ae6a9/jsonschema-4.25.0.tar.gz", hash = "sha256:e63acf5c11762c0e6672ffb61482bdf57f0876684d8d249c0fe2d730d48bc55f", size = 356830 } +sdist = { url = "https://files.pythonhosted.org/packages/d5/00/a297a868e9d0784450faa7365c2172a7d6110c763e30ba861867c32ae6a9/jsonschema-4.25.0.tar.gz", hash = "sha256:e63acf5c11762c0e6672ffb61482bdf57f0876684d8d249c0fe2d730d48bc55f", size = 356830, upload-time = "2025-07-18T15:39:45.11Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fe/54/c86cd8e011fe98803d7e382fd67c0df5ceab8d2b7ad8c5a81524f791551c/jsonschema-4.25.0-py3-none-any.whl", hash = "sha256:24c2e8da302de79c8b9382fee3e76b355e44d2a4364bb207159ce10b517bd716", size = 89184 }, + { url = "https://files.pythonhosted.org/packages/fe/54/c86cd8e011fe98803d7e382fd67c0df5ceab8d2b7ad8c5a81524f791551c/jsonschema-4.25.0-py3-none-any.whl", hash = "sha256:24c2e8da302de79c8b9382fee3e76b355e44d2a4364bb207159ce10b517bd716", size = 89184, upload-time = "2025-07-18T15:39:42.956Z" }, ] [[package]] @@ -531,81 +531,81 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "referencing" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/bf/ce/46fbd9c8119cfc3581ee5643ea49464d168028cfb5caff5fc0596d0cf914/jsonschema_specifications-2025.4.1.tar.gz", hash = "sha256:630159c9f4dbea161a6a2205c3011cc4f18ff381b189fff48bb39b9bf26ae608", size = 15513 } +sdist = { url = "https://files.pythonhosted.org/packages/bf/ce/46fbd9c8119cfc3581ee5643ea49464d168028cfb5caff5fc0596d0cf914/jsonschema_specifications-2025.4.1.tar.gz", hash = "sha256:630159c9f4dbea161a6a2205c3011cc4f18ff381b189fff48bb39b9bf26ae608", size = 15513, upload-time = "2025-04-23T12:34:07.418Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/01/0e/b27cdbaccf30b890c40ed1da9fd4a3593a5cf94dae54fb34f8a4b74fcd3f/jsonschema_specifications-2025.4.1-py3-none-any.whl", hash = "sha256:4653bffbd6584f7de83a67e0d620ef16900b390ddc7939d56684d6c81e33f1af", size = 18437 }, + { url = "https://files.pythonhosted.org/packages/01/0e/b27cdbaccf30b890c40ed1da9fd4a3593a5cf94dae54fb34f8a4b74fcd3f/jsonschema_specifications-2025.4.1-py3-none-any.whl", hash = "sha256:4653bffbd6584f7de83a67e0d620ef16900b390ddc7939d56684d6c81e33f1af", size = 18437, upload-time = "2025-04-23T12:34:05.422Z" }, ] [[package]] name = "mccabe" version = "0.7.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e7/ff/0ffefdcac38932a54d2b5eed4e0ba8a408f215002cd178ad1df0f2806ff8/mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325", size = 9658 } +sdist = { url = "https://files.pythonhosted.org/packages/e7/ff/0ffefdcac38932a54d2b5eed4e0ba8a408f215002cd178ad1df0f2806ff8/mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325", size = 9658, upload-time = "2022-01-24T01:14:51.113Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/27/1a/1f68f9ba0c207934b35b86a8ca3aad8395a3d6dd7921c0686e23853ff5a9/mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e", size = 7350 }, + { url = "https://files.pythonhosted.org/packages/27/1a/1f68f9ba0c207934b35b86a8ca3aad8395a3d6dd7921c0686e23853ff5a9/mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e", size = 7350, upload-time = "2022-01-24T01:14:49.62Z" }, ] [[package]] name = "multidict" version = "6.6.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/3d/2c/5dad12e82fbdf7470f29bff2171484bf07cb3b16ada60a6589af8f376440/multidict-6.6.3.tar.gz", hash = "sha256:798a9eb12dab0a6c2e29c1de6f3468af5cb2da6053a20dfa3344907eed0937cc", size = 101006 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/0e/a0/6b57988ea102da0623ea814160ed78d45a2645e4bbb499c2896d12833a70/multidict-6.6.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:056bebbeda16b2e38642d75e9e5310c484b7c24e3841dc0fb943206a72ec89d6", size = 76514 }, - { url = "https://files.pythonhosted.org/packages/07/7a/d1e92665b0850c6c0508f101f9cf0410c1afa24973e1115fe9c6a185ebf7/multidict-6.6.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:e5f481cccb3c5c5e5de5d00b5141dc589c1047e60d07e85bbd7dea3d4580d63f", size = 45394 }, - { url = "https://files.pythonhosted.org/packages/52/6f/dd104490e01be6ef8bf9573705d8572f8c2d2c561f06e3826b081d9e6591/multidict-6.6.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:10bea2ee839a759ee368b5a6e47787f399b41e70cf0c20d90dfaf4158dfb4e55", size = 43590 }, - { url = "https://files.pythonhosted.org/packages/44/fe/06e0e01b1b0611e6581b7fd5a85b43dacc08b6cea3034f902f383b0873e5/multidict-6.6.3-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:2334cfb0fa9549d6ce2c21af2bfbcd3ac4ec3646b1b1581c88e3e2b1779ec92b", size = 237292 }, - { url = "https://files.pythonhosted.org/packages/ce/71/4f0e558fb77696b89c233c1ee2d92f3e1d5459070a0e89153c9e9e804186/multidict-6.6.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b8fee016722550a2276ca2cb5bb624480e0ed2bd49125b2b73b7010b9090e888", size = 258385 }, - { url = "https://files.pythonhosted.org/packages/e3/25/cca0e68228addad24903801ed1ab42e21307a1b4b6dd2cf63da5d3ae082a/multidict-6.6.3-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e5511cb35f5c50a2db21047c875eb42f308c5583edf96bd8ebf7d770a9d68f6d", size = 242328 }, - { url = "https://files.pythonhosted.org/packages/6e/a3/46f2d420d86bbcb8fe660b26a10a219871a0fbf4d43cb846a4031533f3e0/multidict-6.6.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:712b348f7f449948e0a6c4564a21c7db965af900973a67db432d724619b3c680", size = 268057 }, - { url = "https://files.pythonhosted.org/packages/9e/73/1c743542fe00794a2ec7466abd3f312ccb8fad8dff9f36d42e18fb1ec33e/multidict-6.6.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e4e15d2138ee2694e038e33b7c3da70e6b0ad8868b9f8094a72e1414aeda9c1a", size = 269341 }, - { url = "https://files.pythonhosted.org/packages/a4/11/6ec9dcbe2264b92778eeb85407d1df18812248bf3506a5a1754bc035db0c/multidict-6.6.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8df25594989aebff8a130f7899fa03cbfcc5d2b5f4a461cf2518236fe6f15961", size = 256081 }, - { url = "https://files.pythonhosted.org/packages/9b/2b/631b1e2afeb5f1696846d747d36cda075bfdc0bc7245d6ba5c319278d6c4/multidict-6.6.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:159ca68bfd284a8860f8d8112cf0521113bffd9c17568579e4d13d1f1dc76b65", size = 253581 }, - { url = "https://files.pythonhosted.org/packages/bf/0e/7e3b93f79efeb6111d3bf9a1a69e555ba1d07ad1c11bceb56b7310d0d7ee/multidict-6.6.3-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:e098c17856a8c9ade81b4810888c5ad1914099657226283cab3062c0540b0643", size = 250750 }, - { url = "https://files.pythonhosted.org/packages/ad/9e/086846c1d6601948e7de556ee464a2d4c85e33883e749f46b9547d7b0704/multidict-6.6.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:67c92ed673049dec52d7ed39f8cf9ebbadf5032c774058b4406d18c8f8fe7063", size = 251548 }, - { url = "https://files.pythonhosted.org/packages/8c/7b/86ec260118e522f1a31550e87b23542294880c97cfbf6fb18cc67b044c66/multidict-6.6.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:bd0578596e3a835ef451784053cfd327d607fc39ea1a14812139339a18a0dbc3", size = 262718 }, - { url = "https://files.pythonhosted.org/packages/8c/bd/22ce8f47abb0be04692c9fc4638508b8340987b18691aa7775d927b73f72/multidict-6.6.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:346055630a2df2115cd23ae271910b4cae40f4e336773550dca4889b12916e75", size = 259603 }, - { url = "https://files.pythonhosted.org/packages/07/9c/91b7ac1691be95cd1f4a26e36a74b97cda6aa9820632d31aab4410f46ebd/multidict-6.6.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:555ff55a359302b79de97e0468e9ee80637b0de1fce77721639f7cd9440b3a10", size = 251351 }, - { url = "https://files.pythonhosted.org/packages/6f/5c/4d7adc739884f7a9fbe00d1eac8c034023ef8bad71f2ebe12823ca2e3649/multidict-6.6.3-cp312-cp312-win32.whl", hash = "sha256:73ab034fb8d58ff85c2bcbadc470efc3fafeea8affcf8722855fb94557f14cc5", size = 41860 }, - { url = "https://files.pythonhosted.org/packages/6a/a3/0fbc7afdf7cb1aa12a086b02959307848eb6bcc8f66fcb66c0cb57e2a2c1/multidict-6.6.3-cp312-cp312-win_amd64.whl", hash = "sha256:04cbcce84f63b9af41bad04a54d4cc4e60e90c35b9e6ccb130be2d75b71f8c17", size = 45982 }, - { url = "https://files.pythonhosted.org/packages/b8/95/8c825bd70ff9b02462dc18d1295dd08d3e9e4eb66856d292ffa62cfe1920/multidict-6.6.3-cp312-cp312-win_arm64.whl", hash = "sha256:0f1130b896ecb52d2a1e615260f3ea2af55fa7dc3d7c3003ba0c3121a759b18b", size = 43210 }, - { url = "https://files.pythonhosted.org/packages/52/1d/0bebcbbb4f000751fbd09957257903d6e002943fc668d841a4cf2fb7f872/multidict-6.6.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:540d3c06d48507357a7d57721e5094b4f7093399a0106c211f33540fdc374d55", size = 75843 }, - { url = "https://files.pythonhosted.org/packages/07/8f/cbe241b0434cfe257f65c2b1bcf9e8d5fb52bc708c5061fb29b0fed22bdf/multidict-6.6.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9c19cea2a690f04247d43f366d03e4eb110a0dc4cd1bbeee4d445435428ed35b", size = 45053 }, - { url = "https://files.pythonhosted.org/packages/32/d2/0b3b23f9dbad5b270b22a3ac3ea73ed0a50ef2d9a390447061178ed6bdb8/multidict-6.6.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7af039820cfd00effec86bda5d8debef711a3e86a1d3772e85bea0f243a4bd65", size = 43273 }, - { url = "https://files.pythonhosted.org/packages/fd/fe/6eb68927e823999e3683bc49678eb20374ba9615097d085298fd5b386564/multidict-6.6.3-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:500b84f51654fdc3944e936f2922114349bf8fdcac77c3092b03449f0e5bc2b3", size = 237124 }, - { url = "https://files.pythonhosted.org/packages/e7/ab/320d8507e7726c460cb77117848b3834ea0d59e769f36fdae495f7669929/multidict-6.6.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f3fc723ab8a5c5ed6c50418e9bfcd8e6dceba6c271cee6728a10a4ed8561520c", size = 256892 }, - { url = "https://files.pythonhosted.org/packages/76/60/38ee422db515ac69834e60142a1a69111ac96026e76e8e9aa347fd2e4591/multidict-6.6.3-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:94c47ea3ade005b5976789baaed66d4de4480d0a0bf31cef6edaa41c1e7b56a6", size = 240547 }, - { url = "https://files.pythonhosted.org/packages/27/fb/905224fde2dff042b030c27ad95a7ae744325cf54b890b443d30a789b80e/multidict-6.6.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:dbc7cf464cc6d67e83e136c9f55726da3a30176f020a36ead246eceed87f1cd8", size = 266223 }, - { url = "https://files.pythonhosted.org/packages/76/35/dc38ab361051beae08d1a53965e3e1a418752fc5be4d3fb983c5582d8784/multidict-6.6.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:900eb9f9da25ada070f8ee4a23f884e0ee66fe4e1a38c3af644256a508ad81ca", size = 267262 }, - { url = "https://files.pythonhosted.org/packages/1f/a3/0a485b7f36e422421b17e2bbb5a81c1af10eac1d4476f2ff92927c730479/multidict-6.6.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7c6df517cf177da5d47ab15407143a89cd1a23f8b335f3a28d57e8b0a3dbb884", size = 254345 }, - { url = "https://files.pythonhosted.org/packages/b4/59/bcdd52c1dab7c0e0d75ff19cac751fbd5f850d1fc39172ce809a74aa9ea4/multidict-6.6.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4ef421045f13879e21c994b36e728d8e7d126c91a64b9185810ab51d474f27e7", size = 252248 }, - { url = "https://files.pythonhosted.org/packages/bb/a4/2d96aaa6eae8067ce108d4acee6f45ced5728beda55c0f02ae1072c730d1/multidict-6.6.3-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:6c1e61bb4f80895c081790b6b09fa49e13566df8fbff817da3f85b3a8192e36b", size = 250115 }, - { url = "https://files.pythonhosted.org/packages/25/d2/ed9f847fa5c7d0677d4f02ea2c163d5e48573de3f57bacf5670e43a5ffaa/multidict-6.6.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:e5e8523bb12d7623cd8300dbd91b9e439a46a028cd078ca695eb66ba31adee3c", size = 249649 }, - { url = "https://files.pythonhosted.org/packages/1f/af/9155850372563fc550803d3f25373308aa70f59b52cff25854086ecb4a79/multidict-6.6.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:ef58340cc896219e4e653dade08fea5c55c6df41bcc68122e3be3e9d873d9a7b", size = 261203 }, - { url = "https://files.pythonhosted.org/packages/36/2f/c6a728f699896252cf309769089568a33c6439626648843f78743660709d/multidict-6.6.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:fc9dc435ec8699e7b602b94fe0cd4703e69273a01cbc34409af29e7820f777f1", size = 258051 }, - { url = "https://files.pythonhosted.org/packages/d0/60/689880776d6b18fa2b70f6cc74ff87dd6c6b9b47bd9cf74c16fecfaa6ad9/multidict-6.6.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9e864486ef4ab07db5e9cb997bad2b681514158d6954dd1958dfb163b83d53e6", size = 249601 }, - { url = "https://files.pythonhosted.org/packages/75/5e/325b11f2222a549019cf2ef879c1f81f94a0d40ace3ef55cf529915ba6cc/multidict-6.6.3-cp313-cp313-win32.whl", hash = "sha256:5633a82fba8e841bc5c5c06b16e21529573cd654f67fd833650a215520a6210e", size = 41683 }, - { url = "https://files.pythonhosted.org/packages/b1/ad/cf46e73f5d6e3c775cabd2a05976547f3f18b39bee06260369a42501f053/multidict-6.6.3-cp313-cp313-win_amd64.whl", hash = "sha256:e93089c1570a4ad54c3714a12c2cef549dc9d58e97bcded193d928649cab78e9", size = 45811 }, - { url = "https://files.pythonhosted.org/packages/c5/c9/2e3fe950db28fb7c62e1a5f46e1e38759b072e2089209bc033c2798bb5ec/multidict-6.6.3-cp313-cp313-win_arm64.whl", hash = "sha256:c60b401f192e79caec61f166da9c924e9f8bc65548d4246842df91651e83d600", size = 43056 }, - { url = "https://files.pythonhosted.org/packages/3a/58/aaf8114cf34966e084a8cc9517771288adb53465188843d5a19862cb6dc3/multidict-6.6.3-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:02fd8f32d403a6ff13864b0851f1f523d4c988051eea0471d4f1fd8010f11134", size = 82811 }, - { url = "https://files.pythonhosted.org/packages/71/af/5402e7b58a1f5b987a07ad98f2501fdba2a4f4b4c30cf114e3ce8db64c87/multidict-6.6.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:f3aa090106b1543f3f87b2041eef3c156c8da2aed90c63a2fbed62d875c49c37", size = 48304 }, - { url = "https://files.pythonhosted.org/packages/39/65/ab3c8cafe21adb45b24a50266fd747147dec7847425bc2a0f6934b3ae9ce/multidict-6.6.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e924fb978615a5e33ff644cc42e6aa241effcf4f3322c09d4f8cebde95aff5f8", size = 46775 }, - { url = "https://files.pythonhosted.org/packages/49/ba/9fcc1b332f67cc0c0c8079e263bfab6660f87fe4e28a35921771ff3eea0d/multidict-6.6.3-cp313-cp313t-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:b9fe5a0e57c6dbd0e2ce81ca66272282c32cd11d31658ee9553849d91289e1c1", size = 229773 }, - { url = "https://files.pythonhosted.org/packages/a4/14/0145a251f555f7c754ce2dcbcd012939bbd1f34f066fa5d28a50e722a054/multidict-6.6.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b24576f208793ebae00280c59927c3b7c2a3b1655e443a25f753c4611bc1c373", size = 250083 }, - { url = "https://files.pythonhosted.org/packages/9e/d4/d5c0bd2bbb173b586c249a151a26d2fb3ec7d53c96e42091c9fef4e1f10c/multidict-6.6.3-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:135631cb6c58eac37d7ac0df380294fecdc026b28837fa07c02e459c7fb9c54e", size = 228980 }, - { url = "https://files.pythonhosted.org/packages/21/32/c9a2d8444a50ec48c4733ccc67254100c10e1c8ae8e40c7a2d2183b59b97/multidict-6.6.3-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:274d416b0df887aef98f19f21578653982cfb8a05b4e187d4a17103322eeaf8f", size = 257776 }, - { url = "https://files.pythonhosted.org/packages/68/d0/14fa1699f4ef629eae08ad6201c6b476098f5efb051b296f4c26be7a9fdf/multidict-6.6.3-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e252017a817fad7ce05cafbe5711ed40faeb580e63b16755a3a24e66fa1d87c0", size = 256882 }, - { url = "https://files.pythonhosted.org/packages/da/88/84a27570fbe303c65607d517a5f147cd2fc046c2d1da02b84b17b9bdc2aa/multidict-6.6.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2e4cc8d848cd4fe1cdee28c13ea79ab0ed37fc2e89dd77bac86a2e7959a8c3bc", size = 247816 }, - { url = "https://files.pythonhosted.org/packages/1c/60/dca352a0c999ce96a5d8b8ee0b2b9f729dcad2e0b0c195f8286269a2074c/multidict-6.6.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9e236a7094b9c4c1b7585f6b9cca34b9d833cf079f7e4c49e6a4a6ec9bfdc68f", size = 245341 }, - { url = "https://files.pythonhosted.org/packages/50/ef/433fa3ed06028f03946f3993223dada70fb700f763f70c00079533c34578/multidict-6.6.3-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:e0cb0ab69915c55627c933f0b555a943d98ba71b4d1c57bc0d0a66e2567c7471", size = 235854 }, - { url = "https://files.pythonhosted.org/packages/1b/1f/487612ab56fbe35715320905215a57fede20de7db40a261759690dc80471/multidict-6.6.3-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:81ef2f64593aba09c5212a3d0f8c906a0d38d710a011f2f42759704d4557d3f2", size = 243432 }, - { url = "https://files.pythonhosted.org/packages/da/6f/ce8b79de16cd885c6f9052c96a3671373d00c59b3ee635ea93e6e81b8ccf/multidict-6.6.3-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:b9cbc60010de3562545fa198bfc6d3825df430ea96d2cc509c39bd71e2e7d648", size = 252731 }, - { url = "https://files.pythonhosted.org/packages/bb/fe/a2514a6aba78e5abefa1624ca85ae18f542d95ac5cde2e3815a9fbf369aa/multidict-6.6.3-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:70d974eaaa37211390cd02ef93b7e938de564bbffa866f0b08d07e5e65da783d", size = 247086 }, - { url = "https://files.pythonhosted.org/packages/8c/22/b788718d63bb3cce752d107a57c85fcd1a212c6c778628567c9713f9345a/multidict-6.6.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:3713303e4a6663c6d01d648a68f2848701001f3390a030edaaf3fc949c90bf7c", size = 243338 }, - { url = "https://files.pythonhosted.org/packages/22/d6/fdb3d0670819f2228f3f7d9af613d5e652c15d170c83e5f1c94fbc55a25b/multidict-6.6.3-cp313-cp313t-win32.whl", hash = "sha256:639ecc9fe7cd73f2495f62c213e964843826f44505a3e5d82805aa85cac6f89e", size = 47812 }, - { url = "https://files.pythonhosted.org/packages/b6/d6/a9d2c808f2c489ad199723197419207ecbfbc1776f6e155e1ecea9c883aa/multidict-6.6.3-cp313-cp313t-win_amd64.whl", hash = "sha256:9f97e181f344a0ef3881b573d31de8542cc0dbc559ec68c8f8b5ce2c2e91646d", size = 53011 }, - { url = "https://files.pythonhosted.org/packages/f2/40/b68001cba8188dd267590a111f9661b6256debc327137667e832bf5d66e8/multidict-6.6.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ce8b7693da41a3c4fde5871c738a81490cea5496c671d74374c8ab889e1834fb", size = 45254 }, - { url = "https://files.pythonhosted.org/packages/d8/30/9aec301e9772b098c1f5c0ca0279237c9766d94b97802e9888010c64b0ed/multidict-6.6.3-py3-none-any.whl", hash = "sha256:8db10f29c7541fc5da4defd8cd697e1ca429db743fa716325f236079b96f775a", size = 12313 }, +sdist = { url = "https://files.pythonhosted.org/packages/3d/2c/5dad12e82fbdf7470f29bff2171484bf07cb3b16ada60a6589af8f376440/multidict-6.6.3.tar.gz", hash = "sha256:798a9eb12dab0a6c2e29c1de6f3468af5cb2da6053a20dfa3344907eed0937cc", size = 101006, upload-time = "2025-06-30T15:53:46.929Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0e/a0/6b57988ea102da0623ea814160ed78d45a2645e4bbb499c2896d12833a70/multidict-6.6.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:056bebbeda16b2e38642d75e9e5310c484b7c24e3841dc0fb943206a72ec89d6", size = 76514, upload-time = "2025-06-30T15:51:48.728Z" }, + { url = "https://files.pythonhosted.org/packages/07/7a/d1e92665b0850c6c0508f101f9cf0410c1afa24973e1115fe9c6a185ebf7/multidict-6.6.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:e5f481cccb3c5c5e5de5d00b5141dc589c1047e60d07e85bbd7dea3d4580d63f", size = 45394, upload-time = "2025-06-30T15:51:49.986Z" }, + { url = "https://files.pythonhosted.org/packages/52/6f/dd104490e01be6ef8bf9573705d8572f8c2d2c561f06e3826b081d9e6591/multidict-6.6.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:10bea2ee839a759ee368b5a6e47787f399b41e70cf0c20d90dfaf4158dfb4e55", size = 43590, upload-time = "2025-06-30T15:51:51.331Z" }, + { url = "https://files.pythonhosted.org/packages/44/fe/06e0e01b1b0611e6581b7fd5a85b43dacc08b6cea3034f902f383b0873e5/multidict-6.6.3-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:2334cfb0fa9549d6ce2c21af2bfbcd3ac4ec3646b1b1581c88e3e2b1779ec92b", size = 237292, upload-time = "2025-06-30T15:51:52.584Z" }, + { url = "https://files.pythonhosted.org/packages/ce/71/4f0e558fb77696b89c233c1ee2d92f3e1d5459070a0e89153c9e9e804186/multidict-6.6.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b8fee016722550a2276ca2cb5bb624480e0ed2bd49125b2b73b7010b9090e888", size = 258385, upload-time = "2025-06-30T15:51:53.913Z" }, + { url = "https://files.pythonhosted.org/packages/e3/25/cca0e68228addad24903801ed1ab42e21307a1b4b6dd2cf63da5d3ae082a/multidict-6.6.3-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e5511cb35f5c50a2db21047c875eb42f308c5583edf96bd8ebf7d770a9d68f6d", size = 242328, upload-time = "2025-06-30T15:51:55.672Z" }, + { url = "https://files.pythonhosted.org/packages/6e/a3/46f2d420d86bbcb8fe660b26a10a219871a0fbf4d43cb846a4031533f3e0/multidict-6.6.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:712b348f7f449948e0a6c4564a21c7db965af900973a67db432d724619b3c680", size = 268057, upload-time = "2025-06-30T15:51:57.037Z" }, + { url = "https://files.pythonhosted.org/packages/9e/73/1c743542fe00794a2ec7466abd3f312ccb8fad8dff9f36d42e18fb1ec33e/multidict-6.6.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e4e15d2138ee2694e038e33b7c3da70e6b0ad8868b9f8094a72e1414aeda9c1a", size = 269341, upload-time = "2025-06-30T15:51:59.111Z" }, + { url = "https://files.pythonhosted.org/packages/a4/11/6ec9dcbe2264b92778eeb85407d1df18812248bf3506a5a1754bc035db0c/multidict-6.6.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8df25594989aebff8a130f7899fa03cbfcc5d2b5f4a461cf2518236fe6f15961", size = 256081, upload-time = "2025-06-30T15:52:00.533Z" }, + { url = "https://files.pythonhosted.org/packages/9b/2b/631b1e2afeb5f1696846d747d36cda075bfdc0bc7245d6ba5c319278d6c4/multidict-6.6.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:159ca68bfd284a8860f8d8112cf0521113bffd9c17568579e4d13d1f1dc76b65", size = 253581, upload-time = "2025-06-30T15:52:02.43Z" }, + { url = "https://files.pythonhosted.org/packages/bf/0e/7e3b93f79efeb6111d3bf9a1a69e555ba1d07ad1c11bceb56b7310d0d7ee/multidict-6.6.3-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:e098c17856a8c9ade81b4810888c5ad1914099657226283cab3062c0540b0643", size = 250750, upload-time = "2025-06-30T15:52:04.26Z" }, + { url = "https://files.pythonhosted.org/packages/ad/9e/086846c1d6601948e7de556ee464a2d4c85e33883e749f46b9547d7b0704/multidict-6.6.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:67c92ed673049dec52d7ed39f8cf9ebbadf5032c774058b4406d18c8f8fe7063", size = 251548, upload-time = "2025-06-30T15:52:06.002Z" }, + { url = "https://files.pythonhosted.org/packages/8c/7b/86ec260118e522f1a31550e87b23542294880c97cfbf6fb18cc67b044c66/multidict-6.6.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:bd0578596e3a835ef451784053cfd327d607fc39ea1a14812139339a18a0dbc3", size = 262718, upload-time = "2025-06-30T15:52:07.707Z" }, + { url = "https://files.pythonhosted.org/packages/8c/bd/22ce8f47abb0be04692c9fc4638508b8340987b18691aa7775d927b73f72/multidict-6.6.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:346055630a2df2115cd23ae271910b4cae40f4e336773550dca4889b12916e75", size = 259603, upload-time = "2025-06-30T15:52:09.58Z" }, + { url = "https://files.pythonhosted.org/packages/07/9c/91b7ac1691be95cd1f4a26e36a74b97cda6aa9820632d31aab4410f46ebd/multidict-6.6.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:555ff55a359302b79de97e0468e9ee80637b0de1fce77721639f7cd9440b3a10", size = 251351, upload-time = "2025-06-30T15:52:10.947Z" }, + { url = "https://files.pythonhosted.org/packages/6f/5c/4d7adc739884f7a9fbe00d1eac8c034023ef8bad71f2ebe12823ca2e3649/multidict-6.6.3-cp312-cp312-win32.whl", hash = "sha256:73ab034fb8d58ff85c2bcbadc470efc3fafeea8affcf8722855fb94557f14cc5", size = 41860, upload-time = "2025-06-30T15:52:12.334Z" }, + { url = "https://files.pythonhosted.org/packages/6a/a3/0fbc7afdf7cb1aa12a086b02959307848eb6bcc8f66fcb66c0cb57e2a2c1/multidict-6.6.3-cp312-cp312-win_amd64.whl", hash = "sha256:04cbcce84f63b9af41bad04a54d4cc4e60e90c35b9e6ccb130be2d75b71f8c17", size = 45982, upload-time = "2025-06-30T15:52:13.6Z" }, + { url = "https://files.pythonhosted.org/packages/b8/95/8c825bd70ff9b02462dc18d1295dd08d3e9e4eb66856d292ffa62cfe1920/multidict-6.6.3-cp312-cp312-win_arm64.whl", hash = "sha256:0f1130b896ecb52d2a1e615260f3ea2af55fa7dc3d7c3003ba0c3121a759b18b", size = 43210, upload-time = "2025-06-30T15:52:14.893Z" }, + { url = "https://files.pythonhosted.org/packages/52/1d/0bebcbbb4f000751fbd09957257903d6e002943fc668d841a4cf2fb7f872/multidict-6.6.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:540d3c06d48507357a7d57721e5094b4f7093399a0106c211f33540fdc374d55", size = 75843, upload-time = "2025-06-30T15:52:16.155Z" }, + { url = "https://files.pythonhosted.org/packages/07/8f/cbe241b0434cfe257f65c2b1bcf9e8d5fb52bc708c5061fb29b0fed22bdf/multidict-6.6.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9c19cea2a690f04247d43f366d03e4eb110a0dc4cd1bbeee4d445435428ed35b", size = 45053, upload-time = "2025-06-30T15:52:17.429Z" }, + { url = "https://files.pythonhosted.org/packages/32/d2/0b3b23f9dbad5b270b22a3ac3ea73ed0a50ef2d9a390447061178ed6bdb8/multidict-6.6.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7af039820cfd00effec86bda5d8debef711a3e86a1d3772e85bea0f243a4bd65", size = 43273, upload-time = "2025-06-30T15:52:19.346Z" }, + { url = "https://files.pythonhosted.org/packages/fd/fe/6eb68927e823999e3683bc49678eb20374ba9615097d085298fd5b386564/multidict-6.6.3-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:500b84f51654fdc3944e936f2922114349bf8fdcac77c3092b03449f0e5bc2b3", size = 237124, upload-time = "2025-06-30T15:52:20.773Z" }, + { url = "https://files.pythonhosted.org/packages/e7/ab/320d8507e7726c460cb77117848b3834ea0d59e769f36fdae495f7669929/multidict-6.6.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f3fc723ab8a5c5ed6c50418e9bfcd8e6dceba6c271cee6728a10a4ed8561520c", size = 256892, upload-time = "2025-06-30T15:52:22.242Z" }, + { url = "https://files.pythonhosted.org/packages/76/60/38ee422db515ac69834e60142a1a69111ac96026e76e8e9aa347fd2e4591/multidict-6.6.3-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:94c47ea3ade005b5976789baaed66d4de4480d0a0bf31cef6edaa41c1e7b56a6", size = 240547, upload-time = "2025-06-30T15:52:23.736Z" }, + { url = "https://files.pythonhosted.org/packages/27/fb/905224fde2dff042b030c27ad95a7ae744325cf54b890b443d30a789b80e/multidict-6.6.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:dbc7cf464cc6d67e83e136c9f55726da3a30176f020a36ead246eceed87f1cd8", size = 266223, upload-time = "2025-06-30T15:52:25.185Z" }, + { url = "https://files.pythonhosted.org/packages/76/35/dc38ab361051beae08d1a53965e3e1a418752fc5be4d3fb983c5582d8784/multidict-6.6.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:900eb9f9da25ada070f8ee4a23f884e0ee66fe4e1a38c3af644256a508ad81ca", size = 267262, upload-time = "2025-06-30T15:52:26.969Z" }, + { url = "https://files.pythonhosted.org/packages/1f/a3/0a485b7f36e422421b17e2bbb5a81c1af10eac1d4476f2ff92927c730479/multidict-6.6.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7c6df517cf177da5d47ab15407143a89cd1a23f8b335f3a28d57e8b0a3dbb884", size = 254345, upload-time = "2025-06-30T15:52:28.467Z" }, + { url = "https://files.pythonhosted.org/packages/b4/59/bcdd52c1dab7c0e0d75ff19cac751fbd5f850d1fc39172ce809a74aa9ea4/multidict-6.6.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4ef421045f13879e21c994b36e728d8e7d126c91a64b9185810ab51d474f27e7", size = 252248, upload-time = "2025-06-30T15:52:29.938Z" }, + { url = "https://files.pythonhosted.org/packages/bb/a4/2d96aaa6eae8067ce108d4acee6f45ced5728beda55c0f02ae1072c730d1/multidict-6.6.3-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:6c1e61bb4f80895c081790b6b09fa49e13566df8fbff817da3f85b3a8192e36b", size = 250115, upload-time = "2025-06-30T15:52:31.416Z" }, + { url = "https://files.pythonhosted.org/packages/25/d2/ed9f847fa5c7d0677d4f02ea2c163d5e48573de3f57bacf5670e43a5ffaa/multidict-6.6.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:e5e8523bb12d7623cd8300dbd91b9e439a46a028cd078ca695eb66ba31adee3c", size = 249649, upload-time = "2025-06-30T15:52:32.996Z" }, + { url = "https://files.pythonhosted.org/packages/1f/af/9155850372563fc550803d3f25373308aa70f59b52cff25854086ecb4a79/multidict-6.6.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:ef58340cc896219e4e653dade08fea5c55c6df41bcc68122e3be3e9d873d9a7b", size = 261203, upload-time = "2025-06-30T15:52:34.521Z" }, + { url = "https://files.pythonhosted.org/packages/36/2f/c6a728f699896252cf309769089568a33c6439626648843f78743660709d/multidict-6.6.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:fc9dc435ec8699e7b602b94fe0cd4703e69273a01cbc34409af29e7820f777f1", size = 258051, upload-time = "2025-06-30T15:52:35.999Z" }, + { url = "https://files.pythonhosted.org/packages/d0/60/689880776d6b18fa2b70f6cc74ff87dd6c6b9b47bd9cf74c16fecfaa6ad9/multidict-6.6.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9e864486ef4ab07db5e9cb997bad2b681514158d6954dd1958dfb163b83d53e6", size = 249601, upload-time = "2025-06-30T15:52:37.473Z" }, + { url = "https://files.pythonhosted.org/packages/75/5e/325b11f2222a549019cf2ef879c1f81f94a0d40ace3ef55cf529915ba6cc/multidict-6.6.3-cp313-cp313-win32.whl", hash = "sha256:5633a82fba8e841bc5c5c06b16e21529573cd654f67fd833650a215520a6210e", size = 41683, upload-time = "2025-06-30T15:52:38.927Z" }, + { url = "https://files.pythonhosted.org/packages/b1/ad/cf46e73f5d6e3c775cabd2a05976547f3f18b39bee06260369a42501f053/multidict-6.6.3-cp313-cp313-win_amd64.whl", hash = "sha256:e93089c1570a4ad54c3714a12c2cef549dc9d58e97bcded193d928649cab78e9", size = 45811, upload-time = "2025-06-30T15:52:40.207Z" }, + { url = "https://files.pythonhosted.org/packages/c5/c9/2e3fe950db28fb7c62e1a5f46e1e38759b072e2089209bc033c2798bb5ec/multidict-6.6.3-cp313-cp313-win_arm64.whl", hash = "sha256:c60b401f192e79caec61f166da9c924e9f8bc65548d4246842df91651e83d600", size = 43056, upload-time = "2025-06-30T15:52:41.575Z" }, + { url = "https://files.pythonhosted.org/packages/3a/58/aaf8114cf34966e084a8cc9517771288adb53465188843d5a19862cb6dc3/multidict-6.6.3-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:02fd8f32d403a6ff13864b0851f1f523d4c988051eea0471d4f1fd8010f11134", size = 82811, upload-time = "2025-06-30T15:52:43.281Z" }, + { url = "https://files.pythonhosted.org/packages/71/af/5402e7b58a1f5b987a07ad98f2501fdba2a4f4b4c30cf114e3ce8db64c87/multidict-6.6.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:f3aa090106b1543f3f87b2041eef3c156c8da2aed90c63a2fbed62d875c49c37", size = 48304, upload-time = "2025-06-30T15:52:45.026Z" }, + { url = "https://files.pythonhosted.org/packages/39/65/ab3c8cafe21adb45b24a50266fd747147dec7847425bc2a0f6934b3ae9ce/multidict-6.6.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e924fb978615a5e33ff644cc42e6aa241effcf4f3322c09d4f8cebde95aff5f8", size = 46775, upload-time = "2025-06-30T15:52:46.459Z" }, + { url = "https://files.pythonhosted.org/packages/49/ba/9fcc1b332f67cc0c0c8079e263bfab6660f87fe4e28a35921771ff3eea0d/multidict-6.6.3-cp313-cp313t-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:b9fe5a0e57c6dbd0e2ce81ca66272282c32cd11d31658ee9553849d91289e1c1", size = 229773, upload-time = "2025-06-30T15:52:47.88Z" }, + { url = "https://files.pythonhosted.org/packages/a4/14/0145a251f555f7c754ce2dcbcd012939bbd1f34f066fa5d28a50e722a054/multidict-6.6.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b24576f208793ebae00280c59927c3b7c2a3b1655e443a25f753c4611bc1c373", size = 250083, upload-time = "2025-06-30T15:52:49.366Z" }, + { url = "https://files.pythonhosted.org/packages/9e/d4/d5c0bd2bbb173b586c249a151a26d2fb3ec7d53c96e42091c9fef4e1f10c/multidict-6.6.3-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:135631cb6c58eac37d7ac0df380294fecdc026b28837fa07c02e459c7fb9c54e", size = 228980, upload-time = "2025-06-30T15:52:50.903Z" }, + { url = "https://files.pythonhosted.org/packages/21/32/c9a2d8444a50ec48c4733ccc67254100c10e1c8ae8e40c7a2d2183b59b97/multidict-6.6.3-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:274d416b0df887aef98f19f21578653982cfb8a05b4e187d4a17103322eeaf8f", size = 257776, upload-time = "2025-06-30T15:52:52.764Z" }, + { url = "https://files.pythonhosted.org/packages/68/d0/14fa1699f4ef629eae08ad6201c6b476098f5efb051b296f4c26be7a9fdf/multidict-6.6.3-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e252017a817fad7ce05cafbe5711ed40faeb580e63b16755a3a24e66fa1d87c0", size = 256882, upload-time = "2025-06-30T15:52:54.596Z" }, + { url = "https://files.pythonhosted.org/packages/da/88/84a27570fbe303c65607d517a5f147cd2fc046c2d1da02b84b17b9bdc2aa/multidict-6.6.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2e4cc8d848cd4fe1cdee28c13ea79ab0ed37fc2e89dd77bac86a2e7959a8c3bc", size = 247816, upload-time = "2025-06-30T15:52:56.175Z" }, + { url = "https://files.pythonhosted.org/packages/1c/60/dca352a0c999ce96a5d8b8ee0b2b9f729dcad2e0b0c195f8286269a2074c/multidict-6.6.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9e236a7094b9c4c1b7585f6b9cca34b9d833cf079f7e4c49e6a4a6ec9bfdc68f", size = 245341, upload-time = "2025-06-30T15:52:57.752Z" }, + { url = "https://files.pythonhosted.org/packages/50/ef/433fa3ed06028f03946f3993223dada70fb700f763f70c00079533c34578/multidict-6.6.3-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:e0cb0ab69915c55627c933f0b555a943d98ba71b4d1c57bc0d0a66e2567c7471", size = 235854, upload-time = "2025-06-30T15:52:59.74Z" }, + { url = "https://files.pythonhosted.org/packages/1b/1f/487612ab56fbe35715320905215a57fede20de7db40a261759690dc80471/multidict-6.6.3-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:81ef2f64593aba09c5212a3d0f8c906a0d38d710a011f2f42759704d4557d3f2", size = 243432, upload-time = "2025-06-30T15:53:01.602Z" }, + { url = "https://files.pythonhosted.org/packages/da/6f/ce8b79de16cd885c6f9052c96a3671373d00c59b3ee635ea93e6e81b8ccf/multidict-6.6.3-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:b9cbc60010de3562545fa198bfc6d3825df430ea96d2cc509c39bd71e2e7d648", size = 252731, upload-time = "2025-06-30T15:53:03.517Z" }, + { url = "https://files.pythonhosted.org/packages/bb/fe/a2514a6aba78e5abefa1624ca85ae18f542d95ac5cde2e3815a9fbf369aa/multidict-6.6.3-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:70d974eaaa37211390cd02ef93b7e938de564bbffa866f0b08d07e5e65da783d", size = 247086, upload-time = "2025-06-30T15:53:05.48Z" }, + { url = "https://files.pythonhosted.org/packages/8c/22/b788718d63bb3cce752d107a57c85fcd1a212c6c778628567c9713f9345a/multidict-6.6.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:3713303e4a6663c6d01d648a68f2848701001f3390a030edaaf3fc949c90bf7c", size = 243338, upload-time = "2025-06-30T15:53:07.522Z" }, + { url = "https://files.pythonhosted.org/packages/22/d6/fdb3d0670819f2228f3f7d9af613d5e652c15d170c83e5f1c94fbc55a25b/multidict-6.6.3-cp313-cp313t-win32.whl", hash = "sha256:639ecc9fe7cd73f2495f62c213e964843826f44505a3e5d82805aa85cac6f89e", size = 47812, upload-time = "2025-06-30T15:53:09.263Z" }, + { url = "https://files.pythonhosted.org/packages/b6/d6/a9d2c808f2c489ad199723197419207ecbfbc1776f6e155e1ecea9c883aa/multidict-6.6.3-cp313-cp313t-win_amd64.whl", hash = "sha256:9f97e181f344a0ef3881b573d31de8542cc0dbc559ec68c8f8b5ce2c2e91646d", size = 53011, upload-time = "2025-06-30T15:53:11.038Z" }, + { url = "https://files.pythonhosted.org/packages/f2/40/b68001cba8188dd267590a111f9661b6256debc327137667e832bf5d66e8/multidict-6.6.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ce8b7693da41a3c4fde5871c738a81490cea5496c671d74374c8ab889e1834fb", size = 45254, upload-time = "2025-06-30T15:53:12.421Z" }, + { url = "https://files.pythonhosted.org/packages/d8/30/9aec301e9772b098c1f5c0ca0279237c9766d94b97802e9888010c64b0ed/multidict-6.6.3-py3-none-any.whl", hash = "sha256:8db10f29c7541fc5da4defd8cd697e1ca429db743fa716325f236079b96f775a", size = 12313, upload-time = "2025-06-30T15:53:45.437Z" }, ] [[package]] @@ -617,54 +617,54 @@ dependencies = [ { name = "tomli" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e3/7b/3fa271e904b0e8689fb0f0083a43a8bf84b9b47b8f3f5a36e0ee2c064eb4/mypy-0.942.tar.gz", hash = "sha256:17e44649fec92e9f82102b48a3bf7b4a5510ad0cd22fa21a104826b5db4903e2", size = 2651177 } +sdist = { url = "https://files.pythonhosted.org/packages/e3/7b/3fa271e904b0e8689fb0f0083a43a8bf84b9b47b8f3f5a36e0ee2c064eb4/mypy-0.942.tar.gz", hash = "sha256:17e44649fec92e9f82102b48a3bf7b4a5510ad0cd22fa21a104826b5db4903e2", size = 2651177, upload-time = "2022-03-24T17:24:12.808Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/dd/c1/072c3187d19d1e5445a0230b526916e37497eefe6b060491845603fa6f95/mypy-0.942-py3-none-any.whl", hash = "sha256:a1b383fe99678d7402754fe90448d4037f9512ce70c21f8aee3b8bf48ffc51db", size = 2453553 }, + { url = "https://files.pythonhosted.org/packages/dd/c1/072c3187d19d1e5445a0230b526916e37497eefe6b060491845603fa6f95/mypy-0.942-py3-none-any.whl", hash = "sha256:a1b383fe99678d7402754fe90448d4037f9512ce70c21f8aee3b8bf48ffc51db", size = 2453553, upload-time = "2022-03-24T17:22:23.861Z" }, ] [[package]] name = "mypy-extensions" version = "1.1.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a2/6e/371856a3fb9d31ca8dac321cda606860fa4548858c0cc45d9d1d4ca2628b/mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558", size = 6343 } +sdist = { url = "https://files.pythonhosted.org/packages/a2/6e/371856a3fb9d31ca8dac321cda606860fa4548858c0cc45d9d1d4ca2628b/mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558", size = 6343, upload-time = "2025-04-22T14:54:24.164Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", size = 4963 }, + { url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", size = 4963, upload-time = "2025-04-22T14:54:22.983Z" }, ] [[package]] name = "nodeenv" version = "1.9.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437 } +sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437, upload-time = "2024-06-04T18:44:11.171Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314 }, + { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314, upload-time = "2024-06-04T18:44:08.352Z" }, ] [[package]] name = "packaging" version = "25.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727 } +sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469 }, + { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, ] [[package]] name = "platformdirs" version = "4.3.8" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/fe/8b/3c73abc9c759ecd3f1f7ceff6685840859e8070c4d947c93fae71f6a0bf2/platformdirs-4.3.8.tar.gz", hash = "sha256:3d512d96e16bcb959a814c9f348431070822a6496326a4be0911c40b5a74c2bc", size = 21362 } +sdist = { url = "https://files.pythonhosted.org/packages/fe/8b/3c73abc9c759ecd3f1f7ceff6685840859e8070c4d947c93fae71f6a0bf2/platformdirs-4.3.8.tar.gz", hash = "sha256:3d512d96e16bcb959a814c9f348431070822a6496326a4be0911c40b5a74c2bc", size = 21362, upload-time = "2025-05-07T22:47:42.121Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fe/39/979e8e21520d4e47a0bbe349e2713c0aac6f3d853d0e5b34d76206c439aa/platformdirs-4.3.8-py3-none-any.whl", hash = "sha256:ff7059bb7eb1179e2685604f4aaf157cfd9535242bd23742eadc3c13542139b4", size = 18567 }, + { url = "https://files.pythonhosted.org/packages/fe/39/979e8e21520d4e47a0bbe349e2713c0aac6f3d853d0e5b34d76206c439aa/platformdirs-4.3.8-py3-none-any.whl", hash = "sha256:ff7059bb7eb1179e2685604f4aaf157cfd9535242bd23742eadc3c13542139b4", size = 18567, upload-time = "2025-05-07T22:47:40.376Z" }, ] [[package]] name = "pluggy" version = "1.6.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412 } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538 }, + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, ] [[package]] @@ -678,84 +678,84 @@ dependencies = [ { name = "pyyaml" }, { name = "virtualenv" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/08/39/679ca9b26c7bb2999ff122d50faa301e49af82ca9c066ec061cfbc0c6784/pre_commit-4.2.0.tar.gz", hash = "sha256:601283b9757afd87d40c4c4a9b2b5de9637a8ea02eaff7adc2d0fb4e04841146", size = 193424 } +sdist = { url = "https://files.pythonhosted.org/packages/08/39/679ca9b26c7bb2999ff122d50faa301e49af82ca9c066ec061cfbc0c6784/pre_commit-4.2.0.tar.gz", hash = "sha256:601283b9757afd87d40c4c4a9b2b5de9637a8ea02eaff7adc2d0fb4e04841146", size = 193424, upload-time = "2025-03-18T21:35:20.987Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/88/74/a88bf1b1efeae488a0c0b7bdf71429c313722d1fc0f377537fbe554e6180/pre_commit-4.2.0-py2.py3-none-any.whl", hash = "sha256:a009ca7205f1eb497d10b845e52c838a98b6cdd2102a6c8e4540e94ee75c58bd", size = 220707 }, + { url = "https://files.pythonhosted.org/packages/88/74/a88bf1b1efeae488a0c0b7bdf71429c313722d1fc0f377537fbe554e6180/pre_commit-4.2.0-py2.py3-none-any.whl", hash = "sha256:a009ca7205f1eb497d10b845e52c838a98b6cdd2102a6c8e4540e94ee75c58bd", size = 220707, upload-time = "2025-03-18T21:35:19.343Z" }, ] [[package]] name = "propcache" version = "0.3.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a6/16/43264e4a779dd8588c21a70f0709665ee8f611211bdd2c87d952cfa7c776/propcache-0.3.2.tar.gz", hash = "sha256:20d7d62e4e7ef05f221e0db2856b979540686342e7dd9973b815599c7057e168", size = 44139 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a8/42/9ca01b0a6f48e81615dca4765a8f1dd2c057e0540f6116a27dc5ee01dfb6/propcache-0.3.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:8de106b6c84506b31c27168582cd3cb3000a6412c16df14a8628e5871ff83c10", size = 73674 }, - { url = "https://files.pythonhosted.org/packages/af/6e/21293133beb550f9c901bbece755d582bfaf2176bee4774000bd4dd41884/propcache-0.3.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:28710b0d3975117239c76600ea351934ac7b5ff56e60953474342608dbbb6154", size = 43570 }, - { url = "https://files.pythonhosted.org/packages/0c/c8/0393a0a3a2b8760eb3bde3c147f62b20044f0ddac81e9d6ed7318ec0d852/propcache-0.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce26862344bdf836650ed2487c3d724b00fbfec4233a1013f597b78c1cb73615", size = 43094 }, - { url = "https://files.pythonhosted.org/packages/37/2c/489afe311a690399d04a3e03b069225670c1d489eb7b044a566511c1c498/propcache-0.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bca54bd347a253af2cf4544bbec232ab982f4868de0dd684246b67a51bc6b1db", size = 226958 }, - { url = "https://files.pythonhosted.org/packages/9d/ca/63b520d2f3d418c968bf596839ae26cf7f87bead026b6192d4da6a08c467/propcache-0.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:55780d5e9a2ddc59711d727226bb1ba83a22dd32f64ee15594b9392b1f544eb1", size = 234894 }, - { url = "https://files.pythonhosted.org/packages/11/60/1d0ed6fff455a028d678df30cc28dcee7af77fa2b0e6962ce1df95c9a2a9/propcache-0.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:035e631be25d6975ed87ab23153db6a73426a48db688070d925aa27e996fe93c", size = 233672 }, - { url = "https://files.pythonhosted.org/packages/37/7c/54fd5301ef38505ab235d98827207176a5c9b2aa61939b10a460ca53e123/propcache-0.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee6f22b6eaa39297c751d0e80c0d3a454f112f5c6481214fcf4c092074cecd67", size = 224395 }, - { url = "https://files.pythonhosted.org/packages/ee/1a/89a40e0846f5de05fdc6779883bf46ba980e6df4d2ff8fb02643de126592/propcache-0.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7ca3aee1aa955438c4dba34fc20a9f390e4c79967257d830f137bd5a8a32ed3b", size = 212510 }, - { url = "https://files.pythonhosted.org/packages/5e/33/ca98368586c9566a6b8d5ef66e30484f8da84c0aac3f2d9aec6d31a11bd5/propcache-0.3.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7a4f30862869fa2b68380d677cc1c5fcf1e0f2b9ea0cf665812895c75d0ca3b8", size = 222949 }, - { url = "https://files.pythonhosted.org/packages/ba/11/ace870d0aafe443b33b2f0b7efdb872b7c3abd505bfb4890716ad7865e9d/propcache-0.3.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:b77ec3c257d7816d9f3700013639db7491a434644c906a2578a11daf13176251", size = 217258 }, - { url = "https://files.pythonhosted.org/packages/5b/d2/86fd6f7adffcfc74b42c10a6b7db721d1d9ca1055c45d39a1a8f2a740a21/propcache-0.3.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:cab90ac9d3f14b2d5050928483d3d3b8fb6b4018893fc75710e6aa361ecb2474", size = 213036 }, - { url = "https://files.pythonhosted.org/packages/07/94/2d7d1e328f45ff34a0a284cf5a2847013701e24c2a53117e7c280a4316b3/propcache-0.3.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:0b504d29f3c47cf6b9e936c1852246c83d450e8e063d50562115a6be6d3a2535", size = 227684 }, - { url = "https://files.pythonhosted.org/packages/b7/05/37ae63a0087677e90b1d14710e532ff104d44bc1efa3b3970fff99b891dc/propcache-0.3.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:ce2ac2675a6aa41ddb2a0c9cbff53780a617ac3d43e620f8fd77ba1c84dcfc06", size = 234562 }, - { url = "https://files.pythonhosted.org/packages/a4/7c/3f539fcae630408d0bd8bf3208b9a647ccad10976eda62402a80adf8fc34/propcache-0.3.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:62b4239611205294cc433845b914131b2a1f03500ff3c1ed093ed216b82621e1", size = 222142 }, - { url = "https://files.pythonhosted.org/packages/7c/d2/34b9eac8c35f79f8a962546b3e97e9d4b990c420ee66ac8255d5d9611648/propcache-0.3.2-cp312-cp312-win32.whl", hash = "sha256:df4a81b9b53449ebc90cc4deefb052c1dd934ba85012aa912c7ea7b7e38b60c1", size = 37711 }, - { url = "https://files.pythonhosted.org/packages/19/61/d582be5d226cf79071681d1b46b848d6cb03d7b70af7063e33a2787eaa03/propcache-0.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:7046e79b989d7fe457bb755844019e10f693752d169076138abf17f31380800c", size = 41479 }, - { url = "https://files.pythonhosted.org/packages/dc/d1/8c747fafa558c603c4ca19d8e20b288aa0c7cda74e9402f50f31eb65267e/propcache-0.3.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ca592ed634a73ca002967458187109265e980422116c0a107cf93d81f95af945", size = 71286 }, - { url = "https://files.pythonhosted.org/packages/61/99/d606cb7986b60d89c36de8a85d58764323b3a5ff07770a99d8e993b3fa73/propcache-0.3.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9ecb0aad4020e275652ba3975740f241bd12a61f1a784df044cf7477a02bc252", size = 42425 }, - { url = "https://files.pythonhosted.org/packages/8c/96/ef98f91bbb42b79e9bb82bdd348b255eb9d65f14dbbe3b1594644c4073f7/propcache-0.3.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7f08f1cc28bd2eade7a8a3d2954ccc673bb02062e3e7da09bc75d843386b342f", size = 41846 }, - { url = "https://files.pythonhosted.org/packages/5b/ad/3f0f9a705fb630d175146cd7b1d2bf5555c9beaed54e94132b21aac098a6/propcache-0.3.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d1a342c834734edb4be5ecb1e9fb48cb64b1e2320fccbd8c54bf8da8f2a84c33", size = 208871 }, - { url = "https://files.pythonhosted.org/packages/3a/38/2085cda93d2c8b6ec3e92af2c89489a36a5886b712a34ab25de9fbca7992/propcache-0.3.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8a544caaae1ac73f1fecfae70ded3e93728831affebd017d53449e3ac052ac1e", size = 215720 }, - { url = "https://files.pythonhosted.org/packages/61/c1/d72ea2dc83ac7f2c8e182786ab0fc2c7bd123a1ff9b7975bee671866fe5f/propcache-0.3.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:310d11aa44635298397db47a3ebce7db99a4cc4b9bbdfcf6c98a60c8d5261cf1", size = 215203 }, - { url = "https://files.pythonhosted.org/packages/af/81/b324c44ae60c56ef12007105f1460d5c304b0626ab0cc6b07c8f2a9aa0b8/propcache-0.3.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c1396592321ac83157ac03a2023aa6cc4a3cc3cfdecb71090054c09e5a7cce3", size = 206365 }, - { url = "https://files.pythonhosted.org/packages/09/73/88549128bb89e66d2aff242488f62869014ae092db63ccea53c1cc75a81d/propcache-0.3.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8cabf5b5902272565e78197edb682017d21cf3b550ba0460ee473753f28d23c1", size = 196016 }, - { url = "https://files.pythonhosted.org/packages/b9/3f/3bdd14e737d145114a5eb83cb172903afba7242f67c5877f9909a20d948d/propcache-0.3.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0a2f2235ac46a7aa25bdeb03a9e7060f6ecbd213b1f9101c43b3090ffb971ef6", size = 205596 }, - { url = "https://files.pythonhosted.org/packages/0f/ca/2f4aa819c357d3107c3763d7ef42c03980f9ed5c48c82e01e25945d437c1/propcache-0.3.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:92b69e12e34869a6970fd2f3da91669899994b47c98f5d430b781c26f1d9f387", size = 200977 }, - { url = "https://files.pythonhosted.org/packages/cd/4a/e65276c7477533c59085251ae88505caf6831c0e85ff8b2e31ebcbb949b1/propcache-0.3.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:54e02207c79968ebbdffc169591009f4474dde3b4679e16634d34c9363ff56b4", size = 197220 }, - { url = "https://files.pythonhosted.org/packages/7c/54/fc7152e517cf5578278b242396ce4d4b36795423988ef39bb8cd5bf274c8/propcache-0.3.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4adfb44cb588001f68c5466579d3f1157ca07f7504fc91ec87862e2b8e556b88", size = 210642 }, - { url = "https://files.pythonhosted.org/packages/b9/80/abeb4a896d2767bf5f1ea7b92eb7be6a5330645bd7fb844049c0e4045d9d/propcache-0.3.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:fd3e6019dc1261cd0291ee8919dd91fbab7b169bb76aeef6c716833a3f65d206", size = 212789 }, - { url = "https://files.pythonhosted.org/packages/b3/db/ea12a49aa7b2b6d68a5da8293dcf50068d48d088100ac016ad92a6a780e6/propcache-0.3.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4c181cad81158d71c41a2bce88edce078458e2dd5ffee7eddd6b05da85079f43", size = 205880 }, - { url = "https://files.pythonhosted.org/packages/d1/e5/9076a0bbbfb65d1198007059c65639dfd56266cf8e477a9707e4b1999ff4/propcache-0.3.2-cp313-cp313-win32.whl", hash = "sha256:8a08154613f2249519e549de2330cf8e2071c2887309a7b07fb56098f5170a02", size = 37220 }, - { url = "https://files.pythonhosted.org/packages/d3/f5/b369e026b09a26cd77aa88d8fffd69141d2ae00a2abaaf5380d2603f4b7f/propcache-0.3.2-cp313-cp313-win_amd64.whl", hash = "sha256:e41671f1594fc4ab0a6dec1351864713cb3a279910ae8b58f884a88a0a632c05", size = 40678 }, - { url = "https://files.pythonhosted.org/packages/a4/3a/6ece377b55544941a08d03581c7bc400a3c8cd3c2865900a68d5de79e21f/propcache-0.3.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:9a3cf035bbaf035f109987d9d55dc90e4b0e36e04bbbb95af3055ef17194057b", size = 76560 }, - { url = "https://files.pythonhosted.org/packages/0c/da/64a2bb16418740fa634b0e9c3d29edff1db07f56d3546ca2d86ddf0305e1/propcache-0.3.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:156c03d07dc1323d8dacaa221fbe028c5c70d16709cdd63502778e6c3ccca1b0", size = 44676 }, - { url = "https://files.pythonhosted.org/packages/36/7b/f025e06ea51cb72c52fb87e9b395cced02786610b60a3ed51da8af017170/propcache-0.3.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:74413c0ba02ba86f55cf60d18daab219f7e531620c15f1e23d95563f505efe7e", size = 44701 }, - { url = "https://files.pythonhosted.org/packages/a4/00/faa1b1b7c3b74fc277f8642f32a4c72ba1d7b2de36d7cdfb676db7f4303e/propcache-0.3.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f066b437bb3fa39c58ff97ab2ca351db465157d68ed0440abecb21715eb24b28", size = 276934 }, - { url = "https://files.pythonhosted.org/packages/74/ab/935beb6f1756e0476a4d5938ff44bf0d13a055fed880caf93859b4f1baf4/propcache-0.3.2-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f1304b085c83067914721e7e9d9917d41ad87696bf70f0bc7dee450e9c71ad0a", size = 278316 }, - { url = "https://files.pythonhosted.org/packages/f8/9d/994a5c1ce4389610838d1caec74bdf0e98b306c70314d46dbe4fcf21a3e2/propcache-0.3.2-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ab50cef01b372763a13333b4e54021bdcb291fc9a8e2ccb9c2df98be51bcde6c", size = 282619 }, - { url = "https://files.pythonhosted.org/packages/2b/00/a10afce3d1ed0287cef2e09506d3be9822513f2c1e96457ee369adb9a6cd/propcache-0.3.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fad3b2a085ec259ad2c2842666b2a0a49dea8463579c606426128925af1ed725", size = 265896 }, - { url = "https://files.pythonhosted.org/packages/2e/a8/2aa6716ffa566ca57c749edb909ad27884680887d68517e4be41b02299f3/propcache-0.3.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:261fa020c1c14deafd54c76b014956e2f86991af198c51139faf41c4d5e83892", size = 252111 }, - { url = "https://files.pythonhosted.org/packages/36/4f/345ca9183b85ac29c8694b0941f7484bf419c7f0fea2d1e386b4f7893eed/propcache-0.3.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:46d7f8aa79c927e5f987ee3a80205c987717d3659f035c85cf0c3680526bdb44", size = 268334 }, - { url = "https://files.pythonhosted.org/packages/3e/ca/fcd54f78b59e3f97b3b9715501e3147f5340167733d27db423aa321e7148/propcache-0.3.2-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:6d8f3f0eebf73e3c0ff0e7853f68be638b4043c65a70517bb575eff54edd8dbe", size = 255026 }, - { url = "https://files.pythonhosted.org/packages/8b/95/8e6a6bbbd78ac89c30c225210a5c687790e532ba4088afb8c0445b77ef37/propcache-0.3.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:03c89c1b14a5452cf15403e291c0ccd7751d5b9736ecb2c5bab977ad6c5bcd81", size = 250724 }, - { url = "https://files.pythonhosted.org/packages/ee/b0/0dd03616142baba28e8b2d14ce5df6631b4673850a3d4f9c0f9dd714a404/propcache-0.3.2-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:0cc17efde71e12bbaad086d679ce575268d70bc123a5a71ea7ad76f70ba30bba", size = 268868 }, - { url = "https://files.pythonhosted.org/packages/c5/98/2c12407a7e4fbacd94ddd32f3b1e3d5231e77c30ef7162b12a60e2dd5ce3/propcache-0.3.2-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:acdf05d00696bc0447e278bb53cb04ca72354e562cf88ea6f9107df8e7fd9770", size = 271322 }, - { url = "https://files.pythonhosted.org/packages/35/91/9cb56efbb428b006bb85db28591e40b7736847b8331d43fe335acf95f6c8/propcache-0.3.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4445542398bd0b5d32df908031cb1b30d43ac848e20470a878b770ec2dcc6330", size = 265778 }, - { url = "https://files.pythonhosted.org/packages/9a/4c/b0fe775a2bdd01e176b14b574be679d84fc83958335790f7c9a686c1f468/propcache-0.3.2-cp313-cp313t-win32.whl", hash = "sha256:f86e5d7cd03afb3a1db8e9f9f6eff15794e79e791350ac48a8c924e6f439f394", size = 41175 }, - { url = "https://files.pythonhosted.org/packages/a4/ff/47f08595e3d9b5e149c150f88d9714574f1a7cbd89fe2817158a952674bf/propcache-0.3.2-cp313-cp313t-win_amd64.whl", hash = "sha256:9704bedf6e7cbe3c65eca4379a9b53ee6a83749f047808cbb5044d40d7d72198", size = 44857 }, - { url = "https://files.pythonhosted.org/packages/cc/35/cc0aaecf278bb4575b8555f2b137de5ab821595ddae9da9d3cd1da4072c7/propcache-0.3.2-py3-none-any.whl", hash = "sha256:98f1ec44fb675f5052cccc8e609c46ed23a35a1cfd18545ad4e29002d858a43f", size = 12663 }, +sdist = { url = "https://files.pythonhosted.org/packages/a6/16/43264e4a779dd8588c21a70f0709665ee8f611211bdd2c87d952cfa7c776/propcache-0.3.2.tar.gz", hash = "sha256:20d7d62e4e7ef05f221e0db2856b979540686342e7dd9973b815599c7057e168", size = 44139, upload-time = "2025-06-09T22:56:06.081Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a8/42/9ca01b0a6f48e81615dca4765a8f1dd2c057e0540f6116a27dc5ee01dfb6/propcache-0.3.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:8de106b6c84506b31c27168582cd3cb3000a6412c16df14a8628e5871ff83c10", size = 73674, upload-time = "2025-06-09T22:54:30.551Z" }, + { url = "https://files.pythonhosted.org/packages/af/6e/21293133beb550f9c901bbece755d582bfaf2176bee4774000bd4dd41884/propcache-0.3.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:28710b0d3975117239c76600ea351934ac7b5ff56e60953474342608dbbb6154", size = 43570, upload-time = "2025-06-09T22:54:32.296Z" }, + { url = "https://files.pythonhosted.org/packages/0c/c8/0393a0a3a2b8760eb3bde3c147f62b20044f0ddac81e9d6ed7318ec0d852/propcache-0.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce26862344bdf836650ed2487c3d724b00fbfec4233a1013f597b78c1cb73615", size = 43094, upload-time = "2025-06-09T22:54:33.929Z" }, + { url = "https://files.pythonhosted.org/packages/37/2c/489afe311a690399d04a3e03b069225670c1d489eb7b044a566511c1c498/propcache-0.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bca54bd347a253af2cf4544bbec232ab982f4868de0dd684246b67a51bc6b1db", size = 226958, upload-time = "2025-06-09T22:54:35.186Z" }, + { url = "https://files.pythonhosted.org/packages/9d/ca/63b520d2f3d418c968bf596839ae26cf7f87bead026b6192d4da6a08c467/propcache-0.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:55780d5e9a2ddc59711d727226bb1ba83a22dd32f64ee15594b9392b1f544eb1", size = 234894, upload-time = "2025-06-09T22:54:36.708Z" }, + { url = "https://files.pythonhosted.org/packages/11/60/1d0ed6fff455a028d678df30cc28dcee7af77fa2b0e6962ce1df95c9a2a9/propcache-0.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:035e631be25d6975ed87ab23153db6a73426a48db688070d925aa27e996fe93c", size = 233672, upload-time = "2025-06-09T22:54:38.062Z" }, + { url = "https://files.pythonhosted.org/packages/37/7c/54fd5301ef38505ab235d98827207176a5c9b2aa61939b10a460ca53e123/propcache-0.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee6f22b6eaa39297c751d0e80c0d3a454f112f5c6481214fcf4c092074cecd67", size = 224395, upload-time = "2025-06-09T22:54:39.634Z" }, + { url = "https://files.pythonhosted.org/packages/ee/1a/89a40e0846f5de05fdc6779883bf46ba980e6df4d2ff8fb02643de126592/propcache-0.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7ca3aee1aa955438c4dba34fc20a9f390e4c79967257d830f137bd5a8a32ed3b", size = 212510, upload-time = "2025-06-09T22:54:41.565Z" }, + { url = "https://files.pythonhosted.org/packages/5e/33/ca98368586c9566a6b8d5ef66e30484f8da84c0aac3f2d9aec6d31a11bd5/propcache-0.3.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7a4f30862869fa2b68380d677cc1c5fcf1e0f2b9ea0cf665812895c75d0ca3b8", size = 222949, upload-time = "2025-06-09T22:54:43.038Z" }, + { url = "https://files.pythonhosted.org/packages/ba/11/ace870d0aafe443b33b2f0b7efdb872b7c3abd505bfb4890716ad7865e9d/propcache-0.3.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:b77ec3c257d7816d9f3700013639db7491a434644c906a2578a11daf13176251", size = 217258, upload-time = "2025-06-09T22:54:44.376Z" }, + { url = "https://files.pythonhosted.org/packages/5b/d2/86fd6f7adffcfc74b42c10a6b7db721d1d9ca1055c45d39a1a8f2a740a21/propcache-0.3.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:cab90ac9d3f14b2d5050928483d3d3b8fb6b4018893fc75710e6aa361ecb2474", size = 213036, upload-time = "2025-06-09T22:54:46.243Z" }, + { url = "https://files.pythonhosted.org/packages/07/94/2d7d1e328f45ff34a0a284cf5a2847013701e24c2a53117e7c280a4316b3/propcache-0.3.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:0b504d29f3c47cf6b9e936c1852246c83d450e8e063d50562115a6be6d3a2535", size = 227684, upload-time = "2025-06-09T22:54:47.63Z" }, + { url = "https://files.pythonhosted.org/packages/b7/05/37ae63a0087677e90b1d14710e532ff104d44bc1efa3b3970fff99b891dc/propcache-0.3.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:ce2ac2675a6aa41ddb2a0c9cbff53780a617ac3d43e620f8fd77ba1c84dcfc06", size = 234562, upload-time = "2025-06-09T22:54:48.982Z" }, + { url = "https://files.pythonhosted.org/packages/a4/7c/3f539fcae630408d0bd8bf3208b9a647ccad10976eda62402a80adf8fc34/propcache-0.3.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:62b4239611205294cc433845b914131b2a1f03500ff3c1ed093ed216b82621e1", size = 222142, upload-time = "2025-06-09T22:54:50.424Z" }, + { url = "https://files.pythonhosted.org/packages/7c/d2/34b9eac8c35f79f8a962546b3e97e9d4b990c420ee66ac8255d5d9611648/propcache-0.3.2-cp312-cp312-win32.whl", hash = "sha256:df4a81b9b53449ebc90cc4deefb052c1dd934ba85012aa912c7ea7b7e38b60c1", size = 37711, upload-time = "2025-06-09T22:54:52.072Z" }, + { url = "https://files.pythonhosted.org/packages/19/61/d582be5d226cf79071681d1b46b848d6cb03d7b70af7063e33a2787eaa03/propcache-0.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:7046e79b989d7fe457bb755844019e10f693752d169076138abf17f31380800c", size = 41479, upload-time = "2025-06-09T22:54:53.234Z" }, + { url = "https://files.pythonhosted.org/packages/dc/d1/8c747fafa558c603c4ca19d8e20b288aa0c7cda74e9402f50f31eb65267e/propcache-0.3.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ca592ed634a73ca002967458187109265e980422116c0a107cf93d81f95af945", size = 71286, upload-time = "2025-06-09T22:54:54.369Z" }, + { url = "https://files.pythonhosted.org/packages/61/99/d606cb7986b60d89c36de8a85d58764323b3a5ff07770a99d8e993b3fa73/propcache-0.3.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9ecb0aad4020e275652ba3975740f241bd12a61f1a784df044cf7477a02bc252", size = 42425, upload-time = "2025-06-09T22:54:55.642Z" }, + { url = "https://files.pythonhosted.org/packages/8c/96/ef98f91bbb42b79e9bb82bdd348b255eb9d65f14dbbe3b1594644c4073f7/propcache-0.3.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7f08f1cc28bd2eade7a8a3d2954ccc673bb02062e3e7da09bc75d843386b342f", size = 41846, upload-time = "2025-06-09T22:54:57.246Z" }, + { url = "https://files.pythonhosted.org/packages/5b/ad/3f0f9a705fb630d175146cd7b1d2bf5555c9beaed54e94132b21aac098a6/propcache-0.3.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d1a342c834734edb4be5ecb1e9fb48cb64b1e2320fccbd8c54bf8da8f2a84c33", size = 208871, upload-time = "2025-06-09T22:54:58.975Z" }, + { url = "https://files.pythonhosted.org/packages/3a/38/2085cda93d2c8b6ec3e92af2c89489a36a5886b712a34ab25de9fbca7992/propcache-0.3.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8a544caaae1ac73f1fecfae70ded3e93728831affebd017d53449e3ac052ac1e", size = 215720, upload-time = "2025-06-09T22:55:00.471Z" }, + { url = "https://files.pythonhosted.org/packages/61/c1/d72ea2dc83ac7f2c8e182786ab0fc2c7bd123a1ff9b7975bee671866fe5f/propcache-0.3.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:310d11aa44635298397db47a3ebce7db99a4cc4b9bbdfcf6c98a60c8d5261cf1", size = 215203, upload-time = "2025-06-09T22:55:01.834Z" }, + { url = "https://files.pythonhosted.org/packages/af/81/b324c44ae60c56ef12007105f1460d5c304b0626ab0cc6b07c8f2a9aa0b8/propcache-0.3.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c1396592321ac83157ac03a2023aa6cc4a3cc3cfdecb71090054c09e5a7cce3", size = 206365, upload-time = "2025-06-09T22:55:03.199Z" }, + { url = "https://files.pythonhosted.org/packages/09/73/88549128bb89e66d2aff242488f62869014ae092db63ccea53c1cc75a81d/propcache-0.3.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8cabf5b5902272565e78197edb682017d21cf3b550ba0460ee473753f28d23c1", size = 196016, upload-time = "2025-06-09T22:55:04.518Z" }, + { url = "https://files.pythonhosted.org/packages/b9/3f/3bdd14e737d145114a5eb83cb172903afba7242f67c5877f9909a20d948d/propcache-0.3.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0a2f2235ac46a7aa25bdeb03a9e7060f6ecbd213b1f9101c43b3090ffb971ef6", size = 205596, upload-time = "2025-06-09T22:55:05.942Z" }, + { url = "https://files.pythonhosted.org/packages/0f/ca/2f4aa819c357d3107c3763d7ef42c03980f9ed5c48c82e01e25945d437c1/propcache-0.3.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:92b69e12e34869a6970fd2f3da91669899994b47c98f5d430b781c26f1d9f387", size = 200977, upload-time = "2025-06-09T22:55:07.792Z" }, + { url = "https://files.pythonhosted.org/packages/cd/4a/e65276c7477533c59085251ae88505caf6831c0e85ff8b2e31ebcbb949b1/propcache-0.3.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:54e02207c79968ebbdffc169591009f4474dde3b4679e16634d34c9363ff56b4", size = 197220, upload-time = "2025-06-09T22:55:09.173Z" }, + { url = "https://files.pythonhosted.org/packages/7c/54/fc7152e517cf5578278b242396ce4d4b36795423988ef39bb8cd5bf274c8/propcache-0.3.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4adfb44cb588001f68c5466579d3f1157ca07f7504fc91ec87862e2b8e556b88", size = 210642, upload-time = "2025-06-09T22:55:10.62Z" }, + { url = "https://files.pythonhosted.org/packages/b9/80/abeb4a896d2767bf5f1ea7b92eb7be6a5330645bd7fb844049c0e4045d9d/propcache-0.3.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:fd3e6019dc1261cd0291ee8919dd91fbab7b169bb76aeef6c716833a3f65d206", size = 212789, upload-time = "2025-06-09T22:55:12.029Z" }, + { url = "https://files.pythonhosted.org/packages/b3/db/ea12a49aa7b2b6d68a5da8293dcf50068d48d088100ac016ad92a6a780e6/propcache-0.3.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4c181cad81158d71c41a2bce88edce078458e2dd5ffee7eddd6b05da85079f43", size = 205880, upload-time = "2025-06-09T22:55:13.45Z" }, + { url = "https://files.pythonhosted.org/packages/d1/e5/9076a0bbbfb65d1198007059c65639dfd56266cf8e477a9707e4b1999ff4/propcache-0.3.2-cp313-cp313-win32.whl", hash = "sha256:8a08154613f2249519e549de2330cf8e2071c2887309a7b07fb56098f5170a02", size = 37220, upload-time = "2025-06-09T22:55:15.284Z" }, + { url = "https://files.pythonhosted.org/packages/d3/f5/b369e026b09a26cd77aa88d8fffd69141d2ae00a2abaaf5380d2603f4b7f/propcache-0.3.2-cp313-cp313-win_amd64.whl", hash = "sha256:e41671f1594fc4ab0a6dec1351864713cb3a279910ae8b58f884a88a0a632c05", size = 40678, upload-time = "2025-06-09T22:55:16.445Z" }, + { url = "https://files.pythonhosted.org/packages/a4/3a/6ece377b55544941a08d03581c7bc400a3c8cd3c2865900a68d5de79e21f/propcache-0.3.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:9a3cf035bbaf035f109987d9d55dc90e4b0e36e04bbbb95af3055ef17194057b", size = 76560, upload-time = "2025-06-09T22:55:17.598Z" }, + { url = "https://files.pythonhosted.org/packages/0c/da/64a2bb16418740fa634b0e9c3d29edff1db07f56d3546ca2d86ddf0305e1/propcache-0.3.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:156c03d07dc1323d8dacaa221fbe028c5c70d16709cdd63502778e6c3ccca1b0", size = 44676, upload-time = "2025-06-09T22:55:18.922Z" }, + { url = "https://files.pythonhosted.org/packages/36/7b/f025e06ea51cb72c52fb87e9b395cced02786610b60a3ed51da8af017170/propcache-0.3.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:74413c0ba02ba86f55cf60d18daab219f7e531620c15f1e23d95563f505efe7e", size = 44701, upload-time = "2025-06-09T22:55:20.106Z" }, + { url = "https://files.pythonhosted.org/packages/a4/00/faa1b1b7c3b74fc277f8642f32a4c72ba1d7b2de36d7cdfb676db7f4303e/propcache-0.3.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f066b437bb3fa39c58ff97ab2ca351db465157d68ed0440abecb21715eb24b28", size = 276934, upload-time = "2025-06-09T22:55:21.5Z" }, + { url = "https://files.pythonhosted.org/packages/74/ab/935beb6f1756e0476a4d5938ff44bf0d13a055fed880caf93859b4f1baf4/propcache-0.3.2-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f1304b085c83067914721e7e9d9917d41ad87696bf70f0bc7dee450e9c71ad0a", size = 278316, upload-time = "2025-06-09T22:55:22.918Z" }, + { url = "https://files.pythonhosted.org/packages/f8/9d/994a5c1ce4389610838d1caec74bdf0e98b306c70314d46dbe4fcf21a3e2/propcache-0.3.2-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ab50cef01b372763a13333b4e54021bdcb291fc9a8e2ccb9c2df98be51bcde6c", size = 282619, upload-time = "2025-06-09T22:55:24.651Z" }, + { url = "https://files.pythonhosted.org/packages/2b/00/a10afce3d1ed0287cef2e09506d3be9822513f2c1e96457ee369adb9a6cd/propcache-0.3.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fad3b2a085ec259ad2c2842666b2a0a49dea8463579c606426128925af1ed725", size = 265896, upload-time = "2025-06-09T22:55:26.049Z" }, + { url = "https://files.pythonhosted.org/packages/2e/a8/2aa6716ffa566ca57c749edb909ad27884680887d68517e4be41b02299f3/propcache-0.3.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:261fa020c1c14deafd54c76b014956e2f86991af198c51139faf41c4d5e83892", size = 252111, upload-time = "2025-06-09T22:55:27.381Z" }, + { url = "https://files.pythonhosted.org/packages/36/4f/345ca9183b85ac29c8694b0941f7484bf419c7f0fea2d1e386b4f7893eed/propcache-0.3.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:46d7f8aa79c927e5f987ee3a80205c987717d3659f035c85cf0c3680526bdb44", size = 268334, upload-time = "2025-06-09T22:55:28.747Z" }, + { url = "https://files.pythonhosted.org/packages/3e/ca/fcd54f78b59e3f97b3b9715501e3147f5340167733d27db423aa321e7148/propcache-0.3.2-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:6d8f3f0eebf73e3c0ff0e7853f68be638b4043c65a70517bb575eff54edd8dbe", size = 255026, upload-time = "2025-06-09T22:55:30.184Z" }, + { url = "https://files.pythonhosted.org/packages/8b/95/8e6a6bbbd78ac89c30c225210a5c687790e532ba4088afb8c0445b77ef37/propcache-0.3.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:03c89c1b14a5452cf15403e291c0ccd7751d5b9736ecb2c5bab977ad6c5bcd81", size = 250724, upload-time = "2025-06-09T22:55:31.646Z" }, + { url = "https://files.pythonhosted.org/packages/ee/b0/0dd03616142baba28e8b2d14ce5df6631b4673850a3d4f9c0f9dd714a404/propcache-0.3.2-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:0cc17efde71e12bbaad086d679ce575268d70bc123a5a71ea7ad76f70ba30bba", size = 268868, upload-time = "2025-06-09T22:55:33.209Z" }, + { url = "https://files.pythonhosted.org/packages/c5/98/2c12407a7e4fbacd94ddd32f3b1e3d5231e77c30ef7162b12a60e2dd5ce3/propcache-0.3.2-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:acdf05d00696bc0447e278bb53cb04ca72354e562cf88ea6f9107df8e7fd9770", size = 271322, upload-time = "2025-06-09T22:55:35.065Z" }, + { url = "https://files.pythonhosted.org/packages/35/91/9cb56efbb428b006bb85db28591e40b7736847b8331d43fe335acf95f6c8/propcache-0.3.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4445542398bd0b5d32df908031cb1b30d43ac848e20470a878b770ec2dcc6330", size = 265778, upload-time = "2025-06-09T22:55:36.45Z" }, + { url = "https://files.pythonhosted.org/packages/9a/4c/b0fe775a2bdd01e176b14b574be679d84fc83958335790f7c9a686c1f468/propcache-0.3.2-cp313-cp313t-win32.whl", hash = "sha256:f86e5d7cd03afb3a1db8e9f9f6eff15794e79e791350ac48a8c924e6f439f394", size = 41175, upload-time = "2025-06-09T22:55:38.436Z" }, + { url = "https://files.pythonhosted.org/packages/a4/ff/47f08595e3d9b5e149c150f88d9714574f1a7cbd89fe2817158a952674bf/propcache-0.3.2-cp313-cp313t-win_amd64.whl", hash = "sha256:9704bedf6e7cbe3c65eca4379a9b53ee6a83749f047808cbb5044d40d7d72198", size = 44857, upload-time = "2025-06-09T22:55:39.687Z" }, + { url = "https://files.pythonhosted.org/packages/cc/35/cc0aaecf278bb4575b8555f2b137de5ab821595ddae9da9d3cd1da4072c7/propcache-0.3.2-py3-none-any.whl", hash = "sha256:98f1ec44fb675f5052cccc8e609c46ed23a35a1cfd18545ad4e29002d858a43f", size = 12663, upload-time = "2025-06-09T22:56:04.484Z" }, ] [[package]] name = "pycparser" version = "2.22" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/1d/b2/31537cf4b1ca988837256c910a668b553fceb8f069bedc4b1c826024b52c/pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", size = 172736 } +sdist = { url = "https://files.pythonhosted.org/packages/1d/b2/31537cf4b1ca988837256c910a668b553fceb8f069bedc4b1c826024b52c/pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", size = 172736, upload-time = "2024-03-30T13:22:22.564Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/13/a3/a812df4e2dd5696d1f351d58b8fe16a405b234ad2886a0dab9183fb78109/pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc", size = 117552 }, + { url = "https://files.pythonhosted.org/packages/13/a3/a812df4e2dd5696d1f351d58b8fe16a405b234ad2886a0dab9183fb78109/pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc", size = 117552, upload-time = "2024-03-30T13:22:20.476Z" }, ] [[package]] name = "pygments" version = "2.19.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631 } +sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217 }, + { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, ] [[package]] @@ -771,30 +771,30 @@ dependencies = [ { name = "platformdirs" }, { name = "tomlkit" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/1c/e4/83e487d3ddd64ab27749b66137b26dc0c5b5c161be680e6beffdc99070b3/pylint-3.3.7.tar.gz", hash = "sha256:2b11de8bde49f9c5059452e0c310c079c746a0a8eeaa789e5aa966ecc23e4559", size = 1520709 } +sdist = { url = "https://files.pythonhosted.org/packages/1c/e4/83e487d3ddd64ab27749b66137b26dc0c5b5c161be680e6beffdc99070b3/pylint-3.3.7.tar.gz", hash = "sha256:2b11de8bde49f9c5059452e0c310c079c746a0a8eeaa789e5aa966ecc23e4559", size = 1520709, upload-time = "2025-05-04T17:07:51.089Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e8/83/bff755d09e31b5d25cc7fdc4bf3915d1a404e181f1abf0359af376845c24/pylint-3.3.7-py3-none-any.whl", hash = "sha256:43860aafefce92fca4cf6b61fe199cdc5ae54ea28f9bf4cd49de267b5195803d", size = 522565 }, + { url = "https://files.pythonhosted.org/packages/e8/83/bff755d09e31b5d25cc7fdc4bf3915d1a404e181f1abf0359af376845c24/pylint-3.3.7-py3-none-any.whl", hash = "sha256:43860aafefce92fca4cf6b61fe199cdc5ae54ea28f9bf4cd49de267b5195803d", size = 522565, upload-time = "2025-05-04T17:07:48.714Z" }, ] [[package]] name = "pyserial" version = "3.5" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/1e/7d/ae3f0a63f41e4d2f6cb66a5b57197850f919f59e558159a4dd3a818f5082/pyserial-3.5.tar.gz", hash = "sha256:3c77e014170dfffbd816e6ffc205e9842efb10be9f58ec16d3e8675b4925cddb", size = 159125 } +sdist = { url = "https://files.pythonhosted.org/packages/1e/7d/ae3f0a63f41e4d2f6cb66a5b57197850f919f59e558159a4dd3a818f5082/pyserial-3.5.tar.gz", hash = "sha256:3c77e014170dfffbd816e6ffc205e9842efb10be9f58ec16d3e8675b4925cddb", size = 159125, upload-time = "2020-11-23T03:59:15.045Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/07/bc/587a445451b253b285629263eb51c2d8e9bcea4fc97826266d186f96f558/pyserial-3.5-py2.py3-none-any.whl", hash = "sha256:c4451db6ba391ca6ca299fb3ec7bae67a5c55dde170964c7a14ceefec02f2cf0", size = 90585 }, + { url = "https://files.pythonhosted.org/packages/07/bc/587a445451b253b285629263eb51c2d8e9bcea4fc97826266d186f96f558/pyserial-3.5-py2.py3-none-any.whl", hash = "sha256:c4451db6ba391ca6ca299fb3ec7bae67a5c55dde170964c7a14ceefec02f2cf0", size = 90585, upload-time = "2020-11-23T03:59:13.41Z" }, ] [[package]] -name = "pyserial-asyncio" -version = "0.6" +name = "pyserial-asyncio-fast" +version = "0.16" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pyserial" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/4a/9a/8477699dcbc1882ea51dcff4d3c25aa3f2063ed8f7d7a849fd8f610506b6/pyserial-asyncio-0.6.tar.gz", hash = "sha256:b6032923e05e9d75ec17a5af9a98429c46d2839adfaf80604d52e0faacd7a32f", size = 31322 } +sdist = { url = "https://files.pythonhosted.org/packages/74/d1/6c444e0f6b886345a7993d358c6734ccc440521cdca4999601e86f111708/pyserial_asyncio_fast-0.16.tar.gz", hash = "sha256:fd52643380406739d777014b0aea0873d756b542eb62f7556567239cec007115", size = 32696, upload-time = "2025-03-27T02:35:20.624Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/27/24/c820cf15f87f7b164e83710c1852d4f900d9793961579e5ef64189bc0c10/pyserial_asyncio-0.6-py3-none-any.whl", hash = "sha256:de9337922619421b62b9b1a84048634b3ac520e1d690a674ed246a2af7ce1fc5", size = 7594 }, + { url = "https://files.pythonhosted.org/packages/1b/19/f76987bad313bb2dabf21914c1ec7441a1e846f05764f9948f1ccc2640a8/pyserial_asyncio_fast-0.16-py3-none-any.whl", hash = "sha256:88939d94e341a04c0c8bc3c1ed4e874439cb5a1e21ccfb0fd7315a8e45df1687", size = 9729, upload-time = "2025-03-27T02:35:19.062Z" }, ] [[package]] @@ -808,9 +808,9 @@ dependencies = [ { name = "pluggy" }, { name = "pygments" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/08/ba/45911d754e8eba3d5a841a5ce61a65a685ff1798421ac054f85aa8747dfb/pytest-8.4.1.tar.gz", hash = "sha256:7c67fd69174877359ed9371ec3af8a3d2b04741818c51e5e99cc1742251fa93c", size = 1517714 } +sdist = { url = "https://files.pythonhosted.org/packages/08/ba/45911d754e8eba3d5a841a5ce61a65a685ff1798421ac054f85aa8747dfb/pytest-8.4.1.tar.gz", hash = "sha256:7c67fd69174877359ed9371ec3af8a3d2b04741818c51e5e99cc1742251fa93c", size = 1517714, upload-time = "2025-06-18T05:48:06.109Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/29/16/c8a903f4c4dffe7a12843191437d7cd8e32751d5de349d45d3fe69544e87/pytest-8.4.1-py3-none-any.whl", hash = "sha256:539c70ba6fcead8e78eebbf1115e8b589e7565830d7d006a8723f19ac8a0afb7", size = 365474 }, + { url = "https://files.pythonhosted.org/packages/29/16/c8a903f4c4dffe7a12843191437d7cd8e32751d5de349d45d3fe69544e87/pytest-8.4.1-py3-none-any.whl", hash = "sha256:539c70ba6fcead8e78eebbf1115e8b589e7565830d7d006a8723f19ac8a0afb7", size = 365474, upload-time = "2025-06-18T05:48:03.955Z" }, ] [[package]] @@ -820,9 +820,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pytest" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/4e/51/f8794af39eeb870e87a8c8068642fc07bce0c854d6865d7dd0f2a9d338c2/pytest_asyncio-1.1.0.tar.gz", hash = "sha256:796aa822981e01b68c12e4827b8697108f7205020f24b5793b3c41555dab68ea", size = 46652 } +sdist = { url = "https://files.pythonhosted.org/packages/4e/51/f8794af39eeb870e87a8c8068642fc07bce0c854d6865d7dd0f2a9d338c2/pytest_asyncio-1.1.0.tar.gz", hash = "sha256:796aa822981e01b68c12e4827b8697108f7205020f24b5793b3c41555dab68ea", size = 46652, upload-time = "2025-07-16T04:29:26.393Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c7/9d/bf86eddabf8c6c9cb1ea9a869d6873b46f105a5d292d3a6f7071f5b07935/pytest_asyncio-1.1.0-py3-none-any.whl", hash = "sha256:5fe2d69607b0bd75c656d1211f969cadba035030156745ee09e7d71740e58ecf", size = 15157 }, + { url = "https://files.pythonhosted.org/packages/c7/9d/bf86eddabf8c6c9cb1ea9a869d6873b46f105a5d292d3a6f7071f5b07935/pytest_asyncio-1.1.0-py3-none-any.whl", hash = "sha256:5fe2d69607b0bd75c656d1211f969cadba035030156745ee09e7d71740e58ecf", size = 15157, upload-time = "2025-07-16T04:29:24.929Z" }, ] [[package]] @@ -834,9 +834,9 @@ dependencies = [ { name = "pluggy" }, { name = "pytest" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/18/99/668cade231f434aaa59bbfbf49469068d2ddd945000621d3d165d2e7dd7b/pytest_cov-6.2.1.tar.gz", hash = "sha256:25cc6cc0a5358204b8108ecedc51a9b57b34cc6b8c967cc2c01a4e00d8a67da2", size = 69432 } +sdist = { url = "https://files.pythonhosted.org/packages/18/99/668cade231f434aaa59bbfbf49469068d2ddd945000621d3d165d2e7dd7b/pytest_cov-6.2.1.tar.gz", hash = "sha256:25cc6cc0a5358204b8108ecedc51a9b57b34cc6b8c967cc2c01a4e00d8a67da2", size = 69432, upload-time = "2025-06-12T10:47:47.684Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/bc/16/4ea354101abb1287856baa4af2732be351c7bee728065aed451b678153fd/pytest_cov-6.2.1-py3-none-any.whl", hash = "sha256:f5bc4c23f42f1cdd23c70b1dab1bbaef4fc505ba950d53e0081d0730dd7e86d5", size = 24644 }, + { url = "https://files.pythonhosted.org/packages/bc/16/4ea354101abb1287856baa4af2732be351c7bee728065aed451b678153fd/pytest_cov-6.2.1-py3-none-any.whl", hash = "sha256:f5bc4c23f42f1cdd23c70b1dab1bbaef4fc505ba950d53e0081d0730dd7e86d5", size = 24644, upload-time = "2025-06-12T10:47:45.932Z" }, ] [[package]] @@ -846,9 +846,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pytest" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/39/d4/c54ee6a871eee4a7468e3a8c0dead28e634c0bc2110c694309dcb7563a66/pytest_github_actions_annotate_failures-0.3.0.tar.gz", hash = "sha256:d4c3177c98046c3900a7f8ddebb22ea54b9f6822201b5d3ab8fcdea51e010db7", size = 11248 } +sdist = { url = "https://files.pythonhosted.org/packages/39/d4/c54ee6a871eee4a7468e3a8c0dead28e634c0bc2110c694309dcb7563a66/pytest_github_actions_annotate_failures-0.3.0.tar.gz", hash = "sha256:d4c3177c98046c3900a7f8ddebb22ea54b9f6822201b5d3ab8fcdea51e010db7", size = 11248, upload-time = "2025-01-17T22:39:32.722Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6d/73/7b0b15cb8605ee967b34aa1d949737ab664f94e6b0f1534e8339d9e64ab2/pytest_github_actions_annotate_failures-0.3.0-py3-none-any.whl", hash = "sha256:41ea558ba10c332c0bfc053daeee0c85187507b2034e990f21e4f7e5fef044cf", size = 6030 }, + { url = "https://files.pythonhosted.org/packages/6d/73/7b0b15cb8605ee967b34aa1d949737ab664f94e6b0f1534e8339d9e64ab2/pytest_github_actions_annotate_failures-0.3.0-py3-none-any.whl", hash = "sha256:41ea558ba10c332c0bfc053daeee0c85187507b2034e990f21e4f7e5fef044cf", size = 6030, upload-time = "2025-01-17T22:39:31.701Z" }, ] [[package]] @@ -860,9 +860,9 @@ dependencies = [ { name = "pytest" }, { name = "termcolor" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f5/ac/5754f5edd6d508bc6493bc37d74b928f102a5fff82d9a80347e180998f08/pytest-sugar-1.0.0.tar.gz", hash = "sha256:6422e83258f5b0c04ce7c632176c7732cab5fdb909cb39cca5c9139f81276c0a", size = 14992 } +sdist = { url = "https://files.pythonhosted.org/packages/f5/ac/5754f5edd6d508bc6493bc37d74b928f102a5fff82d9a80347e180998f08/pytest-sugar-1.0.0.tar.gz", hash = "sha256:6422e83258f5b0c04ce7c632176c7732cab5fdb909cb39cca5c9139f81276c0a", size = 14992, upload-time = "2024-02-01T18:30:36.735Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/92/fb/889f1b69da2f13691de09a111c16c4766a433382d44aa0ecf221deded44a/pytest_sugar-1.0.0-py3-none-any.whl", hash = "sha256:70ebcd8fc5795dc457ff8b69d266a4e2e8a74ae0c3edc749381c64b5246c8dfd", size = 10171 }, + { url = "https://files.pythonhosted.org/packages/92/fb/889f1b69da2f13691de09a111c16c4766a433382d44aa0ecf221deded44a/pytest_sugar-1.0.0-py3-none-any.whl", hash = "sha256:70ebcd8fc5795dc457ff8b69d266a4e2e8a74ae0c3edc749381c64b5246c8dfd", size = 10171, upload-time = "2024-02-01T18:30:29.395Z" }, ] [[package]] @@ -872,9 +872,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pytest" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ac/82/4c9ecabab13363e72d880f2fb504c5f750433b2b6f16e99f4ec21ada284c/pytest_timeout-2.4.0.tar.gz", hash = "sha256:7e68e90b01f9eff71332b25001f85c75495fc4e3a836701876183c4bcfd0540a", size = 17973 } +sdist = { url = "https://files.pythonhosted.org/packages/ac/82/4c9ecabab13363e72d880f2fb504c5f750433b2b6f16e99f4ec21ada284c/pytest_timeout-2.4.0.tar.gz", hash = "sha256:7e68e90b01f9eff71332b25001f85c75495fc4e3a836701876183c4bcfd0540a", size = 17973, upload-time = "2025-05-05T19:44:34.99Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fa/b6/3127540ecdf1464a00e5a01ee60a1b09175f6913f0644ac748494d9c4b21/pytest_timeout-2.4.0-py3-none-any.whl", hash = "sha256:c42667e5cdadb151aeb5b26d114aff6bdf5a907f176a007a30b940d3d865b5c2", size = 14382 }, + { url = "https://files.pythonhosted.org/packages/fa/b6/3127540ecdf1464a00e5a01ee60a1b09175f6913f0644ac748494d9c4b21/pytest_timeout-2.4.0-py3-none-any.whl", hash = "sha256:c42667e5cdadb151aeb5b26d114aff6bdf5a907f176a007a30b940d3d865b5c2", size = 14382, upload-time = "2025-05-05T19:44:33.502Z" }, ] [[package]] @@ -885,9 +885,9 @@ dependencies = [ { name = "execnet" }, { name = "pytest" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/78/b4/439b179d1ff526791eb921115fca8e44e596a13efeda518b9d845a619450/pytest_xdist-3.8.0.tar.gz", hash = "sha256:7e578125ec9bc6050861aa93f2d59f1d8d085595d6551c2c90b6f4fad8d3a9f1", size = 88069 } +sdist = { url = "https://files.pythonhosted.org/packages/78/b4/439b179d1ff526791eb921115fca8e44e596a13efeda518b9d845a619450/pytest_xdist-3.8.0.tar.gz", hash = "sha256:7e578125ec9bc6050861aa93f2d59f1d8d085595d6551c2c90b6f4fad8d3a9f1", size = 88069, upload-time = "2025-07-01T13:30:59.346Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl", hash = "sha256:202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88", size = 46396 }, + { url = "https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl", hash = "sha256:202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88", size = 46396, upload-time = "2025-07-01T13:30:56.632Z" }, ] [[package]] @@ -897,35 +897,35 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "six" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432 } +sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892 }, + { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, ] [[package]] name = "pyyaml" version = "6.0.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/86/0c/c581167fc46d6d6d7ddcfb8c843a4de25bdd27e4466938109ca68492292c/PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab", size = 183873 }, - { url = "https://files.pythonhosted.org/packages/a8/0c/38374f5bb272c051e2a69281d71cba6fdb983413e6758b84482905e29a5d/PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725", size = 173302 }, - { url = "https://files.pythonhosted.org/packages/c3/93/9916574aa8c00aa06bbac729972eb1071d002b8e158bd0e83a3b9a20a1f7/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5", size = 739154 }, - { url = "https://files.pythonhosted.org/packages/95/0f/b8938f1cbd09739c6da569d172531567dbcc9789e0029aa070856f123984/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425", size = 766223 }, - { url = "https://files.pythonhosted.org/packages/b9/2b/614b4752f2e127db5cc206abc23a8c19678e92b23c3db30fc86ab731d3bd/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476", size = 767542 }, - { url = "https://files.pythonhosted.org/packages/d4/00/dd137d5bcc7efea1836d6264f049359861cf548469d18da90cd8216cf05f/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48", size = 731164 }, - { url = "https://files.pythonhosted.org/packages/c9/1f/4f998c900485e5c0ef43838363ba4a9723ac0ad73a9dc42068b12aaba4e4/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", size = 756611 }, - { url = "https://files.pythonhosted.org/packages/df/d1/f5a275fdb252768b7a11ec63585bc38d0e87c9e05668a139fea92b80634c/PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", size = 140591 }, - { url = "https://files.pythonhosted.org/packages/0c/e8/4f648c598b17c3d06e8753d7d13d57542b30d56e6c2dedf9c331ae56312e/PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", size = 156338 }, - { url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309 }, - { url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679 }, - { url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428 }, - { url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361 }, - { url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523 }, - { url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660 }, - { url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597 }, - { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527 }, - { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446 }, +sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631, upload-time = "2024-08-06T20:33:50.674Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/86/0c/c581167fc46d6d6d7ddcfb8c843a4de25bdd27e4466938109ca68492292c/PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab", size = 183873, upload-time = "2024-08-06T20:32:25.131Z" }, + { url = "https://files.pythonhosted.org/packages/a8/0c/38374f5bb272c051e2a69281d71cba6fdb983413e6758b84482905e29a5d/PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725", size = 173302, upload-time = "2024-08-06T20:32:26.511Z" }, + { url = "https://files.pythonhosted.org/packages/c3/93/9916574aa8c00aa06bbac729972eb1071d002b8e158bd0e83a3b9a20a1f7/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5", size = 739154, upload-time = "2024-08-06T20:32:28.363Z" }, + { url = "https://files.pythonhosted.org/packages/95/0f/b8938f1cbd09739c6da569d172531567dbcc9789e0029aa070856f123984/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425", size = 766223, upload-time = "2024-08-06T20:32:30.058Z" }, + { url = "https://files.pythonhosted.org/packages/b9/2b/614b4752f2e127db5cc206abc23a8c19678e92b23c3db30fc86ab731d3bd/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476", size = 767542, upload-time = "2024-08-06T20:32:31.881Z" }, + { url = "https://files.pythonhosted.org/packages/d4/00/dd137d5bcc7efea1836d6264f049359861cf548469d18da90cd8216cf05f/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48", size = 731164, upload-time = "2024-08-06T20:32:37.083Z" }, + { url = "https://files.pythonhosted.org/packages/c9/1f/4f998c900485e5c0ef43838363ba4a9723ac0ad73a9dc42068b12aaba4e4/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", size = 756611, upload-time = "2024-08-06T20:32:38.898Z" }, + { url = "https://files.pythonhosted.org/packages/df/d1/f5a275fdb252768b7a11ec63585bc38d0e87c9e05668a139fea92b80634c/PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", size = 140591, upload-time = "2024-08-06T20:32:40.241Z" }, + { url = "https://files.pythonhosted.org/packages/0c/e8/4f648c598b17c3d06e8753d7d13d57542b30d56e6c2dedf9c331ae56312e/PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", size = 156338, upload-time = "2024-08-06T20:32:41.93Z" }, + { url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309, upload-time = "2024-08-06T20:32:43.4Z" }, + { url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679, upload-time = "2024-08-06T20:32:44.801Z" }, + { url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428, upload-time = "2024-08-06T20:32:46.432Z" }, + { url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361, upload-time = "2024-08-06T20:32:51.188Z" }, + { url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523, upload-time = "2024-08-06T20:32:53.019Z" }, + { url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660, upload-time = "2024-08-06T20:32:54.708Z" }, + { url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597, upload-time = "2024-08-06T20:32:56.985Z" }, + { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527, upload-time = "2024-08-06T20:33:03.001Z" }, + { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446, upload-time = "2024-08-06T20:33:04.33Z" }, ] [[package]] @@ -937,9 +937,9 @@ dependencies = [ { name = "rpds-py" }, { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/2f/db/98b5c277be99dd18bfd91dd04e1b759cad18d1a338188c936e92f921c7e2/referencing-0.36.2.tar.gz", hash = "sha256:df2e89862cd09deabbdba16944cc3f10feb6b3e6f18e902f7cc25609a34775aa", size = 74744 } +sdist = { url = "https://files.pythonhosted.org/packages/2f/db/98b5c277be99dd18bfd91dd04e1b759cad18d1a338188c936e92f921c7e2/referencing-0.36.2.tar.gz", hash = "sha256:df2e89862cd09deabbdba16944cc3f10feb6b3e6f18e902f7cc25609a34775aa", size = 74744, upload-time = "2025-01-25T08:48:16.138Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c1/b1/3baf80dc6d2b7bc27a95a67752d0208e410351e3feb4eb78de5f77454d8d/referencing-0.36.2-py3-none-any.whl", hash = "sha256:e8699adbbf8b5c7de96d8ffa0eb5c158b3beafce084968e2ea8bb08c6794dcd0", size = 26775 }, + { url = "https://files.pythonhosted.org/packages/c1/b1/3baf80dc6d2b7bc27a95a67752d0208e410351e3feb4eb78de5f77454d8d/referencing-0.36.2-py3-none-any.whl", hash = "sha256:e8699adbbf8b5c7de96d8ffa0eb5c158b3beafce084968e2ea8bb08c6794dcd0", size = 26775, upload-time = "2025-01-25T08:48:14.241Z" }, ] [[package]] @@ -952,133 +952,133 @@ dependencies = [ { name = "idna" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e1/0a/929373653770d8a0d7ea76c37de6e41f11eb07559b103b1c02cafb3f7cf8/requests-2.32.4.tar.gz", hash = "sha256:27d0316682c8a29834d3264820024b62a36942083d52caf2f14c0591336d3422", size = 135258 } +sdist = { url = "https://files.pythonhosted.org/packages/e1/0a/929373653770d8a0d7ea76c37de6e41f11eb07559b103b1c02cafb3f7cf8/requests-2.32.4.tar.gz", hash = "sha256:27d0316682c8a29834d3264820024b62a36942083d52caf2f14c0591336d3422", size = 135258, upload-time = "2025-06-09T16:43:07.34Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7c/e4/56027c4a6b4ae70ca9de302488c5ca95ad4a39e190093d6c1a8ace08341b/requests-2.32.4-py3-none-any.whl", hash = "sha256:27babd3cda2a6d50b30443204ee89830707d396671944c998b5975b031ac2b2c", size = 64847 }, + { url = "https://files.pythonhosted.org/packages/7c/e4/56027c4a6b4ae70ca9de302488c5ca95ad4a39e190093d6c1a8ace08341b/requests-2.32.4-py3-none-any.whl", hash = "sha256:27babd3cda2a6d50b30443204ee89830707d396671944c998b5975b031ac2b2c", size = 64847, upload-time = "2025-06-09T16:43:05.728Z" }, ] [[package]] name = "rpds-py" version = "0.27.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/1e/d9/991a0dee12d9fc53ed027e26a26a64b151d77252ac477e22666b9688bc16/rpds_py-0.27.0.tar.gz", hash = "sha256:8b23cf252f180cda89220b378d917180f29d313cd6a07b2431c0d3b776aae86f", size = 27420 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/cd/17/e67309ca1ac993fa1888a0d9b2f5ccc1f67196ace32e76c9f8e1dbbbd50c/rpds_py-0.27.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:19c990fdf5acecbf0623e906ae2e09ce1c58947197f9bced6bbd7482662231c4", size = 362611 }, - { url = "https://files.pythonhosted.org/packages/93/2e/28c2fb84aa7aa5d75933d1862d0f7de6198ea22dfd9a0cca06e8a4e7509e/rpds_py-0.27.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6c27a7054b5224710fcfb1a626ec3ff4f28bcb89b899148c72873b18210e446b", size = 347680 }, - { url = "https://files.pythonhosted.org/packages/44/3e/9834b4c8f4f5fe936b479e623832468aa4bd6beb8d014fecaee9eac6cdb1/rpds_py-0.27.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09965b314091829b378b60607022048953e25f0b396c2b70e7c4c81bcecf932e", size = 384600 }, - { url = "https://files.pythonhosted.org/packages/19/78/744123c7b38865a965cd9e6f691fde7ef989a00a256fa8bf15b75240d12f/rpds_py-0.27.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:14f028eb47f59e9169bfdf9f7ceafd29dd64902141840633683d0bad5b04ff34", size = 400697 }, - { url = "https://files.pythonhosted.org/packages/32/97/3c3d32fe7daee0a1f1a678b6d4dfb8c4dcf88197fa2441f9da7cb54a8466/rpds_py-0.27.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6168af0be75bba990a39f9431cdfae5f0ad501f4af32ae62e8856307200517b8", size = 517781 }, - { url = "https://files.pythonhosted.org/packages/b2/be/28f0e3e733680aa13ecec1212fc0f585928a206292f14f89c0b8a684cad1/rpds_py-0.27.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ab47fe727c13c09d0e6f508e3a49e545008e23bf762a245b020391b621f5b726", size = 406449 }, - { url = "https://files.pythonhosted.org/packages/95/ae/5d15c83e337c082d0367053baeb40bfba683f42459f6ebff63a2fd7e5518/rpds_py-0.27.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fa01b3d5e3b7d97efab65bd3d88f164e289ec323a8c033c5c38e53ee25c007e", size = 386150 }, - { url = "https://files.pythonhosted.org/packages/bf/65/944e95f95d5931112829e040912b25a77b2e7ed913ea5fe5746aa5c1ce75/rpds_py-0.27.0-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:6c135708e987f46053e0a1246a206f53717f9fadfba27174a9769ad4befba5c3", size = 406100 }, - { url = "https://files.pythonhosted.org/packages/21/a4/1664b83fae02894533cd11dc0b9f91d673797c2185b7be0f7496107ed6c5/rpds_py-0.27.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fc327f4497b7087d06204235199daf208fd01c82d80465dc5efa4ec9df1c5b4e", size = 421345 }, - { url = "https://files.pythonhosted.org/packages/7c/26/b7303941c2b0823bfb34c71378249f8beedce57301f400acb04bb345d025/rpds_py-0.27.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7e57906e38583a2cba67046a09c2637e23297618dc1f3caddbc493f2be97c93f", size = 561891 }, - { url = "https://files.pythonhosted.org/packages/9b/c8/48623d64d4a5a028fa99576c768a6159db49ab907230edddc0b8468b998b/rpds_py-0.27.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f4f69d7a4300fbf91efb1fb4916421bd57804c01ab938ab50ac9c4aa2212f03", size = 591756 }, - { url = "https://files.pythonhosted.org/packages/b3/51/18f62617e8e61cc66334c9fb44b1ad7baae3438662098efbc55fb3fda453/rpds_py-0.27.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b4c4fbbcff474e1e5f38be1bf04511c03d492d42eec0babda5d03af3b5589374", size = 557088 }, - { url = "https://files.pythonhosted.org/packages/bd/4c/e84c3a276e2496a93d245516be6b49e20499aa8ca1c94d59fada0d79addc/rpds_py-0.27.0-cp312-cp312-win32.whl", hash = "sha256:27bac29bbbf39601b2aab474daf99dbc8e7176ca3389237a23944b17f8913d97", size = 221926 }, - { url = "https://files.pythonhosted.org/packages/83/89/9d0fbcef64340db0605eb0a0044f258076f3ae0a3b108983b2c614d96212/rpds_py-0.27.0-cp312-cp312-win_amd64.whl", hash = "sha256:8a06aa1197ec0281eb1d7daf6073e199eb832fe591ffa329b88bae28f25f5fe5", size = 233235 }, - { url = "https://files.pythonhosted.org/packages/c9/b0/e177aa9f39cbab060f96de4a09df77d494f0279604dc2f509263e21b05f9/rpds_py-0.27.0-cp312-cp312-win_arm64.whl", hash = "sha256:e14aab02258cb776a108107bd15f5b5e4a1bbaa61ef33b36693dfab6f89d54f9", size = 223315 }, - { url = "https://files.pythonhosted.org/packages/81/d2/dfdfd42565a923b9e5a29f93501664f5b984a802967d48d49200ad71be36/rpds_py-0.27.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:443d239d02d9ae55b74015234f2cd8eb09e59fbba30bf60baeb3123ad4c6d5ff", size = 362133 }, - { url = "https://files.pythonhosted.org/packages/ac/4a/0a2e2460c4b66021d349ce9f6331df1d6c75d7eea90df9785d333a49df04/rpds_py-0.27.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b8a7acf04fda1f30f1007f3cc96d29d8cf0a53e626e4e1655fdf4eabc082d367", size = 347128 }, - { url = "https://files.pythonhosted.org/packages/35/8d/7d1e4390dfe09d4213b3175a3f5a817514355cb3524593380733204f20b9/rpds_py-0.27.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d0f92b78cfc3b74a42239fdd8c1266f4715b573204c234d2f9fc3fc7a24f185", size = 384027 }, - { url = "https://files.pythonhosted.org/packages/c1/65/78499d1a62172891c8cd45de737b2a4b84a414b6ad8315ab3ac4945a5b61/rpds_py-0.27.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ce4ed8e0c7dbc5b19352b9c2c6131dd23b95fa8698b5cdd076307a33626b72dc", size = 399973 }, - { url = "https://files.pythonhosted.org/packages/10/a1/1c67c1d8cc889107b19570bb01f75cf49852068e95e6aee80d22915406fc/rpds_py-0.27.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fde355b02934cc6b07200cc3b27ab0c15870a757d1a72fd401aa92e2ea3c6bfe", size = 515295 }, - { url = "https://files.pythonhosted.org/packages/df/27/700ec88e748436b6c7c4a2262d66e80f8c21ab585d5e98c45e02f13f21c0/rpds_py-0.27.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:13bbc4846ae4c993f07c93feb21a24d8ec637573d567a924b1001e81c8ae80f9", size = 406737 }, - { url = "https://files.pythonhosted.org/packages/33/cc/6b0ee8f0ba3f2df2daac1beda17fde5cf10897a7d466f252bd184ef20162/rpds_py-0.27.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:be0744661afbc4099fef7f4e604e7f1ea1be1dd7284f357924af12a705cc7d5c", size = 385898 }, - { url = "https://files.pythonhosted.org/packages/e8/7e/c927b37d7d33c0a0ebf249cc268dc2fcec52864c1b6309ecb960497f2285/rpds_py-0.27.0-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:069e0384a54f427bd65d7fda83b68a90606a3835901aaff42185fcd94f5a9295", size = 405785 }, - { url = "https://files.pythonhosted.org/packages/5b/d2/8ed50746d909dcf402af3fa58b83d5a590ed43e07251d6b08fad1a535ba6/rpds_py-0.27.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4bc262ace5a1a7dc3e2eac2fa97b8257ae795389f688b5adf22c5db1e2431c43", size = 419760 }, - { url = "https://files.pythonhosted.org/packages/d3/60/2b2071aee781cb3bd49f94d5d35686990b925e9b9f3e3d149235a6f5d5c1/rpds_py-0.27.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2fe6e18e5c8581f0361b35ae575043c7029d0a92cb3429e6e596c2cdde251432", size = 561201 }, - { url = "https://files.pythonhosted.org/packages/98/1f/27b67304272521aaea02be293fecedce13fa351a4e41cdb9290576fc6d81/rpds_py-0.27.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d93ebdb82363d2e7bec64eecdc3632b59e84bd270d74fe5be1659f7787052f9b", size = 591021 }, - { url = "https://files.pythonhosted.org/packages/db/9b/a2fadf823164dd085b1f894be6443b0762a54a7af6f36e98e8fcda69ee50/rpds_py-0.27.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0954e3a92e1d62e83a54ea7b3fdc9efa5d61acef8488a8a3d31fdafbfb00460d", size = 556368 }, - { url = "https://files.pythonhosted.org/packages/24/f3/6d135d46a129cda2e3e6d4c5e91e2cc26ea0428c6cf152763f3f10b6dd05/rpds_py-0.27.0-cp313-cp313-win32.whl", hash = "sha256:2cff9bdd6c7b906cc562a505c04a57d92e82d37200027e8d362518df427f96cd", size = 221236 }, - { url = "https://files.pythonhosted.org/packages/c5/44/65d7494f5448ecc755b545d78b188440f81da98b50ea0447ab5ebfdf9bd6/rpds_py-0.27.0-cp313-cp313-win_amd64.whl", hash = "sha256:dc79d192fb76fc0c84f2c58672c17bbbc383fd26c3cdc29daae16ce3d927e8b2", size = 232634 }, - { url = "https://files.pythonhosted.org/packages/70/d9/23852410fadab2abb611733933401de42a1964ce6600a3badae35fbd573e/rpds_py-0.27.0-cp313-cp313-win_arm64.whl", hash = "sha256:5b3a5c8089eed498a3af23ce87a80805ff98f6ef8f7bdb70bd1b7dae5105f6ac", size = 222783 }, - { url = "https://files.pythonhosted.org/packages/15/75/03447917f78512b34463f4ef11066516067099a0c466545655503bed0c77/rpds_py-0.27.0-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:90fb790138c1a89a2e58c9282fe1089638401f2f3b8dddd758499041bc6e0774", size = 359154 }, - { url = "https://files.pythonhosted.org/packages/6b/fc/4dac4fa756451f2122ddaf136e2c6aeb758dc6fdbe9ccc4bc95c98451d50/rpds_py-0.27.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:010c4843a3b92b54373e3d2291a7447d6c3fc29f591772cc2ea0e9f5c1da434b", size = 343909 }, - { url = "https://files.pythonhosted.org/packages/7b/81/723c1ed8e6f57ed9d8c0c07578747a2d3d554aaefc1ab89f4e42cfeefa07/rpds_py-0.27.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9ce7a9e967afc0a2af7caa0d15a3e9c1054815f73d6a8cb9225b61921b419bd", size = 379340 }, - { url = "https://files.pythonhosted.org/packages/98/16/7e3740413de71818ce1997df82ba5f94bae9fff90c0a578c0e24658e6201/rpds_py-0.27.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:aa0bf113d15e8abdfee92aa4db86761b709a09954083afcb5bf0f952d6065fdb", size = 391655 }, - { url = "https://files.pythonhosted.org/packages/e0/63/2a9f510e124d80660f60ecce07953f3f2d5f0b96192c1365443859b9c87f/rpds_py-0.27.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eb91d252b35004a84670dfeafadb042528b19842a0080d8b53e5ec1128e8f433", size = 513017 }, - { url = "https://files.pythonhosted.org/packages/2c/4e/cf6ff311d09776c53ea1b4f2e6700b9d43bb4e99551006817ade4bbd6f78/rpds_py-0.27.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:db8a6313dbac934193fc17fe7610f70cd8181c542a91382531bef5ed785e5615", size = 402058 }, - { url = "https://files.pythonhosted.org/packages/88/11/5e36096d474cb10f2a2d68b22af60a3bc4164fd8db15078769a568d9d3ac/rpds_py-0.27.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce96ab0bdfcef1b8c371ada2100767ace6804ea35aacce0aef3aeb4f3f499ca8", size = 383474 }, - { url = "https://files.pythonhosted.org/packages/db/a2/3dff02805b06058760b5eaa6d8cb8db3eb3e46c9e452453ad5fc5b5ad9fe/rpds_py-0.27.0-cp313-cp313t-manylinux_2_31_riscv64.whl", hash = "sha256:7451ede3560086abe1aa27dcdcf55cd15c96b56f543fb12e5826eee6f721f858", size = 400067 }, - { url = "https://files.pythonhosted.org/packages/67/87/eed7369b0b265518e21ea836456a4ed4a6744c8c12422ce05bce760bb3cf/rpds_py-0.27.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:32196b5a99821476537b3f7732432d64d93a58d680a52c5e12a190ee0135d8b5", size = 412085 }, - { url = "https://files.pythonhosted.org/packages/8b/48/f50b2ab2fbb422fbb389fe296e70b7a6b5ea31b263ada5c61377e710a924/rpds_py-0.27.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a029be818059870664157194e46ce0e995082ac49926f1423c1f058534d2aaa9", size = 555928 }, - { url = "https://files.pythonhosted.org/packages/98/41/b18eb51045d06887666c3560cd4bbb6819127b43d758f5adb82b5f56f7d1/rpds_py-0.27.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3841f66c1ffdc6cebce8aed64e36db71466f1dc23c0d9a5592e2a782a3042c79", size = 585527 }, - { url = "https://files.pythonhosted.org/packages/be/03/a3dd6470fc76499959b00ae56295b76b4bdf7c6ffc60d62006b1217567e1/rpds_py-0.27.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:42894616da0fc0dcb2ec08a77896c3f56e9cb2f4b66acd76fc8992c3557ceb1c", size = 554211 }, - { url = "https://files.pythonhosted.org/packages/bf/d1/ee5fd1be395a07423ac4ca0bcc05280bf95db2b155d03adefeb47d5ebf7e/rpds_py-0.27.0-cp313-cp313t-win32.whl", hash = "sha256:b1fef1f13c842a39a03409e30ca0bf87b39a1e2a305a9924deadb75a43105d23", size = 216624 }, - { url = "https://files.pythonhosted.org/packages/1c/94/4814c4c858833bf46706f87349c37ca45e154da7dbbec9ff09f1abeb08cc/rpds_py-0.27.0-cp313-cp313t-win_amd64.whl", hash = "sha256:183f5e221ba3e283cd36fdfbe311d95cd87699a083330b4f792543987167eff1", size = 230007 }, - { url = "https://files.pythonhosted.org/packages/0e/a5/8fffe1c7dc7c055aa02df310f9fb71cfc693a4d5ccc5de2d3456ea5fb022/rpds_py-0.27.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:f3cd110e02c5bf17d8fb562f6c9df5c20e73029d587cf8602a2da6c5ef1e32cb", size = 362595 }, - { url = "https://files.pythonhosted.org/packages/bc/c7/4e4253fd2d4bb0edbc0b0b10d9f280612ca4f0f990e3c04c599000fe7d71/rpds_py-0.27.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:8d0e09cf4863c74106b5265c2c310f36146e2b445ff7b3018a56799f28f39f6f", size = 347252 }, - { url = "https://files.pythonhosted.org/packages/f3/c8/3d1a954d30f0174dd6baf18b57c215da03cf7846a9d6e0143304e784cddc/rpds_py-0.27.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:64f689ab822f9b5eb6dfc69893b4b9366db1d2420f7db1f6a2adf2a9ca15ad64", size = 384886 }, - { url = "https://files.pythonhosted.org/packages/e0/52/3c5835f2df389832b28f9276dd5395b5a965cea34226e7c88c8fbec2093c/rpds_py-0.27.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e36c80c49853b3ffda7aa1831bf175c13356b210c73128c861f3aa93c3cc4015", size = 399716 }, - { url = "https://files.pythonhosted.org/packages/40/73/176e46992461a1749686a2a441e24df51ff86b99c2d34bf39f2a5273b987/rpds_py-0.27.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6de6a7f622860af0146cb9ee148682ff4d0cea0b8fd3ad51ce4d40efb2f061d0", size = 517030 }, - { url = "https://files.pythonhosted.org/packages/79/2a/7266c75840e8c6e70effeb0d38922a45720904f2cd695e68a0150e5407e2/rpds_py-0.27.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4045e2fc4b37ec4b48e8907a5819bdd3380708c139d7cc358f03a3653abedb89", size = 408448 }, - { url = "https://files.pythonhosted.org/packages/e6/5f/a7efc572b8e235093dc6cf39f4dbc8a7f08e65fdbcec7ff4daeb3585eef1/rpds_py-0.27.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9da162b718b12c4219eeeeb68a5b7552fbc7aadedf2efee440f88b9c0e54b45d", size = 387320 }, - { url = "https://files.pythonhosted.org/packages/a2/eb/9ff6bc92efe57cf5a2cb74dee20453ba444b6fdc85275d8c99e0d27239d1/rpds_py-0.27.0-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:0665be515767dc727ffa5f74bd2ef60b0ff85dad6bb8f50d91eaa6b5fb226f51", size = 407414 }, - { url = "https://files.pythonhosted.org/packages/fb/bd/3b9b19b00d5c6e1bd0f418c229ab0f8d3b110ddf7ec5d9d689ef783d0268/rpds_py-0.27.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:203f581accef67300a942e49a37d74c12ceeef4514874c7cede21b012613ca2c", size = 420766 }, - { url = "https://files.pythonhosted.org/packages/17/6b/521a7b1079ce16258c70805166e3ac6ec4ee2139d023fe07954dc9b2d568/rpds_py-0.27.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7873b65686a6471c0037139aa000d23fe94628e0daaa27b6e40607c90e3f5ec4", size = 562409 }, - { url = "https://files.pythonhosted.org/packages/8b/bf/65db5bfb14ccc55e39de8419a659d05a2a9cd232f0a699a516bb0991da7b/rpds_py-0.27.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:249ab91ceaa6b41abc5f19513cb95b45c6f956f6b89f1fe3d99c81255a849f9e", size = 590793 }, - { url = "https://files.pythonhosted.org/packages/db/b8/82d368b378325191ba7aae8f40f009b78057b598d4394d1f2cdabaf67b3f/rpds_py-0.27.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d2f184336bc1d6abfaaa1262ed42739c3789b1e3a65a29916a615307d22ffd2e", size = 558178 }, - { url = "https://files.pythonhosted.org/packages/f6/ff/f270bddbfbc3812500f8131b1ebbd97afd014cd554b604a3f73f03133a36/rpds_py-0.27.0-cp314-cp314-win32.whl", hash = "sha256:d3c622c39f04d5751408f5b801ecb527e6e0a471b367f420a877f7a660d583f6", size = 222355 }, - { url = "https://files.pythonhosted.org/packages/bf/20/fdab055b1460c02ed356a0e0b0a78c1dd32dc64e82a544f7b31c9ac643dc/rpds_py-0.27.0-cp314-cp314-win_amd64.whl", hash = "sha256:cf824aceaeffff029ccfba0da637d432ca71ab21f13e7f6f5179cd88ebc77a8a", size = 234007 }, - { url = "https://files.pythonhosted.org/packages/4d/a8/694c060005421797a3be4943dab8347c76c2b429a9bef68fb2c87c9e70c7/rpds_py-0.27.0-cp314-cp314-win_arm64.whl", hash = "sha256:86aca1616922b40d8ac1b3073a1ead4255a2f13405e5700c01f7c8d29a03972d", size = 223527 }, - { url = "https://files.pythonhosted.org/packages/1e/f9/77f4c90f79d2c5ca8ce6ec6a76cb4734ee247de6b3a4f337e289e1f00372/rpds_py-0.27.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:341d8acb6724c0c17bdf714319c393bb27f6d23d39bc74f94221b3e59fc31828", size = 359469 }, - { url = "https://files.pythonhosted.org/packages/c0/22/b97878d2f1284286fef4172069e84b0b42b546ea7d053e5fb7adb9ac6494/rpds_py-0.27.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6b96b0b784fe5fd03beffff2b1533dc0d85e92bab8d1b2c24ef3a5dc8fac5669", size = 343960 }, - { url = "https://files.pythonhosted.org/packages/b1/b0/dfd55b5bb480eda0578ae94ef256d3061d20b19a0f5e18c482f03e65464f/rpds_py-0.27.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0c431bfb91478d7cbe368d0a699978050d3b112d7f1d440a41e90faa325557fd", size = 380201 }, - { url = "https://files.pythonhosted.org/packages/28/22/e1fa64e50d58ad2b2053077e3ec81a979147c43428de9e6de68ddf6aff4e/rpds_py-0.27.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:20e222a44ae9f507d0f2678ee3dd0c45ec1e930f6875d99b8459631c24058aec", size = 392111 }, - { url = "https://files.pythonhosted.org/packages/49/f9/43ab7a43e97aedf6cea6af70fdcbe18abbbc41d4ae6cdec1bfc23bbad403/rpds_py-0.27.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:184f0d7b342967f6cda94a07d0e1fae177d11d0b8f17d73e06e36ac02889f303", size = 515863 }, - { url = "https://files.pythonhosted.org/packages/38/9b/9bd59dcc636cd04d86a2d20ad967770bf348f5eb5922a8f29b547c074243/rpds_py-0.27.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a00c91104c173c9043bc46f7b30ee5e6d2f6b1149f11f545580f5d6fdff42c0b", size = 402398 }, - { url = "https://files.pythonhosted.org/packages/71/bf/f099328c6c85667aba6b66fa5c35a8882db06dcd462ea214be72813a0dd2/rpds_py-0.27.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f7a37dd208f0d658e0487522078b1ed68cd6bce20ef4b5a915d2809b9094b410", size = 384665 }, - { url = "https://files.pythonhosted.org/packages/a9/c5/9c1f03121ece6634818490bd3c8be2c82a70928a19de03467fb25a3ae2a8/rpds_py-0.27.0-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:92f3b3ec3e6008a1fe00b7c0946a170f161ac00645cde35e3c9a68c2475e8156", size = 400405 }, - { url = "https://files.pythonhosted.org/packages/b5/b8/e25d54af3e63ac94f0c16d8fe143779fe71ff209445a0c00d0f6984b6b2c/rpds_py-0.27.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a1b3db5fae5cbce2131b7420a3f83553d4d89514c03d67804ced36161fe8b6b2", size = 413179 }, - { url = "https://files.pythonhosted.org/packages/f9/d1/406b3316433fe49c3021546293a04bc33f1478e3ec7950215a7fce1a1208/rpds_py-0.27.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5355527adaa713ab693cbce7c1e0ec71682f599f61b128cf19d07e5c13c9b1f1", size = 556895 }, - { url = "https://files.pythonhosted.org/packages/5f/bc/3697c0c21fcb9a54d46ae3b735eb2365eea0c2be076b8f770f98e07998de/rpds_py-0.27.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:fcc01c57ce6e70b728af02b2401c5bc853a9e14eb07deda30624374f0aebfe42", size = 585464 }, - { url = "https://files.pythonhosted.org/packages/63/09/ee1bb5536f99f42c839b177d552f6114aa3142d82f49cef49261ed28dbe0/rpds_py-0.27.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:3001013dae10f806380ba739d40dee11db1ecb91684febb8406a87c2ded23dae", size = 555090 }, - { url = "https://files.pythonhosted.org/packages/7d/2c/363eada9e89f7059199d3724135a86c47082cbf72790d6ba2f336d146ddb/rpds_py-0.27.0-cp314-cp314t-win32.whl", hash = "sha256:0f401c369186a5743694dd9fc08cba66cf70908757552e1f714bfc5219c655b5", size = 218001 }, - { url = "https://files.pythonhosted.org/packages/e2/3f/d6c216ed5199c9ef79e2a33955601f454ed1e7420a93b89670133bca5ace/rpds_py-0.27.0-cp314-cp314t-win_amd64.whl", hash = "sha256:8a1dca5507fa1337f75dcd5070218b20bc68cf8844271c923c1b79dfcbc20391", size = 230993 }, +sdist = { url = "https://files.pythonhosted.org/packages/1e/d9/991a0dee12d9fc53ed027e26a26a64b151d77252ac477e22666b9688bc16/rpds_py-0.27.0.tar.gz", hash = "sha256:8b23cf252f180cda89220b378d917180f29d313cd6a07b2431c0d3b776aae86f", size = 27420, upload-time = "2025-08-07T08:26:39.624Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cd/17/e67309ca1ac993fa1888a0d9b2f5ccc1f67196ace32e76c9f8e1dbbbd50c/rpds_py-0.27.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:19c990fdf5acecbf0623e906ae2e09ce1c58947197f9bced6bbd7482662231c4", size = 362611, upload-time = "2025-08-07T08:23:44.773Z" }, + { url = "https://files.pythonhosted.org/packages/93/2e/28c2fb84aa7aa5d75933d1862d0f7de6198ea22dfd9a0cca06e8a4e7509e/rpds_py-0.27.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6c27a7054b5224710fcfb1a626ec3ff4f28bcb89b899148c72873b18210e446b", size = 347680, upload-time = "2025-08-07T08:23:46.014Z" }, + { url = "https://files.pythonhosted.org/packages/44/3e/9834b4c8f4f5fe936b479e623832468aa4bd6beb8d014fecaee9eac6cdb1/rpds_py-0.27.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09965b314091829b378b60607022048953e25f0b396c2b70e7c4c81bcecf932e", size = 384600, upload-time = "2025-08-07T08:23:48Z" }, + { url = "https://files.pythonhosted.org/packages/19/78/744123c7b38865a965cd9e6f691fde7ef989a00a256fa8bf15b75240d12f/rpds_py-0.27.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:14f028eb47f59e9169bfdf9f7ceafd29dd64902141840633683d0bad5b04ff34", size = 400697, upload-time = "2025-08-07T08:23:49.407Z" }, + { url = "https://files.pythonhosted.org/packages/32/97/3c3d32fe7daee0a1f1a678b6d4dfb8c4dcf88197fa2441f9da7cb54a8466/rpds_py-0.27.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6168af0be75bba990a39f9431cdfae5f0ad501f4af32ae62e8856307200517b8", size = 517781, upload-time = "2025-08-07T08:23:50.557Z" }, + { url = "https://files.pythonhosted.org/packages/b2/be/28f0e3e733680aa13ecec1212fc0f585928a206292f14f89c0b8a684cad1/rpds_py-0.27.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ab47fe727c13c09d0e6f508e3a49e545008e23bf762a245b020391b621f5b726", size = 406449, upload-time = "2025-08-07T08:23:51.732Z" }, + { url = "https://files.pythonhosted.org/packages/95/ae/5d15c83e337c082d0367053baeb40bfba683f42459f6ebff63a2fd7e5518/rpds_py-0.27.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fa01b3d5e3b7d97efab65bd3d88f164e289ec323a8c033c5c38e53ee25c007e", size = 386150, upload-time = "2025-08-07T08:23:52.822Z" }, + { url = "https://files.pythonhosted.org/packages/bf/65/944e95f95d5931112829e040912b25a77b2e7ed913ea5fe5746aa5c1ce75/rpds_py-0.27.0-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:6c135708e987f46053e0a1246a206f53717f9fadfba27174a9769ad4befba5c3", size = 406100, upload-time = "2025-08-07T08:23:54.339Z" }, + { url = "https://files.pythonhosted.org/packages/21/a4/1664b83fae02894533cd11dc0b9f91d673797c2185b7be0f7496107ed6c5/rpds_py-0.27.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fc327f4497b7087d06204235199daf208fd01c82d80465dc5efa4ec9df1c5b4e", size = 421345, upload-time = "2025-08-07T08:23:55.832Z" }, + { url = "https://files.pythonhosted.org/packages/7c/26/b7303941c2b0823bfb34c71378249f8beedce57301f400acb04bb345d025/rpds_py-0.27.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7e57906e38583a2cba67046a09c2637e23297618dc1f3caddbc493f2be97c93f", size = 561891, upload-time = "2025-08-07T08:23:56.951Z" }, + { url = "https://files.pythonhosted.org/packages/9b/c8/48623d64d4a5a028fa99576c768a6159db49ab907230edddc0b8468b998b/rpds_py-0.27.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f4f69d7a4300fbf91efb1fb4916421bd57804c01ab938ab50ac9c4aa2212f03", size = 591756, upload-time = "2025-08-07T08:23:58.146Z" }, + { url = "https://files.pythonhosted.org/packages/b3/51/18f62617e8e61cc66334c9fb44b1ad7baae3438662098efbc55fb3fda453/rpds_py-0.27.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b4c4fbbcff474e1e5f38be1bf04511c03d492d42eec0babda5d03af3b5589374", size = 557088, upload-time = "2025-08-07T08:23:59.6Z" }, + { url = "https://files.pythonhosted.org/packages/bd/4c/e84c3a276e2496a93d245516be6b49e20499aa8ca1c94d59fada0d79addc/rpds_py-0.27.0-cp312-cp312-win32.whl", hash = "sha256:27bac29bbbf39601b2aab474daf99dbc8e7176ca3389237a23944b17f8913d97", size = 221926, upload-time = "2025-08-07T08:24:00.695Z" }, + { url = "https://files.pythonhosted.org/packages/83/89/9d0fbcef64340db0605eb0a0044f258076f3ae0a3b108983b2c614d96212/rpds_py-0.27.0-cp312-cp312-win_amd64.whl", hash = "sha256:8a06aa1197ec0281eb1d7daf6073e199eb832fe591ffa329b88bae28f25f5fe5", size = 233235, upload-time = "2025-08-07T08:24:01.846Z" }, + { url = "https://files.pythonhosted.org/packages/c9/b0/e177aa9f39cbab060f96de4a09df77d494f0279604dc2f509263e21b05f9/rpds_py-0.27.0-cp312-cp312-win_arm64.whl", hash = "sha256:e14aab02258cb776a108107bd15f5b5e4a1bbaa61ef33b36693dfab6f89d54f9", size = 223315, upload-time = "2025-08-07T08:24:03.337Z" }, + { url = "https://files.pythonhosted.org/packages/81/d2/dfdfd42565a923b9e5a29f93501664f5b984a802967d48d49200ad71be36/rpds_py-0.27.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:443d239d02d9ae55b74015234f2cd8eb09e59fbba30bf60baeb3123ad4c6d5ff", size = 362133, upload-time = "2025-08-07T08:24:04.508Z" }, + { url = "https://files.pythonhosted.org/packages/ac/4a/0a2e2460c4b66021d349ce9f6331df1d6c75d7eea90df9785d333a49df04/rpds_py-0.27.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b8a7acf04fda1f30f1007f3cc96d29d8cf0a53e626e4e1655fdf4eabc082d367", size = 347128, upload-time = "2025-08-07T08:24:05.695Z" }, + { url = "https://files.pythonhosted.org/packages/35/8d/7d1e4390dfe09d4213b3175a3f5a817514355cb3524593380733204f20b9/rpds_py-0.27.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d0f92b78cfc3b74a42239fdd8c1266f4715b573204c234d2f9fc3fc7a24f185", size = 384027, upload-time = "2025-08-07T08:24:06.841Z" }, + { url = "https://files.pythonhosted.org/packages/c1/65/78499d1a62172891c8cd45de737b2a4b84a414b6ad8315ab3ac4945a5b61/rpds_py-0.27.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ce4ed8e0c7dbc5b19352b9c2c6131dd23b95fa8698b5cdd076307a33626b72dc", size = 399973, upload-time = "2025-08-07T08:24:08.143Z" }, + { url = "https://files.pythonhosted.org/packages/10/a1/1c67c1d8cc889107b19570bb01f75cf49852068e95e6aee80d22915406fc/rpds_py-0.27.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fde355b02934cc6b07200cc3b27ab0c15870a757d1a72fd401aa92e2ea3c6bfe", size = 515295, upload-time = "2025-08-07T08:24:09.711Z" }, + { url = "https://files.pythonhosted.org/packages/df/27/700ec88e748436b6c7c4a2262d66e80f8c21ab585d5e98c45e02f13f21c0/rpds_py-0.27.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:13bbc4846ae4c993f07c93feb21a24d8ec637573d567a924b1001e81c8ae80f9", size = 406737, upload-time = "2025-08-07T08:24:11.182Z" }, + { url = "https://files.pythonhosted.org/packages/33/cc/6b0ee8f0ba3f2df2daac1beda17fde5cf10897a7d466f252bd184ef20162/rpds_py-0.27.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:be0744661afbc4099fef7f4e604e7f1ea1be1dd7284f357924af12a705cc7d5c", size = 385898, upload-time = "2025-08-07T08:24:12.798Z" }, + { url = "https://files.pythonhosted.org/packages/e8/7e/c927b37d7d33c0a0ebf249cc268dc2fcec52864c1b6309ecb960497f2285/rpds_py-0.27.0-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:069e0384a54f427bd65d7fda83b68a90606a3835901aaff42185fcd94f5a9295", size = 405785, upload-time = "2025-08-07T08:24:14.906Z" }, + { url = "https://files.pythonhosted.org/packages/5b/d2/8ed50746d909dcf402af3fa58b83d5a590ed43e07251d6b08fad1a535ba6/rpds_py-0.27.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4bc262ace5a1a7dc3e2eac2fa97b8257ae795389f688b5adf22c5db1e2431c43", size = 419760, upload-time = "2025-08-07T08:24:16.129Z" }, + { url = "https://files.pythonhosted.org/packages/d3/60/2b2071aee781cb3bd49f94d5d35686990b925e9b9f3e3d149235a6f5d5c1/rpds_py-0.27.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2fe6e18e5c8581f0361b35ae575043c7029d0a92cb3429e6e596c2cdde251432", size = 561201, upload-time = "2025-08-07T08:24:17.645Z" }, + { url = "https://files.pythonhosted.org/packages/98/1f/27b67304272521aaea02be293fecedce13fa351a4e41cdb9290576fc6d81/rpds_py-0.27.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d93ebdb82363d2e7bec64eecdc3632b59e84bd270d74fe5be1659f7787052f9b", size = 591021, upload-time = "2025-08-07T08:24:18.999Z" }, + { url = "https://files.pythonhosted.org/packages/db/9b/a2fadf823164dd085b1f894be6443b0762a54a7af6f36e98e8fcda69ee50/rpds_py-0.27.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0954e3a92e1d62e83a54ea7b3fdc9efa5d61acef8488a8a3d31fdafbfb00460d", size = 556368, upload-time = "2025-08-07T08:24:20.54Z" }, + { url = "https://files.pythonhosted.org/packages/24/f3/6d135d46a129cda2e3e6d4c5e91e2cc26ea0428c6cf152763f3f10b6dd05/rpds_py-0.27.0-cp313-cp313-win32.whl", hash = "sha256:2cff9bdd6c7b906cc562a505c04a57d92e82d37200027e8d362518df427f96cd", size = 221236, upload-time = "2025-08-07T08:24:22.144Z" }, + { url = "https://files.pythonhosted.org/packages/c5/44/65d7494f5448ecc755b545d78b188440f81da98b50ea0447ab5ebfdf9bd6/rpds_py-0.27.0-cp313-cp313-win_amd64.whl", hash = "sha256:dc79d192fb76fc0c84f2c58672c17bbbc383fd26c3cdc29daae16ce3d927e8b2", size = 232634, upload-time = "2025-08-07T08:24:23.642Z" }, + { url = "https://files.pythonhosted.org/packages/70/d9/23852410fadab2abb611733933401de42a1964ce6600a3badae35fbd573e/rpds_py-0.27.0-cp313-cp313-win_arm64.whl", hash = "sha256:5b3a5c8089eed498a3af23ce87a80805ff98f6ef8f7bdb70bd1b7dae5105f6ac", size = 222783, upload-time = "2025-08-07T08:24:25.098Z" }, + { url = "https://files.pythonhosted.org/packages/15/75/03447917f78512b34463f4ef11066516067099a0c466545655503bed0c77/rpds_py-0.27.0-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:90fb790138c1a89a2e58c9282fe1089638401f2f3b8dddd758499041bc6e0774", size = 359154, upload-time = "2025-08-07T08:24:26.249Z" }, + { url = "https://files.pythonhosted.org/packages/6b/fc/4dac4fa756451f2122ddaf136e2c6aeb758dc6fdbe9ccc4bc95c98451d50/rpds_py-0.27.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:010c4843a3b92b54373e3d2291a7447d6c3fc29f591772cc2ea0e9f5c1da434b", size = 343909, upload-time = "2025-08-07T08:24:27.405Z" }, + { url = "https://files.pythonhosted.org/packages/7b/81/723c1ed8e6f57ed9d8c0c07578747a2d3d554aaefc1ab89f4e42cfeefa07/rpds_py-0.27.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9ce7a9e967afc0a2af7caa0d15a3e9c1054815f73d6a8cb9225b61921b419bd", size = 379340, upload-time = "2025-08-07T08:24:28.714Z" }, + { url = "https://files.pythonhosted.org/packages/98/16/7e3740413de71818ce1997df82ba5f94bae9fff90c0a578c0e24658e6201/rpds_py-0.27.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:aa0bf113d15e8abdfee92aa4db86761b709a09954083afcb5bf0f952d6065fdb", size = 391655, upload-time = "2025-08-07T08:24:30.223Z" }, + { url = "https://files.pythonhosted.org/packages/e0/63/2a9f510e124d80660f60ecce07953f3f2d5f0b96192c1365443859b9c87f/rpds_py-0.27.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eb91d252b35004a84670dfeafadb042528b19842a0080d8b53e5ec1128e8f433", size = 513017, upload-time = "2025-08-07T08:24:31.446Z" }, + { url = "https://files.pythonhosted.org/packages/2c/4e/cf6ff311d09776c53ea1b4f2e6700b9d43bb4e99551006817ade4bbd6f78/rpds_py-0.27.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:db8a6313dbac934193fc17fe7610f70cd8181c542a91382531bef5ed785e5615", size = 402058, upload-time = "2025-08-07T08:24:32.613Z" }, + { url = "https://files.pythonhosted.org/packages/88/11/5e36096d474cb10f2a2d68b22af60a3bc4164fd8db15078769a568d9d3ac/rpds_py-0.27.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce96ab0bdfcef1b8c371ada2100767ace6804ea35aacce0aef3aeb4f3f499ca8", size = 383474, upload-time = "2025-08-07T08:24:33.767Z" }, + { url = "https://files.pythonhosted.org/packages/db/a2/3dff02805b06058760b5eaa6d8cb8db3eb3e46c9e452453ad5fc5b5ad9fe/rpds_py-0.27.0-cp313-cp313t-manylinux_2_31_riscv64.whl", hash = "sha256:7451ede3560086abe1aa27dcdcf55cd15c96b56f543fb12e5826eee6f721f858", size = 400067, upload-time = "2025-08-07T08:24:35.021Z" }, + { url = "https://files.pythonhosted.org/packages/67/87/eed7369b0b265518e21ea836456a4ed4a6744c8c12422ce05bce760bb3cf/rpds_py-0.27.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:32196b5a99821476537b3f7732432d64d93a58d680a52c5e12a190ee0135d8b5", size = 412085, upload-time = "2025-08-07T08:24:36.267Z" }, + { url = "https://files.pythonhosted.org/packages/8b/48/f50b2ab2fbb422fbb389fe296e70b7a6b5ea31b263ada5c61377e710a924/rpds_py-0.27.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a029be818059870664157194e46ce0e995082ac49926f1423c1f058534d2aaa9", size = 555928, upload-time = "2025-08-07T08:24:37.573Z" }, + { url = "https://files.pythonhosted.org/packages/98/41/b18eb51045d06887666c3560cd4bbb6819127b43d758f5adb82b5f56f7d1/rpds_py-0.27.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3841f66c1ffdc6cebce8aed64e36db71466f1dc23c0d9a5592e2a782a3042c79", size = 585527, upload-time = "2025-08-07T08:24:39.391Z" }, + { url = "https://files.pythonhosted.org/packages/be/03/a3dd6470fc76499959b00ae56295b76b4bdf7c6ffc60d62006b1217567e1/rpds_py-0.27.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:42894616da0fc0dcb2ec08a77896c3f56e9cb2f4b66acd76fc8992c3557ceb1c", size = 554211, upload-time = "2025-08-07T08:24:40.6Z" }, + { url = "https://files.pythonhosted.org/packages/bf/d1/ee5fd1be395a07423ac4ca0bcc05280bf95db2b155d03adefeb47d5ebf7e/rpds_py-0.27.0-cp313-cp313t-win32.whl", hash = "sha256:b1fef1f13c842a39a03409e30ca0bf87b39a1e2a305a9924deadb75a43105d23", size = 216624, upload-time = "2025-08-07T08:24:42.204Z" }, + { url = "https://files.pythonhosted.org/packages/1c/94/4814c4c858833bf46706f87349c37ca45e154da7dbbec9ff09f1abeb08cc/rpds_py-0.27.0-cp313-cp313t-win_amd64.whl", hash = "sha256:183f5e221ba3e283cd36fdfbe311d95cd87699a083330b4f792543987167eff1", size = 230007, upload-time = "2025-08-07T08:24:43.329Z" }, + { url = "https://files.pythonhosted.org/packages/0e/a5/8fffe1c7dc7c055aa02df310f9fb71cfc693a4d5ccc5de2d3456ea5fb022/rpds_py-0.27.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:f3cd110e02c5bf17d8fb562f6c9df5c20e73029d587cf8602a2da6c5ef1e32cb", size = 362595, upload-time = "2025-08-07T08:24:44.478Z" }, + { url = "https://files.pythonhosted.org/packages/bc/c7/4e4253fd2d4bb0edbc0b0b10d9f280612ca4f0f990e3c04c599000fe7d71/rpds_py-0.27.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:8d0e09cf4863c74106b5265c2c310f36146e2b445ff7b3018a56799f28f39f6f", size = 347252, upload-time = "2025-08-07T08:24:45.678Z" }, + { url = "https://files.pythonhosted.org/packages/f3/c8/3d1a954d30f0174dd6baf18b57c215da03cf7846a9d6e0143304e784cddc/rpds_py-0.27.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:64f689ab822f9b5eb6dfc69893b4b9366db1d2420f7db1f6a2adf2a9ca15ad64", size = 384886, upload-time = "2025-08-07T08:24:46.86Z" }, + { url = "https://files.pythonhosted.org/packages/e0/52/3c5835f2df389832b28f9276dd5395b5a965cea34226e7c88c8fbec2093c/rpds_py-0.27.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e36c80c49853b3ffda7aa1831bf175c13356b210c73128c861f3aa93c3cc4015", size = 399716, upload-time = "2025-08-07T08:24:48.174Z" }, + { url = "https://files.pythonhosted.org/packages/40/73/176e46992461a1749686a2a441e24df51ff86b99c2d34bf39f2a5273b987/rpds_py-0.27.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6de6a7f622860af0146cb9ee148682ff4d0cea0b8fd3ad51ce4d40efb2f061d0", size = 517030, upload-time = "2025-08-07T08:24:49.52Z" }, + { url = "https://files.pythonhosted.org/packages/79/2a/7266c75840e8c6e70effeb0d38922a45720904f2cd695e68a0150e5407e2/rpds_py-0.27.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4045e2fc4b37ec4b48e8907a5819bdd3380708c139d7cc358f03a3653abedb89", size = 408448, upload-time = "2025-08-07T08:24:50.727Z" }, + { url = "https://files.pythonhosted.org/packages/e6/5f/a7efc572b8e235093dc6cf39f4dbc8a7f08e65fdbcec7ff4daeb3585eef1/rpds_py-0.27.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9da162b718b12c4219eeeeb68a5b7552fbc7aadedf2efee440f88b9c0e54b45d", size = 387320, upload-time = "2025-08-07T08:24:52.004Z" }, + { url = "https://files.pythonhosted.org/packages/a2/eb/9ff6bc92efe57cf5a2cb74dee20453ba444b6fdc85275d8c99e0d27239d1/rpds_py-0.27.0-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:0665be515767dc727ffa5f74bd2ef60b0ff85dad6bb8f50d91eaa6b5fb226f51", size = 407414, upload-time = "2025-08-07T08:24:53.664Z" }, + { url = "https://files.pythonhosted.org/packages/fb/bd/3b9b19b00d5c6e1bd0f418c229ab0f8d3b110ddf7ec5d9d689ef783d0268/rpds_py-0.27.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:203f581accef67300a942e49a37d74c12ceeef4514874c7cede21b012613ca2c", size = 420766, upload-time = "2025-08-07T08:24:55.917Z" }, + { url = "https://files.pythonhosted.org/packages/17/6b/521a7b1079ce16258c70805166e3ac6ec4ee2139d023fe07954dc9b2d568/rpds_py-0.27.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7873b65686a6471c0037139aa000d23fe94628e0daaa27b6e40607c90e3f5ec4", size = 562409, upload-time = "2025-08-07T08:24:57.17Z" }, + { url = "https://files.pythonhosted.org/packages/8b/bf/65db5bfb14ccc55e39de8419a659d05a2a9cd232f0a699a516bb0991da7b/rpds_py-0.27.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:249ab91ceaa6b41abc5f19513cb95b45c6f956f6b89f1fe3d99c81255a849f9e", size = 590793, upload-time = "2025-08-07T08:24:58.388Z" }, + { url = "https://files.pythonhosted.org/packages/db/b8/82d368b378325191ba7aae8f40f009b78057b598d4394d1f2cdabaf67b3f/rpds_py-0.27.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d2f184336bc1d6abfaaa1262ed42739c3789b1e3a65a29916a615307d22ffd2e", size = 558178, upload-time = "2025-08-07T08:24:59.756Z" }, + { url = "https://files.pythonhosted.org/packages/f6/ff/f270bddbfbc3812500f8131b1ebbd97afd014cd554b604a3f73f03133a36/rpds_py-0.27.0-cp314-cp314-win32.whl", hash = "sha256:d3c622c39f04d5751408f5b801ecb527e6e0a471b367f420a877f7a660d583f6", size = 222355, upload-time = "2025-08-07T08:25:01.027Z" }, + { url = "https://files.pythonhosted.org/packages/bf/20/fdab055b1460c02ed356a0e0b0a78c1dd32dc64e82a544f7b31c9ac643dc/rpds_py-0.27.0-cp314-cp314-win_amd64.whl", hash = "sha256:cf824aceaeffff029ccfba0da637d432ca71ab21f13e7f6f5179cd88ebc77a8a", size = 234007, upload-time = "2025-08-07T08:25:02.268Z" }, + { url = "https://files.pythonhosted.org/packages/4d/a8/694c060005421797a3be4943dab8347c76c2b429a9bef68fb2c87c9e70c7/rpds_py-0.27.0-cp314-cp314-win_arm64.whl", hash = "sha256:86aca1616922b40d8ac1b3073a1ead4255a2f13405e5700c01f7c8d29a03972d", size = 223527, upload-time = "2025-08-07T08:25:03.45Z" }, + { url = "https://files.pythonhosted.org/packages/1e/f9/77f4c90f79d2c5ca8ce6ec6a76cb4734ee247de6b3a4f337e289e1f00372/rpds_py-0.27.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:341d8acb6724c0c17bdf714319c393bb27f6d23d39bc74f94221b3e59fc31828", size = 359469, upload-time = "2025-08-07T08:25:04.648Z" }, + { url = "https://files.pythonhosted.org/packages/c0/22/b97878d2f1284286fef4172069e84b0b42b546ea7d053e5fb7adb9ac6494/rpds_py-0.27.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6b96b0b784fe5fd03beffff2b1533dc0d85e92bab8d1b2c24ef3a5dc8fac5669", size = 343960, upload-time = "2025-08-07T08:25:05.863Z" }, + { url = "https://files.pythonhosted.org/packages/b1/b0/dfd55b5bb480eda0578ae94ef256d3061d20b19a0f5e18c482f03e65464f/rpds_py-0.27.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0c431bfb91478d7cbe368d0a699978050d3b112d7f1d440a41e90faa325557fd", size = 380201, upload-time = "2025-08-07T08:25:07.513Z" }, + { url = "https://files.pythonhosted.org/packages/28/22/e1fa64e50d58ad2b2053077e3ec81a979147c43428de9e6de68ddf6aff4e/rpds_py-0.27.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:20e222a44ae9f507d0f2678ee3dd0c45ec1e930f6875d99b8459631c24058aec", size = 392111, upload-time = "2025-08-07T08:25:09.149Z" }, + { url = "https://files.pythonhosted.org/packages/49/f9/43ab7a43e97aedf6cea6af70fdcbe18abbbc41d4ae6cdec1bfc23bbad403/rpds_py-0.27.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:184f0d7b342967f6cda94a07d0e1fae177d11d0b8f17d73e06e36ac02889f303", size = 515863, upload-time = "2025-08-07T08:25:10.431Z" }, + { url = "https://files.pythonhosted.org/packages/38/9b/9bd59dcc636cd04d86a2d20ad967770bf348f5eb5922a8f29b547c074243/rpds_py-0.27.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a00c91104c173c9043bc46f7b30ee5e6d2f6b1149f11f545580f5d6fdff42c0b", size = 402398, upload-time = "2025-08-07T08:25:11.819Z" }, + { url = "https://files.pythonhosted.org/packages/71/bf/f099328c6c85667aba6b66fa5c35a8882db06dcd462ea214be72813a0dd2/rpds_py-0.27.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f7a37dd208f0d658e0487522078b1ed68cd6bce20ef4b5a915d2809b9094b410", size = 384665, upload-time = "2025-08-07T08:25:13.194Z" }, + { url = "https://files.pythonhosted.org/packages/a9/c5/9c1f03121ece6634818490bd3c8be2c82a70928a19de03467fb25a3ae2a8/rpds_py-0.27.0-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:92f3b3ec3e6008a1fe00b7c0946a170f161ac00645cde35e3c9a68c2475e8156", size = 400405, upload-time = "2025-08-07T08:25:14.417Z" }, + { url = "https://files.pythonhosted.org/packages/b5/b8/e25d54af3e63ac94f0c16d8fe143779fe71ff209445a0c00d0f6984b6b2c/rpds_py-0.27.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a1b3db5fae5cbce2131b7420a3f83553d4d89514c03d67804ced36161fe8b6b2", size = 413179, upload-time = "2025-08-07T08:25:15.664Z" }, + { url = "https://files.pythonhosted.org/packages/f9/d1/406b3316433fe49c3021546293a04bc33f1478e3ec7950215a7fce1a1208/rpds_py-0.27.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5355527adaa713ab693cbce7c1e0ec71682f599f61b128cf19d07e5c13c9b1f1", size = 556895, upload-time = "2025-08-07T08:25:17.061Z" }, + { url = "https://files.pythonhosted.org/packages/5f/bc/3697c0c21fcb9a54d46ae3b735eb2365eea0c2be076b8f770f98e07998de/rpds_py-0.27.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:fcc01c57ce6e70b728af02b2401c5bc853a9e14eb07deda30624374f0aebfe42", size = 585464, upload-time = "2025-08-07T08:25:18.406Z" }, + { url = "https://files.pythonhosted.org/packages/63/09/ee1bb5536f99f42c839b177d552f6114aa3142d82f49cef49261ed28dbe0/rpds_py-0.27.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:3001013dae10f806380ba739d40dee11db1ecb91684febb8406a87c2ded23dae", size = 555090, upload-time = "2025-08-07T08:25:20.461Z" }, + { url = "https://files.pythonhosted.org/packages/7d/2c/363eada9e89f7059199d3724135a86c47082cbf72790d6ba2f336d146ddb/rpds_py-0.27.0-cp314-cp314t-win32.whl", hash = "sha256:0f401c369186a5743694dd9fc08cba66cf70908757552e1f714bfc5219c655b5", size = 218001, upload-time = "2025-08-07T08:25:21.761Z" }, + { url = "https://files.pythonhosted.org/packages/e2/3f/d6c216ed5199c9ef79e2a33955601f454ed1e7420a93b89670133bca5ace/rpds_py-0.27.0-cp314-cp314t-win_amd64.whl", hash = "sha256:8a1dca5507fa1337f75dcd5070218b20bc68cf8844271c923c1b79dfcbc20391", size = 230993, upload-time = "2025-08-07T08:25:23.34Z" }, ] [[package]] name = "ruff" version = "0.9.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c0/17/529e78f49fc6f8076f50d985edd9a2cf011d1dbadb1cdeacc1d12afc1d26/ruff-0.9.4.tar.gz", hash = "sha256:6907ee3529244bb0ed066683e075f09285b38dd5b4039370df6ff06041ca19e7", size = 3599458 } +sdist = { url = "https://files.pythonhosted.org/packages/c0/17/529e78f49fc6f8076f50d985edd9a2cf011d1dbadb1cdeacc1d12afc1d26/ruff-0.9.4.tar.gz", hash = "sha256:6907ee3529244bb0ed066683e075f09285b38dd5b4039370df6ff06041ca19e7", size = 3599458, upload-time = "2025-01-30T18:09:51.03Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b6/f8/3fafb7804d82e0699a122101b5bee5f0d6e17c3a806dcbc527bb7d3f5b7a/ruff-0.9.4-py3-none-linux_armv6l.whl", hash = "sha256:64e73d25b954f71ff100bb70f39f1ee09e880728efb4250c632ceed4e4cdf706", size = 11668400 }, - { url = "https://files.pythonhosted.org/packages/2e/a6/2efa772d335da48a70ab2c6bb41a096c8517ca43c086ea672d51079e3d1f/ruff-0.9.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:6ce6743ed64d9afab4fafeaea70d3631b4d4b28b592db21a5c2d1f0ef52934bf", size = 11628395 }, - { url = "https://files.pythonhosted.org/packages/dc/d7/cd822437561082f1c9d7225cc0d0fbb4bad117ad7ac3c41cd5d7f0fa948c/ruff-0.9.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:54499fb08408e32b57360f6f9de7157a5fec24ad79cb3f42ef2c3f3f728dfe2b", size = 11090052 }, - { url = "https://files.pythonhosted.org/packages/9e/67/3660d58e893d470abb9a13f679223368ff1684a4ef40f254a0157f51b448/ruff-0.9.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37c892540108314a6f01f105040b5106aeb829fa5fb0561d2dcaf71485021137", size = 11882221 }, - { url = "https://files.pythonhosted.org/packages/79/d1/757559995c8ba5f14dfec4459ef2dd3fcea82ac43bc4e7c7bf47484180c0/ruff-0.9.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:de9edf2ce4b9ddf43fd93e20ef635a900e25f622f87ed6e3047a664d0e8f810e", size = 11424862 }, - { url = "https://files.pythonhosted.org/packages/c0/96/7915a7c6877bb734caa6a2af424045baf6419f685632469643dbd8eb2958/ruff-0.9.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:87c90c32357c74f11deb7fbb065126d91771b207bf9bfaaee01277ca59b574ec", size = 12626735 }, - { url = "https://files.pythonhosted.org/packages/0e/cc/dadb9b35473d7cb17c7ffe4737b4377aeec519a446ee8514123ff4a26091/ruff-0.9.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:56acd6c694da3695a7461cc55775f3a409c3815ac467279dfa126061d84b314b", size = 13255976 }, - { url = "https://files.pythonhosted.org/packages/5f/c3/ad2dd59d3cabbc12df308cced780f9c14367f0321e7800ca0fe52849da4c/ruff-0.9.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e0c93e7d47ed951b9394cf352d6695b31498e68fd5782d6cbc282425655f687a", size = 12752262 }, - { url = "https://files.pythonhosted.org/packages/c7/17/5f1971e54bd71604da6788efd84d66d789362b1105e17e5ccc53bba0289b/ruff-0.9.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1d4c8772670aecf037d1bf7a07c39106574d143b26cfe5ed1787d2f31e800214", size = 14401648 }, - { url = "https://files.pythonhosted.org/packages/30/24/6200b13ea611b83260501b6955b764bb320e23b2b75884c60ee7d3f0b68e/ruff-0.9.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfc5f1d7afeda8d5d37660eeca6d389b142d7f2b5a1ab659d9214ebd0e025231", size = 12414702 }, - { url = "https://files.pythonhosted.org/packages/34/cb/f5d50d0c4ecdcc7670e348bd0b11878154bc4617f3fdd1e8ad5297c0d0ba/ruff-0.9.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:faa935fc00ae854d8b638c16a5f1ce881bc3f67446957dd6f2af440a5fc8526b", size = 11859608 }, - { url = "https://files.pythonhosted.org/packages/d6/f4/9c8499ae8426da48363bbb78d081b817b0f64a9305f9b7f87eab2a8fb2c1/ruff-0.9.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:a6c634fc6f5a0ceae1ab3e13c58183978185d131a29c425e4eaa9f40afe1e6d6", size = 11485702 }, - { url = "https://files.pythonhosted.org/packages/18/59/30490e483e804ccaa8147dd78c52e44ff96e1c30b5a95d69a63163cdb15b/ruff-0.9.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:433dedf6ddfdec7f1ac7575ec1eb9844fa60c4c8c2f8887a070672b8d353d34c", size = 12067782 }, - { url = "https://files.pythonhosted.org/packages/3d/8c/893fa9551760b2f8eb2a351b603e96f15af167ceaf27e27ad873570bc04c/ruff-0.9.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:d612dbd0f3a919a8cc1d12037168bfa536862066808960e0cc901404b77968f0", size = 12483087 }, - { url = "https://files.pythonhosted.org/packages/23/15/f6751c07c21ca10e3f4a51ea495ca975ad936d780c347d9808bcedbd7182/ruff-0.9.4-py3-none-win32.whl", hash = "sha256:db1192ddda2200671f9ef61d9597fcef89d934f5d1705e571a93a67fb13a4402", size = 9852302 }, - { url = "https://files.pythonhosted.org/packages/12/41/2d2d2c6a72e62566f730e49254f602dfed23019c33b5b21ea8f8917315a1/ruff-0.9.4-py3-none-win_amd64.whl", hash = "sha256:05bebf4cdbe3ef75430d26c375773978950bbf4ee3c95ccb5448940dc092408e", size = 10850051 }, - { url = "https://files.pythonhosted.org/packages/c6/e6/3d6ec3bc3d254e7f005c543a661a41c3e788976d0e52a1ada195bd664344/ruff-0.9.4-py3-none-win_arm64.whl", hash = "sha256:585792f1e81509e38ac5123492f8875fbc36f3ede8185af0a26df348e5154f41", size = 10078251 }, + { url = "https://files.pythonhosted.org/packages/b6/f8/3fafb7804d82e0699a122101b5bee5f0d6e17c3a806dcbc527bb7d3f5b7a/ruff-0.9.4-py3-none-linux_armv6l.whl", hash = "sha256:64e73d25b954f71ff100bb70f39f1ee09e880728efb4250c632ceed4e4cdf706", size = 11668400, upload-time = "2025-01-30T18:08:46.508Z" }, + { url = "https://files.pythonhosted.org/packages/2e/a6/2efa772d335da48a70ab2c6bb41a096c8517ca43c086ea672d51079e3d1f/ruff-0.9.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:6ce6743ed64d9afab4fafeaea70d3631b4d4b28b592db21a5c2d1f0ef52934bf", size = 11628395, upload-time = "2025-01-30T18:08:50.87Z" }, + { url = "https://files.pythonhosted.org/packages/dc/d7/cd822437561082f1c9d7225cc0d0fbb4bad117ad7ac3c41cd5d7f0fa948c/ruff-0.9.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:54499fb08408e32b57360f6f9de7157a5fec24ad79cb3f42ef2c3f3f728dfe2b", size = 11090052, upload-time = "2025-01-30T18:08:54.498Z" }, + { url = "https://files.pythonhosted.org/packages/9e/67/3660d58e893d470abb9a13f679223368ff1684a4ef40f254a0157f51b448/ruff-0.9.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37c892540108314a6f01f105040b5106aeb829fa5fb0561d2dcaf71485021137", size = 11882221, upload-time = "2025-01-30T18:08:57.784Z" }, + { url = "https://files.pythonhosted.org/packages/79/d1/757559995c8ba5f14dfec4459ef2dd3fcea82ac43bc4e7c7bf47484180c0/ruff-0.9.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:de9edf2ce4b9ddf43fd93e20ef635a900e25f622f87ed6e3047a664d0e8f810e", size = 11424862, upload-time = "2025-01-30T18:09:01.167Z" }, + { url = "https://files.pythonhosted.org/packages/c0/96/7915a7c6877bb734caa6a2af424045baf6419f685632469643dbd8eb2958/ruff-0.9.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:87c90c32357c74f11deb7fbb065126d91771b207bf9bfaaee01277ca59b574ec", size = 12626735, upload-time = "2025-01-30T18:09:05.312Z" }, + { url = "https://files.pythonhosted.org/packages/0e/cc/dadb9b35473d7cb17c7ffe4737b4377aeec519a446ee8514123ff4a26091/ruff-0.9.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:56acd6c694da3695a7461cc55775f3a409c3815ac467279dfa126061d84b314b", size = 13255976, upload-time = "2025-01-30T18:09:09.425Z" }, + { url = "https://files.pythonhosted.org/packages/5f/c3/ad2dd59d3cabbc12df308cced780f9c14367f0321e7800ca0fe52849da4c/ruff-0.9.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e0c93e7d47ed951b9394cf352d6695b31498e68fd5782d6cbc282425655f687a", size = 12752262, upload-time = "2025-01-30T18:09:13.112Z" }, + { url = "https://files.pythonhosted.org/packages/c7/17/5f1971e54bd71604da6788efd84d66d789362b1105e17e5ccc53bba0289b/ruff-0.9.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1d4c8772670aecf037d1bf7a07c39106574d143b26cfe5ed1787d2f31e800214", size = 14401648, upload-time = "2025-01-30T18:09:17.086Z" }, + { url = "https://files.pythonhosted.org/packages/30/24/6200b13ea611b83260501b6955b764bb320e23b2b75884c60ee7d3f0b68e/ruff-0.9.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfc5f1d7afeda8d5d37660eeca6d389b142d7f2b5a1ab659d9214ebd0e025231", size = 12414702, upload-time = "2025-01-30T18:09:21.672Z" }, + { url = "https://files.pythonhosted.org/packages/34/cb/f5d50d0c4ecdcc7670e348bd0b11878154bc4617f3fdd1e8ad5297c0d0ba/ruff-0.9.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:faa935fc00ae854d8b638c16a5f1ce881bc3f67446957dd6f2af440a5fc8526b", size = 11859608, upload-time = "2025-01-30T18:09:25.663Z" }, + { url = "https://files.pythonhosted.org/packages/d6/f4/9c8499ae8426da48363bbb78d081b817b0f64a9305f9b7f87eab2a8fb2c1/ruff-0.9.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:a6c634fc6f5a0ceae1ab3e13c58183978185d131a29c425e4eaa9f40afe1e6d6", size = 11485702, upload-time = "2025-01-30T18:09:28.903Z" }, + { url = "https://files.pythonhosted.org/packages/18/59/30490e483e804ccaa8147dd78c52e44ff96e1c30b5a95d69a63163cdb15b/ruff-0.9.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:433dedf6ddfdec7f1ac7575ec1eb9844fa60c4c8c2f8887a070672b8d353d34c", size = 12067782, upload-time = "2025-01-30T18:09:32.371Z" }, + { url = "https://files.pythonhosted.org/packages/3d/8c/893fa9551760b2f8eb2a351b603e96f15af167ceaf27e27ad873570bc04c/ruff-0.9.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:d612dbd0f3a919a8cc1d12037168bfa536862066808960e0cc901404b77968f0", size = 12483087, upload-time = "2025-01-30T18:09:36.124Z" }, + { url = "https://files.pythonhosted.org/packages/23/15/f6751c07c21ca10e3f4a51ea495ca975ad936d780c347d9808bcedbd7182/ruff-0.9.4-py3-none-win32.whl", hash = "sha256:db1192ddda2200671f9ef61d9597fcef89d934f5d1705e571a93a67fb13a4402", size = 9852302, upload-time = "2025-01-30T18:09:40.013Z" }, + { url = "https://files.pythonhosted.org/packages/12/41/2d2d2c6a72e62566f730e49254f602dfed23019c33b5b21ea8f8917315a1/ruff-0.9.4-py3-none-win_amd64.whl", hash = "sha256:05bebf4cdbe3ef75430d26c375773978950bbf4ee3c95ccb5448940dc092408e", size = 10850051, upload-time = "2025-01-30T18:09:43.42Z" }, + { url = "https://files.pythonhosted.org/packages/c6/e6/3d6ec3bc3d254e7f005c543a661a41c3e788976d0e52a1ada195bd664344/ruff-0.9.4-py3-none-win_arm64.whl", hash = "sha256:585792f1e81509e38ac5123492f8875fbc36f3ede8185af0a26df348e5154f41", size = 10078251, upload-time = "2025-01-30T18:09:48.01Z" }, ] [[package]] name = "six" version = "1.17.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031 } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050 }, + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, ] [[package]] name = "termcolor" version = "3.1.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ca/6c/3d75c196ac07ac8749600b60b03f4f6094d54e132c4d94ebac6ee0e0add0/termcolor-3.1.0.tar.gz", hash = "sha256:6a6dd7fbee581909eeec6a756cff1d7f7c376063b14e4a298dc4980309e55970", size = 14324 } +sdist = { url = "https://files.pythonhosted.org/packages/ca/6c/3d75c196ac07ac8749600b60b03f4f6094d54e132c4d94ebac6ee0e0add0/termcolor-3.1.0.tar.gz", hash = "sha256:6a6dd7fbee581909eeec6a756cff1d7f7c376063b14e4a298dc4980309e55970", size = 14324, upload-time = "2025-04-30T11:37:53.791Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4f/bd/de8d508070629b6d84a30d01d57e4a65c69aa7f5abe7560b8fad3b50ea59/termcolor-3.1.0-py3-none-any.whl", hash = "sha256:591dd26b5c2ce03b9e43f391264626557873ce1d379019786f99b0c2bee140aa", size = 7684 }, + { url = "https://files.pythonhosted.org/packages/4f/bd/de8d508070629b6d84a30d01d57e4a65c69aa7f5abe7560b8fad3b50ea59/termcolor-3.1.0-py3-none-any.whl", hash = "sha256:591dd26b5c2ce03b9e43f391264626557873ce1d379019786f99b0c2bee140aa", size = 7684, upload-time = "2025-04-30T11:37:52.382Z" }, ] [[package]] @@ -1088,119 +1088,119 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "python-dateutil" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/29/17/4a28bd7834a98b8fa2f96c6af9b22822f75f0e7593653b5b3234e559a8d8/time_machine-2.17.0.tar.gz", hash = "sha256:bc31f23aa4c31b6567a7e5b2bbb0d1a0c0a1340c6d050c1f1b71cd0e2e76cb7f", size = 13357 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/34/97/45b8a34e32a0dbda5c12f412dfb2128611676d38faa2b60923382d4913aa/time_machine-2.17.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:f580046d0f6c2a485ad2f350cf2b3c1e9bfbf3b03d1d353eeda63691baa44a28", size = 17428 }, - { url = "https://files.pythonhosted.org/packages/e2/0e/cdaab3d5856ac168ef36fc1673bf1a518258fa6f5685c280f9fe723fe801/time_machine-2.17.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7ef15716f52614c0156cbfd2e0a9ee1da339f399f0546735e047250ef4cd6f28", size = 13926 }, - { url = "https://files.pythonhosted.org/packages/68/a4/5677af63ddb1a204b11c06ea9b78871809079e6f42358708cb5922026f2b/time_machine-2.17.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:76c142d5af575be821beb1125f7ddff886349314d25d070eb5ab1ad017209961", size = 28614 }, - { url = "https://files.pythonhosted.org/packages/ca/c4/25639d0fc79f54849a557d0b2023d5de6f12588df64b9313e2168c296c8c/time_machine-2.17.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:d0a601556d5cc018f0ffb16f2e8bb671d7064b8a2eb350ed448392f1228eb7c2", size = 30593 }, - { url = "https://files.pythonhosted.org/packages/c7/47/486e0534b50684fc365e740f3104b8538ed58fdeb4ce8fd4086e39b5f15c/time_machine-2.17.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fe6933eede169ad2b5c3a4ded82f141b693888366f7e546c3d750040afc64485", size = 31493 }, - { url = "https://files.pythonhosted.org/packages/2f/0f/805ecfcd7606ef9313527bfcaad496b76d7875a5e1339a1dfd44c303b4d6/time_machine-2.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:97f6adb986e30d84e9fc361cf183a891704032d85e78810a885caa9c1b3bbfb3", size = 30438 }, - { url = "https://files.pythonhosted.org/packages/5a/f6/058c9d7b0f03aae68cb4cbaffcbdf1451e75967ba66413589b32dba4ee85/time_machine-2.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:43abc5426281e1967284afa24a181baa0044b9c36a9d6cd1d5cf04e35a07a11d", size = 28592 }, - { url = "https://files.pythonhosted.org/packages/a7/a9/ab7fe8c001b2f8131401b24ce4b960636952ec4a70a759bf888ab7a113a7/time_machine-2.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c308d3aed47ac0c398c45db31d9836e86758b9da17fb7dfc8f698c4d6b304070", size = 30145 }, - { url = "https://files.pythonhosted.org/packages/48/2e/dbc76e0dfea5e4bf24b71780d42a8f7f2b254316ec6a8796778482dd7645/time_machine-2.17.0-cp312-cp312-win32.whl", hash = "sha256:f4365ac2686dde0be9a60efafc7081586ae3f633ed8d7d7b556583f299b36961", size = 16168 }, - { url = "https://files.pythonhosted.org/packages/f1/14/4e28e1ea445b5b0b10b119d151117c71ef54755fa6fde3ab7039968268e7/time_machine-2.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:85058d192163af8ae6393960533204013809732d8210b6e7bb604a621e00f527", size = 17056 }, - { url = "https://files.pythonhosted.org/packages/ab/87/0effa03740870236d56a5f05841e3f3cf35cb144df6b464f1f0268d86894/time_machine-2.17.0-cp312-cp312-win_arm64.whl", hash = "sha256:48e8a850dbc83c3b7cc913537a5b1175c811a286eece1c477dc873798ff93b9d", size = 15414 }, - { url = "https://files.pythonhosted.org/packages/51/f8/6d47f24a536657cb0120984dfdfb1e0ef5046876493d839d9d6acb62ceac/time_machine-2.17.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:b74ff0463b3ca47adec9660be2b91ac15dc15e85616cecd3d526e50d006a15bf", size = 17488 }, - { url = "https://files.pythonhosted.org/packages/59/de/4035b3a46eecb1c8beef963715bcdc6bebef6cab0f5159815058eef2d181/time_machine-2.17.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0f1b96579296b124a8b85661315875c7036d09bfe985e602196bf7531bec577b", size = 13962 }, - { url = "https://files.pythonhosted.org/packages/4e/0b/88b16180e45c28461b46e649d9228a65087f3383069104149e28c62df01a/time_machine-2.17.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:ba557aa2485a942f08e9f7a6e0605d90e597f8208d9eec43994dfc55c792a5df", size = 28701 }, - { url = "https://files.pythonhosted.org/packages/84/34/b8bb83f50f6c898a49c5be9fec812591b7948ab1bcc2bb2ab660ca88326f/time_machine-2.17.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9681fd2966d1279b92cf9734c85305f1ba924cb66f8f7dffe3dc53c105e67ae0", size = 30692 }, - { url = "https://files.pythonhosted.org/packages/58/b2/4de343c1d1fa3c788f9770d372ed77619951748a7b2c1f2bcac0b1b26a22/time_machine-2.17.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:06896406b22cb5bf0665386127ec140098efd07253b91e3a9bb7bc49ef282b56", size = 31614 }, - { url = "https://files.pythonhosted.org/packages/62/14/9709374921d3c8d65cfbd74980aff5c5e66c48702ca6d072b09d06526e30/time_machine-2.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0895e81874b81066d68e88744bd261b119cb100e0dc79e7930d527fb166f2514", size = 30505 }, - { url = "https://files.pythonhosted.org/packages/a8/c9/d369908aefb1e2cacb8d4f09cca850e1c13883b11d09009aee6ecc74c0a7/time_machine-2.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:3dbb4205ab7fcbe6c2bd3ac381fa6d896ec9a025b6efad02444b00a7b6b0e921", size = 28679 }, - { url = "https://files.pythonhosted.org/packages/0c/6a/5352ade0b4467f2e6b47449659953afa30a52ffb536e84bc6518326718d6/time_machine-2.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c6363772ded138ed9d2bb312efd528dfffc7a719541b2e0c46c3afc044e8d973", size = 30222 }, - { url = "https://files.pythonhosted.org/packages/dc/9a/9ceec84be9ef1993b028e2ab09b425cb58ee324b9313ec10be83bd29bf15/time_machine-2.17.0-cp313-cp313-win32.whl", hash = "sha256:79addc4e83d6a6003a81bb7becf9a46e73f79132d5b2f5311b45e1b9f1e14807", size = 16201 }, - { url = "https://files.pythonhosted.org/packages/35/3b/39890aded8016649dcc7f1ec891725dce75cdb23576ab7a8697e2102b4f9/time_machine-2.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:47ab5947541526a322926d7ab30a6b3c9b8dfd0e23a345afa3cda80147a06130", size = 17073 }, - { url = "https://files.pythonhosted.org/packages/59/72/2bac1a52d4fb26a2f35fe103af68dedb844a7f5484d7c481bd6aac9b3413/time_machine-2.17.0-cp313-cp313-win_arm64.whl", hash = "sha256:ab37bbe5f233667d0a1aa14f81ed0a85f402cc72c2f9e10e190f404a2ff057cc", size = 15447 }, - { url = "https://files.pythonhosted.org/packages/70/53/280947f1f718d6a1ab26502f6e74e694dd52221860822cb996ffc1ba00be/time_machine-2.17.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:2852334b4ae8442dd182c2623dea79aa5167eb5dc558a63a116617db8b96a573", size = 18160 }, - { url = "https://files.pythonhosted.org/packages/9f/d3/48a9e53dd222261434e92c691308561b50c933d7ae4d1ab9b98f64cb3528/time_machine-2.17.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:9abb2098d22a17d0255a1768c7caa0ffe70f3c2c936a5351a7c81555f28b768d", size = 14274 }, - { url = "https://files.pythonhosted.org/packages/72/13/b832d7ec0480b2a5d4ede67749c89d5ef8ebb8ed7847852888e4aff71846/time_machine-2.17.0-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:1fc270f6220762c31d5afe2f0f3e05bea2366c51368db18c43c303a9640e84c8", size = 34870 }, - { url = "https://files.pythonhosted.org/packages/9b/f3/91be773deb38a96c312aba7a7b5a03188b9fc9a84fec03ba551d437a77e7/time_machine-2.17.0-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9f6afd89664d2e30a6e57f3ce9aeb53502064167f628f14bf6927d5a2cbd2101", size = 36477 }, - { url = "https://files.pythonhosted.org/packages/ad/45/4b878dfefffc4093e7eb1997a2fa3fc392a10b9bc10ed19013b9b0c3903d/time_machine-2.17.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2844002ff867d083c267bb19ecf7fb326e964c01a0a9cc323dd2f55d275fdb9d", size = 38048 }, - { url = "https://files.pythonhosted.org/packages/fa/02/91824603ae9f45bc35dcc56f4e9b58821ce0a60a5c96e043a374813e1ef1/time_machine-2.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a8228b79be107bb0eb76ece610545b5a9d88bf398d0cbeb1ab5363fe026939fa", size = 36439 }, - { url = "https://files.pythonhosted.org/packages/eb/aa/d4a102148a1a7a25d7bfa47f36fa1a4fc62637c4112ca2fd0d41203d9b53/time_machine-2.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:8137ea6c680bd62554f15e36b9f384406790f0b2605bdbc4fe52f0b9e4644ff5", size = 34508 }, - { url = "https://files.pythonhosted.org/packages/82/48/77a14d9c876273086848ddd0bf8fd255813e2cd74bda7e449d159c52bea3/time_machine-2.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:7c216990c381c4a3f25fb648377cd1022d65cfbf0023ecbab12f78c9f02066cf", size = 35604 }, - { url = "https://files.pythonhosted.org/packages/07/55/5b0d30d2d756f1ec631a75a9c0c61b2e121426d9ca4e313b986ca5ef94f3/time_machine-2.17.0-cp313-cp313t-win32.whl", hash = "sha256:f22139193db761cb470e20a954aa86157e1b51b3e03f1ece879d235fef3a13e1", size = 16662 }, - { url = "https://files.pythonhosted.org/packages/21/53/fa0ed23fb5ad4aff986c310e5049f4e354a9c2d995dbfae042b5d7bd194c/time_machine-2.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:8b37d391555e316248a3c227a298959034a23e5fc6e059e1f1fe591d0f58fe77", size = 17775 }, - { url = "https://files.pythonhosted.org/packages/6a/37/e8b2b85dfdaa68cee7a16684366a8defe240bef5c9a8780eac0783a5930b/time_machine-2.17.0-cp313-cp313t-win_arm64.whl", hash = "sha256:c4ab494d787e571b53323c130349d667c4d91bd74a0278758cf9edc1ecfc7098", size = 15573 }, - { url = "https://files.pythonhosted.org/packages/8d/d3/028f9c3661c3fff8e53730151939c5a5bdca9489d5b8d59e1ffdb806a3e0/time_machine-2.17.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:ce7f9967f1a744b1b0c8c2c29aca0a20468077041907b4e4288a82a4988e7fcf", size = 17510 }, - { url = "https://files.pythonhosted.org/packages/49/b2/52f6d0ae707944d4cadc16f8c1c4c720f1ea23251290edf0f17fda757270/time_machine-2.17.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:6673ce6e3000d8e42104d0dd5d5b6a367ca6c69d215704f72da74e354e5f860e", size = 13953 }, - { url = "https://files.pythonhosted.org/packages/19/56/9045a2b54df55f0df1105e2949edbe4030a5b64542555202ae61456886e7/time_machine-2.17.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:0d59b492109dcfe424885a3ef50555cfeb0ccc71e58ad4e027babfc91809adb1", size = 28649 }, - { url = "https://files.pythonhosted.org/packages/26/70/dfe5f9a9624b6e18be2e116789eea615a489aa71a36c9aa6a03c36a6e1c5/time_machine-2.17.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:1594e8e1d970675a87615f3fe59d212d527b54f0315ae577fef0c0d7baf42275", size = 30775 }, - { url = "https://files.pythonhosted.org/packages/8f/19/98ef48cab5c16327117558b05a96c707bb25fb30b2177c4c5b12892ca35b/time_machine-2.17.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:49e1e7be05eb0396e0e71373c552061bd644e8973a5a0139ea76a328c7b794a0", size = 31665 }, - { url = "https://files.pythonhosted.org/packages/9f/09/eee2ca0409012a78a7ecf5a165bfe2f3baaa668b460c8e7fb6004c0cf2a1/time_machine-2.17.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7bd4e0120184c377827050bbe41760a385943d64291089855a6ccdf3f5dc554e", size = 30574 }, - { url = "https://files.pythonhosted.org/packages/04/8c/009515834c7668b09b084f03104e05bd906b1ca0630321d2ebe6d6e00c9d/time_machine-2.17.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:fd8859dbba8f214a4c733a00cd84a1da1262510e6d8a1adac0c10478b61c018a", size = 28593 }, - { url = "https://files.pythonhosted.org/packages/94/8e/de7c4ba4c8891570b29a7cf47babe93a020d51b10713f7e9cb25445a4d62/time_machine-2.17.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:7b8cfa7412093a4ca0eb218e6f042ef476a3fbf0035a07405c095f0fdf2c4ab5", size = 30296 }, - { url = "https://files.pythonhosted.org/packages/dc/70/a37621b293d312d3b6d2140d593f8f6d58842ee1c68dfd40286d4d321db5/time_machine-2.17.0-cp314-cp314-win32.whl", hash = "sha256:71f432058917fb2405a9d0005886d4680d30f1a36de400bb5f726b5106b67566", size = 16290 }, - { url = "https://files.pythonhosted.org/packages/74/05/ee42ab62574ff20199a39127439e927cfcb68d65b0ee82bae10d8ae67496/time_machine-2.17.0-cp314-cp314-win_amd64.whl", hash = "sha256:bec64a2d1e33c14438b94f80b241e9e7a3e543cfcb70ae9c12020b17c23728d2", size = 17151 }, - { url = "https://files.pythonhosted.org/packages/f8/db/9b0675488d6b4526814d697331e1646e055ae0e29e3452e74e88bbd98faa/time_machine-2.17.0-cp314-cp314-win_arm64.whl", hash = "sha256:b12c419bc5d23a3153976177c24bf95d666af3ef32acb73947145eb18e051854", size = 15478 }, - { url = "https://files.pythonhosted.org/packages/08/f3/04ba0fa1d4d95b29eee1cd6b7adf81ff62dc4e6d15d940eca52ac442b649/time_machine-2.17.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:239e069a3b09f68082ffa7fbd500078a99ed0a80defb8d0b3f1607be74532166", size = 18161 }, - { url = "https://files.pythonhosted.org/packages/4d/ee/416d6e8254c9e3d262738927490661fa7ed8067d377ab7af4b932b914e23/time_machine-2.17.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:ddd4d92bd51c536e11469f3c9ff40b7604b8d02425da2243d8a8e498d9a1cc71", size = 14273 }, - { url = "https://files.pythonhosted.org/packages/4d/90/90045f06548fe4bc5bb3ba0e8d7b765134abde6bcc871dbb48460f90a76e/time_machine-2.17.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:b38b77bdd8a45820bbdaad6c031b71b925b442b78cef84c05d98f5d52e5f4c7e", size = 34860 }, - { url = "https://files.pythonhosted.org/packages/ee/64/0a1676ad8671ee2652e734347ac57a283780f07a7c24610f5c4948395a5e/time_machine-2.17.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:dc22a40dc78613fae6092d577845cc47e84fff5b83749b4f405e923cc186829e", size = 36493 }, - { url = "https://files.pythonhosted.org/packages/ed/73/da80da3400c732b5b118331cc31b1725e5c886c8120e9a46c35be2cfbdb5/time_machine-2.17.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:05ea377c8b57dc74395ba05cd6a1c63dc2b23db5f709f704a39c8fe920bb6135", size = 38047 }, - { url = "https://files.pythonhosted.org/packages/f3/12/32a8e0f0a4f8de599bdcebbc4738f8959759ae6b2e880867e4453bd4d8e6/time_machine-2.17.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:4d93d2838d05676ae892eaa6f9e52e3c3697fd58e3c9c7a288302bc00a55afb9", size = 36453 }, - { url = "https://files.pythonhosted.org/packages/18/61/633b23f9f515bdf8331264e4530b622513a95482897a93db354888ca9d63/time_machine-2.17.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:32ec169809838cc68cd03ee878a93742b7d4c83f87f494816bfa9ca4b053f244", size = 34509 }, - { url = "https://files.pythonhosted.org/packages/dc/39/686d69635cc0a9c2b5e3e639982504803ea45877e14f81a34f5f158b230d/time_machine-2.17.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:657444bac9cb0e1326aa83936df0ff1ed99e66e2142555ad9a6f32f3c5dd6560", size = 35616 }, - { url = "https://files.pythonhosted.org/packages/c4/8c/ca9eb63adceaf2895d40d37f67bb0bb5e304e010bcb46573e7e845acb67f/time_machine-2.17.0-cp314-cp314t-win32.whl", hash = "sha256:4c7e18d92375070c43be2a54e40ec1a25fd82b1955e11f72cb4d61d47c76cf42", size = 16842 }, - { url = "https://files.pythonhosted.org/packages/3f/d6/e08acb5071787b22438872dd9e7966f00cb6c8e2bad8cf8be5242a8fa9b5/time_machine-2.17.0-cp314-cp314t-win_amd64.whl", hash = "sha256:e64eaecc26631f69c17925d3e5a1da4a50956f02d63b6589eb5f9b401b17ce67", size = 17998 }, - { url = "https://files.pythonhosted.org/packages/b3/95/9b7562f26c9b9d34b8658a9e9fc4c710e8162c000201f81ff3c68c1af840/time_machine-2.17.0-cp314-cp314t-win_arm64.whl", hash = "sha256:d83d2e4cc1db49441bed3320e0d3225d027db456912fceabfe393e4664d5027f", size = 15619 }, +sdist = { url = "https://files.pythonhosted.org/packages/29/17/4a28bd7834a98b8fa2f96c6af9b22822f75f0e7593653b5b3234e559a8d8/time_machine-2.17.0.tar.gz", hash = "sha256:bc31f23aa4c31b6567a7e5b2bbb0d1a0c0a1340c6d050c1f1b71cd0e2e76cb7f", size = 13357, upload-time = "2025-08-05T15:20:17.153Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/34/97/45b8a34e32a0dbda5c12f412dfb2128611676d38faa2b60923382d4913aa/time_machine-2.17.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:f580046d0f6c2a485ad2f350cf2b3c1e9bfbf3b03d1d353eeda63691baa44a28", size = 17428, upload-time = "2025-08-05T15:19:04.823Z" }, + { url = "https://files.pythonhosted.org/packages/e2/0e/cdaab3d5856ac168ef36fc1673bf1a518258fa6f5685c280f9fe723fe801/time_machine-2.17.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7ef15716f52614c0156cbfd2e0a9ee1da339f399f0546735e047250ef4cd6f28", size = 13926, upload-time = "2025-08-05T15:19:05.728Z" }, + { url = "https://files.pythonhosted.org/packages/68/a4/5677af63ddb1a204b11c06ea9b78871809079e6f42358708cb5922026f2b/time_machine-2.17.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:76c142d5af575be821beb1125f7ddff886349314d25d070eb5ab1ad017209961", size = 28614, upload-time = "2025-08-05T15:19:06.603Z" }, + { url = "https://files.pythonhosted.org/packages/ca/c4/25639d0fc79f54849a557d0b2023d5de6f12588df64b9313e2168c296c8c/time_machine-2.17.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:d0a601556d5cc018f0ffb16f2e8bb671d7064b8a2eb350ed448392f1228eb7c2", size = 30593, upload-time = "2025-08-05T15:19:07.904Z" }, + { url = "https://files.pythonhosted.org/packages/c7/47/486e0534b50684fc365e740f3104b8538ed58fdeb4ce8fd4086e39b5f15c/time_machine-2.17.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fe6933eede169ad2b5c3a4ded82f141b693888366f7e546c3d750040afc64485", size = 31493, upload-time = "2025-08-05T15:19:08.888Z" }, + { url = "https://files.pythonhosted.org/packages/2f/0f/805ecfcd7606ef9313527bfcaad496b76d7875a5e1339a1dfd44c303b4d6/time_machine-2.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:97f6adb986e30d84e9fc361cf183a891704032d85e78810a885caa9c1b3bbfb3", size = 30438, upload-time = "2025-08-05T15:19:09.834Z" }, + { url = "https://files.pythonhosted.org/packages/5a/f6/058c9d7b0f03aae68cb4cbaffcbdf1451e75967ba66413589b32dba4ee85/time_machine-2.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:43abc5426281e1967284afa24a181baa0044b9c36a9d6cd1d5cf04e35a07a11d", size = 28592, upload-time = "2025-08-05T15:19:10.747Z" }, + { url = "https://files.pythonhosted.org/packages/a7/a9/ab7fe8c001b2f8131401b24ce4b960636952ec4a70a759bf888ab7a113a7/time_machine-2.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c308d3aed47ac0c398c45db31d9836e86758b9da17fb7dfc8f698c4d6b304070", size = 30145, upload-time = "2025-08-05T15:19:11.731Z" }, + { url = "https://files.pythonhosted.org/packages/48/2e/dbc76e0dfea5e4bf24b71780d42a8f7f2b254316ec6a8796778482dd7645/time_machine-2.17.0-cp312-cp312-win32.whl", hash = "sha256:f4365ac2686dde0be9a60efafc7081586ae3f633ed8d7d7b556583f299b36961", size = 16168, upload-time = "2025-08-05T15:19:13.196Z" }, + { url = "https://files.pythonhosted.org/packages/f1/14/4e28e1ea445b5b0b10b119d151117c71ef54755fa6fde3ab7039968268e7/time_machine-2.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:85058d192163af8ae6393960533204013809732d8210b6e7bb604a621e00f527", size = 17056, upload-time = "2025-08-05T15:19:14.545Z" }, + { url = "https://files.pythonhosted.org/packages/ab/87/0effa03740870236d56a5f05841e3f3cf35cb144df6b464f1f0268d86894/time_machine-2.17.0-cp312-cp312-win_arm64.whl", hash = "sha256:48e8a850dbc83c3b7cc913537a5b1175c811a286eece1c477dc873798ff93b9d", size = 15414, upload-time = "2025-08-05T15:19:15.487Z" }, + { url = "https://files.pythonhosted.org/packages/51/f8/6d47f24a536657cb0120984dfdfb1e0ef5046876493d839d9d6acb62ceac/time_machine-2.17.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:b74ff0463b3ca47adec9660be2b91ac15dc15e85616cecd3d526e50d006a15bf", size = 17488, upload-time = "2025-08-05T15:19:16.417Z" }, + { url = "https://files.pythonhosted.org/packages/59/de/4035b3a46eecb1c8beef963715bcdc6bebef6cab0f5159815058eef2d181/time_machine-2.17.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0f1b96579296b124a8b85661315875c7036d09bfe985e602196bf7531bec577b", size = 13962, upload-time = "2025-08-05T15:19:17.424Z" }, + { url = "https://files.pythonhosted.org/packages/4e/0b/88b16180e45c28461b46e649d9228a65087f3383069104149e28c62df01a/time_machine-2.17.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:ba557aa2485a942f08e9f7a6e0605d90e597f8208d9eec43994dfc55c792a5df", size = 28701, upload-time = "2025-08-05T15:19:18.52Z" }, + { url = "https://files.pythonhosted.org/packages/84/34/b8bb83f50f6c898a49c5be9fec812591b7948ab1bcc2bb2ab660ca88326f/time_machine-2.17.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9681fd2966d1279b92cf9734c85305f1ba924cb66f8f7dffe3dc53c105e67ae0", size = 30692, upload-time = "2025-08-05T15:19:19.466Z" }, + { url = "https://files.pythonhosted.org/packages/58/b2/4de343c1d1fa3c788f9770d372ed77619951748a7b2c1f2bcac0b1b26a22/time_machine-2.17.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:06896406b22cb5bf0665386127ec140098efd07253b91e3a9bb7bc49ef282b56", size = 31614, upload-time = "2025-08-05T15:19:20.895Z" }, + { url = "https://files.pythonhosted.org/packages/62/14/9709374921d3c8d65cfbd74980aff5c5e66c48702ca6d072b09d06526e30/time_machine-2.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0895e81874b81066d68e88744bd261b119cb100e0dc79e7930d527fb166f2514", size = 30505, upload-time = "2025-08-05T15:19:22.203Z" }, + { url = "https://files.pythonhosted.org/packages/a8/c9/d369908aefb1e2cacb8d4f09cca850e1c13883b11d09009aee6ecc74c0a7/time_machine-2.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:3dbb4205ab7fcbe6c2bd3ac381fa6d896ec9a025b6efad02444b00a7b6b0e921", size = 28679, upload-time = "2025-08-05T15:19:23.237Z" }, + { url = "https://files.pythonhosted.org/packages/0c/6a/5352ade0b4467f2e6b47449659953afa30a52ffb536e84bc6518326718d6/time_machine-2.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c6363772ded138ed9d2bb312efd528dfffc7a719541b2e0c46c3afc044e8d973", size = 30222, upload-time = "2025-08-05T15:19:24.387Z" }, + { url = "https://files.pythonhosted.org/packages/dc/9a/9ceec84be9ef1993b028e2ab09b425cb58ee324b9313ec10be83bd29bf15/time_machine-2.17.0-cp313-cp313-win32.whl", hash = "sha256:79addc4e83d6a6003a81bb7becf9a46e73f79132d5b2f5311b45e1b9f1e14807", size = 16201, upload-time = "2025-08-05T15:19:25.334Z" }, + { url = "https://files.pythonhosted.org/packages/35/3b/39890aded8016649dcc7f1ec891725dce75cdb23576ab7a8697e2102b4f9/time_machine-2.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:47ab5947541526a322926d7ab30a6b3c9b8dfd0e23a345afa3cda80147a06130", size = 17073, upload-time = "2025-08-05T15:19:26.431Z" }, + { url = "https://files.pythonhosted.org/packages/59/72/2bac1a52d4fb26a2f35fe103af68dedb844a7f5484d7c481bd6aac9b3413/time_machine-2.17.0-cp313-cp313-win_arm64.whl", hash = "sha256:ab37bbe5f233667d0a1aa14f81ed0a85f402cc72c2f9e10e190f404a2ff057cc", size = 15447, upload-time = "2025-08-05T15:19:27.384Z" }, + { url = "https://files.pythonhosted.org/packages/70/53/280947f1f718d6a1ab26502f6e74e694dd52221860822cb996ffc1ba00be/time_machine-2.17.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:2852334b4ae8442dd182c2623dea79aa5167eb5dc558a63a116617db8b96a573", size = 18160, upload-time = "2025-08-05T15:19:28.323Z" }, + { url = "https://files.pythonhosted.org/packages/9f/d3/48a9e53dd222261434e92c691308561b50c933d7ae4d1ab9b98f64cb3528/time_machine-2.17.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:9abb2098d22a17d0255a1768c7caa0ffe70f3c2c936a5351a7c81555f28b768d", size = 14274, upload-time = "2025-08-05T15:19:29.228Z" }, + { url = "https://files.pythonhosted.org/packages/72/13/b832d7ec0480b2a5d4ede67749c89d5ef8ebb8ed7847852888e4aff71846/time_machine-2.17.0-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:1fc270f6220762c31d5afe2f0f3e05bea2366c51368db18c43c303a9640e84c8", size = 34870, upload-time = "2025-08-05T15:19:30.196Z" }, + { url = "https://files.pythonhosted.org/packages/9b/f3/91be773deb38a96c312aba7a7b5a03188b9fc9a84fec03ba551d437a77e7/time_machine-2.17.0-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9f6afd89664d2e30a6e57f3ce9aeb53502064167f628f14bf6927d5a2cbd2101", size = 36477, upload-time = "2025-08-05T15:19:31.651Z" }, + { url = "https://files.pythonhosted.org/packages/ad/45/4b878dfefffc4093e7eb1997a2fa3fc392a10b9bc10ed19013b9b0c3903d/time_machine-2.17.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2844002ff867d083c267bb19ecf7fb326e964c01a0a9cc323dd2f55d275fdb9d", size = 38048, upload-time = "2025-08-05T15:19:32.624Z" }, + { url = "https://files.pythonhosted.org/packages/fa/02/91824603ae9f45bc35dcc56f4e9b58821ce0a60a5c96e043a374813e1ef1/time_machine-2.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a8228b79be107bb0eb76ece610545b5a9d88bf398d0cbeb1ab5363fe026939fa", size = 36439, upload-time = "2025-08-05T15:19:33.604Z" }, + { url = "https://files.pythonhosted.org/packages/eb/aa/d4a102148a1a7a25d7bfa47f36fa1a4fc62637c4112ca2fd0d41203d9b53/time_machine-2.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:8137ea6c680bd62554f15e36b9f384406790f0b2605bdbc4fe52f0b9e4644ff5", size = 34508, upload-time = "2025-08-05T15:19:34.606Z" }, + { url = "https://files.pythonhosted.org/packages/82/48/77a14d9c876273086848ddd0bf8fd255813e2cd74bda7e449d159c52bea3/time_machine-2.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:7c216990c381c4a3f25fb648377cd1022d65cfbf0023ecbab12f78c9f02066cf", size = 35604, upload-time = "2025-08-05T15:19:35.658Z" }, + { url = "https://files.pythonhosted.org/packages/07/55/5b0d30d2d756f1ec631a75a9c0c61b2e121426d9ca4e313b986ca5ef94f3/time_machine-2.17.0-cp313-cp313t-win32.whl", hash = "sha256:f22139193db761cb470e20a954aa86157e1b51b3e03f1ece879d235fef3a13e1", size = 16662, upload-time = "2025-08-05T15:19:36.69Z" }, + { url = "https://files.pythonhosted.org/packages/21/53/fa0ed23fb5ad4aff986c310e5049f4e354a9c2d995dbfae042b5d7bd194c/time_machine-2.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:8b37d391555e316248a3c227a298959034a23e5fc6e059e1f1fe591d0f58fe77", size = 17775, upload-time = "2025-08-05T15:19:37.948Z" }, + { url = "https://files.pythonhosted.org/packages/6a/37/e8b2b85dfdaa68cee7a16684366a8defe240bef5c9a8780eac0783a5930b/time_machine-2.17.0-cp313-cp313t-win_arm64.whl", hash = "sha256:c4ab494d787e571b53323c130349d667c4d91bd74a0278758cf9edc1ecfc7098", size = 15573, upload-time = "2025-08-05T15:19:38.967Z" }, + { url = "https://files.pythonhosted.org/packages/8d/d3/028f9c3661c3fff8e53730151939c5a5bdca9489d5b8d59e1ffdb806a3e0/time_machine-2.17.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:ce7f9967f1a744b1b0c8c2c29aca0a20468077041907b4e4288a82a4988e7fcf", size = 17510, upload-time = "2025-08-05T15:19:39.912Z" }, + { url = "https://files.pythonhosted.org/packages/49/b2/52f6d0ae707944d4cadc16f8c1c4c720f1ea23251290edf0f17fda757270/time_machine-2.17.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:6673ce6e3000d8e42104d0dd5d5b6a367ca6c69d215704f72da74e354e5f860e", size = 13953, upload-time = "2025-08-05T15:19:41.395Z" }, + { url = "https://files.pythonhosted.org/packages/19/56/9045a2b54df55f0df1105e2949edbe4030a5b64542555202ae61456886e7/time_machine-2.17.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:0d59b492109dcfe424885a3ef50555cfeb0ccc71e58ad4e027babfc91809adb1", size = 28649, upload-time = "2025-08-05T15:19:42.731Z" }, + { url = "https://files.pythonhosted.org/packages/26/70/dfe5f9a9624b6e18be2e116789eea615a489aa71a36c9aa6a03c36a6e1c5/time_machine-2.17.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:1594e8e1d970675a87615f3fe59d212d527b54f0315ae577fef0c0d7baf42275", size = 30775, upload-time = "2025-08-05T15:19:43.855Z" }, + { url = "https://files.pythonhosted.org/packages/8f/19/98ef48cab5c16327117558b05a96c707bb25fb30b2177c4c5b12892ca35b/time_machine-2.17.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:49e1e7be05eb0396e0e71373c552061bd644e8973a5a0139ea76a328c7b794a0", size = 31665, upload-time = "2025-08-05T15:19:44.928Z" }, + { url = "https://files.pythonhosted.org/packages/9f/09/eee2ca0409012a78a7ecf5a165bfe2f3baaa668b460c8e7fb6004c0cf2a1/time_machine-2.17.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7bd4e0120184c377827050bbe41760a385943d64291089855a6ccdf3f5dc554e", size = 30574, upload-time = "2025-08-05T15:19:45.972Z" }, + { url = "https://files.pythonhosted.org/packages/04/8c/009515834c7668b09b084f03104e05bd906b1ca0630321d2ebe6d6e00c9d/time_machine-2.17.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:fd8859dbba8f214a4c733a00cd84a1da1262510e6d8a1adac0c10478b61c018a", size = 28593, upload-time = "2025-08-05T15:19:46.957Z" }, + { url = "https://files.pythonhosted.org/packages/94/8e/de7c4ba4c8891570b29a7cf47babe93a020d51b10713f7e9cb25445a4d62/time_machine-2.17.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:7b8cfa7412093a4ca0eb218e6f042ef476a3fbf0035a07405c095f0fdf2c4ab5", size = 30296, upload-time = "2025-08-05T15:19:47.938Z" }, + { url = "https://files.pythonhosted.org/packages/dc/70/a37621b293d312d3b6d2140d593f8f6d58842ee1c68dfd40286d4d321db5/time_machine-2.17.0-cp314-cp314-win32.whl", hash = "sha256:71f432058917fb2405a9d0005886d4680d30f1a36de400bb5f726b5106b67566", size = 16290, upload-time = "2025-08-05T15:19:48.918Z" }, + { url = "https://files.pythonhosted.org/packages/74/05/ee42ab62574ff20199a39127439e927cfcb68d65b0ee82bae10d8ae67496/time_machine-2.17.0-cp314-cp314-win_amd64.whl", hash = "sha256:bec64a2d1e33c14438b94f80b241e9e7a3e543cfcb70ae9c12020b17c23728d2", size = 17151, upload-time = "2025-08-05T15:19:50.011Z" }, + { url = "https://files.pythonhosted.org/packages/f8/db/9b0675488d6b4526814d697331e1646e055ae0e29e3452e74e88bbd98faa/time_machine-2.17.0-cp314-cp314-win_arm64.whl", hash = "sha256:b12c419bc5d23a3153976177c24bf95d666af3ef32acb73947145eb18e051854", size = 15478, upload-time = "2025-08-05T15:19:51.006Z" }, + { url = "https://files.pythonhosted.org/packages/08/f3/04ba0fa1d4d95b29eee1cd6b7adf81ff62dc4e6d15d940eca52ac442b649/time_machine-2.17.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:239e069a3b09f68082ffa7fbd500078a99ed0a80defb8d0b3f1607be74532166", size = 18161, upload-time = "2025-08-05T15:19:52.343Z" }, + { url = "https://files.pythonhosted.org/packages/4d/ee/416d6e8254c9e3d262738927490661fa7ed8067d377ab7af4b932b914e23/time_machine-2.17.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:ddd4d92bd51c536e11469f3c9ff40b7604b8d02425da2243d8a8e498d9a1cc71", size = 14273, upload-time = "2025-08-05T15:19:53.447Z" }, + { url = "https://files.pythonhosted.org/packages/4d/90/90045f06548fe4bc5bb3ba0e8d7b765134abde6bcc871dbb48460f90a76e/time_machine-2.17.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:b38b77bdd8a45820bbdaad6c031b71b925b442b78cef84c05d98f5d52e5f4c7e", size = 34860, upload-time = "2025-08-05T15:19:54.452Z" }, + { url = "https://files.pythonhosted.org/packages/ee/64/0a1676ad8671ee2652e734347ac57a283780f07a7c24610f5c4948395a5e/time_machine-2.17.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:dc22a40dc78613fae6092d577845cc47e84fff5b83749b4f405e923cc186829e", size = 36493, upload-time = "2025-08-05T15:19:55.503Z" }, + { url = "https://files.pythonhosted.org/packages/ed/73/da80da3400c732b5b118331cc31b1725e5c886c8120e9a46c35be2cfbdb5/time_machine-2.17.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:05ea377c8b57dc74395ba05cd6a1c63dc2b23db5f709f704a39c8fe920bb6135", size = 38047, upload-time = "2025-08-05T15:19:56.532Z" }, + { url = "https://files.pythonhosted.org/packages/f3/12/32a8e0f0a4f8de599bdcebbc4738f8959759ae6b2e880867e4453bd4d8e6/time_machine-2.17.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:4d93d2838d05676ae892eaa6f9e52e3c3697fd58e3c9c7a288302bc00a55afb9", size = 36453, upload-time = "2025-08-05T15:19:57.53Z" }, + { url = "https://files.pythonhosted.org/packages/18/61/633b23f9f515bdf8331264e4530b622513a95482897a93db354888ca9d63/time_machine-2.17.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:32ec169809838cc68cd03ee878a93742b7d4c83f87f494816bfa9ca4b053f244", size = 34509, upload-time = "2025-08-05T15:19:58.53Z" }, + { url = "https://files.pythonhosted.org/packages/dc/39/686d69635cc0a9c2b5e3e639982504803ea45877e14f81a34f5f158b230d/time_machine-2.17.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:657444bac9cb0e1326aa83936df0ff1ed99e66e2142555ad9a6f32f3c5dd6560", size = 35616, upload-time = "2025-08-05T15:19:59.588Z" }, + { url = "https://files.pythonhosted.org/packages/c4/8c/ca9eb63adceaf2895d40d37f67bb0bb5e304e010bcb46573e7e845acb67f/time_machine-2.17.0-cp314-cp314t-win32.whl", hash = "sha256:4c7e18d92375070c43be2a54e40ec1a25fd82b1955e11f72cb4d61d47c76cf42", size = 16842, upload-time = "2025-08-05T15:20:01.074Z" }, + { url = "https://files.pythonhosted.org/packages/3f/d6/e08acb5071787b22438872dd9e7966f00cb6c8e2bad8cf8be5242a8fa9b5/time_machine-2.17.0-cp314-cp314t-win_amd64.whl", hash = "sha256:e64eaecc26631f69c17925d3e5a1da4a50956f02d63b6589eb5f9b401b17ce67", size = 17998, upload-time = "2025-08-05T15:20:02.076Z" }, + { url = "https://files.pythonhosted.org/packages/b3/95/9b7562f26c9b9d34b8658a9e9fc4c710e8162c000201f81ff3c68c1af840/time_machine-2.17.0-cp314-cp314t-win_arm64.whl", hash = "sha256:d83d2e4cc1db49441bed3320e0d3225d027db456912fceabfe393e4664d5027f", size = 15619, upload-time = "2025-08-05T15:20:03.49Z" }, ] [[package]] name = "tomli" version = "2.2.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/18/87/302344fed471e44a87289cf4967697d07e532f2421fdaf868a303cbae4ff/tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff", size = 17175 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/52/e1/f8af4c2fcde17500422858155aeb0d7e93477a0d59a98e56cbfe75070fd0/tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea", size = 132762 }, - { url = "https://files.pythonhosted.org/packages/03/b8/152c68bb84fc00396b83e7bbddd5ec0bd3dd409db4195e2a9b3e398ad2e3/tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8", size = 123453 }, - { url = "https://files.pythonhosted.org/packages/c8/d6/fc9267af9166f79ac528ff7e8c55c8181ded34eb4b0e93daa767b8841573/tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192", size = 233486 }, - { url = "https://files.pythonhosted.org/packages/5c/51/51c3f2884d7bab89af25f678447ea7d297b53b5a3b5730a7cb2ef6069f07/tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222", size = 242349 }, - { url = "https://files.pythonhosted.org/packages/ab/df/bfa89627d13a5cc22402e441e8a931ef2108403db390ff3345c05253935e/tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77", size = 252159 }, - { url = "https://files.pythonhosted.org/packages/9e/6e/fa2b916dced65763a5168c6ccb91066f7639bdc88b48adda990db10c8c0b/tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6", size = 237243 }, - { url = "https://files.pythonhosted.org/packages/b4/04/885d3b1f650e1153cbb93a6a9782c58a972b94ea4483ae4ac5cedd5e4a09/tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd", size = 259645 }, - { url = "https://files.pythonhosted.org/packages/9c/de/6b432d66e986e501586da298e28ebeefd3edc2c780f3ad73d22566034239/tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e", size = 244584 }, - { url = "https://files.pythonhosted.org/packages/1c/9a/47c0449b98e6e7d1be6cbac02f93dd79003234ddc4aaab6ba07a9a7482e2/tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98", size = 98875 }, - { url = "https://files.pythonhosted.org/packages/ef/60/9b9638f081c6f1261e2688bd487625cd1e660d0a85bd469e91d8db969734/tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4", size = 109418 }, - { url = "https://files.pythonhosted.org/packages/04/90/2ee5f2e0362cb8a0b6499dc44f4d7d48f8fff06d28ba46e6f1eaa61a1388/tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7", size = 132708 }, - { url = "https://files.pythonhosted.org/packages/c0/ec/46b4108816de6b385141f082ba99e315501ccd0a2ea23db4a100dd3990ea/tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c", size = 123582 }, - { url = "https://files.pythonhosted.org/packages/a0/bd/b470466d0137b37b68d24556c38a0cc819e8febe392d5b199dcd7f578365/tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13", size = 232543 }, - { url = "https://files.pythonhosted.org/packages/d9/e5/82e80ff3b751373f7cead2815bcbe2d51c895b3c990686741a8e56ec42ab/tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281", size = 241691 }, - { url = "https://files.pythonhosted.org/packages/05/7e/2a110bc2713557d6a1bfb06af23dd01e7dde52b6ee7dadc589868f9abfac/tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272", size = 251170 }, - { url = "https://files.pythonhosted.org/packages/64/7b/22d713946efe00e0adbcdfd6d1aa119ae03fd0b60ebed51ebb3fa9f5a2e5/tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140", size = 236530 }, - { url = "https://files.pythonhosted.org/packages/38/31/3a76f67da4b0cf37b742ca76beaf819dca0ebef26d78fc794a576e08accf/tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2", size = 258666 }, - { url = "https://files.pythonhosted.org/packages/07/10/5af1293da642aded87e8a988753945d0cf7e00a9452d3911dd3bb354c9e2/tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744", size = 243954 }, - { url = "https://files.pythonhosted.org/packages/5b/b9/1ed31d167be802da0fc95020d04cd27b7d7065cc6fbefdd2f9186f60d7bd/tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec", size = 98724 }, - { url = "https://files.pythonhosted.org/packages/c7/32/b0963458706accd9afcfeb867c0f9175a741bf7b19cd424230714d722198/tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69", size = 109383 }, - { url = "https://files.pythonhosted.org/packages/6e/c2/61d3e0f47e2b74ef40a68b9e6ad5984f6241a942f7cd3bbfbdbd03861ea9/tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", size = 14257 }, +sdist = { url = "https://files.pythonhosted.org/packages/18/87/302344fed471e44a87289cf4967697d07e532f2421fdaf868a303cbae4ff/tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff", size = 17175, upload-time = "2024-11-27T22:38:36.873Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/52/e1/f8af4c2fcde17500422858155aeb0d7e93477a0d59a98e56cbfe75070fd0/tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea", size = 132762, upload-time = "2024-11-27T22:38:07.731Z" }, + { url = "https://files.pythonhosted.org/packages/03/b8/152c68bb84fc00396b83e7bbddd5ec0bd3dd409db4195e2a9b3e398ad2e3/tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8", size = 123453, upload-time = "2024-11-27T22:38:09.384Z" }, + { url = "https://files.pythonhosted.org/packages/c8/d6/fc9267af9166f79ac528ff7e8c55c8181ded34eb4b0e93daa767b8841573/tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192", size = 233486, upload-time = "2024-11-27T22:38:10.329Z" }, + { url = "https://files.pythonhosted.org/packages/5c/51/51c3f2884d7bab89af25f678447ea7d297b53b5a3b5730a7cb2ef6069f07/tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222", size = 242349, upload-time = "2024-11-27T22:38:11.443Z" }, + { url = "https://files.pythonhosted.org/packages/ab/df/bfa89627d13a5cc22402e441e8a931ef2108403db390ff3345c05253935e/tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77", size = 252159, upload-time = "2024-11-27T22:38:13.099Z" }, + { url = "https://files.pythonhosted.org/packages/9e/6e/fa2b916dced65763a5168c6ccb91066f7639bdc88b48adda990db10c8c0b/tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6", size = 237243, upload-time = "2024-11-27T22:38:14.766Z" }, + { url = "https://files.pythonhosted.org/packages/b4/04/885d3b1f650e1153cbb93a6a9782c58a972b94ea4483ae4ac5cedd5e4a09/tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd", size = 259645, upload-time = "2024-11-27T22:38:15.843Z" }, + { url = "https://files.pythonhosted.org/packages/9c/de/6b432d66e986e501586da298e28ebeefd3edc2c780f3ad73d22566034239/tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e", size = 244584, upload-time = "2024-11-27T22:38:17.645Z" }, + { url = "https://files.pythonhosted.org/packages/1c/9a/47c0449b98e6e7d1be6cbac02f93dd79003234ddc4aaab6ba07a9a7482e2/tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98", size = 98875, upload-time = "2024-11-27T22:38:19.159Z" }, + { url = "https://files.pythonhosted.org/packages/ef/60/9b9638f081c6f1261e2688bd487625cd1e660d0a85bd469e91d8db969734/tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4", size = 109418, upload-time = "2024-11-27T22:38:20.064Z" }, + { url = "https://files.pythonhosted.org/packages/04/90/2ee5f2e0362cb8a0b6499dc44f4d7d48f8fff06d28ba46e6f1eaa61a1388/tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7", size = 132708, upload-time = "2024-11-27T22:38:21.659Z" }, + { url = "https://files.pythonhosted.org/packages/c0/ec/46b4108816de6b385141f082ba99e315501ccd0a2ea23db4a100dd3990ea/tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c", size = 123582, upload-time = "2024-11-27T22:38:22.693Z" }, + { url = "https://files.pythonhosted.org/packages/a0/bd/b470466d0137b37b68d24556c38a0cc819e8febe392d5b199dcd7f578365/tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13", size = 232543, upload-time = "2024-11-27T22:38:24.367Z" }, + { url = "https://files.pythonhosted.org/packages/d9/e5/82e80ff3b751373f7cead2815bcbe2d51c895b3c990686741a8e56ec42ab/tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281", size = 241691, upload-time = "2024-11-27T22:38:26.081Z" }, + { url = "https://files.pythonhosted.org/packages/05/7e/2a110bc2713557d6a1bfb06af23dd01e7dde52b6ee7dadc589868f9abfac/tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272", size = 251170, upload-time = "2024-11-27T22:38:27.921Z" }, + { url = "https://files.pythonhosted.org/packages/64/7b/22d713946efe00e0adbcdfd6d1aa119ae03fd0b60ebed51ebb3fa9f5a2e5/tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140", size = 236530, upload-time = "2024-11-27T22:38:29.591Z" }, + { url = "https://files.pythonhosted.org/packages/38/31/3a76f67da4b0cf37b742ca76beaf819dca0ebef26d78fc794a576e08accf/tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2", size = 258666, upload-time = "2024-11-27T22:38:30.639Z" }, + { url = "https://files.pythonhosted.org/packages/07/10/5af1293da642aded87e8a988753945d0cf7e00a9452d3911dd3bb354c9e2/tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744", size = 243954, upload-time = "2024-11-27T22:38:31.702Z" }, + { url = "https://files.pythonhosted.org/packages/5b/b9/1ed31d167be802da0fc95020d04cd27b7d7065cc6fbefdd2f9186f60d7bd/tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec", size = 98724, upload-time = "2024-11-27T22:38:32.837Z" }, + { url = "https://files.pythonhosted.org/packages/c7/32/b0963458706accd9afcfeb867c0f9175a741bf7b19cd424230714d722198/tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69", size = 109383, upload-time = "2024-11-27T22:38:34.455Z" }, + { url = "https://files.pythonhosted.org/packages/6e/c2/61d3e0f47e2b74ef40a68b9e6ad5984f6241a942f7cd3bbfbdbd03861ea9/tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", size = 14257, upload-time = "2024-11-27T22:38:35.385Z" }, ] [[package]] name = "tomlkit" version = "0.13.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/cc/18/0bbf3884e9eaa38819ebe46a7bd25dcd56b67434402b66a58c4b8e552575/tomlkit-0.13.3.tar.gz", hash = "sha256:430cf247ee57df2b94ee3fbe588e71d362a941ebb545dec29b53961d61add2a1", size = 185207 } +sdist = { url = "https://files.pythonhosted.org/packages/cc/18/0bbf3884e9eaa38819ebe46a7bd25dcd56b67434402b66a58c4b8e552575/tomlkit-0.13.3.tar.gz", hash = "sha256:430cf247ee57df2b94ee3fbe588e71d362a941ebb545dec29b53961d61add2a1", size = 185207, upload-time = "2025-06-05T07:13:44.947Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/bd/75/8539d011f6be8e29f339c42e633aae3cb73bffa95dd0f9adec09b9c58e85/tomlkit-0.13.3-py3-none-any.whl", hash = "sha256:c89c649d79ee40629a9fda55f8ace8c6a1b42deb912b2a8fd8d942ddadb606b0", size = 38901 }, + { url = "https://files.pythonhosted.org/packages/bd/75/8539d011f6be8e29f339c42e633aae3cb73bffa95dd0f9adec09b9c58e85/tomlkit-0.13.3-py3-none-any.whl", hash = "sha256:c89c649d79ee40629a9fda55f8ace8c6a1b42deb912b2a8fd8d942ddadb606b0", size = 38901, upload-time = "2025-06-05T07:13:43.546Z" }, ] [[package]] name = "typing-extensions" version = "4.14.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/98/5a/da40306b885cc8c09109dc2e1abd358d5684b1425678151cdaed4731c822/typing_extensions-4.14.1.tar.gz", hash = "sha256:38b39f4aeeab64884ce9f74c94263ef78f3c22467c8724005483154c26648d36", size = 107673 } +sdist = { url = "https://files.pythonhosted.org/packages/98/5a/da40306b885cc8c09109dc2e1abd358d5684b1425678151cdaed4731c822/typing_extensions-4.14.1.tar.gz", hash = "sha256:38b39f4aeeab64884ce9f74c94263ef78f3c22467c8724005483154c26648d36", size = 107673, upload-time = "2025-07-04T13:28:34.16Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b5/00/d631e67a838026495268c2f6884f3711a15a9a2a96cd244fdaea53b823fb/typing_extensions-4.14.1-py3-none-any.whl", hash = "sha256:d1e1e3b58374dc93031d6eda2420a48ea44a36c2b4766a4fdeb3710755731d76", size = 43906 }, + { url = "https://files.pythonhosted.org/packages/b5/00/d631e67a838026495268c2f6884f3711a15a9a2a96cd244fdaea53b823fb/typing_extensions-4.14.1-py3-none-any.whl", hash = "sha256:d1e1e3b58374dc93031d6eda2420a48ea44a36c2b4766a4fdeb3710755731d76", size = 43906, upload-time = "2025-07-04T13:28:32.743Z" }, ] [[package]] name = "urllib3" version = "2.5.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/15/22/9ee70a2574a4f4599c47dd506532914ce044817c7752a79b6a51286319bc/urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760", size = 393185 } +sdist = { url = "https://files.pythonhosted.org/packages/15/22/9ee70a2574a4f4599c47dd506532914ce044817c7752a79b6a51286319bc/urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760", size = 393185, upload-time = "2025-06-18T14:07:41.644Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc", size = 129795 }, + { url = "https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc", size = 129795, upload-time = "2025-06-18T14:07:40.39Z" }, ] [[package]] @@ -1212,18 +1212,18 @@ dependencies = [ { name = "filelock" }, { name = "platformdirs" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/8b/60/4f20960df6c7b363a18a55ab034c8f2bcd5d9770d1f94f9370ec104c1855/virtualenv-20.33.1.tar.gz", hash = "sha256:1b44478d9e261b3fb8baa5e74a0ca3bc0e05f21aa36167bf9cbf850e542765b8", size = 6082160 } +sdist = { url = "https://files.pythonhosted.org/packages/8b/60/4f20960df6c7b363a18a55ab034c8f2bcd5d9770d1f94f9370ec104c1855/virtualenv-20.33.1.tar.gz", hash = "sha256:1b44478d9e261b3fb8baa5e74a0ca3bc0e05f21aa36167bf9cbf850e542765b8", size = 6082160, upload-time = "2025-08-05T16:10:55.605Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ca/ff/ded57ac5ff40a09e6e198550bab075d780941e0b0f83cbeabd087c59383a/virtualenv-20.33.1-py3-none-any.whl", hash = "sha256:07c19bc66c11acab6a5958b815cbcee30891cd1c2ccf53785a28651a0d8d8a67", size = 6060362 }, + { url = "https://files.pythonhosted.org/packages/ca/ff/ded57ac5ff40a09e6e198550bab075d780941e0b0f83cbeabd087c59383a/virtualenv-20.33.1-py3-none-any.whl", hash = "sha256:07c19bc66c11acab6a5958b815cbcee30891cd1c2ccf53785a28651a0d8d8a67", size = 6060362, upload-time = "2025-08-05T16:10:52.81Z" }, ] [[package]] name = "voluptuous" version = "0.15.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/91/af/a54ce0fb6f1d867e0b9f0efe5f082a691f51ccf705188fca67a3ecefd7f4/voluptuous-0.15.2.tar.gz", hash = "sha256:6ffcab32c4d3230b4d2af3a577c87e1908a714a11f6f95570456b1849b0279aa", size = 51651 } +sdist = { url = "https://files.pythonhosted.org/packages/91/af/a54ce0fb6f1d867e0b9f0efe5f082a691f51ccf705188fca67a3ecefd7f4/voluptuous-0.15.2.tar.gz", hash = "sha256:6ffcab32c4d3230b4d2af3a577c87e1908a714a11f6f95570456b1849b0279aa", size = 51651, upload-time = "2024-07-02T19:10:00.528Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/db/a8/8f9cc6749331186e6a513bfe3745454f81d25f6e34c6024f88f80c71ed28/voluptuous-0.15.2-py3-none-any.whl", hash = "sha256:016348bc7788a9af9520b1764ebd4de0df41fe2138ebe9e06fa036bf86a65566", size = 31349 }, + { url = "https://files.pythonhosted.org/packages/db/a8/8f9cc6749331186e6a513bfe3745454f81d25f6e34c6024f88f80c71ed28/voluptuous-0.15.2-py3-none-any.whl", hash = "sha256:016348bc7788a9af9520b1764ebd4de0df41fe2138ebe9e06fa036bf86a65566", size = 31349, upload-time = "2024-07-02T19:09:58.125Z" }, ] [[package]] @@ -1235,60 +1235,60 @@ dependencies = [ { name = "multidict" }, { name = "propcache" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/3c/fb/efaa23fa4e45537b827620f04cf8f3cd658b76642205162e072703a5b963/yarl-1.20.1.tar.gz", hash = "sha256:d017a4997ee50c91fd5466cef416231bb82177b93b029906cefc542ce14c35ac", size = 186428 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5f/9a/cb7fad7d73c69f296eda6815e4a2c7ed53fc70c2f136479a91c8e5fbdb6d/yarl-1.20.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bdcc4cd244e58593a4379fe60fdee5ac0331f8eb70320a24d591a3be197b94a9", size = 133667 }, - { url = "https://files.pythonhosted.org/packages/67/38/688577a1cb1e656e3971fb66a3492501c5a5df56d99722e57c98249e5b8a/yarl-1.20.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b29a2c385a5f5b9c7d9347e5812b6f7ab267193c62d282a540b4fc528c8a9d2a", size = 91025 }, - { url = "https://files.pythonhosted.org/packages/50/ec/72991ae51febeb11a42813fc259f0d4c8e0507f2b74b5514618d8b640365/yarl-1.20.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1112ae8154186dfe2de4732197f59c05a83dc814849a5ced892b708033f40dc2", size = 89709 }, - { url = "https://files.pythonhosted.org/packages/99/da/4d798025490e89426e9f976702e5f9482005c548c579bdae792a4c37769e/yarl-1.20.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:90bbd29c4fe234233f7fa2b9b121fb63c321830e5d05b45153a2ca68f7d310ee", size = 352287 }, - { url = "https://files.pythonhosted.org/packages/1a/26/54a15c6a567aac1c61b18aa0f4b8aa2e285a52d547d1be8bf48abe2b3991/yarl-1.20.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:680e19c7ce3710ac4cd964e90dad99bf9b5029372ba0c7cbfcd55e54d90ea819", size = 345429 }, - { url = "https://files.pythonhosted.org/packages/d6/95/9dcf2386cb875b234353b93ec43e40219e14900e046bf6ac118f94b1e353/yarl-1.20.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4a979218c1fdb4246a05efc2cc23859d47c89af463a90b99b7c56094daf25a16", size = 365429 }, - { url = "https://files.pythonhosted.org/packages/91/b2/33a8750f6a4bc224242a635f5f2cff6d6ad5ba651f6edcccf721992c21a0/yarl-1.20.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255b468adf57b4a7b65d8aad5b5138dce6a0752c139965711bdcb81bc370e1b6", size = 363862 }, - { url = "https://files.pythonhosted.org/packages/98/28/3ab7acc5b51f4434b181b0cee8f1f4b77a65919700a355fb3617f9488874/yarl-1.20.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a97d67108e79cfe22e2b430d80d7571ae57d19f17cda8bb967057ca8a7bf5bfd", size = 355616 }, - { url = "https://files.pythonhosted.org/packages/36/a3/f666894aa947a371724ec7cd2e5daa78ee8a777b21509b4252dd7bd15e29/yarl-1.20.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8570d998db4ddbfb9a590b185a0a33dbf8aafb831d07a5257b4ec9948df9cb0a", size = 339954 }, - { url = "https://files.pythonhosted.org/packages/f1/81/5f466427e09773c04219d3450d7a1256138a010b6c9f0af2d48565e9ad13/yarl-1.20.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:97c75596019baae7c71ccf1d8cc4738bc08134060d0adfcbe5642f778d1dca38", size = 365575 }, - { url = "https://files.pythonhosted.org/packages/2e/e3/e4b0ad8403e97e6c9972dd587388940a032f030ebec196ab81a3b8e94d31/yarl-1.20.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:1c48912653e63aef91ff988c5432832692ac5a1d8f0fb8a33091520b5bbe19ef", size = 365061 }, - { url = "https://files.pythonhosted.org/packages/ac/99/b8a142e79eb86c926f9f06452eb13ecb1bb5713bd01dc0038faf5452e544/yarl-1.20.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4c3ae28f3ae1563c50f3d37f064ddb1511ecc1d5584e88c6b7c63cf7702a6d5f", size = 364142 }, - { url = "https://files.pythonhosted.org/packages/34/f2/08ed34a4a506d82a1a3e5bab99ccd930a040f9b6449e9fd050320e45845c/yarl-1.20.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c5e9642f27036283550f5f57dc6156c51084b458570b9d0d96100c8bebb186a8", size = 381894 }, - { url = "https://files.pythonhosted.org/packages/92/f8/9a3fbf0968eac704f681726eff595dce9b49c8a25cd92bf83df209668285/yarl-1.20.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:2c26b0c49220d5799f7b22c6838409ee9bc58ee5c95361a4d7831f03cc225b5a", size = 383378 }, - { url = "https://files.pythonhosted.org/packages/af/85/9363f77bdfa1e4d690957cd39d192c4cacd1c58965df0470a4905253b54f/yarl-1.20.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:564ab3d517e3d01c408c67f2e5247aad4019dcf1969982aba3974b4093279004", size = 374069 }, - { url = "https://files.pythonhosted.org/packages/35/99/9918c8739ba271dcd935400cff8b32e3cd319eaf02fcd023d5dcd487a7c8/yarl-1.20.1-cp312-cp312-win32.whl", hash = "sha256:daea0d313868da1cf2fac6b2d3a25c6e3a9e879483244be38c8e6a41f1d876a5", size = 81249 }, - { url = "https://files.pythonhosted.org/packages/eb/83/5d9092950565481b413b31a23e75dd3418ff0a277d6e0abf3729d4d1ce25/yarl-1.20.1-cp312-cp312-win_amd64.whl", hash = "sha256:48ea7d7f9be0487339828a4de0360d7ce0efc06524a48e1810f945c45b813698", size = 86710 }, - { url = "https://files.pythonhosted.org/packages/8a/e1/2411b6d7f769a07687acee88a062af5833cf1966b7266f3d8dfb3d3dc7d3/yarl-1.20.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:0b5ff0fbb7c9f1b1b5ab53330acbfc5247893069e7716840c8e7d5bb7355038a", size = 131811 }, - { url = "https://files.pythonhosted.org/packages/b2/27/584394e1cb76fb771371770eccad35de400e7b434ce3142c2dd27392c968/yarl-1.20.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:14f326acd845c2b2e2eb38fb1346c94f7f3b01a4f5c788f8144f9b630bfff9a3", size = 90078 }, - { url = "https://files.pythonhosted.org/packages/bf/9a/3246ae92d4049099f52d9b0fe3486e3b500e29b7ea872d0f152966fc209d/yarl-1.20.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f60e4ad5db23f0b96e49c018596707c3ae89f5d0bd97f0ad3684bcbad899f1e7", size = 88748 }, - { url = "https://files.pythonhosted.org/packages/a3/25/35afe384e31115a1a801fbcf84012d7a066d89035befae7c5d4284df1e03/yarl-1.20.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:49bdd1b8e00ce57e68ba51916e4bb04461746e794e7c4d4bbc42ba2f18297691", size = 349595 }, - { url = "https://files.pythonhosted.org/packages/28/2d/8aca6cb2cabc8f12efcb82749b9cefecbccfc7b0384e56cd71058ccee433/yarl-1.20.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:66252d780b45189975abfed839616e8fd2dbacbdc262105ad7742c6ae58f3e31", size = 342616 }, - { url = "https://files.pythonhosted.org/packages/0b/e9/1312633d16b31acf0098d30440ca855e3492d66623dafb8e25b03d00c3da/yarl-1.20.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59174e7332f5d153d8f7452a102b103e2e74035ad085f404df2e40e663a22b28", size = 361324 }, - { url = "https://files.pythonhosted.org/packages/bc/a0/688cc99463f12f7669eec7c8acc71ef56a1521b99eab7cd3abb75af887b0/yarl-1.20.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e3968ec7d92a0c0f9ac34d5ecfd03869ec0cab0697c91a45db3fbbd95fe1b653", size = 359676 }, - { url = "https://files.pythonhosted.org/packages/af/44/46407d7f7a56e9a85a4c207724c9f2c545c060380718eea9088f222ba697/yarl-1.20.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1a4fbb50e14396ba3d375f68bfe02215d8e7bc3ec49da8341fe3157f59d2ff5", size = 352614 }, - { url = "https://files.pythonhosted.org/packages/b1/91/31163295e82b8d5485d31d9cf7754d973d41915cadce070491778d9c9825/yarl-1.20.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11a62c839c3a8eac2410e951301309426f368388ff2f33799052787035793b02", size = 336766 }, - { url = "https://files.pythonhosted.org/packages/b4/8e/c41a5bc482121f51c083c4c2bcd16b9e01e1cf8729e380273a952513a21f/yarl-1.20.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:041eaa14f73ff5a8986b4388ac6bb43a77f2ea09bf1913df7a35d4646db69e53", size = 364615 }, - { url = "https://files.pythonhosted.org/packages/e3/5b/61a3b054238d33d70ea06ebba7e58597891b71c699e247df35cc984ab393/yarl-1.20.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:377fae2fef158e8fd9d60b4c8751387b8d1fb121d3d0b8e9b0be07d1b41e83dc", size = 360982 }, - { url = "https://files.pythonhosted.org/packages/df/a3/6a72fb83f8d478cb201d14927bc8040af901811a88e0ff2da7842dd0ed19/yarl-1.20.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1c92f4390e407513f619d49319023664643d3339bd5e5a56a3bebe01bc67ec04", size = 369792 }, - { url = "https://files.pythonhosted.org/packages/7c/af/4cc3c36dfc7c077f8dedb561eb21f69e1e9f2456b91b593882b0b18c19dc/yarl-1.20.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:d25ddcf954df1754ab0f86bb696af765c5bfaba39b74095f27eececa049ef9a4", size = 382049 }, - { url = "https://files.pythonhosted.org/packages/19/3a/e54e2c4752160115183a66dc9ee75a153f81f3ab2ba4bf79c3c53b33de34/yarl-1.20.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:909313577e9619dcff8c31a0ea2aa0a2a828341d92673015456b3ae492e7317b", size = 384774 }, - { url = "https://files.pythonhosted.org/packages/9c/20/200ae86dabfca89060ec6447649f219b4cbd94531e425e50d57e5f5ac330/yarl-1.20.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:793fd0580cb9664548c6b83c63b43c477212c0260891ddf86809e1c06c8b08f1", size = 374252 }, - { url = "https://files.pythonhosted.org/packages/83/75/11ee332f2f516b3d094e89448da73d557687f7d137d5a0f48c40ff211487/yarl-1.20.1-cp313-cp313-win32.whl", hash = "sha256:468f6e40285de5a5b3c44981ca3a319a4b208ccc07d526b20b12aeedcfa654b7", size = 81198 }, - { url = "https://files.pythonhosted.org/packages/ba/ba/39b1ecbf51620b40ab402b0fc817f0ff750f6d92712b44689c2c215be89d/yarl-1.20.1-cp313-cp313-win_amd64.whl", hash = "sha256:495b4ef2fea40596bfc0affe3837411d6aa3371abcf31aac0ccc4bdd64d4ef5c", size = 86346 }, - { url = "https://files.pythonhosted.org/packages/43/c7/669c52519dca4c95153c8ad96dd123c79f354a376346b198f438e56ffeb4/yarl-1.20.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:f60233b98423aab21d249a30eb27c389c14929f47be8430efa7dbd91493a729d", size = 138826 }, - { url = "https://files.pythonhosted.org/packages/6a/42/fc0053719b44f6ad04a75d7f05e0e9674d45ef62f2d9ad2c1163e5c05827/yarl-1.20.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:6f3eff4cc3f03d650d8755c6eefc844edde99d641d0dcf4da3ab27141a5f8ddf", size = 93217 }, - { url = "https://files.pythonhosted.org/packages/4f/7f/fa59c4c27e2a076bba0d959386e26eba77eb52ea4a0aac48e3515c186b4c/yarl-1.20.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:69ff8439d8ba832d6bed88af2c2b3445977eba9a4588b787b32945871c2444e3", size = 92700 }, - { url = "https://files.pythonhosted.org/packages/2f/d4/062b2f48e7c93481e88eff97a6312dca15ea200e959f23e96d8ab898c5b8/yarl-1.20.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cf34efa60eb81dd2645a2e13e00bb98b76c35ab5061a3989c7a70f78c85006d", size = 347644 }, - { url = "https://files.pythonhosted.org/packages/89/47/78b7f40d13c8f62b499cc702fdf69e090455518ae544c00a3bf4afc9fc77/yarl-1.20.1-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:8e0fe9364ad0fddab2688ce72cb7a8e61ea42eff3c7caeeb83874a5d479c896c", size = 323452 }, - { url = "https://files.pythonhosted.org/packages/eb/2b/490d3b2dc66f52987d4ee0d3090a147ea67732ce6b4d61e362c1846d0d32/yarl-1.20.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8f64fbf81878ba914562c672024089e3401974a39767747691c65080a67b18c1", size = 346378 }, - { url = "https://files.pythonhosted.org/packages/66/ad/775da9c8a94ce925d1537f939a4f17d782efef1f973039d821cbe4bcc211/yarl-1.20.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f6342d643bf9a1de97e512e45e4b9560a043347e779a173250824f8b254bd5ce", size = 353261 }, - { url = "https://files.pythonhosted.org/packages/4b/23/0ed0922b47a4f5c6eb9065d5ff1e459747226ddce5c6a4c111e728c9f701/yarl-1.20.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56dac5f452ed25eef0f6e3c6a066c6ab68971d96a9fb441791cad0efba6140d3", size = 335987 }, - { url = "https://files.pythonhosted.org/packages/3e/49/bc728a7fe7d0e9336e2b78f0958a2d6b288ba89f25a1762407a222bf53c3/yarl-1.20.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7d7f497126d65e2cad8dc5f97d34c27b19199b6414a40cb36b52f41b79014be", size = 329361 }, - { url = "https://files.pythonhosted.org/packages/93/8f/b811b9d1f617c83c907e7082a76e2b92b655400e61730cd61a1f67178393/yarl-1.20.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:67e708dfb8e78d8a19169818eeb5c7a80717562de9051bf2413aca8e3696bf16", size = 346460 }, - { url = "https://files.pythonhosted.org/packages/70/fd/af94f04f275f95da2c3b8b5e1d49e3e79f1ed8b6ceb0f1664cbd902773ff/yarl-1.20.1-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:595c07bc79af2494365cc96ddeb772f76272364ef7c80fb892ef9d0649586513", size = 334486 }, - { url = "https://files.pythonhosted.org/packages/84/65/04c62e82704e7dd0a9b3f61dbaa8447f8507655fd16c51da0637b39b2910/yarl-1.20.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:7bdd2f80f4a7df852ab9ab49484a4dee8030023aa536df41f2d922fd57bf023f", size = 342219 }, - { url = "https://files.pythonhosted.org/packages/91/95/459ca62eb958381b342d94ab9a4b6aec1ddec1f7057c487e926f03c06d30/yarl-1.20.1-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:c03bfebc4ae8d862f853a9757199677ab74ec25424d0ebd68a0027e9c639a390", size = 350693 }, - { url = "https://files.pythonhosted.org/packages/a6/00/d393e82dd955ad20617abc546a8f1aee40534d599ff555ea053d0ec9bf03/yarl-1.20.1-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:344d1103e9c1523f32a5ed704d576172d2cabed3122ea90b1d4e11fe17c66458", size = 355803 }, - { url = "https://files.pythonhosted.org/packages/9e/ed/c5fb04869b99b717985e244fd93029c7a8e8febdfcffa06093e32d7d44e7/yarl-1.20.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:88cab98aa4e13e1ade8c141daeedd300a4603b7132819c484841bb7af3edce9e", size = 341709 }, - { url = "https://files.pythonhosted.org/packages/24/fd/725b8e73ac2a50e78a4534ac43c6addf5c1c2d65380dd48a9169cc6739a9/yarl-1.20.1-cp313-cp313t-win32.whl", hash = "sha256:b121ff6a7cbd4abc28985b6028235491941b9fe8fe226e6fdc539c977ea1739d", size = 86591 }, - { url = "https://files.pythonhosted.org/packages/94/c3/b2e9f38bc3e11191981d57ea08cab2166e74ea770024a646617c9cddd9f6/yarl-1.20.1-cp313-cp313t-win_amd64.whl", hash = "sha256:541d050a355bbbc27e55d906bc91cb6fe42f96c01413dd0f4ed5a5240513874f", size = 93003 }, - { url = "https://files.pythonhosted.org/packages/b4/2d/2345fce04cfd4bee161bf1e7d9cdc702e3e16109021035dbb24db654a622/yarl-1.20.1-py3-none-any.whl", hash = "sha256:83b8eb083fe4683c6115795d9fc1cfaf2cbbefb19b3a1cb68f6527460f483a77", size = 46542 }, +sdist = { url = "https://files.pythonhosted.org/packages/3c/fb/efaa23fa4e45537b827620f04cf8f3cd658b76642205162e072703a5b963/yarl-1.20.1.tar.gz", hash = "sha256:d017a4997ee50c91fd5466cef416231bb82177b93b029906cefc542ce14c35ac", size = 186428, upload-time = "2025-06-10T00:46:09.923Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5f/9a/cb7fad7d73c69f296eda6815e4a2c7ed53fc70c2f136479a91c8e5fbdb6d/yarl-1.20.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bdcc4cd244e58593a4379fe60fdee5ac0331f8eb70320a24d591a3be197b94a9", size = 133667, upload-time = "2025-06-10T00:43:44.369Z" }, + { url = "https://files.pythonhosted.org/packages/67/38/688577a1cb1e656e3971fb66a3492501c5a5df56d99722e57c98249e5b8a/yarl-1.20.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b29a2c385a5f5b9c7d9347e5812b6f7ab267193c62d282a540b4fc528c8a9d2a", size = 91025, upload-time = "2025-06-10T00:43:46.295Z" }, + { url = "https://files.pythonhosted.org/packages/50/ec/72991ae51febeb11a42813fc259f0d4c8e0507f2b74b5514618d8b640365/yarl-1.20.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1112ae8154186dfe2de4732197f59c05a83dc814849a5ced892b708033f40dc2", size = 89709, upload-time = "2025-06-10T00:43:48.22Z" }, + { url = "https://files.pythonhosted.org/packages/99/da/4d798025490e89426e9f976702e5f9482005c548c579bdae792a4c37769e/yarl-1.20.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:90bbd29c4fe234233f7fa2b9b121fb63c321830e5d05b45153a2ca68f7d310ee", size = 352287, upload-time = "2025-06-10T00:43:49.924Z" }, + { url = "https://files.pythonhosted.org/packages/1a/26/54a15c6a567aac1c61b18aa0f4b8aa2e285a52d547d1be8bf48abe2b3991/yarl-1.20.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:680e19c7ce3710ac4cd964e90dad99bf9b5029372ba0c7cbfcd55e54d90ea819", size = 345429, upload-time = "2025-06-10T00:43:51.7Z" }, + { url = "https://files.pythonhosted.org/packages/d6/95/9dcf2386cb875b234353b93ec43e40219e14900e046bf6ac118f94b1e353/yarl-1.20.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4a979218c1fdb4246a05efc2cc23859d47c89af463a90b99b7c56094daf25a16", size = 365429, upload-time = "2025-06-10T00:43:53.494Z" }, + { url = "https://files.pythonhosted.org/packages/91/b2/33a8750f6a4bc224242a635f5f2cff6d6ad5ba651f6edcccf721992c21a0/yarl-1.20.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255b468adf57b4a7b65d8aad5b5138dce6a0752c139965711bdcb81bc370e1b6", size = 363862, upload-time = "2025-06-10T00:43:55.766Z" }, + { url = "https://files.pythonhosted.org/packages/98/28/3ab7acc5b51f4434b181b0cee8f1f4b77a65919700a355fb3617f9488874/yarl-1.20.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a97d67108e79cfe22e2b430d80d7571ae57d19f17cda8bb967057ca8a7bf5bfd", size = 355616, upload-time = "2025-06-10T00:43:58.056Z" }, + { url = "https://files.pythonhosted.org/packages/36/a3/f666894aa947a371724ec7cd2e5daa78ee8a777b21509b4252dd7bd15e29/yarl-1.20.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8570d998db4ddbfb9a590b185a0a33dbf8aafb831d07a5257b4ec9948df9cb0a", size = 339954, upload-time = "2025-06-10T00:43:59.773Z" }, + { url = "https://files.pythonhosted.org/packages/f1/81/5f466427e09773c04219d3450d7a1256138a010b6c9f0af2d48565e9ad13/yarl-1.20.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:97c75596019baae7c71ccf1d8cc4738bc08134060d0adfcbe5642f778d1dca38", size = 365575, upload-time = "2025-06-10T00:44:02.051Z" }, + { url = "https://files.pythonhosted.org/packages/2e/e3/e4b0ad8403e97e6c9972dd587388940a032f030ebec196ab81a3b8e94d31/yarl-1.20.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:1c48912653e63aef91ff988c5432832692ac5a1d8f0fb8a33091520b5bbe19ef", size = 365061, upload-time = "2025-06-10T00:44:04.196Z" }, + { url = "https://files.pythonhosted.org/packages/ac/99/b8a142e79eb86c926f9f06452eb13ecb1bb5713bd01dc0038faf5452e544/yarl-1.20.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4c3ae28f3ae1563c50f3d37f064ddb1511ecc1d5584e88c6b7c63cf7702a6d5f", size = 364142, upload-time = "2025-06-10T00:44:06.527Z" }, + { url = "https://files.pythonhosted.org/packages/34/f2/08ed34a4a506d82a1a3e5bab99ccd930a040f9b6449e9fd050320e45845c/yarl-1.20.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c5e9642f27036283550f5f57dc6156c51084b458570b9d0d96100c8bebb186a8", size = 381894, upload-time = "2025-06-10T00:44:08.379Z" }, + { url = "https://files.pythonhosted.org/packages/92/f8/9a3fbf0968eac704f681726eff595dce9b49c8a25cd92bf83df209668285/yarl-1.20.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:2c26b0c49220d5799f7b22c6838409ee9bc58ee5c95361a4d7831f03cc225b5a", size = 383378, upload-time = "2025-06-10T00:44:10.51Z" }, + { url = "https://files.pythonhosted.org/packages/af/85/9363f77bdfa1e4d690957cd39d192c4cacd1c58965df0470a4905253b54f/yarl-1.20.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:564ab3d517e3d01c408c67f2e5247aad4019dcf1969982aba3974b4093279004", size = 374069, upload-time = "2025-06-10T00:44:12.834Z" }, + { url = "https://files.pythonhosted.org/packages/35/99/9918c8739ba271dcd935400cff8b32e3cd319eaf02fcd023d5dcd487a7c8/yarl-1.20.1-cp312-cp312-win32.whl", hash = "sha256:daea0d313868da1cf2fac6b2d3a25c6e3a9e879483244be38c8e6a41f1d876a5", size = 81249, upload-time = "2025-06-10T00:44:14.731Z" }, + { url = "https://files.pythonhosted.org/packages/eb/83/5d9092950565481b413b31a23e75dd3418ff0a277d6e0abf3729d4d1ce25/yarl-1.20.1-cp312-cp312-win_amd64.whl", hash = "sha256:48ea7d7f9be0487339828a4de0360d7ce0efc06524a48e1810f945c45b813698", size = 86710, upload-time = "2025-06-10T00:44:16.716Z" }, + { url = "https://files.pythonhosted.org/packages/8a/e1/2411b6d7f769a07687acee88a062af5833cf1966b7266f3d8dfb3d3dc7d3/yarl-1.20.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:0b5ff0fbb7c9f1b1b5ab53330acbfc5247893069e7716840c8e7d5bb7355038a", size = 131811, upload-time = "2025-06-10T00:44:18.933Z" }, + { url = "https://files.pythonhosted.org/packages/b2/27/584394e1cb76fb771371770eccad35de400e7b434ce3142c2dd27392c968/yarl-1.20.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:14f326acd845c2b2e2eb38fb1346c94f7f3b01a4f5c788f8144f9b630bfff9a3", size = 90078, upload-time = "2025-06-10T00:44:20.635Z" }, + { url = "https://files.pythonhosted.org/packages/bf/9a/3246ae92d4049099f52d9b0fe3486e3b500e29b7ea872d0f152966fc209d/yarl-1.20.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f60e4ad5db23f0b96e49c018596707c3ae89f5d0bd97f0ad3684bcbad899f1e7", size = 88748, upload-time = "2025-06-10T00:44:22.34Z" }, + { url = "https://files.pythonhosted.org/packages/a3/25/35afe384e31115a1a801fbcf84012d7a066d89035befae7c5d4284df1e03/yarl-1.20.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:49bdd1b8e00ce57e68ba51916e4bb04461746e794e7c4d4bbc42ba2f18297691", size = 349595, upload-time = "2025-06-10T00:44:24.314Z" }, + { url = "https://files.pythonhosted.org/packages/28/2d/8aca6cb2cabc8f12efcb82749b9cefecbccfc7b0384e56cd71058ccee433/yarl-1.20.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:66252d780b45189975abfed839616e8fd2dbacbdc262105ad7742c6ae58f3e31", size = 342616, upload-time = "2025-06-10T00:44:26.167Z" }, + { url = "https://files.pythonhosted.org/packages/0b/e9/1312633d16b31acf0098d30440ca855e3492d66623dafb8e25b03d00c3da/yarl-1.20.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59174e7332f5d153d8f7452a102b103e2e74035ad085f404df2e40e663a22b28", size = 361324, upload-time = "2025-06-10T00:44:27.915Z" }, + { url = "https://files.pythonhosted.org/packages/bc/a0/688cc99463f12f7669eec7c8acc71ef56a1521b99eab7cd3abb75af887b0/yarl-1.20.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e3968ec7d92a0c0f9ac34d5ecfd03869ec0cab0697c91a45db3fbbd95fe1b653", size = 359676, upload-time = "2025-06-10T00:44:30.041Z" }, + { url = "https://files.pythonhosted.org/packages/af/44/46407d7f7a56e9a85a4c207724c9f2c545c060380718eea9088f222ba697/yarl-1.20.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1a4fbb50e14396ba3d375f68bfe02215d8e7bc3ec49da8341fe3157f59d2ff5", size = 352614, upload-time = "2025-06-10T00:44:32.171Z" }, + { url = "https://files.pythonhosted.org/packages/b1/91/31163295e82b8d5485d31d9cf7754d973d41915cadce070491778d9c9825/yarl-1.20.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11a62c839c3a8eac2410e951301309426f368388ff2f33799052787035793b02", size = 336766, upload-time = "2025-06-10T00:44:34.494Z" }, + { url = "https://files.pythonhosted.org/packages/b4/8e/c41a5bc482121f51c083c4c2bcd16b9e01e1cf8729e380273a952513a21f/yarl-1.20.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:041eaa14f73ff5a8986b4388ac6bb43a77f2ea09bf1913df7a35d4646db69e53", size = 364615, upload-time = "2025-06-10T00:44:36.856Z" }, + { url = "https://files.pythonhosted.org/packages/e3/5b/61a3b054238d33d70ea06ebba7e58597891b71c699e247df35cc984ab393/yarl-1.20.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:377fae2fef158e8fd9d60b4c8751387b8d1fb121d3d0b8e9b0be07d1b41e83dc", size = 360982, upload-time = "2025-06-10T00:44:39.141Z" }, + { url = "https://files.pythonhosted.org/packages/df/a3/6a72fb83f8d478cb201d14927bc8040af901811a88e0ff2da7842dd0ed19/yarl-1.20.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1c92f4390e407513f619d49319023664643d3339bd5e5a56a3bebe01bc67ec04", size = 369792, upload-time = "2025-06-10T00:44:40.934Z" }, + { url = "https://files.pythonhosted.org/packages/7c/af/4cc3c36dfc7c077f8dedb561eb21f69e1e9f2456b91b593882b0b18c19dc/yarl-1.20.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:d25ddcf954df1754ab0f86bb696af765c5bfaba39b74095f27eececa049ef9a4", size = 382049, upload-time = "2025-06-10T00:44:42.854Z" }, + { url = "https://files.pythonhosted.org/packages/19/3a/e54e2c4752160115183a66dc9ee75a153f81f3ab2ba4bf79c3c53b33de34/yarl-1.20.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:909313577e9619dcff8c31a0ea2aa0a2a828341d92673015456b3ae492e7317b", size = 384774, upload-time = "2025-06-10T00:44:45.275Z" }, + { url = "https://files.pythonhosted.org/packages/9c/20/200ae86dabfca89060ec6447649f219b4cbd94531e425e50d57e5f5ac330/yarl-1.20.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:793fd0580cb9664548c6b83c63b43c477212c0260891ddf86809e1c06c8b08f1", size = 374252, upload-time = "2025-06-10T00:44:47.31Z" }, + { url = "https://files.pythonhosted.org/packages/83/75/11ee332f2f516b3d094e89448da73d557687f7d137d5a0f48c40ff211487/yarl-1.20.1-cp313-cp313-win32.whl", hash = "sha256:468f6e40285de5a5b3c44981ca3a319a4b208ccc07d526b20b12aeedcfa654b7", size = 81198, upload-time = "2025-06-10T00:44:49.164Z" }, + { url = "https://files.pythonhosted.org/packages/ba/ba/39b1ecbf51620b40ab402b0fc817f0ff750f6d92712b44689c2c215be89d/yarl-1.20.1-cp313-cp313-win_amd64.whl", hash = "sha256:495b4ef2fea40596bfc0affe3837411d6aa3371abcf31aac0ccc4bdd64d4ef5c", size = 86346, upload-time = "2025-06-10T00:44:51.182Z" }, + { url = "https://files.pythonhosted.org/packages/43/c7/669c52519dca4c95153c8ad96dd123c79f354a376346b198f438e56ffeb4/yarl-1.20.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:f60233b98423aab21d249a30eb27c389c14929f47be8430efa7dbd91493a729d", size = 138826, upload-time = "2025-06-10T00:44:52.883Z" }, + { url = "https://files.pythonhosted.org/packages/6a/42/fc0053719b44f6ad04a75d7f05e0e9674d45ef62f2d9ad2c1163e5c05827/yarl-1.20.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:6f3eff4cc3f03d650d8755c6eefc844edde99d641d0dcf4da3ab27141a5f8ddf", size = 93217, upload-time = "2025-06-10T00:44:54.658Z" }, + { url = "https://files.pythonhosted.org/packages/4f/7f/fa59c4c27e2a076bba0d959386e26eba77eb52ea4a0aac48e3515c186b4c/yarl-1.20.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:69ff8439d8ba832d6bed88af2c2b3445977eba9a4588b787b32945871c2444e3", size = 92700, upload-time = "2025-06-10T00:44:56.784Z" }, + { url = "https://files.pythonhosted.org/packages/2f/d4/062b2f48e7c93481e88eff97a6312dca15ea200e959f23e96d8ab898c5b8/yarl-1.20.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cf34efa60eb81dd2645a2e13e00bb98b76c35ab5061a3989c7a70f78c85006d", size = 347644, upload-time = "2025-06-10T00:44:59.071Z" }, + { url = "https://files.pythonhosted.org/packages/89/47/78b7f40d13c8f62b499cc702fdf69e090455518ae544c00a3bf4afc9fc77/yarl-1.20.1-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:8e0fe9364ad0fddab2688ce72cb7a8e61ea42eff3c7caeeb83874a5d479c896c", size = 323452, upload-time = "2025-06-10T00:45:01.605Z" }, + { url = "https://files.pythonhosted.org/packages/eb/2b/490d3b2dc66f52987d4ee0d3090a147ea67732ce6b4d61e362c1846d0d32/yarl-1.20.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8f64fbf81878ba914562c672024089e3401974a39767747691c65080a67b18c1", size = 346378, upload-time = "2025-06-10T00:45:03.946Z" }, + { url = "https://files.pythonhosted.org/packages/66/ad/775da9c8a94ce925d1537f939a4f17d782efef1f973039d821cbe4bcc211/yarl-1.20.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f6342d643bf9a1de97e512e45e4b9560a043347e779a173250824f8b254bd5ce", size = 353261, upload-time = "2025-06-10T00:45:05.992Z" }, + { url = "https://files.pythonhosted.org/packages/4b/23/0ed0922b47a4f5c6eb9065d5ff1e459747226ddce5c6a4c111e728c9f701/yarl-1.20.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56dac5f452ed25eef0f6e3c6a066c6ab68971d96a9fb441791cad0efba6140d3", size = 335987, upload-time = "2025-06-10T00:45:08.227Z" }, + { url = "https://files.pythonhosted.org/packages/3e/49/bc728a7fe7d0e9336e2b78f0958a2d6b288ba89f25a1762407a222bf53c3/yarl-1.20.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7d7f497126d65e2cad8dc5f97d34c27b19199b6414a40cb36b52f41b79014be", size = 329361, upload-time = "2025-06-10T00:45:10.11Z" }, + { url = "https://files.pythonhosted.org/packages/93/8f/b811b9d1f617c83c907e7082a76e2b92b655400e61730cd61a1f67178393/yarl-1.20.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:67e708dfb8e78d8a19169818eeb5c7a80717562de9051bf2413aca8e3696bf16", size = 346460, upload-time = "2025-06-10T00:45:12.055Z" }, + { url = "https://files.pythonhosted.org/packages/70/fd/af94f04f275f95da2c3b8b5e1d49e3e79f1ed8b6ceb0f1664cbd902773ff/yarl-1.20.1-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:595c07bc79af2494365cc96ddeb772f76272364ef7c80fb892ef9d0649586513", size = 334486, upload-time = "2025-06-10T00:45:13.995Z" }, + { url = "https://files.pythonhosted.org/packages/84/65/04c62e82704e7dd0a9b3f61dbaa8447f8507655fd16c51da0637b39b2910/yarl-1.20.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:7bdd2f80f4a7df852ab9ab49484a4dee8030023aa536df41f2d922fd57bf023f", size = 342219, upload-time = "2025-06-10T00:45:16.479Z" }, + { url = "https://files.pythonhosted.org/packages/91/95/459ca62eb958381b342d94ab9a4b6aec1ddec1f7057c487e926f03c06d30/yarl-1.20.1-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:c03bfebc4ae8d862f853a9757199677ab74ec25424d0ebd68a0027e9c639a390", size = 350693, upload-time = "2025-06-10T00:45:18.399Z" }, + { url = "https://files.pythonhosted.org/packages/a6/00/d393e82dd955ad20617abc546a8f1aee40534d599ff555ea053d0ec9bf03/yarl-1.20.1-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:344d1103e9c1523f32a5ed704d576172d2cabed3122ea90b1d4e11fe17c66458", size = 355803, upload-time = "2025-06-10T00:45:20.677Z" }, + { url = "https://files.pythonhosted.org/packages/9e/ed/c5fb04869b99b717985e244fd93029c7a8e8febdfcffa06093e32d7d44e7/yarl-1.20.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:88cab98aa4e13e1ade8c141daeedd300a4603b7132819c484841bb7af3edce9e", size = 341709, upload-time = "2025-06-10T00:45:23.221Z" }, + { url = "https://files.pythonhosted.org/packages/24/fd/725b8e73ac2a50e78a4534ac43c6addf5c1c2d65380dd48a9169cc6739a9/yarl-1.20.1-cp313-cp313t-win32.whl", hash = "sha256:b121ff6a7cbd4abc28985b6028235491941b9fe8fe226e6fdc539c977ea1739d", size = 86591, upload-time = "2025-06-10T00:45:25.793Z" }, + { url = "https://files.pythonhosted.org/packages/94/c3/b2e9f38bc3e11191981d57ea08cab2166e74ea770024a646617c9cddd9f6/yarl-1.20.1-cp313-cp313t-win_amd64.whl", hash = "sha256:541d050a355bbbc27e55d906bc91cb6fe42f96c01413dd0f4ed5a5240513874f", size = 93003, upload-time = "2025-06-10T00:45:27.752Z" }, + { url = "https://files.pythonhosted.org/packages/b4/2d/2345fce04cfd4bee161bf1e7d9cdc702e3e16109021035dbb24db654a622/yarl-1.20.1-py3-none-any.whl", hash = "sha256:83b8eb083fe4683c6115795d9fc1cfaf2cbbefb19b3a1cb68f6527460f483a77", size = 46542, upload-time = "2025-06-10T00:46:07.521Z" }, ] [[package]] @@ -1321,7 +1321,7 @@ dev = [ ] [package.metadata] -requires-dist = [{ name = "zigpy", specifier = ">=0.85.0" }] +requires-dist = [{ name = "zigpy", specifier = ">=0.86.0" }] [package.metadata.requires-dev] ci = [ @@ -1347,7 +1347,7 @@ dev = [ [[package]] name = "zigpy" -version = "0.85.0" +version = "0.86.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "aiohttp" }, @@ -1357,11 +1357,11 @@ dependencies = [ { name = "cryptography" }, { name = "frozendict" }, { name = "jsonschema" }, - { name = "pyserial-asyncio" }, + { name = "pyserial-asyncio-fast" }, { name = "typing-extensions" }, { name = "voluptuous" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/cf/33/078717e92a79b74864b3f98d5fea0814166a7c7789c33be0ad562a0ccc62/zigpy-0.85.0.tar.gz", hash = "sha256:8c4a1dec729e3a76be184e7b88af9dce87ef802ccf0a2e5d81ee2800c8eae449", size = 305253 } +sdist = { url = "https://files.pythonhosted.org/packages/36/73/654c29dfa4eeaa4a3c62eb008b5fbe03463f6f41b33b2a0fb85da6bd600b/zigpy-0.86.0.tar.gz", hash = "sha256:fbb4d04d872f9e6934096d30da99f18a92aeb0a71a5332ad11fa7370c6772fd4", size = 305640, upload-time = "2025-10-27T20:55:30.871Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/82/39/6a54d9877663def2138524446a5b16b133fd26f40c526fa69dcbdc2d944f/zigpy-0.85.0-py3-none-any.whl", hash = "sha256:8980ec3c9c7f4511f829dff79d6626f3a45b5cf5e3659561d454b3701fb5f755", size = 235920 }, + { url = "https://files.pythonhosted.org/packages/55/8d/dd0c1f2b9669b565a91cd0a44867e2c83b04d505e344b584784be5819088/zigpy-0.86.0-py3-none-any.whl", hash = "sha256:5d5634b3d014896d4a9ceda59bf7e8072d7be2014195929eee1fa5b92d5da259", size = 235873, upload-time = "2025-10-27T20:55:29.299Z" }, ] diff --git a/zhaquirks/adeo/color_controller.py b/zhaquirks/adeo/color_controller.py index ca83310a4f..0fa0cd9ea1 100644 --- a/zhaquirks/adeo/color_controller.py +++ b/zhaquirks/adeo/color_controller.py @@ -2,23 +2,10 @@ from typing import Any, Optional, Union -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice +from zigpy.quirks.v2 import CustomDeviceV2, QuirkBuilder import zigpy.types as t -from zigpy.zcl import foundation -from zigpy.zcl.clusters.general import ( - Basic, - Groups, - Identify, - LevelControl, - OnOff, - Ota, - PowerConfiguration, - Scenes, -) -from zigpy.zcl.clusters.homeautomation import Diagnostic -from zigpy.zcl.clusters.lighting import Color -from zigpy.zcl.clusters.lightlink import LightLink +from zigpy.zcl import ClusterType, foundation +from zigpy.zcl.clusters.general import Scenes from zigpy.zcl.foundation import BaseCommandDefs from zhaquirks import Bus, EventableCluster @@ -36,16 +23,10 @@ COMMAND_STEP_COLOR_TEMP, COMMAND_STEP_HUE, COMMAND_STEP_SATURATION, - DEVICE_TYPE, DIM_DOWN, DIM_UP, ENDPOINT_ID, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, PARAMS, - PROFILE_ID, SHORT_PRESS, TURN_OFF, TURN_ON, @@ -106,7 +87,7 @@ def __init__(self, *args, **kwargs): self.endpoint.device.scenes_bus.add_listener(self) -class AdeoColorController(CustomDevice): +class AdeoColorController(CustomDeviceV2): """Custom device representing ADEO color controller.""" def __init__(self, *args, **kwargs): @@ -114,160 +95,112 @@ def __init__(self, *args, **kwargs): self.scenes_bus = Bus() super().__init__(*args, **kwargs) - signature = { - # - MODELS_INFO: [("ADEO", "LXEK-5"), ("ADEO", "ZBEK-26")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, # 260 - DEVICE_TYPE: zha.DeviceType.COLOR_CONTROLLER, # 2048 - INPUT_CLUSTERS: [ - Basic.cluster_id, # 0 - PowerConfiguration.cluster_id, # 1 - Identify.cluster_id, # 3 - Diagnostic.cluster_id, # 2821 - LightLink.cluster_id, # 4096 - 0xFD01, # 64769 - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, # 3 - Groups.cluster_id, # 4 - OnOff.cluster_id, # 6 - LevelControl.cluster_id, # 8 - Ota.cluster_id, # 25 - Color.cluster_id, # 768 - LightLink.cluster_id, # 4096 - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.COLOR_CONTROLLER, - INPUT_CLUSTERS: [ - Basic.cluster_id, # 0 - PowerConfiguration.cluster_id, # 1 - Identify.cluster_id, # 3 - Diagnostic.cluster_id, # 2821 - LightLink.cluster_id, # 4096 - 0xFD01, # 64769 - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, # 3 - Groups.cluster_id, # 4 - AdeoScenesCluster, # 5 - OnOff.cluster_id, # 6 - LevelControl.cluster_id, # 8 - Ota.cluster_id, # 25 - Color.cluster_id, # 768 - LightLink.cluster_id, # 4096 - AdeoManufacturerCluster, # 65024 - ], - } - }, - } - device_automation_triggers = { - (SHORT_PRESS, TURN_ON): { - COMMAND: COMMAND_ON, - CLUSTER_ID: 6, # OnOff.cluster_id - ENDPOINT_ID: 1, - ARGS: [], - }, - (SHORT_PRESS, TURN_OFF): { - COMMAND: COMMAND_OFF, - CLUSTER_ID: 6, # OnOff.cluster_id - ENDPOINT_ID: 1, - ARGS: [], - }, - (SHORT_PRESS, DIM_UP): { - COMMAND: COMMAND_STEP, - CLUSTER_ID: 8, # LevelControl.cluster_id - ENDPOINT_ID: 1, - PARAMS: {"step_mode": 0}, - }, - (SHORT_PRESS, DIM_DOWN): { - COMMAND: COMMAND_STEP, - CLUSTER_ID: 8, # LevelControl.cluster_id - ENDPOINT_ID: 1, - PARAMS: {"step_mode": 1}, - }, - (SHORT_PRESS, COLOR_UP): { - COMMAND: COMMAND_STEP_COLOR_TEMP, - CLUSTER_ID: 768, # Color.cluster_id - ENDPOINT_ID: 1, - PARAMS: { - "step_mode": 3, - "step_size": 22, - "transition_time": 5, - "color_temp_min_mireds": 153, - "color_temp_max_mireds": 370, +( + QuirkBuilder("ADEO", "LXEK-5") + .applies_to("ADEO", "ZBEK-26") + .device_class(AdeoColorController) + .replaces(AdeoScenesCluster, cluster_type=ClusterType.Client, endpoint_id=1) + .adds(AdeoManufacturerCluster, cluster_type=ClusterType.Client, endpoint_id=1) + .device_automation_triggers( + { + (SHORT_PRESS, TURN_ON): { + COMMAND: COMMAND_ON, + CLUSTER_ID: 6, # OnOff.cluster_id + ENDPOINT_ID: 1, + ARGS: [], + }, + (SHORT_PRESS, TURN_OFF): { + COMMAND: COMMAND_OFF, + CLUSTER_ID: 6, # OnOff.cluster_id + ENDPOINT_ID: 1, + ARGS: [], + }, + (SHORT_PRESS, DIM_UP): { + COMMAND: COMMAND_STEP, + CLUSTER_ID: 8, # LevelControl.cluster_id + ENDPOINT_ID: 1, + PARAMS: {"step_mode": 0}, + }, + (SHORT_PRESS, DIM_DOWN): { + COMMAND: COMMAND_STEP, + CLUSTER_ID: 8, # LevelControl.cluster_id + ENDPOINT_ID: 1, + PARAMS: {"step_mode": 1}, + }, + (SHORT_PRESS, COLOR_UP): { + COMMAND: COMMAND_STEP_COLOR_TEMP, + CLUSTER_ID: 768, # Color.cluster_id + ENDPOINT_ID: 1, + PARAMS: { + "step_mode": 3, + "step_size": 22, + "transition_time": 5, + "color_temp_min_mireds": 153, + "color_temp_max_mireds": 370, + }, + }, + (SHORT_PRESS, COLOR_DOWN): { + COMMAND: COMMAND_STEP_COLOR_TEMP, + CLUSTER_ID: 768, # Color.cluster_id + ENDPOINT_ID: 1, + PARAMS: { + "step_mode": 1, + "step_size": 22, + "transition_time": 5, + "color_temp_min_mireds": 153, + "color_temp_max_mireds": 370, + }, + }, + (SHORT_PRESS, SATURATION_UP): { + COMMAND: COMMAND_STEP_SATURATION, + CLUSTER_ID: 768, # Color.cluster_id + ENDPOINT_ID: 1, + PARAMS: {"step_mode": 1}, }, - }, - (SHORT_PRESS, COLOR_DOWN): { - COMMAND: COMMAND_STEP_COLOR_TEMP, - CLUSTER_ID: 768, # Color.cluster_id - ENDPOINT_ID: 1, - PARAMS: { - "step_mode": 1, - "step_size": 22, - "transition_time": 5, - "color_temp_min_mireds": 153, - "color_temp_max_mireds": 370, + (SHORT_PRESS, SATURATION_DOWN): { + COMMAND: COMMAND_STEP_SATURATION, + CLUSTER_ID: 768, # Color.cluster_id + ENDPOINT_ID: 1, + PARAMS: {"step_mode": 3}, }, - }, - (SHORT_PRESS, SATURATION_UP): { - COMMAND: COMMAND_STEP_SATURATION, - CLUSTER_ID: 768, # Color.cluster_id - ENDPOINT_ID: 1, - PARAMS: {"step_mode": 1}, - }, - (SHORT_PRESS, SATURATION_DOWN): { - COMMAND: COMMAND_STEP_SATURATION, - CLUSTER_ID: 768, # Color.cluster_id - ENDPOINT_ID: 1, - PARAMS: {"step_mode": 3}, - }, - (SHORT_PRESS, HUE_LEFT): { - COMMAND: COMMAND_STEP_HUE, - CLUSTER_ID: 768, # Color.cluster_id - ENDPOINT_ID: 1, - PARAMS: {"step_mode": 3}, - }, - (SHORT_PRESS, HUE_RIGHT): { - COMMAND: COMMAND_STEP_HUE, - CLUSTER_ID: 768, # Color.cluster_id - ENDPOINT_ID: 1, - PARAMS: {"step_mode": 1}, - }, - (SHORT_PRESS, BUTTON_1): { - COMMAND: "view", - CLUSTER_ID: 5, # Scenes.cluster_id - ENDPOINT_ID: 1, - ARGS: [0, 0xA], - }, - (SHORT_PRESS, BUTTON_2): { - COMMAND: "view", - CLUSTER_ID: 5, # Scenes.cluster_id - ENDPOINT_ID: 1, - ARGS: [0, 0xB], - }, - (SHORT_PRESS, BUTTON_3): { - COMMAND: "view", - CLUSTER_ID: 5, # Scenes.cluster_id - ENDPOINT_ID: 1, - ARGS: [0, 0xC], - }, - (SHORT_PRESS, BUTTON_4): { - COMMAND: "view", - CLUSTER_ID: 5, # Scenes.cluster_id - ENDPOINT_ID: 1, - ARGS: [0, 0xD], - }, - } + (SHORT_PRESS, HUE_LEFT): { + COMMAND: COMMAND_STEP_HUE, + CLUSTER_ID: 768, # Color.cluster_id + ENDPOINT_ID: 1, + PARAMS: {"step_mode": 3}, + }, + (SHORT_PRESS, HUE_RIGHT): { + COMMAND: COMMAND_STEP_HUE, + CLUSTER_ID: 768, # Color.cluster_id + ENDPOINT_ID: 1, + PARAMS: {"step_mode": 1}, + }, + (SHORT_PRESS, BUTTON_1): { + COMMAND: "view", + CLUSTER_ID: 5, # Scenes.cluster_id + ENDPOINT_ID: 1, + ARGS: [0, 0xA], + }, + (SHORT_PRESS, BUTTON_2): { + COMMAND: "view", + CLUSTER_ID: 5, # Scenes.cluster_id + ENDPOINT_ID: 1, + ARGS: [0, 0xB], + }, + (SHORT_PRESS, BUTTON_3): { + COMMAND: "view", + CLUSTER_ID: 5, # Scenes.cluster_id + ENDPOINT_ID: 1, + ARGS: [0, 0xC], + }, + (SHORT_PRESS, BUTTON_4): { + COMMAND: "view", + CLUSTER_ID: 5, # Scenes.cluster_id + ENDPOINT_ID: 1, + ARGS: [0, 0xD], + }, + } + ) + .add_to_registry() +) diff --git a/zhaquirks/aduro/adurolightncc.py b/zhaquirks/aduro/adurolightncc.py index 14bb50de6b..0737918c42 100644 --- a/zhaquirks/aduro/adurolightncc.py +++ b/zhaquirks/aduro/adurolightncc.py @@ -1,10 +1,7 @@ """ADUROLIGHT Adurolight_NCC device.""" -from zigpy.profiles import zha -from zigpy.profiles.zha import DeviceType -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import Basic, Groups, Identify, LevelControl, OnOff -from zigpy.zcl.clusters.lightlink import LightLink +from zigpy.quirks.v2 import QuirkBuilder +from zigpy.zcl.clusters.general import LevelControl from zhaquirks.const import ( CLUSTER_ID, @@ -12,16 +9,10 @@ COMMAND_OFF, COMMAND_ON, COMMAND_STEP, - DEVICE_TYPE, DIM_DOWN, DIM_UP, ENDPOINT_ID, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, PARAMS, - PROFILE_ID, SHORT_PRESS, TURN_OFF, TURN_ON, @@ -30,74 +21,34 @@ ADUROLIGHT_CLUSTER_ID = 64716 -class AdurolightNCC(CustomDevice): - """ADUROLIGHT Adurolight_NCC device.""" - - signature = { - # - MODELS_INFO: [("ADUROLIGHT", "Adurolight_NCC")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: DeviceType.NON_COLOR_CONTROLLER, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - LevelControl.cluster_id, - LightLink.cluster_id, - ADUROLIGHT_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - LightLink.cluster_id, - ADUROLIGHT_CLUSTER_ID, - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: DeviceType.NON_COLOR_CONTROLLER, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - LightLink.cluster_id, - ADUROLIGHT_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - LightLink.cluster_id, - ADUROLIGHT_CLUSTER_ID, - ], - } +( + QuirkBuilder("ADUROLIGHT", "Adurolight_NCC") + .removes(LevelControl, endpoint_id=1) + .device_automation_triggers( + { + (SHORT_PRESS, TURN_ON): { + COMMAND: COMMAND_ON, + CLUSTER_ID: 6, + ENDPOINT_ID: 1, + }, + (SHORT_PRESS, TURN_OFF): { + COMMAND: COMMAND_OFF, + CLUSTER_ID: 6, + ENDPOINT_ID: 1, + }, + (SHORT_PRESS, DIM_UP): { + COMMAND: COMMAND_STEP, + CLUSTER_ID: 8, + ENDPOINT_ID: 1, + PARAMS: {"step_mode": 0}, + }, + (SHORT_PRESS, DIM_DOWN): { + COMMAND: COMMAND_STEP, + CLUSTER_ID: 8, + ENDPOINT_ID: 1, + PARAMS: {"step_mode": 1}, + }, } - } - - device_automation_triggers = { - (SHORT_PRESS, TURN_ON): {COMMAND: COMMAND_ON, CLUSTER_ID: 6, ENDPOINT_ID: 1}, - (SHORT_PRESS, TURN_OFF): {COMMAND: COMMAND_OFF, CLUSTER_ID: 6, ENDPOINT_ID: 1}, - (SHORT_PRESS, DIM_UP): { - COMMAND: COMMAND_STEP, - CLUSTER_ID: 8, - ENDPOINT_ID: 1, - PARAMS: {"step_mode": 0}, - }, - (SHORT_PRESS, DIM_DOWN): { - COMMAND: COMMAND_STEP, - CLUSTER_ID: 8, - ENDPOINT_ID: 1, - PARAMS: {"step_mode": 1}, - }, - } + ) + .add_to_registry() +) diff --git a/zhaquirks/aurora/aurora_dimmer.py b/zhaquirks/aurora/aurora_dimmer.py index 14bfbe58ee..582cfa607f 100644 --- a/zhaquirks/aurora/aurora_dimmer.py +++ b/zhaquirks/aurora/aurora_dimmer.py @@ -1,15 +1,7 @@ """Device handler for Aurora dimmer switch, battery powered.""" -from zigpy.profiles import zgp, zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - GreenPowerProxy, - Identify, - LevelControl, - OnOff, - Ota, -) +from zigpy.quirks.v2 import QuirkBuilder +from zigpy.zcl.clusters.general import LevelControl, OnOff from zigpy.zcl.clusters.lighting import Color from zhaquirks import EventableCluster, PowerConfigurationCluster @@ -19,17 +11,11 @@ COMMAND, COMMAND_STEP, COMMAND_STEP_COLOR_TEMP, - DEVICE_TYPE, DIM_DOWN, DIM_UP, ENDPOINT_ID, - ENDPOINTS, - INPUT_CLUSTERS, LEFT, - MODELS_INFO, - OUTPUT_CLUSTERS, PARAMS, - PROFILE_ID, RIGHT, SHORT_PRESS, ) @@ -39,198 +25,104 @@ CURRENT_LEVEL = "current_level" -class AuroraDimmerBatteryPowered(CustomDevice): - """Aurora dimmer switch, battery powered.""" +class WallSwitchOnOffCluster(EventableCluster, OnOff): + """WallSwitchOnOffCluster: fire events corresponding to press type.""" + + # prevent creation of junk entities + ep_attribute = "not_on_off" + + # as the device is battery powered, whether or not it thinks it is + # on or off is irrelevant + def _update_attribute(self, attrid, value): + return - class WallSwitchOnOffCluster(EventableCluster, OnOff): - """WallSwitchOnOffCluster: fire events corresponding to press type.""" - # prevent creation of junk entities - ep_attribute = "not_on_off" +class WallSwitchLevelControlCluster(EventableCluster, LevelControl): + """WallSwitchLevelControlCluster: fire events corresponding to level changes.""" - # as the device is battery powered, whether or not it thinks it is - # on or off is irrelevant - def _update_attribute(self, attrid, value): + # the value reported by the device is always 254, so we may as well + # throw away this report + def _update_attribute(self, attrid, value): + if attrid == CURRENT_LEVEL: return + else: + super()._update_attribute(attrid, value) - class WallSwitchLevelControlCluster(EventableCluster, LevelControl): - """WallSwitchLevelControlCluster: fire events corresponding to level changes.""" - # the value reported by the device is always 254, so we may as well - # throw away this report - def _update_attribute(self, attrid, value): - if attrid == CURRENT_LEVEL: - return - else: - super()._update_attribute(attrid, value) +class WallSwitchColorCluster(EventableCluster, Color): + """WallSwitchColorCluster: fire events corresponding to color changes.""" - class WallSwitchColorCluster(EventableCluster, Color): - """WallSwitchColorCluster: fire events corresponding to color changes.""" - signature = { - # - MODELS_INFO: [("Aurora", "2GBatteryDimmer50AU")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.COLOR_DIMMER_SWITCH, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfigurationCluster.cluster_id, - Identify.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Color.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - Color.cluster_id, - ], +( + QuirkBuilder("Aurora", "2GBatteryDimmer50AU") + .replaces(PowerConfigurationCluster, endpoint_id=1) + .replaces(WallSwitchOnOffCluster, endpoint_id=1) + .replaces(WallSwitchLevelControlCluster, endpoint_id=1) + .replaces(WallSwitchColorCluster, endpoint_id=1) + .replaces(WallSwitchOnOffCluster, endpoint_id=2) + .replaces(WallSwitchLevelControlCluster, endpoint_id=2) + .replaces(WallSwitchColorCluster, endpoint_id=2) + .device_automation_triggers( + { + (DIM_UP, RIGHT): { + COMMAND: COMMAND_STEP, + CLUSTER_ID: 8, + ENDPOINT_ID: 1, + PARAMS: {"step_mode": 0}, }, - # - 2: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.COLOR_DIMMER_SWITCH, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Color.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Color.cluster_id, - ], + (DIM_DOWN, RIGHT): { + COMMAND: COMMAND_STEP, + CLUSTER_ID: 8, + ENDPOINT_ID: 1, + PARAMS: {"step_mode": 1}, }, - # - MODELS_INFO: [(BOSCH, "ISW-ZDL1-WP11G")], - ENDPOINTS: { - 5: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfigurationCluster.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - IasZone.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - }, - } - - replacement = { - ENDPOINTS: { - 5: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - BoschWP11GPowerConfiguration, - Identify.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - IasZone.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - } - } +( + QuirkBuilder(BOSCH, "ISW-ZDL1-WP11G") + .replaces(BoschWP11GPowerConfiguration, endpoint_id=5) + .add_to_registry() +) diff --git a/zhaquirks/bosch/motion.py b/zhaquirks/bosch/motion.py index a9abc0f6d1..e0be9e16b9 100755 --- a/zhaquirks/bosch/motion.py +++ b/zhaquirks/bosch/motion.py @@ -1,22 +1,9 @@ """Device handler for Bosch motion sensors.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import Basic, Identify, Ota, PollControl -from zigpy.zcl.clusters.homeautomation import Diagnostic -from zigpy.zcl.clusters.measurement import TemperatureMeasurement -from zigpy.zcl.clusters.security import IasZone +from zigpy.quirks.v2 import QuirkBuilder from zhaquirks import PowerConfigurationCluster from zhaquirks.bosch import BOSCH -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) class BoschPowerConfiguration(PowerConfigurationCluster): @@ -26,46 +13,8 @@ class BoschPowerConfiguration(PowerConfigurationCluster): MIN_VOLTS = 1.9 -class ISWZPR1WP13(CustomDevice): - """Custom device representing Bosch motion sensors.""" - - signature = { - # - MODELS_INFO: [(BOSCH, "ISW-ZPR1-WP13")], - ENDPOINTS: { - 5: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfigurationCluster.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - IasZone.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - }, - } - - replacement = { - ENDPOINTS: { - 5: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - BoschPowerConfiguration, - Identify.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - IasZone.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - } - } +( + QuirkBuilder(BOSCH, "ISW-ZPR1-WP13") + .replaces(BoschPowerConfiguration, endpoint_id=5) + .add_to_registry() +) diff --git a/zhaquirks/centralite/cl_3130.py b/zhaquirks/centralite/cl_3130.py index 28f3118a0c..c4e0823e97 100755 --- a/zhaquirks/centralite/cl_3130.py +++ b/zhaquirks/centralite/cl_3130.py @@ -1,16 +1,6 @@ """Device handler for centralite 3130.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - Identify, - LevelControl, - OnOff, - Ota, - PollControl, -) -from zigpy.zcl.clusters.homeautomation import Diagnostic +from zigpy.quirks.v2 import QuirkBuilder from zigpy.zcl.clusters.measurement import TemperatureMeasurement from zhaquirks import PowerConfigurationCluster @@ -21,14 +11,8 @@ COMMAND_MOVE_ON_OFF, COMMAND_OFF, COMMAND_ON, - DEVICE_TYPE, DIM_DOWN, DIM_UP, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, SHORT_PRESS, TURN_OFF, TURN_ON, @@ -43,59 +27,18 @@ class CustomPowerConfigurationCluster(PowerConfigurationCluster): MAX_VOLTS = 3.0 -class CentraLite3130(CustomDevice): - """Custom device representing centralite 3130.""" - - signature = { - # - MODELS_INFO: [(OSRAM, "LIGHTIFY Dimming Switch"), (CENTRALITE, "3130")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.LEVEL_CONTROL_SWITCH, - INPUT_CLUSTERS: [ - Basic.cluster_id, - CustomPowerConfigurationCluster.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - ], - } - }, - } - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - CustomPowerConfigurationCluster, - Identify.cluster_id, - PollControl.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - ], - } +( + QuirkBuilder(OSRAM, "LIGHTIFY Dimming Switch") + .applies_to(CENTRALITE, "3130") + .removes(TemperatureMeasurement.cluster_id, endpoint_id=1) + .replaces(CustomPowerConfigurationCluster, endpoint_id=1) + .device_automation_triggers( + { + (SHORT_PRESS, TURN_ON): {COMMAND: COMMAND_ON}, + (SHORT_PRESS, TURN_OFF): {COMMAND: COMMAND_OFF}, + (SHORT_PRESS, DIM_UP): {COMMAND: COMMAND_MOVE_ON_OFF}, + (SHORT_PRESS, DIM_DOWN): {COMMAND: COMMAND_MOVE}, } - } - - device_automation_triggers = { - (SHORT_PRESS, TURN_ON): {COMMAND: COMMAND_ON}, - (SHORT_PRESS, TURN_OFF): {COMMAND: COMMAND_OFF}, - (SHORT_PRESS, DIM_UP): {COMMAND: COMMAND_MOVE_ON_OFF}, - (SHORT_PRESS, DIM_DOWN): {COMMAND: COMMAND_MOVE}, - } + ) + .add_to_registry() +) diff --git a/zhaquirks/centralite/cl_3157100.py b/zhaquirks/centralite/cl_3157100.py index bfc51bd8bb..9c0a6d51e9 100755 --- a/zhaquirks/centralite/cl_3157100.py +++ b/zhaquirks/centralite/cl_3157100.py @@ -1,67 +1,13 @@ """Device handler for centralite 3157100.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import Basic, Identify, Ota, PollControl, Time -from zigpy.zcl.clusters.homeautomation import Diagnostic -from zigpy.zcl.clusters.hvac import Fan, Thermostat, UserInterface +from zigpy.quirks.v2 import QuirkBuilder from zhaquirks import PowerConfigurationCluster from zhaquirks.centralite import CENTRALITE -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) - - -class CentraLite3157100(CustomDevice): - """Custom device representing centralite 3157100.""" - signature = { - # - MODELS_INFO: [(CENTRALITE, "3157100"), ("Centralite", "3157100")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.THERMOSTAT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfigurationCluster.cluster_id, - Identify.cluster_id, - Thermostat.cluster_id, - Fan.cluster_id, - UserInterface.cluster_id, - PollControl.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.THERMOSTAT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfigurationCluster, - Identify.cluster_id, - Thermostat.cluster_id, - Fan.cluster_id, - UserInterface.cluster_id, - PollControl.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id], - } - } - } +( + QuirkBuilder(CENTRALITE, "3157100") + .applies_to("Centralite", "3157100") + .replaces(PowerConfigurationCluster, endpoint_id=1) + .add_to_registry() +) diff --git a/zhaquirks/centralite/cl_3300S.py b/zhaquirks/centralite/cl_3300S.py index bc7102633d..df3290b418 100755 --- a/zhaquirks/centralite/cl_3300S.py +++ b/zhaquirks/centralite/cl_3300S.py @@ -1,94 +1,19 @@ """Device handler for centralite 3300.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import Basic, BinaryInput, Identify, Ota, PollControl -from zigpy.zcl.clusters.homeautomation import Diagnostic -from zigpy.zcl.clusters.measurement import TemperatureMeasurement -from zigpy.zcl.clusters.security import IasZone +from zigpy.quirks.v2 import QuirkBuilder +from zigpy.zcl.clusters.general import BinaryInput, PowerConfiguration from zhaquirks import PowerConfigurationCluster from zhaquirks.centralite import CENTRALITE -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) MANUFACTURER_SPECIFIC_PROFILE_ID = 0xC2DF # decimal = 49887 - -class CentraLite3300S(CustomDevice): - """Custom device representing centralite 3300.""" - - signature = { - # - MODELS_INFO: [ - (CENTRALITE, "3300"), - (CENTRALITE, "3300-S"), - (CENTRALITE, "3323-G"), - ], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfigurationCluster.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - IasZone.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - }, - # - 2: { - PROFILE_ID: MANUFACTURER_SPECIFIC_PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.SIMPLE_SENSOR, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfigurationCluster.cluster_id, - Identify.cluster_id, - BinaryInput.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [Identify.cluster_id], - }, - }, - } - - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfigurationCluster, - Identify.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - IasZone.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - }, - 2: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [Identify.cluster_id], - }, - } - } +( + QuirkBuilder(CENTRALITE, "3300") + # .applies_to(CENTRALITE, "3300-S") # TODO: this is also defined in `ias.py`! + .applies_to(CENTRALITE, "3323-G") + .replaces(PowerConfigurationCluster, endpoint_id=1) + .removes(PowerConfiguration.cluster_id, endpoint_id=2) + .removes(BinaryInput.cluster_id, endpoint_id=2) + .add_to_registry() +) diff --git a/zhaquirks/centralite/cl_3305S.py b/zhaquirks/centralite/cl_3305S.py index 5bc8a6f9f9..62fef3de1b 100755 --- a/zhaquirks/centralite/cl_3305S.py +++ b/zhaquirks/centralite/cl_3305S.py @@ -1,109 +1,20 @@ """Device handler for centralite 3305.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import Basic, Identify, Ota, PollControl -from zigpy.zcl.clusters.homeautomation import Diagnostic -from zigpy.zcl.clusters.measurement import OccupancySensing, TemperatureMeasurement -from zigpy.zcl.clusters.security import IasZone +from zigpy.quirks.v2 import QuirkBuilder from zhaquirks import PowerConfigurationCluster from zhaquirks.centralite import CENTRALITE -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) - - -class CentraLite3305S(CustomDevice): - """Custom device representing centralite 3305.""" - - signature = { - # - MODELS_INFO: [ - (CENTRALITE, "3305-S"), - (CENTRALITE, "3305"), - (CENTRALITE, "3325-S"), - (CENTRALITE, "3325"), - (CENTRALITE, "3326-L"), - (CENTRALITE, "3326"), - (CENTRALITE, "3328-G"), - (CENTRALITE, "Motion Sensor-A"), - ], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfigurationCluster.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - IasZone.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - }, - # - 2: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.OCCUPANCY_SENSOR, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfigurationCluster.cluster_id, - Identify.cluster_id, - OccupancySensing.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [Identify.cluster_id], - }, - }, - } - - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfigurationCluster, - Identify.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - IasZone.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - }, - 2: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - OccupancySensing.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [Identify.cluster_id], - }, - } - } - -class CentraLite3305S2(CentraLite3305S): - """Custom device representing centralite 3305 with one endpoint.""" - - signature = { - MODELS_INFO: [(CENTRALITE, "3305")], - ENDPOINTS: {1: {**CentraLite3305S.signature["endpoints"][1]}}, - } - - replacement = {ENDPOINTS: {1: {**CentraLite3305S.replacement["endpoints"][1]}}} +( + QuirkBuilder(CENTRALITE, "3305-S") + .applies_to(CENTRALITE, "3305") + .applies_to(CENTRALITE, "3325-S") + .applies_to(CENTRALITE, "3325") + .applies_to(CENTRALITE, "3326-L") + .applies_to(CENTRALITE, "3326") + .applies_to(CENTRALITE, "3328-G") + .applies_to(CENTRALITE, "Motion Sensor-A") + .replaces(PowerConfigurationCluster, endpoint_id=1) + .removes(PowerConfigurationCluster, endpoint_id=2) + .add_to_registry() +) diff --git a/zhaquirks/centralite/cl_3310S.py b/zhaquirks/centralite/cl_3310S.py index ee88814ffb..9d19ba5130 100755 --- a/zhaquirks/centralite/cl_3310S.py +++ b/zhaquirks/centralite/cl_3310S.py @@ -1,23 +1,12 @@ """Centralite 3310S implementation.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomCluster, CustomDevice +from zigpy.quirks import CustomCluster +from zigpy.quirks.v2 import QuirkBuilder import zigpy.types as t -from zigpy.zcl.clusters.general import Basic, Identify, Ota, PollControl -from zigpy.zcl.clusters.homeautomation import Diagnostic -from zigpy.zcl.clusters.measurement import TemperatureMeasurement from zigpy.zcl.foundation import BaseAttributeDefs, ZCLAttributeDef from zhaquirks import PowerConfigurationCluster from zhaquirks.centralite import CENTRALITE -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) SMRT_THINGS_REL_HUM_CLSTR = 0xFC45 @@ -38,50 +27,11 @@ class AttributeDefs(BaseAttributeDefs): ) -class CentraLite3310S(CustomDevice): - """CentraLite3310S custom device implementation.""" - - signature = { - # - MODELS_INFO: [ - (CENTRALITE, "3310-G"), - (CENTRALITE, "3310-S"), - (CENTRALITE, "3310"), - ], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.TEMPERATURE_SENSOR, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfigurationCluster.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - Diagnostic.cluster_id, - SmartthingsRelativeHumidityCluster.cluster_id, - ], - OUTPUT_CLUSTERS: [Identify.cluster_id, Ota.cluster_id], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfigurationCluster, - Identify.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - Diagnostic.cluster_id, - SmartthingsRelativeHumidityCluster, - ], - OUTPUT_CLUSTERS: [Identify.cluster_id, Ota.cluster_id], - } - } - } +( + QuirkBuilder(CENTRALITE, "3310-G") + .applies_to(CENTRALITE, "3310-S") + .applies_to(CENTRALITE, "3310") + .replaces(PowerConfigurationCluster, endpoint_id=1) + .replaces(SmartthingsRelativeHumidityCluster, endpoint_id=1) + .add_to_registry() +) diff --git a/zhaquirks/centralite/cl_3321S.py b/zhaquirks/centralite/cl_3321S.py index e3ff87b6ff..917d333e8e 100755 --- a/zhaquirks/centralite/cl_3321S.py +++ b/zhaquirks/centralite/cl_3321S.py @@ -1,101 +1,18 @@ """Centralite 3321S quirk.""" # pylint disable=C0103 -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import Basic, Identify, Ota, PollControl -from zigpy.zcl.clusters.homeautomation import Diagnostic -from zigpy.zcl.clusters.measurement import TemperatureMeasurement -from zigpy.zcl.clusters.security import IasZone +from zigpy.quirks.v2 import QuirkBuilder +from zigpy.zcl.clusters.general import PowerConfiguration from zhaquirks import PowerConfigurationCluster from zhaquirks.centralite import CENTRALITE, CentraLiteAccelCluster -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) -from zhaquirks.samjin import SAMJIN - -MANUFACTURER_SPECIFIC_CLUSTER_ID = 0xFC0F # decimal = 64527 -MANUFACTURER_SPECIFIC_PROFILE_ID = 0xC2DF # decimal = 49887 - -class CentraLite3321S(CustomDevice): - """CentraLite3321S custom device implementation.""" - - signature = { - # - MODELS_INFO: [ - (CENTRALITE, "3320"), - (CENTRALITE, "3321-S"), - (CENTRALITE, "3321"), - (SAMJIN, "multi"), - ], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfigurationCluster.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - IasZone.cluster_id, - Diagnostic.cluster_id, - CentraLiteAccelCluster.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - }, - # - 2: { - PROFILE_ID: MANUFACTURER_SPECIFIC_PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.SIMPLE_SENSOR, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfigurationCluster.cluster_id, - Identify.cluster_id, - Diagnostic.cluster_id, - MANUFACTURER_SPECIFIC_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [Identify.cluster_id], - }, - }, - } - - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfigurationCluster, - Identify.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - IasZone.cluster_id, - Diagnostic.cluster_id, - CentraLiteAccelCluster, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - }, - 2: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Diagnostic.cluster_id, - MANUFACTURER_SPECIFIC_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [Identify.cluster_id], - }, - } - } +( + QuirkBuilder(CENTRALITE, "3320") + .applies_to(CENTRALITE, "3321-S") + .applies_to(CENTRALITE, "3321") + .replaces(PowerConfigurationCluster, endpoint_id=1) + .replaces(CentraLiteAccelCluster, endpoint_id=1) + .removes(PowerConfiguration.cluster_id, endpoint_id=2) + .add_to_registry() +) diff --git a/zhaquirks/centralite/cl_3460L.py b/zhaquirks/centralite/cl_3460L.py index e628dd1f60..dfd65acf53 100755 --- a/zhaquirks/centralite/cl_3460L.py +++ b/zhaquirks/centralite/cl_3460L.py @@ -1,18 +1,7 @@ """Device handler for centralite 3460L.""" # pylint disable=C0103 -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - Identify, - OnOff, - OnOffConfiguration, - Ota, - PollControl, -) -from zigpy.zcl.clusters.homeautomation import Diagnostic -from zigpy.zcl.clusters.measurement import TemperatureMeasurement +from zigpy.quirks.v2 import QuirkBuilder from zhaquirks import PowerConfigurationCluster from zhaquirks.centralite import CENTRALITE @@ -21,12 +10,6 @@ COMMAND, COMMAND_OFF, COMMAND_ON, - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, SHORT_PRESS, SHORT_RELEASE, ) @@ -39,59 +22,14 @@ class CustomPowerConfigurationCluster(PowerConfigurationCluster): MAX_VOLTS = 3.0 -class CentraLite3460L(CustomDevice): - """Custom device representing centralite 3460L.""" - - signature = { - # - MODELS_INFO: [(CENTRALITE, "3460-L")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.REMOTE_CONTROL, - INPUT_CLUSTERS: [ - Basic.cluster_id, - CustomPowerConfigurationCluster.cluster_id, - Identify.cluster_id, - OnOffConfiguration.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - OnOff.cluster_id, - Ota.cluster_id, - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - CustomPowerConfigurationCluster, - Identify.cluster_id, - OnOffConfiguration.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - OnOff.cluster_id, - Ota.cluster_id, - ], - } +( + QuirkBuilder(CENTRALITE, "3460-L") + .replaces(CustomPowerConfigurationCluster, endpoint_id=1) + .device_automation_triggers( + { + (SHORT_PRESS, BUTTON_1): {COMMAND: COMMAND_ON}, + (SHORT_RELEASE, BUTTON_1): {COMMAND: COMMAND_OFF}, } - } - - device_automation_triggers = { - (SHORT_PRESS, BUTTON_1): {COMMAND: COMMAND_ON}, - (SHORT_RELEASE, BUTTON_1): {COMMAND: COMMAND_OFF}, - } + ) + .add_to_registry() +) diff --git a/zhaquirks/centralite/ias.py b/zhaquirks/centralite/ias.py index a1f8466922..13f56b1d27 100755 --- a/zhaquirks/centralite/ias.py +++ b/zhaquirks/centralite/ias.py @@ -1,168 +1,20 @@ """Device handler for centralite ias sensors.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import Basic, BinaryInput, Identify, Ota, PollControl -from zigpy.zcl.clusters.homeautomation import Diagnostic -from zigpy.zcl.clusters.measurement import TemperatureMeasurement -from zigpy.zcl.clusters.security import IasZone +from zigpy.quirks.v2 import QuirkBuilder +from zigpy.zcl.clusters.general import PowerConfiguration from zhaquirks import PowerConfigurationCluster -from zhaquirks.centralite import CENTRALITE -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) - -MANUFACTURER_SPECIFIC_CLUSTER_ID = 0xFC0F # decimal = 64527 -MANUFACTURER_SPECIFIC_PROFILE_ID = 0xC2DF # decimal = 49887 - - -class CentraLiteIASSensor(CustomDevice): - """Custom device representing centralite ias sensors.""" - - signature = { - # - MODELS_INFO: [ - (CENTRALITE, "3300-S"), - (CENTRALITE, "3315-G"), - (CENTRALITE, "3315-L"), - (CENTRALITE, "3315-S"), - (CENTRALITE, "3315-Seu"), - (CENTRALITE, "3315"), - (CENTRALITE, "3320-L"), - (CENTRALITE, "Contact Sensor-A"), - ], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfigurationCluster.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - IasZone.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - }, - # - 2: { - PROFILE_ID: MANUFACTURER_SPECIFIC_PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.SIMPLE_SENSOR, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfigurationCluster.cluster_id, - Identify.cluster_id, - Diagnostic.cluster_id, - MANUFACTURER_SPECIFIC_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [Identify.cluster_id], - }, - }, - } - - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfigurationCluster, - Identify.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - IasZone.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - }, - 2: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Diagnostic.cluster_id, - MANUFACTURER_SPECIFIC_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [Identify.cluster_id], - }, - } - } - -class CentraLiteIASSensorV2(CustomDevice): - """Custom device representing centralite ias sensors.""" - - signature = { - # - MODELS_INFO: CentraLiteIASSensor.signature[MODELS_INFO], - ENDPOINTS: { - 1: CentraLiteIASSensor.signature[ENDPOINTS][1], - # - 2: { - PROFILE_ID: MANUFACTURER_SPECIFIC_PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.SIMPLE_SENSOR, - INPUT_CLUSTERS: [ - Basic.cluster_id, - BinaryInput.cluster_id, - PowerConfigurationCluster.cluster_id, - Identify.cluster_id, - Diagnostic.cluster_id, - MANUFACTURER_SPECIFIC_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [Identify.cluster_id], - }, - }, - } - - replacement = CentraLiteIASSensor.replacement - - -class CentraLiteIASSensorV3(CustomDevice): - """Custom device representing centralite ias sensors.""" - - signature = { - # - MODELS_INFO: CentraLiteIASSensor.signature[MODELS_INFO], - ENDPOINTS: { - 1: CentraLiteIASSensor.signature[ENDPOINTS][1], - # - 2: { - PROFILE_ID: MANUFACTURER_SPECIFIC_PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.SIMPLE_SENSOR, - INPUT_CLUSTERS: [ - Basic.cluster_id, - BinaryInput.cluster_id, - PowerConfigurationCluster.cluster_id, - Identify.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [Identify.cluster_id], - }, - }, - } - - replacement = CentraLiteIASSensor.replacement +( + QuirkBuilder("CentraLite", "3300-S") + .applies_to("CentraLite", "3315-G") + .applies_to("CentraLite", "3315-L") + .applies_to("CentraLite", "3315-S") + .applies_to("CentraLite", "3315-Seu") + .applies_to("CentraLite", "3315") + .applies_to("CentraLite", "3320-L") + .applies_to("CentraLite", "Contact Sensor-A") + .replaces(PowerConfigurationCluster, endpoint_id=1) + .removes(PowerConfiguration.cluster_id, endpoint_id=2) + .add_to_registry() +) diff --git a/zhaquirks/centralite/motion.py b/zhaquirks/centralite/motion.py deleted file mode 100755 index 65678f5692..0000000000 --- a/zhaquirks/centralite/motion.py +++ /dev/null @@ -1,96 +0,0 @@ -"""Device handler for centralite motion (only) sensors.""" - -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import Basic, Identify, Ota, PollControl -from zigpy.zcl.clusters.homeautomation import Diagnostic -from zigpy.zcl.clusters.measurement import TemperatureMeasurement -from zigpy.zcl.clusters.security import IasZone - -from zhaquirks import PowerConfigurationCluster -from zhaquirks.centralite import CENTRALITE -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) - -MANUFACTURER_SPECIFIC_CLUSTER_ID = 0xFC46 # decimal = 64582 -MANUFACTURER_SPECIFIC_PROFILE_ID = 0xC2DF # decimal = 49887 - - -class CentraLiteMotionSensor(CustomDevice): - """Custom device representing centralite motion (only) sensors.""" - - signature = { - # - MODELS_INFO: [ - (CENTRALITE, "3305-S"), - (CENTRALITE, "3325-S"), - (CENTRALITE, "3326-L"), - ], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfigurationCluster.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - IasZone.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - }, - # - 2: { - PROFILE_ID: MANUFACTURER_SPECIFIC_PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.OCCUPANCY_SENSOR, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfigurationCluster.cluster_id, - Identify.cluster_id, - Diagnostic.cluster_id, - MANUFACTURER_SPECIFIC_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [Identify.cluster_id], - }, - }, - } - - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfigurationCluster, - Identify.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - IasZone.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - }, - 2: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Diagnostic.cluster_id, - MANUFACTURER_SPECIFIC_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [Identify.cluster_id], - }, - } - } diff --git a/zhaquirks/centralite/motionandtemp.py b/zhaquirks/centralite/motionandtemp.py index 046eadde0a..1d741da7c8 100644 --- a/zhaquirks/centralite/motionandtemp.py +++ b/zhaquirks/centralite/motionandtemp.py @@ -1,18 +1,7 @@ """Device handler for centralite 3450L.""" # pylint disable=C0103 -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - Identify, - OnOff, - OnOffConfiguration, - Ota, - PollControl, - PowerConfiguration, -) -from zigpy.zcl.clusters.homeautomation import Diagnostic +from zigpy.quirks.v2 import QuirkBuilder from zhaquirks import PowerConfigurationCluster from zhaquirks.centralite import CENTRALITE @@ -23,13 +12,7 @@ BUTTON_4, COMMAND, COMMAND_PRESS, - DEVICE_TYPE, ENDPOINT_ID, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, SHORT_PRESS, ) @@ -41,109 +24,17 @@ class CustomPowerConfigurationCluster(PowerConfigurationCluster): MAX_VOLTS = 3.0 -class CentraLite3450L(CustomDevice): - """Custom device representing centralite 3450L.""" - - signature = { - # - MODELS_INFO: [(CENTRALITE, "3450-L"), (CENTRALITE, "3450-L2")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.REMOTE_CONTROL, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - OnOffConfiguration.cluster_id, - PollControl.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - OnOff.cluster_id, - Ota.cluster_id, - ], - }, - 2: { - # input_clusters=[7] - # output_clusters=[6]> - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.REMOTE_CONTROL, - INPUT_CLUSTERS: [OnOffConfiguration.cluster_id], - OUTPUT_CLUSTERS: [OnOff.cluster_id], - }, - 3: { - # input_clusters=[7] - # output_clusters=[6]> - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.REMOTE_CONTROL, - INPUT_CLUSTERS: [OnOffConfiguration.cluster_id], - OUTPUT_CLUSTERS: [OnOff.cluster_id], - }, - 4: { - # input_clusters=[7] - # output_clusters=[6]> - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.REMOTE_CONTROL, - INPUT_CLUSTERS: [OnOffConfiguration.cluster_id], - OUTPUT_CLUSTERS: [OnOff.cluster_id], - }, - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.REMOTE_CONTROL, - INPUT_CLUSTERS: [ - Basic.cluster_id, - CustomPowerConfigurationCluster, - Identify.cluster_id, - OnOffConfiguration.cluster_id, - PollControl.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - OnOff.cluster_id, - Ota.cluster_id, - ], - }, - 2: { - # input_clusters=[7] - # output_clusters=[6]> - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.REMOTE_CONTROL, - INPUT_CLUSTERS: [OnOffConfiguration.cluster_id], - OUTPUT_CLUSTERS: [OnOff.cluster_id], - }, - 3: { - # input_clusters=[7] - # output_clusters=[6]> - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.REMOTE_CONTROL, - INPUT_CLUSTERS: [OnOffConfiguration.cluster_id], - OUTPUT_CLUSTERS: [OnOff.cluster_id], - }, - 4: { - # input_clusters=[7] - # output_clusters=[6]> - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.REMOTE_CONTROL, - INPUT_CLUSTERS: [OnOffConfiguration.cluster_id], - OUTPUT_CLUSTERS: [OnOff.cluster_id], - }, +( + QuirkBuilder(CENTRALITE, "3450-L") + .applies_to(CENTRALITE, "3450-L2") + .replaces(CustomPowerConfigurationCluster, endpoint_id=1) + .device_automation_triggers( + { + (SHORT_PRESS, BUTTON_1): {COMMAND: COMMAND_PRESS, ENDPOINT_ID: 1}, + (SHORT_PRESS, BUTTON_2): {COMMAND: COMMAND_PRESS, ENDPOINT_ID: 2}, + (SHORT_PRESS, BUTTON_3): {COMMAND: COMMAND_PRESS, ENDPOINT_ID: 3}, + (SHORT_PRESS, BUTTON_4): {COMMAND: COMMAND_PRESS, ENDPOINT_ID: 4}, } - } - - device_automation_triggers = { - (SHORT_PRESS, BUTTON_1): {COMMAND: COMMAND_PRESS, ENDPOINT_ID: 1}, - (SHORT_PRESS, BUTTON_2): {COMMAND: COMMAND_PRESS, ENDPOINT_ID: 2}, - (SHORT_PRESS, BUTTON_3): {COMMAND: COMMAND_PRESS, ENDPOINT_ID: 3}, - (SHORT_PRESS, BUTTON_4): {COMMAND: COMMAND_PRESS, ENDPOINT_ID: 4}, - } + ) + .add_to_registry() +) diff --git a/zhaquirks/danfoss/thermostat.py b/zhaquirks/danfoss/thermostat.py index fe41a91db9..2ed9679dab 100644 --- a/zhaquirks/danfoss/thermostat.py +++ b/zhaquirks/danfoss/thermostat.py @@ -34,28 +34,13 @@ from typing import Any from zigpy import types -from zigpy.profiles import zha -from zigpy.quirks import CustomCluster, CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - Identify, - Ota, - PollControl, - PowerConfiguration, - Time, -) +from zigpy.quirks import CustomCluster +from zigpy.quirks.v2 import CustomDeviceV2, QuirkBuilder +from zigpy.zcl.clusters.general import Time from zigpy.zcl.clusters.homeautomation import Diagnostic from zigpy.zcl.clusters.hvac import Thermostat, UserInterface from zigpy.zcl.foundation import ZCLAttributeDef, ZCLCommandDef -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.quirk_ids import DANFOSS_ALLY_THERMOSTAT DANFOSS = "Danfoss" @@ -480,59 +465,25 @@ async def bind(self): return result -class DanfossThermostat(CustomDevice): +class DanfossThermostat(CustomDeviceV2): """DanfossThermostat custom device.""" quirk_id = DANFOSS_ALLY_THERMOSTAT - manufacturer_code = 0x1246 - signature = { - # - MODELS_INFO: [ - (DANFOSS, "eTRV0100"), - (DANFOSS, "eTRV0101"), - (DANFOSS, "eTRV0103"), - (POPP, "eT093WRO"), - (POPP, "eT093WRG"), - (HIVE, "TRV001"), - (HIVE, "TRV003"), - ], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.THERMOSTAT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - Time.cluster_id, - PollControl.cluster_id, - Thermostat.cluster_id, - UserInterface.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [Basic.cluster_id, Ota.cluster_id], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - DanfossTimeCluster, - DanfossThermostatCluster, - DanfossUserInterfaceCluster, - DanfossDiagnosticCluster, - ], - OUTPUT_CLUSTERS: [Basic.cluster_id, Ota.cluster_id], - } - } - } + +( + QuirkBuilder(DANFOSS, "eTRV0100") + .device_class(DanfossThermostat) + .applies_to(DANFOSS, "eTRV0101") + .applies_to(DANFOSS, "eTRV0103") + .applies_to(POPP, "eT093WRO") + .applies_to(POPP, "eT093WRG") + .applies_to(HIVE, "TRV001") + .applies_to(HIVE, "TRV003") + .replaces(DanfossTimeCluster, endpoint_id=1) + .replaces(DanfossThermostatCluster, endpoint_id=1) + .replaces(DanfossUserInterfaceCluster, endpoint_id=1) + .replaces(DanfossDiagnosticCluster, endpoint_id=1) + .add_to_registry() +) diff --git a/zhaquirks/echostar/bell.py b/zhaquirks/echostar/bell.py index d2ff26479a..312a340486 100644 --- a/zhaquirks/echostar/bell.py +++ b/zhaquirks/echostar/bell.py @@ -1,16 +1,8 @@ """Echostar Sage Doorbell Sensor Device.""" from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Alarms, - Basic, - Identify, - LevelControl, - OnOff, - Ota, - PowerConfiguration, -) +from zigpy.quirks.v2 import QuirkBuilder +from zigpy.zcl.clusters.general import OnOff from zhaquirks.const import ( BUTTON_1, @@ -19,70 +11,29 @@ COMMAND, COMMAND_OFF, COMMAND_ON, - DEVICE_TYPE, ENDPOINT_ID, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, SHORT_PRESS, ) -MANUFACTURER = " Echostar" -MODEL = " Bell" - - -class Bell(CustomDevice): - """Echostar Bell device.""" - - signature = { - # - MODELS_INFO: [(MANUFACTURER, MODEL)], - ENDPOINTS: { - 18: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.DIMMER_SWITCH, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Alarms.cluster_id, - PowerConfiguration.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 18: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Alarms.cluster_id, - PowerConfiguration.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - ], - } +( + QuirkBuilder(" Echostar", " Bell") + .replaces_endpoint( + 18, + device_type=zha.DeviceType.ON_OFF_SWITCH, + ) + .device_automation_triggers( + { + (SHORT_PRESS, BUTTON_1): { + COMMAND: COMMAND_ON, + CLUSTER_ID: OnOff.cluster_id, + ENDPOINT_ID: 18, + }, + (SHORT_PRESS, BUTTON_2): { + COMMAND: COMMAND_OFF, + CLUSTER_ID: OnOff.cluster_id, + ENDPOINT_ID: 18, + }, } - } - device_automation_triggers = { - (SHORT_PRESS, BUTTON_1): {COMMAND: COMMAND_ON, CLUSTER_ID: 6, ENDPOINT_ID: 18}, - (SHORT_PRESS, BUTTON_2): {COMMAND: COMMAND_OFF, CLUSTER_ID: 6, ENDPOINT_ID: 18}, - } + ) + .add_to_registry() +) diff --git a/zhaquirks/ecolink/contact.py b/zhaquirks/ecolink/contact.py index c64abb0f58..761d802c5c 100644 --- a/zhaquirks/ecolink/contact.py +++ b/zhaquirks/ecolink/contact.py @@ -1,21 +1,8 @@ """Ecolink 4655BC0-R device.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import Basic, Identify, Ota, PollControl -from zigpy.zcl.clusters.homeautomation import Diagnostic -from zigpy.zcl.clusters.measurement import TemperatureMeasurement -from zigpy.zcl.clusters.security import IasZone +from zigpy.quirks.v2 import QuirkBuilder from zhaquirks import PowerConfigurationCluster -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) class CustomPowerConfigurationCluster(PowerConfigurationCluster): @@ -25,47 +12,8 @@ class CustomPowerConfigurationCluster(PowerConfigurationCluster): MAX_VOLTS = 3.0 -class Ecolink4655BC0R(CustomDevice): - """Ecolink 4655BC0-R device.""" - - signature = { - # - MODELS_INFO: [("Ecolink", "4655BC0-R")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - CustomPowerConfigurationCluster.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - IasZone.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - INPUT_CLUSTERS: [ - Basic.cluster_id, - CustomPowerConfigurationCluster, - Identify.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - IasZone.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - } - } +( + QuirkBuilder("Ecolink", "4655BC0-R") + .replaces(CustomPowerConfigurationCluster, endpoint_id=1) + .add_to_registry() +) diff --git a/zhaquirks/edpwithus/redy_plug.py b/zhaquirks/edpwithus/redy_plug.py index 25bb5142cb..e2c51c41cd 100644 --- a/zhaquirks/edpwithus/redy_plug.py +++ b/zhaquirks/edpwithus/redy_plug.py @@ -1,65 +1,13 @@ """EDP WithUs SmartPlug Quirk.""" from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Alarms, - Basic, - Groups, - Identify, - OnOff, - Ota, - Scenes, - Time, -) -from zigpy.zcl.clusters.smartenergy import Metering +from zigpy.quirks.v2 import QuirkBuilder from zhaquirks.edpwithus import MeteringCluster - -class EdpWithUsSmartPlug(CustomDevice): - """Tradfri Plug.""" - - signature = { - "endpoints": { - # - 85: { - "profile_id": zha.PROFILE_ID, - "device_type": zha.DeviceType.MAIN_POWER_OUTLET, - "input_clusters": [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - Alarms.cluster_id, - Time.cluster_id, - Metering.cluster_id, - ], - "output_clusters": [Ota.cluster_id], - } - }, - "manufacturer": "EDP-WITHUS", - } - - replacement = { - "endpoints": { - 85: { - "profile_id": zha.PROFILE_ID, - "device_type": zha.DeviceType.ON_OFF_PLUG_IN_UNIT, - "input_clusters": [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - Alarms.cluster_id, - Time.cluster_id, - MeteringCluster, - ], - "output_clusters": [Ota.cluster_id], - } - } - } +( + QuirkBuilder("EDP-WITHUS", "Smart Plug") + .replaces_endpoint(85, device_type=zha.DeviceType.ON_OFF_PLUG_IN_UNIT) + .replaces(MeteringCluster, endpoint_id=85) + .add_to_registry() +) diff --git a/zhaquirks/elko/__init__.py b/zhaquirks/elko/__init__.py index ca2727eb49..ffcda6f651 100644 --- a/zhaquirks/elko/__init__.py +++ b/zhaquirks/elko/__init__.py @@ -1,77 +1 @@ """Module for Elko quirks implementations.""" - -from zigpy.quirks import CustomCluster, CustomDevice -from zigpy.zcl.clusters.homeautomation import ElectricalMeasurement -from zigpy.zcl.clusters.hvac import Thermostat, UserInterface - -from zhaquirks import Bus, LocalDataCluster - -ELKO = "ELKO" - - -class ElkoThermostatCluster(CustomCluster, Thermostat): - """Thermostat cluster for Elko Thermostats.""" - - class AttributeDefs(Thermostat.AttributeDefs): - """Cluster attributes.""" - - def __init__(self, *args, **kwargs): - """Init thermostat cluster.""" - super().__init__(*args, **kwargs) - self.endpoint.device.thermostat_bus.add_listener(self) - - def heating_active_change(self, value): - """State update from device.""" - if value == 0: - mode = self.RunningMode.Off - state = self.RunningState.Idle - else: - mode = self.RunningMode.Heat - state = self.RunningState.Heat_State_On - - self._update_attribute(self.attributes_by_name["running_mode"].id, mode) - self._update_attribute(self.attributes_by_name["running_state"].id, state) - - -class ElkoUserInterfaceCluster(LocalDataCluster, UserInterface): - """User interface cluster for Elko Thermostats.""" - - def __init__(self, *args, **kwargs): - """Init UI cluster.""" - super().__init__(*args, **kwargs) - self.endpoint.device.ui_bus.add_listener(self) - - def child_lock_change(self, mode): - """Enable/disable child lock.""" - if mode: - lockout = self.KeypadLockout.Level_1_lockout - else: - lockout = self.KeypadLockout.No_lockout - - self._update_attribute(self.attributes_by_name["keypad_lockout"].id, lockout) - - -class ElkoElectricalMeasurementCluster(LocalDataCluster, ElectricalMeasurement): - """Electrical measurement cluster for Elko Thermostats.""" - - ACTIVE_POWER_ID = 0x050B - - def __init__(self, *args, **kwargs): - """Init electrical measurement cluster.""" - super().__init__(*args, **kwargs) - self.endpoint.device.power_bus.add_listener(self) - - def power_reported(self, value): - """Report consumption.""" - self._update_attribute(self.ACTIVE_POWER_ID, value) - - -class ElkoThermostat(CustomDevice): - """Generic Elko Thermostat device.""" - - def __init__(self, *args, **kwargs): - """Init device.""" - self.thermostat_bus = Bus() - self.ui_bus = Bus() - self.power_bus = Bus() - super().__init__(*args, **kwargs) diff --git a/zhaquirks/elko/smart_super_thermostat.py b/zhaquirks/elko/smart_super_thermostat.py index 06a2cbe93d..9ae9011039 100644 --- a/zhaquirks/elko/smart_super_thermostat.py +++ b/zhaquirks/elko/smart_super_thermostat.py @@ -2,27 +2,16 @@ from typing import Final -import zigpy.profiles.zha as zha_p +from zigpy.quirks import CustomCluster +from zigpy.quirks.v2 import CustomDeviceV2, QuirkBuilder import zigpy.types as t -from zigpy.zcl.clusters.general import Basic, Groups, Identify, Ota, Scenes -from zigpy.zcl.clusters.hvac import Thermostat +from zigpy.zcl.clusters.homeautomation import ElectricalMeasurement +from zigpy.zcl.clusters.hvac import Thermostat, UserInterface from zigpy.zcl.foundation import ZCLAttributeDef -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) -from zhaquirks.elko import ( - ELKO, - ElkoElectricalMeasurementCluster, - ElkoThermostat, - ElkoThermostatCluster, - ElkoUserInterfaceCluster, -) +from zhaquirks import Bus, LocalDataCluster + +ELKO = "ELKO" LOCAL_TEMP = 0x0000 UNKNOWN_1 = 0x0401 @@ -46,6 +35,74 @@ UNKNOWN_9 = 0x0419 +class ElkoThermostatCluster(CustomCluster, Thermostat): + """Thermostat cluster for Elko Thermostats.""" + + class AttributeDefs(Thermostat.AttributeDefs): + """Cluster attributes.""" + + def __init__(self, *args, **kwargs): + """Init thermostat cluster.""" + super().__init__(*args, **kwargs) + self.endpoint.device.thermostat_bus.add_listener(self) + + def heating_active_change(self, value): + """State update from device.""" + if value == 0: + mode = self.RunningMode.Off + state = self.RunningState.Idle + else: + mode = self.RunningMode.Heat + state = self.RunningState.Heat_State_On + + self._update_attribute(self.attributes_by_name["running_mode"].id, mode) + self._update_attribute(self.attributes_by_name["running_state"].id, state) + + +class ElkoUserInterfaceCluster(LocalDataCluster, UserInterface): + """User interface cluster for Elko Thermostats.""" + + def __init__(self, *args, **kwargs): + """Init UI cluster.""" + super().__init__(*args, **kwargs) + self.endpoint.device.ui_bus.add_listener(self) + + def child_lock_change(self, mode): + """Enable/disable child lock.""" + if mode: + lockout = self.KeypadLockout.Level_1_lockout + else: + lockout = self.KeypadLockout.No_lockout + + self._update_attribute(self.attributes_by_name["keypad_lockout"].id, lockout) + + +class ElkoElectricalMeasurementCluster(LocalDataCluster, ElectricalMeasurement): + """Electrical measurement cluster for Elko Thermostats.""" + + ACTIVE_POWER_ID = 0x050B + + def __init__(self, *args, **kwargs): + """Init electrical measurement cluster.""" + super().__init__(*args, **kwargs) + self.endpoint.device.power_bus.add_listener(self) + + def power_reported(self, value): + """Report consumption.""" + self._update_attribute(self.ACTIVE_POWER_ID, value) + + +class ElkoThermostat(CustomDeviceV2): + """Generic Elko Thermostat device.""" + + def __init__(self, *args, **kwargs): + """Init device.""" + self.thermostat_bus = Bus() + self.ui_bus = Bus() + self.power_bus = Bus() + super().__init__(*args, **kwargs) + + class ActiveSensor(t.enum8): """Working modes of the thermostat.""" @@ -135,48 +192,11 @@ def _update_attribute(self, attrid, value): super()._update_attribute(attrid, value) -class ElkoSuperTRThermostat(ElkoThermostat): - """Elko thermostat custom device.""" - - manufacturer_id_override = 0 - - signature = { - MODELS_INFO: [(ELKO, "Super TR")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha_p.PROFILE_ID, - DEVICE_TYPE: zha_p.DeviceType.THERMOSTAT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - Thermostat.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Ota.cluster_id, - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - ElkoSuperTRThermostatCluster, - ElkoUserInterfaceCluster, - ElkoElectricalMeasurementCluster, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Ota.cluster_id, - ], - } - } - } +( + QuirkBuilder(ELKO, "Super TR") + .device_class(ElkoThermostat) + .replaces(ElkoSuperTRThermostatCluster, endpoint_id=1) + .adds(ElkoUserInterfaceCluster, endpoint_id=1) + .adds(ElkoElectricalMeasurementCluster, endpoint_id=1) + .add_to_registry() +) diff --git a/zhaquirks/eurotronic/spzb0001.py b/zhaquirks/eurotronic/spzb0001.py index 214bb16028..28b4a02a3e 100644 --- a/zhaquirks/eurotronic/spzb0001.py +++ b/zhaquirks/eurotronic/spzb0001.py @@ -1,84 +1,13 @@ """Eurotronic Spirit Zigbee quirk.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - Groups, - Identify, - Ota, - PowerConfiguration, - Time, -) -from zigpy.zcl.clusters.hvac import Thermostat +from zigpy.quirks.v2 import QuirkBuilder +from zigpy.zcl import ClusterType -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.eurotronic import EUROTRONIC, ThermostatCluster - -class SPZB0001(CustomDevice): - """Eurotronic Spirit Zigbee device.""" - - signature = { - # - MODELS_INFO: [(EUROTRONIC, "SPZB0001")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.THERMOSTAT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - Thermostat.cluster_id, - Ota.cluster_id, - Time.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Thermostat.cluster_id, - Ota.cluster_id, - Time.cluster_id, - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.THERMOSTAT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - ThermostatCluster, - Ota.cluster_id, - Time.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - ThermostatCluster, - Ota.cluster_id, - Time.cluster_id, - ], - } - } - } +( + QuirkBuilder(EUROTRONIC, "SPZB0001") + .replaces(ThermostatCluster, cluster_type=ClusterType.Server, endpoint_id=1) + .replaces(ThermostatCluster, cluster_type=ClusterType.Client, endpoint_id=1) + .add_to_registry() +) diff --git a/zhaquirks/feibit/switch.py b/zhaquirks/feibit/switch.py index 75d41e3239..664483e7b4 100644 --- a/zhaquirks/feibit/switch.py +++ b/zhaquirks/feibit/switch.py @@ -1,236 +1,29 @@ """Quirk for FeiBit light switches to remove the LevelControl cluster.""" -from zigpy.profiles import zll -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - Groups, - Identify, - LevelControl, - OnOff, - Ota, - Scenes, -) -from zigpy.zcl.clusters.lightlink import LightLink +from zigpy.quirks.v2 import QuirkBuilder +from zigpy.zcl.clusters.general import LevelControl -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.feibit import FEIBIT +( + QuirkBuilder(FEIBIT, "FNB56-ZSW01LX2.0") + .removes(LevelControl, endpoint_id=11) + .add_to_registry() +) -class FeiBitOneWaySwitch(CustomDevice): - """FeiBit FNB56-ZSW01LX2.0 custom device implementation.""" - - signature = { - MODELS_INFO: [(FEIBIT, "FNB56-ZSW01LX2.0")], - ENDPOINTS: { - 11: { - PROFILE_ID: zll.PROFILE_ID, - DEVICE_TYPE: zll.DeviceType.ON_OFF_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - LightLink.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Ota.cluster_id, - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 11: { - PROFILE_ID: zll.PROFILE_ID, - DEVICE_TYPE: zll.DeviceType.ON_OFF_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LightLink.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Ota.cluster_id, - ], - } - } - } - - -class FeiBitTwoWaySwitch(CustomDevice): - """FeiBit FNB56-ZSW02LX2.0 custom device implementation.""" - - signature = { - MODELS_INFO: [(FEIBIT, "FNB56-ZSW02LX2.0")], - ENDPOINTS: { - 11: { - PROFILE_ID: zll.PROFILE_ID, - DEVICE_TYPE: zll.DeviceType.ON_OFF_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - LightLink.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Ota.cluster_id, - ], - }, - 12: { - PROFILE_ID: zll.PROFILE_ID, - DEVICE_TYPE: zll.DeviceType.ON_OFF_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Ota.cluster_id, - ], - }, - }, - } - - replacement = { - ENDPOINTS: { - 11: { - PROFILE_ID: zll.PROFILE_ID, - DEVICE_TYPE: zll.DeviceType.ON_OFF_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LightLink.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Ota.cluster_id, - ], - }, - 12: { - PROFILE_ID: zll.PROFILE_ID, - DEVICE_TYPE: zll.DeviceType.ON_OFF_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Ota.cluster_id, - ], - }, - } - } +( + QuirkBuilder(FEIBIT, "FNB56-ZSW02LX2.0") + .removes(LevelControl.cluster_id, endpoint_id=11) + .removes(LevelControl.cluster_id, endpoint_id=12) + .add_to_registry() +) -class FeiBitThreeWaySwitch(CustomDevice): - """FeiBit FNB56-ZSW03LX2.0 custom device implementation.""" - signature = { - MODELS_INFO: [(FEIBIT, "FNB56-ZSW03LX2.0")], - ENDPOINTS: { - 1: { - PROFILE_ID: zll.PROFILE_ID, - DEVICE_TYPE: zll.DeviceType.ON_OFF_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - LightLink.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - }, - 2: { - PROFILE_ID: zll.PROFILE_ID, - DEVICE_TYPE: zll.DeviceType.ON_OFF_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - }, - 3: { - PROFILE_ID: zll.PROFILE_ID, - DEVICE_TYPE: zll.DeviceType.ON_OFF_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - }, - }, - } - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zll.PROFILE_ID, - DEVICE_TYPE: zll.DeviceType.ON_OFF_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LightLink.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - }, - 2: { - PROFILE_ID: zll.PROFILE_ID, - DEVICE_TYPE: zll.DeviceType.ON_OFF_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - }, - 3: { - PROFILE_ID: zll.PROFILE_ID, - DEVICE_TYPE: zll.DeviceType.ON_OFF_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - }, - }, - } +( + QuirkBuilder(FEIBIT, "FNB56-ZSW03LX2.0") + .removes(LevelControl.cluster_id, endpoint_id=1) + .removes(LevelControl.cluster_id, endpoint_id=2) + .removes(LevelControl.cluster_id, endpoint_id=3) + .add_to_registry() +) diff --git a/zhaquirks/gledopto/glc009.py b/zhaquirks/gledopto/glc009.py index ccdebaf57d..285b879168 100644 --- a/zhaquirks/gledopto/glc009.py +++ b/zhaquirks/gledopto/glc009.py @@ -1,78 +1,8 @@ """GLEDOPTO GL-C-009 device.""" -from zigpy.profiles import zll -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - Groups, - Identify, - LevelControl, - OnOff, - Scenes, -) +from zigpy.quirks.v2 import QuirkBuilder from zigpy.zcl.clusters.lighting import Color -from zigpy.zcl.clusters.lightlink import LightLink -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.gledopto import GLEDOPTO - -class GLC009(CustomDevice): - """GLEDOPTO GL-C-009 device.""" - - signature = { - # SizePrefixedSimpleDescriptor(endpoint=11, profile=49246, - # device_type=256, device_version=2, - # input_clusters=[0, 3, 4, 5, 6, 8, 768], output_clusters=[]) - MODELS_INFO: [(GLEDOPTO, "GL-C-009")], - ENDPOINTS: { - 11: { - PROFILE_ID: zll.PROFILE_ID, - DEVICE_TYPE: zll.DeviceType.DIMMABLE_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Color.cluster_id, - ], - OUTPUT_CLUSTERS: [], - }, - # SizePrefixedSimpleDescriptor(endpoint=13, profile=49246, - # device_type=256, device_version=2, input_clusters=[4096], - # output_clusters=[4096]) - 13: { - PROFILE_ID: zll.PROFILE_ID, - DEVICE_TYPE: zll.DeviceType.DIMMABLE_LIGHT, - INPUT_CLUSTERS: [LightLink.cluster_id], - OUTPUT_CLUSTERS: [LightLink.cluster_id], - }, - }, - } - - replacement = { - ENDPOINTS: { - 11: { - PROFILE_ID: zll.PROFILE_ID, - DEVICE_TYPE: zll.DeviceType.DIMMABLE_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - ], - OUTPUT_CLUSTERS: [], - }, - } - } +(QuirkBuilder(GLEDOPTO, "GL-C-009").removes(Color, endpoint_id=11).add_to_registry()) diff --git a/zhaquirks/gledopto/glc009p.py b/zhaquirks/gledopto/glc009p.py index 31cffb709a..effd56f294 100644 --- a/zhaquirks/gledopto/glc009p.py +++ b/zhaquirks/gledopto/glc009p.py @@ -1,89 +1,11 @@ """GLEDOPTO GL-C-009P device.""" -from zigpy.profiles import zgp, zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - GreenPowerProxy, - Groups, - Identify, - LevelControl, - OnOff, - Ota, - Scenes, -) +from zigpy.quirks.v2 import QuirkBuilder from zigpy.zcl.clusters.lighting import Color -from zigpy.zcl.clusters.lightlink import LightLink -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, +( + # TODO: this quirk is likely unneeded + QuirkBuilder("GLEDOPTO", "GL-C-009P") + .removes(Color, endpoint_id=11) + .add_to_registry() ) - - -class GLC009P(CustomDevice): - """Gledopto GL-C-009P (mini) custom device implementation for removing Color cluster.""" - - signature = { - MODELS_INFO: [("GLEDOPTO", "GL-C-009P")], - ENDPOINTS: { - 11: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.DIMMABLE_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Color.cluster_id, - LightLink.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Ota.cluster_id, - ], - }, - 242: { - PROFILE_ID: zgp.PROFILE_ID, - DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC, - INPUT_CLUSTERS: [], - OUTPUT_CLUSTERS: [ - GreenPowerProxy.cluster_id, - ], - }, - }, - } - - replacement = { - ENDPOINTS: { - 11: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.DIMMABLE_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - LightLink.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Ota.cluster_id, - ], - }, - 242: { - PROFILE_ID: zgp.PROFILE_ID, - DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC, - INPUT_CLUSTERS: [], - OUTPUT_CLUSTERS: [ - GreenPowerProxy.cluster_id, - ], - }, - } - } diff --git a/zhaquirks/gledopto/gls007z.py b/zhaquirks/gledopto/gls007z.py index 4dc041d0b8..ab31107192 100644 --- a/zhaquirks/gledopto/gls007z.py +++ b/zhaquirks/gledopto/gls007z.py @@ -1,98 +1,12 @@ """GLEDOPTO GL-S-007Z device.""" -from zigpy.profiles import zha, zll -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - Groups, - Identify, - LevelControl, - OnOff, - Scenes, -) -from zigpy.zcl.clusters.lighting import Color -from zigpy.zcl.clusters.lightlink import LightLink +from zigpy.quirks.v2 import QuirkBuilder -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.gledopto import GLEDOPTO - -class GLS007Z(CustomDevice): - """GLEDOPTO GL-S-007Z device.""" - - signature = { - # - MODELS_INFO: [(GLEDOPTO, "GL-S-007Z")], - ENDPOINTS: { - 12: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.COLOR_DIMMABLE_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Color.cluster_id, - ], - OUTPUT_CLUSTERS: [], - }, - # - 11: { - PROFILE_ID: zll.PROFILE_ID, - DEVICE_TYPE: zll.DeviceType.EXTENDED_COLOR_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Color.cluster_id, - ], - OUTPUT_CLUSTERS: [], - }, - # - 13: { - PROFILE_ID: zll.PROFILE_ID, - DEVICE_TYPE: 57694, - INPUT_CLUSTERS: [LightLink.cluster_id], - OUTPUT_CLUSTERS: [LightLink.cluster_id], - }, - }, - } - - replacement = { - ENDPOINTS: { - 12: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.COLOR_DIMMABLE_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Color.cluster_id, - ], - OUTPUT_CLUSTERS: [], - } - } - } +( + QuirkBuilder(GLEDOPTO, "GL-S-007Z") + .removes_endpoint(11) + .removes_endpoint(13) + .add_to_registry() +) diff --git a/zhaquirks/gledopto/glsd_dimmer.py b/zhaquirks/gledopto/glsd_dimmer.py index 824ff50e4b..16306a6a08 100644 --- a/zhaquirks/gledopto/glsd_dimmer.py +++ b/zhaquirks/gledopto/glsd_dimmer.py @@ -1,27 +1,10 @@ """Quirk for GLEDOPTO GL-SD-* dimmers.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomCluster, CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - Groups, - Identify, - LevelControl, - OnOff, - Ota, - Scenes, -) -from zigpy.zcl.clusters.lightlink import LightLink +from zigpy.quirks import CustomCluster +from zigpy.quirks.v2 import QuirkBuilder +from zigpy.zcl.clusters.general import LevelControl from zhaquirks import NoReplyMixin -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) class LevelControlNoReply(NoReplyMixin, CustomCluster, LevelControl): @@ -30,48 +13,9 @@ class LevelControlNoReply(NoReplyMixin, CustomCluster, LevelControl): void_input_commands = {cmd.id for cmd in LevelControl.commands_by_name.values()} -class GledoptoGlSdDimmer(CustomDevice): - """Gledopto GL-SD-001 & GL-SD-003P dimmer custom device implementation.""" - - signature = { - MODELS_INFO: [("GLEDOPTO", "GL-SD-001"), ("GLEDOPTO", "GL-SD-003P")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.DIMMABLE_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - LightLink.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Ota.cluster_id, - ], - }, - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.DIMMABLE_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControlNoReply, - LightLink.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Ota.cluster_id, - ], - }, - }, - } +( + QuirkBuilder("GLEDOPTO", "GL-SD-001") + .applies_to("GLEDOPTO", "GL-SD-003P") + .replaces(LevelControlNoReply, endpoint_id=1) + .add_to_registry() +) diff --git a/zhaquirks/gledopto/soposhgu10.py b/zhaquirks/gledopto/soposhgu10.py index 249e3d2902..8d73df61e9 100644 --- a/zhaquirks/gledopto/soposhgu10.py +++ b/zhaquirks/gledopto/soposhgu10.py @@ -1,71 +1,17 @@ """GLEDOPTO Soposh Dual White and color 5W GU10 300lm device.""" -from zigpy.profiles import zll -from zigpy.profiles.zll import DeviceType -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - Groups, - Identify, - LevelControl, - OnOff, - Scenes, -) -from zigpy.zcl.clusters.lighting import Color -from zigpy.zcl.clusters.lightlink import LightLink - -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - OUTPUT_CLUSTERS, - PROFILE_ID, -) +from zigpy.quirks.v2 import QuirkBuilder +# Note: This quirk is incomplete and non-functional +# It has no MODELS_INFO so it won't match any devices +# The only operation it performed was removing endpoint 13 from the signature +# In v2, not mentioning an endpoint effectively removes it from configuration +# However, without manufacturer/model info, this quirk cannot be properly migrated +# TODO: Add proper MODELS_INFO when device details are known -class SoposhGU10(CustomDevice): - """GLEDOPTO Soposh Dual White and color 5W GU10 300lm.""" - - signature = { - ENDPOINTS: { - 11: { - PROFILE_ID: zll.PROFILE_ID, - DEVICE_TYPE: DeviceType.EXTENDED_COLOR_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Color.cluster_id, - ], - OUTPUT_CLUSTERS: [], - }, - 13: { - PROFILE_ID: zll.PROFILE_ID, - DEVICE_TYPE: DeviceType.EXTENDED_COLOR_LIGHT, - INPUT_CLUSTERS: [LightLink.cluster_id], - OUTPUT_CLUSTERS: [LightLink.cluster_id], - }, - } - } - - replacement = { - ENDPOINTS: { - 11: { - PROFILE_ID: zll.PROFILE_ID, - DEVICE_TYPE: DeviceType.EXTENDED_COLOR_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Color.cluster_id, - ], - OUTPUT_CLUSTERS: [], - } - } - } +# Placeholder - will not match any devices +( + QuirkBuilder("UNKNOWN_MANUFACTURER", "UNKNOWN_MODEL") + .skip_configuration() + .add_to_registry() +) diff --git a/zhaquirks/heiman/smoke.py b/zhaquirks/heiman/smoke.py index a73d513b57..b007fee557 100644 --- a/zhaquirks/heiman/smoke.py +++ b/zhaquirks/heiman/smoke.py @@ -1,355 +1,62 @@ """Smoke Sensor.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Alarms, - Basic, - Identify, - Ota, - PollControl, - PowerConfiguration, -) -from zigpy.zcl.clusters.homeautomation import Diagnostic -from zigpy.zcl.clusters.security import IasWd, IasZone -import zigpy.zdo.types - -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - NODE_DESCRIPTOR, - OUTPUT_CLUSTERS, - PROFILE_ID, +from zigpy.quirks.v2 import QuirkBuilder +from zigpy.zcl.clusters.security import IasWd +from zigpy.zdo.types import LogicalType, NodeDescriptor + +( + QuirkBuilder("HEIMAN", "CO_V15") + .applies_to("HEIMAN", "SMOK_YDLV10") + .node_descriptor( + NodeDescriptor( + logical_type=LogicalType.EndDevice, + complex_descriptor_available=False, + user_descriptor_available=False, + aps_flags=0, + frequency_band=NodeDescriptor.FrequencyBand.Freq2400MHz, + mac_capability_flags=NodeDescriptor.MACCapabilityFlags.AllocateAddress, # Clears MACCapabilityFlags.MainsPowered + manufacturer_code=48042, + maximum_buffer_size=64, + maximum_incoming_transfer_size=0x0000, + server_mask=0x0000, + maximum_outgoing_transfer_size=0x0000, + descriptor_capability_field=( + NodeDescriptor.DescriptorCapability.ExtendedActiveEndpointListAvailable + | NodeDescriptor.DescriptorCapability.ExtendedSimpleDescriptorListAvailable + ), + ) + ) + .add_to_registry() ) -from zhaquirks.heiman import HEIMAN - - -class HeimanSmokYDLV10(CustomDevice): - """YDLV10 quirk.""" - - # NodeDescriptor(byte1=2, byte2=64, mac_capability_flags=132, - # manufacturer_code=48042, maximum_buffer_size=64, maximum_incoming_transfer_size=0, - # server_mask=0, maximum_outgoing_transfer_size=0, descriptor_capability_field=3) - # SizePrefixedSimpleDescriptor(endpoint=1, profile=260, device_type=1026, - # device_version=0, input_clusters=[0, 3, 1280, 1, 9, 1282], output_clusters=[25]) - signature = { - MODELS_INFO: [(HEIMAN, "SMOK_YDLV10")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - Alarms.cluster_id, - IasZone.cluster_id, - IasWd.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Ota.cluster_id, - ], - }, - }, - } - - replacement = { - NODE_DESCRIPTOR: zigpy.zdo.types.NodeDescriptor( - 0x02, 0x40, 0x84 & 0b1111_1011, 0xBBAA, 0x40, 0x0000, 0x0000, 0x0000, 0x03 - ), - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - Alarms.cluster_id, - IasZone.cluster_id, - IasWd.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Ota.cluster_id, - ], - }, - }, - } - - -class HeimanSmokCO_V15(CustomDevice): - """CO_V15 quirk.""" - - # NodeDescriptor( - # logical_type=, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, - # frequency_band=, mac_capability_flags=, - # manufacturer_code=48042, maximum_buffer_size=64, maximum_incoming_transfer_size=0, server_mask=0, maximum_outgoing_transfer_size=0, - # descriptor_capability_field=, - # *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=True, *is_full_function_device=False, - # *is_mains_powered=True, *is_receiver_on_when_idle=False, *is_router=False, *is_security_capable=False - # )" - signature = { - MODELS_INFO: [(HEIMAN, "CO_V15")], - ENDPOINTS: { - # "profile_id": 260,"device_type": "0x0402", - # "in_clusters": ["0x0000","0x0001","0x0003","0x0009","0x0500"], - # "out_clusters": ["0x0019"] - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - Alarms.cluster_id, - IasZone.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Ota.cluster_id, - ], - }, - }, - } - - replacement = { - NODE_DESCRIPTOR: zigpy.zdo.types.NodeDescriptor( - 0x02, 0x40, 0x84 & 0b1111_1011, 0xBBAA, 0x40, 0x0000, 0x0000, 0x0000, 0x03 - ), - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - Alarms.cluster_id, - IasZone.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Ota.cluster_id, - ], - }, - }, - } - - -class HeimanSmokCO_CTPG(CustomDevice): - """CO_CTPG quirk.""" - signature = { - MODELS_INFO: [(HEIMAN, "CO_CTPG")], - ENDPOINTS: { - 1: { - # "profile_id": 260, - # "device_type": "0x0402", - # "in_clusters": ["0x0000","0x0001","0x0003","0x0009","0x0500"] - # "out_clusters": ["0x0019"] - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - Alarms.cluster_id, - IasZone.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Ota.cluster_id, - ], - }, - }, - } - - replacement = { - NODE_DESCRIPTOR: zigpy.zdo.types.NodeDescriptor( - logical_type=2, - complex_descriptor_available=0, - user_descriptor_available=0, - reserved=0, +( + QuirkBuilder("HEIMAN", "CO_CTPG") + .node_descriptor( + NodeDescriptor( + logical_type=LogicalType.EndDevice, + complex_descriptor_available=False, + user_descriptor_available=False, aps_flags=0, - frequency_band=8, - mac_capability_flags=132 & 0b1111_1011, + frequency_band=NodeDescriptor.FrequencyBand.Freq2400MHz, + mac_capability_flags=NodeDescriptor.MACCapabilityFlags.AllocateAddress, # Clears MACCapabilityFlags.MainsPowered manufacturer_code=4627, maximum_buffer_size=64, maximum_incoming_transfer_size=0, server_mask=0, maximum_outgoing_transfer_size=0, - descriptor_capability_field=3, - ), - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - Alarms.cluster_id, - IasZone.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Ota.cluster_id, - ], - }, - }, - } - - -class HeimanSmokeN30(CustomDevice): - """SmokeN30 quirk.""" - - # NodeDescriptor( - # logical_type=, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, - # frequency_band=, mac_capability_flags=, - # manufacturer_code=4619, maximum_buffer_size=127, maximum_incoming_transfer_size=100, server_mask=11264, maximum_outgoing_transfer_size=100, - # descriptor_capability_field=, - # *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=True, *is_full_function_device=False, - # *is_mains_powered=False, *is_receiver_on_when_idle=False, *is_router=False, *is_security_capable=False) - signature = { - MODELS_INFO: [("HEIMAN", "SmokeSensor-N-3.0")], - ENDPOINTS: { - # "profile_id": 260,"device_type": "0x0402", - # "in_clusters": ["0x0000","0x0001","0x0003","0x0500","0x0502","0x0b05"], - # "out_clusters": ["0x0019"] - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - IasZone.cluster_id, - IasWd.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Ota.cluster_id, - ], - }, - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - IasZone.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Ota.cluster_id, - ], - }, - }, - } - - -class HeimanSmokeEF30(CustomDevice): - """SmokeEF30 quirk.""" - - # NodeDescriptor( - # logical_type=, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, - # frequency_band=, mac_capability_flags=, - # manufacturer_code=4619, maximum_buffer_size=82, maximum_incoming_transfer_size=82, server_mask=11264, maximum_outgoing_transfer_size=82, - # descriptor_capability_field=, - # *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=True, *is_full_function_device=False, - # *is_mains_powered=False, *is_receiver_on_when_idle=False, *is_router=False, *is_security_capable=False) - signature = { - MODELS_INFO: [("HEIMAN", "SmokeSensor-EF-3.0")], - ENDPOINTS: { - # "profile_id": "0x0104", "device_type": "0x0402", - # "input_clusters": ["0x0000", "0x0001", "0x0003", "0x0020", "0x0500", "0x0502", "0x0b05"], - # "output_clusters": ["0x0003", "0x0019"] - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - IasZone.cluster_id, - IasWd.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Ota.cluster_id, - ], - }, - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - IasZone.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Ota.cluster_id, - ], - }, - }, - } - - -class HeimanSmokeEM(CustomDevice): - """SmokeEM quirk.""" - - signature = { - MODELS_INFO: [("HEIMAN", "SmokeSensor-EM")], - ENDPOINTS: { - # "profile_id": "0x0104", "device_type": "0x0402", - # "input_clusters": ["0x0000", "0x0001", "0x0003", "0x0500", "0x0502"], - # "output_clusters": ["0x0019"] - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - IasZone.cluster_id, - IasWd.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Ota.cluster_id, - ], - }, - }, - } + descriptor_capability_field=( + NodeDescriptor.DescriptorCapability.ExtendedActiveEndpointListAvailable + | NodeDescriptor.DescriptorCapability.ExtendedSimpleDescriptorListAvailable + ), + ) + ) + .add_to_registry() +) - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - IasZone.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Ota.cluster_id, - ], - }, - }, - } +( + QuirkBuilder("HEIMAN", "SmokeSensor-N-3.0") + .applies_to("HEIMAN", "SmokeSensor-EF-3.0") + .applies_to("HEIMAN", "SmokeSensor-EM") + .removes(IasWd, endpoint_id=1) + .add_to_registry() +) diff --git a/zhaquirks/hivehome/mot003V0.py b/zhaquirks/hivehome/mot003V0.py index 795c7c23b7..c0091ef450 100644 --- a/zhaquirks/hivehome/mot003V0.py +++ b/zhaquirks/hivehome/mot003V0.py @@ -1,68 +1,12 @@ """Device handler for hivehome.com MOT003 sensors.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - Identify, - Ota, - PollControl, - PowerConfiguration, -) -from zigpy.zcl.clusters.measurement import OccupancySensing, TemperatureMeasurement +from zigpy.quirks.v2 import QuirkBuilder from zigpy.zcl.clusters.security import IasZone -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.hivehome import HIVEHOME, MotionCluster - -class MOT003(CustomDevice): - """hivehome.com MOT003.""" - - signature = { - # - MODELS_INFO: [(HIVEHOME, "MOT003")], - ENDPOINTS: { - 6: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - OccupancySensing.cluster_id, - IasZone.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - }, - } - - replacement = { - ENDPOINTS: { - 6: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - OccupancySensing.cluster_id, - MotionCluster, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - } - } +( + QuirkBuilder(HIVEHOME, "MOT003") + .replaces(MotionCluster, IasZone.cluster_id, endpoint_id=6) + .add_to_registry() +) diff --git a/zhaquirks/hivehome/mot003V6.py b/zhaquirks/hivehome/mot003V6.py index cc4c839b0a..2fdb4d13f0 100644 --- a/zhaquirks/hivehome/mot003V6.py +++ b/zhaquirks/hivehome/mot003V6.py @@ -1,71 +1,11 @@ """Device handler for hivehome.com MOT003 sensors.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - Identify, - Ota, - PollControl, - PowerConfiguration, -) -from zigpy.zcl.clusters.measurement import ( - IlluminanceMeasurement, - TemperatureMeasurement, -) -from zigpy.zcl.clusters.security import IasZone +from zigpy.quirks.v2 import QuirkBuilder -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.hivehome import HIVEHOME, MotionCluster - -class MOT003(CustomDevice): - """hivehome.com MOT003.""" - - signature = { - # - MODELS_INFO: [(HIVEHOME, "MOT003")], - ENDPOINTS: { - 6: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - IlluminanceMeasurement.cluster_id, - IasZone.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - }, - } - - replacement = { - ENDPOINTS: { - 6: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - IlluminanceMeasurement.cluster_id, - MotionCluster, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - } - } +( + QuirkBuilder(HIVEHOME, "MOT003") + .replaces(MotionCluster, endpoint_id=6) + .add_to_registry() +) diff --git a/zhaquirks/hzc/dimmerswitch.py b/zhaquirks/hzc/dimmerswitch.py index b09fe80ae6..6bfaeace0a 100644 --- a/zhaquirks/hzc/dimmerswitch.py +++ b/zhaquirks/hzc/dimmerswitch.py @@ -1,29 +1,10 @@ """Quirk for HZC Dimmer-Switch-ZB3.0 (e.g. D688-ZG).""" -from zigpy.profiles import zgp, zha -from zigpy.quirks import CustomCluster, CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - GreenPowerProxy, - Groups, - Identify, - LevelControl, - OnOff, - Ota, - Scenes, -) -from zigpy.zcl.clusters.homeautomation import Diagnostic -from zigpy.zcl.clusters.lightlink import LightLink +from zigpy.quirks import CustomCluster +from zigpy.quirks.v2 import QuirkBuilder +from zigpy.zcl.clusters.general import OnOff from zhaquirks import NoReplyMixin -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) class HzcOnOff(NoReplyMixin, CustomCluster, OnOff): @@ -32,68 +13,9 @@ class HzcOnOff(NoReplyMixin, CustomCluster, OnOff): void_input_commands = {cmd.id for cmd in OnOff.commands_by_name.values()} -class DimmerSwitch(CustomDevice): - """Dimmer-Switch-ZB3.0 by HZC / Shyugj.""" - - signature = { - MODELS_INFO: [ - ("HZC", "Dimmer-Switch-ZB3.0"), - ("Shyugj", "Dimmer-Switch-ZB3.0"), - ], - ENDPOINTS: { - 1: { - # - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.DIMMABLE_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Diagnostic.cluster_id, - LightLink.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - }, - 242: { - # - MODELS_INFO: [ - (IKEA, "FYRTUR block-out roller blind"), - (IKEA, "KADRILJ roller blind"), - (IKEA, "TREDANSEN block-out cellul blind"), - (IKEA, "PRAKTLYSING cellular blind"), - ], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.WINDOW_COVERING_DEVICE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - PollControl.cluster_id, - WindowCovering.cluster_id, - LightLink.cluster_id, - IKEA_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id, LightLink.cluster_id], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.WINDOW_COVERING_DEVICE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - DoublingPowerConfigClusterIKEA, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - PollControl.cluster_id, - WindowCovering.cluster_id, - LightLink.cluster_id, - IKEA_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id, LightLink.cluster_id], - } - } - } - - -class IkeaTradfriRollerBlinds2(CustomDevice): - """Custom device representing IKEA of Sweden TRADFRI Fyrtur blinds.""" - - signature = { - # - MODELS_INFO: [ - (IKEA, "FYRTUR block-out roller blind"), - (IKEA, "KADRILJ roller blind"), - ], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.WINDOW_COVERING_DEVICE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - PollControl.cluster_id, - WindowCovering.cluster_id, - LightLink.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id, LightLink.cluster_id], - } - }, - } - - replacement = IkeaTradfriRollerBlinds.replacement diff --git a/zhaquirks/ikea/cctlightzha.py b/zhaquirks/ikea/cctlightzha.py index 57c75d4765..44fc95da0f 100644 --- a/zhaquirks/ikea/cctlightzha.py +++ b/zhaquirks/ikea/cctlightzha.py @@ -1,92 +1,15 @@ """Tradfri CCT light Quirk.""" -from zigpy.profiles import zha, zll -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - Groups, - Identify, - LevelControl, - OnOff, - Ota, - PollControl, - Scenes, -) -from zigpy.zcl.clusters.homeautomation import Diagnostic -from zigpy.zcl.clusters.lighting import Color -from zigpy.zcl.clusters.lightlink import LightLink +from zigpy.profiles import zha +from zigpy.quirks.v2 import QuirkBuilder -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.ikea import IKEA - -class CCTLightZHA(CustomDevice): - """TRADFRI CCT lights with ZHA profile but ZLL device type.""" - - signature = { - # - MODELS_INFO: [ - (IKEA, "TRADFRI bulb GU10 WS 400lm"), - (IKEA, "FLOALT panel WS 30x90"), - (IKEA, "FLOALT panel WS 60x60"), - ], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zll.DeviceType.COLOR_TEMPERATURE_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Color.cluster_id, - Diagnostic.cluster_id, - LightLink.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Scenes.cluster_id, - Ota.cluster_id, - PollControl.cluster_id, - LightLink.cluster_id, - ], - }, - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.COLOR_TEMPERATURE_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Color.cluster_id, - Diagnostic.cluster_id, - LightLink.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Scenes.cluster_id, - Ota.cluster_id, - PollControl.cluster_id, - LightLink.cluster_id, - ], - } - } - } +# TRADFRI CCT lights with ZHA profile but ZLL device type +( + QuirkBuilder(IKEA, "TRADFRI bulb GU10 WS 400lm") + .applies_to(IKEA, "FLOALT panel WS 30x90") + .applies_to(IKEA, "FLOALT panel WS 60x60") + .replaces_endpoint(1, device_type=zha.DeviceType.COLOR_TEMPERATURE_LIGHT) + .add_to_registry() +) diff --git a/zhaquirks/ikea/dimmer.py b/zhaquirks/ikea/dimmer.py index 695fa63927..8143d96d16 100644 --- a/zhaquirks/ikea/dimmer.py +++ b/zhaquirks/ikea/dimmer.py @@ -1,106 +1,43 @@ """Device handler for IKEA of Sweden TRADFRI wireless dimmer ICTC-G-1.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - Groups, - Identify, - LevelControl, - OnOff, - Ota, - PollControl, - PowerConfiguration, -) -from zigpy.zcl.clusters.lightlink import LightLink +from zigpy.quirks.v2 import QuirkBuilder +from zigpy.zcl.clusters.general import PowerConfiguration from zhaquirks.const import ( CLUSTER_ID, COMMAND, COMMAND_MOVE, COMMAND_MOVE_ON_OFF, - DEVICE_TYPE, ENDPOINT_ID, - ENDPOINTS, - INPUT_CLUSTERS, LEFT, - MODELS_INFO, - OUTPUT_CLUSTERS, PARAMS, - PROFILE_ID, RIGHT, ROTATED, ) from zhaquirks.ikea import IKEA, DoublingPowerConfig1CRXCluster - -class IkeaDimmer(CustomDevice): - """Custom device representing IKEA of Sweden TRADFRI wireless dimmer.""" - - signature = { - # - MODELS_INFO: [(IKEA, "TRADFRI remote control")], - ENDPOINTS: { - 1: { - PROFILE_ID: zll.PROFILE_ID, - DEVICE_TYPE: zll.DeviceType.SCENE_CONTROLLER, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - Alarms.cluster_id, - Diagnostic.cluster_id, - LightLink.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - LightLink.cluster_id, - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zll.PROFILE_ID, - DEVICE_TYPE: zll.DeviceType.SCENE_CONTROLLER, - INPUT_CLUSTERS: [ - Basic.cluster_id, - DoublingPowerConfig1CRCluster, - Identify.cluster_id, - Alarms.cluster_id, - Diagnostic.cluster_id, - LightLink.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - ScenesCluster, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - LightLink.cluster_id, - ], - } - } - } - - device_automation_triggers = { - (SHORT_PRESS, TURN_ON): { - COMMAND: COMMAND_TOGGLE, - CLUSTER_ID: 6, - ENDPOINT_ID: 1, - }, - (LONG_PRESS, TURN_ON): { - COMMAND: COMMAND_RELEASE, - CLUSTER_ID: 5, - ENDPOINT_ID: 1, - PARAMS: {"param1": 0}, - }, - (SHORT_PRESS, DIM_UP): { - COMMAND: COMMAND_STEP_ON_OFF, - CLUSTER_ID: 8, - ENDPOINT_ID: 1, - PARAMS: {"step_mode": 0}, - }, - (LONG_PRESS, DIM_UP): { - COMMAND: COMMAND_MOVE_ON_OFF, - CLUSTER_ID: 8, - ENDPOINT_ID: 1, - PARAMS: {"move_mode": 0}, - }, - (LONG_RELEASE, DIM_UP): { - COMMAND: COMMAND_STOP_ON_OFF, - CLUSTER_ID: 8, - ENDPOINT_ID: 1, - }, - (SHORT_PRESS, DIM_DOWN): { - COMMAND: COMMAND_STEP, - CLUSTER_ID: 8, - ENDPOINT_ID: 1, - PARAMS: {"step_mode": 1}, - }, - (LONG_PRESS, DIM_DOWN): { - COMMAND: COMMAND_MOVE, - CLUSTER_ID: 8, - ENDPOINT_ID: 1, - PARAMS: {"move_mode": 1}, - }, - (LONG_RELEASE, DIM_DOWN): { - COMMAND: COMMAND_STOP, - CLUSTER_ID: 8, - ENDPOINT_ID: 1, - }, - (SHORT_PRESS, LEFT): { - COMMAND: COMMAND_PRESS, - CLUSTER_ID: 5, - ENDPOINT_ID: 1, - PARAMS: { - "param1": 257, - "param2": 13, - "param3": 0, - }, - }, - (LONG_PRESS, LEFT): { - COMMAND: COMMAND_HOLD, - CLUSTER_ID: 5, - ENDPOINT_ID: 1, - PARAMS: { - "param1": 3329, - "param2": 0, - }, - }, - (SHORT_PRESS, RIGHT): { - COMMAND: COMMAND_PRESS, - CLUSTER_ID: 5, - ENDPOINT_ID: 1, - PARAMS: { - "param1": 256, - "param2": 13, - "param3": 0, - }, - }, - (LONG_PRESS, RIGHT): { - COMMAND: COMMAND_HOLD, - CLUSTER_ID: 5, - ENDPOINT_ID: 1, - PARAMS: { - "param1": 3328, - "param2": 0, - }, - }, - } - - -class IkeaTradfriRemote2(IkeaTradfriRemote1): - """Custom device representing variation of IKEA five button remote.""" - - signature = { - # - MODELS_INFO: [(IKEA, "TRADFRI remote control")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.NON_COLOR_CONTROLLER, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - LightLink.cluster_id, - IKEA_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - LightLink.cluster_id, - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.NON_COLOR_CONTROLLER, - INPUT_CLUSTERS: [ - Basic.cluster_id, - DoublingPowerConfig1CRCluster, - Identify.cluster_id, - PollControl.cluster_id, - LightLink.cluster_id, - IKEA_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - ScenesCluster, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - LightLink.cluster_id, - ], - } - } - } - - -class IkeaTradfriRemote3(IkeaTradfriRemote1): - """Custom device representing variation of IKEA five button remote.""" - - signature = { - # - MODELS_INFO: [(IKEA, "TRADFRI remote control")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.COLOR_SCENE_CONTROLLER, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - Alarms.cluster_id, - Diagnostic.cluster_id, - LightLink.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - ScenesCluster.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - LightLink.cluster_id, - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.COLOR_SCENE_CONTROLLER, - INPUT_CLUSTERS: [ - Basic.cluster_id, - DoublingPowerConfig1CRCluster, - Identify.cluster_id, - Alarms.cluster_id, - LightLink.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - ScenesCluster, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - LightLink.cluster_id, - ], - } - } - } - - -class IkeaTradfriRemote4(IkeaTradfriRemote1): - """Custom device representing variation of IKEA five button remote.""" - - signature = { - # - MODELS_INFO: [(IKEA, "TRADFRI remote control")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.NON_COLOR_CONTROLLER, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - LightLink.cluster_id, - IKEA_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - ScenesCluster.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - LightLink.cluster_id, - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.NON_COLOR_CONTROLLER, - INPUT_CLUSTERS: [ - Basic.cluster_id, - DoublingPowerConfig1CRCluster, - Identify.cluster_id, - PollControl.cluster_id, - LightLink.cluster_id, - IKEA_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - ScenesCluster, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - LightLink.cluster_id, - ], - } - } - } - - -class IkeaTradfriRemote5(IkeaTradfriRemote1): - """Custom device representing variation of IKEA five button remote.""" - - signature = { - # - MODELS_INFO: [(IKEA, "TRADFRI remote control")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.NON_COLOR_CONTROLLER, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - LightLink.cluster_id, - WWAH_CLUSTER_ID, - IKEA_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - ScenesCluster.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - LightLink.cluster_id, - ], - } - }, - } - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.NON_COLOR_CONTROLLER, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfig1CRCluster, - Identify.cluster_id, - PollControl.cluster_id, - LightLink.cluster_id, - WWAH_CLUSTER_ID, - IKEA_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - ScenesCluster, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - LightLink.cluster_id, - ], - } - } - } +( + QuirkBuilder(IKEA, "TRADFRI remote control") + # TODO: use firmware version filters to identify exactly when this changed + .filter(lambda device: WWAH_CLUSTER_ID in device.endpoints[1].in_clusters) + .replaces(PowerConfig1CRCluster, endpoint_id=1) + .replaces(ScenesCluster, cluster_type=ClusterType.Client, endpoint_id=1) + .device_automation_triggers(DEVICE_AUTOMATION_TRIGGERS) + .add_to_registry() +) diff --git a/zhaquirks/ikea/motion.py b/zhaquirks/ikea/motion.py index d7b4e65762..cb3d71d669 100644 --- a/zhaquirks/ikea/motion.py +++ b/zhaquirks/ikea/motion.py @@ -1,82 +1,14 @@ """Device handler for IKEA of Sweden TRADFRI remote control.""" -from zigpy.profiles import zll -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Alarms, - Basic, - Groups, - Identify, - OnOff, - Ota, - PowerConfiguration, -) -from zigpy.zcl.clusters.homeautomation import Diagnostic -from zigpy.zcl.clusters.lightlink import LightLink +from zigpy.quirks.v2 import QuirkBuilder +from zigpy.zcl.clusters.general import PowerConfiguration -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.ikea import IKEA, DoublingPowerConfig2CRCluster - -class IkeaTradfriMotion(CustomDevice): - """Custom device representing IKEA of Sweden TRADFRI remote control.""" - - signature = { - # - MODELS_INFO: [(IKEA, "TRADFRI motion sensor")], - ENDPOINTS: { - 1: { - PROFILE_ID: zll.PROFILE_ID, - DEVICE_TYPE: zll.DeviceType.ON_OFF_SENSOR, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - Alarms.cluster_id, - Diagnostic.cluster_id, - LightLink.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - Ota.cluster_id, - LightLink.cluster_id, - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zll.PROFILE_ID, - DEVICE_TYPE: zll.DeviceType.ON_OFF_SENSOR, - INPUT_CLUSTERS: [ - Basic.cluster_id, - DoublingPowerConfig2CRCluster, - Identify.cluster_id, - Alarms.cluster_id, - Diagnostic.cluster_id, - LightLink.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - Ota.cluster_id, - LightLink.cluster_id, - ], - } - } - } +( + QuirkBuilder(IKEA, "TRADFRI motion sensor") + .replaces( + DoublingPowerConfig2CRCluster, PowerConfiguration.cluster_id, endpoint_id=1 + ) + .add_to_registry() +) diff --git a/zhaquirks/ikea/motionzha.py b/zhaquirks/ikea/motionzha.py index e714e4b26f..682e336a88 100644 --- a/zhaquirks/ikea/motionzha.py +++ b/zhaquirks/ikea/motionzha.py @@ -1,209 +1,12 @@ """Device handler for IKEA of Sweden TRADFRI remote control.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Alarms, - Basic, - Groups, - Identify, - LevelControl, - OnOff, - Ota, - PollControl, - PowerConfiguration, -) -from zigpy.zcl.clusters.homeautomation import Diagnostic -from zigpy.zcl.clusters.lightlink import LightLink - -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) -from zhaquirks.ikea import ( - IKEA, - IKEA_CLUSTER_ID, - WWAH_CLUSTER_ID, - DoublingPowerConfig2CRCluster, -) - - -class IkeaTradfriMotionE1745_Var01(CustomDevice): - """Custom device representing IKEA of Sweden TRADFRI motion sensor E1745 second gen variation 1.""" - - signature = { - # - MODELS_INFO: [(IKEA, "TRADFRI motion sensor")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.ON_OFF_SENSOR, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - Alarms.cluster_id, - Diagnostic.cluster_id, - LightLink.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - Ota.cluster_id, - LightLink.cluster_id, - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.ON_OFF_SENSOR, - INPUT_CLUSTERS: [ - Basic.cluster_id, - DoublingPowerConfig2CRCluster, - Identify.cluster_id, - Alarms.cluster_id, - Diagnostic.cluster_id, - LightLink.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - Ota.cluster_id, - LightLink.cluster_id, - ], - } - } - } +from zigpy.quirks.v2 import QuirkBuilder +from zhaquirks.ikea import IKEA, DoublingPowerConfig2CRCluster -class IkeaTradfriMotionE1745_Var02(CustomDevice): - """Custom device representing IKEA of Sweden TRADFRI motion sensor E1745 second gen variation 2.""" - - signature = { - # - MODELS_INFO: [(IKEA, "TRADFRI motion sensor")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.ON_OFF_SENSOR, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - Alarms.cluster_id, - PollControl.cluster_id, - LightLink.cluster_id, - IKEA_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - LightLink.cluster_id, - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.ON_OFF_SENSOR, - INPUT_CLUSTERS: [ - Basic.cluster_id, - DoublingPowerConfig2CRCluster, - Identify.cluster_id, - Alarms.cluster_id, - PollControl.cluster_id, - LightLink.cluster_id, - IKEA_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - LightLink.cluster_id, - ], - } - } - } - - -class IkeaTradfriMotionE1525_Var01(CustomDevice): - """Custom device representing IKEA of Sweden TRADFRI motion sensor E1525 first gen variation 1.""" - - signature = { - # - MODELS_INFO: [(IKEA, "TRADFRI motion sensor")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.ON_OFF_SENSOR, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - LightLink.cluster_id, - IKEA_CLUSTER_ID, - WWAH_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - Ota.cluster_id, - LightLink.cluster_id, - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.ON_OFF_SENSOR, - INPUT_CLUSTERS: [ - Basic.cluster_id, - DoublingPowerConfig2CRCluster, - Identify.cluster_id, - PollControl.cluster_id, - LightLink.cluster_id, - IKEA_CLUSTER_ID, - WWAH_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - Ota.cluster_id, - LightLink.cluster_id, - ], - } - } - } +# V2 quirks +( + QuirkBuilder(IKEA, "TRADFRI motion sensor") + .replaces(DoublingPowerConfig2CRCluster, endpoint_id=1) + .add_to_registry() +) diff --git a/zhaquirks/ikea/opencloseremote.py b/zhaquirks/ikea/opencloseremote.py index 520ae79ec5..f883dd296d 100644 --- a/zhaquirks/ikea/opencloseremote.py +++ b/zhaquirks/ikea/opencloseremote.py @@ -2,41 +2,24 @@ from typing import Any, Optional, Union -from zigpy.profiles import zha -from zigpy.quirks import CustomCluster, CustomDevice +from zigpy.quirks import CustomCluster +from zigpy.quirks.v2 import QuirkBuilder import zigpy.types as t -from zigpy.zcl import foundation +from zigpy.zcl import ClusterType, foundation from zigpy.zcl.clusters.closures import WindowCovering -from zigpy.zcl.clusters.general import ( - Alarms, - Basic, - Groups, - Identify, - LevelControl, - OnOff, - Ota, - PollControl, - PowerConfiguration, -) -from zigpy.zcl.clusters.lightlink import LightLink +from zigpy.zcl.clusters.general import OnOff from zhaquirks.const import ( ARGS, CLOSE, COMMAND, COMMAND_STOP, - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, LONG_RELEASE, - MODELS_INFO, OPEN, - OUTPUT_CLUSTERS, - PROFILE_ID, SHORT_PRESS, ZHA_SEND_EVENT, ) -from zhaquirks.ikea import IKEA, IKEA_CLUSTER_ID, DoublingPowerConfig1CRCluster +from zhaquirks.ikea import IKEA, DoublingPowerConfig1CRCluster COMMAND_CLOSE = "down_close" COMMAND_STOP_OPENING = "stop_opening" @@ -76,73 +59,19 @@ def handle_cluster_request( self.listener_event(ZHA_SEND_EVENT, action, []) -class IkeaTradfriOpenCloseRemote(CustomDevice): - """Custom device representing IKEA of Sweden TRADFRI remote control.""" - - signature = { - # - MODELS_INFO: [ - ("\x02KE", "TRADFRI open/close remote"), - (IKEA, "TRADFRI open/close remote"), - ], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.WINDOW_COVERING_CONTROLLER, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - Alarms.cluster_id, - PollControl.cluster_id, - LightLink.cluster_id, - IKEA_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - WindowCovering.cluster_id, - LightLink.cluster_id, - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.WINDOW_COVERING_CONTROLLER, - INPUT_CLUSTERS: [ - Basic.cluster_id, - DoublingPowerConfig1CRCluster, - Identify.cluster_id, - Alarms.cluster_id, - PollControl.cluster_id, - LightLink.cluster_id, - IKEA_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - IkeaWindowCovering, - LightLink.cluster_id, - ], - } - }, - } - - device_automation_triggers = { - (SHORT_PRESS, OPEN): {COMMAND: COMMAND_OPEN, ARGS: []}, - (LONG_RELEASE, OPEN): {COMMAND: COMMAND_STOP_OPENING, ARGS: []}, - (SHORT_PRESS, CLOSE): {COMMAND: COMMAND_CLOSE, ARGS: []}, - (LONG_RELEASE, CLOSE): {COMMAND: COMMAND_STOP_CLOSING, ARGS: []}, - } +( + QuirkBuilder("\x02KE", "TRADFRI open/close remote") + .applies_to(IKEA, "TRADFRI open/close remote") + .replaces(DoublingPowerConfig1CRCluster, endpoint_id=1) + .removes(OnOff.cluster_id, cluster_type=ClusterType.Client, endpoint_id=1) + .adds(IkeaWindowCovering, cluster_type=ClusterType.Client, endpoint_id=1) + .device_automation_triggers( + { + (SHORT_PRESS, OPEN): {COMMAND: COMMAND_OPEN, ARGS: []}, + (LONG_RELEASE, OPEN): {COMMAND: COMMAND_STOP_OPENING, ARGS: []}, + (SHORT_PRESS, CLOSE): {COMMAND: COMMAND_CLOSE, ARGS: []}, + (LONG_RELEASE, CLOSE): {COMMAND: COMMAND_STOP_CLOSING, ARGS: []}, + } + ) + .add_to_registry() +) diff --git a/zhaquirks/ikea/shortcutbtn.py b/zhaquirks/ikea/shortcutbtn.py index 576de89d58..f1f0be3144 100644 --- a/zhaquirks/ikea/shortcutbtn.py +++ b/zhaquirks/ikea/shortcutbtn.py @@ -1,20 +1,6 @@ """Device handler for IKEA of Sweden TRADFRI shortcut button.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.closures import WindowCovering -from zigpy.zcl.clusters.general import ( - Alarms, - Basic, - Groups, - Identify, - LevelControl, - OnOff, - Ota, - PollControl, - PowerConfiguration, -) -from zigpy.zcl.clusters.lightlink import LightLink +from zigpy.quirks.v2 import QuirkBuilder from zhaquirks.const import ( CLUSTER_ID, @@ -23,172 +9,44 @@ COMMAND_OFF, COMMAND_ON, COMMAND_STOP_ON_OFF, - DEVICE_TYPE, DIM_UP, DOUBLE_PRESS, ENDPOINT_ID, - ENDPOINTS, - INPUT_CLUSTERS, LONG_PRESS, LONG_RELEASE, - MODELS_INFO, - OUTPUT_CLUSTERS, PARAMS, - PROFILE_ID, SHORT_PRESS, TURN_ON, ) -from zhaquirks.ikea import IKEA, IKEA_CLUSTER_ID, DoublingPowerConfig1CRCluster - - -class IkeaTradfriShortcutBtn(CustomDevice): - """Custom device representing IKEA of Sweden TRADFRI shortcut button.""" - - signature = { - # - MODELS_INFO: [(IKEA, "TRADFRI SHORTCUT Button")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.NON_COLOR_CONTROLLER, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - Alarms.cluster_id, - PollControl.cluster_id, - LightLink.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - WindowCovering.cluster_id, - LightLink.cluster_id, - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.NON_COLOR_CONTROLLER, - INPUT_CLUSTERS: [ - Basic.cluster_id, - DoublingPowerConfig1CRCluster, - Identify.cluster_id, - Alarms.cluster_id, - PollControl.cluster_id, - LightLink.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - WindowCovering.cluster_id, - LightLink.cluster_id, - ], - } +from zhaquirks.ikea import IKEA, DoublingPowerConfig1CRCluster + +( + QuirkBuilder(IKEA, "TRADFRI SHORTCUT Button") + .replaces(DoublingPowerConfig1CRCluster, endpoint_id=1) + .device_automation_triggers( + { + (SHORT_PRESS, TURN_ON): { + COMMAND: COMMAND_ON, + CLUSTER_ID: 6, + ENDPOINT_ID: 1, + }, + (DOUBLE_PRESS, TURN_ON): { + COMMAND: COMMAND_OFF, + CLUSTER_ID: 6, + ENDPOINT_ID: 1, + }, + (LONG_PRESS, DIM_UP): { + COMMAND: COMMAND_MOVE_ON_OFF, + CLUSTER_ID: 8, + ENDPOINT_ID: 1, + PARAMS: {"move_mode": 0}, + }, + (LONG_RELEASE, DIM_UP): { + COMMAND: COMMAND_STOP_ON_OFF, + CLUSTER_ID: 8, + ENDPOINT_ID: 1, + }, } - } - - device_automation_triggers = { - (SHORT_PRESS, TURN_ON): {COMMAND: COMMAND_ON, CLUSTER_ID: 6, ENDPOINT_ID: 1}, - (DOUBLE_PRESS, TURN_ON): {COMMAND: COMMAND_OFF, CLUSTER_ID: 6, ENDPOINT_ID: 1}, - (LONG_PRESS, DIM_UP): { - COMMAND: COMMAND_MOVE_ON_OFF, - CLUSTER_ID: 8, - ENDPOINT_ID: 1, - PARAMS: {"move_mode": 0}, - }, - (LONG_RELEASE, DIM_UP): { - COMMAND: COMMAND_STOP_ON_OFF, - CLUSTER_ID: 8, - ENDPOINT_ID: 1, - }, - } - - -class IkeaTradfriShortcutBtn2(CustomDevice): - """Custom device representing IKEA of Sweden TRADFRI shortcut button with IKEA cluster.""" - - signature = { - # - MODELS_INFO: [(IKEA, "TRADFRI SHORTCUT Button")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.NON_COLOR_CONTROLLER, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - Alarms.cluster_id, - PollControl.cluster_id, - LightLink.cluster_id, - IKEA_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - LightLink.cluster_id, - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.NON_COLOR_CONTROLLER, - INPUT_CLUSTERS: [ - Basic.cluster_id, - DoublingPowerConfig1CRCluster, - Identify.cluster_id, - Alarms.cluster_id, - PollControl.cluster_id, - LightLink.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - LightLink.cluster_id, - ], - } - } - } - - device_automation_triggers = { - (SHORT_PRESS, TURN_ON): {COMMAND: COMMAND_ON, CLUSTER_ID: 6, ENDPOINT_ID: 1}, - (DOUBLE_PRESS, TURN_ON): {COMMAND: COMMAND_OFF, CLUSTER_ID: 6, ENDPOINT_ID: 1}, - (LONG_PRESS, DIM_UP): { - COMMAND: COMMAND_MOVE_ON_OFF, - CLUSTER_ID: 8, - ENDPOINT_ID: 1, - PARAMS: {"move_mode": 0}, - }, - (LONG_RELEASE, DIM_UP): { - COMMAND: COMMAND_STOP_ON_OFF, - CLUSTER_ID: 8, - ENDPOINT_ID: 1, - }, - } + ) + .add_to_registry() +) diff --git a/zhaquirks/ikea/somrigsmartbtn.py b/zhaquirks/ikea/somrigsmartbtn.py index 39ae9dc79a..98d290f763 100644 --- a/zhaquirks/ikea/somrigsmartbtn.py +++ b/zhaquirks/ikea/somrigsmartbtn.py @@ -1,18 +1,8 @@ """Device handler for IKEA of Sweden SOMRIG shortcut button.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - Groups, - Identify, - LevelControl, - OnOff, - Ota, - PollControl, - PowerConfiguration, -) -from zigpy.zcl.clusters.lightlink import LightLink +from zigpy.quirks.v2 import QuirkBuilder +from zigpy.zcl import ClusterType +from zigpy.zcl.clusters.general import PowerConfiguration from zhaquirks.const import ( BUTTON_1, @@ -23,144 +13,41 @@ COMMAND_M_LONG_RELEASE, COMMAND_M_MULTI_PRESS_COMPLETE, COMMAND_M_SHORT_RELEASE, - DEVICE_TYPE, DOUBLE_PRESS, ENDPOINT_ID, - ENDPOINTS, - INPUT_CLUSTERS, LONG_PRESS, LONG_RELEASE, - MODELS_INFO, - OUTPUT_CLUSTERS, PRESSED, - PROFILE_ID, SHORT_PRESS, ) -from zhaquirks.ikea import ( - IKEA, - IKEA_CLUSTER_ID, - PowerConfig1AAACluster, - ShortcutV2Cluster, -) - +from zhaquirks.ikea import IKEA, PowerConfig1AAACluster, ShortcutV2Cluster -class IkeaSomrigSmartButton(CustomDevice): - """Custom device representing IKEA SOMRIG shortcut button.""" - - signature = { - # - MODELS_INFO: [(IKEA, "SOMRIG shortcut button")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.REMOTE_CONTROL, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - PollControl.cluster_id, - LightLink.cluster_id, - IKEA_CLUSTER_ID, - ShortcutV2Cluster.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - LightLink.cluster_id, - ShortcutV2Cluster.cluster_id, - ], +( + QuirkBuilder(IKEA, "SOMRIG shortcut button") + .replaces(PowerConfig1AAACluster, PowerConfiguration.cluster_id, endpoint_id=1) + .replaces(ShortcutV2Cluster, endpoint_id=1) + .replaces(ShortcutV2Cluster, endpoint_id=1, cluster_type=ClusterType.Client) + .replaces(ShortcutV2Cluster, endpoint_id=2) + .replaces(ShortcutV2Cluster, endpoint_id=2, cluster_type=ClusterType.Client) + .device_automation_triggers( + { + (PRESSED, BUTTON_1): {ENDPOINT_ID: 1, COMMAND: COMMAND_M_INITIAL_PRESS}, + (SHORT_PRESS, BUTTON_1): {ENDPOINT_ID: 1, COMMAND: COMMAND_M_SHORT_RELEASE}, + (DOUBLE_PRESS, BUTTON_1): { + ENDPOINT_ID: 1, + COMMAND: COMMAND_M_MULTI_PRESS_COMPLETE, }, - # - 2: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.REMOTE_CONTROL, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - ShortcutV2Cluster.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - ShortcutV2Cluster.cluster_id, - ], + (LONG_PRESS, BUTTON_1): {ENDPOINT_ID: 1, COMMAND: COMMAND_M_LONG_PRESS}, + (LONG_RELEASE, BUTTON_1): {ENDPOINT_ID: 1, COMMAND: COMMAND_M_LONG_RELEASE}, + (PRESSED, BUTTON_2): {ENDPOINT_ID: 2, COMMAND: COMMAND_M_INITIAL_PRESS}, + (SHORT_PRESS, BUTTON_2): {ENDPOINT_ID: 2, COMMAND: COMMAND_M_SHORT_RELEASE}, + (DOUBLE_PRESS, BUTTON_2): { + ENDPOINT_ID: 2, + COMMAND: COMMAND_M_MULTI_PRESS_COMPLETE, }, - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.REMOTE_CONTROL, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfig1AAACluster, - Identify.cluster_id, - Groups.cluster_id, - PollControl.cluster_id, - LightLink.cluster_id, - IKEA_CLUSTER_ID, - ShortcutV2Cluster, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - LightLink.cluster_id, - ShortcutV2Cluster, - ], - }, - 2: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.REMOTE_CONTROL, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - ShortcutV2Cluster, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - ShortcutV2Cluster, - ], - }, - }, - } - - device_automation_triggers = { - (PRESSED, BUTTON_1): {ENDPOINT_ID: 1, COMMAND: COMMAND_M_INITIAL_PRESS}, - (SHORT_PRESS, BUTTON_1): {ENDPOINT_ID: 1, COMMAND: COMMAND_M_SHORT_RELEASE}, - (DOUBLE_PRESS, BUTTON_1): { - ENDPOINT_ID: 1, - COMMAND: COMMAND_M_MULTI_PRESS_COMPLETE, - }, - (LONG_PRESS, BUTTON_1): {ENDPOINT_ID: 1, COMMAND: COMMAND_M_LONG_PRESS}, - (LONG_RELEASE, BUTTON_1): {ENDPOINT_ID: 1, COMMAND: COMMAND_M_LONG_RELEASE}, - (PRESSED, BUTTON_2): {ENDPOINT_ID: 2, COMMAND: COMMAND_M_INITIAL_PRESS}, - (SHORT_PRESS, BUTTON_2): {ENDPOINT_ID: 2, COMMAND: COMMAND_M_SHORT_RELEASE}, - (DOUBLE_PRESS, BUTTON_2): { - ENDPOINT_ID: 2, - COMMAND: COMMAND_M_MULTI_PRESS_COMPLETE, - }, - (LONG_PRESS, BUTTON_2): {ENDPOINT_ID: 2, COMMAND: COMMAND_M_LONG_PRESS}, - (LONG_RELEASE, BUTTON_2): {ENDPOINT_ID: 2, COMMAND: COMMAND_M_LONG_RELEASE}, - } + (LONG_PRESS, BUTTON_2): {ENDPOINT_ID: 2, COMMAND: COMMAND_M_LONG_PRESS}, + (LONG_RELEASE, BUTTON_2): {ENDPOINT_ID: 2, COMMAND: COMMAND_M_LONG_RELEASE}, + } + ) + .add_to_registry() +) diff --git a/zhaquirks/ikea/starkvind.py b/zhaquirks/ikea/starkvind.py index b3cc1105db..6aab1eada3 100644 --- a/zhaquirks/ikea/starkvind.py +++ b/zhaquirks/ikea/starkvind.py @@ -4,31 +4,16 @@ from typing import Any -from zigpy.profiles import zgp, zha -from zigpy.quirks import CustomCluster, CustomDevice +from zigpy.quirks import CustomCluster +from zigpy.quirks.v2 import CustomDeviceV2, QuirkBuilder import zigpy.types as t -from zigpy.zcl.clusters.general import ( - Basic, - GreenPowerProxy, - Groups, - Identify, - Ota, - Scenes, -) +from zigpy.zcl import ClusterType from zigpy.zcl.clusters.hvac import Fan -from zigpy.zcl.clusters.measurement import PM25, IlluminanceMeasurement +from zigpy.zcl.clusters.measurement import PM25 from zigpy.zcl.foundation import BaseAttributeDefs, ZCLAttributeDef from zhaquirks import Bus -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) -from zhaquirks.ikea import IKEA, IKEA_CLUSTER_ID, WWAH_CLUSTER_ID +from zhaquirks.ikea import IKEA class IkeaAirpurifier(CustomCluster): @@ -144,7 +129,7 @@ async def read_attributes( ) -class IkeaSTARKVIND(CustomDevice): +class IkeaSTARKVIND(CustomDeviceV2): """STARKVIND Air purifier by IKEA of Sweden.""" def __init__(self, *args, **kwargs): @@ -154,153 +139,14 @@ def __init__(self, *args, **kwargs): self.change_fan_mode_ha_bus = Bus() super().__init__(*args, **kwargs) - signature = { - # - MODELS_INFO: [ - (IKEA, "STARKVIND Air purifier"), - (IKEA, "STARKVIND Air purifier table"), - ], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.COMBINED_INTERFACE, - INPUT_CLUSTERS: [ - Basic.cluster_id, # 0 - Identify.cluster_id, # 3 - Groups.cluster_id, # 4 - Scenes.cluster_id, # 5 - Fan.cluster_id, # 514 0x0202 - WWAH_CLUSTER_ID, # 64599 0xFC57 - IkeaAirpurifier.cluster_id, # 64637 0xFC7D - ], - OUTPUT_CLUSTERS: [ - Ota.cluster_id, # 25 0x0019 - IlluminanceMeasurement.cluster_id, # 1024 0x0400 - PM25.cluster_id, # 1066 0x042A PM2.5 Measurement Cluster - ], - }, - # - 242: { - PROFILE_ID: zgp.PROFILE_ID, # 41440 (dec) - DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC, - INPUT_CLUSTERS: [], - OUTPUT_CLUSTERS: [ - GreenPowerProxy.cluster_id, # 0x0021 = GreenPowerProxy.cluster_id - ], - }, - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.COMBINED_INTERFACE, - INPUT_CLUSTERS: [ - Basic.cluster_id, # 0 - Identify.cluster_id, # 3 - Groups.cluster_id, # 4 - Scenes.cluster_id, # 5 - WWAH_CLUSTER_ID, # 64599 0xFC57 - IkeaAirpurifier, # 64637 0xFC7D control air purifier with manufacturer-specific attributes - PM25Cluster, # 1066 0x042A PM2.5 Measurement Cluster - ], - OUTPUT_CLUSTERS: [ - Ota.cluster_id, # 25 0x0019 - IlluminanceMeasurement.cluster_id, # 1024 0x0400 - ], - }, - # - 242: { - PROFILE_ID: zgp.PROFILE_ID, # 41440 (dec) - DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC, - INPUT_CLUSTERS: [], - OUTPUT_CLUSTERS: [ - GreenPowerProxy.cluster_id, # 0x0021 = GreenPowerProxy.cluster_id - ], - }, - }, - } - -class IkeaSTARKVIND_v2(IkeaSTARKVIND): - """STARKVIND Air purifier by IKEA of Sweden.""" - - signature = { - # - MODELS_INFO: IkeaSTARKVIND.signature[MODELS_INFO].copy(), - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.COMBINED_INTERFACE, - INPUT_CLUSTERS: [ - Basic.cluster_id, # 0 - Identify.cluster_id, # 3 - Groups.cluster_id, # 4 - Scenes.cluster_id, # 5 - Fan.cluster_id, # 514 0x0202 - WWAH_CLUSTER_ID, # 64599 0xFC57 - IKEA_CLUSTER_ID, # 64636 0xFC7C - IkeaAirpurifier.cluster_id, # 64637 0xFC7D - ], - OUTPUT_CLUSTERS: [ - Ota.cluster_id, # 25 0x0019 - IlluminanceMeasurement.cluster_id, # 1024 0x0400 - PM25.cluster_id, # 1066 0x042A PM2.5 Measurement Cluster - ], - }, - # - 242: { - PROFILE_ID: zgp.PROFILE_ID, # 41440 (dec) - DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC, - INPUT_CLUSTERS: [], - OUTPUT_CLUSTERS: [ - GreenPowerProxy.cluster_id, # 0x0021 = GreenPowerProxy.cluster_id - ], - }, - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.COMBINED_INTERFACE, - INPUT_CLUSTERS: [ - Basic.cluster_id, # 0 - Identify.cluster_id, # 3 - Groups.cluster_id, # 4 - Scenes.cluster_id, # 5 - WWAH_CLUSTER_ID, # 64599 0xFC57 - IKEA_CLUSTER_ID, # 64636 0xFC7C - IkeaAirpurifier, # 64637 0xFC7D control air purifier with manufacturer-specific attributes - PM25Cluster, # 1066 0x042A PM2.5 Measurement Cluster - ], - OUTPUT_CLUSTERS: [ - Ota.cluster_id, # 25 0x0019 - IlluminanceMeasurement.cluster_id, # 1024 0x0400 - ], - }, - # - 242: { - PROFILE_ID: zgp.PROFILE_ID, # 41440 (dec) - DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC, - INPUT_CLUSTERS: [], - OUTPUT_CLUSTERS: [ - GreenPowerProxy.cluster_id, # 0x0021 = GreenPowerProxy.cluster_id - ], - }, - }, - } +( + QuirkBuilder(IKEA, "STARKVIND Air purifier") + .applies_to(IKEA, "STARKVIND Air purifier table") + .device_class(IkeaSTARKVIND) + .removes(Fan.cluster_id, endpoint_id=1) + .removes(PM25.cluster_id, cluster_type=ClusterType.Client, endpoint_id=1) + .adds(PM25Cluster, cluster_type=ClusterType.Server, endpoint_id=1) + .replaces(IkeaAirpurifier, endpoint_id=1) + .add_to_registry() +) diff --git a/zhaquirks/ikea/symfonisk.py b/zhaquirks/ikea/symfonisk.py index 96f7ec7f58..b7950fc881 100644 --- a/zhaquirks/ikea/symfonisk.py +++ b/zhaquirks/ikea/symfonisk.py @@ -1,19 +1,6 @@ """Device handler for IKEA of Sweden TRADFRI SYMFONISK remote control.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - Groups, - Identify, - LevelControl, - OnOff, - Ota, - PollControl, - PowerConfiguration, - Scenes, -) -from zigpy.zcl.clusters.lightlink import LightLink +from zigpy.quirks.v2 import QuirkBuilder from zhaquirks.const import ( CLUSTER_ID, @@ -22,16 +9,10 @@ COMMAND_STEP, COMMAND_STOP, COMMAND_TOGGLE, - DEVICE_TYPE, DOUBLE_PRESS, ENDPOINT_ID, - ENDPOINTS, - INPUT_CLUSTERS, LEFT, - MODELS_INFO, - OUTPUT_CLUSTERS, PARAMS, - PROFILE_ID, RIGHT, ROTATED, SHORT_PRESS, @@ -41,225 +22,63 @@ ) from zhaquirks.ikea import ( IKEA, - IKEA_CLUSTER_ID, WWAH_CLUSTER_ID, DoublingPowerConfig1CRCluster, PowerConfig1CRCluster, ) +DEVICE_AUTOMATION_TRIGGERS = { + (SHORT_PRESS, TURN_ON): { + COMMAND: COMMAND_TOGGLE, + CLUSTER_ID: 6, + ENDPOINT_ID: 1, + }, + (ROTATED, RIGHT): { + COMMAND: COMMAND_MOVE, + CLUSTER_ID: 8, + ENDPOINT_ID: 1, + PARAMS: {"move_mode": 0}, + }, + (ROTATED, LEFT): { + COMMAND: COMMAND_MOVE, + CLUSTER_ID: 8, + ENDPOINT_ID: 1, + PARAMS: {"move_mode": 1}, + }, + (ROTATED, STOP): { + COMMAND: COMMAND_STOP, + CLUSTER_ID: 8, + ENDPOINT_ID: 1, + }, + (DOUBLE_PRESS, TURN_ON): { + COMMAND: COMMAND_STEP, + CLUSTER_ID: 8, + ENDPOINT_ID: 1, + PARAMS: {"step_mode": 0}, + }, + (TRIPLE_PRESS, TURN_ON): { + COMMAND: COMMAND_STEP, + CLUSTER_ID: 8, + ENDPOINT_ID: 1, + PARAMS: {"step_mode": 1}, + }, +} -class IkeaSYMFONISK1(CustomDevice): - """Custom device representing IKEA of Sweden TRADFRI remote control.""" - - signature = { - # - MODELS_INFO: [(IKEA, "SYMFONISK Sound Controller")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.REMOTE_CONTROL, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - LightLink.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - LightLink.cluster_id, - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.REMOTE_CONTROL, - INPUT_CLUSTERS: [ - Basic.cluster_id, - DoublingPowerConfig1CRCluster, - Identify.cluster_id, - PollControl.cluster_id, - LightLink.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - LightLink.cluster_id, - ], - } - } - } - - device_automation_triggers = { - (SHORT_PRESS, TURN_ON): { - COMMAND: COMMAND_TOGGLE, - CLUSTER_ID: 6, - ENDPOINT_ID: 1, - }, - (ROTATED, RIGHT): { - COMMAND: COMMAND_MOVE, - CLUSTER_ID: 8, - ENDPOINT_ID: 1, - PARAMS: {"move_mode": 0}, - }, - (ROTATED, LEFT): { - COMMAND: COMMAND_MOVE, - CLUSTER_ID: 8, - ENDPOINT_ID: 1, - PARAMS: {"move_mode": 1}, - }, - (ROTATED, STOP): { - COMMAND: COMMAND_STOP, - CLUSTER_ID: 8, - ENDPOINT_ID: 1, - }, - (DOUBLE_PRESS, TURN_ON): { - COMMAND: COMMAND_STEP, - CLUSTER_ID: 8, - ENDPOINT_ID: 1, - PARAMS: {"step_mode": 0}, - }, - (TRIPLE_PRESS, TURN_ON): { - COMMAND: COMMAND_STEP, - CLUSTER_ID: 8, - ENDPOINT_ID: 1, - PARAMS: {"step_mode": 1}, - }, - } - - -class IkeaSYMFONISK2(IkeaSYMFONISK1): - """Custom device representing IKEA of Sweden TRADFRI remote control.""" - - signature = { - # - MODELS_INFO: [(IKEA, "SYMFONISK Sound Controller")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.REMOTE_CONTROL, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - LightLink.cluster_id, - IKEA_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - LightLink.cluster_id, - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.REMOTE_CONTROL, - INPUT_CLUSTERS: [ - Basic.cluster_id, - DoublingPowerConfig1CRCluster, - Identify.cluster_id, - PollControl.cluster_id, - LightLink.cluster_id, - IKEA_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - LightLink.cluster_id, - ], - } - } - } - - -class IkeaSYMFONISK3(IkeaSYMFONISK1): - """Custom device representing IKEA of Sweden TRADFRI remote control.""" +( + QuirkBuilder(IKEA, "SYMFONISK Sound Controller") + # TODO: identify the exact firmware versions when this fix stopped being required + .filter(lambda device: WWAH_CLUSTER_ID not in device.endpoints[1].in_clusters) + .replaces(DoublingPowerConfig1CRCluster, endpoint_id=1) + .device_automation_triggers(DEVICE_AUTOMATION_TRIGGERS) + .add_to_registry() +) - signature = { - # - MODELS_INFO: [(IKEA, "SYMFONISK Sound Controller")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.REMOTE_CONTROL, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - LightLink.cluster_id, - WWAH_CLUSTER_ID, - IKEA_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - LightLink.cluster_id, - ], - }, - }, - } - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.REMOTE_CONTROL, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfig1CRCluster, - Identify.cluster_id, - PollControl.cluster_id, - LightLink.cluster_id, - WWAH_CLUSTER_ID, - IKEA_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - LightLink.cluster_id, - ], - }, - }, - } +( + QuirkBuilder(IKEA, "SYMFONISK Sound Controller") + # TODO: identify the exact firmware versions when this fix stopped being required + .filter(lambda device: WWAH_CLUSTER_ID in device.endpoints[1].in_clusters) + .replaces(PowerConfig1CRCluster, endpoint_id=1) + .device_automation_triggers(DEVICE_AUTOMATION_TRIGGERS) + .add_to_registry() +) diff --git a/zhaquirks/ikea/symfonisk2.py b/zhaquirks/ikea/symfonisk2.py index fd5a96a3dd..de99258eaa 100644 --- a/zhaquirks/ikea/symfonisk2.py +++ b/zhaquirks/ikea/symfonisk2.py @@ -1,18 +1,8 @@ """Device handler for IKEA of Sweden SYMFONISK sound remote gen2.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - Groups, - Identify, - LevelControl, - OnOff, - Ota, - PollControl, - PowerConfiguration, -) -from zigpy.zcl.clusters.lightlink import LightLink +from zigpy.quirks.v2 import QuirkBuilder +from zigpy.zcl import ClusterType +from zigpy.zcl.clusters.general import PowerConfiguration from zhaquirks.const import ( BUTTON_1, @@ -28,28 +18,21 @@ COMMAND_MOVE_ON_OFF, COMMAND_STEP, COMMAND_TOGGLE, - DEVICE_TYPE, DIM_DOWN, DIM_UP, DOUBLE_PRESS, ENDPOINT_ID, - ENDPOINTS, - INPUT_CLUSTERS, LEFT, LONG_PRESS, LONG_RELEASE, - MODELS_INFO, - OUTPUT_CLUSTERS, PARAMS, PRESSED, - PROFILE_ID, RIGHT, SHORT_PRESS, TOGGLE, ) from zhaquirks.ikea import ( IKEA, - IKEA_CLUSTER_ID, WWAH_CLUSTER_ID, DoublingPowerConfig2AAACluster, PowerConfig2AAACluster, @@ -57,120 +40,59 @@ ShortcutV2Cluster, ) +COMMON_DEVICE_AUTOMATION_TRIGGERS = { + (SHORT_PRESS, TOGGLE): { + COMMAND: COMMAND_TOGGLE, + CLUSTER_ID: 6, + ENDPOINT_ID: 1, + }, + (SHORT_PRESS, DIM_UP): { + COMMAND: COMMAND_MOVE_ON_OFF, + CLUSTER_ID: 8, + ENDPOINT_ID: 1, + PARAMS: {"move_mode": 0}, + }, + (LONG_PRESS, DIM_UP): { + COMMAND: COMMAND_MOVE, + CLUSTER_ID: 8, + ENDPOINT_ID: 1, + PARAMS: {"move_mode": 0}, + }, + (SHORT_PRESS, DIM_DOWN): { + COMMAND: COMMAND_MOVE_ON_OFF, + CLUSTER_ID: 8, + ENDPOINT_ID: 1, + PARAMS: {"move_mode": 1}, + }, + (LONG_PRESS, DIM_DOWN): { + COMMAND: COMMAND_MOVE, + CLUSTER_ID: 8, + ENDPOINT_ID: 1, + PARAMS: {"move_mode": 1}, + }, + (SHORT_PRESS, RIGHT): { + COMMAND: COMMAND_STEP, + CLUSTER_ID: 8, + ENDPOINT_ID: 1, + PARAMS: {"step_mode": 0}, + }, + (SHORT_PRESS, LEFT): { + COMMAND: COMMAND_STEP, + CLUSTER_ID: 8, + ENDPOINT_ID: 1, + PARAMS: {"step_mode": 1}, + }, +} -class Symfonisk2CommonTriggers: - """IKEA Symfonisk 2 common device triggers.""" - - device_automation_triggers = { - (SHORT_PRESS, TOGGLE): { - COMMAND: COMMAND_TOGGLE, - CLUSTER_ID: 6, - ENDPOINT_ID: 1, - }, - (SHORT_PRESS, DIM_UP): { - COMMAND: COMMAND_MOVE_ON_OFF, - CLUSTER_ID: 8, - ENDPOINT_ID: 1, - PARAMS: {"move_mode": 0}, - }, - (LONG_PRESS, DIM_UP): { - COMMAND: COMMAND_MOVE, - CLUSTER_ID: 8, - ENDPOINT_ID: 1, - PARAMS: {"move_mode": 0}, - }, - (SHORT_PRESS, DIM_DOWN): { - COMMAND: COMMAND_MOVE_ON_OFF, - CLUSTER_ID: 8, - ENDPOINT_ID: 1, - PARAMS: {"move_mode": 1}, - }, - (LONG_PRESS, DIM_DOWN): { - COMMAND: COMMAND_MOVE, - CLUSTER_ID: 8, - ENDPOINT_ID: 1, - PARAMS: {"move_mode": 1}, - }, - (SHORT_PRESS, RIGHT): { - COMMAND: COMMAND_STEP, - CLUSTER_ID: 8, - ENDPOINT_ID: 1, - PARAMS: {"step_mode": 0}, - }, - (SHORT_PRESS, LEFT): { - COMMAND: COMMAND_STEP, - CLUSTER_ID: 8, - ENDPOINT_ID: 1, - PARAMS: {"step_mode": 1}, - }, - } - - -class IkeaSymfoniskGen2v1(CustomDevice): - """Custom device representing IKEA SYMFONISK sound remote gen2 V1.0.012.""" - - signature = { - # - MODELS_INFO: [(IKEA, "SYMFONISK sound remote gen2")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.REMOTE_CONTROL, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - LightLink.cluster_id, - WWAH_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - LightLink.cluster_id, - ShortcutV1Cluster.cluster_id, - ], - }, - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.REMOTE_CONTROL, - INPUT_CLUSTERS: [ - Basic.cluster_id, - DoublingPowerConfig2AAACluster, - Identify.cluster_id, - PollControl.cluster_id, - LightLink.cluster_id, - WWAH_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - LightLink.cluster_id, - ShortcutV1Cluster, - ], - }, - }, - } - - device_automation_triggers = ( - Symfonisk2CommonTriggers.device_automation_triggers.copy() - ) - device_automation_triggers.update( +( + QuirkBuilder(IKEA, "SYMFONISK sound remote gen2") + # TODO: differentiate between these devices without `filter` + .filter(lambda device: WWAH_CLUSTER_ID in device.endpoints[1].in_clusters) + .replaces(DoublingPowerConfig2AAACluster, endpoint_id=1) + .replaces(ShortcutV1Cluster, cluster_type=ClusterType.Client, endpoint_id=1) + .device_automation_triggers( { + **COMMON_DEVICE_AUTOMATION_TRIGGERS, (SHORT_PRESS, BUTTON_1): { COMMAND: ShortcutV1Cluster.ServerCommandDefs.shortcut_v1_events.name, PARAMS: {"shortcut_button": 1, "shortcut_event": 1}, @@ -195,137 +117,25 @@ class IkeaSymfoniskGen2v1(CustomDevice): COMMAND: ShortcutV1Cluster.ServerCommandDefs.shortcut_v1_events.name, PARAMS: {"shortcut_button": 2, "shortcut_event": 3}, }, - }, + } ) + .add_to_registry() +) - -class IkeaSymfoniskGen2v2(CustomDevice): - """Custom device representing IKEA SYMFONISK sound remote gen2 V1.0.32.""" - - signature = { - # - MODELS_INFO: [(IKEA, "SYMFONISK sound remote gen2")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.REMOTE_CONTROL, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - LightLink.cluster_id, - IKEA_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - LightLink.cluster_id, - ], - }, - # - 2: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.REMOTE_CONTROL, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - ShortcutV2Cluster.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - ShortcutV2Cluster.cluster_id, - ], - }, - # - 3: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.REMOTE_CONTROL, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - ShortcutV2Cluster.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - ShortcutV2Cluster.cluster_id, - ], - }, - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.REMOTE_CONTROL, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfig2AAACluster, - Identify.cluster_id, - PollControl.cluster_id, - LightLink.cluster_id, - IKEA_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - LightLink.cluster_id, - ], - }, - 2: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.REMOTE_CONTROL, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - ShortcutV2Cluster, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - ShortcutV2Cluster, - ], - }, - 3: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.REMOTE_CONTROL, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - ShortcutV2Cluster, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - ShortcutV2Cluster, - ], - }, - }, - } - - device_automation_triggers = ( - Symfonisk2CommonTriggers.device_automation_triggers.copy() +( + QuirkBuilder(IKEA, "SYMFONISK sound remote gen2") + # TODO: differentiate between these devices without `filter` + .filter(lambda device: WWAH_CLUSTER_ID not in device.endpoints[1].in_clusters) + .replaces( + PowerConfig2AAACluster, cluster_id=PowerConfiguration.cluster_id, endpoint_id=1 ) - device_automation_triggers.update( + .replaces(ShortcutV2Cluster, cluster_type=ClusterType.Server, endpoint_id=2) + .replaces(ShortcutV2Cluster, cluster_type=ClusterType.Client, endpoint_id=2) + .replaces(ShortcutV2Cluster, cluster_type=ClusterType.Server, endpoint_id=3) + .replaces(ShortcutV2Cluster, cluster_type=ClusterType.Client, endpoint_id=3) + .device_automation_triggers( { + **COMMON_DEVICE_AUTOMATION_TRIGGERS, (PRESSED, BUTTON_1): {ENDPOINT_ID: 2, COMMAND: COMMAND_M_INITIAL_PRESS}, (SHORT_PRESS, BUTTON_1): {ENDPOINT_ID: 2, COMMAND: COMMAND_M_SHORT_RELEASE}, (DOUBLE_PRESS, BUTTON_1): { @@ -342,5 +152,7 @@ class IkeaSymfoniskGen2v2(CustomDevice): }, (LONG_PRESS, BUTTON_2): {ENDPOINT_ID: 3, COMMAND: COMMAND_M_LONG_PRESS}, (LONG_RELEASE, BUTTON_2): {ENDPOINT_ID: 3, COMMAND: COMMAND_M_LONG_RELEASE}, - }, + } ) + .add_to_registry() +) diff --git a/zhaquirks/ikea/twobtnremote.py b/zhaquirks/ikea/twobtnremote.py index 4279465e4f..1e9c03a2f5 100644 --- a/zhaquirks/ikea/twobtnremote.py +++ b/zhaquirks/ikea/twobtnremote.py @@ -1,20 +1,7 @@ """Device handler for IKEA of Sweden TRADFRI remote control.""" -from zigpy.profiles import zha, zll -from zigpy.quirks import CustomDevice +from zigpy.quirks.v2 import QuirkBuilder from zigpy.zcl.clusters.closures import WindowCovering -from zigpy.zcl.clusters.general import ( - Alarms, - Basic, - Groups, - Identify, - LevelControl, - OnOff, - Ota, - PollControl, - PowerConfiguration, -) -from zigpy.zcl.clusters.lightlink import LightLink from zhaquirks.const import ( CLUSTER_ID, @@ -25,302 +12,70 @@ COMMAND_ON, COMMAND_STOP, COMMAND_STOP_ON_OFF, - DEVICE_TYPE, DIM_DOWN, DIM_UP, ENDPOINT_ID, - ENDPOINTS, - INPUT_CLUSTERS, LONG_PRESS, LONG_RELEASE, - MODELS_INFO, - OUTPUT_CLUSTERS, PARAMS, - PROFILE_ID, SHORT_PRESS, TURN_OFF, TURN_ON, ) -from zhaquirks.ikea import ( - IKEA, - IKEA_CLUSTER_ID, - DoublingPowerConfig1CRCluster, - PowerConfig1AAACluster, +from zhaquirks.ikea import IKEA, DoublingPowerConfig1CRCluster, PowerConfig1AAACluster + +_DEVICE_AUTOMATION_TRIGGERS = { + (SHORT_PRESS, TURN_ON): {COMMAND: COMMAND_ON, CLUSTER_ID: 6, ENDPOINT_ID: 1}, + (LONG_PRESS, DIM_UP): { + COMMAND: COMMAND_MOVE_ON_OFF, + CLUSTER_ID: 8, + ENDPOINT_ID: 1, + PARAMS: {"move_mode": 0}, + }, + (LONG_RELEASE, DIM_UP): { + COMMAND: COMMAND_STOP_ON_OFF, + CLUSTER_ID: 8, + ENDPOINT_ID: 1, + }, + (SHORT_PRESS, TURN_OFF): {COMMAND: COMMAND_OFF, CLUSTER_ID: 6, ENDPOINT_ID: 1}, + (LONG_PRESS, DIM_DOWN): { + COMMAND: COMMAND_MOVE, + CLUSTER_ID: 8, + ENDPOINT_ID: 1, + PARAMS: {"move_mode": 1}, + }, + (LONG_RELEASE, DIM_DOWN): { + COMMAND: COMMAND_STOP, + CLUSTER_ID: 8, + ENDPOINT_ID: 1, + }, +} + +( + QuirkBuilder(IKEA, "TRADFRI on/off switch") + .filter( + lambda device: WindowCovering.cluster_id not in device.endpoints[1].in_clusters + ) + .replaces(DoublingPowerConfig1CRCluster, endpoint_id=1) + .device_automation_triggers(_DEVICE_AUTOMATION_TRIGGERS) + .add_to_registry() ) -class IkeaTradfriRemote2Btn(CustomDevice): - """Custom device representing IKEA of Sweden TRADFRI remote control.""" - - signature = { - # - MODELS_INFO: [(IKEA, "TRADFRI on/off switch")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.NON_COLOR_CONTROLLER, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - Alarms.cluster_id, - PollControl.cluster_id, - LightLink.cluster_id, - IKEA_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - WindowCovering.cluster_id, - LightLink.cluster_id, - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.NON_COLOR_CONTROLLER, - INPUT_CLUSTERS: [ - Basic.cluster_id, - DoublingPowerConfig1CRCluster, - Identify.cluster_id, - Alarms.cluster_id, - PollControl.cluster_id, - LightLink.cluster_id, - IKEA_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - WindowCovering.cluster_id, - LightLink.cluster_id, - ], - } - } - } - - device_automation_triggers = { - (SHORT_PRESS, TURN_ON): {COMMAND: COMMAND_ON, CLUSTER_ID: 6, ENDPOINT_ID: 1}, - (LONG_PRESS, DIM_UP): { - COMMAND: COMMAND_MOVE_ON_OFF, - CLUSTER_ID: 8, - ENDPOINT_ID: 1, - PARAMS: {"move_mode": 0}, - }, - (LONG_RELEASE, DIM_UP): { - COMMAND: COMMAND_STOP_ON_OFF, - CLUSTER_ID: 8, - ENDPOINT_ID: 1, - }, - (SHORT_PRESS, TURN_OFF): {COMMAND: COMMAND_OFF, CLUSTER_ID: 6, ENDPOINT_ID: 1}, - (LONG_PRESS, DIM_DOWN): { - COMMAND: COMMAND_MOVE, - CLUSTER_ID: 8, - ENDPOINT_ID: 1, - PARAMS: {"move_mode": 1}, - }, - (LONG_RELEASE, DIM_DOWN): { - COMMAND: COMMAND_STOP, - CLUSTER_ID: 8, - ENDPOINT_ID: 1, - }, - } - - -class IkeaTradfriRemote2BtnZLL(CustomDevice): - """Custom device representing IKEA of Sweden TRADFRI remote control.""" - - signature = { - # - MODELS_INFO: [(IKEA, "TRADFRI on/off switch")], - ENDPOINTS: { - 1: { - PROFILE_ID: zll.PROFILE_ID, - DEVICE_TYPE: zll.DeviceType.CONTROLLER, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - Alarms.cluster_id, - WindowCovering.cluster_id, - LightLink.cluster_id, - IKEA_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - WindowCovering.cluster_id, - LightLink.cluster_id, - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zll.PROFILE_ID, - DEVICE_TYPE: zll.DeviceType.CONTROLLER, - INPUT_CLUSTERS: [ - Basic.cluster_id, - DoublingPowerConfig1CRCluster, - Identify.cluster_id, - Alarms.cluster_id, - LightLink.cluster_id, - IKEA_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - WindowCovering.cluster_id, - LightLink.cluster_id, - ], - } - } - } - - device_automation_triggers = IkeaTradfriRemote2Btn.device_automation_triggers.copy() - - -class IkeaRodretRemote2Btn(CustomDevice): - """Custom device representing IKEA of Sweden RODRET remote control.""" - - signature = { - # - MODELS_INFO: [(IKEA, "RODRET Dimmer")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.NON_COLOR_CONTROLLER, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - LightLink.cluster_id, - IKEA_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - LightLink.cluster_id, - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.NON_COLOR_CONTROLLER, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfig1AAACluster, - Identify.cluster_id, - PollControl.cluster_id, - LightLink.cluster_id, - IKEA_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - LightLink.cluster_id, - ], - } - } - } - - device_automation_triggers = IkeaTradfriRemote2Btn.device_automation_triggers.copy() - - -class IkeaRodretRemote2BtnNew(CustomDevice): - """Custom device representing IKEA of Sweden RODRET remote control.""" - - signature = { - # - MODELS_INFO: [(IKEA, "RODRET Dimmer"), (IKEA, "RODRET wireless dimmer")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.NON_COLOR_CONTROLLER, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - PollControl.cluster_id, - LightLink.cluster_id, - IKEA_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - LightLink.cluster_id, - ], - } - }, - } +# ZLL profile variant +( + QuirkBuilder(IKEA, "TRADFRI on/off switch") + .filter(lambda device: WindowCovering.cluster_id in device.endpoints[1].in_clusters) + .replaces(DoublingPowerConfig1CRCluster, endpoint_id=1) + .removes(WindowCovering.cluster_id, endpoint_id=1) + .device_automation_triggers(_DEVICE_AUTOMATION_TRIGGERS) + .add_to_registry() +) - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.NON_COLOR_CONTROLLER, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfig1AAACluster, - Identify.cluster_id, - PollControl.cluster_id, - LightLink.cluster_id, - IKEA_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - LightLink.cluster_id, - ], - } - } - } - device_automation_triggers = IkeaTradfriRemote2Btn.device_automation_triggers.copy() +( + QuirkBuilder(IKEA, "RODRET Dimmer") + .replaces(PowerConfig1AAACluster, endpoint_id=1) + .device_automation_triggers(_DEVICE_AUTOMATION_TRIGGERS) + .add_to_registry() +) diff --git a/zhaquirks/iluminize/cct.py b/zhaquirks/iluminize/cct.py index 3a6edb6040..1dd00bb003 100644 --- a/zhaquirks/iluminize/cct.py +++ b/zhaquirks/iluminize/cct.py @@ -1,29 +1,9 @@ """Quirk for iluminize CCT actor.""" -from zigpy.profiles import zgp, zll -from zigpy.quirks import CustomCluster, CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - GreenPowerProxy, - Groups, - Identify, - LevelControl, - OnOff, - Ota, - Scenes, -) -from zigpy.zcl.clusters.homeautomation import Diagnostic +from zigpy.quirks import CustomCluster +from zigpy.quirks.v2 import QuirkBuilder from zigpy.zcl.clusters.lighting import Color -from zigpy.zcl.clusters.lightlink import LightLink -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.iluminize import ILUMINIZE @@ -34,68 +14,8 @@ class IluminizeCCTColorCluster(CustomCluster, Color): _CONSTANT_ATTRIBUTES = {0x400A: 16} -class CCTLight(CustomDevice): - """iluminize ZigBee LightLink CCT Lighting device.""" - - signature = { - MODELS_INFO: [(ILUMINIZE, "CCT Lighting")], - ENDPOINTS: { - 1: { - # - MODELS_INFO: [(IMAGIC, "1117-S")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - RelativeHumidity.cluster_id, - IasZone.cluster_id, - Diagnostic.cluster_id, - MANUFACTURER_SPECIFIC_PROFILE_ID, - MANUFACTURER_SPECIFIC_PROFILE_ID2, - ], - OUTPUT_CLUSTERS: [Identify.cluster_id, Ota.cluster_id], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [ - Basic, - PowerConfigurationCluster, - Identify, - PollControl, - TemperatureMeasurement, - RelativeHumidity, - IasZone, - Diagnostic, - MANUFACTURER_SPECIFIC_PROFILE_ID, - MANUFACTURER_SPECIFIC_PROFILE_ID2, - ], - OUTPUT_CLUSTERS: [Identify, Ota], - } - } - } +( + QuirkBuilder(IMAGIC, "1117-S") + .replaces( + PowerConfigurationCluster, + cluster_id=PowerConfiguration.cluster_id, + endpoint_id=1, + ) + .add_to_registry() +) diff --git a/zhaquirks/imagic/im1116s.py b/zhaquirks/imagic/im1116s.py index fd4e7caa30..19576d3905 100644 --- a/zhaquirks/imagic/im1116s.py +++ b/zhaquirks/imagic/im1116s.py @@ -1,71 +1,16 @@ """Device handler for GreatStar iMagic 1116-S sensor.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import Basic, Identify, Ota, PollControl -from zigpy.zcl.clusters.homeautomation import Diagnostic -from zigpy.zcl.clusters.measurement import TemperatureMeasurement -from zigpy.zcl.clusters.security import IasZone +from zigpy.quirks.v2 import QuirkBuilder from zhaquirks import PowerConfigurationCluster -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.imagic import IMAGIC MANUFACTURER_SPECIFIC_CLUSTER_ID = 0xFC01 # decimal = 64513 MANUFACTURER_SPECIFIC_CLUSTER_ID_2 = 0xFC02 # decimal = 64514 -class iMagic1116(CustomDevice): - """Custom device representing iMagic 1116-S sensor.""" - - signature = { - # - MODELS_INFO: [(IMAGIC, "1116-S")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfigurationCluster.cluster_id, - Identify.cluster_id, - MANUFACTURER_SPECIFIC_CLUSTER_ID, - MANUFACTURER_SPECIFIC_CLUSTER_ID_2, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - IasZone.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id, Identify.cluster_id], - }, - }, - } - - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfigurationCluster, - Identify.cluster_id, - MANUFACTURER_SPECIFIC_CLUSTER_ID, - MANUFACTURER_SPECIFIC_CLUSTER_ID_2, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - IasZone.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id, Identify.cluster_id], - }, - } - } +( + QuirkBuilder(IMAGIC, "1116-S") + .replaces(PowerConfigurationCluster, endpoint_id=1) + .add_to_registry() +) diff --git a/zhaquirks/innr/innr_sp120_plug.py b/zhaquirks/innr/innr_sp120_plug.py index 41c0ed3c74..01e5164125 100644 --- a/zhaquirks/innr/innr_sp120_plug.py +++ b/zhaquirks/innr/innr_sp120_plug.py @@ -1,98 +1,14 @@ """Innr SP 120 plug.""" -from zigpy.profiles import zll -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - Groups, - Identify, - LevelControl, - OnOff, - Ota, - Scenes, - Time, -) +from zigpy.quirks.v2 import QuirkBuilder from zigpy.zcl.clusters.homeautomation import ElectricalMeasurement -from zigpy.zcl.clusters.lightlink import LightLink from zigpy.zcl.clusters.smartenergy import Metering -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.innr import INNR, ElectricalMeasurementClusterInnr, MeteringClusterInnr - -class SP120(CustomDevice): - """Innr SP 120 smart plug.""" - - signature = { - MODELS_INFO: [(INNR, "SP 120")], - ENDPOINTS: { - 1: { - PROFILE_ID: zll.PROFILE_ID, - DEVICE_TYPE: zll.DeviceType.ON_OFF_PLUGIN_UNIT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - ElectricalMeasurement.cluster_id, - Groups.cluster_id, - Identify.cluster_id, - LevelControl.cluster_id, - Metering.cluster_id, - OnOff.cluster_id, - Scenes.cluster_id, - Time.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Ota.cluster_id, - Time.cluster_id, - ], - }, - 2: { - PROFILE_ID: zll.PROFILE_ID, - DEVICE_TYPE: 0x1000, - INPUT_CLUSTERS: [ - LightLink.cluster_id, - ], - OUTPUT_CLUSTERS: [], - }, - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zll.PROFILE_ID, - DEVICE_TYPE: zll.DeviceType.ON_OFF_PLUGIN_UNIT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - ElectricalMeasurementClusterInnr, - Groups.cluster_id, - Identify.cluster_id, - LevelControl.cluster_id, - MeteringClusterInnr, - OnOff.cluster_id, - Scenes.cluster_id, - Time.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Ota.cluster_id, - Time.cluster_id, - ], - }, - 2: { - PROFILE_ID: zll.PROFILE_ID, - DEVICE_TYPE: 0x1000, - INPUT_CLUSTERS: [ - LightLink.cluster_id, - ], - OUTPUT_CLUSTERS: [], - }, - }, - } +( + QuirkBuilder(INNR, "SP 120") + .replaces(ElectricalMeasurementClusterInnr, ElectricalMeasurement, endpoint_id=1) + .replaces(MeteringClusterInnr, Metering, endpoint_id=1) + .add_to_registry() +) diff --git a/zhaquirks/innr/innr_sp234_plug.py b/zhaquirks/innr/innr_sp234_plug.py index ac3245ea54..038fae84a3 100644 --- a/zhaquirks/innr/innr_sp234_plug.py +++ b/zhaquirks/innr/innr_sp234_plug.py @@ -1,98 +1,12 @@ """Innr SP 234 plug.""" -from zigpy.profiles import zgp, zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - GreenPowerProxy, - Groups, - Identify, - OnOff, - Ota, - Scenes, - Time, -) -from zigpy.zcl.clusters.homeautomation import Diagnostic, ElectricalMeasurement -from zigpy.zcl.clusters.lightlink import LightLink -from zigpy.zcl.clusters.smartenergy import Metering +from zigpy.quirks.v2 import QuirkBuilder -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.innr import INNR, ElectricalMeasurementClusterInnr, MeteringClusterInnr - -class SP234(CustomDevice): - """Innr SP 234 smart plug.""" - - signature = { - MODELS_INFO: [(INNR, "SP 234")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.ON_OFF_PLUG_IN_UNIT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - Metering.cluster_id, - ElectricalMeasurement.cluster_id, - Diagnostic.cluster_id, - LightLink.cluster_id, - 0xFC57, - 0xFC82, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Time.cluster_id, - Ota.cluster_id, - ], - }, - 242: { - PROFILE_ID: zgp.PROFILE_ID, - DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC, - INPUT_CLUSTERS: [], - OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id], - }, - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.ON_OFF_PLUG_IN_UNIT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - MeteringClusterInnr, - ElectricalMeasurementClusterInnr, - Diagnostic.cluster_id, - LightLink.cluster_id, - 0xFC57, - 0xFC82, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Time.cluster_id, - Ota.cluster_id, - ], - }, - 242: { - PROFILE_ID: zgp.PROFILE_ID, - DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC, - INPUT_CLUSTERS: [], - OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id], - }, - }, - } +( + QuirkBuilder(INNR, "SP 234") + .replaces(MeteringClusterInnr, endpoint_id=1) + .replaces(ElectricalMeasurementClusterInnr, endpoint_id=1) + .add_to_registry() +) diff --git a/zhaquirks/innr/innr_sp240_plug.py b/zhaquirks/innr/innr_sp240_plug.py index e9fdb57626..66b62c98c2 100644 --- a/zhaquirks/innr/innr_sp240_plug.py +++ b/zhaquirks/innr/innr_sp240_plug.py @@ -1,30 +1,9 @@ """Innr SP 240 plug.""" -from zigpy.profiles import zgp, zha -from zigpy.quirks import CustomCluster, CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - GreenPowerProxy, - Groups, - Identify, - LevelControl, - OnOff, - Ota, - Scenes, - Time, -) -from zigpy.zcl.clusters.homeautomation import ElectricalMeasurement -from zigpy.zcl.clusters.lightlink import LightLink +from zigpy.quirks import CustomCluster +from zigpy.quirks.v2 import QuirkBuilder from zigpy.zcl.clusters.smartenergy import Metering -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.innr import INNR, MeteringClusterInnr @@ -34,72 +13,9 @@ class InnrCluster(CustomCluster): cluster_id = 0xE001 -class SP240(CustomDevice): - """Innr SP 240 smart plug.""" - - signature = { - MODELS_INFO: [(INNR, "SP 240")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.ON_OFF_PLUG_IN_UNIT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Metering.cluster_id, - ElectricalMeasurement.cluster_id, - LightLink.cluster_id, - InnrCluster.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Time.cluster_id, - Ota.cluster_id, - ], - }, - 242: { - PROFILE_ID: zgp.PROFILE_ID, - DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC, - INPUT_CLUSTERS: [], - OUTPUT_CLUSTERS: [ - GreenPowerProxy.cluster_id, - ], - }, - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.ON_OFF_PLUG_IN_UNIT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - MeteringClusterInnr, - ElectricalMeasurement.cluster_id, - LightLink.cluster_id, - InnrCluster, - ], - OUTPUT_CLUSTERS: [ - Time.cluster_id, - Ota.cluster_id, - ], - }, - 242: { - PROFILE_ID: zgp.PROFILE_ID, - DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC, - INPUT_CLUSTERS: [], - OUTPUT_CLUSTERS: [ - GreenPowerProxy.cluster_id, - ], - }, - }, - } +( + QuirkBuilder(INNR, "SP 240") + .replaces(MeteringClusterInnr, Metering.cluster_id, endpoint_id=1) + .replaces(InnrCluster, endpoint_id=1) + .add_to_registry() +) diff --git a/zhaquirks/innr/rs228t.py b/zhaquirks/innr/rs228t.py index e116681c3b..b35a1b33b6 100644 --- a/zhaquirks/innr/rs228t.py +++ b/zhaquirks/innr/rs228t.py @@ -1,92 +1,13 @@ """Innr RS 228 T device.""" -from zigpy.profiles import zgp, zha from zigpy.profiles.zha import DeviceType -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - GreenPowerProxy, - Groups, - Identify, - LevelControl, - OnOff, - Ota, - Scenes, -) -from zigpy.zcl.clusters.lighting import Color -from zigpy.zcl.clusters.lightlink import LightLink +from zigpy.quirks.v2 import QuirkBuilder -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.innr import INNR - -class RS228T(CustomDevice): - """Innr RS 228 T device.""" - - signature = { - # - MODELS_INFO: [(INNR, "RS 228 T")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: 268, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Color.cluster_id, - LightLink.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - }, - # - 242: { - PROFILE_ID: zgp.PROFILE_ID, - DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC, - INPUT_CLUSTERS: [], - OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id], - }, - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: DeviceType.COLOR_DIMMABLE_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Color.cluster_id, - LightLink.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - }, - 242: { - PROFILE_ID: zgp.PROFILE_ID, - DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC, - INPUT_CLUSTERS: [], - OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id], - }, - } - } +( + QuirkBuilder(INNR, "RS 228 T") + # Was COLOR_TEMPERATURE_LIGHT + .replaces_endpoint(1, device_type=DeviceType.COLOR_DIMMABLE_LIGHT) + .add_to_registry() +) diff --git a/zhaquirks/insta/nexentro_pushbutton_interface.py b/zhaquirks/insta/nexentro_pushbutton_interface.py index 639bb4f9be..722711b823 100644 --- a/zhaquirks/insta/nexentro_pushbutton_interface.py +++ b/zhaquirks/insta/nexentro_pushbutton_interface.py @@ -1,28 +1,7 @@ """Device handler for Insta NEXENTRO Pushbutton Interface.""" -from zigpy.profiles import zgp, zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.closures import WindowCovering -from zigpy.zcl.clusters.general import ( - Basic, - GreenPowerProxy, - Groups, - Identify, - LevelControl, - OnOff, - Ota, - Scenes, -) -from zigpy.zcl.clusters.lighting import Color +from zigpy.quirks.v2 import QuirkBuilder -from zhaquirks import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.const import ( ALT_SHORT_PRESS, BUTTON, @@ -51,157 +30,25 @@ COMMAND_RECALL = "recall" -class InstaNexentroPushbuttonInterface(CustomDevice): - """Insta NEXENTRO Pushbutton Interface device.""" - - signature = { - MODELS_INFO: [(INSTA, "NEXENTRO Pushbutton Interface")], - ENDPOINTS: { - # - 4: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.COLOR_DIMMER_SWITCH, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - Color.cluster_id, - ], - }, - # - 5: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.COLOR_DIMMER_SWITCH, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - Color.cluster_id, - ], - }, - # - 7: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.WINDOW_COVERING_CONTROLLER, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - Ota.cluster_id, - WindowCovering.cluster_id, - ], - }, - # - 242: { - PROFILE_ID: zgp.PROFILE_ID, - DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC, - INPUT_CLUSTERS: [], - OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id], - }, - }, - } - - replacement = { - ENDPOINTS: { - 4: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.COLOR_DIMMER_SWITCH, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - Color.cluster_id, - ], - }, - 5: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.COLOR_DIMMER_SWITCH, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - Color.cluster_id, - ], - }, - 7: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.WINDOW_COVERING_CONTROLLER, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - Ota.cluster_id, - WindowCovering.cluster_id, - ], - }, - 242: { - PROFILE_ID: zgp.PROFILE_ID, - DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC, - INPUT_CLUSTERS: [], - OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id], - }, +( + QuirkBuilder(INSTA, "NEXENTRO Pushbutton Interface") + .device_automation_triggers( + { + (SHORT_PRESS, TURN_ON): {COMMAND: COMMAND_ON, ENDPOINT_ID: 4}, + (ALT_SHORT_PRESS, TURN_ON): {COMMAND: COMMAND_ON, ENDPOINT_ID: 5}, + (SHORT_PRESS, TURN_OFF): {COMMAND: COMMAND_OFF, ENDPOINT_ID: 4}, + (ALT_SHORT_PRESS, TURN_OFF): {COMMAND: COMMAND_OFF, ENDPOINT_ID: 5}, + (SHORT_PRESS, BUTTON): {COMMAND: COMMAND_TOGGLE, ENDPOINT_ID: 4}, + (ALT_SHORT_PRESS, BUTTON): {COMMAND: COMMAND_TOGGLE, ENDPOINT_ID: 5}, + (SHORT_PRESS, OPEN): {COMMAND: COMMAND_OPEN}, + (SHORT_PRESS, CLOSE): {COMMAND: COMMAND_CLOSE}, + (SHORT_PRESS, DIM_UP): {COMMAND: COMMAND_MOVE_ON_OFF, ENDPOINT_ID: 4}, + (ALT_SHORT_PRESS, DIM_UP): {COMMAND: COMMAND_MOVE_ON_OFF, ENDPOINT_ID: 5}, + (SHORT_PRESS, DIM_DOWN): {COMMAND: COMMAND_MOVE, ENDPOINT_ID: 4}, + (ALT_SHORT_PRESS, DIM_DOWN): {COMMAND: COMMAND_MOVE, ENDPOINT_ID: 5}, + (SHORT_PRESS, STOP): {COMMAND: COMMAND_STOP, ENDPOINT_ID: 4}, + (ALT_SHORT_PRESS, STOP): {COMMAND: COMMAND_STOP, ENDPOINT_ID: 5}, } - } - - device_automation_triggers = { - (SHORT_PRESS, TURN_ON): {COMMAND: COMMAND_ON, ENDPOINT_ID: 4}, - (ALT_SHORT_PRESS, TURN_ON): {COMMAND: COMMAND_ON, ENDPOINT_ID: 5}, - (SHORT_PRESS, TURN_OFF): {COMMAND: COMMAND_OFF, ENDPOINT_ID: 4}, - (ALT_SHORT_PRESS, TURN_OFF): {COMMAND: COMMAND_OFF, ENDPOINT_ID: 5}, - (SHORT_PRESS, BUTTON): {COMMAND: COMMAND_TOGGLE, ENDPOINT_ID: 4}, - (ALT_SHORT_PRESS, BUTTON): {COMMAND: COMMAND_TOGGLE, ENDPOINT_ID: 5}, - (SHORT_PRESS, OPEN): {COMMAND: COMMAND_OPEN}, - (SHORT_PRESS, CLOSE): {COMMAND: COMMAND_CLOSE}, - (SHORT_PRESS, DIM_UP): {COMMAND: COMMAND_MOVE_ON_OFF, ENDPOINT_ID: 4}, - (ALT_SHORT_PRESS, DIM_UP): {COMMAND: COMMAND_MOVE_ON_OFF, ENDPOINT_ID: 5}, - (SHORT_PRESS, DIM_DOWN): {COMMAND: COMMAND_MOVE, ENDPOINT_ID: 4}, - (ALT_SHORT_PRESS, DIM_DOWN): {COMMAND: COMMAND_MOVE, ENDPOINT_ID: 5}, - (SHORT_PRESS, STOP): {COMMAND: COMMAND_STOP, ENDPOINT_ID: 4}, - (ALT_SHORT_PRESS, STOP): {COMMAND: COMMAND_STOP, ENDPOINT_ID: 5}, - } + ) + .add_to_registry() +) diff --git a/zhaquirks/keenhome/sv02612mp13.py b/zhaquirks/keenhome/sv02612mp13.py index 69628313f5..a590bb7dd7 100644 --- a/zhaquirks/keenhome/sv02612mp13.py +++ b/zhaquirks/keenhome/sv02612mp13.py @@ -1,100 +1,24 @@ """Smart vent quirk.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - Groups, - Identify, - LevelControl, - OnOff, - Ota, - PollControl, - Scenes, -) -from zigpy.zcl.clusters.homeautomation import Diagnostic -from zigpy.zcl.clusters.measurement import PressureMeasurement, TemperatureMeasurement +from zigpy.quirks.v2 import QuirkBuilder from zhaquirks import DoublingPowerConfigurationCluster -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) KEEN1_CLUSTER_ID = 0xFC01 # decimal = 64513 KEEN2_CLUSTER_ID = 0xFC02 # decimal = 64514 - -class KeenHomeSmartVent(CustomDevice): - """Custom device representing Keen Home Smart Vent.""" - - signature = { - # - MODELS_INFO: [ - ("Keen Home Inc", "SV01-410-MP-1.0"), - ("Keen Home Inc", "SV01-410-MP-1.1"), - ("Keen Home Inc", "SV01-410-MP-1.4"), - ("Keen Home Inc", "SV01-410-MP-1.5"), - ("Keen Home Inc", "SV02-410-MP-1.2"), - ("Keen Home Inc", "SV02-410-MP-1.3"), - ("Keen Home Inc", "SV01-412-MP-1.0"), - ("Keen Home Inc", "SV01-610-MP-1.0"), - ("Keen Home Inc", "SV02-610-MP-1.3"), - ("Keen Home Inc", "SV01-612-MP-1.0"), - ("Keen Home Inc", "SV02-612-MP-1.3"), - ], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.LEVEL_CONTROLLABLE_OUTPUT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - DoublingPowerConfigurationCluster.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - PressureMeasurement.cluster_id, - Diagnostic.cluster_id, - KEEN1_CLUSTER_ID, - KEEN2_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - INPUT_CLUSTERS: [ - Basic.cluster_id, - DoublingPowerConfigurationCluster, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - PressureMeasurement.cluster_id, - Diagnostic.cluster_id, - KEEN1_CLUSTER_ID, - KEEN2_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - } - } +( + QuirkBuilder("Keen Home Inc", "SV01-410-MP-1.0") + .applies_to("Keen Home Inc", "SV01-410-MP-1.1") + .applies_to("Keen Home Inc", "SV01-410-MP-1.4") + .applies_to("Keen Home Inc", "SV01-410-MP-1.5") + .applies_to("Keen Home Inc", "SV02-410-MP-1.2") + .applies_to("Keen Home Inc", "SV02-410-MP-1.3") + .applies_to("Keen Home Inc", "SV01-412-MP-1.0") + .applies_to("Keen Home Inc", "SV01-610-MP-1.0") + .applies_to("Keen Home Inc", "SV02-610-MP-1.3") + .applies_to("Keen Home Inc", "SV01-612-MP-1.0") + .applies_to("Keen Home Inc", "SV02-612-MP-1.3") + .replaces(DoublingPowerConfigurationCluster, endpoint_id=1) + .add_to_registry() +) diff --git a/zhaquirks/keenhome/weather.py b/zhaquirks/keenhome/weather.py index 67c63822cc..f7288cadad 100644 --- a/zhaquirks/keenhome/weather.py +++ b/zhaquirks/keenhome/weather.py @@ -1,31 +1,15 @@ """Keen Home temperature/humidity/pressure sensor.""" -from zigpy.profiles import zha -from zigpy.profiles.zha import DeviceType -from zigpy.quirks import CustomCluster, CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - Groups, - Identify, - Ota, - PollControl, - PowerConfiguration, - Scenes, -) +from zigpy.quirks import CustomCluster +from zigpy.quirks.v2 import QuirkBuilder +from zigpy.zcl import ClusterType +from zigpy.zcl.clusters.general import Basic, Groups, Identify, Ota, PollControl, Scenes from zigpy.zcl.clusters.measurement import ( PressureMeasurement, RelativeHumidity, TemperatureMeasurement, ) -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.xiaomi import LUMI @@ -42,53 +26,25 @@ def _update_attribute(self, attrid, value): super()._update_attribute(self.MEASURED_VALUE_ATTR, value) -class TemperatureHumidtyPressureSensor(CustomDevice): - """Keen Home temperature/humidity/pressure sensor.""" - - signature = { - # - MODELS_INFO: [(LUMI, "RS-THP-MP-1.0")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: DeviceType.TEMPERATURE_SENSOR, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - PowerConfiguration.cluster_id, - PollControl.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Basic.cluster_id, - Groups.cluster_id, - Identify.cluster_id, - Scenes.cluster_id, - Ota.cluster_id, - TemperatureMeasurement.cluster_id, - RelativeHumidity.cluster_id, - PressureMeasurement.cluster_id, - PollControl.cluster_id, - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - PowerConfiguration.cluster_id, - RelativeHumidity.cluster_id, - TemperatureMeasurement.cluster_id, - PollControl.cluster_id, - PressureMeasurementCluster, - ], - OUTPUT_CLUSTERS: [Basic.cluster_id, Groups.cluster_id], - } - } - } +( + # TODO: is this right?? + QuirkBuilder(LUMI, "RS-THP-MP-1.0") + .adds(RelativeHumidity, endpoint_id=1) + .adds(TemperatureMeasurement, endpoint_id=1) + .replaces(PressureMeasurementCluster, endpoint_id=1) + .removes(Basic.cluster_id, cluster_type=ClusterType.Client, endpoint_id=1) + .removes(Groups.cluster_id, cluster_type=ClusterType.Client, endpoint_id=1) + .removes(Identify.cluster_id, cluster_type=ClusterType.Client, endpoint_id=1) + .removes(Scenes.cluster_id, cluster_type=ClusterType.Client, endpoint_id=1) + .removes(Ota.cluster_id, cluster_type=ClusterType.Client, endpoint_id=1) + .removes( + TemperatureMeasurement.cluster_id, + cluster_type=ClusterType.Client, + endpoint_id=1, + ) + .removes( + RelativeHumidity.cluster_id, cluster_type=ClusterType.Client, endpoint_id=1 + ) + .removes(PollControl.cluster_id, cluster_type=ClusterType.Client, endpoint_id=1) + .add_to_registry() +) diff --git a/zhaquirks/kof/kof_mr101z.py b/zhaquirks/kof/kof_mr101z.py index 08cba1e3ea..8766755fb2 100644 --- a/zhaquirks/kof/kof_mr101z.py +++ b/zhaquirks/kof/kof_mr101z.py @@ -5,30 +5,19 @@ expect replies at all. """ -from __future__ import annotations - from zigpy.profiles import zha -from zigpy.quirks import CustomCluster, CustomDevice +from zigpy.quirks import CustomCluster +from zigpy.quirks.v2 import QuirkBuilder from zigpy.zcl.clusters.general import ( Basic, Groups, Identify, LevelControl, OnOff, - Ota, Scenes, ) -from zigpy.zcl.clusters.hvac import Fan from zhaquirks import NoReplyMixin -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MANUFACTURER, - OUTPUT_CLUSTERS, - PROFILE_ID, -) class KofBasic(NoReplyMixin, CustomCluster, Basic): @@ -76,43 +65,20 @@ class KofLevelControl(NoReplyMixin, CustomCluster, LevelControl): void_input_commands = {cmd.id for cmd in LevelControl.commands_by_name.values()} -class CeilingFan(CustomDevice): - """Ceiling Fan Device.""" - - signature = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: 14, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Fan.cluster_id, - ], - OUTPUT_CLUSTERS: [Identify.cluster_id, Ota.cluster_id], - } - }, - MANUFACTURER: "King Of Fans, Inc.", - } - - replacement = { - ENDPOINTS: { - 1: { - DEVICE_TYPE: zha.DeviceType.DIMMABLE_LIGHT, - INPUT_CLUSTERS: [ - KofBasic, - KofIdentify, - KofGroups, - KofScenes, - KofOnOff, - KofLevelControl, - Fan, - ], - OUTPUT_CLUSTERS: [Identify, Ota], - } - } - } +( + # The manufacturer has two spaces in its name + QuirkBuilder("King Of Fans, Inc.", "MR101Z") + # TODO: add support for wildcard matching in `applies_to` + .applies_to("King Of Fans, Inc.", "HDC52EastwindFan") + .applies_to("King Of Fans, Inc.", "HBUniversalCFRemote") + .replaces_endpoint( + endpoint_id=1, device_type=zha.DeviceType.DIMMABLE_LIGHT + ) # was 257 + .replaces(KofBasic) + .replaces(KofIdentify) + .replaces(KofGroups) + .replaces(KofScenes) + .replaces(KofOnOff) + .replaces(KofLevelControl) + .add_to_registry() +) diff --git a/zhaquirks/konke/button.py b/zhaquirks/konke/button.py index b0cd21bbbd..5e88dcad38 100644 --- a/zhaquirks/konke/button.py +++ b/zhaquirks/konke/button.py @@ -1,15 +1,7 @@ """Konke Button Remote.""" from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - Groups, - Identify, - OnOff, - PowerConfiguration, - Scenes, -) +from zigpy.quirks.v2 import QuirkBuilder from zhaquirks import PowerConfigurationCluster from zhaquirks.const import ( @@ -17,124 +9,24 @@ COMMAND_DOUBLE, COMMAND_HOLD, COMMAND_SINGLE, - DEVICE_TYPE, DOUBLE_PRESS, - ENDPOINTS, - INPUT_CLUSTERS, LONG_PRESS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, SHORT_PRESS, ) from zhaquirks.konke import KONKE, KonkeOnOffCluster -from zhaquirks.quirk_ids import KONKE_BUTTON - -KONKE_CLUSTER_ID = 0xFCC0 - - -class KonkeButtonRemote1(CustomDevice): - """Konke 1-button remote device.""" - - quirk_id = KONKE_BUTTON - - signature = { - # - MODELS_INFO: [(KONKE, "3AFE280100510001")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.ON_OFF_OUTPUT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - OnOff.cluster_id, - KONKE_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [Identify.cluster_id, KONKE_CLUSTER_ID], - }, - }, - } - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.REMOTE_CONTROL, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfigurationCluster, - Identify.cluster_id, - KonkeOnOffCluster, - KONKE_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - KONKE_CLUSTER_ID, - ], - }, - }, - } - device_automation_triggers = { - (DOUBLE_PRESS, DOUBLE_PRESS): {COMMAND: COMMAND_DOUBLE}, - (SHORT_PRESS, SHORT_PRESS): {COMMAND: COMMAND_SINGLE}, - (LONG_PRESS, LONG_PRESS): {COMMAND: COMMAND_HOLD}, - } - - -class KonkeButtonRemote2(CustomDevice): - """Konke 1-button remote device 2nd variant.""" - - quirk_id = KONKE_BUTTON - - signature = { - # - MODELS_INFO: [(KONKE, "3AFE170100510001")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.ON_OFF_OUTPUT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - ], - OUTPUT_CLUSTERS: [Identify.cluster_id], - }, - }, - } - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.REMOTE_CONTROL, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfigurationCluster, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - KonkeOnOffCluster, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - ], - }, - }, - } - - device_automation_triggers = { - (DOUBLE_PRESS, DOUBLE_PRESS): {COMMAND: COMMAND_DOUBLE}, - (SHORT_PRESS, SHORT_PRESS): {COMMAND: COMMAND_SINGLE}, - (LONG_PRESS, LONG_PRESS): {COMMAND: COMMAND_HOLD}, - } +( + QuirkBuilder(KONKE, "3AFE280100510001") + .applies_to(KONKE, "3AFE170100510001") + .replaces_endpoint(1, device_type=zha.DeviceType.REMOTE_CONTROL) + .replaces(PowerConfigurationCluster, endpoint_id=1) + .replaces(KonkeOnOffCluster, endpoint_id=1) + .device_automation_triggers( + { + (DOUBLE_PRESS, DOUBLE_PRESS): {COMMAND: COMMAND_DOUBLE}, + (SHORT_PRESS, SHORT_PRESS): {COMMAND: COMMAND_SINGLE}, + (LONG_PRESS, LONG_PRESS): {COMMAND: COMMAND_HOLD}, + } + ) + .add_to_registry() +) diff --git a/zhaquirks/konke/magnet.py b/zhaquirks/konke/magnet.py index 169eef2d77..6f6a186553 100644 --- a/zhaquirks/konke/magnet.py +++ b/zhaquirks/konke/magnet.py @@ -1,103 +1,15 @@ """Konke magnet sensor.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import Basic, Identify, PowerConfiguration -from zigpy.zcl.clusters.security import IasZone +from zigpy.quirks.v2 import QuirkBuilder from zhaquirks import PowerConfigurationCluster -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.konke import KONKE -KONKE_CLUSTER_ID = 0xFCC0 - - -class KonkeMagnet(CustomDevice): - """Custom device representing konke magnet sensors.""" - - signature = { - # - MODELS_INFO: [(KONKE, "3AFE270104020015"), (KONKE, "3AFE280104020015")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - IasZone.cluster_id, - KONKE_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [Identify.cluster_id, KONKE_CLUSTER_ID], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfigurationCluster, - Identify.cluster_id, - IasZone.cluster_id, - KONKE_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [Identify.cluster_id, KONKE_CLUSTER_ID], - } - } - } - - -class KonkeMagnet2(CustomDevice): - """Custom device representing konke magnet sensors without custom konke cluster.""" - - signature = { - # - MODELS_INFO: [(KONKE, "3AFE130104020015"), (KONKE, "3AFE140104020015")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - IasZone.cluster_id, - ], - OUTPUT_CLUSTERS: [Identify.cluster_id], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfigurationCluster, - Identify.cluster_id, - IasZone.cluster_id, - ], - OUTPUT_CLUSTERS: [Identify.cluster_id], - } - } - } +( + QuirkBuilder(KONKE, "3AFE270104020015") + .applies_to(KONKE, "3AFE280104020015") + .applies_to(KONKE, "3AFE130104020015") + .applies_to(KONKE, "3AFE140104020015") + .replaces(PowerConfigurationCluster, endpoint_id=1) + .add_to_registry() +) diff --git a/zhaquirks/konke/motion.py b/zhaquirks/konke/motion.py index 932a61e4b3..89828914a6 100644 --- a/zhaquirks/konke/motion.py +++ b/zhaquirks/konke/motion.py @@ -1,119 +1,35 @@ """Konke motion sensor.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import Basic, Identify, PowerConfiguration +from typing import Any + +from zigpy.quirks.v2 import CustomDeviceV2, QuirkBuilder +from zigpy.zcl.clusters.general import PowerConfiguration from zigpy.zcl.clusters.security import IasZone from zhaquirks import Bus, PowerConfigurationCluster -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.konke import KONKE, MotionCluster, OccupancyCluster -KONKE_CLUSTER_ID = 0xFCC0 - - -class KonkeMotion(CustomDevice): - """Custom device representing konke motion sensors.""" - - def __init__(self, *args, **kwargs): - """Init.""" - self.occupancy_bus = Bus() - super().__init__(*args, **kwargs) - - signature = { - # - MODELS_INFO: [ - (KONKE, "3AFE28010402000D"), - (KONKE, "3AFE14010402000D"), - (KONKE, "3AFE27010402000D"), - ], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - IasZone.cluster_id, - KONKE_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [Identify.cluster_id, KONKE_CLUSTER_ID], - } - }, - } - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfigurationCluster, - Identify.cluster_id, - OccupancyCluster, - MotionCluster, - KONKE_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [Identify.cluster_id, KONKE_CLUSTER_ID], - } - } - } +class KonkeMotionDevice(CustomDeviceV2): + """Custom device class for Konke motion sensors that need occupancy_bus.""" - -class KonkeMotionB(CustomDevice): - """Custom device representing konke motion sensors.""" - - def __init__(self, *args, **kwargs): + def __init__(self, *args: Any, **kwargs: Any) -> None: """Init.""" self.occupancy_bus = Bus() super().__init__(*args, **kwargs) - signature = { - # - MODELS_INFO: [ - (KONKE, "3AFE28010402000D"), - (KONKE, "3AFE14010402000D"), - (KONKE, "3AFE27010402000D"), - ], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - IasZone.cluster_id, - ], - OUTPUT_CLUSTERS: [Identify.cluster_id], - } - }, - } - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfigurationCluster, - Identify.cluster_id, - OccupancyCluster, - MotionCluster, - ], - OUTPUT_CLUSTERS: [Identify.cluster_id], - } - } - } +( + QuirkBuilder(KONKE, "3AFE28010402000D") + .applies_to(KONKE, "3AFE14010402000D") + .applies_to(KONKE, "3AFE27010402000D") + .device_class(KonkeMotionDevice) + .replaces( + PowerConfigurationCluster, + cluster_id=PowerConfiguration.cluster_id, + endpoint_id=1, + ) + .replaces(MotionCluster, cluster_id=IasZone.cluster_id, endpoint_id=1) + .adds(OccupancyCluster, endpoint_id=1) + .add_to_registry() +) diff --git a/zhaquirks/konke/temp.py b/zhaquirks/konke/temp.py index 3ea117f92d..5fc558a75d 100644 --- a/zhaquirks/konke/temp.py +++ b/zhaquirks/konke/temp.py @@ -1,60 +1,13 @@ """Konke temp and humidity sensor.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import Basic, Identify, PowerConfiguration -from zigpy.zcl.clusters.measurement import RelativeHumidity, TemperatureMeasurement +from zigpy.quirks.v2 import QuirkBuilder from zhaquirks import PowerConfigurationCluster -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.konke import KONKE - -class KonkeTempHumidity(CustomDevice): - """Custom device representing konke temp and humidity sensors.""" - - signature = { - # - MODELS_INFO: [(KONKE, "3AFE140103020000"), (KONKE, "3AFE220103020000")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.TEMPERATURE_SENSOR, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - TemperatureMeasurement.cluster_id, - RelativeHumidity.cluster_id, - ], - OUTPUT_CLUSTERS: [Identify.cluster_id], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.TEMPERATURE_SENSOR, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfigurationCluster, - Identify.cluster_id, - TemperatureMeasurement.cluster_id, - RelativeHumidity.cluster_id, - ], - OUTPUT_CLUSTERS: [Identify.cluster_id], - } - } - } +( + QuirkBuilder(KONKE, "3AFE140103020000") + .applies_to(KONKE, "3AFE220103020000") + .replaces(PowerConfigurationCluster, endpoint_id=1) + .add_to_registry() +) diff --git a/zhaquirks/lds/cctswitch.py b/zhaquirks/lds/cctswitch.py index 1d7042cbd2..198baafcf0 100644 --- a/zhaquirks/lds/cctswitch.py +++ b/zhaquirks/lds/cctswitch.py @@ -1,18 +1,6 @@ """Device handler for CCS-Switch-D0001 remote control.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - Groups, - Identify, - LevelControl, - OnOff, - Ota, - PowerConfiguration, -) -from zigpy.zcl.clusters.lighting import Color -from zigpy.zcl.clusters.lightlink import LightLink +from zigpy.quirks.v2 import QuirkBuilder from zhaquirks.const import ( ARGS, @@ -24,114 +12,56 @@ COMMAND_STEP, COMMAND_STEP_ON_OFF, COMMAND_TOGGLE, - DEVICE_TYPE, DIM_DOWN, DIM_UP, ENDPOINT_ID, - ENDPOINTS, - INPUT_CLUSTERS, LONG_PRESS, - MODELS_INFO, - OUTPUT_CLUSTERS, PARAMS, - PROFILE_ID, SHORT_PRESS, TURN_ON, ) from zhaquirks.lds import MANUFACTURER - -class CCTSwitch(CustomDevice): - """Custom device representing CCTSwitch-D0001 remote control.""" - - signature = { - # - MODELS_INFO: [(MANUFACTURER, "ZBT-CCTSwitch-D0001")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.COLOR_CONTROLLER, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - LightLink.cluster_id, - 0xFD01, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - Color.cluster_id, - LightLink.cluster_id, - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.COLOR_CONTROLLER, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - LightLink.cluster_id, - 0xFD01, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - Color.cluster_id, - LightLink.cluster_id, - ], - } +( + QuirkBuilder(MANUFACTURER, "ZBT-CCTSwitch-D0001") + .device_automation_triggers( + { + (SHORT_PRESS, TURN_ON): { + COMMAND: COMMAND_TOGGLE, + CLUSTER_ID: 6, + ENDPOINT_ID: 1, + }, + (LONG_PRESS, TURN_ON): { + COMMAND: COMMAND_RELEASE, + CLUSTER_ID: 5, + ENDPOINT_ID: 1, + ARGS: [], + }, + (SHORT_PRESS, DIM_UP): { + COMMAND: COMMAND_STEP_ON_OFF, + CLUSTER_ID: 8, + ENDPOINT_ID: 1, + PARAMS: {"step_mode": 0}, + }, + (LONG_PRESS, DIM_UP): { + COMMAND: COMMAND_MOVE_ON_OFF, + CLUSTER_ID: 8, + ENDPOINT_ID: 1, + PARAMS: {"move_mode": 0}, + }, + (SHORT_PRESS, DIM_DOWN): { + COMMAND: COMMAND_STEP, + CLUSTER_ID: 8, + ENDPOINT_ID: 1, + PARAMS: {"step_mode": 1}, + }, + (LONG_PRESS, DIM_DOWN): { + COMMAND: COMMAND_MOVE, + CLUSTER_ID: 8, + ENDPOINT_ID: 1, + PARAMS: {"move_mode": 1}, + }, } - } - - device_automation_triggers = { - (SHORT_PRESS, TURN_ON): { - COMMAND: COMMAND_TOGGLE, - CLUSTER_ID: 6, - ENDPOINT_ID: 1, - }, - (LONG_PRESS, TURN_ON): { - COMMAND: COMMAND_RELEASE, - CLUSTER_ID: 5, - ENDPOINT_ID: 1, - ARGS: [], - }, - (SHORT_PRESS, DIM_UP): { - COMMAND: COMMAND_STEP_ON_OFF, - CLUSTER_ID: 8, - ENDPOINT_ID: 1, - PARAMS: {"step_mode": 0}, - }, - (LONG_PRESS, DIM_UP): { - COMMAND: COMMAND_MOVE_ON_OFF, - CLUSTER_ID: 8, - ENDPOINT_ID: 1, - PARAMS: {"move_mode": 0}, - }, - (SHORT_PRESS, DIM_DOWN): { - COMMAND: COMMAND_STEP, - CLUSTER_ID: 8, - ENDPOINT_ID: 1, - PARAMS: {"step_mode": 1}, - }, - (LONG_PRESS, DIM_DOWN): { - COMMAND: COMMAND_MOVE, - CLUSTER_ID: 8, - ENDPOINT_ID: 1, - PARAMS: {"move_mode": 1}, - }, - } + ) + .add_to_registry() +) diff --git a/zhaquirks/ledvance/a19rgbw.py b/zhaquirks/ledvance/a19rgbw.py index 63a61da505..d9fe8eca28 100644 --- a/zhaquirks/ledvance/a19rgbw.py +++ b/zhaquirks/ledvance/a19rgbw.py @@ -1,75 +1,11 @@ """Ledvance A19 RGBW device.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - Groups, - Identify, - LevelControl, - OnOff, - Ota, - Scenes, -) -from zigpy.zcl.clusters.homeautomation import Diagnostic -from zigpy.zcl.clusters.lighting import Color +from zigpy.quirks.v2 import QuirkBuilder -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.ledvance import LEDVANCE, LedvanceLightCluster - -class LedvanceA19RGBW(CustomDevice): - """Ledvance A19 RGBW device.""" - - signature = { - # - MODELS_INFO: [(LEDVANCE, "A19 RGBW")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.COLOR_DIMMABLE_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Color.cluster_id, - Diagnostic.cluster_id, - LedvanceLightCluster.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.COLOR_DIMMABLE_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Color.cluster_id, - Diagnostic.cluster_id, - LedvanceLightCluster, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - } - } +( + QuirkBuilder(LEDVANCE, "A19 RGBW") + .replaces(LedvanceLightCluster, endpoint_id=1) + .add_to_registry() +) diff --git a/zhaquirks/ledvance/flexrgbw.py b/zhaquirks/ledvance/flexrgbw.py index dadf663d8f..370bc38cfc 100644 --- a/zhaquirks/ledvance/flexrgbw.py +++ b/zhaquirks/ledvance/flexrgbw.py @@ -1,75 +1,11 @@ """Ledvance flex rgbw device.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - Groups, - Identify, - LevelControl, - OnOff, - Ota, - Scenes, -) -from zigpy.zcl.clusters.homeautomation import Diagnostic -from zigpy.zcl.clusters.lighting import Color +from zigpy.quirks.v2 import QuirkBuilder -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.ledvance import LEDVANCE, LedvanceLightCluster - -class FlexRGBW(CustomDevice): - """Ledvance Flex RGBW LED strip.""" - - signature = { - # - MODELS_INFO: [(LEDVANCE, "FLEX RGBW")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.COLOR_DIMMABLE_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Color.cluster_id, - LedvanceLightCluster.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.COLOR_DIMMABLE_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Color.cluster_id, - LedvanceLightCluster, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - } - } +( + QuirkBuilder(LEDVANCE, "FLEX RGBW") + .replaces(LedvanceLightCluster, endpoint_id=1) + .add_to_registry() +) diff --git a/zhaquirks/legrand/dimmer.py b/zhaquirks/legrand/dimmer.py index c254662fc2..e7fb60efe2 100644 --- a/zhaquirks/legrand/dimmer.py +++ b/zhaquirks/legrand/dimmer.py @@ -1,284 +1,28 @@ """Module for Legrand dimmers.""" -from zigpy.profiles import zgp, zha -from zigpy.quirks import CustomDevice from zigpy.quirks.v2 import QuirkBuilder -from zigpy.zcl.clusters.general import ( - Basic, - BinaryInput, - GreenPowerProxy, - Groups, - Identify, - LevelControl, - OnOff, - Ota, - PollControl, - Scenes, -) +from zigpy.zcl import ClusterType +from zigpy.zcl.clusters.general import BinaryInput, OnOff from zigpy.zcl.clusters.lighting import Ballast -from zhaquirks import PowerConfigurationCluster -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.legrand import ( LEGRAND, - MANUFACTURER_SPECIFIC_CLUSTER_ID, DeviceMode, LegrandCluster, LegrandIdentify, LegrandPowerConfigurationCluster, ) - -class DimmerWithoutNeutral(CustomDevice): - """Dimmer switch w/o neutral.""" - - signature = { - # - MODELS_INFO: [(f" {LEGRAND}", " Dimmer switch w/o neutral")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Scenes.cluster_id, - BinaryInput.cluster_id, - MANUFACTURER_SPECIFIC_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Basic.cluster_id, - MANUFACTURER_SPECIFIC_CLUSTER_ID, - Ota.cluster_id, - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Scenes.cluster_id, - BinaryInput.cluster_id, - LegrandCluster, - ], - OUTPUT_CLUSTERS: [Basic.cluster_id, LegrandCluster, Ota.cluster_id], - } - } - } - - -class DimmerWithoutNeutral2(DimmerWithoutNeutral): - """Dimmer switch w/o neutral 2.""" - - signature = { - # - MODELS_INFO: [(f" {LEGRAND}", " Dimmer switch w/o neutral")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Scenes.cluster_id, - BinaryInput.cluster_id, - MANUFACTURER_SPECIFIC_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Basic.cluster_id, - MANUFACTURER_SPECIFIC_CLUSTER_ID, - Ota.cluster_id, - ], - }, - 242: { - PROFILE_ID: zgp.PROFILE_ID, - DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC, - INPUT_CLUSTERS: [], - OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id], - }, - }, - } - - -class DimmerWithoutNeutral3(CustomDevice): - """Dimmer switch w/o neutral (at least for firmware 0x2e and above).""" - - signature = { - # - MODELS_INFO: [(f" {LEGRAND}", " Dimmer switch w/o neutral")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Scenes.cluster_id, - BinaryInput.cluster_id, - MANUFACTURER_SPECIFIC_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Basic.cluster_id, - MANUFACTURER_SPECIFIC_CLUSTER_ID, - Ota.cluster_id, - OnOff.cluster_id, - Scenes.cluster_id, - ], - }, - 242: { - PROFILE_ID: zgp.PROFILE_ID, - DEVICE_TYPE: zgp.DeviceType.COMBO_BASIC, - INPUT_CLUSTERS: [GreenPowerProxy.cluster_id], - OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id], - }, - }, - } - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Scenes.cluster_id, - BinaryInput.cluster_id, - # Some devices with firmware 0x39 have Ballast cluster, - # but some of them don't. But in any case Ballast works, - # if we add it here. - Ballast.cluster_id, - LegrandCluster, - ], - OUTPUT_CLUSTERS: [ - Basic.cluster_id, - LegrandCluster, - Ota.cluster_id, - OnOff.cluster_id, - Scenes.cluster_id, - ], - }, - # Green Power End Point - 242: { - PROFILE_ID: zgp.PROFILE_ID, - DEVICE_TYPE: zgp.DeviceType.COMBO_BASIC, - INPUT_CLUSTERS: [GreenPowerProxy.cluster_id], - OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id], - }, - }, - } - - -class DimmerWithoutNeutralAndBallast(CustomDevice): - """Dimmer switch w/o neutral (at least for firmware 0x39).""" - - signature = { - # - MODELS_INFO: [(f" {LEGRAND}", " Dimmer switch w/o neutral")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Scenes.cluster_id, - BinaryInput.cluster_id, - Ballast.cluster_id, - MANUFACTURER_SPECIFIC_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Basic.cluster_id, - MANUFACTURER_SPECIFIC_CLUSTER_ID, - Ota.cluster_id, - OnOff.cluster_id, - Scenes.cluster_id, - ], - }, - 242: { - PROFILE_ID: zgp.PROFILE_ID, - DEVICE_TYPE: zgp.DeviceType.COMBO_BASIC, - INPUT_CLUSTERS: [GreenPowerProxy.cluster_id], - OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id], - }, - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Scenes.cluster_id, - BinaryInput.cluster_id, - Ballast.cluster_id, - LegrandCluster, - ], - OUTPUT_CLUSTERS: [ - Basic.cluster_id, - LegrandCluster, - Ota.cluster_id, - OnOff.cluster_id, - Scenes.cluster_id, - ], - }, - # Green Power End Point - 242: { - PROFILE_ID: zgp.PROFILE_ID, - DEVICE_TYPE: zgp.DeviceType.COMBO_BASIC, - INPUT_CLUSTERS: [GreenPowerProxy.cluster_id], - OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id], - }, - }, - } +# Some devices with firmware 0x39 have Ballast cluster, +# but some of them don't. But in any case Ballast works, +# if we add it here. +( + QuirkBuilder(f" {LEGRAND}", " Dimmer switch w/o neutral") + .replaces(LegrandCluster, endpoint_id=1) + .replaces(LegrandCluster, cluster_type=ClusterType.Client, endpoint_id=1) + .adds(Ballast, endpoint_id=1) + .add_to_registry() +) ( @@ -315,58 +59,10 @@ class DimmerWithoutNeutralAndBallast(CustomDevice): ) -class RemoteDimmer(CustomDevice): - """Remote dimmer .""" - - signature = { - MODELS_INFO: [(f" {LEGRAND}", " Remote dimmer switch")], - ENDPOINTS: { - 1: { - # "profile_id": 260, - # "device_type": "0x0104", - # "in_clusters": ["0x0000","0x0001","0x0003","0x000f","0x0020","0xfc01"], - # "out_clusters": ["0x0000","0x0003","0x0006","0x0008","0x0019","0xfc01"] - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.DIMMER_SWITCH, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfigurationCluster.cluster_id, - Identify.cluster_id, - BinaryInput.cluster_id, - PollControl.cluster_id, - LegrandCluster.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - LegrandCluster.cluster_id, - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - LegrandPowerConfigurationCluster, - Identify.cluster_id, - BinaryInput.cluster_id, - PollControl.cluster_id, - LegrandCluster, - ], - OUTPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - LegrandCluster, - ], - } - } - } +( + QuirkBuilder(f" {LEGRAND}", " Remote dimmer switch") + .replaces(LegrandPowerConfigurationCluster, endpoint_id=1) + .replaces(LegrandCluster, endpoint_id=1) + .replaces(LegrandCluster, cluster_type=ClusterType.Client, endpoint_id=1) + .add_to_registry() +) diff --git a/zhaquirks/lidl/TS0501A.py b/zhaquirks/lidl/TS0501A.py index 38f6900b1b..46286268b2 100644 --- a/zhaquirks/lidl/TS0501A.py +++ b/zhaquirks/lidl/TS0501A.py @@ -1,91 +1,12 @@ """Lidl dimmable bulb.""" -from zigpy.profiles import zgp, zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - GreenPowerProxy, - Groups, - Identify, - LevelControl, - OnOff, - Ota, - Scenes, - Time, -) +from zigpy.quirks.v2 import QuirkBuilder from zigpy.zcl.clusters.lighting import Color -from zigpy.zcl.clusters.lightlink import LightLink -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, +( + QuirkBuilder("_TZ3000_nosnx7im", "TS0501A") + .applies_to("_TZ3000_nbnmw9nc", "TS0501A") + .applies_to("_TZ3000_7dcddnye", "TS0501A") + .removes(Color, endpoint_id=1) + .add_to_registry() ) - - -class DimmableBulb(CustomDevice): - """Lidl dimmable bulb.""" - - signature = { - MODELS_INFO: [ - ("_TZ3000_nosnx7im", "TS0501A"), - ("_TZ3000_nbnmw9nc", "TS0501A"), - ("_TZ3000_7dcddnye", "TS0501A"), - ], - ENDPOINTS: { - # - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.DIMMABLE_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Color.cluster_id, - LightLink.cluster_id, - ], - OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id], - }, - 242: { - # - MODELS_INFO: [("LK", "A001082")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfigurationCluster.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - IasZone.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - LinkindBasicCluster, - PowerConfigurationCluster.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - IasZone.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - }, - } +( + QuirkBuilder("LK", "A001082") + .replaces(LinkindBasicCluster, endpoint_id=1) + .add_to_registry() +) diff --git a/zhaquirks/linkind/motion.py b/zhaquirks/linkind/motion.py index 49ed8dd459..a3b567e57c 100644 --- a/zhaquirks/linkind/motion.py +++ b/zhaquirks/linkind/motion.py @@ -1,25 +1,9 @@ """Linkind Motion Sensors.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomCluster, CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - Identify, - Ota, - PollControl, - PowerConfiguration, -) -from zigpy.zcl.clusters.homeautomation import Diagnostic +from zigpy.quirks import CustomCluster +from zigpy.quirks.v2 import QuirkBuilder from zigpy.zcl.clusters.security import IasZone -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.linkind import LinkindBasicCluster LINKIND_CLUSTER_ID = 0xFC81 @@ -39,48 +23,9 @@ def _update_attribute(self, attrid, value): super()._update_attribute(attrid, value) -class LinkindD0003(CustomDevice): - """Linkind ZB-MotionSensor-D0003.""" - - signature = { - MODELS_INFO: [("lk", "ZB-MotionSensor-D0003")], - # - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - IasZone.cluster_id, - Diagnostic.cluster_id, - LINKIND_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - LinkindBasicCluster, - PowerConfiguration.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - IasZoneLinkind, - Diagnostic.cluster_id, - LINKIND_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - }, - } +( + QuirkBuilder("lk", "ZB-MotionSensor-D0003") + .replaces(LinkindBasicCluster, endpoint_id=1) + .replaces(IasZoneLinkind, endpoint_id=1) + .add_to_registry() +) diff --git a/zhaquirks/linxura/button.py b/zhaquirks/linxura/button.py index 5d1a2f6e61..6d81fa49d4 100644 --- a/zhaquirks/linxura/button.py +++ b/zhaquirks/linxura/button.py @@ -1,8 +1,7 @@ """Linxura button device.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomCluster, CustomDevice -from zigpy.zcl.clusters.general import Basic +from zigpy.quirks import CustomCluster +from zigpy.quirks.v2 import QuirkBuilder from zigpy.zcl.clusters.security import IasZone from zhaquirks.const import ( @@ -13,15 +12,9 @@ BUTTON_4, CLUSTER_ID, COMMAND, - DEVICE_TYPE, DOUBLE_PRESS, - ENDPOINTS, - INPUT_CLUSTERS, LONG_PRESS, - MODELS_INFO, - OUTPUT_CLUSTERS, PRESS_TYPE, - PROFILE_ID, SHORT_PRESS, ZHA_SEND_EVENT, ) @@ -64,46 +57,18 @@ def _update_attribute(self, attrid, value): self.listener_event(ZHA_SEND_EVENT, action, event_args) -class LinxuraButton(CustomDevice): - """Linxura button device.""" - - signature = { - # input_clusters=[0, 1280] - # output_clusters=[3]>=>output_clusters=[] - MODELS_INFO: [(LINXURA, "Smart Controller")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - IasZone.cluster_id, - ], - OUTPUT_CLUSTERS: [], - }, - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - INPUT_CLUSTERS: [ - Basic.cluster_id, - LinxuraIASCluster, - ], - OUTPUT_CLUSTERS: [], - }, - } - } - - device_automation_triggers = { - (press_type, button): { - COMMAND: f"{button}_{press_type}", - CLUSTER_ID: IasZone.cluster_id, +( + QuirkBuilder(LINXURA, "Smart Controller") + .replaces(LinxuraIASCluster, endpoint_id=1) + .device_automation_triggers( + { + (press_type, button): { + COMMAND: f"{button}_{press_type}", + CLUSTER_ID: IasZone.cluster_id, + } + for press_type in (SHORT_PRESS, DOUBLE_PRESS, LONG_PRESS) + for button in (BUTTON_1, BUTTON_2, BUTTON_3, BUTTON_4) } - for press_type in (SHORT_PRESS, DOUBLE_PRESS, LONG_PRESS) - for button in (BUTTON_1, BUTTON_2, BUTTON_3, BUTTON_4) - } + ) + .add_to_registry() +) diff --git a/zhaquirks/lixee/zlinky.py b/zhaquirks/lixee/zlinky.py index 1dae5bb3ef..577101a64b 100644 --- a/zhaquirks/lixee/zlinky.py +++ b/zhaquirks/lixee/zlinky.py @@ -1,33 +1,15 @@ """Quirk for ZLinky_TIC.""" -from copy import deepcopy from typing import Final -from zigpy.profiles import zgp, zha -from zigpy.quirks import CustomCluster, CustomDevice +from zigpy.quirks import CustomCluster +from zigpy.quirks.v2 import QuirkBuilder import zigpy.types as t -from zigpy.zcl.clusters.general import ( - Basic, - GreenPowerProxy, - Identify, - Ota, - PowerConfiguration, - Time, -) -from zigpy.zcl.clusters.homeautomation import ElectricalMeasurement, MeterIdentification +from zigpy.zcl.clusters.general import PowerConfiguration from zigpy.zcl.clusters.smartenergy import Metering from zigpy.zcl.foundation import BaseAttributeDefs, ZCLAttributeDef -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.lixee import LIXEE, ZLINKY_MANUFACTURER_CLUSTER_ID -from zhaquirks.tuya import TuyaManufCluster class ZLinkyTICManufacturerCluster(CustomCluster): @@ -225,89 +207,11 @@ class ZLinkyTICMetering(CustomCluster, Metering): _CONSTANT_ATTRIBUTES = {MULTIPLIER: 1, DIVISOR: 1000} -class ZLinkyTIC(CustomDevice): - """ZLinky_TIC from LiXee.""" - - signature = { - MODELS_INFO: [(LIXEE, "ZLinky_TIC")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.METER_INTERFACE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Metering.cluster_id, - MeterIdentification.cluster_id, - ElectricalMeasurement.cluster_id, - ZLinkyTICManufacturerCluster.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - }, - 242: { - PROFILE_ID: zgp.PROFILE_ID, - DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC, - INPUT_CLUSTERS: [GreenPowerProxy.cluster_id], - OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id], - }, - }, - } - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.METER_INTERFACE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - ZLinkyTICMetering, - MeterIdentification.cluster_id, - ElectricalMeasurement.cluster_id, - ZLinkyTICManufacturerCluster, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - }, - 242: { - PROFILE_ID: zgp.PROFILE_ID, - DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC, - INPUT_CLUSTERS: [GreenPowerProxy.cluster_id], - OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id], - }, - }, - } - - -class ZLinkyTICFWV12(ZLinkyTIC): - """ZLinky_TIC from LiXee with firmware v12.0 & v13.0.""" - - signature = deepcopy(ZLinkyTIC.signature) - - # Insert PowerConfiguration cluster in signature for devices with firmware v12.0 & v13.0 - signature[ENDPOINTS][1][INPUT_CLUSTERS].insert(1, PowerConfiguration.cluster_id) - - -class ZLinkyTICFWV14(ZLinkyTICFWV12): - """ZLinky_TIC from LiXee with firmware v14.0+.""" - - signature = deepcopy(ZLinkyTICFWV12.signature) - replacement = deepcopy(ZLinkyTICFWV12.replacement) - - # Insert Time configuration cluster in signature for devices with firmware v14.0+ - signature[ENDPOINTS][1][INPUT_CLUSTERS].insert(1, Time.cluster_id) - - # Insert Tuya cluster in signature for devices with firmware v14.0+ - signature[ENDPOINTS][1][INPUT_CLUSTERS].insert(7, TuyaManufCluster.cluster_id) - signature[ENDPOINTS][1][OUTPUT_CLUSTERS].insert(1, TuyaManufCluster.cluster_id) - - replacement[ENDPOINTS][1][INPUT_CLUSTERS].insert(1, Time.cluster_id) - - -class ZLinkyTICFWV15(ZLinkyTICFWV14): - """ZLinky_TIC from LiXee with firmware v15.0+.""" - - signature = deepcopy(ZLinkyTICFWV14.signature) - replacement = deepcopy(ZLinkyTICFWV14.replacement) - - signature[ENDPOINTS][1][DEVICE_TYPE] = zha.DeviceType.DIMMABLE_LIGHT - replacement[ENDPOINTS][1][DEVICE_TYPE] = zha.DeviceType.DIMMABLE_LIGHT +( + QuirkBuilder(LIXEE, "ZLinky_TIC") + # Not all firmware variants have a power configuration cluster + .adds(PowerConfiguration.cluster_id, endpoint_id=1) + .replaces(ZLinkyTICMetering, endpoint_id=1) + .replaces(ZLinkyTICManufacturerCluster, endpoint_id=1) + .add_to_registry() +) diff --git a/zhaquirks/lutron/lzl4bwhl01remote.py b/zhaquirks/lutron/lzl4bwhl01remote.py index 1cc730c6ad..c3bace09c7 100644 --- a/zhaquirks/lutron/lzl4bwhl01remote.py +++ b/zhaquirks/lutron/lzl4bwhl01remote.py @@ -1,16 +1,8 @@ """Device handler for Lutron LZL4BWHL01 Remote.""" -from zigpy.profiles import zll -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - Groups, - Identify, - LevelControl, - OnOff, - Scenes, -) -from zigpy.zcl.clusters.lightlink import LightLink +from zigpy.quirks.v2 import QuirkBuilder +from zigpy.zcl import ClusterType +from zigpy.zcl.clusters.general import LevelControl, OnOff from zhaquirks import GroupBoundCluster from zhaquirks.const import ( @@ -19,16 +11,10 @@ COMMAND_MOVE_TO_LEVEL_ON_OFF, COMMAND_STEP, COMMAND_STEP_ON_OFF, - DEVICE_TYPE, DIM_DOWN, DIM_UP, ENDPOINT_ID, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, PARAMS, - PROFILE_ID, SHORT_PRESS, TURN_OFF, TURN_ON, @@ -46,90 +32,38 @@ class LevelControlGroupCluster(GroupBoundCluster, LevelControl): """Level Control Cluster which only binds to a group.""" -class LutronLZL4BWHL01Remote(CustomDevice): - """Custom device representing Lutron LZL4BWHL01 Remote.""" - - signature = { - # - MODELS_INFO: [ - ("Lutron", "LZL4BWHL01 Remote"), - (" Lutron", "LZL4BWHL01 Remote"), - ], - ENDPOINTS: { - 1: { - PROFILE_ID: zll.PROFILE_ID, - DEVICE_TYPE: zll.DeviceType.CONTROLLER, - INPUT_CLUSTERS: [ - Basic.cluster_id, - LightLink.cluster_id, - MANUFACTURER_SPECIFIC_CLUSTER_ID_1, - MANUFACTURER_SPECIFIC_CLUSTER_ID_2, - ], - OUTPUT_CLUSTERS: [ - LightLink.cluster_id, - Identify.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - Basic.cluster_id, - MANUFACTURER_SPECIFIC_CLUSTER_ID_1, - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zll.PROFILE_ID, - DEVICE_TYPE: zll.DeviceType.CONTROLLER, - INPUT_CLUSTERS: [ - Basic.cluster_id, - LightLink.cluster_id, - MANUFACTURER_SPECIFIC_CLUSTER_ID_1, - MANUFACTURER_SPECIFIC_CLUSTER_ID_2, - ], - OUTPUT_CLUSTERS: [ - LightLink.cluster_id, - Identify.cluster_id, - OnOffGroupCluster, - LevelControlGroupCluster, - Groups.cluster_id, - Scenes.cluster_id, - Basic.cluster_id, - MANUFACTURER_SPECIFIC_CLUSTER_ID_1, - ], - } +( + QuirkBuilder("Lutron", "LZL4BWHL01 Remote") + .applies_to(" Lutron", "LZL4BWHL01 Remote") + .replaces(OnOffGroupCluster, cluster_type=ClusterType.Client, endpoint_id=1) + .replaces(LevelControlGroupCluster, cluster_type=ClusterType.Client, endpoint_id=1) + .device_automation_triggers( + { + (SHORT_PRESS, TURN_ON): { + COMMAND: COMMAND_MOVE_TO_LEVEL_ON_OFF, + CLUSTER_ID: 8, + ENDPOINT_ID: 1, + PARAMS: {"level": 254, "transition_time": 4}, + }, + (SHORT_PRESS, TURN_OFF): { + COMMAND: COMMAND_MOVE_TO_LEVEL_ON_OFF, + CLUSTER_ID: 8, + ENDPOINT_ID: 1, + PARAMS: {"level": 0, "transition_time": 4}, + }, + (SHORT_PRESS, DIM_UP): { + COMMAND: COMMAND_STEP_ON_OFF, + CLUSTER_ID: 8, + ENDPOINT_ID: 1, + PARAMS: {"step_mode": 0}, + }, + (SHORT_PRESS, DIM_DOWN): { + COMMAND: COMMAND_STEP, + CLUSTER_ID: 8, + ENDPOINT_ID: 1, + PARAMS: {"step_mode": 1}, + }, } - } - - device_automation_triggers = { - (SHORT_PRESS, TURN_ON): { - COMMAND: COMMAND_MOVE_TO_LEVEL_ON_OFF, - CLUSTER_ID: 8, - ENDPOINT_ID: 1, - PARAMS: {"level": 254, "transition_time": 4}, - }, - (SHORT_PRESS, TURN_OFF): { - COMMAND: COMMAND_MOVE_TO_LEVEL_ON_OFF, - CLUSTER_ID: 8, - ENDPOINT_ID: 1, - PARAMS: {"level": 0, "transition_time": 4}, - }, - (SHORT_PRESS, DIM_UP): { - COMMAND: COMMAND_STEP_ON_OFF, - CLUSTER_ID: 8, - ENDPOINT_ID: 1, - PARAMS: {"step_mode": 0}, - }, - (SHORT_PRESS, DIM_DOWN): { - COMMAND: COMMAND_STEP, - CLUSTER_ID: 8, - ENDPOINT_ID: 1, - PARAMS: {"step_mode": 1}, - }, - } + ) + .add_to_registry() +) diff --git a/zhaquirks/mli/tint.py b/zhaquirks/mli/tint.py index 9cc8383954..ce1bcd858d 100644 --- a/zhaquirks/mli/tint.py +++ b/zhaquirks/mli/tint.py @@ -1,29 +1,11 @@ """Tint remote.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomCluster, CustomDevice -from zigpy.zcl import foundation -from zigpy.zcl.clusters.general import ( - Basic, - Groups, - Identify, - LevelControl, - OnOff, - Ota, - Scenes, -) -from zigpy.zcl.clusters.lighting import Color -from zigpy.zcl.clusters.lightlink import LightLink +from zigpy.quirks import CustomCluster +from zigpy.quirks.v2 import CustomDeviceV2, QuirkBuilder +from zigpy.zcl import ClusterType, foundation +from zigpy.zcl.clusters.general import Basic, Scenes from zhaquirks import Bus, LocalDataCluster -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) TINT_SCENE_ATTR = 0x4005 @@ -58,7 +40,7 @@ def handle_cluster_general_request(self, hdr, args, *, dst_addressing=None): self.endpoint.device.scene_bus.listener_event("change_scene", value) -class TintRemote(CustomDevice): +class TintRemote(CustomDeviceV2): """Tint remote quirk.""" def __init__(self, *args, **kwargs): @@ -66,54 +48,11 @@ def __init__(self, *args, **kwargs): self.scene_bus = Bus() super().__init__(*args, **kwargs) - signature = { - # endpoint=1 profile=260 device_type=2048 device_version=1 input_clusters=[0, 3, 4096] - # output_clusters=[0, 3, 4, 5, 8, 25, 768, 4096] - MODELS_INFO: [("MLI", "ZBT-Remote-ALL-RGBW")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.COLOR_CONTROLLER, - INPUT_CLUSTERS: [ - Basic.cluster_id, # 0 - Identify.cluster_id, # 3 - LightLink.cluster_id, # 4096 - ], - OUTPUT_CLUSTERS: [ - Basic.cluster_id, # 0 - Identify.cluster_id, # 3 - Groups.cluster_id, # 4 - OnOff.cluster_id, # 6 - LevelControl.cluster_id, # 8 - Ota.cluster_id, # 25 - Color.cluster_id, # 768 - LightLink.cluster_id, # 4096 - ], - }, - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.COLOR_CONTROLLER, - INPUT_CLUSTERS: [ - TintRemoteBasicCluster, # 0 - Identify.cluster_id, # 3 - LightLink.cluster_id, # 4096 - ], - OUTPUT_CLUSTERS: [ - Basic.cluster_id, # 0 - Identify.cluster_id, # 3 - Groups.cluster_id, # 4 - TintRemoteScenesCluster, # 5 - OnOff.cluster_id, # 6 - LevelControl.cluster_id, # 8 - Ota.cluster_id, # 25 - Color.cluster_id, # 768 - LightLink.cluster_id, # 4096 - ], - }, - }, - } + +( + QuirkBuilder("MLI", "ZBT-Remote-ALL-RGBW") + .device_class(TintRemote) + .replaces(TintRemoteBasicCluster, endpoint_id=1) + .adds(TintRemoteScenesCluster, cluster_type=ClusterType.Client, endpoint_id=1) + .add_to_registry() +) diff --git a/zhaquirks/mli/tintE14rgbcct.py b/zhaquirks/mli/tintE14rgbcct.py index c5268e7b1d..c2ed68e5a5 100644 --- a/zhaquirks/mli/tintE14rgbcct.py +++ b/zhaquirks/mli/tintE14rgbcct.py @@ -1,34 +1,8 @@ """Tint E14 RGB CCT.""" -from zigpy.profiles import zgp, zha -from zigpy.quirks import CustomCluster, CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - GreenPowerProxy, - Groups, - Identify, - LevelControl, - OnOff, - Ota, - Scenes, -) +from zigpy.quirks import CustomCluster +from zigpy.quirks.v2 import QuirkBuilder from zigpy.zcl.clusters.lighting import Color -from zigpy.zcl.clusters.lightlink import LightLink - -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) - - -class TintManufacturerSpecificCluster(CustomCluster): - """Tint manufacturer specific cluster.""" - - cluster_id = 0x100F # not inside the manufacturer specific cluster range class TintRGBCCTColorCluster(CustomCluster, Color): @@ -39,60 +13,8 @@ class TintRGBCCTColorCluster(CustomCluster, Color): _CONSTANT_ATTRIBUTES = {0x400A: 0b11110} -class TintRGBCCTLight(CustomDevice): - """Tint E14 RGB+CCT Lighting device.""" - - signature = { - MODELS_INFO: [("MLI", "tint-ExtendedColor")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.EXTENDED_COLOR_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Color.cluster_id, - LightLink.cluster_id, - TintManufacturerSpecificCluster.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - }, - 242: { - PROFILE_ID: zgp.PROFILE_ID, - DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC, - INPUT_CLUSTERS: [], - OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id], - }, - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.EXTENDED_COLOR_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - TintRGBCCTColorCluster, - LightLink.cluster_id, - TintManufacturerSpecificCluster, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - }, - 242: { - PROFILE_ID: zgp.PROFILE_ID, - DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC, - INPUT_CLUSTERS: [], - OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id], - }, - } - } +( + QuirkBuilder("MLI", "tint-ExtendedColor") + .replaces(TintRGBCCTColorCluster, endpoint_id=1) + .add_to_registry() +) diff --git a/zhaquirks/netvox/z308e3ed.py b/zhaquirks/netvox/z308e3ed.py index ee1bcc99db..f5aa39a417 100755 --- a/zhaquirks/netvox/z308e3ed.py +++ b/zhaquirks/netvox/z308e3ed.py @@ -1,19 +1,8 @@ """Netvox device.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import Basic, Commissioning, Identify, PollControl -from zigpy.zcl.clusters.homeautomation import Diagnostic -from zigpy.zcl.clusters.security import IasZone +from zigpy.quirks.v2 import QuirkBuilder from zhaquirks import PowerConfigurationCluster -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - OUTPUT_CLUSTERS, - PROFILE_ID, -) class CustomPowerConfigurationCluster(PowerConfigurationCluster): @@ -23,44 +12,8 @@ class CustomPowerConfigurationCluster(PowerConfigurationCluster): MAX_VOLTS = 3.0 -class Z308E3ED(CustomDevice): - """Netvox Z308E3ED.""" - - signature = { - # - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - CustomPowerConfigurationCluster.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - IasZone.cluster_id, - Commissioning.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [], - } - } - } - - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - CustomPowerConfigurationCluster, - Identify.cluster_id, - PollControl.cluster_id, - IasZone.cluster_id, - Commissioning.cluster_id, - Diagnostic.cluster_id, - ] - } - } - } +( + QuirkBuilder("Netvox", "Z308E3ED") + .replaces(CustomPowerConfigurationCluster, endpoint_id=1) + .add_to_registry() +) diff --git a/zhaquirks/nue/auwz02000.py b/zhaquirks/nue/auwz02000.py index 4fba9fc847..f426d18220 100644 --- a/zhaquirks/nue/auwz02000.py +++ b/zhaquirks/nue/auwz02000.py @@ -1,88 +1,13 @@ """Nue / 3A Smart Home - Double GPO Quirk.""" from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import Basic, Groups, Identify, OnOff, Ota, Scenes -from zigpy.zcl.clusters.lightlink import LightLink - -from ..const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, +from zigpy.quirks.v2 import QuirkBuilder + +( + QuirkBuilder("3A Smart Home DE", "LXN56-TS27LX1.2") + # Was ON_OFF_LIGHT + .replaces_endpoint(1, device_type=zha.DeviceType.MAIN_POWER_OUTLET) + # Was ON_OFF_LIGHT + .replaces_endpoint(2, device_type=zha.DeviceType.MAIN_POWER_OUTLET) + .add_to_registry() ) - - -class auwz02000(CustomDevice): - """Model NUE-AUWZ02-000 Double GPO - Australia plug.""" - - signature = { - MODELS_INFO: [("3A Smart Home DE", "LXN56-TS27LX1.2")], - ENDPOINTS: { - # - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LightLink.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - }, - # - 2: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - }, - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.MAIN_POWER_OUTLET, # 0x0009 - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LightLink.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - }, - 2: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.MAIN_POWER_OUTLET, # 0x0009 - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - }, - } - } diff --git a/zhaquirks/orvibo/dimmer.py b/zhaquirks/orvibo/dimmer.py index 9efa1fe82a..ea02a6fbc0 100644 --- a/zhaquirks/orvibo/dimmer.py +++ b/zhaquirks/orvibo/dimmer.py @@ -1,59 +1,14 @@ """ORVIBO dimmers.""" from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import Basic, Groups, LevelControl, OnOff, Scenes +from zigpy.quirks.v2 import QuirkBuilder from zigpy.zcl.clusters.lighting import Color -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.orvibo import ORVIBO - -class T10D1ZW(CustomDevice): - """T10D1ZW in-wall dimmer.""" - - signature = { - # - MODELS_INFO: [(ORVIBO, "abb71ca5fe1846f185cfbda554046cce")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.LEVEL_CONTROL_SWITCH, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Color.cluster_id, - ], - OUTPUT_CLUSTERS: [Basic.cluster_id], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - DEVICE_TYPE: zha.DeviceType.DIMMABLE_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - ], - OUTPUT_CLUSTERS: [Basic.cluster_id], - } - } - } +( + QuirkBuilder(ORVIBO, "abb71ca5fe1846f185cfbda554046cce") + .replaces_endpoint(endpoint_id=1, device_type=zha.DeviceType.DIMMABLE_LIGHT) + .removes(Color.cluster_id, endpoint_id=1) + .add_to_registry() +) diff --git a/zhaquirks/orvibo/motion.py b/zhaquirks/orvibo/motion.py index e10dd282aa..902bb43e50 100644 --- a/zhaquirks/orvibo/motion.py +++ b/zhaquirks/orvibo/motion.py @@ -3,84 +3,37 @@ Based on Konke motion sensor code. """ -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - Groups, - Identify, - PowerConfiguration, - Scenes, -) +from typing import Any + +from zigpy.quirks.v2 import CustomDeviceV2, QuirkBuilder +from zigpy.zcl.clusters.general import PowerConfiguration from zigpy.zcl.clusters.security import IasZone from zhaquirks import Bus, PowerConfigurationCluster -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.orvibo import ORVIBO_LATIN, MotionCluster, OccupancyCluster ORVIBO_CLUSTER_ID = 0xFFFF -class SN10ZW(CustomDevice): - """SN10ZW motion sensor.""" +class OrviboMotionDevice(CustomDeviceV2): + """Custom device class for ORVIBO motion sensors that need occupancy_bus.""" - def __init__(self, *args, **kwargs): + def __init__(self, *args: Any, **kwargs: Any) -> None: """Init.""" self.occupancy_bus = Bus() super().__init__(*args, **kwargs) - signature = { - # - MODELS_INFO: [(ORVIBO_LATIN, "895a2d80097f4ae2b2d40500d5e03dcc")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - IasZone.cluster_id, - ORVIBO_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - ], - } - }, - } - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfigurationCluster, - Identify.cluster_id, - OccupancyCluster, - MotionCluster, - ], - OUTPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - ], - } - } - } +( + QuirkBuilder(ORVIBO_LATIN, "895a2d80097f4ae2b2d40500d5e03dcc") + .device_class(OrviboMotionDevice) + .replaces( + PowerConfigurationCluster, + cluster_id=PowerConfiguration.cluster_id, + endpoint_id=1, + ) + .replaces(MotionCluster, cluster_id=IasZone.cluster_id, endpoint_id=1) + .removes(ORVIBO_CLUSTER_ID, endpoint_id=1) + .adds(OccupancyCluster, endpoint_id=1) + .add_to_registry() +) diff --git a/zhaquirks/osram/a19rgbw.py b/zhaquirks/osram/a19rgbw.py index be77c85fc3..3ea3eb3a03 100644 --- a/zhaquirks/osram/a19rgbw.py +++ b/zhaquirks/osram/a19rgbw.py @@ -1,72 +1,11 @@ """Osram LIGHTIFY A19 RGBW device.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - Groups, - Identify, - LevelControl, - OnOff, - Ota, - Scenes, -) -from zigpy.zcl.clusters.lighting import Color +from zigpy.quirks.v2 import QuirkBuilder -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.osram import OSRAM, OsramLightCluster - -class LIGHTIFYA19RGBW(CustomDevice): - """Osram LIGHTIFY A19 RGBW device.""" - - signature = { - # - MODELS_INFO: [(OSRAM, "LIGHTIFY A19 RGBW")], - ENDPOINTS: { - 3: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.COLOR_DIMMABLE_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Color.cluster_id, - OsramLightCluster.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - }, - } - - replacement = { - ENDPOINTS: { - 3: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.COLOR_DIMMABLE_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Color.cluster_id, - OsramLightCluster, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - } - } +( + QuirkBuilder(OSRAM, "LIGHTIFY A19 RGBW") + .replaces(OsramLightCluster, endpoint_id=3) + .add_to_registry() +) diff --git a/zhaquirks/osram/cla60tw.py b/zhaquirks/osram/cla60tw.py index 0f08a8d993..ab5da87b0a 100644 --- a/zhaquirks/osram/cla60tw.py +++ b/zhaquirks/osram/cla60tw.py @@ -1,75 +1,11 @@ """Osram CLA60 TW device.""" -from zigpy.profiles import zll -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - Groups, - Identify, - LevelControl, - OnOff, - Ota, - Scenes, -) -from zigpy.zcl.clusters.lighting import Color -from zigpy.zcl.clusters.lightlink import LightLink +from zigpy.quirks.v2 import QuirkBuilder -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.osram import OSRAM, OsramLightCluster - -class CLA60TW(CustomDevice): - """Osram CLA60 TW device.""" - - signature = { - # - MODELS_INFO: [(OSRAM, "CLA60 TW OSRAM")], - ENDPOINTS: { - 3: { - PROFILE_ID: zll.PROFILE_ID, - DEVICE_TYPE: zll.DeviceType.COLOR_TEMPERATURE_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Color.cluster_id, - LightLink.cluster_id, - OsramLightCluster.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - }, - } - - replacement = { - ENDPOINTS: { - 3: { - PROFILE_ID: zll.PROFILE_ID, - DEVICE_TYPE: zll.DeviceType.COLOR_TEMPERATURE_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Color.cluster_id, - LightLink.cluster_id, - OsramLightCluster, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - } - } +( + QuirkBuilder(OSRAM, "CLA60 TW OSRAM") + .replaces(OsramLightCluster, endpoint_id=3) + .add_to_registry() +) diff --git a/zhaquirks/osram/flexrgbw.py b/zhaquirks/osram/flexrgbw.py index 84802d7a00..196461214e 100644 --- a/zhaquirks/osram/flexrgbw.py +++ b/zhaquirks/osram/flexrgbw.py @@ -1,75 +1,12 @@ """Osram Flex RGBW LED strip.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - Groups, - Identify, - LevelControl, - OnOff, - Ota, - Scenes, -) -from zigpy.zcl.clusters.lighting import Color +from zigpy.quirks.v2 import QuirkBuilder -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.osram import OSRAM, OsramLightCluster - -class FlexRGBW(CustomDevice): - """Osram Flex RGBW LED strip.""" - - signature = { - # - MODELS_INFO: [ - (OSRAM, "LIGHTIFY Flex RGBW"), - (OSRAM, "LIGHTIFY FLEX OUTDOOR RGBW"), - ], - ENDPOINTS: { - 3: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.COLOR_DIMMABLE_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Color.cluster_id, - OsramLightCluster.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - }, - } - - replacement = { - ENDPOINTS: { - 3: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.COLOR_DIMMABLE_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Color.cluster_id, - OsramLightCluster, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - } - } +( + QuirkBuilder(OSRAM, "LIGHTIFY Flex RGBW") + .applies_to(OSRAM, "LIGHTIFY FLEX OUTDOOR RGBW") + .replaces(OsramLightCluster, endpoint_id=3) + .add_to_registry() +) diff --git a/zhaquirks/osram/gardenpolesrgbw.py b/zhaquirks/osram/gardenpolesrgbw.py index 8b760bb80d..3bb501d62b 100644 --- a/zhaquirks/osram/gardenpolesrgbw.py +++ b/zhaquirks/osram/gardenpolesrgbw.py @@ -1,75 +1,11 @@ """Osram RGBW Gardenpoles.""" -from zigpy.profiles import zll -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - Groups, - Identify, - LevelControl, - OnOff, - Ota, - Scenes, -) -from zigpy.zcl.clusters.lighting import Color -from zigpy.zcl.clusters.lightlink import LightLink +from zigpy.quirks.v2 import QuirkBuilder -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.osram import OSRAM, OsramLightCluster - -class GardenpoleRGBW(CustomDevice): - """Osram Gardenpole RGBW-Lightify.""" - - signature = { - # - MODELS_INFO: [(OSRAM, "Gardenpole RGBW-Lightify")], - ENDPOINTS: { - 3: { - PROFILE_ID: zll.PROFILE_ID, - DEVICE_TYPE: zll.DeviceType.EXTENDED_COLOR_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Color.cluster_id, - LightLink.cluster_id, - OsramLightCluster.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - }, - } - - replacement = { - ENDPOINTS: { - 3: { - PROFILE_ID: zll.PROFILE_ID, - DEVICE_TYPE: zll.DeviceType.EXTENDED_COLOR_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Color.cluster_id, - LightLink.cluster_id, - OsramLightCluster, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - } - } +( + QuirkBuilder(OSRAM, "Gardenpole RGBW-Lightify") + .replaces(OsramLightCluster, endpoint_id=1) + .add_to_registry() +) diff --git a/zhaquirks/osram/lightifyx4.py b/zhaquirks/osram/lightifyx4.py index 0343b66035..5e18f60d48 100644 --- a/zhaquirks/osram/lightifyx4.py +++ b/zhaquirks/osram/lightifyx4.py @@ -1,23 +1,8 @@ """Osram Lightify X4 device.""" -import copy - -from zigpy.profiles import zha -from zigpy.quirks import CustomCluster, CustomDevice +from zigpy.quirks import CustomCluster +from zigpy.quirks.v2 import QuirkBuilder import zigpy.types as t -from zigpy.zcl.clusters.general import ( - Basic, - Groups, - Identify, - LevelControl, - OnOff, - Ota, - PollControl, - PowerConfiguration, - Scenes, -) -from zigpy.zcl.clusters.lighting import Color -from zigpy.zcl.clusters.lightlink import LightLink from zigpy.zcl.foundation import BaseAttributeDefs, ZCLAttributeDef from zhaquirks.const import ( @@ -29,15 +14,9 @@ COMMAND_MOVE, COMMAND_ON, COMMAND_STOP, - DEVICE_TYPE, ENDPOINT_ID, - ENDPOINTS, - INPUT_CLUSTERS, LONG_PRESS, LONG_RELEASE, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, SHORT_PRESS, ) from zhaquirks.osram import OSRAM @@ -124,220 +103,58 @@ async def bind(self): return result -class LightifyX4(CustomDevice): - """Osram Lightify X4 device.""" - - SIGNATURE_ENDPOINT = { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: OSRAM_DEVICE, - INPUT_CLUSTERS: [Basic.cluster_id, LightLink.cluster_id, OSRAM_CLUSTER], - OUTPUT_CLUSTERS: [ - Groups.cluster_id, - Identify.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - Color.cluster_id, - LevelControl.cluster_id, - LightLink.cluster_id, - ], - } - - signature = { - # - MODELS_INFO: [(OSRAM, "Switch 4x-LIGHTIFY"), (OSRAM, "Switch 4x EU-LIGHTIFY")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: OSRAM_DEVICE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - PollControl.cluster_id, - LightLink.cluster_id, - OSRAM_CLUSTER, - ], - OUTPUT_CLUSTERS: [ - Groups.cluster_id, - Identify.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - Ota.cluster_id, - Color.cluster_id, - LevelControl.cluster_id, - LightLink.cluster_id, - ], - }, - # - 2: copy.deepcopy(SIGNATURE_ENDPOINT), - # - 3: copy.deepcopy(SIGNATURE_ENDPOINT), - # - 4: copy.deepcopy(SIGNATURE_ENDPOINT), - # - 5: copy.deepcopy(SIGNATURE_ENDPOINT), - # - 6: copy.deepcopy(SIGNATURE_ENDPOINT), - }, - } - - REPLACEMENT_ENDPOINT = { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: OSRAM_DEVICE, - INPUT_CLUSTERS: [Basic.cluster_id, LightLink.cluster_id, OsramButtonCluster], - OUTPUT_CLUSTERS: [ - Groups.cluster_id, - Identify.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - Color.cluster_id, - LevelControl.cluster_id, - LightLink.cluster_id, - ], - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: OSRAM_DEVICE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - PollControl.cluster_id, - LightLink.cluster_id, - OsramButtonCluster, - ], - OUTPUT_CLUSTERS: [ - Groups.cluster_id, - Identify.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - Ota.cluster_id, - Color.cluster_id, - LevelControl.cluster_id, - LightLink.cluster_id, - ], - }, - 2: copy.deepcopy(REPLACEMENT_ENDPOINT), - 3: copy.deepcopy(REPLACEMENT_ENDPOINT), - 4: copy.deepcopy(REPLACEMENT_ENDPOINT), - 5: copy.deepcopy(REPLACEMENT_ENDPOINT), - 6: copy.deepcopy(REPLACEMENT_ENDPOINT), +# V2 Quirks +( + QuirkBuilder(OSRAM, "Switch 4x-LIGHTIFY") + .applies_to(OSRAM, "Switch 4x EU-LIGHTIFY") + .replaces(OsramButtonCluster, cluster_id=OSRAM_CLUSTER, endpoint_id=1) + .replaces(OsramButtonCluster, cluster_id=OSRAM_CLUSTER, endpoint_id=2) + .replaces(OsramButtonCluster, cluster_id=OSRAM_CLUSTER, endpoint_id=3) + .replaces(OsramButtonCluster, cluster_id=OSRAM_CLUSTER, endpoint_id=4) + .replaces(OsramButtonCluster, cluster_id=OSRAM_CLUSTER, endpoint_id=5) + .replaces(OsramButtonCluster, cluster_id=OSRAM_CLUSTER, endpoint_id=6) + .device_automation_triggers( + { + (SHORT_PRESS, BUTTON_1): {COMMAND: COMMAND_ON, ENDPOINT_ID: 1}, + (SHORT_PRESS, BUTTON_2): {COMMAND: COMMAND_ON, ENDPOINT_ID: 2}, + (SHORT_PRESS, BUTTON_3): {COMMAND: COMMAND_ON, ENDPOINT_ID: 3}, + (SHORT_PRESS, BUTTON_4): {COMMAND: COMMAND_ON, ENDPOINT_ID: 4}, + (LONG_PRESS, BUTTON_1): {COMMAND: COMMAND_MOVE, ENDPOINT_ID: 1}, + (LONG_PRESS, BUTTON_2): {COMMAND: COMMAND_MOVE, ENDPOINT_ID: 2}, + (LONG_PRESS, BUTTON_3): {COMMAND: COMMAND_MOVE, ENDPOINT_ID: 3}, + (LONG_PRESS, BUTTON_4): {COMMAND: COMMAND_MOVE, ENDPOINT_ID: 4}, + (LONG_RELEASE, BUTTON_1): {COMMAND: COMMAND_STOP, ENDPOINT_ID: 1}, + (LONG_RELEASE, BUTTON_2): {COMMAND: COMMAND_STOP, ENDPOINT_ID: 2}, + (LONG_RELEASE, BUTTON_3): {COMMAND: COMMAND_STOP, ENDPOINT_ID: 3}, + (LONG_RELEASE, BUTTON_4): {COMMAND: COMMAND_STOP, ENDPOINT_ID: 4}, } - } - - device_automation_triggers = { - (SHORT_PRESS, BUTTON_1): {COMMAND: COMMAND_ON, ENDPOINT_ID: 1}, - (SHORT_PRESS, BUTTON_2): {COMMAND: COMMAND_ON, ENDPOINT_ID: 2}, - (SHORT_PRESS, BUTTON_3): {COMMAND: COMMAND_ON, ENDPOINT_ID: 3}, - (SHORT_PRESS, BUTTON_4): {COMMAND: COMMAND_ON, ENDPOINT_ID: 4}, - (LONG_PRESS, BUTTON_1): {COMMAND: COMMAND_MOVE, ENDPOINT_ID: 1}, - (LONG_PRESS, BUTTON_2): {COMMAND: COMMAND_MOVE, ENDPOINT_ID: 2}, - (LONG_PRESS, BUTTON_3): {COMMAND: COMMAND_MOVE, ENDPOINT_ID: 3}, - (LONG_PRESS, BUTTON_4): {COMMAND: COMMAND_MOVE, ENDPOINT_ID: 4}, - (LONG_RELEASE, BUTTON_1): {COMMAND: COMMAND_STOP, ENDPOINT_ID: 1}, - (LONG_RELEASE, BUTTON_2): {COMMAND: COMMAND_STOP, ENDPOINT_ID: 2}, - (LONG_RELEASE, BUTTON_3): {COMMAND: COMMAND_STOP, ENDPOINT_ID: 3}, - (LONG_RELEASE, BUTTON_4): {COMMAND: COMMAND_STOP, ENDPOINT_ID: 4}, - } - - -class LightifySwitch(CustomDevice): - """Osram Lightify Switch device.""" - - SIGNATURE_ENDPOINT = { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: OSRAM_DEVICE, - INPUT_CLUSTERS: [LightLink.cluster_id, OSRAM_CLUSTER], - OUTPUT_CLUSTERS: [ - Groups.cluster_id, - Identify.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - Color.cluster_id, - LevelControl.cluster_id, - LightLink.cluster_id, - ], - } - - signature = { - # - MODELS_INFO: [(OSRAM, "Switch-LIGHTIFY")], - ENDPOINTS: { - 1: copy.deepcopy(LightifyX4.signature[ENDPOINTS][1]), - # - 2: copy.deepcopy(SIGNATURE_ENDPOINT), - # - 3: copy.deepcopy(SIGNATURE_ENDPOINT), - # - 4: copy.deepcopy(SIGNATURE_ENDPOINT), - # - 5: copy.deepcopy(SIGNATURE_ENDPOINT), - # - 6: copy.deepcopy(SIGNATURE_ENDPOINT), - }, - } - - REPLACEMENT_ENDPOINT = { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: OSRAM_DEVICE, - INPUT_CLUSTERS: [LightLink.cluster_id, OsramButtonCluster], - OUTPUT_CLUSTERS: [ - Groups.cluster_id, - Identify.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - Color.cluster_id, - LevelControl.cluster_id, - LightLink.cluster_id, - ], - } + ) + .add_to_registry() +) - replacement = { - ENDPOINTS: { - 1: copy.deepcopy(LightifyX4.replacement[ENDPOINTS][1]), - 2: copy.deepcopy(REPLACEMENT_ENDPOINT), - 3: copy.deepcopy(REPLACEMENT_ENDPOINT), - 4: copy.deepcopy(REPLACEMENT_ENDPOINT), - 5: copy.deepcopy(REPLACEMENT_ENDPOINT), - 6: copy.deepcopy(REPLACEMENT_ENDPOINT), +( + QuirkBuilder(OSRAM, "Switch-LIGHTIFY") + .replaces(OsramButtonCluster, cluster_id=OSRAM_CLUSTER, endpoint_id=1) + .replaces(OsramButtonCluster, cluster_id=OSRAM_CLUSTER, endpoint_id=2) + .replaces(OsramButtonCluster, cluster_id=OSRAM_CLUSTER, endpoint_id=3) + .replaces(OsramButtonCluster, cluster_id=OSRAM_CLUSTER, endpoint_id=4) + .replaces(OsramButtonCluster, cluster_id=OSRAM_CLUSTER, endpoint_id=5) + .replaces(OsramButtonCluster, cluster_id=OSRAM_CLUSTER, endpoint_id=6) + .device_automation_triggers( + { + (SHORT_PRESS, BUTTON_1): {COMMAND: COMMAND_ON, ENDPOINT_ID: 1}, + (SHORT_PRESS, BUTTON_2): {COMMAND: COMMAND_ON, ENDPOINT_ID: 2}, + (SHORT_PRESS, BUTTON_3): {COMMAND: COMMAND_ON, ENDPOINT_ID: 3}, + (SHORT_PRESS, BUTTON_4): {COMMAND: COMMAND_ON, ENDPOINT_ID: 4}, + (LONG_PRESS, BUTTON_1): {COMMAND: COMMAND_MOVE, ENDPOINT_ID: 1}, + (LONG_PRESS, BUTTON_2): {COMMAND: COMMAND_MOVE, ENDPOINT_ID: 2}, + (LONG_PRESS, BUTTON_3): {COMMAND: COMMAND_MOVE, ENDPOINT_ID: 3}, + (LONG_PRESS, BUTTON_4): {COMMAND: COMMAND_MOVE, ENDPOINT_ID: 4}, + (LONG_RELEASE, BUTTON_1): {COMMAND: COMMAND_STOP, ENDPOINT_ID: 1}, + (LONG_RELEASE, BUTTON_2): {COMMAND: COMMAND_STOP, ENDPOINT_ID: 2}, + (LONG_RELEASE, BUTTON_3): {COMMAND: COMMAND_STOP, ENDPOINT_ID: 3}, + (LONG_RELEASE, BUTTON_4): {COMMAND: COMMAND_STOP, ENDPOINT_ID: 4}, } - } - - device_automation_triggers = copy.deepcopy(LightifyX4.device_automation_triggers) + ) + .add_to_registry() +) diff --git a/zhaquirks/osram/osramplug.py b/zhaquirks/osram/osramplug.py index c63489ef7c..6dff90960a 100644 --- a/zhaquirks/osram/osramplug.py +++ b/zhaquirks/osram/osramplug.py @@ -1,69 +1,12 @@ """Osram Smart+ Plug device.""" -from zigpy.profiles import zll -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import Basic, Groups, Identify, OnOff, Ota, Scenes +from zigpy.quirks.v2 import QuirkBuilder from zigpy.zcl.clusters.homeautomation import ElectricalMeasurement -from zigpy.zcl.clusters.lightlink import LightLink -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) -from zhaquirks.osram import OSRAM, OsramLightCluster - - -class OsramPlug(CustomDevice): - """Osram Smart+ Plug.""" +from zhaquirks.osram import OSRAM - signature = { - MODELS_INFO: [(OSRAM, "Plug 01")], - ENDPOINTS: { - # - 3: { - PROFILE_ID: zll.PROFILE_ID, - DEVICE_TYPE: zll.DeviceType.ON_OFF_PLUGIN_UNIT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - ElectricalMeasurement.cluster_id, - LightLink.cluster_id, - OsramLightCluster.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Ota.cluster_id, - ], - }, - }, - } - - replacement = { - ENDPOINTS: { - 3: { - PROFILE_ID: zll.PROFILE_ID, - DEVICE_TYPE: zll.DeviceType.ON_OFF_PLUGIN_UNIT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LightLink.cluster_id, - OsramLightCluster.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Ota.cluster_id, - ], - }, - }, - } +( + QuirkBuilder(OSRAM, "Plug 01") + .removes(ElectricalMeasurement.cluster_id, endpoint_id=3) + .add_to_registry() +) diff --git a/zhaquirks/osram/smartplusac05347.py b/zhaquirks/osram/smartplusac05347.py index 7c439565ad..a90480df06 100644 --- a/zhaquirks/osram/smartplusac05347.py +++ b/zhaquirks/osram/smartplusac05347.py @@ -1,75 +1,11 @@ """Osram Smart+ AC05347 GU10 White.""" -from zigpy.profiles import zll -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - Groups, - Identify, - LevelControl, - OnOff, - Ota, - Scenes, -) -from zigpy.zcl.clusters.lighting import Color -from zigpy.zcl.clusters.lightlink import LightLink +from zigpy.quirks.v2 import QuirkBuilder -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.osram import OSRAM, OsramLightCluster - -class SmartplusAC05347(CustomDevice): - """Osram Smart+ AC05347 GU10 White.""" - - signature = { - # - MODELS_INFO: [(OSRAM, "Smart+ AC05347")], - ENDPOINTS: { - 3: { - PROFILE_ID: zll.PROFILE_ID, - DEVICE_TYPE: zll.DeviceType.COLOR_TEMPERATURE_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Color.cluster_id, - LightLink.cluster_id, - OsramLightCluster.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - }, - } - - replacement = { - ENDPOINTS: { - 3: { - PROFILE_ID: zll.PROFILE_ID, - DEVICE_TYPE: zll.DeviceType.COLOR_TEMPERATURE_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Color.cluster_id, - LightLink.cluster_id, - OsramLightCluster, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - } - } +( + QuirkBuilder(OSRAM, "Smart+ AC05347") + .replaces(OsramLightCluster, endpoint_id=3) + .add_to_registry() +) diff --git a/zhaquirks/osram/switchmini.py b/zhaquirks/osram/switchmini.py index a8ccfa3705..3ce353b225 100644 --- a/zhaquirks/osram/switchmini.py +++ b/zhaquirks/osram/switchmini.py @@ -1,20 +1,6 @@ """Osram Smart+ Switch Mini device.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - Groups, - Identify, - LevelControl, - OnOff, - Ota, - PollControl, - PowerConfiguration, - Scenes, -) -from zigpy.zcl.clusters.lighting import Color -from zigpy.zcl.clusters.lightlink import LightLink +from zigpy.quirks.v2 import QuirkBuilder from zhaquirks.const import ( BUTTON_1, @@ -28,106 +14,30 @@ COMMAND_ON, COMMAND_STOP, COMMAND_STOP_ON_OFF, - DEVICE_TYPE, ENDPOINT_ID, - ENDPOINTS, - INPUT_CLUSTERS, LONG_PRESS, LONG_RELEASE, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, SHORT_PRESS, ) from zhaquirks.osram import OSRAM -OSRAM_CLUSTER = 0xFD00 - - -class OsramSwitchMini(CustomDevice): - """Osram Smart+ Switch Mini device.""" - - signature = { - MODELS_INFO: [(OSRAM, "Lightify Switch Mini")], - ENDPOINTS: { - # - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.COLOR_SCENE_CONTROLLER, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - PollControl.cluster_id, - LightLink.cluster_id, - OSRAM_CLUSTER, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - Color.cluster_id, - LightLink.cluster_id, - ], - }, - # - 2: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.COLOR_SCENE_CONTROLLER, - INPUT_CLUSTERS: [Basic.cluster_id, LightLink.cluster_id, OSRAM_CLUSTER], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Color.cluster_id, - LightLink.cluster_id, - ], +( + QuirkBuilder(OSRAM, "Lightify Switch Mini") + .device_automation_triggers( + { + (SHORT_PRESS, BUTTON_1): {COMMAND: COMMAND_ON, ENDPOINT_ID: 1}, + (LONG_PRESS, BUTTON_1): {COMMAND: COMMAND_MOVE_ON_OFF, ENDPOINT_ID: 1}, + (LONG_RELEASE, BUTTON_1): {COMMAND: COMMAND_STOP_ON_OFF, ENDPOINT_ID: 1}, + (SHORT_PRESS, BUTTON_2): { + COMMAND: COMMAND_MOVE_TO_LEVEL_ON_OFF, + ENDPOINT_ID: 3, }, - # - 3: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.COLOR_SCENE_CONTROLLER, - INPUT_CLUSTERS: [Basic.cluster_id, LightLink.cluster_id, OSRAM_CLUSTER], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Color.cluster_id, - LightLink.cluster_id, - ], - }, - }, - } - - replacement = {**signature} - replacement.pop(MODELS_INFO) - - device_automation_triggers = { - (SHORT_PRESS, BUTTON_1): {COMMAND: COMMAND_ON, ENDPOINT_ID: 1}, - (LONG_PRESS, BUTTON_1): {COMMAND: COMMAND_MOVE_ON_OFF, ENDPOINT_ID: 1}, - (LONG_RELEASE, BUTTON_1): {COMMAND: COMMAND_STOP_ON_OFF, ENDPOINT_ID: 1}, - (SHORT_PRESS, BUTTON_2): { - COMMAND: COMMAND_MOVE_TO_LEVEL_ON_OFF, - ENDPOINT_ID: 3, - }, - (LONG_PRESS, BUTTON_2): {COMMAND: "move_to_saturation", ENDPOINT_ID: 3}, - (LONG_RELEASE, BUTTON_2): {COMMAND: "move_hue", ENDPOINT_ID: 3}, - (SHORT_PRESS, BUTTON_3): {COMMAND: COMMAND_OFF, ENDPOINT_ID: 2}, - (LONG_PRESS, BUTTON_3): {COMMAND: COMMAND_MOVE, ENDPOINT_ID: 2}, - (LONG_RELEASE, BUTTON_3): {COMMAND: COMMAND_STOP, ENDPOINT_ID: 2}, - } + (LONG_PRESS, BUTTON_2): {COMMAND: "move_to_saturation", ENDPOINT_ID: 3}, + (LONG_RELEASE, BUTTON_2): {COMMAND: "move_hue", ENDPOINT_ID: 3}, + (SHORT_PRESS, BUTTON_3): {COMMAND: COMMAND_OFF, ENDPOINT_ID: 2}, + (LONG_PRESS, BUTTON_3): {COMMAND: COMMAND_MOVE, ENDPOINT_ID: 2}, + (LONG_RELEASE, BUTTON_3): {COMMAND: COMMAND_STOP, ENDPOINT_ID: 2}, + } + ) + .add_to_registry() +) diff --git a/zhaquirks/osram/tunablewhite.py b/zhaquirks/osram/tunablewhite.py index b6a6b32080..4aee9fd94a 100644 --- a/zhaquirks/osram/tunablewhite.py +++ b/zhaquirks/osram/tunablewhite.py @@ -1,28 +1,10 @@ """Osram tunable white device.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomCluster, CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - Groups, - Identify, - LevelControl, - OnOff, - Ota, - Scenes, -) -from zigpy.zcl.clusters.homeautomation import ElectricalMeasurement +from zigpy.quirks import CustomCluster +from zigpy.quirks.v2 import QuirkBuilder from zigpy.zcl.clusters.lighting import Color -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) -from zhaquirks.osram import OSRAM, OsramLightCluster +from zhaquirks.osram import OSRAM class OsramColorCluster(CustomCluster, Color): @@ -31,54 +13,9 @@ class OsramColorCluster(CustomCluster, Color): _CONSTANT_ATTRIBUTES = {0x400A: 16, 0x400C: 370} -class OsramTunableWhite(CustomDevice): - """Osram tunable white device.""" - - signature = { - # - MODELS_INFO: [ - (OSRAM, "LIGHTIFY A19 Tunable White"), - (OSRAM, "LIGHTIFY RT Tunable White"), - ], - ENDPOINTS: { - 3: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.COLOR_DIMMABLE_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Color.cluster_id, - ElectricalMeasurement.cluster_id, - OsramLightCluster.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - }, - } - - replacement = { - ENDPOINTS: { - 3: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.COLOR_DIMMABLE_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - OsramColorCluster, - ElectricalMeasurement.cluster_id, - OsramLightCluster, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - } - } +( + QuirkBuilder(OSRAM, "LIGHTIFY A19 Tunable White") + .applies_to(OSRAM, "LIGHTIFY RT Tunable White") + .replaces(OsramColorCluster, endpoint_id=3) + .add_to_registry() +) diff --git a/zhaquirks/paulmann/fourbtnremote.py b/zhaquirks/paulmann/fourbtnremote.py index fd396aef95..ca60e4a7bb 100644 --- a/zhaquirks/paulmann/fourbtnremote.py +++ b/zhaquirks/paulmann/fourbtnremote.py @@ -1,20 +1,6 @@ """Device handler for Paulmann 4-button remote control.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - Groups, - Identify, - LevelControl, - OnOff, - Ota, - PowerConfiguration, - Scenes, -) -from zigpy.zcl.clusters.homeautomation import Diagnostic -from zigpy.zcl.clusters.lighting import Color -from zigpy.zcl.clusters.lightlink import LightLink +from zigpy.quirks.v2 import QuirkBuilder from zhaquirks.const import ( BUTTON_1, @@ -27,174 +13,84 @@ COMMAND_OFF, COMMAND_ON, COMMAND_STOP_ON_OFF, - DEVICE_TYPE, ENDPOINT_ID, - ENDPOINTS, - INPUT_CLUSTERS, LONG_PRESS, LONG_RELEASE, - MODELS_INFO, - OUTPUT_CLUSTERS, PARAMS, - PROFILE_ID, SHORT_PRESS, ) from zhaquirks.paulmann import PAULMANN, PAULMANN_VARIANT - -class PaulmannRemote4Btn(CustomDevice): - """Custom device representing Paulmann 4-button 501.34 remote control.""" - - signature = { - # - MODELS_INFO: [(PAULMANN, "501.34"), (PAULMANN_VARIANT, "501.34")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.LEVEL_CONTROL_SWITCH, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Diagnostic.cluster_id, - Identify.cluster_id, - LightLink.cluster_id, - PowerConfiguration.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Color.cluster_id, - Groups.cluster_id, - Identify.cluster_id, - LevelControl.cluster_id, - LightLink.cluster_id, - OnOff.cluster_id, - Ota.cluster_id, - Scenes.cluster_id, - ], +( + QuirkBuilder(PAULMANN, "501.34") + .applies_to(PAULMANN_VARIANT, "501.34") + .device_automation_triggers( + { + (SHORT_PRESS, BUTTON_1): { + COMMAND: COMMAND_ON, + CLUSTER_ID: 6, + ENDPOINT_ID: 1, }, - 2: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.LEVEL_CONTROL_SWITCH, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Diagnostic.cluster_id, - Identify.cluster_id, - LightLink.cluster_id, - PowerConfiguration.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Color.cluster_id, - Groups.cluster_id, - Identify.cluster_id, - LevelControl.cluster_id, - LightLink.cluster_id, - OnOff.cluster_id, - Ota.cluster_id, - Scenes.cluster_id, - ], + (LONG_PRESS, BUTTON_1): { + COMMAND: COMMAND_MOVE_ON_OFF, + CLUSTER_ID: 8, + ENDPOINT_ID: 1, + PARAMS: {"move_mode": 0, "rate": 50}, }, - }, - } - - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - Diagnostic.cluster_id, - Identify.cluster_id, - LightLink.cluster_id, - PowerConfiguration.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Color.cluster_id, - Groups.cluster_id, - Identify.cluster_id, - LevelControl.cluster_id, - LightLink.cluster_id, - OnOff.cluster_id, - Ota.cluster_id, - Scenes.cluster_id, - ], + (LONG_RELEASE, BUTTON_1): { + COMMAND: COMMAND_STOP_ON_OFF, + CLUSTER_ID: 8, + ENDPOINT_ID: 1, + }, + (SHORT_PRESS, BUTTON_2): { + COMMAND: COMMAND_OFF, + CLUSTER_ID: 6, + ENDPOINT_ID: 1, + }, + (LONG_PRESS, BUTTON_2): { + COMMAND: COMMAND_MOVE_ON_OFF, + CLUSTER_ID: 8, + ENDPOINT_ID: 1, + PARAMS: {"move_mode": 1, "rate": 50}, + }, + (LONG_RELEASE, BUTTON_2): { + COMMAND: COMMAND_STOP_ON_OFF, + CLUSTER_ID: 8, + ENDPOINT_ID: 1, }, - 2: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - Diagnostic.cluster_id, - Identify.cluster_id, - LightLink.cluster_id, - PowerConfiguration.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Color.cluster_id, - Groups.cluster_id, - Identify.cluster_id, - LevelControl.cluster_id, - LightLink.cluster_id, - OnOff.cluster_id, - Ota.cluster_id, - Scenes.cluster_id, - ], + (SHORT_PRESS, BUTTON_3): { + COMMAND: COMMAND_ON, + CLUSTER_ID: 6, + ENDPOINT_ID: 2, + }, + (LONG_PRESS, BUTTON_3): { + COMMAND: COMMAND_MOVE_ON_OFF, + CLUSTER_ID: 8, + ENDPOINT_ID: 2, + PARAMS: {"move_mode": 0, "rate": 50}, + }, + (LONG_RELEASE, BUTTON_3): { + COMMAND: COMMAND_STOP_ON_OFF, + CLUSTER_ID: 8, + ENDPOINT_ID: 2, + }, + (SHORT_PRESS, BUTTON_4): { + COMMAND: COMMAND_OFF, + CLUSTER_ID: 6, + ENDPOINT_ID: 2, + }, + (LONG_PRESS, BUTTON_4): { + COMMAND: COMMAND_MOVE_ON_OFF, + CLUSTER_ID: 8, + ENDPOINT_ID: 2, + PARAMS: {"move_mode": 1, "rate": 50}, + }, + (LONG_RELEASE, BUTTON_4): { + COMMAND: COMMAND_STOP_ON_OFF, + CLUSTER_ID: 8, + ENDPOINT_ID: 2, }, } - } - - device_automation_triggers = { - (SHORT_PRESS, BUTTON_1): {COMMAND: COMMAND_ON, CLUSTER_ID: 6, ENDPOINT_ID: 1}, - (LONG_PRESS, BUTTON_1): { - COMMAND: COMMAND_MOVE_ON_OFF, - CLUSTER_ID: 8, - ENDPOINT_ID: 1, - PARAMS: {"move_mode": 0, "rate": 50}, - }, - (LONG_RELEASE, BUTTON_1): { - COMMAND: COMMAND_STOP_ON_OFF, - CLUSTER_ID: 8, - ENDPOINT_ID: 1, - }, - (SHORT_PRESS, BUTTON_2): {COMMAND: COMMAND_OFF, CLUSTER_ID: 6, ENDPOINT_ID: 1}, - (LONG_PRESS, BUTTON_2): { - COMMAND: COMMAND_MOVE_ON_OFF, - CLUSTER_ID: 8, - ENDPOINT_ID: 1, - PARAMS: {"move_mode": 1, "rate": 50}, - }, - (LONG_RELEASE, BUTTON_2): { - COMMAND: COMMAND_STOP_ON_OFF, - CLUSTER_ID: 8, - ENDPOINT_ID: 1, - }, - (SHORT_PRESS, BUTTON_3): { - COMMAND: COMMAND_ON, - CLUSTER_ID: 6, - ENDPOINT_ID: 2, - }, - (LONG_PRESS, BUTTON_3): { - COMMAND: COMMAND_MOVE_ON_OFF, - CLUSTER_ID: 8, - ENDPOINT_ID: 2, - PARAMS: {"move_mode": 0, "rate": 50}, - }, - (LONG_RELEASE, BUTTON_3): { - COMMAND: COMMAND_STOP_ON_OFF, - CLUSTER_ID: 8, - ENDPOINT_ID: 2, - }, - (SHORT_PRESS, BUTTON_4): { - COMMAND: COMMAND_OFF, - CLUSTER_ID: 6, - ENDPOINT_ID: 2, - }, - (LONG_PRESS, BUTTON_4): { - COMMAND: COMMAND_MOVE_ON_OFF, - CLUSTER_ID: 8, - ENDPOINT_ID: 2, - PARAMS: {"move_mode": 1, "rate": 50}, - }, - (LONG_RELEASE, BUTTON_4): { - COMMAND: COMMAND_STOP_ON_OFF, - CLUSTER_ID: 8, - ENDPOINT_ID: 2, - }, - } + ) + .add_to_registry() +) diff --git a/zhaquirks/philio/pst03a.py b/zhaquirks/philio/pst03a.py index 89131e3d2a..df108e6707 100644 --- a/zhaquirks/philio/pst03a.py +++ b/zhaquirks/philio/pst03a.py @@ -1,15 +1,8 @@ """Device handler for Philio PST03A-v2.2.5.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Alarms, - Basic, - BinaryInput, - OnOff, - Ota, - PowerConfiguration, -) +from zigpy.quirks.v2 import QuirkBuilder +from zigpy.zcl import ClusterType +from zigpy.zcl.clusters.general import BinaryInput, OnOff, PowerConfiguration from zigpy.zcl.clusters.measurement import ( IlluminanceMeasurement, OccupancySensing, @@ -17,77 +10,20 @@ ) from zigpy.zcl.clusters.security import IasZone -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MANUFACTURER, - MODEL, - OUTPUT_CLUSTERS, - PROFILE_ID, - SKIP_CONFIGURATION, -) -from zhaquirks.philio import PHILIO, MotionCluster - +from zhaquirks.philio import MotionCluster -class Pst03a(CustomDevice): - """Custom device representing PST03A 4in1 motion/opening/temperature/illuminance sensors.""" - - signature = { - MODEL: "PST03A-v2.2.5", - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Alarms.cluster_id, - OccupancySensing.cluster_id, - IasZone.cluster_id, - ], - OUTPUT_CLUSTERS: [OnOff.cluster_id, Ota.cluster_id], - }, - 2: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Alarms.cluster_id, - BinaryInput.cluster_id, - IasZone.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - }, - }, - } - - replacement = { - SKIP_CONFIGURATION: True, - MANUFACTURER: PHILIO, - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Alarms.cluster_id, - MotionCluster, - TemperatureMeasurement.cluster_id, - IlluminanceMeasurement.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - }, - 2: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Alarms.cluster_id, - IasZone.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - }, - }, - } +( + # TODO: is this correct? The v1 quirk had no manufacturer name. + QuirkBuilder("Philio", "PST03A-v2.2.5") + .skip_configuration() + .replaces(MotionCluster, endpoint_id=1) + .removes(PowerConfiguration, endpoint_id=1) + .removes(OccupancySensing, endpoint_id=1) + .removes(IasZone, endpoint_id=1) + .removes(OnOff, endpoint_id=1, cluster_type=ClusterType.Client) + .adds(TemperatureMeasurement, endpoint_id=1) + .adds(IlluminanceMeasurement, endpoint_id=1) + .removes(PowerConfiguration, endpoint_id=2) + .removes(BinaryInput, endpoint_id=2) + .add_to_registry() +) diff --git a/zhaquirks/philips/motion.py b/zhaquirks/philips/motion.py index d4cafc9ef2..b33839167a 100644 --- a/zhaquirks/philips/motion.py +++ b/zhaquirks/philips/motion.py @@ -2,35 +2,12 @@ from typing import Final -from zigpy.profiles import zha, zll -from zigpy.quirks import CustomCluster, CustomDevice +from zigpy.quirks import CustomCluster +from zigpy.quirks.v2 import QuirkBuilder import zigpy.types as t -from zigpy.zcl.clusters.general import ( - Basic, - Groups, - Identify, - LevelControl, - OnOff, - Ota, - PowerConfiguration, - Scenes, -) -from zigpy.zcl.clusters.lighting import Color -from zigpy.zcl.clusters.measurement import ( - IlluminanceMeasurement, - OccupancySensing, - TemperatureMeasurement, -) +from zigpy.zcl.clusters.general import Basic from zigpy.zcl.foundation import ZCLAttributeDef -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.philips import PHILIPS, SIGNIFY, PhilipsOccupancySensing @@ -45,129 +22,19 @@ class AttributeDefs(Basic.AttributeDefs): ) -class PhilipsMotion(CustomDevice): - """Old Philips motion sensor devices.""" - - signature = { - MODELS_INFO: [(PHILIPS, "SML001"), (PHILIPS, "SML002")], - ENDPOINTS: { - # - 1: { - PROFILE_ID: zll.PROFILE_ID, - DEVICE_TYPE: zll.DeviceType.ON_OFF_SENSOR, - INPUT_CLUSTERS: [Basic.cluster_id], - OUTPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Color.cluster_id, - ], - }, - # - 2: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.OCCUPANCY_SENSOR, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - IlluminanceMeasurement.cluster_id, - TemperatureMeasurement.cluster_id, - OccupancySensing.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - }, - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zll.PROFILE_ID, - DEVICE_TYPE: zll.DeviceType.ON_OFF_SENSOR, - INPUT_CLUSTERS: [Basic.cluster_id], - OUTPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Color.cluster_id, - ], - }, - 2: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.OCCUPANCY_SENSOR, - INPUT_CLUSTERS: [ - BasicCluster, - PowerConfiguration.cluster_id, - Identify.cluster_id, - IlluminanceMeasurement.cluster_id, - TemperatureMeasurement.cluster_id, - PhilipsOccupancySensing, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - }, - } - } - - -class SignifyMotion(CustomDevice): - """New Philips motion sensor devices.""" +( + QuirkBuilder(PHILIPS, "SML001") + .applies_to(PHILIPS, "SML002") + .replaces(BasicCluster, endpoint_id=2) + .replaces(PhilipsOccupancySensing, endpoint_id=2) + .add_to_registry() +) - signature = { - MODELS_INFO: [(SIGNIFY, "SML003"), (SIGNIFY, "SML004")], - ENDPOINTS: { - 2: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.OCCUPANCY_SENSOR, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - IlluminanceMeasurement.cluster_id, - TemperatureMeasurement.cluster_id, - OccupancySensing.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - OnOff.cluster_id, - Ota.cluster_id, - ], - }, - }, - } - replacement = { - ENDPOINTS: { - 2: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.OCCUPANCY_SENSOR, - INPUT_CLUSTERS: [ - BasicCluster, - PowerConfiguration.cluster_id, - Identify.cluster_id, - IlluminanceMeasurement.cluster_id, - TemperatureMeasurement.cluster_id, - PhilipsOccupancySensing, - ], - OUTPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - OnOff.cluster_id, - Ota.cluster_id, - ], - }, - } - } +( + QuirkBuilder(SIGNIFY, "SML003") + .applies_to(SIGNIFY, "SML004") + .replaces(BasicCluster, endpoint_id=2) + .replaces(PhilipsOccupancySensing, endpoint_id=2) + .add_to_registry() +) diff --git a/zhaquirks/philips/rdm002.py b/zhaquirks/philips/rdm002.py index 8af4864a2a..54d990cf8d 100644 --- a/zhaquirks/philips/rdm002.py +++ b/zhaquirks/philips/rdm002.py @@ -4,18 +4,10 @@ from typing import Any from zigpy.profiles import zha -from zigpy.quirks import CustomCluster, CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - Groups, - Identify, - LevelControl, - OnOff, - Ota, - PowerConfiguration, - Scenes, -) -from zigpy.zcl.clusters.lightlink import LightLink +from zigpy.quirks import CustomCluster +from zigpy.quirks.v2 import QuirkBuilder +from zigpy.zcl import ClusterType +from zigpy.zcl.clusters.general import LevelControl from zhaquirks.const import ( BUTTON_1, @@ -25,16 +17,10 @@ CLUSTER_ID, COMMAND, COMMAND_STEP_ON_OFF, - DEVICE_TYPE, DIM_DOWN, DIM_UP, ENDPOINT_ID, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, PARAMS, - PROFILE_ID, SHORT_PRESS, ) from zhaquirks.philips import ( @@ -101,66 +87,15 @@ def listener_event(self, method_name: str, *args) -> list[Any | None]: return super().listener_event(method_name, *args) -class PhilipsRDM002(CustomDevice): - """Philips RDM002 device.""" - - signature = { - # - MODELS_INFO: [(PHILIPS, "RDM002"), (SIGNIFY, "RDM002")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.NON_COLOR_SCENE_CONTROLLER, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - PhilipsRdm002RemoteCluster.cluster_id, - LightLink.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Ota.cluster_id, - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Scenes.cluster_id, - LightLink.cluster_id, - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.NON_COLOR_CONTROLLER, - INPUT_CLUSTERS: [ - PhilipsBasicCluster, - PowerConfiguration.cluster_id, - Identify.cluster_id, - PhilipsRdm002RemoteCluster, - LightLink.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Ota.cluster_id, - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - PhilipsRdm002LevelControl, - Scenes.cluster_id, - LightLink.cluster_id, - ], - } - } - } - - device_automation_triggers = ( +( + QuirkBuilder(PHILIPS, "RDM002") + .applies_to(SIGNIFY, "RDM002") + .replaces_endpoint(1, device_type=zha.DeviceType.NON_COLOR_CONTROLLER) + .replaces(PhilipsBasicCluster, endpoint_id=1) + .replaces(PhilipsRdm002RemoteCluster, endpoint_id=1) + .replaces(PhilipsRdm002LevelControl, cluster_type=ClusterType.Client, endpoint_id=1) + .device_automation_triggers( PhilipsRdm002RemoteCluster.generate_device_automation_triggers(DIAL_TRIGGERS) ) + .add_to_registry() +) diff --git a/zhaquirks/philips/rom001.py b/zhaquirks/philips/rom001.py index 2996d65265..f1a11f373f 100644 --- a/zhaquirks/philips/rom001.py +++ b/zhaquirks/philips/rom001.py @@ -1,32 +1,9 @@ """Philips ROM001 device.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - Groups, - Identify, - LevelControl, - OnOff, - Ota, - PowerConfiguration, - Scenes, -) -from zigpy.zcl.clusters.lightlink import LightLink +from zigpy.quirks.v2 import QuirkBuilder +from zigpy.zcl.clusters.general import Basic -from zhaquirks.const import ( - COMMAND_HOLD, - COMMAND_ON, - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - LONG_PRESS, - LONG_RELEASE, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, - TURN_ON, -) +from zhaquirks.const import COMMAND_HOLD, COMMAND_ON, LONG_PRESS, LONG_RELEASE, TURN_ON from zhaquirks.philips import ( PHILIPS, SIGNIFY, @@ -57,66 +34,14 @@ class PhilipsRom001RemoteCluster(PhilipsRemoteCluster): } -class PhilipsROM001(CustomDevice): - """Philips ROM001 device.""" - - signature = { - # - MODELS_INFO: [(PHILIPS, "ROM001"), (SIGNIFY, "ROM001"), (SIGNIFY, "RDM003")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.NON_COLOR_SCENE_CONTROLLER, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - DEVICE_SPECIFIC_UNKNOWN, - LightLink.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Ota.cluster_id, - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Scenes.cluster_id, - LightLink.cluster_id, - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.NON_COLOR_SCENE_CONTROLLER, - INPUT_CLUSTERS: [ - PhilipsBasicCluster, - PowerConfiguration.cluster_id, - Identify.cluster_id, - PhilipsRom001RemoteCluster, - LightLink.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Ota.cluster_id, - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Scenes.cluster_id, - LightLink.cluster_id, - ], - } - } - } - - device_automation_triggers = ( +( + QuirkBuilder(PHILIPS, "ROM001") + .applies_to(SIGNIFY, "ROM001") + .applies_to(SIGNIFY, "RDM003") + .replaces(PhilipsBasicCluster, Basic.cluster_id, endpoint_id=1) + .replaces(PhilipsRom001RemoteCluster, DEVICE_SPECIFIC_UNKNOWN, endpoint_id=1) + .device_automation_triggers( PhilipsRom001RemoteCluster.generate_device_automation_triggers() ) + .add_to_registry() +) diff --git a/zhaquirks/philips/rwl022.py b/zhaquirks/philips/rwl022.py index 7001d7411d..c30d5ca62e 100644 --- a/zhaquirks/philips/rwl022.py +++ b/zhaquirks/philips/rwl022.py @@ -1,92 +1,19 @@ """Philips RWL022 device.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - Groups, - Identify, - LevelControl, - OnOff, - Ota, - PowerConfiguration, - Scenes, -) -from zigpy.zcl.clusters.lightlink import LightLink +from zigpy.quirks.v2 import QuirkBuilder +from zigpy.zcl.clusters.general import Basic -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.philips import SIGNIFY, PhilipsBasicCluster, PhilipsRwlRemoteCluster DEVICE_SPECIFIC_UNKNOWN = 64512 -class PhilipsRWL022(CustomDevice): - """Philips RWL022 device.""" - - signature = { - # - MODELS_INFO: [(SIGNIFY, "RWL022")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.NON_COLOR_SCENE_CONTROLLER, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - DEVICE_SPECIFIC_UNKNOWN, - LightLink.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Ota.cluster_id, - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Scenes.cluster_id, - LightLink.cluster_id, - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.NON_COLOR_SCENE_CONTROLLER, - INPUT_CLUSTERS: [ - PhilipsBasicCluster, - PowerConfiguration.cluster_id, - Identify.cluster_id, - PhilipsRwlRemoteCluster, - LightLink.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Ota.cluster_id, - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Scenes.cluster_id, - LightLink.cluster_id, - ], - } - } - } - - device_automation_triggers = ( +( + QuirkBuilder(SIGNIFY, "RWL022") + .replaces(PhilipsBasicCluster, Basic.cluster_id, endpoint_id=1) + .replaces(PhilipsRwlRemoteCluster, DEVICE_SPECIFIC_UNKNOWN, endpoint_id=1) + .device_automation_triggers( PhilipsRwlRemoteCluster.generate_device_automation_triggers() ) + .add_to_registry() +) diff --git a/zhaquirks/philips/rwlfirstgen.py b/zhaquirks/philips/rwlfirstgen.py index b928c6483c..63230d18bd 100644 --- a/zhaquirks/philips/rwlfirstgen.py +++ b/zhaquirks/philips/rwlfirstgen.py @@ -1,27 +1,8 @@ """Philips first generation RWL devices.""" -from zigpy.profiles import zha, zll -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - BinaryInput, - Groups, - Identify, - LevelControl, - OnOff, - Ota, - PowerConfiguration, - Scenes, -) +from zigpy.quirks.v2 import QuirkBuilder +from zigpy.zcl.clusters.general import Basic -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.philips import ( PHILIPS, SIGNIFY, @@ -31,156 +12,17 @@ DEVICE_SPECIFIC_UNKNOWN = 64512 - -class PhilipsRWLFirstGen(CustomDevice): - """Philips updated RWL020 and RWL021 devices.""" - - signature = { - # - MODELS_INFO: [ - (PHILIPS, "RWL020"), - (SIGNIFY, "RWL020"), - (PHILIPS, "RWL021"), - (SIGNIFY, "RWL021"), - ], - ENDPOINTS: { - 1: { - PROFILE_ID: zll.PROFILE_ID, - DEVICE_TYPE: zll.DeviceType.SCENE_CONTROLLER, - INPUT_CLUSTERS: [Basic.cluster_id], - OUTPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Scenes.cluster_id, - ], - }, - # - 2: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.SIMPLE_SENSOR, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - BinaryInput.cluster_id, - DEVICE_SPECIFIC_UNKNOWN, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - }, - }, - } - - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [Basic.cluster_id], - OUTPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Scenes.cluster_id, - ], - }, - 2: { - INPUT_CLUSTERS: [ - PhilipsBasicCluster, - PowerConfiguration.cluster_id, - Identify.cluster_id, - BinaryInput.cluster_id, - PhilipsRwlRemoteCluster, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - }, - } - } - - device_automation_triggers = ( - PhilipsRwlRemoteCluster.generate_device_automation_triggers() +( + QuirkBuilder(PHILIPS, "RWL020") + .applies_to(SIGNIFY, "RWL020") + .applies_to(PHILIPS, "RWL021") + .applies_to(SIGNIFY, "RWL021") + .replaces(PhilipsBasicCluster, cluster_id=Basic.cluster_id, endpoint_id=2) + .replaces( + PhilipsRwlRemoteCluster, cluster_id=DEVICE_SPECIFIC_UNKNOWN, endpoint_id=2 ) - - -class PhilipsRWLFirstGen2(CustomDevice): - """Philips older RWL020 and RWL021 devices.""" - - signature = { - # - MODELS_INFO: [ - (PHILIPS, "RWL020"), - (SIGNIFY, "RWL020"), - (PHILIPS, "RWL021"), - (SIGNIFY, "RWL021"), - ], - ENDPOINTS: { - 1: { - PROFILE_ID: zll.PROFILE_ID, - DEVICE_TYPE: zll.DeviceType.CONTROLLER, - INPUT_CLUSTERS: [Basic.cluster_id], - OUTPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - ], - }, - # - 2: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.SIMPLE_SENSOR, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - BinaryInput.cluster_id, - DEVICE_SPECIFIC_UNKNOWN, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - }, - }, - } - - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [Basic.cluster_id], - OUTPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - ], - }, - 2: { - INPUT_CLUSTERS: [ - PhilipsBasicCluster, - PowerConfiguration.cluster_id, - Identify.cluster_id, - BinaryInput.cluster_id, - PhilipsRwlRemoteCluster, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - }, - } - } - - device_automation_triggers = ( + .device_automation_triggers( PhilipsRwlRemoteCluster.generate_device_automation_triggers() ) + .add_to_registry() +) diff --git a/zhaquirks/philips/wall_switch.py b/zhaquirks/philips/wall_switch.py index 45ea393fcd..a7fc23ec5a 100644 --- a/zhaquirks/philips/wall_switch.py +++ b/zhaquirks/philips/wall_switch.py @@ -2,30 +2,14 @@ from typing import Final -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice +from zigpy.quirks.v2 import QuirkBuilder import zigpy.types as t -from zigpy.zcl.clusters.general import ( - Basic, - Groups, - Identify, - LevelControl, - OnOff, - Ota, - PowerConfiguration, -) from zigpy.zcl.foundation import ZCLAttributeDef from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, LEFT, LONG_PRESS, LONG_RELEASE, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, RIGHT, SHORT_PRESS, SHORT_RELEASE, @@ -87,123 +71,20 @@ class PhilipsWallSwitchRemoteCluster(PhilipsRemoteCluster): ] -class PhilipsWallSwitch(CustomDevice): - """Philips RDM001 or RDM004 device using old firmware.""" - - signature = { - # - MODELS_INFO: [ - (PHILIPS, "RDM001"), - (SIGNIFY, "RDM001"), - (PHILIPS, "RDM004"), # likely not needed - (SIGNIFY, "RDM004"), - ], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.NON_COLOR_CONTROLLER, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - PhilipsWallSwitchRemoteCluster.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.NON_COLOR_CONTROLLER, - INPUT_CLUSTERS: [ - PhilipsWallSwitchBasicCluster, - PowerConfiguration.cluster_id, - Identify.cluster_id, - PhilipsWallSwitchRemoteCluster, - ], - OUTPUT_CLUSTERS: [ - Ota.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - ], - } - } - } - - device_automation_triggers = ( - PhilipsWallSwitchRemoteCluster.generate_device_automation_triggers() - ) - - -class PhilipsWallSwitchNewFirmware(CustomDevice): - """Philips RDM001 or RDM004 device using new firmware.""" - - signature = { - MODELS_INFO: [ - (PHILIPS, "RDM001"), - (SIGNIFY, "RDM001"), - (PHILIPS, "RDM004"), # likely not needed - (SIGNIFY, "RDM004"), - ], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.NON_COLOR_SCENE_CONTROLLER, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - PhilipsWallSwitchRemoteCluster.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - ], - }, - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.NON_COLOR_SCENE_CONTROLLER, - INPUT_CLUSTERS: [ - PhilipsWallSwitchBasicCluster, - PowerConfiguration.cluster_id, - Identify.cluster_id, - PhilipsWallSwitchRemoteCluster, - ], - OUTPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - ], - }, - }, - } - - device_automation_triggers = ( +# Philips RDM001 or RDM004 device using old firmware. +# +( + QuirkBuilder(PHILIPS, "RDM001") + .applies_to(SIGNIFY, "RDM001") + .applies_to(PHILIPS, "RDM004") # likely not needed + .applies_to(SIGNIFY, "RDM004") + .replaces(PhilipsWallSwitchBasicCluster, endpoint_id=1) + .replaces(PhilipsWallSwitchRemoteCluster, endpoint_id=1) + .device_automation_triggers( PhilipsWallSwitchRemoteCluster.generate_device_automation_triggers() ) + .add_to_registry() +) diff --git a/zhaquirks/salus/sp600.py b/zhaquirks/salus/sp600.py index e88446962d..75d75fb1c2 100644 --- a/zhaquirks/salus/sp600.py +++ b/zhaquirks/salus/sp600.py @@ -1,27 +1,9 @@ """Salus SP600 plug.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomCluster, CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - Groups, - Identify, - OnOff, - Ota, - PowerConfiguration, - Scenes, -) +from zigpy.quirks import CustomCluster +from zigpy.quirks.v2 import QuirkBuilder from zigpy.zcl.clusters.measurement import TemperatureMeasurement -from zigpy.zcl.clusters.smartenergy import Metering -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.salus import COMPUTIME @@ -37,103 +19,9 @@ def _update_attribute(self, attrid, value): super()._update_attribute(attrid, value) -class SP600(CustomDevice): - """Salus SP600 smart plug.""" - - signature = { - ENDPOINTS: { - # - 9: { - PROFILE_ID: 0x0104, - DEVICE_TYPE: zha.DeviceType.SMART_PLUG, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - TemperatureMeasurement.cluster_id, - Metering.cluster_id, - 0xFC01, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - }, - MODELS_INFO: [(COMPUTIME, "SP600")], - } - - replacement = { - ENDPOINTS: { - 9: { - PROFILE_ID: 0x0104, - DEVICE_TYPE: zha.DeviceType.SMART_PLUG, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - TemperatureMeasurementCluster, - Metering.cluster_id, - 0xFC01, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - }, - } - - -class SPE600(CustomDevice): - """Salus SPE600 smart plug.""" - - signature = { - ENDPOINTS: { - # - 9: { - PROFILE_ID: 0x0104, - DEVICE_TYPE: zha.DeviceType.SMART_PLUG, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - TemperatureMeasurement.cluster_id, - Metering.cluster_id, - 0xFC01, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - }, - MODELS_INFO: [(COMPUTIME, "SPE600")], - } - - replacement = { - ENDPOINTS: { - 9: { - PROFILE_ID: 0x0104, - DEVICE_TYPE: zha.DeviceType.SMART_PLUG, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - TemperatureMeasurementCluster, - Metering.cluster_id, - 0xFC01, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - }, - } +( + QuirkBuilder(COMPUTIME, "SP600") + .applies_to(COMPUTIME, "SPE600") + .replaces(TemperatureMeasurementCluster, endpoint_id=9) + .add_to_registry() +) diff --git a/zhaquirks/samjin/button.py b/zhaquirks/samjin/button.py index b9451bd697..38257de34c 100644 --- a/zhaquirks/samjin/button.py +++ b/zhaquirks/samjin/button.py @@ -1,16 +1,6 @@ """Samjin button device.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - Identify, - Ota, - PollControl, - PowerConfiguration, -) -from zigpy.zcl.clusters.homeautomation import Diagnostic -from zigpy.zcl.clusters.measurement import TemperatureMeasurement +from zigpy.quirks.v2 import QuirkBuilder from zigpy.zcl.clusters.security import IasZone from zhaquirks.const import ( @@ -19,110 +9,21 @@ COMMAND_BUTTON_DOUBLE, COMMAND_BUTTON_HOLD, COMMAND_BUTTON_SINGLE, - DEVICE_TYPE, DOUBLE_PRESS, - ENDPOINTS, - INPUT_CLUSTERS, LONG_PRESS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, SHORT_PRESS, ) from zhaquirks.samjin import SAMJIN, SamjinIASCluster - -class SamjinButton(CustomDevice): - """Samjin button device.""" - - signature = { - # - MODELS_INFO: [(SAMJIN, BUTTON)], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - IasZone.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [Identify.cluster_id, Ota.cluster_id], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - SamjinIASCluster, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [Identify.cluster_id, Ota.cluster_id], - } +( + QuirkBuilder(SAMJIN, BUTTON) + .replaces(SamjinIASCluster, cluster_id=IasZone.cluster_id, endpoint_id=1) + .device_automation_triggers( + { + (DOUBLE_PRESS, DOUBLE_PRESS): {COMMAND: COMMAND_BUTTON_DOUBLE}, + (SHORT_PRESS, SHORT_PRESS): {COMMAND: COMMAND_BUTTON_SINGLE}, + (LONG_PRESS, LONG_PRESS): {COMMAND: COMMAND_BUTTON_HOLD}, } - } - - device_automation_triggers = { - (DOUBLE_PRESS, DOUBLE_PRESS): {COMMAND: COMMAND_BUTTON_DOUBLE}, - (SHORT_PRESS, SHORT_PRESS): {COMMAND: COMMAND_BUTTON_SINGLE}, - (LONG_PRESS, LONG_PRESS): {COMMAND: COMMAND_BUTTON_HOLD}, - } - - -class SamjinButton2(SamjinButton): - """Samjin button device variation without Diagnostic cluster.""" - - signature = { - # - MODELS_INFO: [(SAMJIN, BUTTON)], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - IasZone.cluster_id, - ], - OUTPUT_CLUSTERS: [Identify.cluster_id, Ota.cluster_id], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - SamjinIASCluster, - ], - OUTPUT_CLUSTERS: [Identify.cluster_id, Ota.cluster_id], - } - } - } + ) + .add_to_registry() +) diff --git a/zhaquirks/samjin/multi2.py b/zhaquirks/samjin/multi2.py index ec28a74637..2329db621e 100644 --- a/zhaquirks/samjin/multi2.py +++ b/zhaquirks/samjin/multi2.py @@ -1,71 +1,12 @@ """Samjin Multi 2019 Refresh Quirk.""" -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - Identify, - Ota, - PollControl, - PowerConfiguration, -) -from zigpy.zcl.clusters.homeautomation import Diagnostic -from zigpy.zcl.clusters.measurement import TemperatureMeasurement -from zigpy.zcl.clusters.security import IasZone +from zigpy.quirks.v2 import QuirkBuilder -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.samjin import SAMJIN from zhaquirks.smartthings import SmartThingsAccelCluster - -class SmartthingsMultiPurposeSensor2019(CustomDevice): - """Samjin multi device.""" - - signature = { - MODELS_INFO: [(SAMJIN, "multi")], - ENDPOINTS: { - # - 1: { - PROFILE_ID: 0x0104, - DEVICE_TYPE: 0x0402, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - IasZone.cluster_id, - Diagnostic.cluster_id, - SmartThingsAccelCluster.cluster_id, - ], - OUTPUT_CLUSTERS: [Identify.cluster_id, Ota.cluster_id], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - IasZone.cluster_id, - Diagnostic.cluster_id, - SmartThingsAccelCluster, - ], - OUTPUT_CLUSTERS: [Identify.cluster_id, Ota.cluster_id], - } - } - } +( + QuirkBuilder(SAMJIN, "multi") + .replaces(SmartThingsAccelCluster, endpoint_id=1) + .add_to_registry() +) diff --git a/zhaquirks/schneiderelectric/outlet.py b/zhaquirks/schneiderelectric/outlet.py index 5397a71a3c..5bacad1965 100644 --- a/zhaquirks/schneiderelectric/outlet.py +++ b/zhaquirks/schneiderelectric/outlet.py @@ -1,27 +1,9 @@ """Schneider Electric (Wiser) Outlet Quirks.""" -from zigpy.profiles import zgp, zha -from zigpy.quirks import CustomCluster, CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - GreenPowerProxy, - Groups, - Identify, - OnOff, - Ota, - Scenes, -) -from zigpy.zcl.clusters.homeautomation import Diagnostic, ElectricalMeasurement -from zigpy.zcl.clusters.smartenergy import DeviceManagement, Metering +from zigpy.quirks import CustomCluster +from zigpy.quirks.v2 import QuirkBuilder +from zigpy.zcl.clusters.smartenergy import Metering -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.schneiderelectric import SE_MANUF_NAME @@ -34,76 +16,9 @@ def _update_attribute(self, attrid, value): super()._update_attribute(attrid, value) -class SocketOutlet(CustomDevice): - """Schneider Electric Socket outlet WDE002182, WDE002172.""" - - signature = { - MODELS_INFO: [ - (SE_MANUF_NAME, "SOCKET/OUTLET/1"), - (SE_MANUF_NAME, "SOCKET/OUTLET/2"), - ], - ENDPOINTS: { - # - 6: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.MAIN_POWER_OUTLET, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - Metering.cluster_id, - DeviceManagement.cluster_id, - ElectricalMeasurement.cluster_id, - Diagnostic.cluster_id, - 0xFC04, - ], - OUTPUT_CLUSTERS: [ - Ota.cluster_id, - ], - }, - 242: { - PROFILE_ID: zgp.PROFILE_ID, - DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC, - INPUT_CLUSTERS: [], - OUTPUT_CLUSTERS: [ - GreenPowerProxy.cluster_id, - ], - }, - }, - } - - replacement = { - ENDPOINTS: { - 6: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.MAIN_POWER_OUTLET, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - MeteringCluster, - DeviceManagement.cluster_id, - ElectricalMeasurement.cluster_id, - Diagnostic.cluster_id, - 0xFC04, - ], - OUTPUT_CLUSTERS: [ - Ota.cluster_id, - ], - }, - 242: { - PROFILE_ID: zgp.PROFILE_ID, - DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC, - INPUT_CLUSTERS: [], - OUTPUT_CLUSTERS: [ - GreenPowerProxy.cluster_id, - ], - }, - }, - } +( + QuirkBuilder(SE_MANUF_NAME, "SOCKET/OUTLET/1") + .applies_to(SE_MANUF_NAME, "SOCKET/OUTLET/2") + .replaces(MeteringCluster, endpoint_id=6) + .add_to_registry() +) diff --git a/zhaquirks/sengled/e1e_g7f.py b/zhaquirks/sengled/e1e_g7f.py index cf151b32c2..0f2e3bfdc1 100644 --- a/zhaquirks/sengled/e1e_g7f.py +++ b/zhaquirks/sengled/e1e_g7f.py @@ -2,19 +2,11 @@ from typing import Any, Optional, Union -from zigpy.profiles import zha -from zigpy.quirks import CustomCluster, CustomDevice +from zigpy.quirks import CustomCluster +from zigpy.quirks.v2 import CustomDeviceV2, QuirkBuilder import zigpy.types as t -from zigpy.zcl import foundation -from zigpy.zcl.clusters.general import ( - Basic, - Groups, - Identify, - LevelControl, - OnOff, - PollControl, - PowerConfiguration, -) +from zigpy.zcl import ClusterType, foundation +from zigpy.zcl.clusters.general import LevelControl, OnOff from zigpy.zcl.foundation import BaseCommandDefs from zhaquirks import Bus @@ -23,17 +15,11 @@ COMMAND_OFF, COMMAND_ON, COMMAND_STEP, - DEVICE_TYPE, DIM_DOWN, DIM_UP, DOUBLE_PRESS, - ENDPOINTS, - INPUT_CLUSTERS, LONG_PRESS, - MODELS_INFO, - OUTPUT_CLUSTERS, PARAMS, - PROFILE_ID, SHORT_PRESS, TURN_OFF, TURN_ON, @@ -139,79 +125,45 @@ def handle_cluster_request( ) -class SengledE1EG7F(CustomDevice): +class SengledE1EG7FDevice(CustomDeviceV2): """Sengled E1E-G7F device.""" def __init__(self, *args, **kwargs): """Init.""" - self.on_off_bus = Bus() self.level_control_bus = Bus() - super().__init__(*args, **kwargs) - signature = { - MODELS_INFO: [("sengled", "E1E-G7F")], - ENDPOINTS: { - # - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.DIMMER_SWITCH, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - 0xFC11, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - SengledE1EG7FManufacturerSpecificCluster.cluster_id, - ], + +( + QuirkBuilder("sengled", "E1E-G7F") + .device_class(SengledE1EG7FDevice) + .replaces(SengledE1EG7FOnOffCluster, cluster_type=ClusterType.Client, endpoint_id=1) + .replaces( + SengledE1EG7FLevelControlCluster, cluster_type=ClusterType.Client, endpoint_id=1 + ) + .replaces( + SengledE1EG7FManufacturerSpecificCluster, + cluster_type=ClusterType.Client, + endpoint_id=1, + ) + .device_automation_triggers( + { + (SHORT_PRESS, TURN_ON): {COMMAND: COMMAND_ON}, + (LONG_PRESS, TURN_ON): {COMMAND: "on_long"}, + (DOUBLE_PRESS, TURN_ON): {COMMAND: "on_double"}, + (SHORT_PRESS, DIM_UP): { + COMMAND: COMMAND_STEP, + PARAMS: {"step_mode": 0}, }, - }, - } - - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - 0xFC11, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - SengledE1EG7FOnOffCluster, - SengledE1EG7FLevelControlCluster, - SengledE1EG7FManufacturerSpecificCluster, - ], + (SHORT_PRESS, DIM_DOWN): { + COMMAND: COMMAND_STEP, + PARAMS: {"step_mode": 1}, }, + (SHORT_PRESS, TURN_OFF): {COMMAND: COMMAND_OFF}, + (LONG_PRESS, TURN_OFF): {COMMAND: "off_long"}, + (DOUBLE_PRESS, TURN_OFF): {COMMAND: "off_double"}, } - } - - device_automation_triggers = { - (SHORT_PRESS, TURN_ON): {COMMAND: COMMAND_ON}, - (LONG_PRESS, TURN_ON): {COMMAND: "on_long"}, - (DOUBLE_PRESS, TURN_ON): {COMMAND: "on_double"}, - (SHORT_PRESS, DIM_UP): { - COMMAND: COMMAND_STEP, - PARAMS: {"step_mode": 0}, - }, - (SHORT_PRESS, DIM_DOWN): { - COMMAND: COMMAND_STEP, - PARAMS: {"step_mode": 1}, - }, - (SHORT_PRESS, TURN_OFF): {COMMAND: COMMAND_OFF}, - (LONG_PRESS, TURN_OFF): {COMMAND: "off_long"}, - (DOUBLE_PRESS, TURN_OFF): {COMMAND: "off_double"}, - } + ) + .add_to_registry() +) diff --git a/zhaquirks/sercomm/contact_sensor.py b/zhaquirks/sercomm/contact_sensor.py index ac19e21cdd..8a384c2b94 100644 --- a/zhaquirks/sercomm/contact_sensor.py +++ b/zhaquirks/sercomm/contact_sensor.py @@ -1,62 +1,7 @@ """Device handler for Sercomm XHS2-SE contact sensor.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import Basic, Identify, Ota, PollControl -from zigpy.zcl.clusters.homeautomation import Diagnostic -from zigpy.zcl.clusters.measurement import TemperatureMeasurement -from zigpy.zcl.clusters.security import IasZone +from zigpy.quirks.v2 import QuirkBuilder -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.sercomm import SERCOMM, SercommPowerConfiguration - -class XHS2SE(CustomDevice): - """Custom device representing Sercomm XHS2-SE contact sensor.""" - - signature = { - # - MODELS_INFO: [(SERCOMM, "XHS2-SE")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - SercommPowerConfiguration.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - IasZone.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [Identify.cluster_id, Ota.cluster_id], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - SercommPowerConfiguration, - Identify.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - IasZone.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [Identify.cluster_id, Ota.cluster_id], - } - } - } +(QuirkBuilder(SERCOMM, "XHS2-SE").replaces(SercommPowerConfiguration).add_to_registry()) diff --git a/zhaquirks/sercomm/flood_sensor.py b/zhaquirks/sercomm/flood_sensor.py index 517dd6bd6b..ecb4e2043b 100644 --- a/zhaquirks/sercomm/flood_sensor.py +++ b/zhaquirks/sercomm/flood_sensor.py @@ -1,60 +1,11 @@ """Device handler for Sercomm SZ-WTD02N flood sensor.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import Basic, Identify, Ota, PollControl -from zigpy.zcl.clusters.homeautomation import Diagnostic -from zigpy.zcl.clusters.security import IasZone +from zigpy.quirks.v2 import QuirkBuilder -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.sercomm import SERCOMM, SercommPowerConfiguration - -class SZWTD02N(CustomDevice): - """Custom device representing Sercomm SZ-WTD02N flood sensor.""" - - signature = { - # - MODELS_INFO: [(SERCOMM, "SZ-WTD02N_SF")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - SercommPowerConfiguration.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - IasZone.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [Identify.cluster_id, Ota.cluster_id], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - SercommPowerConfiguration, - Identify.cluster_id, - PollControl.cluster_id, - IasZone.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [Identify.cluster_id, Ota.cluster_id], - } - } - } +( + QuirkBuilder(SERCOMM, "SZ-WTD02N_SF") + .replaces(SercommPowerConfiguration) + .add_to_registry() +) diff --git a/zhaquirks/siglis/zigfred.py b/zhaquirks/siglis/zigfred.py index 4a3f1a620f..0433e6dbd0 100644 --- a/zhaquirks/siglis/zigfred.py +++ b/zhaquirks/siglis/zigfred.py @@ -3,21 +3,10 @@ import logging from typing import Any, Optional, Union -from zigpy.profiles import zgp, zha -from zigpy.quirks import CustomCluster, CustomDevice +from zigpy.quirks import CustomCluster +from zigpy.quirks.v2 import QuirkBuilder import zigpy.types as t from zigpy.zcl import foundation -from zigpy.zcl.clusters.closures import WindowCovering -from zigpy.zcl.clusters.general import ( - Basic, - GreenPowerProxy, - Groups, - Identify, - LevelControl, - OnOff, - Scenes, -) -from zigpy.zcl.clusters.lighting import Color from zigpy.zcl.foundation import BaseCommandDefs from zhaquirks.const import ( @@ -27,16 +16,10 @@ BUTTON_3, BUTTON_4, COMMAND, - DEVICE_TYPE, DOUBLE_PRESS, - ENDPOINTS, - INPUT_CLUSTERS, LONG_PRESS, LONG_RELEASE, - MODELS_INFO, - OUTPUT_CLUSTERS, PRESS_TYPE, - PROFILE_ID, SHORT_PRESS, ZHA_SEND_EVENT, ) @@ -114,417 +97,55 @@ def handle_cluster_request( self._process_button_event(args[0]) -class ZigfredUno(CustomDevice): - """zigfred uno device handler.""" - - signature = { - MODELS_INFO: [("Siglis", "zigfred uno")], - ENDPOINTS: { - 5: { - # Front Module LED - # SizePrefixedSimpleDescriptor(endpoint=5, - # profile=260, device_type=258, - # device_version=1, - # input_clusters=[0, 3, 4, 5, 6, 8, 768, 837], - # output_clusters=[]) - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.COLOR_DIMMABLE_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Color.cluster_id, - ZigfredCluster.cluster_id, - ], - OUTPUT_CLUSTERS: [], - }, - 6: { - # Relay - # SizePrefixedSimpleDescriptor(endpoint=6, - # profile=260, device_type=256, - # device_version=1, - # input_clusters=[0, 3, 4, 5, 6], - # output_clusters=[]) - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - ], - OUTPUT_CLUSTERS: [], - }, - 7: { - # Relay - # SizePrefixedSimpleDescriptor(endpoint=7, - # profile=260, device_type=257, - # device_version=1, - # input_clusters=[0, 3, 5, 4, 6, 8], - # output_clusters=[]) - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.DIMMABLE_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - ], - OUTPUT_CLUSTERS: [], - }, - 242: { - # SizePrefixedSimpleDescriptor(endpoint=242, - # profile=41440, device_type=97, - # device_version=0, - # input_clusters=[], - # output_clusters=[33]) - PROFILE_ID: zgp.PROFILE_ID, - DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC, - INPUT_CLUSTERS: [], - OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id], - }, - }, - } - - replacement = { - ENDPOINTS: { - 5: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.COLOR_DIMMABLE_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Color.cluster_id, - ZigfredCluster, - ], - OUTPUT_CLUSTERS: [], - }, - 6: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - ], - }, - 7: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.DIMMABLE_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - ], - }, - 242: { - PROFILE_ID: zgp.PROFILE_ID, - DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC, - INPUT_CLUSTERS: [], - OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id], - }, - }, - } - - device_automation_triggers = { - (SHORT_PRESS, BUTTON_1): {COMMAND: f"{BUTTON_1}_{SHORT_PRESS}"}, - (SHORT_PRESS, BUTTON_2): {COMMAND: f"{BUTTON_2}_{SHORT_PRESS}"}, - (SHORT_PRESS, BUTTON_3): {COMMAND: f"{BUTTON_3}_{SHORT_PRESS}"}, - (SHORT_PRESS, BUTTON_4): {COMMAND: f"{BUTTON_4}_{SHORT_PRESS}"}, - (DOUBLE_PRESS, BUTTON_1): {COMMAND: f"{BUTTON_1}_{DOUBLE_PRESS}"}, - (DOUBLE_PRESS, BUTTON_2): {COMMAND: f"{BUTTON_2}_{DOUBLE_PRESS}"}, - (DOUBLE_PRESS, BUTTON_3): {COMMAND: f"{BUTTON_3}_{DOUBLE_PRESS}"}, - (DOUBLE_PRESS, BUTTON_4): {COMMAND: f"{BUTTON_4}_{DOUBLE_PRESS}"}, - (LONG_PRESS, BUTTON_1): {COMMAND: f"{BUTTON_1}_{LONG_PRESS}"}, - (LONG_PRESS, BUTTON_2): {COMMAND: f"{BUTTON_2}_{LONG_PRESS}"}, - (LONG_PRESS, BUTTON_3): {COMMAND: f"{BUTTON_3}_{LONG_PRESS}"}, - (LONG_PRESS, BUTTON_4): {COMMAND: f"{BUTTON_4}_{LONG_PRESS}"}, - (LONG_RELEASE, BUTTON_1): {COMMAND: f"{BUTTON_1}_{LONG_RELEASE}"}, - (LONG_RELEASE, BUTTON_2): {COMMAND: f"{BUTTON_2}_{LONG_RELEASE}"}, - (LONG_RELEASE, BUTTON_3): {COMMAND: f"{BUTTON_3}_{LONG_RELEASE}"}, - (LONG_RELEASE, BUTTON_4): {COMMAND: f"{BUTTON_4}_{LONG_RELEASE}"}, - } - - -class ZigfredPlus(CustomDevice): - """zigfred plus device handler.""" - - signature = { - MODELS_INFO: [("Siglis", "zigfred plus")], - ENDPOINTS: { - 5: { - # Front Module LED - # SizePrefixedSimpleDescriptor(endpoint=5, - # profile=260, device_type=258, - # device_version=1, - # input_clusters=[0, 3, 4, 5, 6, 8, 768, 837], - # output_clusters=[]) - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.COLOR_DIMMABLE_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Color.cluster_id, - ZigfredCluster.cluster_id, - ], - OUTPUT_CLUSTERS: [], - }, - 7: { - # Dimmable Light 1 - # SizePrefixedSimpleDescriptor(endpoint=7, - # profile=260, device_type=257, - # device_version=1, - # input_clusters=[0, 3, 5, 4, 6, 8], - # output_clusters=[]) - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.DIMMABLE_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - ], - OUTPUT_CLUSTERS: [], - }, - 8: { - # Dimmable Light 2 - # SizePrefixedSimpleDescriptor(endpoint=8, - # profile=260, device_type=257, - # device_version=1, - # input_clusters=[0, 3, 5, 4, 6, 8], - # output_clusters=[]) - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.DIMMABLE_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - ], - OUTPUT_CLUSTERS: [], - }, - 9: { - # Dimmable Light 3 - # SizePrefixedSimpleDescriptor(endpoint=9, - # profile=260, device_type=257, - # device_version=1, - # input_clusters=[0, 3, 5, 4, 6, 8], - # output_clusters=[]) - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.DIMMABLE_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - ], - OUTPUT_CLUSTERS: [], - }, - 10: { - # Dimmable Light 4 - # SizePrefixedSimpleDescriptor(endpoint=10, - # profile=260, device_type=257, - # device_version=1, - # input_clusters=[0, 3, 5, 4, 6, 8], - # output_clusters=[]) - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.DIMMABLE_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - ], - OUTPUT_CLUSTERS: [], - }, - 11: { - # Window Cover 1 - # SizePrefixedSimpleDescriptor(endpoint=11, - # profile=260, device_type=514, - # device_version=1, - # input_clusters=[0, 3, 5, 4, 258], - # output_clusters=[]) - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.WINDOW_COVERING_DEVICE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - WindowCovering.cluster_id, - ], - OUTPUT_CLUSTERS: [], - }, - 12: { - # Window Cover 1 - # SizePrefixedSimpleDescriptor(endpoint=12, - # profile=260, device_type=514, - # device_version=1, - # input_clusters=[0, 3, 5, 4, 258], - # output_clusters=[]) - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.WINDOW_COVERING_DEVICE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - WindowCovering.cluster_id, - ], - OUTPUT_CLUSTERS: [], - }, - 242: { - # SizePrefixedSimpleDescriptor(endpoint=242, - # profile=41440, device_type=97, - # device_version=0, - # input_clusters=[], - # output_clusters=[33]) - PROFILE_ID: zgp.PROFILE_ID, - DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC, - INPUT_CLUSTERS: [], - OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id], - }, - }, - } +( + QuirkBuilder("Siglis", "zigfred uno") + .replaces(ZigfredCluster, endpoint_id=5) + .device_automation_triggers( + { + (SHORT_PRESS, BUTTON_1): {COMMAND: f"{BUTTON_1}_{SHORT_PRESS}"}, + (SHORT_PRESS, BUTTON_2): {COMMAND: f"{BUTTON_2}_{SHORT_PRESS}"}, + (SHORT_PRESS, BUTTON_3): {COMMAND: f"{BUTTON_3}_{SHORT_PRESS}"}, + (SHORT_PRESS, BUTTON_4): {COMMAND: f"{BUTTON_4}_{SHORT_PRESS}"}, + (DOUBLE_PRESS, BUTTON_1): {COMMAND: f"{BUTTON_1}_{DOUBLE_PRESS}"}, + (DOUBLE_PRESS, BUTTON_2): {COMMAND: f"{BUTTON_2}_{DOUBLE_PRESS}"}, + (DOUBLE_PRESS, BUTTON_3): {COMMAND: f"{BUTTON_3}_{DOUBLE_PRESS}"}, + (DOUBLE_PRESS, BUTTON_4): {COMMAND: f"{BUTTON_4}_{DOUBLE_PRESS}"}, + (LONG_PRESS, BUTTON_1): {COMMAND: f"{BUTTON_1}_{LONG_PRESS}"}, + (LONG_PRESS, BUTTON_2): {COMMAND: f"{BUTTON_2}_{LONG_PRESS}"}, + (LONG_PRESS, BUTTON_3): {COMMAND: f"{BUTTON_3}_{LONG_PRESS}"}, + (LONG_PRESS, BUTTON_4): {COMMAND: f"{BUTTON_4}_{LONG_PRESS}"}, + (LONG_RELEASE, BUTTON_1): {COMMAND: f"{BUTTON_1}_{LONG_RELEASE}"}, + (LONG_RELEASE, BUTTON_2): {COMMAND: f"{BUTTON_2}_{LONG_RELEASE}"}, + (LONG_RELEASE, BUTTON_3): {COMMAND: f"{BUTTON_3}_{LONG_RELEASE}"}, + (LONG_RELEASE, BUTTON_4): {COMMAND: f"{BUTTON_4}_{LONG_RELEASE}"}, + } + ) + .add_to_registry() +) - replacement = { - ENDPOINTS: { - 5: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.COLOR_DIMMABLE_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Color.cluster_id, - ZigfredCluster, - ], - OUTPUT_CLUSTERS: [], - }, - 7: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.DIMMABLE_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - ], - }, - 8: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.DIMMABLE_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - ], - }, - 9: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.DIMMABLE_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - ], - }, - 10: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.DIMMABLE_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - ], - }, - 11: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.WINDOW_COVERING_DEVICE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - WindowCovering.cluster_id, - ], - }, - 12: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.WINDOW_COVERING_DEVICE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - WindowCovering.cluster_id, - ], - }, - 242: { - PROFILE_ID: zgp.PROFILE_ID, - DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC, - INPUT_CLUSTERS: [], - OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id], - }, - }, - } - device_automation_triggers = { - (SHORT_PRESS, BUTTON_1): {COMMAND: f"{BUTTON_1}_{SHORT_PRESS}"}, - (SHORT_PRESS, BUTTON_2): {COMMAND: f"{BUTTON_2}_{SHORT_PRESS}"}, - (SHORT_PRESS, BUTTON_3): {COMMAND: f"{BUTTON_3}_{SHORT_PRESS}"}, - (SHORT_PRESS, BUTTON_4): {COMMAND: f"{BUTTON_4}_{SHORT_PRESS}"}, - (DOUBLE_PRESS, BUTTON_1): {COMMAND: f"{BUTTON_1}_{DOUBLE_PRESS}"}, - (DOUBLE_PRESS, BUTTON_2): {COMMAND: f"{BUTTON_2}_{DOUBLE_PRESS}"}, - (DOUBLE_PRESS, BUTTON_3): {COMMAND: f"{BUTTON_3}_{DOUBLE_PRESS}"}, - (DOUBLE_PRESS, BUTTON_4): {COMMAND: f"{BUTTON_4}_{DOUBLE_PRESS}"}, - (LONG_PRESS, BUTTON_1): {COMMAND: f"{BUTTON_1}_{LONG_PRESS}"}, - (LONG_PRESS, BUTTON_2): {COMMAND: f"{BUTTON_2}_{LONG_PRESS}"}, - (LONG_PRESS, BUTTON_3): {COMMAND: f"{BUTTON_3}_{LONG_PRESS}"}, - (LONG_PRESS, BUTTON_4): {COMMAND: f"{BUTTON_4}_{LONG_PRESS}"}, - (LONG_RELEASE, BUTTON_1): {COMMAND: f"{BUTTON_1}_{LONG_RELEASE}"}, - (LONG_RELEASE, BUTTON_2): {COMMAND: f"{BUTTON_2}_{LONG_RELEASE}"}, - (LONG_RELEASE, BUTTON_3): {COMMAND: f"{BUTTON_3}_{LONG_RELEASE}"}, - (LONG_RELEASE, BUTTON_4): {COMMAND: f"{BUTTON_4}_{LONG_RELEASE}"}, - } +( + QuirkBuilder("Siglis", "zigfred plus") + .replaces(ZigfredCluster, endpoint_id=5) + .device_automation_triggers( + { + (SHORT_PRESS, BUTTON_1): {COMMAND: f"{BUTTON_1}_{SHORT_PRESS}"}, + (SHORT_PRESS, BUTTON_2): {COMMAND: f"{BUTTON_2}_{SHORT_PRESS}"}, + (SHORT_PRESS, BUTTON_3): {COMMAND: f"{BUTTON_3}_{SHORT_PRESS}"}, + (SHORT_PRESS, BUTTON_4): {COMMAND: f"{BUTTON_4}_{SHORT_PRESS}"}, + (DOUBLE_PRESS, BUTTON_1): {COMMAND: f"{BUTTON_1}_{DOUBLE_PRESS}"}, + (DOUBLE_PRESS, BUTTON_2): {COMMAND: f"{BUTTON_2}_{DOUBLE_PRESS}"}, + (DOUBLE_PRESS, BUTTON_3): {COMMAND: f"{BUTTON_3}_{DOUBLE_PRESS}"}, + (DOUBLE_PRESS, BUTTON_4): {COMMAND: f"{BUTTON_4}_{DOUBLE_PRESS}"}, + (LONG_PRESS, BUTTON_1): {COMMAND: f"{BUTTON_1}_{LONG_PRESS}"}, + (LONG_PRESS, BUTTON_2): {COMMAND: f"{BUTTON_2}_{LONG_PRESS}"}, + (LONG_PRESS, BUTTON_3): {COMMAND: f"{BUTTON_3}_{LONG_PRESS}"}, + (LONG_PRESS, BUTTON_4): {COMMAND: f"{BUTTON_4}_{LONG_PRESS}"}, + (LONG_RELEASE, BUTTON_1): {COMMAND: f"{BUTTON_1}_{LONG_RELEASE}"}, + (LONG_RELEASE, BUTTON_2): {COMMAND: f"{BUTTON_2}_{LONG_RELEASE}"}, + (LONG_RELEASE, BUTTON_3): {COMMAND: f"{BUTTON_3}_{LONG_RELEASE}"}, + (LONG_RELEASE, BUTTON_4): {COMMAND: f"{BUTTON_4}_{LONG_RELEASE}"}, + } + ) + .add_to_registry() +) diff --git a/zhaquirks/sinope/light.py b/zhaquirks/sinope/light.py index bd5249dc9c..fd7007916c 100644 --- a/zhaquirks/sinope/light.py +++ b/zhaquirks/sinope/light.py @@ -8,22 +8,10 @@ from typing import Any, Final, Optional, Union import zigpy.profiles.zha as zha_p -from zigpy.quirks import CustomCluster, CustomDevice +from zigpy.quirks import CustomCluster +from zigpy.quirks.v2 import QuirkBuilder import zigpy.types as t from zigpy.zcl import foundation -from zigpy.zcl.clusters.general import ( - Basic, - DeviceTemperature, - Groups, - Identify, - LevelControl, - OnOff, - Ota, - Scenes, - Time, -) -from zigpy.zcl.clusters.homeautomation import Diagnostic, ElectricalMeasurement -from zigpy.zcl.clusters.smartenergy import Metering from zigpy.zcl.foundation import BaseCommandDefs from zhaquirks import EventableCluster @@ -36,12 +24,6 @@ COMMAND_M_MULTI_PRESS_COMPLETE, COMMAND_M_SHORT_RELEASE, DESCRIPTION, - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, TURN_OFF, TURN_ON, VALUE, @@ -239,198 +221,37 @@ class LightManufacturerCluster(EventableCluster, SinopeTechnologiesManufacturerC """LightManufacturerCluster: fire events corresponding to press type.""" -class SinopeTechnologieslight(CustomDevice): - """SinopeTechnologiesLight custom device.""" - - signature = { - # - MODELS_INFO: [ - (SINOPE, "SW2500ZB"), - (SINOPE, "SW2500ZB-G2"), - ], - ENDPOINTS: { - 1: { - PROFILE_ID: zha_p.PROFILE_ID, - DEVICE_TYPE: zha_p.DeviceType.ON_OFF_LIGHT_SWITCH, - INPUT_CLUSTERS: [ - Basic.cluster_id, - DeviceTemperature.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - Metering.cluster_id, - Diagnostic.cluster_id, - SINOPE_MANUFACTURER_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - Ota.cluster_id, - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha_p.PROFILE_ID, - DEVICE_TYPE: zha_p.DeviceType.ON_OFF_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - CustomDeviceTemperatureCluster, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - Metering.cluster_id, - Diagnostic.cluster_id, - LightManufacturerCluster, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - Ota.cluster_id, - ], - } - } - } - - device_automation_triggers = LIGHT_DEVICE_TRIGGERS - - -class SinopeDM2500ZB(CustomDevice): - """DM2500ZB, DM2500ZB-G2 Dimmers.""" - - signature = { - # - MODELS_INFO: [ - (SINOPE, "DM2500ZB"), - (SINOPE, "DM2500ZB-G2"), - ], - ENDPOINTS: { - 1: { - PROFILE_ID: zha_p.PROFILE_ID, - DEVICE_TYPE: zha_p.DeviceType.DIMMER_SWITCH, - INPUT_CLUSTERS: [ - Basic.cluster_id, - DeviceTemperature.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Metering.cluster_id, - Diagnostic.cluster_id, - SINOPE_MANUFACTURER_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - Ota.cluster_id, - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha_p.PROFILE_ID, - DEVICE_TYPE: zha_p.DeviceType.DIMMABLE_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - CustomDeviceTemperatureCluster, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Metering.cluster_id, - Diagnostic.cluster_id, - LightManufacturerCluster, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - Ota.cluster_id, - ], - } - } - } - - device_automation_triggers = LIGHT_DEVICE_TRIGGERS - - -class SinopeDM2550ZB(CustomDevice): - """DM2550ZB, DM2550ZB-G2 Dimmers.""" - - signature = { - # - MODELS_INFO: [ - (SINOPE, "DM2550ZB"), - (SINOPE, "DM2550ZB-G2"), - ], - ENDPOINTS: { - 1: { - PROFILE_ID: zha_p.PROFILE_ID, - DEVICE_TYPE: zha_p.DeviceType.DIMMER_SWITCH, - INPUT_CLUSTERS: [ - Basic.cluster_id, - DeviceTemperature.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Metering.cluster_id, - ElectricalMeasurement.cluster_id, - Diagnostic.cluster_id, - SINOPE_MANUFACTURER_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - Time.cluster_id, - Ota.cluster_id, - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha_p.PROFILE_ID, - DEVICE_TYPE: zha_p.DeviceType.DIMMABLE_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - CustomDeviceTemperatureCluster, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Metering.cluster_id, - ElectricalMeasurement.cluster_id, - Diagnostic.cluster_id, - LightManufacturerCluster, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - Time.cluster_id, - Ota.cluster_id, - ], - } - } - } +( + QuirkBuilder(SINOPE, "SW2500ZB") + .applies_to(SINOPE, "SW2500ZB-G2") + .replaces_endpoint( + 1, device_type=zha_p.DeviceType.ON_OFF_LIGHT + ) # Was ON_OFF_LIGHT_SWITCH + .replaces(LightManufacturerCluster, endpoint_id=1) + .device_automation_triggers(LIGHT_DEVICE_TRIGGERS) + .add_to_registry() +) + +( + QuirkBuilder(SINOPE, "DM2500ZB") + .applies_to(SINOPE, "DM2500ZB-G2") + .replaces_endpoint( + 1, device_type=zha_p.DeviceType.DIMMABLE_LIGHT + ) # Was DIMMER_SWITCH + .replaces(CustomDeviceTemperatureCluster, endpoint_id=1) + .replaces(LightManufacturerCluster, endpoint_id=1) + .device_automation_triggers(LIGHT_DEVICE_TRIGGERS) + .add_to_registry() +) - device_automation_triggers = LIGHT_DEVICE_TRIGGERS +( + QuirkBuilder(SINOPE, "DM2550ZB") + .applies_to(SINOPE, "DM2550ZB-G2") + .replaces_endpoint( + 1, device_type=zha_p.DeviceType.DIMMABLE_LIGHT + ) # Was DIMMER_SWITCH + .replaces(CustomDeviceTemperatureCluster, endpoint_id=1) + .replaces(LightManufacturerCluster, endpoint_id=1) + .device_automation_triggers(LIGHT_DEVICE_TRIGGERS) + .add_to_registry() +) diff --git a/zhaquirks/sinope/sensor.py b/zhaquirks/sinope/sensor.py index 7fbdf1dbb7..e028b495c9 100644 --- a/zhaquirks/sinope/sensor.py +++ b/zhaquirks/sinope/sensor.py @@ -7,29 +7,12 @@ from typing import Final import zigpy.profiles.zha as zha_p -from zigpy.quirks import CustomCluster, CustomDevice +from zigpy.quirks import CustomCluster +from zigpy.quirks.v2 import QuirkBuilder import zigpy.types as t from zigpy.zcl import foundation -from zigpy.zcl.clusters.general import ( - AnalogInput, - Basic, - Identify, - Ota, - PollControl, - PowerConfiguration, -) -from zigpy.zcl.clusters.homeautomation import Diagnostic -from zigpy.zcl.clusters.measurement import TemperatureMeasurement from zigpy.zcl.clusters.security import IasZone -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.sinope import SINOPE, SINOPE_MANUFACTURER_CLUSTER_ID @@ -87,167 +70,18 @@ class AttributeDefs(IasZone.AttributeDefs): ) -class SinopeTechnologiesSensor(CustomDevice): - """SinopeTechnologiesSensor custom device.""" - - signature = { - # - MODELS_INFO: [ - (SINOPE, "WL4200"), - (SINOPE, "WL4200S"), - ], - ENDPOINTS: { - 1: { - PROFILE_ID: zha_p.PROFILE_ID, - DEVICE_TYPE: zha_p.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - TemperatureMeasurement.cluster_id, - IasZone.cluster_id, - Diagnostic.cluster_id, - SINOPE_MANUFACTURER_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Ota.cluster_id, - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha_p.PROFILE_ID, - DEVICE_TYPE: zha_p.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - TemperatureMeasurement.cluster_id, - SinopeTechnologiesIasZoneCluster, - Diagnostic.cluster_id, - SinopeManufacturerCluster, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Ota.cluster_id, - ], - } - } - } - - -class SinopeTechnologiesSensor2(CustomDevice): - """SinopeTechnologiesSensor2 custom device.""" - - signature = { - # - MODELS_INFO: [ - (SINOPE, "WL4200"), - (SINOPE, "WL4200S"), - ], - ENDPOINTS: { - 1: { - PROFILE_ID: zha_p.PROFILE_ID, - DEVICE_TYPE: zha_p.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - IasZone.cluster_id, - Diagnostic.cluster_id, - SINOPE_MANUFACTURER_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Ota.cluster_id, - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha_p.PROFILE_ID, - DEVICE_TYPE: zha_p.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - SinopeTechnologiesIasZoneCluster, - Diagnostic.cluster_id, - SinopeManufacturerCluster, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Ota.cluster_id, - ], - } - } - } - - -class SinopeTechnologiesLevelMonitor(CustomDevice): - """SinopeTechnologiesLevelMonitor custom device.""" - - signature = { - # - MODELS_INFO: [ - (SINOPE, "LM4110-ZB"), - ], - ENDPOINTS: { - 1: { - PROFILE_ID: zha_p.PROFILE_ID, - DEVICE_TYPE: zha_p.DeviceType.ON_OFF_SWITCH, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - AnalogInput.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - Diagnostic.cluster_id, - SINOPE_MANUFACTURER_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Ota.cluster_id, - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha_p.PROFILE_ID, - DEVICE_TYPE: zha_p.DeviceType.METER_INTERFACE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - AnalogInput.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - Diagnostic.cluster_id, - SinopeManufacturerCluster, - ], - OUTPUT_CLUSTERS: [ - Ota.cluster_id, - ], - } - } - } +( + QuirkBuilder(SINOPE, "WL4200") + .applies_to(SINOPE, "WL4200S") + .replaces(SinopeTechnologiesIasZoneCluster, endpoint_id=1) + .replaces(SinopeManufacturerCluster, endpoint_id=1) + .add_to_registry() +) + + +( + QuirkBuilder(SINOPE, "LM4110-ZB") + .replaces_endpoint(1, device_type=zha_p.DeviceType.METER_INTERFACE) + .replaces(SinopeManufacturerCluster, endpoint_id=1) + .add_to_registry() +) diff --git a/zhaquirks/sinope/switch.py b/zhaquirks/sinope/switch.py index e3eada7b84..f2061c87c6 100644 --- a/zhaquirks/sinope/switch.py +++ b/zhaquirks/sinope/switch.py @@ -8,41 +8,15 @@ from typing import Final import zigpy.profiles.zha as zha_p -from zigpy.quirks import CustomCluster, CustomDevice +from zigpy.quirks import CustomCluster +from zigpy.quirks.v2 import QuirkBuilder import zigpy.types as t from zigpy.zcl import foundation -from zigpy.zcl.clusters.general import ( - Basic, - BinaryInput, - DeviceTemperature, - Groups, - Identify, - LevelControl, - OnOff, - Ota, - PowerConfiguration, - Scenes, - Time, -) -from zigpy.zcl.clusters.homeautomation import Diagnostic, ElectricalMeasurement -from zigpy.zcl.clusters.lightlink import LightLink -from zigpy.zcl.clusters.measurement import ( - FlowMeasurement, - RelativeHumidity, - TemperatureMeasurement, -) -from zigpy.zcl.clusters.security import IasZone +from zigpy.zcl.clusters.general import Basic +from zigpy.zcl.clusters.measurement import FlowMeasurement from zigpy.zcl.clusters.smartenergy import Metering from zigpy.zcl.foundation import Array -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.sinope import ( SINOPE, SINOPE_MANUFACTURER_CLUSTER_ID, @@ -311,500 +285,57 @@ def _update_attribute(self, attrid, value): super()._update_attribute(attrid, value) -class SinopeTechnologiesSwitch(CustomDevice): - """SinopeTechnologiesSwitch custom device.""" - - signature = { - # - MODELS_INFO: [ - (SINOPE, "SP2600ZB"), - (SINOPE, "SP2610ZB"), - ], - ENDPOINTS: { - 1: { - PROFILE_ID: zha_p.PROFILE_ID, - DEVICE_TYPE: zha_p.DeviceType.SMART_PLUG, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - OnOff.cluster_id, - Metering.cluster_id, - ElectricalMeasurement.cluster_id, - SINOPE_MANUFACTURER_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - OnOff.cluster_id, - SinopeTechnologiesMeteringCluster, - ElectricalMeasurement.cluster_id, - SinopeManufacturerCluster, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - } - } - - -class SinopeTechnologiesLoadController(CustomDevice): - """SinopeTechnologiesLoadController custom device.""" - - signature = { - # - MODELS_INFO: [ - (SINOPE, "RM3250ZB"), - ], - ENDPOINTS: { - 1: { - PROFILE_ID: zha_p.PROFILE_ID, - DEVICE_TYPE: zha_p.DeviceType.ON_OFF_OUTPUT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - Metering.cluster_id, - ElectricalMeasurement.cluster_id, - Diagnostic.cluster_id, - SINOPE_MANUFACTURER_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - Ota.cluster_id, - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - Metering.cluster_id, - ElectricalMeasurement.cluster_id, - Diagnostic.cluster_id, - SinopeManufacturerCluster, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - Ota.cluster_id, - ], - } - } - } - - -class SinopeTechnologiesLoadController_V2(CustomDevice): - """SinopeTechnologiesLoadController version 2 custom device.""" - - signature = { - # - MODELS_INFO: [ - (SINOPE, "RM3250ZB"), - ], - ENDPOINTS: { - 1: { - PROFILE_ID: zha_p.PROFILE_ID, - DEVICE_TYPE: zha_p.DeviceType.ON_OFF_OUTPUT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - DeviceTemperature.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - Metering.cluster_id, - ElectricalMeasurement.cluster_id, - Diagnostic.cluster_id, - SINOPE_MANUFACTURER_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - Ota.cluster_id, - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - CustomDeviceTemperatureCluster, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - Metering.cluster_id, - ElectricalMeasurement.cluster_id, - Diagnostic.cluster_id, - SinopeManufacturerCluster, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Groups.cluster_id, - Ota.cluster_id, - ], - } - } - } - - -class SinopeTechnologiesValve(CustomDevice): - """SinopeTechnologiesValve custom device.""" - - signature = { - # - MODELS_INFO: [ - (SINOPE, "VA4200WZ"), - (SINOPE, "VA4201WZ"), - (SINOPE, "VA4200ZB"), - (SINOPE, "VA4201ZB"), - (SINOPE, "VA4220ZB"), - (SINOPE, "VA4221ZB"), - ], - ENDPOINTS: { - 1: { - PROFILE_ID: zha_p.PROFILE_ID, - DEVICE_TYPE: zha_p.DeviceType.LEVEL_CONTROLLABLE_OUTPUT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Diagnostic.cluster_id, - SINOPE_MANUFACTURER_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Ota.cluster_id, - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [ - SinopeTechnologiesBasicCluster, - PowerConfiguration.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Diagnostic.cluster_id, - SinopeManufacturerCluster, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Ota.cluster_id, - ], - } - } - } - - -class SinopeTechnologiesValveG2(CustomDevice): - """SinopeTechnologiesValveG2 custom device.""" - - signature = { - # - MODELS_INFO: [ - (SINOPE, "VA4220ZB"), - (SINOPE, "VA4221ZB"), - ], - ENDPOINTS: { - 1: { - PROFILE_ID: zha_p.PROFILE_ID, - DEVICE_TYPE: zha_p.DeviceType.LEVEL_CONTROLLABLE_OUTPUT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - TemperatureMeasurement.cluster_id, - IasZone.cluster_id, - Metering.cluster_id, - Diagnostic.cluster_id, - SINOPE_MANUFACTURER_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - OnOff.cluster_id, - Ota.cluster_id, - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [ - SinopeTechnologiesBasicCluster, - PowerConfiguration.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - TemperatureMeasurement.cluster_id, - SinopeTechnologiesFlowMeasurementCluster, - IasZone.cluster_id, - SinopeTechnologiesMeteringCluster, - Diagnostic.cluster_id, - SinopeManufacturerCluster, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - OnOff.cluster_id, - Ota.cluster_id, - ], - } - } - } - - -class SinopeTechnologiesMultiController(CustomDevice): - """SinopeTechnologiesMultiController custom device.""" - - signature = { - # - MODELS_INFO: [(SINOPE, "MC3100ZB")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha_p.PROFILE_ID, - DEVICE_TYPE: zha_p.DeviceType.ON_OFF_OUTPUT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - BinaryInput.cluster_id, - TemperatureMeasurement.cluster_id, - RelativeHumidity.cluster_id, - Diagnostic.cluster_id, - SINOPE_MANUFACTURER_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - }, - 2: { - PROFILE_ID: zha_p.PROFILE_ID, - DEVICE_TYPE: zha_p.DeviceType.ON_OFF_OUTPUT, - INPUT_CLUSTERS: [ - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - BinaryInput.cluster_id, - TemperatureMeasurement.cluster_id, - SINOPE_MANUFACTURER_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [], - }, - }, - } - - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - BinaryInput.cluster_id, - TemperatureMeasurement.cluster_id, - RelativeHumidity.cluster_id, - Diagnostic.cluster_id, - SinopeManufacturerCluster, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - }, - 2: { - INPUT_CLUSTERS: [ - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - BinaryInput.cluster_id, - TemperatureMeasurement.cluster_id, - SinopeManufacturerCluster, - ], - OUTPUT_CLUSTERS: [], - }, - }, - } - - -class SinopeTechnologiesCalypso(CustomDevice): - """SinopeTechnologiesCalypso custom device.""" - - signature = { - # - MODELS_INFO: [ - (SINOPE, "RM3500ZB"), - ], - ENDPOINTS: { - 1: { - PROFILE_ID: zha_p.PROFILE_ID, - DEVICE_TYPE: zha_p.DeviceType.DIMMER_SWITCH, - INPUT_CLUSTERS: [ - Basic.cluster_id, - DeviceTemperature.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - TemperatureMeasurement.cluster_id, - IasZone.cluster_id, - Metering.cluster_id, - ElectricalMeasurement.cluster_id, - Diagnostic.cluster_id, - SINOPE_MANUFACTURER_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Time.cluster_id, - Ota.cluster_id, - ], - }, - 2: { - PROFILE_ID: zha_p.PROFILE_ID, - DEVICE_TYPE: zha_p.DeviceType.DIMMER_SWITCH, - INPUT_CLUSTERS: [ - TemperatureMeasurement.cluster_id, - ], - OUTPUT_CLUSTERS: [], - }, - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha_p.PROFILE_ID, - DEVICE_TYPE: zha_p.DeviceType.ON_OFF_OUTPUT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - CustomDeviceTemperatureCluster, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - TemperatureMeasurement.cluster_id, - IasZone.cluster_id, - Metering.cluster_id, - ElectricalMeasurement.cluster_id, - Diagnostic.cluster_id, - SinopeManufacturerCluster, - ], - OUTPUT_CLUSTERS: [ - Time.cluster_id, - Ota.cluster_id, - ], - } - } - } - - -class SinopeTechnologiesSwitch_V2(CustomDevice): - """SinopeTechnologiesSwitch version 2 custom device.""" - - signature = { - # - MODELS_INFO: [ - (SINOPE, "SP2600ZB"), - (SINOPE, "SP2610ZB"), - ], - ENDPOINTS: { - 1: { - PROFILE_ID: zha_p.PROFILE_ID, - DEVICE_TYPE: zha_p.DeviceType.SMART_PLUG, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - OnOff.cluster_id, - Metering.cluster_id, - ElectricalMeasurement.cluster_id, - LightLink.cluster_id, - SINOPE_MANUFACTURER_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Ota.cluster_id, - LightLink.cluster_id, - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - OnOff.cluster_id, - SinopeTechnologiesMeteringCluster, - ElectricalMeasurement.cluster_id, - LightLink.cluster_id, - SinopeManufacturerCluster, - ], - OUTPUT_CLUSTERS: [ - Ota.cluster_id, - LightLink.cluster_id, - ], - } - } - } +( + QuirkBuilder(SINOPE, "SP2600ZB") + .applies_to(SINOPE, "SP2610ZB") + .replaces(SinopeTechnologiesMeteringCluster, endpoint_id=1) + .replaces(SinopeManufacturerCluster, endpoint_id=1) + .add_to_registry() +) + + +( + QuirkBuilder(SINOPE, "RM3250ZB") + .replaces(CustomDeviceTemperatureCluster, endpoint_id=1) + .replaces(SinopeManufacturerCluster, endpoint_id=1) + .add_to_registry() +) + + +( + QuirkBuilder(SINOPE, "VA4200WZ") + .applies_to(SINOPE, "VA4201WZ") + .applies_to(SINOPE, "VA4200ZB") + .applies_to(SINOPE, "VA4201ZB") + .replaces(SinopeTechnologiesBasicCluster, endpoint_id=1) + .replaces(SinopeManufacturerCluster, endpoint_id=1) + .add_to_registry() +) + + +( + QuirkBuilder(SINOPE, "VA4220ZB") + .applies_to(SINOPE, "VA4221ZB") + .replaces(SinopeTechnologiesBasicCluster, endpoint_id=1) + .replaces(SinopeTechnologiesMeteringCluster, endpoint_id=1) + .replaces(SinopeManufacturerCluster, endpoint_id=1) + .adds(SinopeTechnologiesFlowMeasurementCluster, endpoint_id=1) + .add_to_registry() +) + + +( + QuirkBuilder(SINOPE, "RM3500ZB") + .replaces_endpoint(1, device_type=zha_p.DeviceType.ON_OFF_OUTPUT) + .replaces(CustomDeviceTemperatureCluster, endpoint_id=1) + .replaces(SinopeManufacturerCluster, endpoint_id=1) + .add_to_registry() +) + + +( + QuirkBuilder(SINOPE, "MC3100ZB") + .replaces(SinopeManufacturerCluster, endpoint_id=1) + .replaces(SinopeManufacturerCluster, endpoint_id=2) + .add_to_registry() +) diff --git a/zhaquirks/sinope/thermostat.py b/zhaquirks/sinope/thermostat.py index 3a0d3515b5..b5c8b46b7e 100644 --- a/zhaquirks/sinope/thermostat.py +++ b/zhaquirks/sinope/thermostat.py @@ -6,34 +6,14 @@ from typing import Final -import zigpy.profiles.zha as zha_p -from zigpy.quirks import CustomCluster, CustomDevice +from zigpy.quirks import CustomCluster +from zigpy.quirks.v2 import QuirkBuilder import zigpy.types as t from zigpy.zcl import foundation -from zigpy.zcl.clusters.general import ( - Basic, - Groups, - Identify, - LevelControl, - Ota, - PowerConfiguration, - Scenes, - Time, -) -from zigpy.zcl.clusters.homeautomation import Diagnostic, ElectricalMeasurement -from zigpy.zcl.clusters.hvac import Fan, Thermostat, UserInterface -from zigpy.zcl.clusters.measurement import TemperatureMeasurement -from zigpy.zcl.clusters.smartenergy import Metering +from zigpy.zcl.clusters.homeautomation import ElectricalMeasurement +from zigpy.zcl.clusters.hvac import Thermostat from zigpy.zcl.foundation import Array -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.sinope import SINOPE, SINOPE_MANUFACTURER_CLUSTER_ID @@ -336,403 +316,35 @@ class AttributeDefs(ElectricalMeasurement.AttributeDefs): ) -class SinopeTechnologiesThermostat(CustomDevice): - """SinopeTechnologiesThermostat custom device.""" - - signature = { - # - MODELS_INFO: [ - (SINOPE, "TH1123ZB"), - (SINOPE, "TH1124ZB"), - (SINOPE, "TH1500ZB"), - ], - ENDPOINTS: { - 1: { - PROFILE_ID: zha_p.PROFILE_ID, - DEVICE_TYPE: zha_p.DeviceType.THERMOSTAT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - Thermostat.cluster_id, - UserInterface.cluster_id, - TemperatureMeasurement.cluster_id, - ElectricalMeasurement.cluster_id, - Diagnostic.cluster_id, - SINOPE_MANUFACTURER_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id, SINOPE_MANUFACTURER_CLUSTER_ID], - }, - # - 196: { - PROFILE_ID: 0xC25D, - DEVICE_TYPE: zha_p.DeviceType.THERMOSTAT, - INPUT_CLUSTERS: [PowerConfiguration.cluster_id], - OUTPUT_CLUSTERS: [], - }, - }, - } - - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - UserInterface.cluster_id, - TemperatureMeasurement.cluster_id, - Diagnostic.cluster_id, - SinopeTechnologiesElectricalMeasurementCluster, - SinopeTechnologiesThermostatCluster, - SinopeTechnologiesManufacturerCluster, - ], - OUTPUT_CLUSTERS: [ - Ota.cluster_id, - SINOPE_MANUFACTURER_CLUSTER_ID, - ], - }, - 196: {INPUT_CLUSTERS: [PowerConfiguration.cluster_id]}, - } - } - - -class SinopeTH1400ZB(CustomDevice): - """TH1400ZB thermostat.""" - - signature = { - # - MODELS_INFO: [(SINOPE, "TH1400ZB")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha_p.PROFILE_ID, - DEVICE_TYPE: zha_p.DeviceType.THERMOSTAT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - Thermostat.cluster_id, - UserInterface.cluster_id, - TemperatureMeasurement.cluster_id, - Metering.cluster_id, - Diagnostic.cluster_id, - SINOPE_MANUFACTURER_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Time.cluster_id, - Ota.cluster_id, - SINOPE_MANUFACTURER_CLUSTER_ID, - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - UserInterface.cluster_id, - TemperatureMeasurement.cluster_id, - Metering.cluster_id, - Diagnostic.cluster_id, - SinopeTechnologiesThermostatCluster, - SinopeTechnologiesManufacturerCluster, - ], - OUTPUT_CLUSTERS: [ - Time.cluster_id, - Ota.cluster_id, - SINOPE_MANUFACTURER_CLUSTER_ID, - ], - } - } - } - - -class SinopeTH1300ZB(CustomDevice): - """TH1300ZB thermostat.""" - - signature = { - # - MODELS_INFO: [(SINOPE, "TH1300ZB")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha_p.PROFILE_ID, - DEVICE_TYPE: zha_p.DeviceType.THERMOSTAT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - Thermostat.cluster_id, - UserInterface.cluster_id, - TemperatureMeasurement.cluster_id, - Metering.cluster_id, - ElectricalMeasurement.cluster_id, - Diagnostic.cluster_id, - SINOPE_MANUFACTURER_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Time.cluster_id, - Ota.cluster_id, - SINOPE_MANUFACTURER_CLUSTER_ID, - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - UserInterface.cluster_id, - TemperatureMeasurement.cluster_id, - Metering.cluster_id, - Diagnostic.cluster_id, - SinopeTechnologiesElectricalMeasurementCluster, - SinopeTechnologiesThermostatCluster, - SinopeTechnologiesManufacturerCluster, - ], - OUTPUT_CLUSTERS: [ - Time.cluster_id, - Ota.cluster_id, - SINOPE_MANUFACTURER_CLUSTER_ID, - ], - } - } - } - - -class SinopeLineThermostats(CustomDevice): - """TH1123ZB, TH1124ZB, TH1500ZB and OTH3600-GA-ZB thermostats.""" - - signature = { - # - MODELS_INFO: [ - (SINOPE, "TH1123ZB"), - (SINOPE, "TH1124ZB"), - (SINOPE, "TH1500ZB"), - (SINOPE, "OTH3600-GA-ZB"), - ], - ENDPOINTS: { - 1: { - PROFILE_ID: zha_p.PROFILE_ID, - DEVICE_TYPE: zha_p.DeviceType.THERMOSTAT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - Thermostat.cluster_id, - UserInterface.cluster_id, - TemperatureMeasurement.cluster_id, - Metering.cluster_id, - ElectricalMeasurement.cluster_id, - Diagnostic.cluster_id, - SINOPE_MANUFACTURER_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Time.cluster_id, - Ota.cluster_id, - SINOPE_MANUFACTURER_CLUSTER_ID, - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - UserInterface.cluster_id, - TemperatureMeasurement.cluster_id, - Metering.cluster_id, - Diagnostic.cluster_id, - SinopeTechnologiesElectricalMeasurementCluster, - SinopeTechnologiesThermostatCluster, - SinopeTechnologiesManufacturerCluster, - ], - OUTPUT_CLUSTERS: [ - Time.cluster_id, - Ota.cluster_id, - SINOPE_MANUFACTURER_CLUSTER_ID, - ], - } - } - } - - -class SinopeG2Thermostats(CustomDevice): - """TH1123ZB-G2 and TH1124ZB-G2 thermostats.""" - - signature = { - # - MODELS_INFO: [ - (SINOPE, "TH1123ZB-G2"), - (SINOPE, "TH1124ZB-G2"), - ], - ENDPOINTS: { - 1: { - PROFILE_ID: zha_p.PROFILE_ID, - DEVICE_TYPE: zha_p.DeviceType.THERMOSTAT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - Thermostat.cluster_id, - UserInterface.cluster_id, - TemperatureMeasurement.cluster_id, - Metering.cluster_id, - ElectricalMeasurement.cluster_id, - Diagnostic.cluster_id, - SINOPE_MANUFACTURER_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Time.cluster_id, - Ota.cluster_id, - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - UserInterface.cluster_id, - TemperatureMeasurement.cluster_id, - Metering.cluster_id, - Diagnostic.cluster_id, - SinopeTechnologiesElectricalMeasurementCluster, - SinopeTechnologiesThermostatCluster, - SinopeTechnologiesManufacturerCluster, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Time.cluster_id, - Ota.cluster_id, - ], - } - } - } - - -class SinopeHPThermostats(CustomDevice): - """HP6000ZB-GE, HP6000ZB-HS and HP6000ZB-MA thermostats.""" - - signature = { - # - MODELS_INFO: [ - (SINOPE, "HP6000ZB-GE"), - (SINOPE, "HP6000ZB-HS"), - (SINOPE, "HP6000ZB-MA"), - ], - ENDPOINTS: { - 1: { - PROFILE_ID: zha_p.PROFILE_ID, - DEVICE_TYPE: zha_p.DeviceType.MINI_SPLIT_AC, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - LevelControl.cluster_id, - Thermostat.cluster_id, - Fan.cluster_id, - UserInterface.cluster_id, - TemperatureMeasurement.cluster_id, - Diagnostic.cluster_id, - SINOPE_MANUFACTURER_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - }, - 2: { - PROFILE_ID: zha_p.PROFILE_ID, - DEVICE_TYPE: zha_p.DeviceType.MINI_SPLIT_AC, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - LevelControl.cluster_id, - Thermostat.cluster_id, - Fan.cluster_id, - UserInterface.cluster_id, - TemperatureMeasurement.cluster_id, - Diagnostic.cluster_id, - SINOPE_MANUFACTURER_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - }, - }, - } - - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - LevelControl.cluster_id, - Fan.cluster_id, - UserInterface.cluster_id, - TemperatureMeasurement.cluster_id, - Diagnostic.cluster_id, - SinopeTechnologiesThermostatCluster, - SinopeTechnologiesManufacturerCluster, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - }, - 2: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - LevelControl.cluster_id, - Fan.cluster_id, - UserInterface.cluster_id, - TemperatureMeasurement.cluster_id, - Diagnostic.cluster_id, - SinopeTechnologiesThermostatCluster, - SinopeTechnologiesManufacturerCluster, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - }, - } - } +( + QuirkBuilder(SINOPE, "TH1123ZB") + .applies_to(SINOPE, "TH1124ZB") + .applies_to(SINOPE, "TH1500ZB") + .applies_to(SINOPE, "TH1300ZB") + .applies_to(SINOPE, "OTH3600-GA-ZB") + .applies_to(SINOPE, "TH1123ZB-G2") + .applies_to(SINOPE, "TH1124ZB-G2") + .replaces(SinopeTechnologiesElectricalMeasurementCluster, endpoint_id=1) + .replaces(SinopeTechnologiesThermostatCluster, endpoint_id=1) + .replaces(SinopeTechnologiesManufacturerCluster, endpoint_id=1) + .add_to_registry() +) + + +( + QuirkBuilder(SINOPE, "TH1400ZB") + .replaces(SinopeTechnologiesThermostatCluster, endpoint_id=1) + .replaces(SinopeTechnologiesManufacturerCluster, endpoint_id=1) + .add_to_registry() +) + +( + QuirkBuilder(SINOPE, "HP6000ZB-GE") + .applies_to(SINOPE, "HP6000ZB-HS") + .applies_to(SINOPE, "HP6000ZB-MA") + .replaces(SinopeTechnologiesThermostatCluster, endpoint_id=1) + .replaces(SinopeTechnologiesManufacturerCluster, endpoint_id=1) + .replaces(SinopeTechnologiesThermostatCluster, endpoint_id=2) + .replaces(SinopeTechnologiesManufacturerCluster, endpoint_id=2) + .add_to_registry() +) diff --git a/zhaquirks/smartthings/moisturev4.py b/zhaquirks/smartthings/moisturev4.py index 37d9e2aa4e..27afc1dbf0 100755 --- a/zhaquirks/smartthings/moisturev4.py +++ b/zhaquirks/smartthings/moisturev4.py @@ -1,21 +1,11 @@ """Device handler for smartthings moistureV4 sensor.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomCluster, CustomDevice -from zigpy.zcl.clusters.general import Basic, BinaryInput, Identify, Ota, PollControl -from zigpy.zcl.clusters.measurement import TemperatureMeasurement +from zigpy.quirks import CustomCluster +from zigpy.quirks.v2 import QuirkBuilder from zigpy.zcl.clusters.security import IasZone from zhaquirks import PowerConfigurationCluster -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, - ZONE_TYPE, -) +from zhaquirks.const import ZONE_TYPE from zhaquirks.smartthings import SMART_THINGS @@ -25,46 +15,9 @@ class CustomIasZone(CustomCluster, IasZone): _CONSTANT_ATTRIBUTES = {ZONE_TYPE: IasZone.ZoneType.Water_Sensor} -class SmartThingsMoistureV4(CustomDevice): - """SmartThingsMoistureV4.""" - - signature = { - # - MODELS_INFO: [(SMART_THINGS, "moisturev4")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfigurationCluster.cluster_id, - Identify.cluster_id, - BinaryInput.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - IasZone.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfigurationCluster, - Identify.cluster_id, - BinaryInput.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - CustomIasZone, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - } - } +( + QuirkBuilder(SMART_THINGS, "moisturev4") + .replaces(PowerConfigurationCluster) + .replaces(CustomIasZone) + .add_to_registry() +) diff --git a/zhaquirks/smartthings/motion.py b/zhaquirks/smartthings/motion.py index 22a10bdd89..2a5feb640c 100755 --- a/zhaquirks/smartthings/motion.py +++ b/zhaquirks/smartthings/motion.py @@ -1,63 +1,18 @@ """Device handler for smartthings motionV4 sensors.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import Basic, BinaryInput, Identify, Ota, PollControl -from zigpy.zcl.clusters.measurement import TemperatureMeasurement -from zigpy.zcl.clusters.security import IasZone +from zigpy.quirks.v2 import QuirkBuilder +from zigpy.zcl.clusters.general import PowerConfiguration from zhaquirks import PowerConfigurationCluster -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.smartthings import SMART_THINGS - -class SmartThingsMotion(CustomDevice): - """SmartThingsMotionV4 or V5.""" - - signature = { - # - MODELS_INFO: [(SMART_THINGS, "motionv4"), (SMART_THINGS, "motionv5")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfigurationCluster.cluster_id, - Identify.cluster_id, - BinaryInput.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - IasZone.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfigurationCluster, - Identify.cluster_id, - BinaryInput.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - IasZone.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - } - } +( + QuirkBuilder(SMART_THINGS, "motionv4") + .applies_to(SMART_THINGS, "motionv5") + .replaces( + PowerConfigurationCluster, + cluster_id=PowerConfiguration.cluster_id, + endpoint_id=1, + ) + .add_to_registry() +) diff --git a/zhaquirks/smartthings/multi.py b/zhaquirks/smartthings/multi.py index ac987558c6..d68dbbef0c 100644 --- a/zhaquirks/smartthings/multi.py +++ b/zhaquirks/smartthings/multi.py @@ -1,65 +1,11 @@ """Smart Things multi purpose sensor quirk.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - Identify, - Ota, - PollControl, - PowerConfiguration, -) -from zigpy.zcl.clusters.measurement import TemperatureMeasurement -from zigpy.zcl.clusters.security import IasZone - -from zhaquirks import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - OUTPUT_CLUSTERS, - PROFILE_ID, -) -from zhaquirks.smartthings import SmartThingsAccelCluster +from zigpy.quirks.v2 import QuirkBuilder +from zhaquirks.smartthings import SMART_THINGS, SmartThingsAccelCluster -class SmartthingsMultiPurposeSensor(CustomDevice): - """Custom device representing a Smartthings Multi Purpose Sensor.""" - - signature = { - ENDPOINTS: { - # - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - IasZone.cluster_id, - SmartThingsAccelCluster.cluster_id, - ], - OUTPUT_CLUSTERS: [Identify.cluster_id, Ota.cluster_id], - } - } - } - - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - IasZone.cluster_id, - SmartThingsAccelCluster, - ], - OUTPUT_CLUSTERS: [Identify.cluster_id, Ota.cluster_id], - } - } - } +( + QuirkBuilder(SMART_THINGS, "multi") + .replaces(SmartThingsAccelCluster) + .add_to_registry() +) diff --git a/zhaquirks/smartthings/multiv4.py b/zhaquirks/smartthings/multiv4.py index 9541e489b7..1812b03d6b 100755 --- a/zhaquirks/smartthings/multiv4.py +++ b/zhaquirks/smartthings/multiv4.py @@ -1,66 +1,14 @@ """Device handler for smartthings multiV4 sensors.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import Basic, BinaryInput, Identify, Ota, PollControl -from zigpy.zcl.clusters.measurement import TemperatureMeasurement -from zigpy.zcl.clusters.security import IasZone +from zigpy.quirks.v2 import QuirkBuilder from zhaquirks import PowerConfigurationCluster from zhaquirks.centralite import CentraLiteAccelCluster -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.smartthings import SMART_THINGS - -class SmartThingsMultiV4(CustomDevice): - """SmartThingsMultiV4.""" - - signature = { - # - MODELS_INFO: [(SMART_THINGS, "multiv4")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfigurationCluster.cluster_id, - Identify.cluster_id, - BinaryInput.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - IasZone.cluster_id, - CentraLiteAccelCluster.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfigurationCluster, - Identify.cluster_id, - BinaryInput.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - IasZone.cluster_id, - CentraLiteAccelCluster, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - } - } +( + QuirkBuilder(SMART_THINGS, "multiv4") + .replaces(PowerConfigurationCluster) + .replaces(CentraLiteAccelCluster) + .add_to_registry() +) diff --git a/zhaquirks/smartthings/pgc313.py b/zhaquirks/smartthings/pgc313.py index 073c0dedd5..63be006469 100755 --- a/zhaquirks/smartthings/pgc313.py +++ b/zhaquirks/smartthings/pgc313.py @@ -1,23 +1,11 @@ """SmartThings SmartSense Multi Sensor quirk.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import Basic, Ota +from zigpy.quirks.v2 import QuirkBuilder from zigpy.zcl.clusters.security import IasZone -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, - ZONE_TYPE, -) +from zhaquirks.const import ZONE_TYPE from zhaquirks.smartthings import SMART_THINGS, SmartThingsIasZone -SMARTSENSE_MULTI_DEVICE_TYPE = 0x0139 # decimal = 313 - class IasZoneContactSwitchCluster(SmartThingsIasZone): """Custom IasZone cluster.""" @@ -25,36 +13,8 @@ class IasZoneContactSwitchCluster(SmartThingsIasZone): _CONSTANT_ATTRIBUTES = {ZONE_TYPE: IasZone.ZoneType.Contact_Switch} -class SmartthingsSmartSenseMultiSensor(CustomDevice): - """Multipurpose sensor.""" - - signature = { - # - MODELS_INFO: [(SMART_THINGS, "PGC313")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: SMARTSENSE_MULTI_DEVICE_TYPE, - INPUT_CLUSTERS: [Basic.cluster_id], - OUTPUT_CLUSTERS: [Ota.cluster_id], - }, - # - 2: { - PROFILE_ID: 0xFC01, # decimal = 64513 - DEVICE_TYPE: SMARTSENSE_MULTI_DEVICE_TYPE, - INPUT_CLUSTERS: [], - OUTPUT_CLUSTERS: [], - }, - }, - } - - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [Basic.cluster_id, IasZoneContactSwitchCluster], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - } - } +( + QuirkBuilder(SMART_THINGS, "PGC313") + .adds(IasZoneContactSwitchCluster) + .add_to_registry() +) diff --git a/zhaquirks/smartthings/pgc314.py b/zhaquirks/smartthings/pgc314.py index dd3963c3b6..6a21f58412 100644 --- a/zhaquirks/smartthings/pgc314.py +++ b/zhaquirks/smartthings/pgc314.py @@ -1,21 +1,9 @@ """SmartThings SmartSense Motion quirk.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import Basic, Ota +from zigpy.quirks.v2 import QuirkBuilder -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.smartthings import SMART_THINGS, SmartThingsIasZone -SMARTSENSE_MOTION_DEVICE_TYPE = 0x013A # decimal = 314 - class IasZoneMotionCluster(SmartThingsIasZone): """Custom IasZone cluster.""" @@ -25,36 +13,4 @@ class IasZoneMotionCluster(SmartThingsIasZone): _CONSTANT_ATTRIBUTES = {ZONE_TYPE: MOTION_TYPE} -class SmartthingsSmartSenseMotionSensor(CustomDevice): - """SmartSense Motion Sensor.""" - - signature = { - # - MODELS_INFO: [(SMART_THINGS, "PGC314")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: SMARTSENSE_MOTION_DEVICE_TYPE, - INPUT_CLUSTERS: [Basic.cluster_id], - OUTPUT_CLUSTERS: [Ota.cluster_id], - }, - # - 2: { - PROFILE_ID: 0xFC01, # decimal = 64513 - DEVICE_TYPE: SMARTSENSE_MOTION_DEVICE_TYPE, - INPUT_CLUSTERS: [], - OUTPUT_CLUSTERS: [], - }, - }, - } - - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [Basic.cluster_id, IasZoneMotionCluster], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - } - } +(QuirkBuilder(SMART_THINGS, "PGC314").adds(IasZoneMotionCluster).add_to_registry()) diff --git a/zhaquirks/smartthings/tag_v4.py b/zhaquirks/smartthings/tag_v4.py index c4028192d0..18f448ee6b 100755 --- a/zhaquirks/smartthings/tag_v4.py +++ b/zhaquirks/smartthings/tag_v4.py @@ -1,17 +1,11 @@ """Device handler for smartthings tagV4 sensors.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import Basic, BinaryInput, Identify, Ota, PollControl +from typing import Any + +from zigpy.quirks.v2 import CustomDeviceV2, QuirkBuilder +from zigpy.zcl.clusters.general import BinaryInput from zhaquirks import Bus, LocalDataCluster, PowerConfigurationCluster -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - OUTPUT_CLUSTERS, - PROFILE_ID, -) ARRIVAL_SENSOR_DEVICE_TYPE = 0x8000 @@ -61,47 +55,20 @@ def update_tracking(self, attrid, value): self._update_attribute(0, 1) -class SmartThingsTagV4(CustomDevice): +class SmartThingsTagV4(CustomDeviceV2): """Custom device representing smartthings tagV4 sensors.""" - def __init__(self, *args, **kwargs): + def __init__(self, *args: Any, **kwargs: Any) -> None: """Init.""" self.tracking_bus = Bus() super().__init__(*args, **kwargs) - signature = { - # - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.SIMPLE_SENSOR, - INPUT_CLUSTERS: [ - Basic.cluster_id, - FastPollingPowerConfigurationCluster.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - TrackingCluster.cluster_id, - ], - OUTPUT_CLUSTERS: [Identify.cluster_id, Ota.cluster_id], - } - } - } - - replacement = { - ENDPOINTS: { - 1: { - DEVICE_TYPE: ARRIVAL_SENSOR_DEVICE_TYPE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - FastPollingPowerConfigurationCluster, - Identify.cluster_id, - PollControl.cluster_id, - TrackingCluster, - ], - OUTPUT_CLUSTERS: [Identify.cluster_id, Ota.cluster_id], - } - } - } + +( + QuirkBuilder("SmartThings", "tagv4") + .device_class(SmartThingsTagV4) + .replaces_endpoint(1, device_type=ARRIVAL_SENSOR_DEVICE_TYPE) # was SIMPLE_SENSOR + .replaces(FastPollingPowerConfigurationCluster, endpoint_id=1) + .replaces(TrackingCluster, endpoint_id=1) + .add_to_registry() +) diff --git a/zhaquirks/smartwings/wm25lz.py b/zhaquirks/smartwings/wm25lz.py index ec26899dba..af50ae84f2 100644 --- a/zhaquirks/smartwings/wm25lz.py +++ b/zhaquirks/smartwings/wm25lz.py @@ -5,29 +5,13 @@ from collections.abc import Coroutine from typing import Any -from zigpy.profiles import zha -from zigpy.quirks import CustomCluster, CustomDevice +from zigpy.quirks import CustomCluster +from zigpy.quirks.v2 import QuirkBuilder import zigpy.types as t from zigpy.zcl import foundation from zigpy.zcl.clusters.closures import WindowCovering -from zigpy.zcl.clusters.general import ( - Basic, - Groups, - Identify, - Ota, - PowerConfiguration, - Scenes, -) from zhaquirks import DoublingPowerConfigurationCluster -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) class InvertedWindowCoveringCluster(CustomCluster, WindowCovering): @@ -62,48 +46,9 @@ async def command( ) -class WM25LBlinds(CustomDevice): - """Custom device representing Smartwings WM25LZ blinds.""" - - signature = { - # - MODELS_INFO: [ - ("Smartwings", "WM25/L-Z"), - ], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.WINDOW_COVERING_DEVICE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - WindowCovering.cluster_id, - ], - OUTPUT_CLUSTERS: [Identify.cluster_id, Ota.cluster_id], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.WINDOW_COVERING_DEVICE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - DoublingPowerConfigurationCluster, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - InvertedWindowCoveringCluster, - ], - OUTPUT_CLUSTERS: [Identify.cluster_id, Ota.cluster_id], - } - } - } +( + QuirkBuilder("Smartwings", "WM25/L-Z") + .replaces(DoublingPowerConfigurationCluster, endpoint_id=1) + .replaces(InvertedWindowCoveringCluster, endpoint_id=1) + .add_to_registry() +) diff --git a/zhaquirks/sonoff/snzb06p.py b/zhaquirks/sonoff/snzb06p.py index e268d4770b..0427f2f3ba 100644 --- a/zhaquirks/sonoff/snzb06p.py +++ b/zhaquirks/sonoff/snzb06p.py @@ -1,21 +1,10 @@ """Sonoff SNZB-06 - Zigbee presence sensor.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomCluster, CustomDevice +from zigpy.quirks import CustomCluster +from zigpy.quirks.v2 import QuirkBuilder import zigpy.types as t -from zigpy.zcl.clusters.general import Basic, Identify, Ota -from zigpy.zcl.clusters.measurement import OccupancySensing from zigpy.zcl.clusters.security import IasZone -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) - SONOFF_CLUSTER_FC11_ID = 0xFC11 SONOFF_CLUSTER_FC57_ID = 0xFC57 ATTR_SONOFF_ILLUMINATION_STATUS = 0x2001 @@ -38,52 +27,9 @@ class SonoffFC11Cluster(CustomCluster): } -class SonoffPresenceSenorSNZB06P(CustomDevice): - """Sonoff human presence senor - model SNZB-06P.""" - - signature = { - # - MODELS_INFO: [ - ("SONOFF", "SNZB-06P"), - ], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.OCCUPANCY_SENSOR, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - OccupancySensing.cluster_id, - IasZone.cluster_id, - SONOFF_CLUSTER_FC11_ID, - SONOFF_CLUSTER_FC57_ID, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Ota.cluster_id, - ], - }, - }, - } - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.OCCUPANCY_SENSOR, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - OccupancySensing.cluster_id, - SonoffFC11Cluster, - SONOFF_CLUSTER_FC57_ID, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Ota.cluster_id, - ], - }, - }, - } +( + QuirkBuilder("SONOFF", "SNZB-06P") + .replaces(SonoffFC11Cluster, cluster_id=SONOFF_CLUSTER_FC11_ID, endpoint_id=1) + .removes(IasZone.cluster_id, endpoint_id=1) + .add_to_registry() +) diff --git a/zhaquirks/sourcingandcreation/smart_button.py b/zhaquirks/sourcingandcreation/smart_button.py index 0cdd44294a..a2080bcc67 100644 --- a/zhaquirks/sourcingandcreation/smart_button.py +++ b/zhaquirks/sourcingandcreation/smart_button.py @@ -1,19 +1,6 @@ """Device handler for Sourcing & Creation EB-SB-1B (Boulanger Essentielb 8009289) smart button.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - Groups, - Identify, - LevelControl, - OnOff, - Ota, - PowerConfiguration, -) -from zigpy.zcl.clusters.homeautomation import Diagnostic -from zigpy.zcl.clusters.lighting import Color -from zigpy.zcl.clusters.lightlink import LightLink +from zigpy.quirks.v2 import QuirkBuilder from zhaquirks.const import ( CLUSTER_ID, @@ -21,99 +8,38 @@ COMMAND_STEP, COMMAND_STEP_COLOR_TEMP, COMMAND_STOP, - DEVICE_TYPE, DOUBLE_PRESS, ENDPOINT_ID, - ENDPOINTS, - INPUT_CLUSTERS, LONG_PRESS, LONG_RELEASE, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, SHORT_PRESS, TURN_ON, ) - -class SourcingAndCreationSmartButton(CustomDevice): - """Custom device representing Sourcing & Creation smart button.""" - - signature = { - # - MODELS_INFO: [("Sourcing & Creation", "EB-SB-1B")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, # 260 - DEVICE_TYPE: zha.DeviceType.COLOR_CONTROLLER, # 2048 - INPUT_CLUSTERS: [ - Basic.cluster_id, # 0 - PowerConfiguration.cluster_id, # 1 - Identify.cluster_id, # 3 - Diagnostic.cluster_id, # 2821 - LightLink.cluster_id, # 4096 - 0xFD01, # 64769 - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, # 3 - Groups.cluster_id, # 4 - OnOff.cluster_id, # 6 - LevelControl.cluster_id, # 8 - Ota.cluster_id, # 25 - Color.cluster_id, # 768 - LightLink.cluster_id, # 4096 - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.COLOR_CONTROLLER, - INPUT_CLUSTERS: [ - Basic.cluster_id, # 0 - PowerConfiguration.cluster_id, # 1 - Identify.cluster_id, # 3 - Diagnostic.cluster_id, # 2821 - LightLink.cluster_id, # 4096 - 0xFD01, # 64769 - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, # 3 - Groups.cluster_id, # 4 - OnOff.cluster_id, # 6 - LevelControl.cluster_id, # 8 - Ota.cluster_id, # 25 - Color.cluster_id, # 768 - LightLink.cluster_id, # 4096 - ], - } - }, - } - - device_automation_triggers = { - (SHORT_PRESS, TURN_ON): { - CLUSTER_ID: 6, # OnOff.cluster_id - ENDPOINT_ID: 1, - }, - (LONG_PRESS, TURN_ON): { - COMMAND: COMMAND_STEP, - CLUSTER_ID: 8, # LevelControl.cluster_id - ENDPOINT_ID: 1, - }, - (LONG_RELEASE, TURN_ON): { - COMMAND: COMMAND_STOP, - CLUSTER_ID: 8, # LevelControl.cluster_id - ENDPOINT_ID: 1, - }, - (DOUBLE_PRESS, TURN_ON): { - COMMAND: COMMAND_STEP_COLOR_TEMP, - CLUSTER_ID: 768, # Color.cluster_id - ENDPOINT_ID: 1, - }, - } +( + QuirkBuilder("Sourcing & Creation", "EB-SB-1B") + .device_automation_triggers( + { + (SHORT_PRESS, TURN_ON): { + CLUSTER_ID: 6, # OnOff.cluster_id + ENDPOINT_ID: 1, + }, + (LONG_PRESS, TURN_ON): { + COMMAND: COMMAND_STEP, + CLUSTER_ID: 8, # LevelControl.cluster_id + ENDPOINT_ID: 1, + }, + (LONG_RELEASE, TURN_ON): { + COMMAND: COMMAND_STOP, + CLUSTER_ID: 8, # LevelControl.cluster_id + ENDPOINT_ID: 1, + }, + (DOUBLE_PRESS, TURN_ON): { + COMMAND: COMMAND_STEP_COLOR_TEMP, + CLUSTER_ID: 768, # Color.cluster_id + ENDPOINT_ID: 1, + }, + } + ) + .add_to_registry() +) diff --git a/zhaquirks/terncy/cl001.py b/zhaquirks/terncy/cl001.py index 09ebec3ca7..d38ac8b2b5 100644 --- a/zhaquirks/terncy/cl001.py +++ b/zhaquirks/terncy/cl001.py @@ -1,27 +1,8 @@ """Quirk for Xiaoyan CL001 ceiling light.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomCluster, CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - Groups, - Identify, - LevelControl, - OnOff, - Ota, - Scenes, -) +from zigpy.quirks import CustomCluster +from zigpy.quirks.v2 import QuirkBuilder from zigpy.zcl.clusters.lighting import Color -from zigpy.zcl.clusters.lightlink import LightLink - -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) class ColorClusterTerncy(CustomCluster, Color): @@ -34,56 +15,4 @@ class ColorClusterTerncy(CustomCluster, Color): } -class TerncyLightCCT(CustomDevice): - """Terncy Light CCT device.""" - - signature = { - MODELS_INFO: [("Xiaoyan", "CL001")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.COLOR_TEMPERATURE_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - Color.cluster_id, - LightLink.cluster_id, - 0xFCCC, - 0xFCCD, - 0xFCCE, - ], - OUTPUT_CLUSTERS: [ - Ota.cluster_id, - ], - }, - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.COLOR_TEMPERATURE_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - ColorClusterTerncy, - LightLink.cluster_id, - 0xFCCC, - 0xFCCD, - 0xFCCE, - ], - OUTPUT_CLUSTERS: [ - Ota.cluster_id, - ], - }, - }, - } +(QuirkBuilder("Xiaoyan", "CL001").replaces(ColorClusterTerncy).add_to_registry()) diff --git a/zhaquirks/terncy/pp01.py b/zhaquirks/terncy/pp01.py index 22e4193974..4fd56c4cdd 100755 --- a/zhaquirks/terncy/pp01.py +++ b/zhaquirks/terncy/pp01.py @@ -1,29 +1,9 @@ """Device handler for Terncy awareness switch.""" from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - Identify, - Ota, - PollControl, - PowerConfiguration, -) -from zigpy.zcl.clusters.measurement import ( - IlluminanceMeasurement, - OccupancySensing, - TemperatureMeasurement, -) +from zigpy.quirks.v2 import CustomDeviceV2, QuirkBuilder from zhaquirks import Bus, DoublingPowerConfigurationCluster -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.terncy import ( BUTTON_TRIGGERS, IlluminanceMeasurementCluster, @@ -37,7 +17,7 @@ TERNCY_AWARENESS_DEVICE_TYPE = 0x01F0 -class TerncyAwarenessSwitch(CustomDevice): +class TerncyAwarenessSwitchV2(CustomDeviceV2): """Terncy awareness switch.""" def __init__(self, *args, **kwargs): @@ -47,56 +27,23 @@ def __init__(self, *args, **kwargs): self.occupancy_bus = Bus() super().__init__(*args, **kwargs) - signature = { - # - MODELS_INFO: [("Xiaoyan", "TERNCY-PP01"), (None, "TERNCY-PP01")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: TERNCY_AWARENESS_DEVICE_TYPE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - IlluminanceMeasurement.cluster_id, - TemperatureMeasurement.cluster_id, - OccupancySensing.cluster_id, - TerncyRawCluster.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - }, - } - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: TERNCY_AWARENESS_DEVICE_TYPE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - DoublingPowerConfigurationCluster, - Identify.cluster_id, - PollControl.cluster_id, - IlluminanceMeasurementCluster, - TemperatureMeasurementCluster, - MotionClusterLeft, - OccupancyCluster, - TerncyRawCluster, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - }, - 2: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: TERNCY_AWARENESS_DEVICE_TYPE, - INPUT_CLUSTERS: [MotionClusterRight], - OUTPUT_CLUSTERS: [], - }, - } - } - - device_automation_triggers = BUTTON_TRIGGERS +( + QuirkBuilder("Xiaoyan", "TERNCY-PP01") + .applies_to("Terncy", "TERNCY-PP01") + .device_class(TerncyAwarenessSwitchV2) + .replaces(DoublingPowerConfigurationCluster, endpoint_id=1) + .replaces(IlluminanceMeasurementCluster, endpoint_id=1) + .replaces(TemperatureMeasurementCluster, endpoint_id=1) + .replaces(OccupancyCluster, endpoint_id=1) + .replaces(TerncyRawCluster, endpoint_id=1) + .adds(MotionClusterLeft, endpoint_id=1) + .adds_endpoint( + endpoint_id=2, + profile_id=zha.PROFILE_ID, + device_type=TERNCY_AWARENESS_DEVICE_TYPE, + ) + .adds(MotionClusterRight, endpoint_id=2) + .device_automation_triggers(BUTTON_TRIGGERS) + .add_to_registry() +) diff --git a/zhaquirks/terncy/sd01.py b/zhaquirks/terncy/sd01.py index 2a1fc67731..a315702f44 100644 --- a/zhaquirks/terncy/sd01.py +++ b/zhaquirks/terncy/sd01.py @@ -1,66 +1,14 @@ """Device handler for Terncy knob smart dimmer.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - Identify, - Ota, - PollControl, - PowerConfiguration, -) +from zigpy.quirks.v2 import QuirkBuilder from zhaquirks import DoublingPowerConfigurationCluster -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, +from zhaquirks.terncy import BUTTON_TRIGGERS, KNOB_TRIGGERS + +( + QuirkBuilder("Xiaoyan", "TERNCY-SD01") + .applies_to(None, "TERNCY-SD01") + .replaces(DoublingPowerConfigurationCluster) + .device_automation_triggers({**BUTTON_TRIGGERS, **KNOB_TRIGGERS}) + .add_to_registry() ) -from zhaquirks.terncy import BUTTON_TRIGGERS, KNOB_TRIGGERS, TerncyRawCluster - -TERNCY_KNOB_DEVICE_TYPE = 0x01F2 - - -class TerncyKnobSmartDimmer(CustomDevice): - """Terncy knob smart dimmer.""" - - signature = { - MODELS_INFO: [("Xiaoyan", "TERNCY-SD01"), (None, "TERNCY-SD01")], - ENDPOINTS: { - # - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: TERNCY_KNOB_DEVICE_TYPE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - TerncyRawCluster.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - DoublingPowerConfigurationCluster, - Identify.cluster_id, - PollControl.cluster_id, - TerncyRawCluster, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - } - } - - device_automation_triggers = {**BUTTON_TRIGGERS, **KNOB_TRIGGERS} diff --git a/zhaquirks/texasinstruments/router.py b/zhaquirks/texasinstruments/router.py index 7f1bfe0291..79740705ea 100644 --- a/zhaquirks/texasinstruments/router.py +++ b/zhaquirks/texasinstruments/router.py @@ -2,21 +2,13 @@ from typing import Final -from zigpy.profiles import zgp, zha -from zigpy.quirks import CustomCluster, CustomDevice +from zigpy.quirks import CustomCluster +from zigpy.quirks.v2 import QuirkBuilder import zigpy.types as t -from zigpy.zcl.clusters.general import Basic, GreenPowerProxy, Identify +from zigpy.zcl import ClusterType +from zigpy.zcl.clusters.general import Basic from zigpy.zcl.foundation import ZCLAttributeDef -from zhaquirks import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) - class BasicCluster(CustomCluster, Basic): """Texas Instruments Basic cluster.""" @@ -29,49 +21,9 @@ class AttributeDefs(Basic.AttributeDefs): ) -class TiRouter(CustomDevice): - """Texas Instruments Z-Stack router device.""" - - signature = { - MODELS_INFO: [("TexasInstruments", "ti.router")], - ENDPOINTS: { - 8: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: 0x00FF, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Basic.cluster_id, - ], - }, - 242: { - PROFILE_ID: zgp.PROFILE_ID, - DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC, - INPUT_CLUSTERS: [], - OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id], - }, - }, - } - replacement = { - ENDPOINTS: { - 8: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: 0x00FF, - INPUT_CLUSTERS: [ - BasicCluster, - Identify.cluster_id, - ], - OUTPUT_CLUSTERS: [ - BasicCluster, - ], - }, - 242: { - PROFILE_ID: zgp.PROFILE_ID, - DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC, - INPUT_CLUSTERS: [], - OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id], - }, - }, - } +( + QuirkBuilder("TexasInstruments", "ti.router") + .replaces(BasicCluster, endpoint_id=8) + .replaces(BasicCluster, cluster_type=ClusterType.Client, endpoint_id=8) + .add_to_registry() +) diff --git a/zhaquirks/thirdreality/button.py b/zhaquirks/thirdreality/button.py index e5c54f77c1..0791be9e0e 100644 --- a/zhaquirks/thirdreality/button.py +++ b/zhaquirks/thirdreality/button.py @@ -1,8 +1,8 @@ """Third Reality button devices.""" from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import Basic, LevelControl, MultistateInput, OnOff, Ota +from zigpy.quirks.v2 import QuirkBuilder +from zigpy.zcl.clusters.general import MultistateInput from zhaquirks import CustomCluster, PowerConfigurationCluster from zhaquirks.const import ( @@ -11,17 +11,10 @@ COMMAND_HOLD, COMMAND_RELEASE, COMMAND_SINGLE, - DEVICE_TYPE, DOUBLE_PRESS, - ENDPOINTS, - INPUT_CLUSTERS, LONG_PRESS, LONG_RELEASE, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, SHORT_PRESS, - SKIP_CONFIGURATION, VALUE, ZHA_SEND_EVENT, ) @@ -63,50 +56,19 @@ def _update_attribute(self, attrid, value): super()._update_attribute(0, action) -class Button(CustomDevice): - """thirdreality button device - alternate version.""" - - signature = { - MODELS_INFO: [(THIRD_REALITY, "3RSB22BZ")], - ENDPOINTS: { - 1: { - PROFILE_ID: 0x0104, - DEVICE_TYPE: 0x0006, - INPUT_CLUSTERS: [ - Basic.cluster_id, - MultistateInput.cluster_id, - CustomPowerConfigurationCluster.cluster_id, - ], - OUTPUT_CLUSTERS: [ - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - ], - } - }, - } - replacement = { - SKIP_CONFIGURATION: True, - ENDPOINTS: { - 1: { - DEVICE_TYPE: zha.DeviceType.REMOTE_CONTROL, - INPUT_CLUSTERS: [ - Basic.cluster_id, - CustomPowerConfigurationCluster, - MultistateInputCluster, - ], - OUTPUT_CLUSTERS: [ - OnOff.cluster_id, - LevelControl.cluster_id, - Ota.cluster_id, - ], - } - }, - } - - device_automation_triggers = { - (DOUBLE_PRESS, DOUBLE_PRESS): {COMMAND: COMMAND_DOUBLE}, - (SHORT_PRESS, SHORT_PRESS): {COMMAND: COMMAND_SINGLE}, - (LONG_PRESS, LONG_PRESS): {COMMAND: COMMAND_HOLD}, - (LONG_RELEASE, LONG_RELEASE): {COMMAND: COMMAND_RELEASE}, - } +( + QuirkBuilder(THIRD_REALITY, "3RSB22BZ") + .skip_configuration() + .replaces_endpoint(endpoint_id=1, device_type=zha.DeviceType.REMOTE_CONTROL) + .replaces(CustomPowerConfigurationCluster, endpoint_id=1) + .replaces(MultistateInputCluster, endpoint_id=1) + .device_automation_triggers( + { + (DOUBLE_PRESS, DOUBLE_PRESS): {COMMAND: COMMAND_DOUBLE}, + (SHORT_PRESS, SHORT_PRESS): {COMMAND: COMMAND_SINGLE}, + (LONG_PRESS, LONG_PRESS): {COMMAND: COMMAND_HOLD}, + (LONG_RELEASE, LONG_RELEASE): {COMMAND: COMMAND_RELEASE}, + } + ) + .add_to_registry() +) diff --git a/zhaquirks/thirdreality/night_light.py b/zhaquirks/thirdreality/night_light.py index 36224899f0..cc6790775f 100644 --- a/zhaquirks/thirdreality/night_light.py +++ b/zhaquirks/thirdreality/night_light.py @@ -1,33 +1,12 @@ """Third Reality night light zigbee devices.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomCluster, CustomDevice +from zigpy.quirks import CustomCluster +from zigpy.quirks.v2 import QuirkBuilder import zigpy.types as t -from zigpy.zcl.clusters.general import ( - Basic, - Groups, - Identify, - LevelControl, - MultistateInput, - OnOff, - Ota, - Scenes, -) -from zigpy.zcl.clusters.lighting import Color -from zigpy.zcl.clusters.lightlink import LightLink -from zigpy.zcl.clusters.measurement import IlluminanceMeasurement from zigpy.zcl.clusters.security import IasZone from zigpy.zcl.foundation import BaseAttributeDefs, ZCLAttributeDef from zhaquirks import LocalDataCluster -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.thirdreality import THIRD_REALITY THIRD_REALITY_CLUSTER_ID = 0xFC00 @@ -74,55 +53,9 @@ class LocalIasZone(LocalDataCluster, IasZone): } -class Nightlight(CustomDevice): - """Custom device for 3RSNL02043Z.""" - - signature = { - MODELS_INFO: [(THIRD_REALITY, "3RSNL02043Z")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.COLOR_DIMMABLE_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - MultistateInput.cluster_id, - Color.cluster_id, - IlluminanceMeasurement.cluster_id, - LightLink.cluster_id, - ThirdRealitySpecificCluster.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Ota.cluster_id, - ], - } - }, - } - replacement = { - ENDPOINTS: { - 1: { - DEVICE_TYPE: zha.DeviceType.COLOR_DIMMABLE_LIGHT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - LevelControl.cluster_id, - MultistateInput.cluster_id, - Color.cluster_id, - IlluminanceMeasurement.cluster_id, - LightLink.cluster_id, - LocalIasZone, - ThirdRealitySpecificCluster, - ], - OUTPUT_CLUSTERS: [ - Ota.cluster_id, - ], - } - } - } +( + QuirkBuilder(THIRD_REALITY, "3RSNL02043Z") + .replaces(ThirdRealitySpecificCluster, endpoint_id=1) + .adds(LocalIasZone, endpoint_id=1) + .add_to_registry() +) diff --git a/zhaquirks/thirdreality/switch.py b/zhaquirks/thirdreality/switch.py index a56a1c9e91..740729b517 100755 --- a/zhaquirks/thirdreality/switch.py +++ b/zhaquirks/thirdreality/switch.py @@ -1,19 +1,8 @@ """Third Reality switch devices.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import Basic, Groups, Identify, OnOff, Ota, Scenes -from zigpy.zcl.clusters.homeautomation import Diagnostic +from zigpy.quirks.v2 import QuirkBuilder from zhaquirks import PowerConfigurationCluster -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.thirdreality import THIRD_REALITY @@ -24,95 +13,9 @@ class CustomPowerConfigurationCluster(PowerConfigurationCluster): MAX_VOLTS = 3.0 -class Switch(CustomDevice): - """3RSS008Z device.""" - - signature = { - # - MODELS_INFO: [(THIRD_REALITY, "3RSS007Z"), (THIRD_REALITY, "3RSS008Z")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.ON_OFF_OUTPUT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - Ota.cluster_id, - CustomPowerConfigurationCluster.cluster_id, - ], - OUTPUT_CLUSTERS: [CustomPowerConfigurationCluster.cluster_id], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.ON_OFF_OUTPUT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - Ota.cluster_id, - CustomPowerConfigurationCluster, - ], - OUTPUT_CLUSTERS: [CustomPowerConfigurationCluster.cluster_id], - } - } - } - - -class SwitchPlus(Switch): - """RealitySwitch Plus (3RSS008Z) device.""" - - signature = { - # - MODELS_INFO: [(THIRD_REALITY, "3RSS008Z")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.ON_OFF_OUTPUT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - Diagnostic.cluster_id, - CustomPowerConfigurationCluster.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.ON_OFF_OUTPUT, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - OnOff.cluster_id, - Diagnostic.cluster_id, - CustomPowerConfigurationCluster, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - } - } +( + QuirkBuilder(THIRD_REALITY, "3RSS007Z") + .applies_to(THIRD_REALITY, "3RSS008Z") + .replaces(CustomPowerConfigurationCluster, endpoint_id=1) + .add_to_registry() +) diff --git a/zhaquirks/thirdreality/vibrate.py b/zhaquirks/thirdreality/vibrate.py index ee77088d2c..c8c8cf6bef 100644 --- a/zhaquirks/thirdreality/vibrate.py +++ b/zhaquirks/thirdreality/vibrate.py @@ -2,22 +2,11 @@ from typing import Final -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice +from zigpy.quirks.v2 import QuirkBuilder import zigpy.types as t -from zigpy.zcl.clusters.general import Basic, Ota, PowerConfiguration -from zigpy.zcl.clusters.security import IasZone from zigpy.zcl.foundation import BaseAttributeDefs, ZCLAttributeDef from zhaquirks import CustomCluster -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.thirdreality import THIRD_REALITY MANUFACTURER_SPECIFIC_CLUSTER_ID = 0xFFF1 @@ -42,41 +31,8 @@ class AttributeDefs(BaseAttributeDefs): ) -class Vibrate(CustomDevice): - """ThirdReality vibrate device.""" - - signature = { - MODELS_INFO: [(THIRD_REALITY, "3RVS01031Z")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - IasZone.cluster_id, - ThirdRealityAccelCluster.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Ota.cluster_id, - ], - } - }, - } - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - IasZone.cluster_id, - ThirdRealityAccelCluster, - ], - OUTPUT_CLUSTERS: [ - Ota.cluster_id, - ], - } - }, - } +( + QuirkBuilder(THIRD_REALITY, "3RVS01031Z") + .replaces(ThirdRealityAccelCluster, endpoint_id=1) + .add_to_registry() +) diff --git a/zhaquirks/trust/zpir8000.py b/zhaquirks/trust/zpir8000.py index 58f2ae00e4..fda4685150 100644 --- a/zhaquirks/trust/zpir8000.py +++ b/zhaquirks/trust/zpir8000.py @@ -1,58 +1,7 @@ """Device handler for Trust ZPIR-8000 sensors.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import Basic, Identify, PowerConfiguration -from zigpy.zcl.clusters.security import IasZone +from zigpy.quirks.v2 import QuirkBuilder -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.trust import MotionCluster -MANUFACTURER_SPECIFIC_CLUSTER_ID = 0xFFFF - - -class ZPIR8000(CustomDevice): - """Trust ZPIR-8000.""" - - signature = { - # - MODELS_INFO: [("ADUROLIGHT", "VMS_ADUROLIGHT")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Identify.cluster_id, - IasZone.cluster_id, - MANUFACTURER_SPECIFIC_CLUSTER_ID, - PowerConfiguration.cluster_id, - ], - OUTPUT_CLUSTERS: [], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - MotionCluster, - MANUFACTURER_SPECIFIC_CLUSTER_ID, - ] - } - } - } +(QuirkBuilder("ADUROLIGHT", "VMS_ADUROLIGHT").replaces(MotionCluster).add_to_registry()) diff --git a/zhaquirks/universalelectronics/contact_sensor.py b/zhaquirks/universalelectronics/contact_sensor.py index c1f5574ae3..e4f13366ad 100644 --- a/zhaquirks/universalelectronics/contact_sensor.py +++ b/zhaquirks/universalelectronics/contact_sensor.py @@ -1,21 +1,8 @@ """XHS2-UE Door/Window Sensor.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import Basic, Identify, Ota, PollControl -from zigpy.zcl.clusters.homeautomation import Diagnostic -from zigpy.zcl.clusters.measurement import TemperatureMeasurement -from zigpy.zcl.clusters.security import IasZone +from zigpy.quirks.v2 import QuirkBuilder from zhaquirks import PowerConfigurationCluster -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) class CustomPowerConfigurationCluster(PowerConfigurationCluster): @@ -25,47 +12,8 @@ class CustomPowerConfigurationCluster(PowerConfigurationCluster): MAX_VOLTS = 3.0 -class ContactSensor(CustomDevice): - """XHS2-UE Door/Window Sensor.""" - - signature = { - # - MODELS_INFO: [("Universal Electronics Inc", "URC4460BC0-X-R")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - CustomPowerConfigurationCluster.cluster_id, - Identify.cluster_id, - TemperatureMeasurement.cluster_id, - IasZone.cluster_id, - PollControl.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - INPUT_CLUSTERS: [ - Basic.cluster_id, - CustomPowerConfigurationCluster, - Identify.cluster_id, - TemperatureMeasurement.cluster_id, - IasZone.cluster_id, - PollControl.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - } - } +( + QuirkBuilder("Universal Electronics Inc", "URC4460BC0-X-R") + .replaces(CustomPowerConfigurationCluster, endpoint_id=1) + .add_to_registry() +) diff --git a/zhaquirks/visonic/mct340.py b/zhaquirks/visonic/mct340.py index 3814e2cb2e..be123d1234 100644 --- a/zhaquirks/visonic/mct340.py +++ b/zhaquirks/visonic/mct340.py @@ -1,21 +1,8 @@ """Visonic MCT340 device.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import Basic, Identify, Ota, PollControl -from zigpy.zcl.clusters.homeautomation import Diagnostic -from zigpy.zcl.clusters.measurement import TemperatureMeasurement -from zigpy.zcl.clusters.security import IasZone +from zigpy.quirks.v2 import QuirkBuilder from zhaquirks import PowerConfigurationCluster -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) OSRAM_DEVICE = 0x0810 # 2064 base 10 OSRAM_CLUSTER = 0xFD00 # 64768 base 10 @@ -28,47 +15,9 @@ class CustomPowerConfigurationCluster(PowerConfigurationCluster): MAX_VOLTS = 3.0 -class MCT340(CustomDevice): - """Visonic MCT340 device.""" - - signature = { - # - MODELS_INFO: [("Visonic", "MCT-340 E"), ("Visonic", "MCT-340 SMA")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - CustomPowerConfigurationCluster.cluster_id, - Identify.cluster_id, - TemperatureMeasurement.cluster_id, - IasZone.cluster_id, - PollControl.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - INPUT_CLUSTERS: [ - Basic.cluster_id, - CustomPowerConfigurationCluster, - Identify.cluster_id, - TemperatureMeasurement.cluster_id, - IasZone.cluster_id, - PollControl.cluster_id, - Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - } - } +( + QuirkBuilder("Visonic", "MCT-340 E") + .applies_to("Visonic", "MCT-340 SMA") + .replaces(CustomPowerConfigurationCluster, endpoint_id=1) + .add_to_registry() +) diff --git a/zhaquirks/waxman/leaksmart.py b/zhaquirks/waxman/leaksmart.py index 3464d6b4c7..478e232898 100644 --- a/zhaquirks/waxman/leaksmart.py +++ b/zhaquirks/waxman/leaksmart.py @@ -3,32 +3,16 @@ # pylint: disable=W0102 from typing import Any, Optional, Union -from zigpy.profiles import zha -from zigpy.quirks import CustomCluster, CustomDevice +from zigpy.quirks import CustomCluster +from zigpy.quirks.v2 import CustomDeviceV2, QuirkBuilder import zigpy.types as t from zigpy.zcl import foundation -from zigpy.zcl.clusters.general import ( - Basic, - Identify, - Ota, - PollControl, - PowerConfiguration, -) from zigpy.zcl.clusters.homeautomation import ApplianceEventAlerts -from zigpy.zcl.clusters.measurement import TemperatureMeasurement from zigpy.zcl.clusters.security import IasZone from zigpy.zcl.foundation import BaseCommandDefs from zhaquirks import Bus, LocalDataCluster -from zhaquirks.const import ( - CLUSTER_COMMAND, - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) +from zhaquirks.const import CLUSTER_COMMAND from zhaquirks.waxman import WAXMAN MANUFACTURER_SPECIFIC_CLUSTER_ID = 0xFC02 # decimal = 64514 @@ -93,103 +77,20 @@ def handle_cluster_request( self.endpoint.device.ias_bus.listener_event("update_state", state) -class WAXMANleakSMARTv2(CustomDevice): - """Custom device representing WAXMAN leakSMART v2.""" +class WAXMANLeakSmartCustomDevice(CustomDeviceV2): + """Custom device for WAXMAN leakSMART with Bus support.""" def __init__(self, *args, **kwargs): """Init.""" self.ias_bus = Bus() super().__init__(*args, **kwargs) - signature = { - # - MODELS_INFO: [(WAXMAN, "leakSMART Water Sensor V2")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.TEMPERATURE_SENSOR, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - ApplianceEventAlerts.cluster_id, - MANUFACTURER_SPECIFIC_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [Identify.cluster_id, Ota.cluster_id], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.TEMPERATURE_SENSOR, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - TemperatureMeasurement.cluster_id, - WAXMANApplianceEventAlerts, - EmulatedIasZone, - ], - OUTPUT_CLUSTERS: [Identify.cluster_id, Ota.cluster_id], - } - } - } - - -class WAXMANleakSMARTv2NOPOLL(CustomDevice): - """Custom WAXMAN leakSMART v2 without PollControl cluster.""" - - def __init__(self, *args, **kwargs): - """Init.""" - self.ias_bus = Bus() - super().__init__(*args, **kwargs) - signature = { - # - MODELS_INFO: [(WAXMAN, "leakSMART Water Sensor V2")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.TEMPERATURE_SENSOR, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - TemperatureMeasurement.cluster_id, - ApplianceEventAlerts.cluster_id, - MANUFACTURER_SPECIFIC_CLUSTER_ID, - ], - OUTPUT_CLUSTERS: [Identify.cluster_id, Ota.cluster_id], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.TEMPERATURE_SENSOR, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - TemperatureMeasurement.cluster_id, - WAXMANApplianceEventAlerts, - EmulatedIasZone, - ], - OUTPUT_CLUSTERS: [Identify.cluster_id, Ota.cluster_id], - } - } - } +( + QuirkBuilder(WAXMAN, "leakSMART Water Sensor V2") + .device_class(WAXMANLeakSmartCustomDevice) + .removes(MANUFACTURER_SPECIFIC_CLUSTER_ID, endpoint_id=1) + .replaces(WAXMANApplianceEventAlerts, endpoint_id=1) + .adds(EmulatedIasZone, endpoint_id=1) + .add_to_registry() +) diff --git a/zhaquirks/xiaomi/__init__.py b/zhaquirks/xiaomi/__init__.py index 9d3e3b78d3..4c3a0295a5 100644 --- a/zhaquirks/xiaomi/__init__.py +++ b/zhaquirks/xiaomi/__init__.py @@ -11,8 +11,9 @@ import zigpy.device from zigpy.profiles import zha from zigpy.quirks import CustomCluster, CustomDevice +from zigpy.quirks.v2 import CustomDeviceV2 from zigpy.typing import AddressingMode -from zigpy.zcl import Cluster, foundation +from zigpy.zcl import foundation from zigpy.zcl.clusters.general import ( AnalogInput, Basic, @@ -122,28 +123,15 @@ def __init__(self, *args, **kwargs): self.battery_size = BatterySize.CR2032 super().__init__(*args, **kwargs) - def _find_zcl_cluster( - self, hdr: foundation.ZCLHeader, packet: t.ZigbeePacket - ) -> Cluster: - """Find a cluster for the packet.""" - # Aqara devices seem to be very lax with their ZCL header's `direction` field, - # we should try "flipping" it if matching doesn't work normally. - try: - return super()._find_zcl_cluster_strict(hdr, packet) - except KeyError: - _LOGGER.debug( - "Packet is coming in the wrong direction, swapping direction and trying again", - ) +class XiaomiCustomDeviceV2(CustomDeviceV2): + """Custom device representing xiaomi devices.""" - return super()._find_zcl_cluster_strict( - hdr.replace( - frame_control=hdr.frame_control.replace( - direction=hdr.frame_control.direction.flip() - ) - ), - packet, - ) + def __init__(self, *args, **kwargs): + """Init.""" + if not hasattr(self, BATTERY_SIZE): + self.battery_size = BatterySize.CR2032 + super().__init__(*args, **kwargs) class XiaomiQuickInitDevice(XiaomiCustomDevice, QuickInitDevice): diff --git a/zhaquirks/xiaomi/aqara/driver_curtain_e1.py b/zhaquirks/xiaomi/aqara/driver_curtain_e1.py index 883a3125b9..1055f51af4 100644 --- a/zhaquirks/xiaomi/aqara/driver_curtain_e1.py +++ b/zhaquirks/xiaomi/aqara/driver_curtain_e1.py @@ -6,39 +6,23 @@ from zigpy import types as t from zigpy.profiles import zha -from zigpy.zcl import foundation +from zigpy.quirks.v2 import QuirkBuilder +from zigpy.zcl import ClusterType, foundation from zigpy.zcl.clusters.closures import WindowCovering -from zigpy.zcl.clusters.general import Basic, Identify, Ota, PowerConfiguration, Time from zigpy.zcl.clusters.measurement import IlluminanceMeasurement from zigpy.zcl.foundation import ZCLAttributeDef -from zigpy.zdo.types import NodeDescriptor +from zigpy.zdo.types import LogicalType, NodeDescriptor from zhaquirks import CustomCluster -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - NODE_DESCRIPTOR, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.xiaomi import ( LUMI, BasicCluster, LocalIlluminanceMeasurementCluster, XiaomiAqaraE1Cluster, - XiaomiCustomDevice, + XiaomiCustomDeviceV2, XiaomiPowerConfigurationPercent, ) -HAND_OPEN = 0x0401 -POSITIONS_STORED = 0x0402 -STORE_POSITION = 0x0407 -HOOKS_LOCK = 0x0427 -HOOKS_STATE = 0x0428 -LIGHT_LEVEL = 0x0429 - class XiaomiAqaraDriverE1(XiaomiAqaraE1Cluster): """Xiaomi Aqara Curtain Driver E1 cluster.""" @@ -47,26 +31,26 @@ class AttributeDefs(XiaomiAqaraE1Cluster.AttributeDefs): """Attribute definitions.""" hand_open: Final = ZCLAttributeDef( - id=HAND_OPEN, type=t.Bool, is_manufacturer_specific=True + id=0x0401, type=t.Bool, is_manufacturer_specific=True ) positions_stored: Final = ZCLAttributeDef( - id=POSITIONS_STORED, type=t.Bool, is_manufacturer_specific=True + id=0x0402, type=t.Bool, is_manufacturer_specific=True ) store_position: Final = ZCLAttributeDef( - id=STORE_POSITION, type=t.uint8_t, is_manufacturer_specific=True + id=0x0407, type=t.uint8_t, is_manufacturer_specific=True ) hooks_lock: Final = ZCLAttributeDef( - id=HOOKS_LOCK, type=t.uint8_t, is_manufacturer_specific=True + id=0x0427, type=t.uint8_t, is_manufacturer_specific=True ) hooks_state: Final = ZCLAttributeDef( - id=HOOKS_STATE, type=t.uint8_t, is_manufacturer_specific=True + id=0x0428, type=t.uint8_t, is_manufacturer_specific=True ) light_level: Final = ZCLAttributeDef( - id=LIGHT_LEVEL, type=t.uint8_t, is_manufacturer_specific=True + id=0x0429, type=t.uint8_t, is_manufacturer_specific=True ) def _update_attribute(self, attrid, value): - if attrid == LIGHT_LEVEL: + if attrid == self.AttributeDefs.light_level.id: # Light level value seems like it can be 0, 1, or 2. # Multiply by 50 to map those values to later show: 1 lx, 50 lx, 100 lx. self.endpoint.illuminance.update_attribute( @@ -106,58 +90,32 @@ async def command( ) -class DriverE1(XiaomiCustomDevice): - """Aqara Curtain Driver E1 device.""" - - signature = { - MODELS_INFO: [(LUMI, "lumi.curtain.agl001")], - ENDPOINTS: { - # - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.OCCUPANCY_SENSOR, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - Time.cluster_id, - WindowCovering.cluster_id, - XiaomiAqaraDriverE1.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Time.cluster_id, - Ota.cluster_id, - XiaomiAqaraDriverE1.cluster_id, - ], - } - }, - } - replacement = { - NODE_DESCRIPTOR: NodeDescriptor( - 0x02, 0x40, 0x80, 0x115F, 0x7F, 0x0064, 0x2C00, 0x0064, 0x00 - ), - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.WINDOW_COVERING_DEVICE, - INPUT_CLUSTERS: [ - BasicCluster, - XiaomiPowerConfigurationPercent, - Identify.cluster_id, - Time.cluster_id, - WindowCoveringE1, - LocalIlluminanceMeasurementCluster, - XiaomiAqaraDriverE1, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - Time.cluster_id, - Ota.cluster_id, - ], - } - }, - } +( + QuirkBuilder(LUMI, "lumi.curtain.agl001") + .device_class(XiaomiCustomDeviceV2) + .replaces_endpoint(1, device_type=zha.DeviceType.WINDOW_COVERING_DEVICE) + .replaces(BasicCluster, endpoint_id=1) + .replaces(XiaomiPowerConfigurationPercent, endpoint_id=1) + .replaces(WindowCoveringE1, endpoint_id=1) + .adds(LocalIlluminanceMeasurementCluster, endpoint_id=1) + .replaces(XiaomiAqaraDriverE1, endpoint_id=1) + .removes(XiaomiAqaraDriverE1, cluster_type=ClusterType.Client, endpoint_id=1) + .node_descriptor( + NodeDescriptor( + logical_type=LogicalType.EndDevice, + complex_descriptor_available=0, + user_descriptor_available=0, + reserved=0, + aps_flags=0, + frequency_band=NodeDescriptor.FrequencyBand.Freq2400MHz, + mac_capability_flags=NodeDescriptor.MACCapabilityFlags.AllocateAddress, # removes `MainsPowered` + manufacturer_code=4447, + maximum_buffer_size=127, + maximum_incoming_transfer_size=100, + server_mask=11264, + maximum_outgoing_transfer_size=100, + descriptor_capability_field=NodeDescriptor.DescriptorCapability.NONE, + ) + ) + .add_to_registry() +) diff --git a/zhaquirks/yale/realliving.py b/zhaquirks/yale/realliving.py index af172062b3..c97bb2a80e 100644 --- a/zhaquirks/yale/realliving.py +++ b/zhaquirks/yale/realliving.py @@ -1,108 +1,18 @@ """Device handler for Yale Real Living.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice +from zigpy.quirks.v2 import QuirkBuilder +from zigpy.zcl import ClusterType from zigpy.zcl.clusters.closures import DoorLock -from zigpy.zcl.clusters.general import Alarms, Basic, Identify, Ota, PollControl, Time +from zigpy.zcl.clusters.general import Time from zhaquirks import DoublingPowerConfigurationCluster -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) - - -class YRD210PBDB220TSLL(CustomDevice): - """Yale YRD210 PB BP and Yale YRL220 TS LL Locks.""" - - signature = { - # - MODELS_INFO: [("Yale", "YRD210 PB DB"), ("Yale", "YRL220 TS LL")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.DOOR_LOCK, - INPUT_CLUSTERS: [ - Basic.cluster_id, - DoublingPowerConfigurationCluster.cluster_id, - Identify.cluster_id, - Alarms.cluster_id, - Time.cluster_id, - DoorLock.cluster_id, - PollControl.cluster_id, - ], - OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.DOOR_LOCK, - INPUT_CLUSTERS: [ - Basic.cluster_id, - DoublingPowerConfigurationCluster, - Identify.cluster_id, - Alarms.cluster_id, - Time.cluster_id, - DoorLock.cluster_id, - PollControl.cluster_id, - ], - OUTPUT_CLUSTERS: [DoorLock.cluster_id, Ota.cluster_id], - } - } - } - -class YRD220240TSDB(CustomDevice): - """Yale YRD220/240 TSDB Lock.""" - - signature = { - # - MODELS_INFO: [("Yale", "YRD220/240 TSDB")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.DOOR_LOCK, - INPUT_CLUSTERS: [ - Basic.cluster_id, - DoublingPowerConfigurationCluster.cluster_id, - Alarms.cluster_id, - Time.cluster_id, - PollControl.cluster_id, - DoorLock.cluster_id, - ], - OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.DOOR_LOCK, - INPUT_CLUSTERS: [ - Basic.cluster_id, - DoublingPowerConfigurationCluster, - Alarms.cluster_id, - Time.cluster_id, - PollControl.cluster_id, - DoorLock.cluster_id, - ], - OUTPUT_CLUSTERS: [DoorLock.cluster_id, Ota.cluster_id], - } - } - } +( + QuirkBuilder("Yale", "YRD210 PB DB") + .applies_to("Yale", "YRL220 TS LL") + .applies_to("Yale", "YRD220/240 TSDB") + .replaces(DoublingPowerConfigurationCluster, endpoint_id=1) + .removes(Time.cluster_id, cluster_type=ClusterType.Client, endpoint_id=1) + .adds(DoorLock.cluster_id, cluster_type=ClusterType.Client, endpoint_id=1) + .add_to_registry() +) diff --git a/zhaquirks/zbeacon/doorsensor.py b/zhaquirks/zbeacon/doorsensor.py index 8d47c5144c..3321d5023e 100644 --- a/zhaquirks/zbeacon/doorsensor.py +++ b/zhaquirks/zbeacon/doorsensor.py @@ -1,71 +1,15 @@ """Doorsensors.""" -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - Identify, - Ota, - PollControl, - PowerConfiguration, -) -from zigpy.zcl.clusters.security import IasZone - -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) - - -class DS01DoorSensor(CustomDevice): - """One of the long rectangular Doorsensors working on 2xAAA. - - It doesn't correctly implement the PollControl Cluster. - The device will send "PollControl:checkin()" on PollControl cluster, - but doesn't respond when checkin_response is sent after that from the coordinator - - The model zbeacon DS01 sounds a lot like ("eWeLink", "DS01") from Sonoff sold as Sonoff SNZB-04 - The device tested is sold as Elivco and IHseno IH-MC01 and uses a TuYa ZTU module as described here: - https://github.com/dresden-elektronik/deconz-rest-plugin/issues/7415 - """ - - signature = { - MODELS_INFO: [("zbeacon", "DS01")], - ENDPOINTS: { - # SizePrefixedSimpleDescriptor( - # endpoint=1, profile=260, device_type=1026, device_version=0, - # input_clusters=[0, 3, 1, 1280, 32], output_clusters=[25]) - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - PollControl.cluster_id, - IasZone.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - IasZone.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Ota.cluster_id, - ], - } - } - } +from zigpy.quirks.v2 import QuirkBuilder +from zigpy.zcl.clusters.general import PollControl + +# One of the long rectangular Doorsensors working on 2xAAA. +# +# It doesn't correctly implement the PollControl Cluster. +# The device will send "PollControl:checkin()" on PollControl cluster, +# but doesn't respond when checkin_response is sent after that from the coordinator +# +# The model zbeacon DS01 sounds a lot like ("eWeLink", "DS01") from Sonoff sold as Sonoff SNZB-04 +# The device tested is sold as Elivco and IHseno IH-MC01 and uses a TuYa ZTU module as described here: +# https://github.com/dresden-elektronik/deconz-rest-plugin/issues/7415 +(QuirkBuilder("zbeacon", "DS01").removes(PollControl, endpoint_id=1).add_to_registry()) diff --git a/zhaquirks/zen/thermostat.py b/zhaquirks/zen/thermostat.py index 905ef2bc6e..f3ebd5378c 100644 --- a/zhaquirks/zen/thermostat.py +++ b/zhaquirks/zen/thermostat.py @@ -1,69 +1,11 @@ """Module to handle quirks of the Zen Within thermostat.""" -import zigpy.profiles.zha as zha_p -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters import general, homeautomation, hvac +from zigpy.quirks.v2 import QuirkBuilder -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) from zhaquirks.zen import ZEN, ZenPowerConfiguration - -class ZenThermostat(CustomDevice): - """Zen Within Thermostat custom device.""" - - signature = { - # Node Descriptor: - # - MODELS_INFO: [(ZEN, "Zen-01")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha_p.PROFILE_ID, - DEVICE_TYPE: zha_p.DeviceType.THERMOSTAT, - INPUT_CLUSTERS: [ - general.Basic.cluster_id, - general.PowerConfiguration.cluster_id, - general.Identify.cluster_id, - general.Groups.cluster_id, - general.Scenes.cluster_id, - general.PollControl.cluster_id, - hvac.Thermostat.cluster_id, - hvac.Fan.cluster_id, - hvac.UserInterface.cluster_id, - homeautomation.Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [general.Time.cluster_id, general.Ota.cluster_id], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [ - general.Basic.cluster_id, - ZenPowerConfiguration, - general.Identify.cluster_id, - general.Groups.cluster_id, - general.Scenes.cluster_id, - general.PollControl.cluster_id, - hvac.Thermostat.cluster_id, - hvac.Fan.cluster_id, - hvac.UserInterface.cluster_id, - homeautomation.Diagnostic.cluster_id, - ], - OUTPUT_CLUSTERS: [general.Time.cluster_id, general.Ota.cluster_id], - } - } - } +( + QuirkBuilder(ZEN, "Zen-01") + .replaces(ZenPowerConfiguration, endpoint_id=1) + .add_to_registry() +) diff --git a/zhaquirks/zhongxing/motion.py b/zhaquirks/zhongxing/motion.py index 00652277ba..6fb2cbc22d 100644 --- a/zhaquirks/zhongxing/motion.py +++ b/zhaquirks/zhongxing/motion.py @@ -3,76 +3,20 @@ Aka. ZHONGXING. Based on Orvibo motion sensor code. """ -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import ( - Basic, - Groups, - Identify, - PowerConfiguration, - Scenes, -) -from zigpy.zcl.clusters.security import IasZone +from zigpy.quirks.v2 import QuirkBuilder +from zigpy.zcl import ClusterType +from zigpy.zcl.clusters.general import Basic, Groups, PowerConfiguration, Scenes -from zhaquirks import Bus, PowerConfigurationCluster -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, -) +from zhaquirks import PowerConfigurationCluster from zhaquirks.zhongxing import ZHONGXING, MotionCluster - -class SN10ZW(CustomDevice): - """SN10ZW motion sensor.""" - - def __init__(self, *args, **kwargs): - """Init.""" - self.occupancy_bus = Bus() - super().__init__(*args, **kwargs) - - signature = { - # - MODELS_INFO: [(ZHONGXING, "700ae5aab3414ec09c1872efe7b8755a")], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.IAS_ZONE, - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - IasZone.cluster_id, - ], - OUTPUT_CLUSTERS: [ - Identify.cluster_id, - ], - } - }, - } - - replacement = { - ENDPOINTS: { - 1: { - INPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfigurationCluster, - Identify.cluster_id, - MotionCluster, - ], - OUTPUT_CLUSTERS: [ - Basic.cluster_id, - PowerConfiguration.cluster_id, - Identify.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - ], - } - } - } +( + QuirkBuilder(ZHONGXING, "700ae5aab3414ec09c1872efe7b8755a") + .replaces(PowerConfigurationCluster, endpoint_id=1) + .replaces(MotionCluster, endpoint_id=1) + .adds(Basic.cluster_id, cluster_type=ClusterType.Client, endpoint_id=1) + .adds(PowerConfiguration.cluster_id, cluster_type=ClusterType.Client, endpoint_id=1) + .adds(Groups.cluster_id, cluster_type=ClusterType.Client, endpoint_id=1) + .adds(Scenes.cluster_id, cluster_type=ClusterType.Client, endpoint_id=1) + .add_to_registry() +)