Skip to content

Commit 01e9e7e

Browse files
authored
Merge branch 'dev' into add-_TZE204_upagmta9
2 parents fa6e3c1 + b7f2bc7 commit 01e9e7e

File tree

2 files changed

+96
-4
lines changed

2 files changed

+96
-4
lines changed

tests/test_tuya_smoke.py

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,19 @@
1616
[
1717
("_TZE200_dq1mfjug", "TS0601", []),
1818
("_TZE200_m9skfctm", "TS0601", []),
19-
("_TZE200_ntcy3xu1", "TS0601", []),
2019
("_TZE200_rccxox8p", "TS0601", []),
2120
("_TZE284_rccxox8p", "TS0601", []),
2221
("_TZE200_vzekyi4c", "TS0601", []),
2322
("_TZE204_vawy74yh", "TS0601", []),
23+
(
24+
"_TZE200_ntcy3xu1",
25+
"TS0601",
26+
(
27+
(b"\x09\x3a\x02\x00\x12\x0e\x04\x00\x01\x02", 200),
28+
(b"\x09\x3a\x02\x00\x12\x0e\x04\x00\x01\x01", 80),
29+
(b"\x09\x3a\x02\x00\x12\x0e\x04\x00\x01\x00", 10),
30+
),
31+
),
2432
(
2533
"_TZE204_ntcy3xu1",
2634
"TS0601",
@@ -31,7 +39,6 @@
3139
),
3240
),
3341
("_TZE284_0zaf1cr8", "TS0601", []),
34-
("_TZ3210_up3pngle", "TS0205", []),
3542
],
3643
)
3744
async def test_handle_get_data(zigpy_device_from_v2_quirk, model, manuf, battery_test):
@@ -80,3 +87,32 @@ async def test_handle_get_data(zigpy_device_from_v2_quirk, model, manuf, battery
8087

8188
assert len(power_listener.attribute_updates) == 1
8289
assert power_listener.attribute_updates[0][1] == state
90+
91+
92+
async def test_tuya_smoke_sensor_attribute_update(zigpy_device_from_v2_quirk):
93+
"""Test update_attribute on Tuya smoke sensor."""
94+
95+
device = zigpy_device_from_v2_quirk("_TZ3210_up3pngle", "TS0205")
96+
97+
tuya_cluster = device.endpoints[1].tuya_manufacturer
98+
tuya_listener = ClusterListener(tuya_cluster)
99+
100+
ias_cluster = device.endpoints[1].ias_zone
101+
ias_listener = ClusterListener(ias_cluster)
102+
103+
zone_status_id = IasZone.AttributeDefs.zone_status.id
104+
105+
# check that updating smoke attribute also updates zone status on the Ias Zone cluster
106+
107+
# turn on smoke alarm
108+
tuya_cluster.update_attribute(0x0401, 1)
109+
assert len(tuya_listener.attribute_updates) == 1
110+
assert len(ias_listener.attribute_updates) == 1
111+
assert ias_listener.attribute_updates[0][0] == zone_status_id
112+
assert ias_listener.attribute_updates[0][1] == 0
113+
# turn off smoke alarm
114+
tuya_cluster.update_attribute(0x0401, 0)
115+
assert len(tuya_listener.attribute_updates) == 2
116+
assert len(ias_listener.attribute_updates) == 2
117+
assert ias_listener.attribute_updates[1][0] == zone_status_id
118+
assert ias_listener.attribute_updates[1][1] == IasZone.ZoneStatus.Alarm_1

zhaquirks/tuya/tuya_smoke.py

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,82 @@
11
"""Smoke Sensor."""
22

3+
from zigpy.quirks.v2 import EntityType, QuirkBuilder
4+
from zigpy.quirks.v2.homeassistant.binary_sensor import BinarySensorDeviceClass
5+
import zigpy.types as t
6+
from zigpy.zcl.clusters.general import OnOff, Time
7+
from zigpy.zcl.clusters.lightlink import LightLink
8+
from zigpy.zcl.clusters.security import IasZone
9+
from zigpy.zcl.foundation import BaseAttributeDefs, ZCLAttributeDef
10+
11+
from zhaquirks import LocalDataCluster
12+
from zhaquirks.tuya import TuyaManufClusterAttributes
313
from zhaquirks.tuya.builder import TuyaPowerConfigurationCluster2AAA, TuyaQuirkBuilder
414

15+
16+
class TuyaIasZone(LocalDataCluster, IasZone):
17+
"""IAS Zone."""
18+
19+
_CONSTANT_ATTRIBUTES = {
20+
IasZone.AttributeDefs.zone_type.id: IasZone.ZoneType.Fire_Sensor
21+
}
22+
23+
24+
class TuyaSmokeDetectorCluster(TuyaManufClusterAttributes):
25+
"""Manufacturer Specific Cluster of the TS0205 smoke detector."""
26+
27+
class AttributeDefs(BaseAttributeDefs):
28+
"""Attribute definitions."""
29+
30+
smoke_detected = ZCLAttributeDef(
31+
id=0x0401, # [0]/[1] [Detected]/[Clear]
32+
type=t.uint8_t,
33+
is_manufacturer_specific=True,
34+
)
35+
36+
def _update_attribute(self, attrid, value):
37+
super()._update_attribute(attrid, value)
38+
if attrid == self.AttributeDefs.smoke_detected.id:
39+
self.endpoint.ias_zone.update_attribute(
40+
IasZone.AttributeDefs.zone_status.id,
41+
IasZone.ZoneStatus.Alarm_1 if value == 0 else 0,
42+
)
43+
44+
45+
(
46+
QuirkBuilder("_TZ3210_up3pngle", "TS0205")
47+
.removes(LightLink.cluster_id)
48+
.removes(OnOff.cluster_id)
49+
.removes(Time.cluster_id)
50+
.replaces(TuyaIasZone)
51+
.replaces(TuyaSmokeDetectorCluster)
52+
.add_to_registry()
53+
)
54+
555
(
656
TuyaQuirkBuilder("_TZE200_aycxwiau", "TS0601")
757
.applies_to("_TZE200_dq1mfjug", "TS0601")
858
.applies_to("_TZE200_m9skfctm", "TS0601")
9-
.applies_to("_TZE200_ntcy3xu1", "TS0601")
1059
.applies_to("_TZE200_rccxox8p", "TS0601")
1160
.applies_to("_TZE284_rccxox8p", "TS0601")
1261
.applies_to("_TZE200_vzekyi4c", "TS0601")
1362
.applies_to("_TZE204_vawy74yh", "TS0601")
1463
.applies_to("_TZE284_0zaf1cr8", "TS0601")
15-
.applies_to("_TZ3210_up3pngle", "TS0205")
1664
.tuya_smoke(dp_id=1)
1765
.skip_configuration()
1866
.add_to_registry()
1967
)
2068

2169
(
2270
TuyaQuirkBuilder("_TZE204_ntcy3xu1", "TS0601")
71+
.applies_to("_TZE200_ntcy3xu1", "TS0601")
2372
.tuya_smoke(dp_id=1)
73+
.tuya_binary_sensor(
74+
dp_id=4,
75+
attribute_name="tamper",
76+
device_class=BinarySensorDeviceClass.TAMPER,
77+
entity_type=EntityType.DIAGNOSTIC,
78+
fallback_name="Tamper",
79+
)
2480
.tuya_dp(
2581
dp_id=14,
2682
ep_attribute=TuyaPowerConfigurationCluster2AAA.ep_attribute,

0 commit comments

Comments
 (0)