Skip to content

Commit 34f93a6

Browse files
committed
WIP: Fix most failing tests
1 parent d6c8ee2 commit 34f93a6

18 files changed

+182
-396
lines changed

tests/conftest.py

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ def _dev(
171171
model: str,
172172
endpoint_ids: list[int] = [1],
173173
cluster_ids: dict[int, dict[int, ClusterType]] = {},
174+
device_types: dict[int, int] = {},
174175
ieee=None,
175176
nwk=zigpy.types.NWK(0x1234),
176177
apply_quirk=True,
@@ -184,6 +185,8 @@ def _dev(
184185
and their cluster ids and types to be added to the device.
185186
More advanced version of endpoint_ids argument.
186187
Example: `cluster_ids={2: {OnOff.cluster_id: ClusterType.Client}}`
188+
:param device_types: Dictionary mapping endpoint ids to device_type values.
189+
Example: `device_types={1: 0x0820}`
187190
:param ieee: IEEE address of the device.
188191
:param nwk: Network address of the device.
189192
:param apply_quirk: Whether to apply the quirk to the device.
@@ -212,29 +215,22 @@ def _dev(
212215
for endpoint_id, clusters in endpoint_clusters.items():
213216
ep = raw_device.add_endpoint(endpoint_id)
214217

218+
# set device_type if provided
219+
if endpoint_id in device_types:
220+
ep.device_type = device_types[endpoint_id]
221+
215222
# add custom cluster ids to test device
216223
for cluster_id, cluster_type in clusters.items():
217224
if cluster_type == ClusterType.Client:
218225
ep.add_output_cluster(cluster_id)
219226
else:
220227
ep.add_input_cluster(cluster_id)
221228

222-
quirked = zigpy.quirks.get_device(raw_device)
223-
224229
if not apply_quirk:
225-
for ep_id, ep_data in quirked.endpoints.items():
226-
if ep_id != 0:
227-
ep = raw_device.add_endpoint(ep_id)
228-
ep.profile_id = ep_data.get(PROFILE_ID, 0x0260)
229-
ep.device_type = ep_data.get(DEVICE_TYPE, 0xFEDB)
230-
in_clusters = ep_data.get(INPUT_CLUSTERS, [])
231-
for cluster_id in in_clusters:
232-
ep.add_input_cluster(cluster_id)
233-
out_clusters = ep_data.get(OUTPUT_CLUSTERS, [])
234-
for cluster_id in out_clusters:
235-
ep.add_output_cluster(cluster_id)
236230
return raw_device
237231

232+
quirked = zigpy.quirks.get_device(raw_device)
233+
238234
MockAppController.devices[ieee] = quirked
239235

240236
return quirked

tests/test_danfoss.py

Lines changed: 6 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -14,42 +14,10 @@
1414
zhaquirks.setup()
1515

1616

17-
def test_popp_signature(assert_signature_matches_quirk):
18-
"""Test the signature matching the Device Class."""
19-
signature = {
20-
"node_descriptor": "NodeDescriptor(logical_type=<LogicalType.EndDevice: 2>, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=<FrequencyBand.Freq2400MHz: 8>, mac_capability_flags=<MACCapabilityFlags.AllocateAddress: 128>, manufacturer_code=4678, maximum_buffer_size=82, maximum_incoming_transfer_size=82, server_mask=11264, maximum_outgoing_transfer_size=82, descriptor_capability_field=<DescriptorCapability.NONE: 0>, *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)",
21-
# 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])
22-
"endpoints": {
23-
"1": {
24-
"profile_id": 260,
25-
"device_type": "0x0301",
26-
"in_clusters": [
27-
"0x0000",
28-
"0x0001",
29-
"0x0003",
30-
"0x000a",
31-
"0x0020",
32-
"0x0201",
33-
"0x0204",
34-
"0x0b05",
35-
],
36-
"out_clusters": ["0x0000", "0x0019"],
37-
}
38-
},
39-
"manufacturer": "D5X84YU",
40-
"model": "eT093WRO",
41-
"class": "danfoss.thermostat.DanfossThermostat",
42-
}
43-
44-
assert_signature_matches_quirk(
45-
zhaquirks.danfoss.thermostat.DanfossThermostat, signature
46-
)
47-
48-
4917
@mock.patch("zigpy.zcl.Cluster.bind", mock.AsyncMock())
50-
async def test_danfoss_time_bind(zigpy_device_from_quirk):
18+
async def test_danfoss_time_bind(zigpy_device_from_v2_quirk):
5119
"""Test the time being set when binding the Time cluster."""
52-
device = zigpy_device_from_quirk(zhaquirks.danfoss.thermostat.DanfossThermostat)
20+
device = zigpy_device_from_v2_quirk("Danfoss", "eTRV0103")
5321

5422
danfoss_time_cluster = device.endpoints[1].time
5523
danfoss_thermostat_cluster = device.endpoints[1].thermostat
@@ -74,9 +42,9 @@ def mock_write(attributes, manufacturer=None):
7442
assert 0x0002 in danfoss_time_cluster._attr_cache
7543

7644

77-
async def test_danfoss_thermostat_write_attributes(zigpy_device_from_quirk):
45+
async def test_danfoss_thermostat_write_attributes(zigpy_device_from_v2_quirk):
7846
"""Test the Thermostat writes behaving correctly, in particular regarding setpoint."""
79-
device = zigpy_device_from_quirk(zhaquirks.danfoss.thermostat.DanfossThermostat)
47+
device = zigpy_device_from_v2_quirk("Danfoss", "eTRV0103")
8048

8149
danfoss_thermostat_cluster = device.endpoints[1].thermostat
8250

@@ -144,12 +112,12 @@ def mock_setpoint(oper, sett, manufacturer=None):
144112
assert setting == 5
145113

146114

147-
async def test_customized_standardcluster(zigpy_device_from_quirk):
115+
async def test_customized_standardcluster(zigpy_device_from_v2_quirk):
148116
"""Test customized standard cluster class correctly separating zigbee operations.
149117
150118
This is regarding manufacturer specific attributes.
151119
"""
152-
device = zigpy_device_from_quirk(zhaquirks.danfoss.thermostat.DanfossThermostat)
120+
device = zigpy_device_from_v2_quirk("Danfoss", "eTRV0103")
153121

154122
danfoss_thermostat_cluster = device.endpoints[1].in_clusters[Thermostat.cluster_id]
155123

tests/test_gledopto.py

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1 @@
11
"""Tests for GLEDOPTO quirks."""
2-
3-
import zhaquirks.gledopto.glc009
4-
5-
6-
def test_gledopto_glc009_signature(assert_signature_matches_quirk):
7-
"""Test GLEDOPTO GL-C-009 signature is matched to its quirk."""
8-
signature = {
9-
"node_descriptor": "NodeDescriptor(logical_type=<LogicalType.Router: 1>, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=<FrequencyBand.Freq2400MHz: 8>, mac_capability_flags=<MACCapabilityFlags.AllocateAddress|RxOnWhenIdle|MainsPowered|FullFunctionDevice: 142>, manufacturer_code=0, maximum_buffer_size=80, maximum_incoming_transfer_size=160, server_mask=0, maximum_outgoing_transfer_size=160, descriptor_capability_field=<DescriptorCapability.NONE: 0>, *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)",
10-
"endpoints": {
11-
"11": {
12-
"profile_id": 49246,
13-
"device_type": "0x0100",
14-
"in_clusters": [
15-
"0x0000",
16-
"0x0003",
17-
"0x0004",
18-
"0x0005",
19-
"0x0006",
20-
"0x0008",
21-
"0x0300",
22-
],
23-
"out_clusters": [],
24-
},
25-
"13": {
26-
"profile_id": 49246,
27-
"device_type": "0x0100",
28-
"in_clusters": ["0x1000"],
29-
"out_clusters": ["0x1000"],
30-
},
31-
},
32-
"manufacturer": "GLEDOPTO",
33-
"model": "GL-C-009",
34-
"class": "zigpy.device.Device",
35-
}
36-
37-
assert_signature_matches_quirk(zhaquirks.gledopto.glc009.GLC009, signature)

tests/test_ikea.py

Lines changed: 10 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -15,77 +15,6 @@
1515
zhaquirks.setup()
1616

1717

18-
def test_ikea_starkvind(assert_signature_matches_quirk):
19-
"""Test new 'STARKVIND Air purifier table' signature is matched to its quirk."""
20-
21-
signature = {
22-
"node_descriptor": "NodeDescriptor(logical_type=<LogicalType.Router: 1>, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=<FrequencyBand.Freq2400MHz: 8>, mac_capability_flags=<MACCapabilityFlags.AllocateAddress|RxOnWhenIdle|MainsPowered|FullFunctionDevice: 142>, manufacturer_code=4476, maximum_buffer_size=82, maximum_incoming_transfer_size=82, server_mask=11264, maximum_outgoing_transfer_size=82, descriptor_capability_field=<DescriptorCapability.NONE: 0>, *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)",
23-
"endpoints": {
24-
"1": {
25-
"profile_id": 260,
26-
"device_type": "0x0007",
27-
"in_clusters": [
28-
"0x0000",
29-
"0x0003",
30-
"0x0004",
31-
"0x0005",
32-
"0x0202",
33-
"0xfc57",
34-
"0xfc7d",
35-
],
36-
"out_clusters": ["0x0019", "0x0400", "0x042a"],
37-
},
38-
"242": {
39-
"profile_id": 41440,
40-
"device_type": "0x0061",
41-
"in_clusters": [],
42-
"out_clusters": ["0x0021"],
43-
},
44-
},
45-
"manufacturer": "IKEA of Sweden",
46-
"model": "STARKVIND Air purifier",
47-
"class": "ikea.starkvind.IkeaSTARKVIND",
48-
}
49-
50-
assert_signature_matches_quirk(zhaquirks.ikea.starkvind.IkeaSTARKVIND, signature)
51-
52-
53-
def test_ikea_starkvind_v2(assert_signature_matches_quirk):
54-
"""Test new 'STARKVIND Air purifier table' signature is matched to its quirk."""
55-
56-
signature = {
57-
"node_descriptor": "NodeDescriptor(logical_type=<LogicalType.Router: 1>, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=<FrequencyBand.Freq2400MHz: 8>, mac_capability_flags=<MACCapabilityFlags.AllocateAddress|RxOnWhenIdle|MainsPowered|FullFunctionDevice: 142>, manufacturer_code=4476, maximum_buffer_size=82, maximum_incoming_transfer_size=82, server_mask=11264, maximum_outgoing_transfer_size=82, descriptor_capability_field=<DescriptorCapability.NONE: 0>, *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)",
58-
"endpoints": {
59-
"1": {
60-
"profile_id": 260,
61-
"device_type": "0x0007",
62-
"in_clusters": [
63-
"0x0000",
64-
"0x0003",
65-
"0x0004",
66-
"0x0005",
67-
"0x0202",
68-
"0xfc57",
69-
"0xfc7c",
70-
"0xfc7d",
71-
],
72-
"out_clusters": ["0x0019", "0x0400", "0x042a"],
73-
},
74-
"242": {
75-
"profile_id": 41440,
76-
"device_type": "0x0061",
77-
"in_clusters": [],
78-
"out_clusters": ["0x0021"],
79-
},
80-
},
81-
"manufacturer": "IKEA of Sweden",
82-
"model": "STARKVIND Air purifier table",
83-
"class": "ikea.starkvind.IkeaSTARKVIND_v2",
84-
}
85-
86-
assert_signature_matches_quirk(zhaquirks.ikea.starkvind.IkeaSTARKVIND_v2, signature)
87-
88-
8918
@pytest.mark.parametrize("attribute", ["fan_speed", "fan_mode"])
9019
@pytest.mark.parametrize(
9120
"value,expected",
@@ -98,11 +27,13 @@ def test_ikea_starkvind_v2(assert_signature_matches_quirk):
9827
],
9928
)
10029
async def test_fan_speed_mode_update(
101-
zigpy_device_from_quirk, attribute, value, expected
30+
zigpy_device_from_v2_quirk, attribute, value, expected
10231
):
10332
"""Test reading the fan speed and mode."""
10433

105-
starkvind_device = zigpy_device_from_quirk(zhaquirks.ikea.starkvind.IkeaSTARKVIND)
34+
starkvind_device = zigpy_device_from_v2_quirk(
35+
"IKEA of Sweden", "STARKVIND Air purifier"
36+
)
10637
assert starkvind_device.model == "STARKVIND Air purifier"
10738

10839
ikea_cluster = starkvind_device.endpoints[1].in_clusters[
@@ -117,10 +48,12 @@ async def test_fan_speed_mode_update(
11748
assert ikea_listener.attribute_updates[0] == (attr_id, expected)
11849

11950

120-
async def test_pm25_cluster_read(zigpy_device_from_quirk):
51+
async def test_pm25_cluster_read(zigpy_device_from_v2_quirk):
12152
"""Test reading from PM25 cluster."""
12253

123-
starkvind_device = zigpy_device_from_quirk(zhaquirks.ikea.starkvind.IkeaSTARKVIND)
54+
starkvind_device = zigpy_device_from_v2_quirk(
55+
"IKEA of Sweden", "STARKVIND Air purifier"
56+
)
12457
assert starkvind_device.model == "STARKVIND Air purifier"
12558

12659
pm25_cluster = starkvind_device.endpoints[1].in_clusters[PM25.cluster_id]
@@ -175,7 +108,7 @@ def mock_read(attributes, manufacturer=None):
175108
)
176109
async def test_double_power_config_firmware(
177110
caplog,
178-
zigpy_device_from_quirk,
111+
zigpy_device_from_v2_quirk,
179112
firmware,
180113
pct_device,
181114
pct_correct,
@@ -184,7 +117,7 @@ async def test_double_power_config_firmware(
184117
):
185118
"""Test battery percentage remaining is doubled for old firmware."""
186119

187-
device = zigpy_device_from_quirk(zhaquirks.ikea.fivebtnremote.IkeaTradfriRemote1)
120+
device = zigpy_device_from_v2_quirk("IKEA of Sweden", "TRADFRI remote control")
188121

189122
basic_cluster = device.endpoints[1].basic
190123
ClusterListener(basic_cluster)

tests/test_konke.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@
2424

2525

2626
@pytest.mark.parametrize(
27-
"quirk", (zhaquirks.konke.motion.KonkeMotion, zhaquirks.konke.motion.KonkeMotionB)
27+
"model", ("3AFE28010402000D", "3AFE14010402000D", "3AFE27010402000D")
2828
)
29-
async def test_konke_motion(zigpy_device_from_quirk, quirk):
29+
async def test_konke_motion(zigpy_device_from_v2_quirk, model):
3030
"""Test konke motion sensor."""
3131

32-
motion_dev = zigpy_device_from_quirk(quirk)
32+
motion_dev = zigpy_device_from_v2_quirk("Konke", model)
3333

3434
motion_cluster = motion_dev.endpoints[1].ias_zone
3535
motion_listener = ClusterListener(motion_cluster)
@@ -67,16 +67,16 @@ async def test_konke_motion(zigpy_device_from_quirk, quirk):
6767

6868

6969
@pytest.mark.parametrize(
70-
"quirk",
70+
"model",
7171
(
72-
zhaquirks.konke.button.KonkeButtonRemote1,
73-
zhaquirks.konke.button.KonkeButtonRemote2,
72+
"3AFE170100510001",
73+
"3AFE280100510001",
7474
),
7575
)
76-
async def test_konke_button(zigpy_device_from_quirk, quirk):
76+
async def test_konke_button(zigpy_device_from_v2_quirk, model):
7777
"""Test Konke button remotes."""
7878

79-
device = zigpy_device_from_quirk(quirk)
79+
device = zigpy_device_from_v2_quirk("Konke", model)
8080
cluster = device.endpoints[1].konke_on_off
8181

8282
listener = mock.MagicMock()

tests/test_legrand.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@
2323
(24.0, 0), # below min
2424
),
2525
)
26-
async def test_legrand_battery(zigpy_device_from_quirk, voltage, bpr):
26+
async def test_legrand_battery(zigpy_device_from_v2_quirk, voltage, bpr):
2727
"""Test Legrand battery voltage to % battery left."""
2828

29-
device = zigpy_device_from_quirk(zhaquirks.legrand.dimmer.RemoteDimmer)
29+
device = zigpy_device_from_v2_quirk(f" {LEGRAND}", " Remote dimmer switch")
3030
power_cluster = device.endpoints[1].power
3131
power_cluster.update_attribute(0x0020, voltage)
3232
assert power_cluster["battery_percentage_remaining"] == bpr

tests/test_linkind.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@
99
zhaquirks.setup()
1010

1111

12-
@pytest.mark.parametrize("quirk", (zhaquirks.linkind.motion.LinkindD0003,))
13-
async def test_linkind_motion_ignore_alarm_2(zigpy_device_from_quirk, quirk):
12+
@pytest.mark.parametrize("manufacturer,model", [("lk", "ZB-MotionSensor-D0003")])
13+
async def test_linkind_motion_ignore_alarm_2(
14+
zigpy_device_from_v2_quirk, manufacturer, model
15+
):
1416
"""Test that the quirk for the Linkind motion sensor ignores the IasZone Alarm_2 bit."""
15-
device = zigpy_device_from_quirk(quirk)
17+
device = zigpy_device_from_v2_quirk(manufacturer, model)
1618

1719
ias_zone_cluster = device.endpoints[1].ias_zone
1820
ias_zone_listener = ClusterListener(ias_zone_cluster)

tests/test_linxura.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@
1212
zhaquirks.setup()
1313

1414

15-
async def test_button_ias(zigpy_device_from_quirk):
15+
async def test_button_ias(zigpy_device_from_v2_quirk):
1616
"""Test Linxura button remotes."""
1717

18-
device = zigpy_device_from_quirk(zhaquirks.linxura.button.LinxuraButton)
18+
device = zigpy_device_from_v2_quirk("Linxura", "Smart Controller")
1919
ias_zone_status_attr_id = IasZone.AttributeDefs.zone_status.id
2020
cluster = device.endpoints[1].ias_zone
2121
listener = mock.MagicMock()
@@ -99,9 +99,9 @@ async def test_button_ias(zigpy_device_from_quirk):
9999
),
100100
],
101101
)
102-
async def test_button_triggers(zigpy_device_from_quirk, message, button, press_type):
102+
async def test_button_triggers(zigpy_device_from_v2_quirk, message, button, press_type):
103103
"""Test ZHA_SEND_EVENT case."""
104-
device = zigpy_device_from_quirk(zhaquirks.linxura.button.LinxuraButton)
104+
device = zigpy_device_from_v2_quirk("Linxura", "Smart Controller")
105105
cluster = device.endpoints[1].ias_zone
106106
listener = mock.MagicMock()
107107
cluster.add_listener(listener)

tests/test_orvibo.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@
1313
zhaquirks.setup()
1414

1515

16-
@pytest.mark.parametrize("quirk", (zhaquirks.orvibo.motion.SN10ZW,))
17-
async def test_orvibo_motion(zigpy_device_from_quirk, quirk):
16+
@pytest.mark.parametrize("model", ("895a2d80097f4ae2b2d40500d5e03dcc",))
17+
async def test_orvibo_motion(zigpy_device_from_v2_quirk, model):
1818
"""Test Orvibo motion sensor."""
1919

20-
motion_dev = zigpy_device_from_quirk(quirk)
20+
motion_dev = zigpy_device_from_v2_quirk("ORVIBO", model)
2121

2222
motion_cluster = motion_dev.endpoints[1].ias_zone
2323
motion_listener = ClusterListener(motion_cluster)

0 commit comments

Comments
 (0)