diff --git a/tests/test_tuya_rain_zg223z.py b/tests/test_tuya_rain_zg223z.py new file mode 100644 index 0000000000..6f62022b25 --- /dev/null +++ b/tests/test_tuya_rain_zg223z.py @@ -0,0 +1,41 @@ +"""Test for Tuya ZG-223Z rain sensor.""" + +import pytest +from zigpy.zcl.clusters.security import IasZone + +from tests.common import ClusterListener +import zhaquirks + +zhaquirks.setup() + + +# DP 1: Rain detection (0 = no rain, 1 = raining) +ZCL_TUYA_RAIN_NONE = b"\t\x00\x02\x00\x00\x01\x04\x00\x01\x00" # DP 1, value 0 +ZCL_TUYA_RAIN_DETECTED = b"\t\x00\x02\x00\x00\x01\x04\x00\x01\x01" # DP 1, value 1 + + +@pytest.mark.parametrize( + "frame, rain_detected", + [ + (ZCL_TUYA_RAIN_NONE, False), + (ZCL_TUYA_RAIN_DETECTED, True), + ], +) +async def test_zg223z_rain_sensor_state_report( + zigpy_device_from_v2_quirk, frame, rain_detected +): + """Test HOBEIAN ZG-223Z rain sensor state reporting.""" + + rain_dev = zigpy_device_from_v2_quirk("_TZE200_jsaqgakf", "TS0601") + tuya_cluster = rain_dev.endpoints[1].tuya_manufacturer + ias_listener = ClusterListener(rain_dev.endpoints[1].ias_zone) + + hdr, args = tuya_cluster.deserialize(frame) + tuya_cluster.handle_message(hdr, args) + + assert len(ias_listener.cluster_commands) == 0 + assert len(ias_listener.attribute_updates) == 1 + assert ias_listener.attribute_updates[0][0] == IasZone.AttributeDefs.zone_status.id + assert ias_listener.attribute_updates[0][1] == ( + IasZone.ZoneStatus.Alarm_1 if rain_detected else 0 + ) diff --git a/zhaquirks/tuya/tuya_rain.py b/zhaquirks/tuya/tuya_rain.py index a040deff0d..bbebf62093 100644 --- a/zhaquirks/tuya/tuya_rain.py +++ b/zhaquirks/tuya/tuya_rain.py @@ -1,6 +1,11 @@ """Quirk for TS0207 rain sensors.""" -from zigpy.quirks.v2.homeassistant import LIGHT_LUX, EntityType, UnitOfElectricPotential +from zigpy.quirks.v2.homeassistant import ( + LIGHT_LUX, + EntityType, + UnitOfElectricPotential, + UnitOfTime, +) from zigpy.quirks.v2.homeassistant.binary_sensor import BinarySensorDeviceClass from zigpy.quirks.v2.homeassistant.sensor import SensorDeviceClass, SensorStateClass import zigpy.types as t @@ -87,3 +92,44 @@ class TuyaIasZone(IasZone, TuyaLocalCluster): .skip_configuration() .add_to_registry() ) + + +# HOBEIAN ZG-223Z Rainwater detection sensor +( + TuyaQuirkBuilder("_TZE200_jsaqgakf", "TS0601") + .applies_to("HOBEIAN", "ZG-223Z") + .applies_to("_TZE200_u6x1zyv2", "TS0601") + .applies_to("_TZE200_2pddnnrk", "TS0601") + .tuya_ias( + dp_id=1, + ias_cfg=TuyaIasZone, + converter=lambda x: IasZone.ZoneStatus.Alarm_1 if x == 1 else 0, + ) + .tuya_number( + dp_id=2, + attribute_name="sensitivity", + type=t.uint8_t, + min_value=0, + max_value=9, + step=1, + unit="x", + translation_key="sensitivity", + fallback_name="Sensitivity", + ) + .tuya_number( + dp_id=101, + attribute_name="illuminance_sampling", + type=t.uint16_t, + min_value=1, + max_value=480, + step=1, + unit=UnitOfTime.MINUTES, + translation_key="illuminance_sampling", + fallback_name="Illuminance sampling", + ) + .tuya_illuminance(dp_id=102) + .tuya_battery(dp_id=104) + .adds(TuyaIasZone) + .skip_configuration() + .add_to_registry() +)