private@homelab: ~/latest
local-first guides · privacy-aware · no noisy tracking
private@homelab:~$ cat guides/article.md
· ·
7–10 minutes
read

Tuya TS004F Zigbee2MQTT Setup: Knob, Switch, or Both

Pair the Tuya TS004F knob or scene switch in Zigbee2MQTT, map rotation to real actions, and pick command vs. event mode. Fully local, no Tuya app.

The Tuya TS004F shows up under a handful of names and at least two physical shapes, and that is the first source of confusion. Buy it as a round black “smart knob” and you would expect a rotate action somewhere in Zigbee2MQTT’s exposes list. Whether you find one depends on which Zigbee2MQTT device definition your unit matched, and that is not the same question as which model number is printed on the box.

This is a Zigbee device, paired through Zigbee2MQTT with no Tuya cloud account and no Smart Life app involved at any point. Everything below stays local: pairing, the action list, and the mode switch that changes what the device reports.

One model string, several Zigbee2MQTT definitions

TS004F is a model string, not a product. Tuya stamps it on hardware in several shapes, and Zigbee2MQTT matches a device definition on the manufacturer code alongside the model, so different units land on different device pages with different exposes and different action lists. Before anything else, find the page your unit actually matched. Zigbee2MQTT’s frontend links to it directly from the device page.

Zigbee2MQTT page Hardware Rotation in the action list
TS004F Flat four-button scene remote No
ERS-10TZBVK-AA Round smart knob (Tuya / Moes) Yes — rotate_left, rotate_right
TS004F_1 Moes-branded four-button variant No
TS004F_6_button Six-button wireless panel No
Note · compatibility

The frontend’s device-page link is the authoritative answer, not the shape of the enclosure. If Zigbee2MQTT identifies your round knob as plain TS004F rather than ERS-10TZBVK-AA, your unit matched the four-button definition and the rotate actions below will not appear for it. That is a converter-matching outcome, not a broken device.

Pairing: joined to your coordinator, or Touchlink-bound without one

The TS004F supports two setups. The one most readers will use is standard: join it to your Zigbee network through your Z2M coordinator, then bind it to a group of lights or other devices so button presses and rotation control that group. The official device page is explicit that binding here only ever targets a group. It does not support driving one specific device on its own through that mechanism.

The second path skips the coordinator entirely. The remote is Touchlink-capable, so it can bind directly to a group of Touchlink-capable bulbs (Hue and similar) without ever joining a Zigbee2MQTT network. That is a fallback for standalone lighting control, not the setup most Home Assistant users want, since it bypasses Z2M and HA automations completely.

The action list, and where rotation actually appears

On the base four-button definition, the action list splits roughly into two buckets:

Category Action values What triggers it
Numbered button taps 1_single, 1_double, 1_hold, 2_single, 2_double, 2_hold, 3_single, 3_double, 3_hold, 4_single, 4_double, 4_hold A physical press on the corresponding numbered button
Remote-style commands on, off, brightness_step_up, brightness_step_down, brightness_move_up, brightness_move_down, color_temperature_step_up, color_temperature_step_down, brightness_stop Standard smart-remote gestures issued to the bound group

The knob’s definition carries a different list. Its taps are bare single, double and hold with no numeric prefix, because there is only one button to press. Alongside the same brightness and colour-temperature step commands it also publishes hue_move, saturation_move, hue_stop, toggle, and the two values people go looking for and are told do not exist: rotate_left and rotate_right.

Which of those a physical turn produces is decided by operation_mode. In command mode the knob behaves as an ordinary Zigbee controller and emits level-control commands, so a turn surfaces as brightness_step_up or brightness_step_down, with the _move_ variants for a sustained turn. In event mode it reports rotate_left and rotate_right instead. That is why one blueprint thread tells you to trigger on brightness_step_up and another tells you to trigger on rotate_left: both are correct, for different modes.

If your unit matched the plain four-button definition, there is no rotate value to find at all, and the brightness-step actions are the whole story.

Mapping rotation to something useful in Home Assistant

With the knob in command mode, wiring a turn into an automation is ordinary MQTT trigger work:

automations.yaml
- alias: "TS004F knob dims office lamp"
  trigger:
    - platform: mqtt
      topic: "zigbee2mqtt/office_knob"
      value_template: "{{ value_json.action }}"
      payload: "brightness_step_up"
  action:
    - service: light.turn_on
      target:
        entity_id: light.office_lamp
      data:
        brightness_step_pct: 5

A mirrored automation on brightness_step_down with a negative step handles the other direction. In event mode, swap the payloads for rotate_left and rotate_right. Our guide to event entities vs. the legacy action sensor covers whether your Z2M version surfaces these as an event entity or a legacy action sensor, which changes the trigger platform you would use instead of a raw MQTT topic.

Note · context

One independent write-up reports that feeding negative brightness_step values straight into a light’s brightness attribute dims it smoothly to off rather than stopping at some minimum. That is a single informal source rather than documented behaviour, so test it on your own lights before an automation depends on it.

command vs. event operation_mode: picking one

operation_mode is an enum with two settings, and it changes what the device sends — for button presses on every shell, and for rotation on the knob:

Mode Behavior Best for
command Sends standard Zigbee commands to the bound group. Immediate, no delay before an action fires. On the knob, a turn reports as brightness_step_up / _down. Group lighting control where you want the fastest response and do not need to distinguish single from double tap.
event Reports discrete events to the coordinator. Adds a short delay so single, double and hold taps can be told apart, and can feel sluggish under rapid presses. On the knob, a turn reports as rotate_left / rotate_right. Automations that branch on tap count, or that want rotation as a named action rather than a brightness command.

The gesture that toggles the mode depends on which shell you have. On the four-button remote it is holding buttons 2 and 4 together for six seconds. On the one-button knob, community blueprint documentation gives a triple click of the knob’s button. Either way you can also set it directly over MQTT:

terminal
mosquitto_pub -h 192.168.10.20 -t "zigbee2mqtt/office_knob/set" \
  -m '{"operation_mode": "event"}'

Command mode is the better starting point for most scene-switch use cases. It is the mode binding acts through, since binding works by the device issuing commands to its group, and it is what most published blueprints assume. Move to event mode when a specific automation genuinely needs tap-count branching, or when you would rather trigger on a named rotate action than on a brightness command.

The device page does not state a factory default, so do not assume one. Zigbee2MQTT publishes the current setting as operation_mode in the device’s state, and the value is writable, so read it in the exposes panel after pairing and set it to whichever mode your automations expect.

The group-only binding limit

Warning

Binding a TS004F only ever targets a group, never one specific device. If you want the knob to control a single bulb, put that bulb in a group by itself first, then bind the remote to the group. There is no direct-to-device binding path.

This trips people up because most other Zigbee remotes let you bind straight to a single light. If a single-device workflow matters more than binding’s low latency, skip binding entirely and drive the device with an HA automation on the action topic, the way the rotation example above does. Our TS0041 and TS0043 guides cover the sibling Tuya scene switches, which take that automation route by default: neither exposes an operation_mode setting at all, so the command-versus-event split described here has no equivalent on them.

Background: why the mode switch exists

The mode toggle is not an arbitrary Tuya design choice. A 2021 Zigbee2MQTT discussion documents the original support gap: early TS004F units were fingerprinting as a TS0044, a similar four-button device, which meant they initially produced only single-tap actions no matter how the buttons were pressed. The command/event mode-switching logic that exists today was added to correct that misidentification. The thread dates to December 2021 and describes a historical fix, not a currently open problem.

That history is also the cleanest way to answer “what is the difference between TS004F and TS0044”. They are related four-button devices from the same family, but the TS0044 reports scene events only. It carries no operation_mode setting and does not act as a standard Zigbee controller you bind to a group, which is exactly the capability the TS004F needed once its identity was sorted out.

Note · context

The four-button TS004F’s device page specifies a single CR2430 (3V) cell, not a CR2032. A CR2032 will physically fit some shells, but it is not the stated cell and it changes your voltage and capacity margin. Check the cell in your own unit rather than assuming across shapes — the enclosures come from different sellers.

What is documented, what is community-observed, and what to check on your own unit

The exposes lists, the action enums, the battery reporting and the group-only binding constraint all come from the official Zigbee2MQTT device pages, which is the part you can treat as settled against current 2.x device definitions. So does the existence of rotate_left and rotate_right on the knob’s definition, despite how often you will see it claimed that no rotate action exists.

Two things sit on thinner ground. The negative-brightness_step behaviour traces to one informal write-up rather than a device page, and the knob’s triple-click mode toggle comes from community blueprint documentation rather than a vendor manual. Both are worth confirming on your own hardware before an automation depends on them.

After pairing, do two things before writing any automation: open the device page link in the Zigbee2MQTT frontend to confirm which definition your unit matched, and read the current operation_mode value in the exposes panel. Those two facts determine every action value you will see, and a mismatch on either is the usual reason an automation copied from a blueprint thread never fires.

local-firstHome Assistantno-cloud