Skip to content

Commit 85ff2ce

Browse files
committed
Init quirk
1 parent d80730f commit 85ff2ce

File tree

5 files changed

+86
-31
lines changed

5 files changed

+86
-31
lines changed

tests/conftest.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import pytest
66
import zigpy.application
77
import zigpy.device
8+
from zigpy.device import Device
89
import zigpy.quirks
910
import zigpy.types
1011
from zigpy.zcl import foundation
@@ -21,6 +22,8 @@
2122
PROFILE_ID,
2223
)
2324

25+
from .async_mock import sentinel
26+
2427

2528
class MockApp(zigpy.application.ControllerApplication):
2629
"""App Controller."""
@@ -204,6 +207,25 @@ def _dev(
204207
return _dev
205208

206209

210+
@pytest.fixture(name="device_mock")
211+
def real_device(MockAppController):
212+
"""Device fixture with a single endpoint."""
213+
ieee = sentinel.ieee
214+
nwk = 0x2233
215+
device = Device(MockAppController, ieee, nwk)
216+
217+
device.add_endpoint(1)
218+
device[1].profile_id = 0x0104
219+
device[1].device_type = 0x0051
220+
device.model = "model"
221+
device.manufacturer = "manufacturer"
222+
device[1].add_input_cluster(0x0000)
223+
device[1].add_input_cluster(0xEF00)
224+
device[1].add_output_cluster(0x000A)
225+
device[1].add_output_cluster(0x0019)
226+
return device
227+
228+
207229
@pytest.fixture
208230
def assert_signature_matches_quirk():
209231
"""Return a function that can be used to check if a given quirk matches a signature."""

tests/test_quirks.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
import zigpy.endpoint
1515
import zigpy.profiles
1616
import zigpy.quirks as zq
17-
from zigpy.quirks import CustomDevice
17+
from zigpy.quirks import CustomDevice, DeviceRegistry
1818
from zigpy.quirks.v2 import QuirkBuilder
1919
import zigpy.types
2020
from zigpy.zcl import foundation
@@ -845,8 +845,9 @@ def check_for_duplicate_cluster_ids(clusters) -> None:
845845
check_for_duplicate_cluster_ids(ep_data.get(OUTPUT_CLUSTERS, []))
846846

847847

848-
async def test_local_data_cluster(zigpy_device_from_v2_quirk) -> None:
848+
async def test_local_data_cluster(device_mock) -> None:
849849
"""Ensure reading attributes from a LocalDataCluster works as expected."""
850+
registry = DeviceRegistry()
850851

851852
class TestLocalCluster(zhaquirks.LocalDataCluster):
852853
"""Test cluster."""
@@ -856,11 +857,11 @@ class TestLocalCluster(zhaquirks.LocalDataCluster):
856857
_VALID_ATTRIBUTES = [2]
857858

858859
(
859-
QuirkBuilder("manufacturer-local-test", "model")
860+
QuirkBuilder(device_mock.manufacturer, device_mock.model, registry=registry)
860861
.adds(TestLocalCluster)
861862
.add_to_registry()
862863
)
863-
device = zigpy_device_from_v2_quirk("manufacturer-local-test", "model")
864+
device = registry.get_device(device_mock)
864865
assert isinstance(device.endpoints[1].in_clusters[0x1234], TestLocalCluster)
865866

866867
# reading invalid attribute return unsupported attribute

tests/test_tuya_builder.py

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
from unittest import mock
44

55
import pytest
6-
from zigpy.device import Device
76
from zigpy.quirks.registry import DeviceRegistry
87
from zigpy.quirks.v2 import CustomDeviceV2
98
import zigpy.types as t
@@ -25,30 +24,9 @@
2524
)
2625
from zhaquirks.tuya.mcu import TuyaMCUCluster, TuyaOnOffNM
2726

28-
from .async_mock import sentinel
29-
3027
zhaquirks.setup()
3128

3229

33-
@pytest.fixture(name="device_mock")
34-
def real_device(MockAppController):
35-
"""Device fixture with a single endpoint."""
36-
ieee = sentinel.ieee
37-
nwk = 0x2233
38-
device = Device(MockAppController, ieee, nwk)
39-
40-
device.add_endpoint(1)
41-
device[1].profile_id = 0x0104
42-
device[1].device_type = 0x0051
43-
device.model = "model"
44-
device.manufacturer = "manufacturer"
45-
device[1].add_input_cluster(0x0000)
46-
device[1].add_input_cluster(0xEF00)
47-
device[1].add_output_cluster(0x000A)
48-
device[1].add_output_cluster(0x0019)
49-
return device
50-
51-
5230
@pytest.mark.parametrize(
5331
"method_name,attr_name,exp_class",
5432
[
@@ -95,6 +73,9 @@ class TestEnum(t.enum8):
9573
A = 0x00
9674
B = 0x01
9775

76+
class ModTuyaMCUCluster(TuyaMCUCluster):
77+
"""Modified Cluster."""
78+
9879
entry = (
9980
TuyaQuirkBuilder(device_mock.manufacturer, device_mock.model, registry=registry)
10081
.tuya_battery(dp_id=1)
@@ -133,7 +114,7 @@ class TestEnum(t.enum8):
133114
fallback_name="Test enum",
134115
)
135116
.skip_configuration()
136-
.add_to_registry()
117+
.add_to_registry(mcu_cluster=ModTuyaMCUCluster)
137118
)
138119

139120
# coverage for overridden __eq__ method
@@ -150,6 +131,7 @@ class TestEnum(t.enum8):
150131
assert isinstance(ep.basic, Basic)
151132

152133
assert ep.tuya_manufacturer is not None
134+
assert isinstance(ep.tuya_manufacturer, ModTuyaMCUCluster)
153135
assert isinstance(ep.tuya_manufacturer, TuyaMCUCluster)
154136

155137
tuya_cluster = ep.tuya_manufacturer

zhaquirks/tuya/builder/__init__.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -538,16 +538,16 @@ class EnchantedDeviceV2(CustomDeviceV2, BaseEnchantedDevice):
538538

539539
return self
540540

541-
def add_to_registry(self) -> QuirksV2RegistryEntry:
541+
def add_to_registry(self, mcu_cluster=TuyaMCUCluster) -> QuirksV2RegistryEntry:
542542
"""Build the quirks v2 registry entry."""
543543

544-
class NewAttributeDefs(TuyaMCUCluster.AttributeDefs):
544+
class NewAttributeDefs(mcu_cluster.AttributeDefs):
545545
"""Attribute Definitions."""
546546

547547
for attr in self.new_attributes:
548548
setattr(NewAttributeDefs, attr.name, attr)
549549

550-
class TuyaReplacementCluster(TuyaMCUCluster):
550+
class TuyaReplacementCluster(mcu_cluster):
551551
"""Replacement Tuya Cluster."""
552552

553553
data_point_handlers: dict[int, str]

zhaquirks/tuya/ts0601_sensor.py

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,15 @@
22

33
from zigpy.quirks.v2.homeassistant.sensor import SensorDeviceClass, SensorStateClass
44
import zigpy.types as t
5+
from zigpy.zcl import foundation
56

6-
from zhaquirks.tuya.builder import TuyaPowerConfigurationCluster2AAA, TuyaQuirkBuilder
7+
from zhaquirks.tuya import (
8+
TUYA_MCU_VERSION_REQ,
9+
TUYA_QUERY_DATA,
10+
TuyaPowerConfigurationCluster2AAA,
11+
)
12+
from zhaquirks.tuya.builder import TuyaQuirkBuilder
13+
from zhaquirks.tuya.mcu import TuyaMCUCluster
714

815
(
916
TuyaQuirkBuilder("_TZE200_bjawzodf", "TS0601")
@@ -33,6 +40,49 @@
3340
)
3441

3542

43+
class RespondingTuyaMCUCluster(TuyaMCUCluster):
44+
"""Tuya Manufacturer Cluster with mcu version response."""
45+
46+
def handle_mcu_version_response(
47+
self, payload: TuyaMCUCluster.MCUVersion
48+
) -> foundation.Status:
49+
"""Handle MCU version response."""
50+
51+
self.create_catching_task(
52+
super().command(TUYA_MCU_VERSION_REQ, 2, expect_reply=False)
53+
)
54+
self.create_catching_task(super().command(TUYA_QUERY_DATA, expect_reply=False))
55+
super().handle_mcu_version_response(payload)
56+
57+
server_commands = TuyaMCUCluster.server_commands.copy()
58+
server_commands.update(
59+
{
60+
TUYA_MCU_VERSION_REQ: foundation.ZCLCommandDef(
61+
"mcu_version_req",
62+
{"data": t.uint16_t},
63+
True,
64+
is_manufacturer_specific=False,
65+
),
66+
}
67+
)
68+
69+
70+
(
71+
TuyaQuirkBuilder("_TZE204_upagmta9", "TS0601")
72+
.tuya_temperature(dp_id=1, scale=10)
73+
.tuya_humidity(dp_id=2)
74+
.tuya_dp(
75+
dp_id=3,
76+
ep_attribute=TuyaPowerConfigurationCluster2AAA.ep_attribute,
77+
attribute_name="battery_percentage_remaining",
78+
converter=lambda x: {0: 50, 1: 100, 2: 200}[x],
79+
)
80+
.adds(TuyaPowerConfigurationCluster2AAA)
81+
.skip_configuration()
82+
.add_to_registry(mcu_cluster=RespondingTuyaMCUCluster)
83+
)
84+
85+
3686
(
3787
TuyaQuirkBuilder("_TZE200_yjjdcqsq", "TS0601")
3888
.applies_to("_TZE200_9yapgbuv", "TS0601")

0 commit comments

Comments
 (0)