Temperature and humidity sensors are one of my favorite Home Automation devices to play with. They are very low power, operate on batteries that need replacing once or twice a year and provide you with valuable information about the ambient in your home. I’ve tested a bunch of different sensors of this type on my reviews channel, recently the Sonoff SNZB-02D and the Moes ZSS-KB-TH.
These are one of those smart devices that absolutely do not need to be expensive. I would even go so far in saying that you should not spend more than $10-13 a piece on such a device, any manufacturer asking for more is ripping you off or you are paying the brand name needlessly.
The device subject in this review is Tuya Zigbee Temperature & Humidity Sensor with an LCD screen white labelled model SZ-T04. This one runs on 3xAAA batteries, is supported in ZHA & Zigbee2MQTT and has a solid LCD for the price.
I bought it on AliExpress for $9 during a sale, but it’s also available on Amazon for double the price if you can’t wait for shipping. Let’s get into it.
Technical Specification
- Display: LCD
- Display Contents: Temperature, humidity, date & time, battery
- Connectivity: Zigbee 3.0 or Wi-Fi 2.4GHz
- Battery: 3xAAA [AlIExpress, Amazon]
- Working Temperature: -10~55°C
- Working Humidity: 10-90% RH
- Reporting Interval: Adjustable
- Dimensions: 63x60x25mm
- Color: White/Black
- Price: $10 [AliExpress], $13 Amazon
Teardown
The device came packed in a neat little box containing the sensor itself and a user manual, nothing else. Like it often happens, the packing was banged up but the device intact. There are no AAA batteries included, so you will have to supply those yourself.
The screen is surprisingly solid, with okay contrast and readable contents from a distance. It’s better than the Sonoff SNZB-02D Temperature sensor, that one had weak viewing angles. It displays the current date, time and battery at the top while the temperature and humidity reading are cleanly in the middle. You can cycle between °C/°F.
On the back side, some labelling is printed and an arrow engraved telling you to pull downwards to remove the battery cover. The plastic is no that great, doesn’t feel premium but perhaps it doesn’t have to as the device is all screen. There is a small hole on the top to mount the sensor on a screw or nail.
The pairing button is placed on the top of the sensor, it’s seamlessly integrated so it doesn’t ruin it’s design.
Removing the main PCB from the case, you encounter a GNV1792S [Datasheet] LCD driver made by some company named GN Semiconductor, an electronic components distributor from China. I have not come across this driver before, but I guess it’s doing a good job because I didn’t notice any flickering or number artefacts.
Considering this is the Zigbee version, connectivity is enabled by a Tuya ZTU Module [Datasheet], embedded with a low-power 32-bit CPU, 1024-KB flash and 64-KB RAM. This chip handles communication for a bunch of devices I’ve reviewed in the past, for example this Moes Dual USB Socket ZP-LZ-FR2U or the cheap Tuya Water Leak Sensor ZW-08.
More recently, I’ve encountered a variant of this module in the Tuya 3-Phase Clamp Energy Meter PC321-Z-TY called ZTU-IPEX. That energy meter is becoming one my most useful Home Automation devices, so I strongly suggest you check out it’s review.
I could not make out what manufacturer supplied the actual temperature and humidity sensor for this device, the label was somehow smeared during production. But if I would have to venture I guess, this seems a lot like one of Sensirion‘s sensors, either the SHT30 or SHT40. I’m testing it’s accuracy in any case.
Finally, here’s the Tuya Zigbee Temperature Hygrometer SZ-T04 fully disassembled.
Home Assistant Integration
The Tuya Zigbee Temperature and Humidity Sensor SZ-T04 is officially supported in Zigbee2MQTT only, but it works perfectly fine in ZHA with a simple custom quirk. This device’s data cluster are pretty generic, so it will be added to the ZHA database in the near future.
To pair it, press the button for ~5 seconds until the indicator on the screen starts it’s blinking animation.
Zigbee2MQTT
Once paired to Zigbee2MQTT, the device is identified as Model SZ-T04 and Manufacturer _TZE200_locansqn. Labelled as Temperature and humidity sensor with clock, it recycles one of the Tuya converters used across a bunch of other devices, so the image shown in the UI is not accurate.
Being battery powered, it’s correctly identified as an EndDevice but somehow the battery shows 125% in my integration. While they are brand new AAA batteries, this makes no sense. It exposes a bunch of entities in Home Assistant via Zigbee2MQTT:
It’s a highly versatile device and there are many things you can tweak. Starting with the temperature and humidity reporting intervals, you can set those from 5-120 minutes. Some use cases require a faster reporting interval than 5 minutes, so you need to think about your deployment if you are considering this device.
Another interesting asset of this temperature and humidity sensor is the ability to set alarms within a preset range of readings. For example, if you set the min_temperature to 10°C and max_temperature to 21°C, it will update the sensor.temperature_alarm entity in the following manner:
- Temperature drops bellow 10°C
- sensor.temperature_alarm inherits state lower_alarm
- Temperature rises above 21°C
- sensor.temperature_alarm inherits state upper_alarm
Similarly, you can set an alarm for the humidity measurement too. For example, if you set the min_humidity to 30% and max_humidity to 80%, it will update the sensor.humidity_alarm entity in the same manner:
- Humidity drops bellow 30%
- sensor.humidity_alarm inherits state lower_alarm
- Humidity rises above 80%
- sensor.humidity_alarm inherits state upper_alarm
You can actually do this with automations in Home Assistant too, this is just a simpler built-in way to achieve the same thing within the UI of Zigbee2MQTT more easily and natively. If you want to disable all alarms, you can pull the sliders to their maximum values which the sensor will never reach.
Calibration of the sensor is also available with the Settings (Specific) menu of Zigbee2MQTT. If you find the readings to be inaccurate, you can offset the values here. The precision sliders allow you to define the number of decimal points reported to Home Assistant via Zigbee2MQTT.
It’s important to note, the date & time are automatically synced with your Home Assistant instance once you pair the device to Zigbee2MQTT, so you don’t have to worry about setting them up.
ZHA
Pairing the device to ZHA without a custom quirk will give you no entities in Home Assistant. Some awesome people on Github shared a custom quirk which enables the main functionality of the device in ZHA. To enable custom quirks for ZHA in Home Assistant:
- Create a new directory in the config folder of Home Assistant
- For example /config/custom_zha_quirks
- Add the following to your configuration.yaml file
#Enable ZHA Custom Quirks
zha:
custom_quirks_path: /config/custom_zha_quirks/
- Download the custom quirk from Github ts0601_temperature.py
- Place the file in the /config/custom_zha_quirks directory you created
- OR
- Create an empty file and rename it ts0601_temperature.py (note the file extension!)
- Copy the following contents, save it and reboot Home Assistant
"""Tuya temp and humidity sensor with screen."""
from typing import Dict
################## clean this up
import zigpy.types as t
from zigpy.zcl import foundation
from zhaquirks.tuya import TuyaTimePayload, TuyaCommand
import datetime
from typing import Tuple, Optional, Union
##################
from zigpy.profiles import zha
from zigpy.quirks import CustomDevice
from zigpy.zcl.clusters.general import Basic, Groups, Ota, Scenes, Time, AnalogOutput
from zigpy.zcl.clusters.measurement import RelativeHumidity, TemperatureMeasurement
from zhaquirks.const import (
DEVICE_TYPE,
ENDPOINTS,
INPUT_CLUSTERS,
MODELS_INFO,
OUTPUT_CLUSTERS,
PROFILE_ID,
SKIP_CONFIGURATION,
)
from zhaquirks.tuya import TuyaLocalCluster, TuyaPowerConfigurationCluster2AAA
# old from zhaquirks.tuya.mcu import DPToAttributeMapping, TuyaDPType, TuyaMCUCluster
from zhaquirks.tuya.mcu import DPToAttributeMapping, TuyaMCUCluster
TUYA_SET_TIME = 0x24
# NOTES:
# The data comes in as a string on cluster, if there is nothing set up you may see these lines in the logs:
# Unknown message (b'19830100a40102000400000118') on cluster 61184: unknown endpoint or cluster id: 'No cluster ID 0xef00 on (a4:c1:38:d0:18:8b:64:aa, 1)'
# 28.0 degrees
# Unknown message (b'19840100a5020200040000022c') on cluster 61184: unknown endpoint or cluster id: 'No cluster ID 0xef00 on (a4:c1:38:d0:18:8b:64:aa, 1)'
# 55.6% humid
# Unknown message (b'19850100a60402000400000064') on cluster 61184: unknown endpoint or cluster id: 'No cluster ID 0xef00 on (a4:c1:38:d0:18:8b:64:aa, 1)'
# 100% battery
class TemperatureUnitConvert(t.enum8):
"""Tuya Temp unit convert enum."""
Celsius = 0x00
Fahrenheit = 0x01
class TuyaTemperatureMeasurement(TemperatureMeasurement, TuyaLocalCluster):
"""Tuya local TemperatureMeasurement cluster."""
attributes = TemperatureMeasurement.attributes.copy()
attributes.update(
{
0x8001: ("temp_unit_convert", t.enum8),
0x8002: ("alarm_max_temperature", t.Single),
0x8003: ("alarm_min_temperature", t.Single),
0x8004: ("temperature_sensitivity", t.Single),
}
)
class TuyaRelativeHumidity(RelativeHumidity, TuyaLocalCluster):
"""Tuya local RelativeHumidity cluster."""
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",
# dp_type=TuyaDPType.VALUE,
converter=lambda x: x * 10, # decidegree to centidegree
),
2: DPToAttributeMapping(
TuyaRelativeHumidity.ep_attribute,
"measured_value",
# dp_type=TuyaDPType.VALUE,
converter=lambda x: x * 100, # 0.01 to 1.0
),
4: DPToAttributeMapping(
TuyaPowerConfigurationCluster2AAA.ep_attribute,
"battery_percentage_remaining",
# dp_type=TuyaDPType.VALUE,
converter=lambda x: x * 2, # reported percentage is doubled
),
9: DPToAttributeMapping(
TuyaTemperatureMeasurement.ep_attribute,
"temp_unit_convert",
# dp_type=TuyaDPType.ENUM,
converter=lambda x: TemperatureUnitConvert(x)
),
10: DPToAttributeMapping(
TuyaTemperatureMeasurement.ep_attribute,
"alarm_max_temperature",
# dp_type=TuyaDPType.VALUE,
converter=lambda x: x / 10
),
11: DPToAttributeMapping(
TuyaTemperatureMeasurement.ep_attribute,
"alarm_min_temperature",
# dp_type=TuyaDPType.VALUE,
converter=lambda x: x / 10
),
19: DPToAttributeMapping(
TuyaTemperatureMeasurement.ep_attribute,
"temperature_sensitivity",
# dp_type=TuyaDPType.VALUE,
converter=lambda x: x / 10
)
}
set_time_offset = 1970
set_time_local_offset = 1970
data_point_handlers = {
1: "_dp_2_attr_update",
2: "_dp_2_attr_update",
4: "_dp_2_attr_update",
9: "_dp_2_attr_update",
10: "_dp_2_attr_update",
11: "_dp_2_attr_update",
19: "_dp_2_attr_update",
}
def handle_set_time_request(self, sequence_number: t.uint16_t) -> foundation.Status:
payload = TuyaTimePayload()
utc_now = datetime.datetime.utcnow()
now = datetime.datetime.now()
offset_time = datetime.datetime(self.set_time_offset, 1, 1)
offset_time_local = datetime.datetime(self.set_time_local_offset, 1, 1)
utc_timestamp = int((utc_now - offset_time).total_seconds())
local_timestamp = int((now - offset_time).total_seconds())
payload.extend(utc_timestamp.to_bytes(4, "big", signed=False))
payload.extend(local_timestamp.to_bytes(4, "big", signed=False))
self.create_catching_task(
self.command(TUYA_SET_TIME, payload, manufacturer=foundation.ZCLHeader.NO_MANUFACTURER_ID, expect_reply=False)
)
return foundation.Status.SUCCESS
class TuyaNousE6TempHumiditySensor(CustomDevice):
"""Custom device representing tuya temp and humidity sensor with a screen (NOUS E6)."""
signature = {
# <SimpleDescriptor endpoint=1, profile=260, device_type=81
# device_version=1
# input_clusters=[4, 5, 61184, 0]
# output_clusters=[25, 10]>
MODELS_INFO: [("_TZE200_locansqn", "TS0601"), ("_TZE200_3towulqd", "TS0601")],
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.SMART_PLUG, # this is how the device reports itself
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: [
Basic.cluster_id,
TemperatureHumidityManufCluster, # Single bus for temp, humidity, and battery
TuyaTemperatureMeasurement,
TuyaRelativeHumidity,
TuyaPowerConfigurationCluster2AAA,
],
OUTPUT_CLUSTERS: [Ota.cluster_id, Time.cluster_id],
}
},
}
Testing
In comparing the Tuya SZ-T04 to a calibrated Xiaomi LYWSD02 BLE sensor already deployed in my home, I found it’s pretty accurate out of the box. I placed both devices on a bookshelf, just like in previous reviews and recorded the readings in Home Assistant.
Temperature
The Tuya SZ-T04 closely mirrored the temperature measurements of the Xiaomi sensor, average offset was about 0.5% calculated from 20 measurements. This value does not warrant calibration, so I gonna leave it as is.
Humidity
The humidity reading was slightly more different, with the SZ-T04 dipping more when there was a drop in humidity. However, it was still accurate with an average offset of 1.5% calculated from 20 measurements. I calibrated the humidity with a -1% in Zigbee2MQTT and it was all good.
Summary
The Tuya Zigbee T&H sensor with an LCD model SZ-T04 is a solid choice for a climate sensor, considering it’s price tag and the fact that it has a screen. It’s square shape is convenient for simply placing the device on your nightstand and glancing the information on the screen. Or if you want it mounted, you can use a screw or a nail to install it on your wall.
Zigbee communication was solid, I encountered no issues whatsoever. Tuya is constantly bashed for their ecosystem and cloud dependance when it comes to Wi-Fi devices, but I find their Zigbee implementation very adequate and appropriate. It’s worth mentioning that I have a very robust and stable mesh network, so that’s certainly a factor in my experience.
The LCD screen of the device was better than most devices of this type, like the Sonoff SNZB-02D for example. It falls short behind SwitchBot’s Meter Plus, but that one is double the price. If you are hunting for a great looking screen on which you are able to view the information from the distance and at all angles, you are going to have to get an e-ink device, like Xiaomi’s LYWSD02 sensor. In summary:
Pros
- Good screen for an LCD
- Accurate Temperature Reading
- Built-in Temperature Alarm
- Built-in Humidity Alarm
- Common 3xAAA Batteries
- Supported in Zigbee2MQTT
- Adjustable Reporting Interval
- Calibration
- Precision
- Sensitivity
Cons
- Partially supported in ZHA
- Custom Quirk is needed
- Reporting Interval is minimum 5 minutes
- Batteries not included
- Battery state incorrect in Zigbee2MQTT and ZHA
It’s important to note, the Wi-Fi version of this device has been widely reported to eat batteries like crazy. This is somewhat understandable, considering the nature of 2.4GHz Wi-Fi combined with poor implementation and lousy batteries. I suggest you stay away from it, and go for the Zigbee version if you use it.
Where to Buy
I would recommend this device to anyone looking for a cheap climate sensor with a screen, it’s a cheap yet capable little box. I am suggesting this, highly considering price as a factor. You can get the SZ-T04 on AliExpress and Amazon, but the price is beefed up on Amazon because of resellers. Here are some links:
AliExpress | AliExpress | AliExpress | AliExpress
United States | Canada | United Kingdom
Germany | Netherlands | Sweden | Spain
France (WiFi) | Italy | Australia (WiFi)
*If links fail to open, try disabling your AdBlocker.
Wondering if the 125% battery is because it’s expecting rechargeables at 1.2v each rather than non rechargeable batteries which are 1.5v, therefore a 25% higher voltage.
Great article, thanks.
I have 4 of these devices.
Works for a lot of time very stable in HA under Z2Q but after a zigbee update somewere in april 23 all the comminication stops after a small time the data is not sending more to HA and the WI-FI SYMBOL disappear . Repair it it will be work for some times.
By me too (communication stops).
Thank you for your extensive reviews!! I got the device working using z2mqtt and it works as expected, but I cannot change the reporting frequency, it always reverts back to 120 minutes. Do you know if a need to do something extra to make it work?
You need to press the button to wake the device before sending the change frequency payload.
Thank you, so much! It worked!
How to we setup date and time? Can´t see it
It’s synced automatically to the time and date of your HA instance
I’ve been testing one of these with Zigbee2MQTT for about 6 months and it appears that after the initial data exchange as part of pairing with zigbee network, it never gets a time update from the coordinator again. Until you re pair the devices. What makes this worse, is that the device does not keep accurate time, falling behind about 30 minutes per month. I’m not sure how the zigbee time sync functions are designed to work, for example is a time sync done on a regular basis by coordinator or does it have to be requested by the device. The problem could be in the zigbee2mqtt config .js file for the device, firmware of device or ??? Regardless, the fact that it cannot keep time stand alone does not bode well for the device.
Seems like a really weird issue, funnily enough It never occurred to me to test the TIME.
I always assumed time is time you know, and it’s okay. I always benchmarked the temp and humidity measurements.
I will keep an eye out and check this
Looking at the sensor, this would be a sensylink sensor. The Sensirion sensors have the hole in the middle. I bought this exact model from the aliexpress link provided, and mine has a sensylink CHT8310 sensor. It has a boxed S followed by 8310 on the chip.
It might be worth adding that though the working temperature is listed as -10~55C, it will work just fine in lower temperatures. I use these to monitor my freezers and they happily go down as low as -20. The display will skip the first digit (it’s used for the minus symbol, so -18 will show as -8) but the value reported via Zigbee is correct.
That’s a great piece of info, never occurred to me to test.
Thanks!