Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions tests/test_tuya_clusters.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import pytest
import zigpy.types as t
from zigpy.zcl.clusters.general import OnOff
import zigpy.zcl.foundation as zcl_f

from zhaquirks.tuya import (
Expand All @@ -15,6 +16,8 @@
TuyaData,
TuyaDatapointData,
TuyaNewManufCluster,
TuyaSwitchModeSelectEntity,
TuyaZBOnOffAttributeCluster,
)


Expand Down Expand Up @@ -291,3 +294,46 @@ def test_tuya_cluster_request_no_handler(default_rsp_mock, TuyaCluster):

assert default_rsp_mock.call_count == 1
assert default_rsp_mock.call_args[1]["status"] == zcl_f.Status.UNSUP_CLUSTER_COMMAND


def _switch_mode_select_entity(zigpy_device_mock, cluster_cls, cluster_id):
"""Build a TuyaSwitchModeSelectEntity backed by the given cluster class."""
device = zigpy_device_mock()
endpoint = device.add_endpoint(1)
cluster = endpoint.add_input_cluster(cluster_id, cluster_cls(endpoint))

fake_endpoint = mock.MagicMock()
fake_endpoint.id = endpoint.endpoint_id
fake_device = mock.MagicMock()
fake_device.ieee = device.ieee

return TuyaSwitchModeSelectEntity(fake_endpoint, fake_device, cluster=cluster)


def test_tuya_switch_mode_select_entity_wrong_cluster(zigpy_device_mock):
"""Entity is not supported when the backing cluster isn't the Tuya one."""
entity = _switch_mode_select_entity(zigpy_device_mock, OnOff, OnOff.cluster_id)
assert entity._is_supported() is False


def test_tuya_switch_mode_select_entity_no_cached_value(zigpy_device_mock):
"""Entity is not supported until the switch_mode attribute has a cached value."""
entity = _switch_mode_select_entity(
zigpy_device_mock,
TuyaZBOnOffAttributeCluster,
TuyaZBOnOffAttributeCluster.cluster_id,
)
assert entity._is_supported() is False


def test_tuya_switch_mode_select_entity_supported(zigpy_device_mock):
"""Entity is supported once the switch_mode attribute is cached."""
entity = _switch_mode_select_entity(
zigpy_device_mock,
TuyaZBOnOffAttributeCluster,
TuyaZBOnOffAttributeCluster.cluster_id,
)
entity.cluster.update_attribute(
TuyaZBOnOffAttributeCluster.AttributeDefs.switch_mode.name, 0
)
assert entity._is_supported() is True
34 changes: 34 additions & 0 deletions zhaquirks/tuya/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@
import logging
from typing import Any, Final

from zha.application.platforms import (
AttrConfig,
ClusterConfig,
ClusterMatch,
register_entity,
select,
)
import zigpy.types as t
from zigpy.typing import UNDEFINED, AddressingMode, UndefinedType
from zigpy.zcl import BaseAttributeDefs, foundation
Expand Down Expand Up @@ -1760,3 +1767,30 @@ def _dp_2_attr_update(self, datapoint: TuyaDatapointData) -> None:
| value.value
)
cluster.update_attribute(mapped_attr.attribute_name, value)


@register_entity(TuyaZBOnOffAttributeCluster.cluster_id)
class TuyaSwitchModeSelectEntity(select.ZCLEnumSelectEntity):
"""Representation of a ZHA backlight mode select entity."""

_unique_id_suffix = "switch_mode"
_attribute_name = "switch_mode"
_enum = SwitchMode
_attr_translation_key: str = "switch_mode"

_cluster_match = ClusterMatch(
server_clusters=frozenset({TuyaZBOnOffAttributeCluster.cluster_id}),
)

_server_cluster_config = {
TuyaZBOnOffAttributeCluster.cluster_id: ClusterConfig(
attributes={
"switch_mode": AttrConfig(read_on_startup=False),
},
),
}

def _is_supported(self) -> bool:
if not isinstance(self.cluster, TuyaZBOnOffAttributeCluster):
return False
return super()._is_supported()
3 changes: 3 additions & 0 deletions zhaquirks/tuya/ts004f.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
TuyaNoBindPowerConfigurationCluster,
TuyaSmartRemoteOnOffCluster,
TuyaZBExternalSwitchTypeCluster,
TuyaZBOnOffAttributeCluster,
)


Expand Down Expand Up @@ -116,6 +117,7 @@ class TuyaSmartRemote004FROK(EnchantedDevice):
TuyaNoBindPowerConfigurationCluster,
Identify.cluster_id,
Groups.cluster_id, # Is needed for adding group then binding is not working.
TuyaZBOnOffAttributeCluster,
LightLink.cluster_id,
],
OUTPUT_CLUSTERS: [
Expand Down Expand Up @@ -367,6 +369,7 @@ class TuyaSmartRemote004FSK(EnchantedDevice):
TuyaNoBindPowerConfigurationCluster,
Identify.cluster_id,
Groups.cluster_id, # Is needed for adding group then binding is not working.
TuyaZBOnOffAttributeCluster,
LightLink.cluster_id,
TuyaZBExternalSwitchTypeCluster,
],
Expand Down
Loading