Zigbee2MQTT - Tuya 4-button Scene Switch (TS0044)

This is a blueprint for the Tuya 4-button Scene Switch.

Supported actions for each button:

  1. Short press
  2. Double press
  3. Long press (5 seconds)

Get started

Click the badge to import this Blueprint: (needs Home Assistant Core 2021.3 or higher)

Open your Home Assistant instance and show the blueprint import dialog with a specific blueprint pre-filled.

Or import this Blueprint by using the forum topic URL:

blueprint:
  name: Zigbee2MQTT - Tuya 4-Button Scene Switch
  description: Automate your Tuya 4-Button Scene Switch via Zigbee2MQTT.
  domain: automation
  input:
    switch:
      name: Tuya 4-Button Scene Switch
      description: Tuya 4-Button Scene Switch to use
      selector:
        entity:
          integration: mqtt
          domain: sensor
    button_one_short_press:
      name: Single Press - Button 1
      description: Action to run on button 1 (lower-left) single press
      default: []
      selector:
        action: {}
    button_one_double_press:
      name: Double Press - Button 1
      description: Action to run on button 1 (lower-left) double press
      default: []
      selector:
        action: {}
    button_one_long_press:
      name: Long Press - Button 1
      description: Action to run on button 1 (lower-left) long press
      default: []
      selector:
        action: {}
    button_two_short_press:
      name: Single Press - Button 2
      description: Action to run on button 2 (lower-right) single press
      default: []
      selector:
        action: {}
    button_two_double_press:
      name: Double Press - Button 2
      description: Action to run on button 2 (lower-right) double press
      default: []
      selector:
        action: {}
    button_two_long_press:
      name: Long Press - Button 2
      description: Action to run on button 2 (lower-right) long press
      default: []
      selector:
        action: {}
    button_three_short_press:
      name: Single Press - Button 3
      description: Action to run on button 3 (upper-right) single press
      default: []
      selector:
        action: {}
    button_three_double_press:
      name: Double Press - Button 3
      description: Action to run on button 3 (upper-right) double press
      default: []
      selector:
        action: {}
    button_three_long_press:
      name: Long Press - Button 3
      description: Action to run on button 3 (upper-right) long press
      default: []
      selector:
        action: {}
    button_four_short_press:
      name: Single Press - Button 4
      description: Action to run on button 4 (upper-left) single press
      default: []
      selector:
        action: {}
    button_four_double_press:
      name: Double Press - Button 4
      description: Action to run on button 4 (upper-left) double press
      default: []
      selector:
        action: {}
    button_four_long_press:
      name: Long Press - Button 4
      description: Action to run on button 4 (upper-left) long press
      default: []
      selector:
        action: {}
  source_url: https://github.com/AramidX/ha-blueprint/blob/4de1fb2c9fe1d96a58f09c28b1d4a7760e0e9d2b/blueprints/tuya/tuya_4button_scene_switch_z2m.yaml
mode: restart
max_exceeded: silent
trigger:
- platform: state
  entity_id: !input "switch"
  attribute: action
action:
- variables:
    command: "{{ trigger.to_state.state }}"
- choose:
  - conditions: 
    - "{{ command == '1_single' }}"
    sequence: !input "button_one_short_press"
  - conditions: 
    - "{{ command == '2_single' }}"
    sequence: !input "button_two_short_press"
  - conditions: 
    - "{{ command == '3_single' }}"
    sequence: !input "button_three_short_press"
  - conditions: 
    - "{{ command == '4_single' }}"
    sequence: !input "button_four_short_press"
  - conditions: 
    - "{{ command == '1_double' }}"
    sequence: !input "button_one_double_press"
  - conditions: 
    - "{{ command == '2_double' }}"
    sequence: !input "button_two_double_press"
  - conditions: 
    - "{{ command == '3_double' }}"
    sequence: !input "button_three_double_press"
  - conditions: 
    - "{{ command == '4_double' }}"
    sequence: !input "button_four_double_press"
  - conditions: 
    - "{{ command == '1_hold' }}"
    sequence: !input "button_one_long_press"
  - conditions: 
    - "{{ command == '2_hold' }}"
    sequence: !input "button_two_long_press"
  - conditions: 
    - "{{ command == '3_hold' }}"
    sequence: !input "button_three_long_press"
  - conditions: 
    - "{{ command == '4_hold' }}"
    sequence: !input "button_four_long_press"

8 Likes

Wow, this is great, I’ve received this switch like 10 minutes ago and wanted to check if there is was a blueprint available…
Great timing mate.
Will test it out once I received the battery, it was not included unfortunately…

1 Like

Received mine yesterday, and this blueprint is working as expected. Thanks :smiley:

Blueprint works like a charm and really does makes it neater to automate the switch!

@kippuh @marcvanrossen is it possible to connect this through zigbee2mqtt? I’m trying, but can’t figure it out. Or do you guys both have a gateway for this device?

Nevermind, didn’t knew i had to press the lower-left button to join.

However, my device has type; TS004F (and nog TS0044). It is not recognized, however it is the same one as TS0044 as far as i see. Now following this tuts:

Yes. Just add it like you add other devices to zigbee2mqtt

To enter pairing mode hold bottom left button for 10 seconds until all 4 LEDs start flashing.

More info: TuYa TS0044 control via MQTT | zigbee2mqtt.io

Yeah, thanks! Changed my msg at same time you replied. But my modelno is different as you can see in my previous msg. Very strange…

Seems like there are 3 of us now with this new model! There’s a short discussion on the zigbee2mqtt GitHub: TS004F (instead of TS0044) buttons has only single tap · Discussion #7158 · Koenkk/zigbee2mqtt · GitHub

I’m the next one who has a new model TS004F :worried:

Hi there! Same problem. I have the version TS004F. ZHA was always easy and simple but it only works the right side of the button.
I switched to zigbee2mqtt and it says my device is not supported. Tried to follow the tutorial in links above and I get stuck on that part that says: “The next step is the to add an entry of your device to node_modules/zigbee-herdsman-converters/devices.js. In order to provide support for E.G. the lumi.sens from step 1 you would add:”

Does anyone know what path this is? How to find it in Home Assistant?

We all have the same problem: how to find “node_modules/zigbee-herdsman-converters/devices.js” using hassio with zigbee2mqtt add-on.

You don’t actually need to change the devices.js, you can use the external_converters feature of zigbee2mqtt, then you can just make your own tuya.js file and implement the new device. However, that won’t help, as the TS004F has a very different format of messages compared to TS0044. It seems to only have one endpoint active at start (instead of 4 on the TS0044). And that one endpoint seems to be tied to all of the 4 keys, whereas the old one had 4 separate for every key. My hunch is that it requires configuration prior to using the switch, the format of which I don’t know. If anyone has a Tuya gateway and an app, maybe (s)he could sniff the messages and find exactly what is the format. I didn’t even see any battery level being reported with mine at all, I guess that can be configured as well. This is all just guessing on my part, of course, but it doesn’t look similar to any other tuya switch I’ve seen in devices.js file.

Thank for the input but this is just too complex for a button that was supposed do make my life more convenient. :man_facepalming:t2:

Does anyone have a link for the AliExpress vendor that sells the TS0044 model?

2 Likes

Hey, I’m in the same situation. I thought it was gonna be already working, that’s why I bought it. But it looks like this is their updated model and until someone with experience and equipment supports it. I would also like to buy TS0044, but from outside, there doesn’t seem to be a way to tell. My guess is they are now producing this model and the old one won’t be available, but I may be wrong. Our best bet is to either buy some other switch or just hope someone comes along and help us.

Hi everyone. I faced the same problem. I bought a TS004F switch and it did not work with zigbee2mqtt. So I spent a little time and wrote an external conveter for it. But I couldn’t get everything to work. Single press events work for all 4 buttons, and hold event works only for the 2 right side buttons. No other events (like double click) appear in the console in debug mode so I can’t write a converter for them.

To use my converter add the following lines to your configuration.yaml:

external_converters:
  - TS004F.js

And save the code below in the file data/TS004F.js next to the file configuration.yaml:
(UPD: the data dir is the dir where the configuration.yaml file is located and may have a different name for you)

const fz = require('zigbee-herdsman-converters/converters/fromZigbee');
const tz = require('zigbee-herdsman-converters/converters/toZigbee');
const exposes = require('zigbee-herdsman-converters/lib/exposes');
const reporting = require('zigbee-herdsman-converters/lib/reporting');
const extend = require('zigbee-herdsman-converters/lib/extend');
const e = exposes.presets;
const ea = exposes.access;

const bind = async (endpoint, target, clusters) => {
    for (const cluster of clusters) {
        await endpoint.bind(cluster, target);
    }
};

/* 
  Buttons numbers:
      -------
     | 1 | 3 |
     |-------|
     | 2 | 4 |
      -------
*/

const leftButtonsConverter = {
    cluster: 'genOnOff',
    type: ['commandOn', 'commandOff', 'commandToggle'],
    convert: (model, msg, publish, options, meta) => {
        if (msg.type === 'commandOn') {
            return { action: '1_single' };
        }
        
        if (msg.type === 'commandOff') {
            return { action: '2_single' };
        }
    },
};

const rightButtonsConverter = {
    cluster: 'genLevelCtrl',
    type: ['commandStep', 'commandMove', 'commandStop'],
    convert: (model, msg, publish, options, meta) => {    
        if (msg.type === 'commandStep') {
            if (msg.data.stepmode === 0) {
                return { action: '3_single' };
            }
            else if (msg.data.stepmode === 1) {
                return { action: '4_single' };
            }
        }
        else if (msg.type === 'commandMove') {
            if (msg.data.movemode === 0) {
                return { action: '3_hold' };
            }
            else if (msg.data.movemode === 1) {
                return { action: '4_hold' };
            }
        }
        else if (msg.type === 'commandStop') {
            // No data available to determine which button was released
            return { action: 'release' };
        }
        
        // No 'double' events are fired
    },
};

const definition = {
    zigbeeModel: ['TS004F'],
    model: 'TS004F',
    vendor: 'TuYa',
    description: 'Wireless switch with 4 buttons',
    whiteLabel: [{vendor: '_TZ3000_xabckq1v', model: 'TS004F'}],

    // Exposed commands are similar to the Tuya TS0044 switch
    exposes: [
        e.battery(),
        e.action([
            '1_single', 
            '2_single', 
            '3_single', '3_hold',
            '4_single', '4_hold'
            
            /*
            '1_single', '1_double', '1_hold',
            '2_single', '2_double', '2_hold',
            '3_single', '3_double', '3_hold',
            '4_single', '4_double', '4_hold'
            */
        ])
    ],

    fingerprint: [
        {
            modelID: 'TS004F',
            manufacturerName: '_TZ3000_xabckq1v'
        },
    ],
    fromZigbee: [
        fz.battery,
        leftButtonsConverter,
        rightButtonsConverter,
    ],
    toZigbee: [
    ],
    meta: {
        configureKey: 1,
    },
    configure: async (device, coordinatorEndpoint, logger) => {
        const endpoint = device.getEndpoint(1);
        await bind(endpoint, coordinatorEndpoint, ['genOnOff', 'genLevelCtrl']);
        
        await bind(endpoint, coordinatorEndpoint, ['genPowerCfg']);
        const payload = [{
            attribute: 'batteryPercentageRemaining',
            minimumReportInterval: 0,
            maximumReportInterval: 3600,
            reportableChange: 1,
        }, {
            attribute: 'batteryVoltage',
            minimumReportInterval: 0,
            maximumReportInterval: 3600,
            reportableChange: 1,
        }];
        await endpoint.configureReporting('genPowerCfg', payload);
    },
};

module.exports = definition;

Then you can use the blueprint described here.

7 Likes

Thanks, I verified it and it works as you said. I had to remove the extend import line, but it is unused anyway. And the configure step fails with timeout, so I guess you based it off of some other similar device, or does configure work with your switch? Do you think there is a chance a different mode can be configured so all the functions work for all buttons?

Edit: Configure works now, thanks!

Thank you so much for sharing it!

Yes, you’re right. This is my first expirience with home assistant programming. Before writing my own converters, I tried some converters for Tuya devices that are already supported, and I saw “configuring…” logs in the console during this time. I did not get what this means :slight_smile:

Could you please share with others the steps I missed to get my config working?

UPD: I forgot to say that I was using the dev branch of zigbee2mqtt.

Thank You very much for sharing this.

Aiditz, thank you again for putting it together. I am not really familiar with converters.
Can you please give us some more details about it?
I added the first code to configuration.yaml, but I cant find the path data/ to add TS00F4.js file.’

Also, I am not sure if I am using the dev branch of zigbee2mqttt. Is it essential to get this working?