Skip to content

Commit

Permalink
Add Tuya rain sensor _TZ3210_tgvtvdoc (#3656)
Browse files Browse the repository at this point in the history
Co-authored-by: TheJulianJES <TheJulianJES@users.noreply.github.com>
  • Loading branch information
prairiesnpr and TheJulianJES authored Feb 26, 2025
1 parent ff5bf0b commit e824f31
Show file tree
Hide file tree
Showing 2 changed files with 137 additions and 0 deletions.
44 changes: 44 additions & 0 deletions tests/test_tuya_rain.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"""Test for Tuya rain sensor."""

import pytest
from zigpy.zcl.clusters.security import IasZone

from tests.common import ClusterListener
import zhaquirks

zhaquirks.setup()


ZCL_TUYA_RAIN_MV_01 = b"\tp\x02\x00\x02i\x02\x00\x04\x00\x00\x00\x20" # 32mv
ZCL_TUYA_RAIN_MV_02 = b"\tp\x02\x00\x02i\x02\x00\x04\x00\x00\x01\xf4" # 500mv


@pytest.mark.parametrize(
"frame,value,rain_detected",
[(ZCL_TUYA_RAIN_MV_01, 32, False), (ZCL_TUYA_RAIN_MV_02, 500, True)],
)
async def test_rain_sensor_state_report(
zigpy_device_from_v2_quirk, frame, value, rain_detected
):
"""Test tuya rain sensor standard state reporting."""

rain_dev = zigpy_device_from_v2_quirk("_TZ3210_tgvtvdoc", "TS0207")
tuya_cluster = rain_dev.endpoints[1].tuya_manufacturer

ias_listener = ClusterListener(rain_dev.endpoints[1].ias_zone)
rain_listener = ClusterListener(tuya_cluster)

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
)

assert len(rain_listener.cluster_commands) == 1
assert len(rain_listener.attribute_updates) == 1
assert rain_listener.attribute_updates[0][0] == 0xEF69
assert rain_listener.attribute_updates[0][1] == value
93 changes: 93 additions & 0 deletions zhaquirks/tuya/tuya_rain.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
"""Quirk for TS0207 rain sensors."""

from zigpy.quirks.v2.homeassistant import LIGHT_LUX, EntityType, UnitOfElectricPotential
from zigpy.quirks.v2.homeassistant.binary_sensor import BinarySensorDeviceClass
from zigpy.quirks.v2.homeassistant.sensor import SensorDeviceClass, SensorStateClass
import zigpy.types as t
from zigpy.zcl.clusters.security import IasZone

from zhaquirks.tuya import (
TUYA_CLUSTER_ID,
BatterySize,
DPToAttributeMapping,
TuyaLocalCluster,
)
from zhaquirks.tuya.builder import TuyaQuirkBuilder
from zhaquirks.tuya.mcu import TuyaMCUCluster


class TuyaIasZone(IasZone, TuyaLocalCluster):
"""IAS Zone for rain sensors."""

_CONSTANT_ATTRIBUTES = {
IasZone.AttributeDefs.zone_type.id: IasZone.ZoneType.Water_Sensor
}


(
TuyaQuirkBuilder("_TZ3210_tgvtvdoc", "TS0207")
.tuya_battery(
dp_id=4, battery_type=BatterySize.Other, battery_qty=1, battery_voltage=30
)
.tuya_illuminance(dp_id=101)
.tuya_sensor(
dp_id=102,
attribute_name="average_light_intensity_20mins",
type=t.uint32_t,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.DURATION,
unit=LIGHT_LUX,
entity_type=EntityType.DIAGNOSTIC,
translation_key="average_light_intensity_20mins",
fallback_name="Average light intensity last 20 min",
)
.tuya_sensor(
dp_id=103,
attribute_name="todays_max_light_intensity",
type=t.uint32_t,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.DURATION,
unit=LIGHT_LUX,
entity_type=EntityType.DIAGNOSTIC,
translation_key="todays_max_light_intensity",
fallback_name="Today's max light intensity",
)
.tuya_binary_sensor(
dp_id=104,
attribute_name="cleaning_reminder",
device_class=BinarySensorDeviceClass.PROBLEM,
fallback_name="Cleaning reminder",
)
.tuya_dp_multi(
dp_id=105,
attribute_mapping=[
DPToAttributeMapping(
ep_attribute=TuyaIasZone.ep_attribute,
attribute_name=TuyaIasZone.AttributeDefs.zone_status.name,
converter=lambda x: IasZone.ZoneStatus.Alarm_1 if x > 100 else 0,
),
DPToAttributeMapping(
ep_attribute=TuyaMCUCluster.ep_attribute,
attribute_name="rain_intensity",
),
],
)
.tuya_attribute(
dp_id=105,
attribute_name="rain_intensity",
type=t.uint32_t,
is_manufacturer_specific=True,
)
.sensor(
"rain_intensity",
TUYA_CLUSTER_ID,
device_class=SensorDeviceClass.VOLTAGE,
state_class=SensorStateClass.MEASUREMENT,
unit=UnitOfElectricPotential.MILLIVOLT,
entity_type=EntityType.STANDARD,
fallback_name="Rain intensity",
)
.adds(TuyaIasZone)
.skip_configuration()
.add_to_registry()
)

0 comments on commit e824f31

Please sign in to comment.