-
Notifications
You must be signed in to change notification settings - Fork 960
Labels
device support requestThis requests support for a new deviceThis requests support for a new device
Description
Problem description
I have a TS0601 soil plant sensor which has temperature, humidity , light and moisture sensors. It does look similar to a few Tuya quirks , however i haven't had much luck with allowing home assistant to pickup the quirk as it refuses to apply the quirk
Solution description
I would love some assistance in modifying an existing quirk as i believe there are a few sensors similar. I've tried a few TS0601 PR's (which appear to be V1) and also a V2 quirk. I'm very confused now so would love a push in the right direction.
Screenshots/Video
Screenshots/Video
[Paste/upload your media here]
Diagnostics information
zha-ac9fd73a469166aa43c3a544f7d67577-_TZE284_o9ofysmo TS0601-84991943dd07d72ef0cec37689a57199.json
Device signature
Device signature
{
"node_descriptor": {
"logical_type": 2,
"complex_descriptor_available": 0,
"user_descriptor_available": 0,
"reserved": 0,
"aps_flags": 0,
"frequency_band": 8,
"mac_capability_flags": 128,
"manufacturer_code": 4417,
"maximum_buffer_size": 66,
"maximum_incoming_transfer_size": 66,
"server_mask": 10752,
"maximum_outgoing_transfer_size": 66,
"descriptor_capability_field": 0
},
"endpoints": {
"1": {
"profile_id": "0x0104",
"device_type": "0x0051",
"input_clusters": [
"0x0000",
"0x0004",
"0x0005",
"0xed00",
"0xef00"
],
"output_clusters": [
"0x000a",
"0x0019"
]
}
},
"manufacturer": "_TZE284_o9ofysmo",
"model": "TS0601",
"class": "zigpy.device.Device"
}
Logs
Logs
[Paste the logs here]Custom quirk
Custom quirk
"""Tuya temp and humidity sensors."""
import copy
from zigpy.quirks.v2 import EntityPlatform, EntityType
from zigpy.quirks.v2.homeassistant import PERCENTAGE, UnitOfTemperature, UnitOfTime
from zigpy.quirks.v2.homeassistant.sensor import SensorDeviceClass
import zigpy.types as t
from zigpy.zcl import foundation
from zhaquirks.tuya import (
TUYA_SET_TIME,
TuyaPowerConfigurationCluster2AAA,
TuyaTimePayload,
)
from zhaquirks.tuya.builder import TuyaQuirkBuilder, TuyaTemperatureMeasurement
from zhaquirks.tuya.mcu import TuyaMCUCluster
class TuyaTempUnitConvert(t.enum8):
"""Tuya temperature unit convert enum."""
Celsius = 0x00
Fahrenheit = 0x01
class TuyaNousTempHumiAlarm(t.enum8):
"""Tuya temperature and humidity alarm enum."""
LowerAlarm = 0x00
UpperAlarm = 0x01
Canceled = 0x02
class NoManufTimeTuyaMCUCluster(TuyaMCUCluster):
"""Tuya Manufacturer Cluster with set_time mod."""
set_time_offset = 1970
set_time_local_offset = 1970
# Deepcopy required to override 'set_time', without, it will revert
server_commands = copy.deepcopy(TuyaMCUCluster.server_commands)
server_commands.update(
{
TUYA_SET_TIME: foundation.ZCLCommandDef(
"set_time",
{"time": TuyaTimePayload},
False,
is_manufacturer_specific=False,
),
}
)
(
TuyaQuirkBuilder("_TZE200_bjawzodf", "TS0601")
.applies_to("_TZE200_zl1kmjqx", "TS0601")
# Not using tuya_temperature because device reports negative values incorrectly
.tuya_dp(
dp_id=1,
ep_attribute=TuyaTemperatureMeasurement.ep_attribute,
attribute_name=TuyaTemperatureMeasurement.AttributeDefs.measured_value.name,
converter=lambda x: ((x - 0xFFFF if x > 0x2000 else x) * 10),
)
.adds(TuyaTemperatureMeasurement)
.tuya_humidity(dp_id=2, scale=10)
.tuya_battery(dp_id=4)
.skip_configuration()
.add_to_registry()
)
(
TuyaQuirkBuilder("_TZE200_bq5c8xfe", "TS0601")
.applies_to("_TZE200_vs0skpuc", "TS0601")
.applies_to("_TZE200_qyflbnbj", "TS0601")
.applies_to("_TZE284_qyflbnbj", "TS0601")
.applies_to("_TZE200_44af8vyi", "TS0601")
# Not using tuya_temperature because device reports negative values incorrectly
.tuya_dp(
dp_id=1,
ep_attribute=TuyaTemperatureMeasurement.ep_attribute,
attribute_name=TuyaTemperatureMeasurement.AttributeDefs.measured_value.name,
converter=lambda x: ((x - 0xFFFF if x > 0x2000 else x) * 10),
)
.adds(TuyaTemperatureMeasurement)
.tuya_humidity(dp_id=2)
.tuya_battery(dp_id=4)
.skip_configuration()
.add_to_registry()
)
(
TuyaQuirkBuilder("_TZE200_a8sdabtg", "TS0601") # Variant without screen, round
.applies_to("_TZE200_qoy0ekbd", "TS0601")
.applies_to("_TZE200_znbl8dj5", "TS0601")
.applies_to("_TZE200_zppcgbdj", "TS0601")
.applies_to("_TZE204_s139roas", "TS0601")
.applies_to("_TZE200_s1xgth2u", "TS0601") # Nedis ZBSC30WT
.tuya_temperature(dp_id=1, scale=10)
.adds(TuyaTemperatureMeasurement)
.tuya_humidity(dp_id=2)
.tuya_battery(dp_id=4)
.skip_configuration()
.add_to_registry()
)
# TH01Z - Temperature and humidity sensor with clock
(
TuyaQuirkBuilder("_TZE200_lve3dvpy", "TS0601")
.applies_to("_TZE200_c7emyjom", "TS0601")
.applies_to("_TZE200_locansqn", "TS0601")
.applies_to("_TZE200_qrztc3ev", "TS0601")
.applies_to("_TZE200_snloy4rw", "TS0601")
.applies_to("_TZE200_eanjj2pa", "TS0601")
.applies_to("_TZE200_ydrdfkim", "TS0601")
.applies_to("_TZE284_locansqn", "TS0601")
.applies_to("_TZE200_w6n8jeuu", "TS0601")
.applies_to("_TZE200_vvmbj46n", "TS0601")
.applies_to("_TZE284_vvmbj46n", "TS0601")
.tuya_temperature(dp_id=1, scale=10)
.tuya_humidity(dp_id=2)
.tuya_battery(dp_id=4)
.tuya_number(
dp_id=17,
attribute_name="temperature_report_interval",
type=t.uint16_t,
device_class=SensorDeviceClass.DURATION,
unit=UnitOfTime.MINUTES,
min_value=5,
max_value=120,
step=5,
entity_type=EntityType.CONFIG,
translation_key="temperature_report_interval",
fallback_name="Temperature report interval",
)
.tuya_number(
dp_id=18,
attribute_name="humidity_report_interval",
type=t.uint16_t,
device_class=SensorDeviceClass.DURATION,
unit=UnitOfTime.MINUTES,
min_value=5,
max_value=120,
step=5,
entity_type=EntityType.CONFIG,
translation_key="humidity_report_interval",
fallback_name="Humidity report interval",
)
.tuya_enum(
dp_id=9,
attribute_name="display_unit",
enum_class=TuyaTempUnitConvert,
entity_type=EntityType.CONFIG,
translation_key="display_unit",
fallback_name="Display unit",
)
.tuya_enum(
dp_id=14,
attribute_name="temperature_alarm",
enum_class=TuyaNousTempHumiAlarm,
entity_platform=EntityPlatform.SENSOR,
entity_type=EntityType.STANDARD,
translation_key="temperature_alarm",
fallback_name="Temperature alarm",
)
.tuya_number(
dp_id=10,
attribute_name="alarm_temperature_max",
type=t.uint16_t,
unit=UnitOfTemperature.CELSIUS,
min_value=-20,
max_value=60,
step=1,
multiplier=0.1,
entity_type=EntityType.CONFIG,
translation_key="alarm_temperature_max",
fallback_name="Alarm temperature max",
)
.tuya_number(
dp_id=11,
attribute_name="alarm_temperature_min",
type=t.uint16_t,
unit=UnitOfTemperature.CELSIUS,
min_value=-20,
max_value=60,
step=1,
multiplier=0.1,
entity_type=EntityType.CONFIG,
translation_key="alarm_temperature_min",
fallback_name="Alarm temperature min",
)
.tuya_number(
dp_id=19,
attribute_name="temperature_sensitivity",
type=t.uint16_t,
unit=UnitOfTemperature.CELSIUS,
min_value=0.1,
max_value=50,
step=0.1,
multiplier=0.1,
entity_type=EntityType.CONFIG,
translation_key="temperature_sensitivity",
fallback_name="Temperature sensitivity",
)
.tuya_enum(
dp_id=15,
attribute_name="humidity_alarm",
enum_class=TuyaNousTempHumiAlarm,
entity_platform=EntityPlatform.SENSOR,
entity_type=EntityType.STANDARD,
translation_key="humidity_alarm",
fallback_name="Humidity alarm",
)
.tuya_number(
dp_id=12,
attribute_name="alarm_humidity_max",
type=t.uint16_t,
unit=PERCENTAGE,
min_value=0,
max_value=100,
step=1,
entity_type=EntityType.CONFIG,
translation_key="alarm_humidity_max",
fallback_name="Alarm humidity max",
)
.tuya_number(
dp_id=13,
attribute_name="alarm_humidity_min",
type=t.uint16_t,
unit=PERCENTAGE,
min_value=0,
max_value=100,
step=1,
entity_type=EntityType.CONFIG,
translation_key="alarm_humidity_min",
fallback_name="Alarm humidity min",
)
.tuya_number(
dp_id=20,
attribute_name="humidity_sensitivity",
type=t.uint16_t,
unit=PERCENTAGE,
min_value=1,
max_value=100,
step=1,
entity_type=EntityType.CONFIG,
translation_key="humidity_sensitivity",
fallback_name="Humidity sensitivity",
)
.tuya_enchantment(data_query_spell=True)
.skip_configuration()
.add_to_registry(replacement_cluster=NoManufTimeTuyaMCUCluster)
)
(
TuyaQuirkBuilder("_TZE284_aao3yzhs", "TS0601")
.applies_to("_TZE284_sgabhwa6", "TS0601")
.applies_to("_TZE284_nhgdf6qr", "TS0601") # Giex GX04
.applies_to("_TZE284_ap9owrsa", "TS0601") # Novadigital SG-ZB
.tuya_temperature(dp_id=5, scale=10)
.tuya_battery(dp_id=15)
.tuya_soil_moisture(dp_id=3)
.skip_configuration()
.add_to_registry()
)
(
TuyaQuirkBuilder("_TZE284_rqcuwlsa", "TS0601") # NEO NAS-STH02B2
.tuya_battery(dp_id=15)
.tuya_electrical_conductivity(dp_id=1)
.tuya_soil_moisture(dp_id=3)
.tuya_temperature(dp_id=5, scale=10)
.tuya_enchantment(data_query_spell=True)
.skip_configuration()
.add_to_registry()
)
(
TuyaQuirkBuilder("_TZE200_myd45weu", "TS0601")
.applies_to("_TZE200_ga1maeof", "TS0601")
.applies_to("_TZE200_9cqcpkgb", "TS0601")
.applies_to("_TZE204_myd45weu", "TS0601")
.applies_to("_TZE284_myd45weu", "TS0601")
.applies_to("_TZE200_2se8efxh", "TS0601") # Immax Neo
.tuya_temperature(dp_id=5)
.tuya_battery(dp_id=15)
.tuya_soil_moisture(dp_id=3)
.skip_configuration()
.add_to_registry()
)
(
TuyaQuirkBuilder("_TZE200_upagmta9", "TS0601")
.applies_to("_TZE204_upagmta9", "TS0601")
.applies_to("_TZE200_cirvgep4", "TS0601")
.applies_to("_TZE204_cirvgep4", "TS0601")
.applies_to("_TZE204_jygvp6fk", "TS0601")
.applies_to("_TZE200_yjjdcqsq", "TS0601")
.applies_to("_TZE204_yjjdcqsq", "TS0601")
.applies_to("_TZE284_yjjdcqsq", "TS0601")
.applies_to("_TZE200_9yapgbuv", "TS0601")
.applies_to("_TZE204_9yapgbuv", "TS0601")
.applies_to("_TZE200_utkemkbs", "TS0601")
.applies_to("_TZE204_utkemkbs", "TS0601")
.applies_to("_TZE284_utkemkbs", "TS0601")
.applies_to("_TZE204_ksz749x8", "TS0601")
.applies_to("_TZE284_o9ofysmo", "TS0601")
.tuya_temperature(dp_id=1, scale=10)
.tuya_humidity(dp_id=2)
.tuya_dp(
dp_id=3,
ep_attribute=TuyaPowerConfigurationCluster2AAA.ep_attribute,
attribute_name="battery_percentage_remaining",
converter=lambda x: {0: 50, 1: 100, 2: 200}[x],
)
.tuya_enum(
dp_id=9,
attribute_name="display_unit",
enum_class=TuyaTempUnitConvert,
entity_type=EntityType.CONFIG,
translation_key="display_unit",
fallback_name="Display unit",
)
.adds(TuyaPowerConfigurationCluster2AAA)
.tuya_enchantment(data_query_spell=True)
.skip_configuration()
.add_to_registry()
)Additional information
Sensor was purcahsed from Aliexpress https://www.aliexpress.com/item/1005009121816042.html
Metadata
Metadata
Assignees
Labels
device support requestThis requests support for a new deviceThis requests support for a new device