zha-device-handlers
zha-device-handlers copied to clipboard
[Device Support Request] Tuya Thermometer TS0201 different manufacturer (round with display)
Problem description
Hi,
I purchased a round Tuya Zigbee thermometer with display. https://de.aliexpress.com/item/1005005872944768.html I use a Skyconnect with ZHA, the thermometer connects without problems and reports the initial temperature and air pressure. Unfortunately it never updates those values and after a few hours only reports 0 degrees and air pressure. I noticed that there exists a quirk for the TS0201, unfortunately not for my specific model. In the quirk I found the class class MoesTemperatureHumidtySensorWithScreen(CustomDevice): """Moes temperature and humidity sensor with screen."" and figured that that might best fit my device.
I tried editing the quirk with my zigbee signature, but the quirk won't be applied, no matter how often I re-pair or restart.
Solution description
Could somebody please adjust the quirk to my model?
Screenshots/Video
Screenshots/Video
[Paste/upload your media here]
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": "0x0402",
"input_clusters": [
"0x0000",
"0x0001",
"0x0004",
"0x0402",
"0x0405",
"0xe002"
],
"output_clusters": [
"0x0004",
"0x000a",
"0x0019"
]
}
},
"manufacturer": "_TZ3210_qkj7rujp",
"model": "TS0201",
"class": "zigpy.device.Device"
}
Diagnostic information
Diagnostic information
{
"home_assistant": {
"installation_type": "Home Assistant OS",
"version": "2024.6.3",
"dev": false,
"hassio": true,
"virtualenv": false,
"python_version": "3.12.2",
"docker": true,
"arch": "aarch64",
"timezone": "Europe/Berlin",
"os_name": "Linux",
"os_version": "6.6.29-haos",
"supervisor": "2024.06.0",
"host_os": "Home Assistant OS 12.3",
"docker_version": "25.0.5",
"chassis": "embedded",
"run_as_root": true
},
"custom_components": {
"homematicip_local": {
"documentation": "https://github.com/danielperna84/custom_homematic",
"version": "1.62.1",
"requirements": [
"hahomematic==2024.6.0"
]
},
"home_connect_alt": {
"documentation": "https://github.com/ekutner/home-connect-hass",
"version": "1.1.6",
"requirements": [
"home-connect-async==0.8.0"
]
},
"hacs": {
"documentation": "https://hacs.xyz/docs/configuration/start",
"version": "1.34.0",
"requirements": [
"aiogithubapi>=22.10.1"
]
},
"dwd": {
"documentation": "https://github.com/hg1337/homeassistant-dwd#readme",
"version": "2024.4.0",
"requirements": [
"defusedxml==0.7.1"
]
},
"zeo_one": {
"documentation": "https://github.com/yangqian/hass-zeo_one",
"version": "1.1.0",
"requirements": [
"python-roborock"
]
},
"xiaomi_miot": {
"documentation": "https://github.com/al-one/hass-xiaomi-miot",
"version": "0.7.18",
"requirements": [
"construct>=2.10.68",
"python-miio>=0.5.12",
"micloud>=0.5"
]
},
"better_thermostat": {
"documentation": "https://github.com/KartoffelToby/better_thermostat",
"version": "1.5.1",
"requirements": []
}
},
"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.39.1",
"pyserial==3.5",
"zha-quirks==0.0.116",
"zigpy-deconz==0.23.1",
"zigpy==0.64.1",
"zigpy-xbee==0.20.1",
"zigpy-zigate==0.12.0",
"zigpy-znp==0.12.1",
"universal-silabs-flasher==0.0.20",
"pyserial-asyncio-fast==0.11"
],
"usb": [
{
"vid": "10C4",
"pid": "EA60",
"description": "*2652*",
"known_devices": [
"slae.sh cc2652rb stick"
]
},
{
"vid": "10C4",
"pid": "EA60",
"description": "*slzb-07*",
"known_devices": [
"smlight slzb-07"
]
},
{
"vid": "1A86",
"pid": "55D4",
"description": "*sonoff*plus*",
"known_devices": [
"sonoff zigbee dongle plus v2"
]
},
{
"vid": "10C4",
"pid": "EA60",
"description": "*sonoff*plus*",
"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
},
"setup_times": {
"null": {
"setup": 0.0002770849969238043
},
"8e42468e822f68622f774ebecdf9ea1b": {
"wait_import_platforms": -0.0009566720109432936,
"config_entry_setup": 25.965530738933012
}
},
"data": {
"ieee": "**REDACTED**",
"nwk": 14899,
"manufacturer": "_TZ3210_qkj7rujp",
"model": "TS0201",
"name": "_TZ3210_qkj7rujp TS0201",
"quirk_applied": false,
"quirk_class": "zigpy.device.Device",
"quirk_id": null,
"manufacturer_code": 4417,
"power_source": "Battery or Unknown",
"lqi": 192,
"rssi": -52,
"last_seen": "2024-06-17T15:59:26",
"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": "0x0402",
"input_clusters": [
"0x0000",
"0x0001",
"0x0004",
"0x0402",
"0x0405",
"0xe002"
],
"output_clusters": [
"0x0004",
"0x000a",
"0x0019"
]
}
},
"manufacturer": "_TZ3210_qkj7rujp",
"model": "TS0201"
},
"active_coordinator": false,
"entities": [
{
"entity_id": "sensor.thermometer_pantry_batterie",
"name": "_TZ3210_qkj7rujp TS0201"
},
{
"entity_id": "sensor.thermometer_pantry_temperatur",
"name": "_TZ3210_qkj7rujp TS0201"
},
{
"entity_id": "sensor.thermometer_pantry_luftfeuchtigkeit",
"name": "_TZ3210_qkj7rujp TS0201"
},
{
"entity_id": "update.thermometer_pantry_firmware",
"name": "_TZ3210_qkj7rujp TS0201"
}
],
"neighbors": [],
"routes": [],
"endpoint_names": [
{
"name": "IAS_ZONE"
}
],
"user_given_name": "Thermometer Pantry",
"device_reg_id": "1d66d7db0c63e22b253aac6b48c5ade2",
"area_id": "pantry",
"cluster_details": {
"1": {
"device_type": {
"name": "IAS_ZONE",
"id": 1026
},
"profile_id": 260,
"in_clusters": {
"0x0000": {
"endpoint_attribute": "basic",
"attributes": {
"0x0004": {
"attribute_name": "manufacturer",
"value": "_TZ3210_qkj7rujp"
},
"0x0005": {
"attribute_name": "model",
"value": "TS0201"
}
},
"unsupported_attributes": {}
},
"0x0004": {
"endpoint_attribute": "groups",
"attributes": {},
"unsupported_attributes": {}
},
"0x0001": {
"endpoint_attribute": "power",
"attributes": {
"0x0021": {
"attribute_name": "battery_percentage_remaining",
"value": 200
},
"0x0020": {
"attribute_name": "battery_voltage",
"value": 0
}
},
"unsupported_attributes": {
"0x0031": {
"attribute_name": "battery_size"
},
"0x0033": {
"attribute_name": "battery_quantity"
}
}
},
"0x0402": {
"endpoint_attribute": "temperature",
"attributes": {
"0x0000": {
"attribute_name": "measured_value",
"value": 0
}
},
"unsupported_attributes": {}
},
"0x0405": {
"endpoint_attribute": "humidity",
"attributes": {
"0x0000": {
"attribute_name": "measured_value",
"value": 0
}
},
"unsupported_attributes": {}
},
"0xe002": {
"endpoint_attribute": null,
"attributes": {},
"unsupported_attributes": {}
}
},
"out_clusters": {
"0x0004": {
"endpoint_attribute": "groups",
"attributes": {},
"unsupported_attributes": {}
},
"0x000a": {
"endpoint_attribute": "time",
"attributes": {},
"unsupported_attributes": {}
},
"0x0019": {
"endpoint_attribute": "ota",
"attributes": {
"0x0002": {
"attribute_name": "current_file_version",
"value": 67
}
},
"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 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="0x0402"
# input_clusters=["0x0000", "0x0001", "0x0004", "0x0402", "0x0405", "0xe002"]
# output_clusters=["0x0004", "0x000a", "0x0019"]>
MODELS_INFO: [("_TZ3210_qkj7rujp", "TS0201")],
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
No response