Skip to content

Commit 81c43f5

Browse files
authored
Fix Tuya issue with LocalDataCluster._VALID_ATTRIBUTES (#3443)
* Convert `LocalDataCluster._VALID_ATTRIBUTES` to a set * Explicitly create instance variable in Tuya valid attribute generation * Add test confirming `_VALID_ATTRIBUTES` population for Tuya sensor
1 parent 8a68d5f commit 81c43f5

File tree

3 files changed

+32
-4
lines changed

3 files changed

+32
-4
lines changed

tests/test_tuya_sensor.py

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22

33
import pytest
44
from zigpy.zcl import foundation
5-
from zigpy.zcl.clusters.general import Basic
5+
from zigpy.zcl.clusters.general import Basic, PowerConfiguration
6+
from zigpy.zcl.clusters.measurement import RelativeHumidity, TemperatureMeasurement
67

78
import zhaquirks
8-
import zhaquirks.tuya
9+
from zhaquirks.tuya import TuyaLocalCluster
910
from zhaquirks.tuya.mcu import TuyaMCUCluster
1011

1112
zhaquirks.setup()
@@ -115,3 +116,26 @@ async def test_handle_get_data_enum_batt(
115116

116117
status = ep.tuya_manufacturer.handle_get_data(data.data)
117118
assert status == foundation.Status.UNSUPPORTED_ATTRIBUTE
119+
120+
121+
def test_valid_attributes(zigpy_device_from_v2_quirk):
122+
"""Test that valid attributes on virtual clusters are populated by Tuya datapoints mappings."""
123+
quirked = zigpy_device_from_v2_quirk("_TZE200_bjawzodf", "TS0601")
124+
ep = quirked.endpoints[1]
125+
126+
temperature_attr_id = TemperatureMeasurement.AttributeDefs.measured_value.id
127+
humidity_attr_id = RelativeHumidity.AttributeDefs.measured_value.id
128+
power_attr_id = PowerConfiguration.AttributeDefs.battery_percentage_remaining.id
129+
130+
temperature_cluster = ep.temperature
131+
humidity_cluster = ep.humidity
132+
power_config_cluster = ep.power
133+
134+
assert isinstance(temperature_cluster, TuyaLocalCluster)
135+
assert isinstance(humidity_cluster, TuyaLocalCluster)
136+
assert isinstance(power_config_cluster, TuyaLocalCluster)
137+
138+
# check that the virtual clusters have expected valid attributes
139+
assert {temperature_attr_id} == temperature_cluster._VALID_ATTRIBUTES
140+
assert {humidity_attr_id} == humidity_cluster._VALID_ATTRIBUTES
141+
assert {power_attr_id} == power_config_cluster._VALID_ATTRIBUTES

zhaquirks/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ class LocalDataCluster(CustomCluster):
6969
"""
7070

7171
_CONSTANT_ATTRIBUTES: dict[int, typing.Any] = {}
72-
_VALID_ATTRIBUTES: list[int] = []
72+
_VALID_ATTRIBUTES: set[int] = set()
7373

7474
async def bind(self):
7575
"""Prevent bind."""

zhaquirks/tuya/__init__.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1534,7 +1534,11 @@ def __init__(self, *args, **kwargs):
15341534
# mark mapped to attribute as valid if existing and if on a LocalDataCluster
15351535
attr = cluster.attributes_by_name.get(dp_map.attribute_name)
15361536
if attr and isinstance(cluster, LocalDataCluster):
1537-
cluster._VALID_ATTRIBUTES.append(attr.id)
1537+
# _VALID_ATTRIBUTES is only a class variable, but as want to modify it
1538+
# per instance here, we need to create an instance variable first
1539+
if "_VALID_ATTRIBUTES" not in cluster.__dict__:
1540+
cluster._VALID_ATTRIBUTES = set()
1541+
cluster._VALID_ATTRIBUTES.add(attr.id)
15381542

15391543
def handle_cluster_request(
15401544
self,

0 commit comments

Comments
 (0)