TapHome

Tuya TS0201 Temperature & Humidity Sensor

Packet Parser → MQTT
Submitted by
Last updated: 06. 2026
Tuya TS0201 Temperature & Humidity Sensor

The Tuya TS0201 is a budget battery-powered Zigbee temperature and humidity sensor with a small LCD display. The same hardware is also sold under the BlitzWolf BW-IS4 white label. The device is popular as an inexpensive room climate sensor in the entry-level price range.

TapHome communicates with the TS0201 indirectly — the sensor pairs with a Zigbee coordinator (e.g., Sonoff ZBDongle-P/E, CC2652-based stick, CC2531), which is managed by a Zigbee2MQTT bridge. Zigbee2MQTT translates Zigbee messages into JSON payloads on MQTT topics. TapHome subscribes to these topics via a PacketParser MQTT module and maps the values to temperature/humidity services with battery and link-quality attributes.

Requirements

To use the TS0201 with TapHome, the following components are required:

  • Zigbee coordinator — USB stick based on CC2652P/CC2652R or CC2531, for example the Sonoff ZBDongle-P or Sonoff ZBDongle-E
  • Zigbee2MQTT bridge — running on a dedicated host (Raspberry Pi, NUC, NAS) or as a container alongside the MQTT broker
  • MQTT broker — Mosquitto is the recommended option; must be reachable from both the Zigbee2MQTT host and the TapHome CCU
  • TapHome CCU with PacketParser support (PacketParserCCU model)

The TS0201 itself does not connect to Wi-Fi or Ethernet — all IP networking happens between the MQTT broker and the TapHome CCU.

Pairing

Before importing the TapHome template, the TS0201 must be paired with the Zigbee2MQTT coordinator:

  1. Open the Zigbee2MQTT web UI and enable pairing mode (Permit join)
  2. On the TS0201, press and hold the reset button for approximately five seconds, until the network indicator at the top of the display starts blinking
  3. The device automatically joins the Zigbee network and appears in the Zigbee2MQTT device list with an IEEE address (e.g., 0xa4c1388f85d9eca2)
  4. Optionally rename the device and assign a human-readable friendly name (e.g., bedroom_climate) in the Zigbee2MQTT web UI

The battery percentage may take up to 24 hours to appear after pairing — the sensor only reports the battery value periodically.

Configuration

Import parameters

When importing the template in TapHome, provide the address of the MQTT broker:

ParameterDescriptionDefault
Mqtt Broker ipAddressIP address or hostname of the MQTT broker192.168.0.1
Mqtt Broker portMQTT broker TCP port1883
Module variable

After importing the template, set the TS0201 custom variable to identify the device on the MQTT broker:

VariableDescriptionHow to obtainExample
TS0201Zigbee2MQTT friendly name or IEEE address of the sensorZigbee2MQTT web UI → Devices → find the TS0201 → copy the Friendly name or IEEE address0xa4c1388f85d9eca2

The variable is used as the MQTT topic suffix — the listener script subscribes to zigbee2mqtt/{TS0201} and parses the JSON state payload.

Using a friendly name (e.g., bedroom_climate) instead of the IEEE address makes the TapHome configuration more readable. The friendly name can be changed in the Zigbee2MQTT web UI under device settings.

Device capabilities

The template maps the TS0201 as a Temperature Sensor device in TapHome and exposes humidity alongside battery and signal attributes.

Temperature and humidity

Temperature (°C) and relative humidity (%) are parsed from the JSON state topic zigbee2mqtt/{TS0201}. The sensor reports new values whenever a measured quantity changes or on a periodic schedule managed by the Zigbee2MQTT bridge.

An example payload published by Zigbee2MQTT:

1
2
3
4
5
6
7
{
  "battery": 95,
  "humidity": 54.2,
  "linkquality": 132,
  "temperature": 21.7,
  "voltage": 3000
}
Battery and signal monitoring

The device exposes three service attributes alongside the primary temperature and humidity values:

  • Battery — remaining battery percentage (0–100 %) from the JSON state payload. May take up to 24 hours after pairing before the first value is reported.
  • Battery Voltage — raw battery voltage in millivolts from the JSON state payload.
  • LinkQuality — Zigbee signal quality indicator (LQI) from the JSON state payload, ranging from 0 (worst) to 255 (best).

All attributes display "-" until the first message is received from the device.

Known issues

Humidity value divided by 100

The current listener script in the template divides the humidity payload by 100 (Hu := payloadHum/100). However, Zigbee2MQTT publishes humidity directly as a percentage (e.g. 54.2 means 54.2 %), so applying /100 yields 0.542 % instead of the expected 54.2 %.

Verify the reported humidity on live hardware. If the value is clearly off by two decimal places, adjust the listener script to Hu := payloadHum; (without the /100 division).

Do not apply OTA firmware updates

The most recently published TS0201 firmware image bricks the device and leaves it totally unusable. Zigbee2MQTT exposes OTA updates for this device, but they must not be applied until upstream publishes a safe image. See Zigbee2MQTT GitHub issue #25207 for details.

Do NOT trigger an OTA update for the TS0201 from the Zigbee2MQTT web UI. The current image is known to brick the sensor.

Troubleshooting

No data received
  1. Verify the TS0201 appears in the Zigbee2MQTT device list with a recent “Last seen” timestamp
  2. Check that the TS0201 custom variable in TapHome matches the device’s friendly name or IEEE address exactly — the match is case-sensitive
  3. Use an MQTT client (e.g., MQTT Explorer) to subscribe to zigbee2mqtt/# and confirm that JSON payloads arrive on zigbee2mqtt/{friendly_name}
  4. Confirm the MQTT broker IP and port in the TapHome import parameters match the broker reachable from the CCU
Device shows as offline in Zigbee2MQTT
  1. The TS0201 is a battery-powered end device — it sleeps between reports to save power. “Offline” may simply mean the device has not transmitted recently; wait for the next scheduled report or briefly press the reset button to force a check-in.
  2. If the device never comes back online, the Zigbee link may be broken due to distance from the coordinator. Move the sensor closer or add a Zigbee router (mains-powered Zigbee device) to extend the mesh.
  3. Check the LinkQuality attribute — values below ~30 lqi indicate a weak signal.
  1. Battery and voltage update only when the sensor wakes up and reports — this may be once every few hours
  2. If values show "-", no MQTT message has been received yet; wait for the next report or re-pair the device
  3. After re-pairing, battery may remain "-" for up to 24 hours before the first value is published

Available devices

Tuya TS0201 Module
Custom Variables
TS0201 (string) = 0xa4c1388f85d9eca2Zigbee2MQTT friendly name or IEEE address of the TS0201 sensor — used as MQTT topic suffix (zigbee2mqtt/{friendly_name})
Open Zigbee2MQTT web UI → Devices → find the TS0201 → copy the Friendly name (or use the IEEE address, e.g. 0xa4c1388f85d9eca2)
Temperature & Humidity Sensor Temperature Sensor Read-only

Temperature (°C) and relative humidity (%) parsed from the Zigbee2MQTT JSON state payload

JSON Unit: °C / % json_path
Service Attributes
BatteryRemaining battery percentage (0–100 %); may take up to 24 hours after pairing before the first value is reported
Battery VoltageRaw battery voltage in millivolts (mV) parsed from the JSON state payload
LinkQualityZigbee signal quality indicator (LQI) — 0 (worst) to 255 (best)

Temperature & Humidity Sensor

Read humidity
# Simple HTTP Request:
# VAR response := SENDHTTPREQUEST("/example/getValue");
# IF response.IsSuccess
#  VAR content := response.Content;
#  VAR responseHeaders := response.Headers;
#  RETURN(PARSEXML(content, "//element1/value1"));
# ELSE
#  ADDERROR(response.StatusCode + " (" + response.ReasonPhrase + ")");
#  RETURN(NaN);
# END
#
# Set Http request method, body and headers
# VAR response := SENDHTTPREQUEST("/example/getValue", "GET", "some data", "header1:value1", "header2:value2", ...);
# OR
# VAR request := HTTPREQUEST("/example/getValue", "POST", "some data");
# request.headers := { "header1:value1", "header2:value2", ...};
# request.method := "GET";
# request.data := null;
# VAR response := SENDHTTPREQUEST(request);
#
#
# Send TCP, UDP data:
# VAR data1 := BYTECOLLECTION("0a bb ea df 01");
# SENDDATA(data1);
# VAR data2 := "{\"name\":\"John\", \"age\":32}";
# SENDDATA(data2);
# VAR data3 := TOBYTES("{\"name\":\"John\", \"age\":32}", "iso-8859-1");
# SENDDATA(data3);
# Process received TCP or UDP data and set device values in the Listener script
#
#
# Download data from FTP:
# FTPDOWNLOAD("filePath");
Read temperature
# Simple HTTP Request:
# VAR response := SENDHTTPREQUEST("/example/getValue");
# IF response.IsSuccess
#  VAR content := response.Content;
#  VAR responseHeaders := response.Headers;
#  RETURN(PARSEXML(content, "//element1/value1"));
# ELSE
#  ADDERROR(response.StatusCode + " (" + response.ReasonPhrase + ")");
#  RETURN(NaN);
# END
#
# Set Http request method, body and headers
# VAR response := SENDHTTPREQUEST("/example/getValue", "GET", "some data", "header1:value1", "header2:value2", ...);
# OR
# VAR request := HTTPREQUEST("/example/getValue", "POST", "some data");
# request.headers := { "header1:value1", "header2:value2", ...};
# request.method := "GET";
# request.data := null;
# VAR response := SENDHTTPREQUEST(request);
#
#
# Send TCP, UDP data:
# VAR data1 := BYTECOLLECTION("0a bb ea df 01");
# SENDDATA(data1);
# VAR data2 := "{\"name\":\"John\", \"age\":32}";
# SENDDATA(data2);
# VAR data3 := TOBYTES("{\"name\":\"John\", \"age\":32}", "iso-8859-1");
# SENDDATA(data3);
# Process received TCP or UDP data and set device values in the Listener script
#
#
# Download data from FTP:
# FTPDOWNLOAD("filePath");
Listener
if RECEIVEDMSG.TOPIC = "zigbee2mqtt/"+ TS0201 
   VAR payloadTemp := PARSEJSON(RECEIVEDMSG.PAYLOAD, "temperature");
   Te := payloadTemp;
   VAR payloadHum := PARSEJSON(RECEIVEDMSG.PAYLOAD, "humidity");
   Hu := payloadHum/100;
   battery := PARSEJSON(RECEIVEDMSG.PAYLOAD,"battery", true);
   voltage := PARSEJSON(RECEIVEDMSG.PAYLOAD,"voltage", true);
   link := PARSEJSON(RECEIVEDMSG.PAYLOAD,"linkquality", true);
end
Service Attributes
Battery
IF(ISNAN(battery),"-",battery+"%");
Battery Voltage
IF(ISNAN(voltage),"-",voltage+"mV");
LinkQuality
IF(ISNAN(link),"-",link+"lqi");
Connection: Packet Parser → MQTT
Possible improvements (5)
  • Temperature calibration (absolute offset) — Configurable via Zigbee2MQTT devices.yaml or frontend UI — not exposed via TapHome template. Applied at Z2M layer.
  • Temperature precision (decimal digits 0-3) — Configured at the Z2M layer, not in TapHome template.
  • Humidity calibration (absolute offset) — Configured at the Z2M layer, not in TapHome template.
  • Humidity precision (decimal digits 0-3) — Configured at the Z2M layer, not in TapHome template.
  • Availability status — Online/offline availability topic — could detect unreachable devices. Not subscribed by the current template.

Sources

Found a problem with this device template?

Tell us what's wrong, what's missing, or how the template should behave. We rely on your feedback to keep the catalog accurate.

Verified by TapHome

Want to use this in your TapHome Core?

Open this template in the Customer Portal to apply it to one of your homes, or to draft a refinement and submit it back to the catalog.

Open in portal