diff --git a/tests/test_tuya.py b/tests/test_tuya.py index 3921b3ad43..5ff64ba8b2 100644 --- a/tests/test_tuya.py +++ b/tests/test_tuya.py @@ -1690,72 +1690,6 @@ def test_multiple_attributes_report(): assert data.data.datapoints[3].dp == 9 -@pytest.mark.parametrize( - "quirk", (zhaquirks.tuya.ts0601_sensor.TuyaTempHumiditySensor,) -) -async def test_handle_get_data(zigpy_device_from_quirk, quirk): - """Test handle_get_data for multiple attributes.""" - - ts0601_sensor = zigpy_device_from_quirk(quirk) - tuya_cluster = ts0601_sensor.endpoints[1].tuya_manufacturer - - message = b"\x09\xe0\x02\x0b\x33\x01\x02\x00\x04\x00\x00\x00\xfd\x02\x02\x00\x04\x00\x00\x00\x47\x04\x02\x00\x04\x00\x00\x00\x64" - hdr, data = tuya_cluster.deserialize(message) - - status = tuya_cluster.handle_get_data(data.data) - assert status == foundation.Status.SUCCESS - - message = b"\x09\xe0\x02\x0b\x33\x01\x02\x00\x04\x00\x00\x00\xfd\x02\x02\x00\x04\x00\x00\x00\x47\xff\x02\x00\x04\x00\x00\x00\x64" - hdr, data = tuya_cluster.deserialize(message) - - status = tuya_cluster.handle_get_data(data.data) - assert status == foundation.Status.UNSUPPORTED_ATTRIBUTE - - -@pytest.mark.parametrize( - "quirk", - (zhaquirks.tuya.ts0601_sensor.TuyaTempHumiditySensor,), -) -@pytest.mark.parametrize( - "quirk_sq", (zhaquirks.tuya.ts0601_sensor.TuyaTempHumiditySensor_Square,) -) -async def test_rh_multiplier(zigpy_device_from_quirk, quirk, quirk_sq): - """Test handle_get_data for multiple attributes.""" - - round_sensor = zigpy_device_from_quirk(quirk) - round_cluster = round_sensor.endpoints[1].tuya_manufacturer - round_humidity = round_sensor.endpoints[1].humidity - - square_sensor = zigpy_device_from_quirk(quirk_sq) - square_cluster = square_sensor.endpoints[1].tuya_manufacturer - square_humidity = square_sensor.endpoints[1].humidity - - message = b"\x19\x84\x01\x00\xa5\x02\x02\x00\x04\x00\x00\x02\x2c" - - hdr, round_data = round_cluster.deserialize(message) - hdr, square_data = square_cluster.deserialize(message) - - round_status = round_cluster.handle_get_data(round_data.data) - assert round_status == foundation.Status.SUCCESS - - square_status = square_cluster.handle_get_data(square_data.data) - assert square_status == foundation.Status.SUCCESS - - assert ( - round_data.data.datapoints[0].data.payload - == square_data.data.datapoints[0].data.payload - ) - - assert ( - round_humidity.get("measured_value") - == round_data.data.datapoints[0].data.payload * round_sensor.RH_MULTIPLIER - ) - assert ( - square_humidity.get("measured_value") - == square_data.data.datapoints[0].data.payload * 100 - ) # no square_sensor.RH_MULTIPLIER attribute - - @mock.patch("zigpy.zcl.Cluster.bind", mock.AsyncMock()) @pytest.mark.parametrize( "quirk", diff --git a/tests/test_tuya_sensor.py b/tests/test_tuya_sensor.py new file mode 100644 index 0000000000..0a15bf1beb --- /dev/null +++ b/tests/test_tuya_sensor.py @@ -0,0 +1,117 @@ +"""Tests for Tuya Sensor quirks.""" + +import pytest +from zigpy.zcl import foundation +from zigpy.zcl.clusters.general import Basic + +import zhaquirks +import zhaquirks.tuya +from zhaquirks.tuya.mcu import TuyaMCUCluster + +zhaquirks.setup() + + +@pytest.mark.parametrize( + "model,manuf,rh_scale,temp_scale", + [ + ("_TZE200_bjawzodf", "TS0601", 10, 10), + ("_TZE200_zl1kmjqx", "TS0601", 10, 10), + ("_TZE200_a8sdabtg", "TS0601", 100, 10), # Variant without screen, round + ("_TZE200_qoy0ekbd", "TS0601", 100, 10), + ("_TZE200_znbl8dj5", "TS0601", 100, 10), + ("_TZE200_qyflbnbj", "TS0601", 100, 10), + ("_TZE200_zppcgbdj", "TS0601", 100, 10), + ], +) +async def test_handle_get_data( + zigpy_device_from_v2_quirk, model, manuf, rh_scale, temp_scale +): + """Test handle_get_data for multiple attributes - normal battery.""" + + quirked = zigpy_device_from_v2_quirk(model, manuf) + ep = quirked.endpoints[1] + + assert ep.basic is not None + assert isinstance(ep.basic, Basic) + + assert ep.tuya_manufacturer is not None + assert isinstance(ep.tuya_manufacturer, TuyaMCUCluster) + + message = b"\x09\xe0\x02\x0b\x33\x01\x02\x00\x04\x00\x00\x00\xfd\x02\x02\x00\x04\x00\x00\x00\x47\x04\x02\x00\x04\x00\x00\x00\x64" + hdr, data = ep.tuya_manufacturer.deserialize(message) + + status = ep.tuya_manufacturer.handle_get_data(data.data) + assert status == foundation.Status.SUCCESS + + assert ( + ep.temperature.get("measured_value") + == data.data.datapoints[0].data.payload * temp_scale + ) + + assert ( + ep.humidity.get("measured_value") + == data.data.datapoints[1].data.payload * rh_scale + ) + + assert ( + ep.power.get("battery_percentage_remaining") + == data.data.datapoints[2].data.payload * 2 + ) + + message = b"\x09\xe0\x02\x0b\x33\x01\x02\x00\x04\x00\x00\x00\xfd\x02\x02\x00\x04\x00\x00\x00\x47\xff\x02\x00\x04\x00\x00\x00\x64" + hdr, data = ep.tuya_manufacturer.deserialize(message) + + status = ep.tuya_manufacturer.handle_get_data(data.data) + assert status == foundation.Status.UNSUPPORTED_ATTRIBUTE + + +@pytest.mark.parametrize( + "model,manuf,rh_scale,temp_scale", + [ + ("_TZE200_yjjdcqsq", "TS0601", 100, 10), + ("_TZE200_9yapgbuv", "TS0601", 100, 10), + ("_TZE204_yjjdcqsq", "TS0601", 100, 10), + ("_TZE200_utkemkbs", "TS0601", 100, 10), + ("_TZE204_utkemkbs", "TS0601", 100, 10), + ("_TZE204_yjjdcqsq", "TS0601", 100, 10), + ("_TZE204_ksz749x8", "TS0601", 100, 10), + ], +) +async def test_handle_get_data_enum_batt( + zigpy_device_from_v2_quirk, model, manuf, rh_scale, temp_scale +): + """Test handle_get_data for multiple attributes - enum battery.""" + + quirked = zigpy_device_from_v2_quirk(model, manuf) + ep = quirked.endpoints[1] + + assert ep.basic is not None + assert isinstance(ep.basic, Basic) + + assert ep.tuya_manufacturer is not None + assert isinstance(ep.tuya_manufacturer, TuyaMCUCluster) + + message = b"\x09\xe0\x02\x0b\x33\x01\x02\x00\x04\x00\x00\x00\xfd\x02\x02\x00\x04\x00\x00\x00\x47\x04\x02\x00\x04\x00\x00\x00\x01" + hdr, data = ep.tuya_manufacturer.deserialize(message) + + status = ep.tuya_manufacturer.handle_get_data(data.data) + + assert status == foundation.Status.SUCCESS + + assert ( + ep.temperature.get("measured_value") + == data.data.datapoints[0].data.payload * temp_scale + ) + + assert ( + ep.humidity.get("measured_value") + == data.data.datapoints[1].data.payload * rh_scale + ) + + assert ep.power.get("battery_percentage_remaining") == 100 + + message = b"\x09\xe0\x02\x0b\x33\x01\x02\x00\x04\x00\x00\x00\xfd\x02\x02\x00\x04\x00\x00\x00\x47\xff\x02\x00\x04\x00\x00\x00\x64" + hdr, data = ep.tuya_manufacturer.deserialize(message) + + status = ep.tuya_manufacturer.handle_get_data(data.data) + assert status == foundation.Status.UNSUPPORTED_ATTRIBUTE diff --git a/zhaquirks/tuya/ts0601_sensor.py b/zhaquirks/tuya/ts0601_sensor.py index 86dfdb5eeb..f4a5be519f 100644 --- a/zhaquirks/tuya/ts0601_sensor.py +++ b/zhaquirks/tuya/ts0601_sensor.py @@ -1,487 +1,72 @@ """Tuya temp and humidity sensors.""" -from typing import Any - -from zigpy.profiles import zha -from zigpy.quirks import CustomDevice -from zigpy.zcl.clusters.general import Basic, Groups, Ota, Scenes, Time -from zigpy.zcl.clusters.measurement import ( - RelativeHumidity, - SoilMoisture, - TemperatureMeasurement, +from zhaquirks.tuya.builder import TuyaPowerConfigurationCluster2AAA, TuyaQuirkBuilder + +( + TuyaQuirkBuilder("_TZE200_bjawzodf", "TS0601") + .applies_to("_TZE200_zl1kmjqx", "TS0601") + .tuya_temperature(dp_id=1, scale=10) + .tuya_humidity(dp_id=2, scale=10) + .tuya_battery(dp_id=4) + .skip_configuration() + .add_to_registry() ) -from zhaquirks.const import ( - DEVICE_TYPE, - ENDPOINTS, - INPUT_CLUSTERS, - MODELS_INFO, - OUTPUT_CLUSTERS, - PROFILE_ID, - SKIP_CONFIGURATION, +( + TuyaQuirkBuilder("_TZE200_a8sdabtg", "TS0601") # Variant without screen, round + .applies_to("_TZE200_qoy0ekbd", "TS0601") + .applies_to("_TZE200_znbl8dj5", "TS0601") + .applies_to("_TZE200_qyflbnbj", "TS0601") + .applies_to("_TZE200_zppcgbdj", "TS0601") + .tuya_temperature(dp_id=1, scale=10) + .tuya_humidity(dp_id=2) + .tuya_battery(dp_id=4) + .skip_configuration() + .add_to_registry() ) -from zhaquirks.tuya import TuyaLocalCluster, TuyaPowerConfigurationCluster2AAA -from zhaquirks.tuya.mcu import DPToAttributeMapping, TuyaMCUCluster - - -class TuyaTemperatureMeasurement(TemperatureMeasurement, TuyaLocalCluster): - """Tuya local TemperatureMeasurement cluster.""" - - -class TuyaSoilMoisture(SoilMoisture, TuyaLocalCluster): - """Tuya local SoilMoisture cluster with a device RH_MULTIPLIER factor if required.""" - - -class TuyaRelativeHumidity(RelativeHumidity, TuyaLocalCluster): - """Tuya local RelativeHumidity cluster with a device RH_MULTIPLIER factor.""" - - def update_attribute(self, attr_name: str, value: Any) -> None: - """Apply a correction factor to value.""" - - if attr_name == "measured_value": - value = value * ( - self.endpoint.device.RH_MULTIPLIER - if hasattr(self.endpoint.device, "RH_MULTIPLIER") - else 100 - ) - return super().update_attribute(attr_name, value) - - -class TemperatureHumidityManufCluster(TuyaMCUCluster): - """Tuya Manufacturer Cluster with Temperature and Humidity data points.""" - - dp_to_attribute: dict[int, DPToAttributeMapping] = { - 1: DPToAttributeMapping( - TuyaTemperatureMeasurement.ep_attribute, - "measured_value", - converter=lambda x: x * 10, # decidegree to centidegree - ), - 2: DPToAttributeMapping( - TuyaRelativeHumidity.ep_attribute, - "measured_value", - # converter=lambda x: x * 10, --> move conversion to TuyaRelativeHumidity cluster - ), - 4: DPToAttributeMapping( - TuyaPowerConfigurationCluster2AAA.ep_attribute, - "battery_percentage_remaining", - converter=lambda x: x * 2, # double reported percentage - ), - } - - data_point_handlers = { - 1: "_dp_2_attr_update", - 2: "_dp_2_attr_update", - 4: "_dp_2_attr_update", - } - - -class TemperatureHumidityBatteryStatesManufCluster(TuyaMCUCluster): - """Tuya Manufacturer Cluster with Temperature and Humidity data points. Battery states 25, 50 and 100%.""" - - dp_to_attribute: dict[int, DPToAttributeMapping] = { - 1: TemperatureHumidityManufCluster.dp_to_attribute[1], - 2: TemperatureHumidityManufCluster.dp_to_attribute[2], - 3: DPToAttributeMapping( - TuyaPowerConfigurationCluster2AAA.ep_attribute, - "battery_percentage_remaining", - converter=lambda x: {0: 50, 1: 100, 2: 200}[x], - ), - } - - data_point_handlers = { - 1: "_dp_2_attr_update", - 2: "_dp_2_attr_update", - 3: "_dp_2_attr_update", - } - - -class TuyaTempHumiditySensor(CustomDevice): - """Custom device representing tuya temp and humidity sensor with e-ink screen.""" - - # RelativeHumidity multiplier - RH_MULTIPLIER = 10 - - signature = { - # - MODELS_INFO: [ - ("_TZE200_bjawzodf", "TS0601"), - ("_TZE200_zl1kmjqx", "TS0601"), - ], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.SMART_PLUG, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - TemperatureHumidityManufCluster.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id, Time.cluster_id], - } - }, - } - - replacement = { - SKIP_CONFIGURATION: True, - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.TEMPERATURE_SENSOR, - INPUT_CLUSTERS: [ - TemperatureHumidityManufCluster, # Single bus for temp, humidity, and battery - TuyaTemperatureMeasurement, - TuyaRelativeHumidity, - TuyaPowerConfigurationCluster2AAA, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id, Time.cluster_id], - } - }, - } - - -class TuyaTempHumiditySensorVar02(CustomDevice): - """Custom device representing tuya temp and humidity sensor with e-ink screen.""" - - signature = { - # - MODELS_INFO: [ - ("_TZE200_zppcgbdj", "TS0601"), # Conecto TH - ], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.SMART_PLUG, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - TemperatureHumidityManufCluster.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id, Time.cluster_id], - } - }, - } - - replacement = { - SKIP_CONFIGURATION: True, - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.TEMPERATURE_SENSOR, - INPUT_CLUSTERS: [ - TemperatureHumidityManufCluster, # Single bus for temp, humidity, and battery - TuyaTemperatureMeasurement, - TuyaRelativeHumidity, - TuyaPowerConfigurationCluster2AAA, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id, Time.cluster_id], - } - }, - } -class TuyaTempHumiditySensor_Square(CustomDevice): - """Custom device representing tuya temp and humidity sensor with e-ink screen.""" - - # RelativeHumidity multiplier - # RH_MULTIPLIER = 100 - - signature = { - MODELS_INFO: [ - ("_TZE200_a8sdabtg", "TS0601"), # Variant without screen, round - ("_TZE200_qoy0ekbd", "TS0601"), - ("_TZE200_znbl8dj5", "TS0601"), - ], - ENDPOINTS: { - 1: { - # "profile_id": 260, "device_type": "0x0302", - # "in_clusters": ["0x0000","0x0001","0x0402","0x0405"], - # "out_clusters": ["0x000a","0x0019"] - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.TEMPERATURE_SENSOR, - INPUT_CLUSTERS: [ - Basic.cluster_id, - TuyaPowerConfigurationCluster2AAA.cluster_id, - TemperatureMeasurement.cluster_id, - RelativeHumidity.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id, Time.cluster_id], - } - }, - } - - replacement = { - SKIP_CONFIGURATION: True, - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.TEMPERATURE_SENSOR, - INPUT_CLUSTERS: [ - Basic.cluster_id, - TuyaPowerConfigurationCluster2AAA, - TemperatureHumidityManufCluster, - TuyaTemperatureMeasurement, - TuyaRelativeHumidity, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id, Time.cluster_id], - } - }, - } - - -class TuyaTempHumiditySensorVar03(CustomDevice): - """Tuya temp and humidity sensor (variation 03).""" - - signature = { - # "profile_id": 260, - # "device_type": "0x0051", - # "in_clusters": ["0x0000","0x0004","0x0005","0xef00"], - # "out_clusters": ["0x000a","0x0019"] - MODELS_INFO: [ - ("_TZE200_qyflbnbj", "TS0601"), - ], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.SMART_PLUG, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - TemperatureHumidityManufCluster.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id, Time.cluster_id], - } - }, - } - - replacement = { - SKIP_CONFIGURATION: True, - ENDPOINTS: { - 1: { - DEVICE_TYPE: zha.DeviceType.TEMPERATURE_SENSOR, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - TemperatureHumidityManufCluster, - TuyaTemperatureMeasurement, - TuyaRelativeHumidity, - TuyaPowerConfigurationCluster2AAA, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id, Time.cluster_id], - } - }, - } - - -class TuyaTempHumiditySensorVar04(CustomDevice): - """Tuya temp and humidity sensor (variation 04).""" - - signature = { - # "profile_id": 260, - # "device_type": "0x0051", - # "in_clusters": ["0x0000","0x0004","0x0005","0xef00"], - # "out_clusters": ["0x000a","0x0019"] - MODELS_INFO: [ - ("_TZE200_yjjdcqsq", "TS0601"), - ("_TZE200_9yapgbuv", "TS0601"), - ("_TZE204_yjjdcqsq", "TS0601"), - ("_TZE200_utkemkbs", "TS0601"), - ("_TZE204_utkemkbs", "TS0601"), - ("_TZE204_yjjdcqsq", "TS0601"), - ("_TZE204_ksz749x8", "TS0601"), - ], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.SMART_PLUG, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - TemperatureHumidityManufCluster.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id, Time.cluster_id], - } - }, - } - - replacement = { - SKIP_CONFIGURATION: True, - ENDPOINTS: { - 1: { - DEVICE_TYPE: zha.DeviceType.TEMPERATURE_SENSOR, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - TemperatureHumidityBatteryStatesManufCluster, - TuyaTemperatureMeasurement, - TuyaRelativeHumidity, - TuyaPowerConfigurationCluster2AAA, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id, Time.cluster_id], - } - }, - } - - -class SoilManufCluster(TuyaMCUCluster): - """Tuya Manufacturer Cluster with Temperature and Humidity data points.""" - - dp_to_attribute: dict[int, DPToAttributeMapping] = { - 5: DPToAttributeMapping( - TuyaTemperatureMeasurement.ep_attribute, - "measured_value", - converter=lambda x: x * 100, - ), - 3: DPToAttributeMapping( - TuyaSoilMoisture.ep_attribute, - "measured_value", - converter=lambda x: x * 100, - ), - 15: DPToAttributeMapping( - TuyaPowerConfigurationCluster2AAA.ep_attribute, - "battery_percentage_remaining", - converter=lambda x: x * 2, # double reported percentage - ), - } - - data_point_handlers = { - 3: "_dp_2_attr_update", - 5: "_dp_2_attr_update", - 15: "_dp_2_attr_update", - } - - -class TuyaSoilSensor(CustomDevice): - """Tuya temp and humidity sensor (variation 03).""" - - signature = { - # "profile_id": 260, - # "device_type": "0x0051", - # "in_clusters": ["0x0000","0x0004","0x0005","0xef00"], - # "out_clusters": ["0x000a","0x0019"] - MODELS_INFO: [ - ("_TZE200_myd45weu", "TS0601"), - ("_TZE200_ga1maeof", "TS0601"), - ("_TZE200_9cqcpkgb", "TS0601"), - ("_TZE204_myd45weu", "TS0601"), - ], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.SMART_PLUG, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - TemperatureHumidityManufCluster.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id, Time.cluster_id], - } - }, - } - - replacement = { - SKIP_CONFIGURATION: True, - ENDPOINTS: { - 1: { - DEVICE_TYPE: zha.DeviceType.TEMPERATURE_SENSOR, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - SoilManufCluster, - TuyaTemperatureMeasurement, - TuyaSoilMoisture, - TuyaPowerConfigurationCluster2AAA, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id, Time.cluster_id], - } - }, - } - - -class SoilManufClusterVar02(TuyaMCUCluster): - """Tuya Manufacturer Cluster with Temperature and Humidity data points (variation 02).""" - - dp_to_attribute: dict[int, DPToAttributeMapping] = { - 5: DPToAttributeMapping( - TuyaTemperatureMeasurement.ep_attribute, - "measured_value", - converter=lambda x: x * 10, - ), - 3: DPToAttributeMapping( - TuyaSoilMoisture.ep_attribute, - "measured_value", - converter=lambda x: x * 100, - ), - 15: DPToAttributeMapping( - TuyaPowerConfigurationCluster2AAA.ep_attribute, - "battery_percentage_remaining", - converter=lambda x: x * 2, # double reported percentage - ), - } - - data_point_handlers = { - 3: "_dp_2_attr_update", - 5: "_dp_2_attr_update", - 15: "_dp_2_attr_update", - } +( + TuyaQuirkBuilder("_TZE200_yjjdcqsq", "TS0601") + .applies_to("_TZE200_9yapgbuv", "TS0601") + .applies_to("_TZE204_yjjdcqsq", "TS0601") + .applies_to("_TZE200_utkemkbs", "TS0601") + .applies_to("_TZE204_utkemkbs", "TS0601") + .applies_to("_TZE204_yjjdcqsq", "TS0601") + .applies_to("_TZE204_ksz749x8", "TS0601") + .tuya_temperature(dp_id=1, scale=10) + .tuya_humidity(dp_id=2) + .tuya_dp( + dp_id=4, + ep_attribute=TuyaPowerConfigurationCluster2AAA.ep_attribute, + attribute_name="battery_percentage_remaining", + converter=lambda x: {0: 50, 1: 100, 2: 200}[x], + ) + .adds(TuyaPowerConfigurationCluster2AAA) + .skip_configuration() + .add_to_registry() +) -class TuyaSoilSensorVar02(CustomDevice): - """Tuya temp and humidity sensor (variation 05).""" +( + TuyaQuirkBuilder("_TZE284_aao3yzhs", "TS0601") + .applies_to("_TZE284_sgabhwa6", "TS0601") + .tuya_temperature(dp_id=5, scale=10) + .tuya_battery(dp_id=15) + .tuya_soil_moisture(dp_id=3) + .skip_configuration() + .add_to_registry() +) - signature = { - # "profile_id": 260, - # "device_type": "0x0051", - # "in_clusters": ["0x0000","0x0004","0x0005","0xed00","0xef00"], - # "out_clusters": ["0x000a","0x0019"] - MODELS_INFO: [ - ("_TZE284_aao3yzhs", "TS0601"), - ("_TZE284_sgabhwa6", "TS0601"), - ], - ENDPOINTS: { - 1: { - PROFILE_ID: zha.PROFILE_ID, - DEVICE_TYPE: zha.DeviceType.SMART_PLUG, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - 0xED00, - TemperatureHumidityManufCluster.cluster_id, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id, Time.cluster_id], - } - }, - } - replacement = { - SKIP_CONFIGURATION: True, - ENDPOINTS: { - 1: { - DEVICE_TYPE: zha.DeviceType.TEMPERATURE_SENSOR, - INPUT_CLUSTERS: [ - Basic.cluster_id, - Groups.cluster_id, - Scenes.cluster_id, - SoilManufClusterVar02, - TuyaTemperatureMeasurement, - TuyaSoilMoisture, - TuyaPowerConfigurationCluster2AAA, - ], - OUTPUT_CLUSTERS: [Ota.cluster_id, Time.cluster_id], - } - }, - } +( + TuyaQuirkBuilder("_TZE200_myd45weu", "TS0601") + .applies_to("_TZE200_ga1maeof", "TS0601") + .applies_to("_TZE200_9cqcpkgb", "TS0601") + .applies_to("_TZE204_myd45weu", "TS0601") + .tuya_temperature(dp_id=5) + .tuya_battery(dp_id=15) + .tuya_soil_moisture(dp_id=3) + .skip_configuration() + .add_to_registry() +)