Tuya Zigbee Thermometer TS0201 quirk not loading

Hi everybody,

I purchased a round Tuya Zigbee thermometer with display.


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.
The zigbee signature is

{
  "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"
}

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, resulting in

"""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,
                ],
            },
        },
    }

However, after adding the quirk folder to my configuration.yaml, restarting HA, restarting ZHA an even re-adding the device a couple of times it still won’t apply the quirk.

Where’s the error?
Did I mess up the quirk?
Do I need to rename it to something special? So far it’s still named ts0201.py like the standard one.

Thank you so much in advance.

Check if your model is reported as _TZ3210_qkj7rujp. It probably won’t be, and you’ll need to change the Models info section above from _TZ3210_qkj7rujp to _TZ3210_yourmodel.

Suggest you submit a device support request to discuss that under issues in the ZHA Device Handlers (also known as zha-quirk) repository on GitHub → https://www.home-assistant.io/integrations/zha#how-to-add-support-for-new-and-unsupported-deviceshttps://github.com/zigpy/zha-device-handlers/issues

_TZ3210_qkj7rujp is what I found in the Zigbee signature of my device. Where else can I find my model?

Ok, your model is correct then. I haven’t used ZHA in a while, but this is a step by step process on how to get ZHA to load the quirk file.

It’s strange that the ZHA documentation barely mentions the custom quirks path. Maybe you could suggest an edit to the documentation once you confirm this is how it works.