Smart Home Reviews, Guides & Automation Projects

Article may contain affiliate links - read disclosure.

Tuya ZRF01 Zigbee RF Cloner Integration & Review

Photo of author

SHS

0 replies

Review of the Tuya ZRF01, the first Zigbee controlled RF cloner I have found. Created a Zigbee2MQTT converter and ZHA quirk for Home Assistant integration.

View smart picks on Amazon Storefront

The Tuya ZRF01 is a Zigbee RF cloner built to learn and replay radio frequency codes of remotes for garage doors, gates, blinds, and other devices. Infrared blasters are everywhere in the Zigbee2MQTT and ZHA ecosystem, but a pure RF cloner controlled entirely over Zigbee has been nonexistent until now.

Tuya Zigbee RF Cloner ZRF01 Review SmartHomeScene: Featured Image

I bought this device on AliExpress, wrote a fully working Zigbee2MQTT converter and ZHA quirk from scratch, and tested every function against my own garage remote. It supports RF frequencies from 310MHz to 580MHz and has eight channels for cloning eight remote buttons.

What Is the Tuya ZRF01 RF Cloner?

The ZRF01 is a small, mains-powered Zigbee 3.0 device that listens for RF signals and stores up to eight of them in separate memory slots. Once a code is cloned, the device can transmit it on command, the same way the original remote would trigger a garage door, gate, blind motor, or an RF light switch.

The device automatically adapts to the frequency of the remote it is learning from. It supports 310MHz, 315MHz, 330MHz, 390MHz, 418MHz, 430MHz, 433MHz, 447MHz, and 580MHz. It does not support 299MHz or 915MHz. It also needs to sit fairly close to the source remote during learning, as this is not a long range RF cloner.

The device also has a built-in illuminance sensor as an extra, for creating light automations. It can measure ambient light on a scale from 0 to 3000 lux. The device runs on 5V1A USB-C and has a standby current draw of just 55mA.

Supported RF Codes Types

Not all RF remotes work the same way underneath, and this matters for what the Tuya ZRF01 can and cannot clone.

Fixed codes are the simplest and oldest type of RF codes. The remote sends the exact same code every time you press the button, which makes it easy to capture and replay. Most cheap garage doors, gate openers, wireless doorbells, and basic RF light switches use fixed codes.

Rolling codes are a security measure built to defeat simple RF cloning. The code changes on every button press, following an algorithm that stays synchronized between the remote and the receiver. A cloner that only records one transmission cannot reuse it, since the receiver already expects the next code in the sequence. Most modern garage door openers and car key fobs use rolling codes.

Encrypted codes go a step further, wrapping the transmission in cryptography that requires a shared key to decode. Without that key, capturing the signal gets you nothing usable.

The ZRF01 can copy most fixed RF codes from the range of supported frequencies. It cannot learn rolling codes or encrypted remotes. This is a security limitation of nearly every consumer RF cloner on the market, not something specific to this device.

It does support short and long packet mode, which are used for different types of RF codes. During my own testing, short packet mode successfully learned a fixed code garage remote on the first try. The manufacturer notes that short packet mode can occasionally catch some rolling code remotes as well, although I cannot personally confirm that claim either way. If one packet mode fails to learn your remote, simply switch to the other and try again.

Package Contents and Device Teardown

The box contains the ZRF01 unit itself, a printed user manual, and a short USB charging cable, about one meter long. You will need to supply a 5V1A adapter for power, as it ships only with a cable.

Tuya Zigbee RF Cloner ZRF01 Review SmartHomeScene: Package Contents
Tuya Zigbee RF Cloner ZRF01 Package Contents

The ZRF01 is very small and lightweight, measuring 50x50x10mm. You can install it anywhere convenient with a simple sticker. There is a small indicator LED on the front, along with a pairing and reset button on the back.

Once I dismantled the case, I was able to inspect the internals. This device uses the Tuya ZT3L [Datasheet] as a Zigbee communications module, alongside a CMS32L051 [Datasheet] microcontroller that handles the RF learning and transmit logic. An isolated spring antenna sits on one side of the main PCB, which transmits the copied codes on demand.

After the control button, indicator LED, and illuminance sensor, that is all there is to this device. There is an additional HL1117-33 regulator that steps the 5V USB input down to the 3.3V rail the rest of the board runs on. Here is everything inside the case.

Tuya Zigbee RF Cloner ZRF01 Review SmartHomeScene: Fully Open
Tuya Zigbee RF Cloner ZRF01 Fully Open

Home Assistant Integration

The Tuya ZRF01 is not natively supported by Zigbee2MQTT or ZHA. Pairing it gets you a generic, unsupported Tuya device with no usable entities. However, I built a fully working external converter for Zigbee2MQTT and custom quirk for ZHA from scratch, and after a lot of testing, both works flawlessly.

Learning, deleting, and transmitting codes all behave exactly the way they do through the official Tuya app.

Adding Zigbee2MQTT Support

Tuya devices in general do not speak standard Zigbee that most smart home gear uses. Instead, they communicate over a small set of numbered data points, each one representing a single function on the device. Zigbee2MQTT needs a converter file that explains what each of those numbers means and how to read and write it to and from the device.

To get this RF cloner supported in Zigbee2MQTT, I pulled the full data point list directly from the Tuya IoT developer portal, tested each one against the physical device, and mapped every single one to a clear, readable name inside Zigbee2MQTT.

Tuya Zigbee RF Cloner ZRF01 Review SmartHomeScene: Added to Zigbee2MQTT
Tuya Zigbee RF Cloner ZRF01 Added to Zigbee2MQTT

The trickiest part was getting the outgoing commands to actually register. At first, every command looked like it was sent correctly in the logs, yet the device ignored it completely. It turned out certain values need to be tagged in a specific internal format [tuya.enum(0)] before the radio will accept them. Once I corrected that, every single function started working exactly as expected, matching the behavior in the Tuya app.

I have opened a pull request to get this converter merged into Zigbee2MQTT officially, which you can follow here: [GitHub PR #32836]. Until it gets merged, you can add it manually as an external converter.

  1. Navigate to Zigbee2MQTT’s external_converters folder
  2. Create a new .js file and name it zrf01.js
  3. Open the file and paste the contents of the converter below
  4. Restart Zigbee2MQTT
  5. Pair the device
External Converter for Tuya ZRF01 RF Cloner (Zigbee2MQTT)
const exposes = require('zigbee-herdsman-converters/lib/exposes');
const tuya = require('zigbee-herdsman-converters/lib/tuya');
const e = exposes.presets;
const ea = exposes.access;
const slotStatus = {Learn: tuya.enum(0), Delete: tuya.enum(2), Saved: tuya.enum(1)};
const trigger = {Transmit: tuya.enum(0)};

const definition = {
    fingerprint: [
        {
            modelID: 'TS0601',
            manufacturerName: '_TZE284_tdg4ckyh',
        },
    ],
    model: 'ZRF01',
    vendor: 'Tuya',
    description: 'Zigbee RF cloner with 8 slots',
    extend: [
        tuya.modernExtend.tuyaBase({dp: true}),
    ],
    exposes: [
        e.illuminance(),
        e.binary('state', ea.STATE_SET, true, false)
            .withLabel('State')
            .withDescription(`Enable RF learning mode. Must be enabled before 'Learn' can be pressed for any button.`),
        e.binary('pack', ea.STATE_SET, true, false)
            .withLabel('Packet Mode')
            .withDescription(`Enable for 'Long Packet' mode, Disable for 'Short Packet' mode.`),
        ...Array.from({length: 8}, (_, i) => {
            const n = i + 1;
            return e.enum(`button${n}`, ea.STATE_SET, Object.keys(slotStatus))
                .withLabel(`Button ${n} Code Learning`)
                .withDescription(`Press 'Learn' to clone RF code. Press 'Delete' to clear RF code. 'Saved' gets enabled automatically after successful RF cloning.`);
        }),
        ...Array.from({length: 8}, (_, i) => {
            const n = i + 1;
            return e.enum(`start${n}`, ea.SET, Object.keys(trigger))
                .withLabel(`Button ${n} Code Transmit`)
                .withDescription(`Press 'Transmit' to send saved code.`);
        }),
    ],
    meta: {
        tuyaDatapoints: [
            [117, 'state', tuya.valueConverter.raw],
            [118, 'pack', tuya.valueConverter.raw],
            [119, 'illuminance', tuya.valueConverter.raw],
            [101, 'button1', tuya.valueConverterBasic.lookup(slotStatus)],
            [102, 'button2', tuya.valueConverterBasic.lookup(slotStatus)],
            [103, 'button3', tuya.valueConverterBasic.lookup(slotStatus)],
            [104, 'button4', tuya.valueConverterBasic.lookup(slotStatus)],
            [105, 'button5', tuya.valueConverterBasic.lookup(slotStatus)],
            [106, 'button6', tuya.valueConverterBasic.lookup(slotStatus)],
            [107, 'button7', tuya.valueConverterBasic.lookup(slotStatus)],
            [108, 'button8', tuya.valueConverterBasic.lookup(slotStatus)],
            [109, 'start1', tuya.valueConverterBasic.lookup(trigger)],
            [110, 'start2', tuya.valueConverterBasic.lookup(trigger)],
            [111, 'start3', tuya.valueConverterBasic.lookup(trigger)],
            [112, 'start4', tuya.valueConverterBasic.lookup(trigger)],
            [113, 'start5', tuya.valueConverterBasic.lookup(trigger)],
            [114, 'start6', tuya.valueConverterBasic.lookup(trigger)],
            [115, 'start7', tuya.valueConverterBasic.lookup(trigger)],
            [116, 'start8', tuya.valueConverterBasic.lookup(trigger)],
        ],
    },
};

module.exports = definition;

Once successfully paired and added, the device will get identified as Zigbee Model TS0601 with ID _TZE284_tdg4ckyh. Under Definition (Zigbee2MQTT), you should see ZRF01 with description Zigbee RF cloner with 8 slots. This means the converter has been successfully applied. This is what it exposes in Zigbee2MQTT and Home Assistant:

  1. State
    On/Off switch. This must be turned on before you can enable any button slot for learning.
  2. Packet Mode
    On/Off switch. This changes the RF packet capturing mode. Short packet mode learns the vast majority of fixed code remotes. Long packet mode is the alternative to try if a code refuses to learn in short mode.
  3. Button Code Learning
    Eight learning controls, one for each stored slot. Each one has three options, Learn, Delete, and Saved. Selecting Learn arms that specific slot and puts the device into listening mode for that slot only. Once a valid signal comes in, the slot switches itself to Saved automatically, you do not set this manually. Selecting Delete erases whatever code is currently stored in that slot.
  4. Button Code Transmit
    Eight transmitting buttons, one per slot. Pressing Transmit replays whatever code is stored in that slot. The LED blinks red during transmission, the same behavior you get through the official Tuya app.
  5. Illuminance
    Measured ambient light from 0 to 3000 lux.
  6. Linkquality
    Signal quality in LQI

Adding ZHA Support

The quirk below exposes the same entities as the Zigbee2MQTT converter, an on/off switch for State and Packet Mode, a dropdown per slot for Learn, Delete, and Saved, a button entity per slot for Transmit, and the illuminance sensor.

Tuya Zigbee RF Cloner ZRF01 Review SmartHomeScene: Added to ZHA
Tuya Zigbee RF Cloner ZRF01 Added to ZHA
  1. Save the code below as a .py file inside your custom_zha_quirks folder
  2. Make sure enable_quirks and custom_quirks_path are set under zha in your configuration.yaml
  3. Restart Home Assistant
  4. Pair the device
zha:
  enable_quirks: true
  custom_quirks_path: /config/custom_zha_quirks
Custom Quirk for Tuya ZRF01 RF Cloner (ZHA)
import zigpy.types as t
from zigpy.quirks.v2 import EntityType
from zhaquirks.tuya import TUYA_CLUSTER_ID
from zhaquirks.tuya.builder import TuyaQuirkBuilder


class SlotStatus(t.enum8):
    """Per-slot learn status, matches raw Tuya DP values 0/1/2."""

    Learn = 0x00
    Saved = 0x01
    Delete = 0x02


class Trigger(t.enum8):
    """Single-option replay trigger, matches raw Tuya DP value 0."""

    Transmit = 0x00


quirk = (
    TuyaQuirkBuilder("_TZE284_tdg4ckyh", "TS0601")
    .tuya_switch(
        dp_id=117,
        attribute_name="state",
        entity_type=EntityType.STANDARD,
        translation_key="state",
        fallback_name="State",
    )
    .tuya_switch(
        dp_id=118,
        attribute_name="pack",
        entity_type=EntityType.STANDARD,
        translation_key="packet_mode",
        fallback_name="Packet Mode",
    )
    .tuya_illuminance(dp_id=119)
)

for i in range(1, 9):
    quirk = quirk.tuya_enum(
        dp_id=100 + i,
        attribute_name=f"button{i}",
        enum_class=SlotStatus,
        translation_key=f"button{i}_code_learning",
        fallback_name=f"Button {i} Code Learning",
    )

for i in range(1, 9):
    quirk = (
        quirk.tuya_dp_attribute(
            dp_id=108 + i,
            attribute_name=f"start{i}",
            type=Trigger,
        )
        .write_attr_button(
            attribute_name=f"start{i}",
            cluster_id=TUYA_CLUSTER_ID,
            attribute_value=Trigger.Transmit,
            translation_key=f"button{i}_code_transmit",
            fallback_name=f"Button {i} Code Transmit",
        )
    )

quirk.add_to_registry()

How To Copy an RF Code

Cloning an RF remote code is simple, but it does require clicking the buttons in the correct order:

  1. Enable RF Learning mode, by turning on State
  2. Press Learn under Button N Code Learning
  3. The indicator LED should turn on red
  4. Hold the remote near the RF cloner
  5. Press the remote button until the slot switches to Saved
  6. The indicator LED should turn off red and remain blue
  7. Press Transmit on that slot to test it

If the indicator LED stays red, it means it hasn’t copied the code yet. Switch to Long Packet Mode and try again from the beginning. When everything is correct and the actual code is not encrypted, the device learns it immediately, within a second.

Summary

The Tuya ZRF01 is the first-ever Zigbee RF remote controller I’ve ever encountered. There are many Zigbee infrared remotes out there, several of which I’ve reviewed already (ZS05 and ZS06). This RF cloner is the first device that doesn’t use Wi-Fi or Bluetooth, making things much easier and less cloud dependent.

The limitations of the Tuya ZRF01 are the same ones every RF cloner deals with. No rolling code support, no encrypted code cloning and a relatively short learning range, which means you need the source remote next to the unit. Transmitting range is quite solid, the same as with my existing remote. I was able to open my garage door from about 9 meters away, just like my original remote.

With my external converter and ZHA quirk now fully working, this device is a great local-only way to control garage doors, gates, RF light switches and other legacy RF equipment from Home Assistant. At the moment, you can get it only on AliExpress.

Tuya Zigbee RF Cloner ZRF01 Review SmartHomeScene: Where to buy

Tuya Zigbee RF Cloner ZRF01

Zigbee 3.0

310MHz to 580MHz

5V1A, USB-C

Zigbee2MQTT

Leave a Comment