zha-device-handlers
zha-device-handlers copied to clipboard
[Device Support Request] TY0201 by _TZ3000_bjawzodf
Problem description
Round white temperature and humidity sensor with display purchased from Temu. Only temperature and battery shows.
I attempted using the ts0201.py and replacing ("_TZ3000_qaaysllp", "TS0201") with ("_TZ3000_bjawzodf", "TY0201") and it seems to be working.
Solution description
Temperature, Humidity and Battery level support.
Screenshots/Video
Screenshots/Video
Before Quirk
After Quirk
Device signature
Device signature
{ "node_descriptor": "NodeDescriptor(logical_type=<LogicalType.EndDevice: 2>, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=<FrequencyBand.Freq2400MHz: 8>, mac_capability_flags=<MACCapabilityFlags.AllocateAddress: 128>, manufacturer_code=4417, maximum_buffer_size=66, maximum_incoming_transfer_size=66, server_mask=10752, maximum_outgoing_transfer_size=66, descriptor_capability_field=<DescriptorCapability.NONE: 0>, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=True, *is_full_function_device=False, *is_mains_powered=False, *is_receiver_on_when_idle=False, *is_router=False, *is_security_capable=False)", "endpoints": { "1": { "profile_id": "0x0104", "device_type": "0x0302", "input_clusters": [ "0x0000", "0x0001", "0x0003", "0x0402", "0x0405" ], "output_clusters": [ "0x0019" ] } }, "manufacturer": "_TZ3000_bjawzodf", "model": "TY0201", "class": "zigpy.device.Device" }
Diagnostic information
Diagnostic information
{ "home_assistant": { "installation_type": "Home Assistant OS", "version": "2023.12.3", "dev": false, "hassio": true, "virtualenv": false, "python_version": "3.11.6", "docker": true, "arch": "x86_64", "timezone": "America/New_York", "os_name": "Linux", "os_version": "6.1.63-haos", "supervisor": "2023.12.0", "host_os": "Home Assistant OS 11.2", "docker_version": "24.0.7", "chassis": "vm", "run_as_root": true }, "custom_components": { "meross_lan": { "version": "3.0.0", "requirements": [] }, "hacs": { "version": "1.33.0", "requirements": [ "aiogithubapi>=22.10.1" ] } }, "integration_manifest": { "domain": "zha", "name": "Zigbee Home Automation", "after_dependencies": [ "onboarding", "usb" ], "codeowners": [ "@dmulcahey", "@adminiuga", "@puddly", "@TheJulianJES" ], "config_flow": true, "dependencies": [ "file_upload" ], "documentation": "https://www.home-assistant.io/integrations/zha", "iot_class": "local_polling", "loggers": [ "aiosqlite", "bellows", "crccheck", "pure_pcapy3", "zhaquirks", "zigpy", "zigpy_deconz", "zigpy_xbee", "zigpy_zigate", "zigpy_znp", "universal_silabs_flasher" ], "requirements": [ "bellows==0.37.3", "pyserial==3.5", "pyserial-asyncio==0.6", "zha-quirks==0.0.107", "zigpy-deconz==0.22.2", "zigpy==0.60.1", "zigpy-xbee==0.20.1", "zigpy-zigate==0.12.0", "zigpy-znp==0.12.0", "universal-silabs-flasher==0.0.15", "pyserial-asyncio-fast==0.11" ], "usb": [ { "vid": "10C4", "pid": "EA60", "description": "2652", "known_devices": [ "slae.sh cc2652rb stick" ] }, { "vid": "1A86", "pid": "55D4", "description": "sonoffplus*", "known_devices": [ "sonoff zigbee dongle plus v2" ] }, { "vid": "10C4", "pid": "EA60", "description": "sonoffplus*", "known_devices": [ "sonoff zigbee dongle plus" ] }, { "vid": "10C4", "pid": "EA60", "description": "tubeszb", "known_devices": [ "TubesZB Coordinator" ] }, { "vid": "1A86", "pid": "7523", "description": "tubeszb", "known_devices": [ "TubesZB Coordinator" ] }, { "vid": "1A86", "pid": "7523", "description": "zigstar", "known_devices": [ "ZigStar Coordinators" ] }, { "vid": "1CF1", "pid": "0030", "description": "conbee", "known_devices": [ "Conbee II" ] }, { "vid": "0403", "pid": "6015", "description": "conbee", "known_devices": [ "Conbee III" ] }, { "vid": "10C4", "pid": "8A2A", "description": "zigbee", "known_devices": [ "Nortek HUSBZB-1" ] }, { "vid": "0403", "pid": "6015", "description": "zigate", "known_devices": [ "ZiGate+" ] }, { "vid": "10C4", "pid": "EA60", "description": "zigate", "known_devices": [ "ZiGate" ] }, { "vid": "10C4", "pid": "8B34", "description": "bv 2010/10", "known_devices": [ "Bitron Video AV2010/10" ] } ], "zeroconf": [ { "type": "_esphomelib._tcp.local.", "name": "tube*" }, { "type": "_zigate-zigbee-gateway._tcp.local.", "name": "zigate" }, { "type": "_zigstar_gw._tcp.local.", "name": "zigstar" }, { "type": "_uzg-01._tcp.local.", "name": "uzg-01*" }, { "type": "_slzb-06._tcp.local.", "name": "slzb-06*" } ], "is_built_in": true }, "data": { "ieee": "REDACTED", "nwk": 63935, "manufacturer": "_TZ3000_bjawzodf", "model": "TY0201", "name": "_TZ3000_bjawzodf TY0201", "quirk_applied": false, "quirk_class": "zigpy.device.Device", "quirk_id": null, "manufacturer_code": 4417, "power_source": "Battery or Unknown", "lqi": 87, "rssi": null, "last_seen": "2023-12-25T18:54:54", "available": true, "device_type": "EndDevice", "signature": { "node_descriptor": "NodeDescriptor(logical_type=<LogicalType.EndDevice: 2>, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=<FrequencyBand.Freq2400MHz: 8>, mac_capability_flags=<MACCapabilityFlags.AllocateAddress: 128>, manufacturer_code=4417, maximum_buffer_size=66, maximum_incoming_transfer_size=66, server_mask=10752, maximum_outgoing_transfer_size=66, descriptor_capability_field=<DescriptorCapability.NONE: 0>, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=True, *is_full_function_device=False, *is_mains_powered=False, *is_receiver_on_when_idle=False, *is_router=False, *is_security_capable=False)", "endpoints": { "1": { "profile_id": "0x0104", "device_type": "0x0302", "input_clusters": [ "0x0000", "0x0001", "0x0003", "0x0402", "0x0405" ], "output_clusters": [ "0x0019" ] } }, "manufacturer": "_TZ3000_bjawzodf", "model": "TY0201" }, "active_coordinator": false, "entities": [ { "entity_id": "button.tz3000_bjawzodf_ty0201_identify", "name": "_TZ3000_bjawzodf TY0201" }, { "entity_id": "sensor.tz3000_bjawzodf_ty0201_battery", "name": "_TZ3000_bjawzodf TY0201" }, { "entity_id": "sensor.tz3000_bjawzodf_ty0201_temperature", "name": "_TZ3000_bjawzodf TY0201" } ], "neighbors": [], "routes": [], "endpoint_names": [ { "name": "TEMPERATURE_SENSOR" } ], "user_given_name": null, "device_reg_id": "388644d1eb87a058dbda55635d46ea92", "area_id": null, "cluster_details": { "1": { "device_type": { "name": "TEMPERATURE_SENSOR", "id": 770 }, "profile_id": 260, "in_clusters": { "0x0000": { "endpoint_attribute": "basic", "attributes": { "0x0004": { "attribute_name": "manufacturer", "value": "_TZ3000_bjawzodf" }, "0x0005": { "attribute_name": "model", "value": "TY0201" } }, "unsupported_attributes": {} }, "0x0001": { "endpoint_attribute": "power", "attributes": { "0x0021": { "attribute_name": "battery_percentage_remaining", "value": 200 } }, "unsupported_attributes": {} }, "0x0003": { "endpoint_attribute": "identify", "attributes": {}, "unsupported_attributes": {} }, "0x0402": { "endpoint_attribute": "temperature", "attributes": { "0x0000": { "attribute_name": "measured_value", "value": 2360 } }, "unsupported_attributes": {} }, "0x0405": { "endpoint_attribute": "humidity", "attributes": { "0x0000": { "attribute_name": "measured_value", "value": 3870 } }, "unsupported_attributes": { "0x0000": { "attribute_name": "measured_value" } } } }, "out_clusters": { "0x0019": { "endpoint_attribute": "ota", "attributes": {}, "unsupported_attributes": {} } } } } } }
Logs
Logs
[Paste the logs here]
Custom quirk
Custom quirk
"""Tuya TS201 temperature, humidity and optional illumination sensors."""
from zigpy.profiles import zha from zigpy.profiles.zha import DeviceType from zigpy.quirks import CustomCluster, CustomDevice import zigpy.types as t from zigpy.zcl.clusters.general import Basic, Identify, Ota, PowerConfiguration, Time from zigpy.zcl.clusters.measurement import ( IlluminanceMeasurement, RelativeHumidity, TemperatureMeasurement, ) from zigpy.zdo.types import NodeDescriptor
from zhaquirks.const import ( DEVICE_TYPE, ENDPOINTS, INPUT_CLUSTERS, MODELS_INFO, NODE_DESCRIPTOR, OUTPUT_CLUSTERS, PROFILE_ID, )
class ValueAlarm(t.enum8): """Temperature and humidity alarm values."""
ALARM_OFF = 0x02
MAX_ALARM_ON = 0x01
MIN_ALARM_ON = 0x00
class TuyaTemperatureHumidityAlarmCluster(CustomCluster): """Tuya temperature and humidity alarm cluster (0xE002)."""
name = "Tuya Temperature and Humidity Alarm Cluster"
cluster_id = 0xE002
attributes = {
# Alarm settings
0xD00A: ("alarm_temperature_max", t.uint16_t, True),
0xD00B: ("alarm_temperature_min", t.uint16_t, True),
0xD00C: ("alarm_humidity_max", t.uint16_t, True),
0xD00E: ("alarm_humidity_min", t.uint16_t, True),
# Alarm information
0xD00F: ("alarm_humidity", ValueAlarm, True),
0xD006: ("temperature_humidity", ValueAlarm, True),
# Unknown
0xD010: ("unknown", t.uint8_t, True),
}
class NeoTemperatureHumidtyIlluminanceSensor(CustomDevice): """Neo temperature, humidity and illumination sensor."""
signature = {
# <SimpleDescriptor endpoint=1, profile=260, device_type=262
# device_version=1
# input_clusters=[0, 1, 1024, 57346]
# output_clusters=[25, 10]>
MODELS_INFO: [("_TZ3000_bjawzodf", "TY0201")],
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: DeviceType.LIGHT_SENSOR,
INPUT_CLUSTERS: [
Basic.cluster_id,
PowerConfiguration.cluster_id,
IlluminanceMeasurement.cluster_id,
TuyaTemperatureHumidityAlarmCluster.cluster_id,
],
OUTPUT_CLUSTERS: [
Time.cluster_id,
Ota.cluster_id,
],
},
},
}
replacement = {
ENDPOINTS: {
1: {
INPUT_CLUSTERS: [
Basic.cluster_id,
PowerConfiguration.cluster_id,
IlluminanceMeasurement.cluster_id,
TuyaTemperatureHumidityAlarmCluster,
],
OUTPUT_CLUSTERS: [
Time.cluster_id,
Ota.cluster_id,
],
},
2: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: DeviceType.TEMPERATURE_SENSOR,
INPUT_CLUSTERS: [
Basic.cluster_id,
TemperatureMeasurement.cluster_id,
RelativeHumidity.cluster_id,
],
},
},
}
class ZemismartTemperatureHumidtySensor(CustomDevice): """Zemismart temperature and humidity sensor."""
signature = {
# <SimpleDescriptor endpoint=1 profile=260 device_type=770
# device_version=1
# input_clusters=[0, 1, 3, 1029, 1026, 61183]
# output_clusters=[3, 25]>
MODELS_INFO: [("_TZ3000_lfa05ajd", "TS0201")],
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.TEMPERATURE_SENSOR,
INPUT_CLUSTERS: [
Basic.cluster_id,
PowerConfiguration.cluster_id,
Identify.cluster_id,
RelativeHumidity.cluster_id,
TemperatureMeasurement.cluster_id,
0xEEFF, # Unknown
],
OUTPUT_CLUSTERS: [Identify.cluster_id, Ota.cluster_id],
}
},
}
replacement = {
NODE_DESCRIPTOR: NodeDescriptor(
0x02,
0x40,
0x80,
0x1037,
0x7F,
0x0064,
0x2C00,
0x0064,
0x00, # Forcing capability 0x80 instead of 0x84 so AC Power = false
),
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.TEMPERATURE_SENSOR,
INPUT_CLUSTERS: [
Basic.cluster_id,
PowerConfiguration.cluster_id,
Identify.cluster_id,
RelativeHumidity.cluster_id,
TemperatureMeasurement.cluster_id,
],
OUTPUT_CLUSTERS: [Identify.cluster_id, Ota.cluster_id],
}
},
}
class RelativeHumidityX10(CustomCluster, RelativeHumidity): """Handles invalid humidity values."""
def _update_attribute(self, attrid, value):
# x10 factor in measured_value`(attrid=0)
if attrid == 0:
value = value * 10
super()._update_attribute(attrid, value)
class MoesTemperatureHumidtySensorWithScreen(CustomDevice): """Moes temperature and humidity sensor with screen."""
signature = {
# <SimpleDescriptor endpoint=1, profile=260, device_type="0x0302"
# input_clusters=["0x0000", "0x0001", "0x0003", "0x0402", "0x0405", "0xe002"]
# output_clusters=["0x0003", "0x000a", "0x0019"]>
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: DeviceType.TEMPERATURE_SENSOR,
INPUT_CLUSTERS: [
Basic.cluster_id,
PowerConfiguration.cluster_id,
Identify.cluster_id,
TemperatureMeasurement.cluster_id,
RelativeHumidity.cluster_id,
TuyaTemperatureHumidityAlarmCluster.cluster_id,
],
OUTPUT_CLUSTERS: [
Identify.cluster_id,
Time.cluster_id,
Ota.cluster_id,
],
},
},
}
replacement = {
ENDPOINTS: {
1: {
INPUT_CLUSTERS: [
Basic.cluster_id,
PowerConfiguration.cluster_id,
Identify.cluster_id,
TemperatureMeasurement.cluster_id,
RelativeHumidityX10,
TuyaTemperatureHumidityAlarmCluster,
],
OUTPUT_CLUSTERS: [
Identify.cluster_id,
Time.cluster_id,
Ota.cluster_id,
],
},
},
}
Additional information
https://www.temu.com/tuya-smart-zigbee-temperature-and-humidity-sensor-smart-life-app-control-indoor-humidity-detector-works-with-zigbee-gateway-hub-g-601099531358811.html