Skip to content

TuyaMCU - Module (54) is configured for devices with a Tuya Wi-Fi module and a secondary MCU.

Originally, in those devices, the Wi-Fi module takes care of network and software features. Meanwhile, the MCU controls the hardware based on commands received from the Wi-Fi module or built-in controls (buttons, switches, remotes and similar) and reports the status back to the Wi-Fi module.

TuyaMCU module facilitates communication between Tasmota and the MCU using Tuya Serial Port Communication Protocol:

  • TuyaMCU command maps device functions to Tasmota components
  • TuyaSend<x> command calculates and sends complex serial commands using only two parameters
  • TuyaReceived MCU response interpreted and publishes as status message and a JSON payload to an MQTT topic

TuyaMCU Command~

Command TuyaMCU is used to map Tasmota components to Tuya device dpId's.

Warning

Used only if your device is defined as module TuyaMCU (54).

Command value consists of two comma separated parameters: fnId and dpId.

TuyaMCU <fnId>,<dpId>
where <fnId> is a Tasmota component and <dpId> is the dpId to map the function to.

Example

TuyaMCU 11,1 maps Relay1 (fnId 11) to dpId 1.

If any existing entry with same fnId or dpId is already present, it will be updated to the new value.

Entry is removed when fnId or dpId is 0.

When no parameters are provided TuyaMCU prints the current mapped values.

dpId~

All the device functions controlled by the MCU are identified by a dpId.
Whenever a command is sent to the MCU, this dpId determines which component needs to be controlled and the applies when the status is received from MCU.

There is no way to autodetect dpId's and their functions.

To assist in the process of determining what dpId does what, there is a bookmarklet available that can be used on the console screen. This will send the weblog and other required commands automatically, and present the TuyaMCU information in a single table allowing for easier testing.

Use this procedure to determine which dpId's are available:

  1. Go to Configure -> Console option in Tasmota web interface.
  2. Use command weblog 4 to enable verbose logging in web interface.
  3. Observe the log. After every 9-10 seconds you should see Tuya specific messages labelled as TYA:.
{"TuyaReceived":{"Data":"55AA0107000501010001000F","Cmnd":7,"CmndData":"0101000100","DpType1Id1":0,"1":{"DpId":1,"DpIdType":1,"DpIdData":"00"}}}
TYA: fnId=11 is set for dpId=1
TYA: RX Relay-1 --> MCU State: Off Current State:Off
{"TuyaReceived":{"Data":"55AA01070005020100010010","Cmnd":7,"CmndData":"0201000100","DpType1Id2":0,"2":{"DpId":2,"DpIdType":1,"DpIdData":"00"}}}
TYA: fnId=0 is set for dpId=2
{"TuyaReceived":{"Data":"55AA01070005030100010011","Cmnd":7,"CmndData":"0301000100","DpType1Id3":0,"3":{"DpId":3,"DpIdType":1,"DpIdData":"00"}}}
TYA: fnId=0 is set for dpId=3
{"TuyaReceived":{"Data":"55AA01070005040100010012","Cmnd":7,"CmndData":"0401000100","DpType1Id4":0,"4":{"DpId":4,"DpIdType":1,"DpIdData":"00"}}}
TYA: fnId=0 is set for dpId=4
  1. Observe all lines printed as TYA: FnId=0 is set for dpId=XXX and note all dpId values.

Now that you have a list of usable dpId's you need to determine what their functions are:

  1. Consulting our list of commonly used dpId's and existing device configurations
  2. Observing Tasmota logs while activating features of the device (with a remote or on device controls) and correlating log messages and looking at the DpIdType and DpIdData values (eg: boolean vs value)
  3. Extrapolating possible function of the dpId based on Data Type and Function Command, then testing using TuyaSend<x>

fnId~

Identifier used in TuyaMCU command to map a dpId to a Tasmota component.

Component FnId Note
Switch1 to Switch4 1 to 4 Map only to dpId with on / off function
Relay1 to Relay8 11 to 18 Map only to dpId with on / off function
Lights 21 to 28 21 for Dimmer
22 for Dimmer2
23 for CCT Light
24 for RGB light
25 for white light
26 for light mode set (0 = white and 1 = color)
27 to report the state of Dimmer1
28 to report the state of Dimmer2
Power Monitoring 31 to 33 31 for Power (in deci Watt)
32 for Current (in milli Amps)
33 for Voltage (in deci Volt)
Relay1i to Relay8i 41 to 48 Map only to dpId with on / off function
Battery powered sensor mode 51 Battery powered devices use a slightly different protocol
Enum dpId 61 to 64 Range for each enum is 0 to 31
Sensors 71 to 79 Range of sensors (temperature, humidity, co2, gas, etc)
Timers 81 to 84 Manage integer based timers
Extra functions 97 to 99 97 for motor direction
98 for error logging (report only)
99 as a dummy function

Note

This component is under active development which means the function list may expand in the future.

Since the majority of devices have a power on/off functions on dpId 1 it's mapped to fnId 11 (Relay1) by default. If you don't need it, map it to fnId 99 with TuyaMcu 99,1

Danger

Mapping a relay or switch to a dpId that is not a simple on/off function (data Type 1) might result in unwanted power toggling (i.e. dpId sends value of 4 which toggles the relay to Power 4 aka blink mode)

TuyaSend Command~

Command TuyaSend is used to send commands to dpId's. It is required for dpId's that shouldn't be mapped to a fnId.

With this command it is possible to control every function of the dpId that is controllable, providing you know its data type and data length. With them provided, the rest of the protocol command is calculated.

Command's value consists of two comma separated parameters: dpId and data.

TuyaSend<x> dpId,data

TuyaSend0~

Used without payload to query states of dpID's.

TuyaSend1~

Sends boolean (Type 1) data (0/1) to dpId (Max data length 1 byte)

Example

TuyaSend1 1,0 sends value 0 to dpId=1 switching the device off

TuyaSend2~

Sends integer or 4 byte (Type 2) data to dpId (Max data length 4 bytes)

Example

TuyaSend2 14,100 sends value 100 to dpId=14 setting timer to 100 minutes

TuyaSend3~

Sends an ASCII string (Type 3) data to dpId (Max data length? Not known at this time).

Warning

Note that when sending color values, the MCU may interpret lower case and upper case hex codes differently. You may need to test with your specific MCU to ensure that the values sent properly render the color you desire.

Example

TuyaSend3 108,ff0000646464ff sends a 14 char hex string to dpId=108 (Type 3) containing RGBHSV values to control a light

TuyaSend4~

Sends enum (Type 4) data (0/1/2/3/4/5) to dpId (Max data length 1 bytes)

Example

TuyaSend4 103,2 sends value 2 to dpId=103 to set fan speed to high

TuyaSend5~

Sends an HEX string (Type 3) data to dpId (Max data length? Not known at this time). Does NOT require 0x prefix.

Example

TuyaSend5 108, ABCD sends a string of 2 bytes defined by hex codes to dpId=108

Differences between TuyaSend3 and TuyaSend5:

  • TuyaSend3 108, ABCD sends 55aa000600086c030004414243448a where the payload is 41424344 which is the ASCII bytes representing the string ABCD
  • TuyaSend5 108, ABCD sends 55aa000600066c030002abcdf4 where the payload is a abcd which is a string of 2 bytes 0xAB and 0xCD

TuyaSend6~

Sends payload with raw data (type 0) to dpId (Max data length? Not known at this time). Does NOT require 0x prefix.

Example

TuyaSend6 37, 060000DC08000096 sends raw data defined by hex codes to dpId=37

Differences between TuyaSend3, TuyaSend5 and TuyaSend6: * TuyaSend3 and TuyaSend5 sends payload with the data type 0x03 = string * TuyaSend6 sends payload with the data type 0x00 = raw

TuyaSend8~

Used without payload to get device information and dpId states. Replaces SerialSend5 55aa000100000

TuyaSend9~

Use without any payload to toggle a new STAT topic reporting changes to a dpId, for example:

17:45:38 MQT: stat/TuyaMCU/DPTYPE1ID1 = 1

TuyaReceived~

Every status message from the MCU gets a JSON response named TuyaReceived which contains the MCU protocol status message inside key/value pairs which are hidden from the user by default.

To publish them to a MQTT Topic of tele/%topic%/RESULT you need to enable SetOption66 1.

To avoid some cyclic MCU <-> ESP messages published via MQTT to the topic tele/%topic%/RESULT you need to enable SetOption137 1.

If SetOption137 set to 1 the following cmds will not forwarded: - the heartbeat between the MCU <-> ESP (every 10 seconds, TUYA_CMD_HEARTBEAT) - the Wifi-State between the MCU <-> ESP (during start-up and wifi events, TUYA_CMD_WIFI_STATE) - the local time info query of the MCU (every minute, TUYA_CMD_SET_TIME) - the received update package info from MCU (during firmware update of Tuya MCU, TUYA_CMD_UPGRADE_PACKAGE)

If SetOption137 set to 0 all received Tuya MCU messages will be published. SetOption137 is very useful to reduce the MQTT-traffic.

Example~

After issuing serial command 55aa0006000501010001010e (Device power (dpId=1) is mapped to Relay1 (fnId=11)) we get the following console output (with weblog 4):

19:54:18 TYA: Send "55aa0006000501010001010e"
19:54:18 MQT: stat/GD-30W/STATE = {"Time":"2019-10-25T19:54:18","Uptime":"0T01:45:51","UptimeSec":6351,"Heap":27,"SleepMode":"Dynamic","Sleep":0,"LoadAvg":999,"MqttCount":1,"POWER1":"ON","POWER2":"OFF","POWER3":"ON","POWER4":"OFF","POWER5":"ON","Dimmer":100,"Fade":"OFF","Speed":1,"LedTable":"OFF","Wifi":{"AP":1,"SSId":"HTPC","BSSId":"50:64:2B:5B:41:59","Channel":10,"RSSI":24,"LinkCount":1,"Downtime":"0T00:00:08"}}
19:54:18 MQT: stat/GD-30W/RESULT = {"POWER1":"ON"}
19:54:18 MQT: stat/GD-30W/POWER1 = ON
19:54:18 MQT: stat/GD-30W/RESULT = {"TuyaReceived":{"Data":"55AA0007000501010001010F","ChkSum":"0x0F","Cmnd":7,"CmndDataLen":5,"CmndData":"0101000101","DpId":1,"DpIdType":1,"DpIdLen":1,"DpIdData":"01"}}
19:54:18 TYA: fnId=11 is set for dpId=1
19:54:18 TYA: RX Relay-1 --> MCU State: On Current State:On
Above TYA: fnId=11 is set for dpId=1 you can see the JSON response for that dpId. This JSON string displays the response MCU gave to our command.

"Data" field contains the complete response and the rest of the key/value pairs show the protocol broken into parts. "DpId", "DpIdData" and "DpIdType" are the ones we're most interested in since we can use them for TuyaSend.

Tip

Use command TuyaSend8 and/or TuyaSend0 at any time to request statuses of all dpId's from the MCU.

Use in Rules~

This data can also be used as a trigger for rules using TuyaReceivedData#Data=hex_string

Rule1 on TuyaReceived#Data=55AA000700056E040001007E do publish2 stat/tuya_light/effect rgb_cycle endon
will publish a status message to a custom topic when 55AA000700056E040001007E appears in "Data" field of the response.

Device Configurations~

Before proceeding identify dpId's and their function.

Dimmer~

We need to configure four functions of a dimmer:

  1. Dimming dpId
  2. Dimming Range
  3. Dimming less than 10%

Dimming dpId~

The dimmer FunctionId is 21. On a dimmer dpId generally is 2 or 3. Try both.

  1. Go to the Tasmota Console and type TuyaMCU 21,2 and wait for it to reboot.
  2. Enter Backlog Dimmer 10; Dimmer 100 in the Console.
  3. If your bulb responds to Dimmer commands, you have successfully configured the dimmer FunctionId. Make note of it.
  4. If not try id 3 and if even 3 doesn't work keep trying Ids from all unknown Ids from the log until one works.

Dimming Range~

Once you have figured out the dimming functionId, we need to find the maximum dimming range. Once the dimming Id is set, the logs will continue

TYA: Heartbeat  
TYA: RX Packet: "55aa03070005010100010011"  
TYA: RX Relay-1 --> MCU State: Off Current State:Off    
TYA: RX Packet: "55aa03070008020200040000000720"    
TYA: FnId=21 is set for dpId=2  
TYA: RX Dim State=7 

Now using the hardware buttons increase the dimmer to its maximum and observe the log. The Dim State=XXX shows the current dimmer level reported by MCU. Once the dimmer is at max, note this number. Again using hardware buttons decrease dimmer to minimum and note the number for minimum.
Now we need to tell Tasmota to use maximum and minimum values. This controlled by DimmerRange command. We can set it using DimmerRange <Min>,<Max> where <Min> is the minimum dimmer state and <Max> maximum dimmer state reported in logs.

Once set, try dimmer 100 in the Console and check if the brightness of bulb is same is the same as when the maximum was set using hardware buttons.

Warning

Some Tuya devices automatically send the state of a dimmer after a power off. Tasmota could misunderstand the command and try to turn on the light even with SetOption20 and SetOption54 enabled.

Dual Dimmer~

To enable a dual dimmer setup assign fnId's:

  • 21 as Dimmer1
  • 22 as Dimmer2
  • 11 as Relay1
  • 12 as Relay2

Tasmota will automatically enable SetOption68 and the dimmers will respond to Channel1 and Channel2 commands.

Warning

The use of SetOption68 is limited to two channels and will be automatically disabled if any other combination of lights is used.

Lights~

CCT Light~

To enable a CCT light assign fnId's:

  • 21 as Dimmer1
  • 11 as Relay1
  • 23 as CT channel

RGB Light~

To enable an RGB light assign fnId's:

  • 21 as Dimmer1
  • 11 as Relay1
  • 24 as RGB controller

TuyaMCU uses different types of RGB Hex format where the most recent is 0HUE0SAT0BRI0 (type 1) and the older being RRGGBBFFFF6464 (type 2). Depending on the MCU, code can be case sensitive.

After enabling the RGB function check the TuyaReceived information and use TuyaRGB to configure and store the correct (or the closest) format:

  • TuyaRGB 0 - Type 1, 12 characters uppercase. Example: 00DF00DC0244 (default)
  • TuyaRGB 1 - Type 1, 12 characters lowercase. Example: 008003e8037a
  • TuyaRGB 2 - Type 2, 14 characters uppercase. Example: 00FF00FFFF6464
  • TuyaRGB 3 - Type 2, 14 characters lowercase. Example: 00e420ffff6464

TuyaRGB without payload will return the actual configured format.

RGB+X Light~

To enable an RGB+W light use RGB Light configuration and assign fnId 25 as white color.

To enable an RGB+CCT light use RGB Light configuration and assign fnId 23 as CT channel.

Light mode selector~

The majority of  TuyaMCU devices with an RGB+W or an RGB+CCT light have a button or app function to switch between White and Colored light.

To do the same in Tasmota, assign function (fnId) 26 to the mode select dpId. The possible values are 0 (white) and 1 (colorful). A button on the WebUI will be available once configured.

When the ModeSet function is enabled it is not possible to update both lights at the same time. Only the currently selected light mode will be updated.

Warning

Use of SetOption68 for more than two channels and the light split option (SetOption37 >= 128) are not supported in TuyaMCU mode.

Enums~

Better control over Type4 or enum dpId's. Up to four can be added, with a range from 0 to 31.

  • 61 as Enum1
  • 62 as Enum2
  • 63 as Enum3
  • 64 as Enum4

After an enum is configured, use TuyaEnumList to declare the range it must respect (note 0 is always the first item in range).

TuyaEnumlist <enum>,<range> where <enum> is declared using TuyaMCU and <range> is 0..31.

Example: configure Enum 1 with a range from 0 to 8.

21:14:52 CMD: tuyaenumlist 1,8
21:14:52 MQT: stat/TuyaMCU/RESULT = {"TuyaEnumList":{"Enum1":8,"Enum2":9,"Enum4":1}}

Entering a value greater than 31 will return an error

TuyaEnumList without payload will return the configuration of all the enums enabled in the list.

To update an enum use the command TuyaEnum:

Usage TuyaEnum [1|2|3|4],[TuyaEnumList range]

Example: update Enum 2 to 4.

21:14:12 CMD: tuyaenum2 4
21:14:12 MQT: stat/TuyaMCU/RESULT = {"TuyaEnum2":4}

Entering a value not in range will return an error

TuyaEnum without payload will return the state of all the enums configured.

Sensors~

These are the currently available sensors:

  • 71 as Temperature Sensor
  • 73 as Humidity Sensor
  • 75 as Illuminance Sensor
  • 76 as TVOC Sensor
  • 77 as CO2 Sensor
  • 78 as ECO2 Sensor
  • 79 as %LEL gas Sensor

If your device has a dpId for setting a specific Temperature and/or Humidity:

  • 72 for Temperature Set
  • 74 for Humidity Set

Use TuyaSend2 to manage them.

Temperature and Temperature Set default to °C. If you need °F change SetOption8 to 1.

The TuyaMCU driver sends the temperature as a byte integer. As of 9.3.x, the integer is converted by Tasmota to a float based on the "TempRes" setting which indicates the number of places after the decimal. The TempRes setting is by default "1" which means a device which sends 101 will be interpreted as 10.1. If your device normally returns an integer temperature, you may need to set TempRes to "0".

If your device requires the temperature to be divided (eg. increases in .5° increments), you may need to use the rules functionality to convert the temperature value.

Please note this will not update the value sent by the MCU but will just change the unit of measure reported on /SENSOR topic. You have to find a dpid to set the correct unit and change reported values (if it exists) or perhaps use the rules functionality to do the conversion.

Timers~

4 Type2 (integer) timers can be managed directly from Tasmota

  • 81 as Timer1
  • 82 as Timer2
  • 83 as Timer3
  • 84 as Timer4

Timers can be managed with TuyaSend2 and are visible in the WebUI.

Covers~

Single shutter or double shutters devices can be managed with a dimmer setup For devices that are reporting position to another dpId assign fnId's:

  • 27 to report the state of Dimmer1
  • 28 to report the state of Dimmer2

If your cover device has a motor direction change option assign fnId 97 for motor direction.

Switches~

There is currently no way to detect the number of relays present in an MCU based switch. We need to tell the number of relays to Tasmota using FunctionIDs 12 to 18 for Relay2 to Relay4.

Example

For a 4 gang switch set TuyaMCU 12,2, TuyaMCU 13,3 and TuyaMCU 14,4 if the dpIds for Relays 2-4 are 2,3,4.

Tip

You can configure all at once by using Backlog TuyaMCU 12,2; TuyaMCU 13,3; TuyaMCU 14,4

Power Metering~

Some Tuya MCU devices support Power measurement support over serial. For this it is better to use a bulb with known wattage rating.

Observe the logs in the Console

TYA: Heartbeat
{"TuyaReceived":{"Data":"55AA0107000501010001000F","Cmnd":7,"CmndData":"0101000100","DpType1Id1":0,"1":{"DpId":1,"DpIdType":1,"DpIdData":"00"}}}
TYA: fnId=11 is set for dpId=1
TYA: RX Relay-1 --> MCU State: Off Current State:Off
{"TuyaReceived":{"Data":"55AA01070005020100010111","Cmnd":7,"CmndData":"0201000101","DpType1Id2":1,"2":{"DpId":2,"DpIdType":1,"DpIdData":"01"}}}
TYA: fnId=0 is set for dpId=2
{"TuyaReceived":{"Data":"55AA01070005030100010011","Cmnd":7,"CmndData":"0301000100","DpType1Id3":0,"3":{"DpId":3,"DpIdType":1,"DpIdData":"00"}}}
TYA: fnId=0 is set for dpId=3
{"TuyaReceived":{"Data":"55AA01070005040100010113","Cmnd":7,"CmndData":"0401000101","DpType1Id4":1,"4":{"DpId":4,"DpIdType":1,"DpIdData":"01"}}}
TYA: fnId=0 is set for dpId=4
{"TuyaReceived":{"Data":"55AA0107000807020004000000001C","Cmnd":7,"CmndData":"0702000400000000","DpType2Id7":0,"7":{"DpId":7,"DpIdType":2,"DpIdData":"00000000"}}}
TYA: fnId=0 is set for dpId=7
{"TuyaReceived":{"Data":"55AA0107000808020004000000001D","Cmnd":7,"CmndData":"0802000400000000","DpType2Id8":0,"8":{"DpId":8,"DpIdType":2,"DpIdData":"00000000"}}}
TYA: fnId=0 is set for dpId=8
{"TuyaReceived":{"Data":"55AA0107000809020004000000001E","Cmnd":7,"CmndData":"0902000400000000","DpType2Id9":0,"9":{"DpId":9,"DpIdType":2,"DpIdData":"00000000"}}}
TYA: fnId=0 is set for dpId=9
{"TuyaReceived":{"Data":"55AA010700080A020004000000001F","Cmnd":7,"CmndData":"0A02000400000000","DpType2Id10":0,"10":{"DpId":10,"DpIdType":2,"DpIdData":"00000000"}}}
TYA: fnId=0 is set for dpId=10
{"TuyaReceived":{"Data":"55AA0107000865020004000000007A","Cmnd":7,"CmndData":"6502000400000000","DpType2Id101":0,"101":{"DpId":101,"DpIdType":2,"DpIdData":"00000000"}}}
TYA: fnId=0 is set for dpId=101
{"TuyaReceived":{"Data":"55AA01070008660200040000009813","Cmnd":7,"CmndData":"6602000400000098","DpType2Id102":152,"102":{"DpId":102,"DpIdType":2,"DpIdData":"00000098"}}}
TYA: fnId=0 is set for dpId=102
{"TuyaReceived":{"Data":"55AA01070008670200040000017EFB","Cmnd":7,"CmndData":"670200040000017E","DpType2Id103":382,"103":{"DpId":103,"DpIdType":2,"DpIdData":"0000017E"}}}
TYA: fnId=0 is set for dpId=103
{"TuyaReceived":{"Data":"55AA0107000868020004000009951B","Cmnd":7,"CmndData":"6802000400000995","DpType2Id104":2453,"104":{"DpId":104,"DpIdType":2,"DpIdData":"00000995"}}}
TYA: fnId=0 is set for dpId=104

In the TuyaReceived we are interested in DpIdData. For example: 00000995 is the second last entry.

  • Make sure the bulb if off.
  • Find out the voltage standard of your country (generally 220, 240, 120v) from this table.
  • Multiply that number by 10 (2400) and Convert that number (2400) to Hex using any hex converter (2400 = 0x960)
  • Now look for the number nearest to 960 in the logs. In our case it is 00000995. So we expect that's the voltage which is "DpId":104 in our example.
  • Set voltage functionId 33 by entering TuyaMCU 33,104.
  • Now set dimmer to 100% using the dimmer 100 command, or power on using power1 on (depending on the device) and observe the logs.
  • Now we need the power rating of your bulb, for example 40W. Multiply by 10 (400) and convert to hex which gives us 0x190. Check which unknown ID is close to 190. I this example it is 17E for "DpId":103. This is the Id of Active Power function.
  • Set the active power functionId 31 by entering TuyaMCU 31,103.
  • Once Power and Voltage are set you should see something such as this in the logs:
    TYA: Heartbeat
    {"TuyaReceived":{"Data":"55AA0107000501010001000F","Cmnd":7,"CmndData":"0101000100","DpType1Id1":0,"1":{"DpId":1,"DpIdType":1,"DpIdData":"00"}}}
    TYA: fnId=11 is set for dpId=1
    TYA: RX Relay-1 --> MCU State: Off Current State:Off
    {"TuyaReceived":{"Data":"55AA01070005020100010111","Cmnd":7,"CmndData":"0201000101","DpType1Id2":1,"2":{"DpId":2,"DpIdType":1,"DpIdData":"01"}}}
    TYA: fnId=0 is set for dpId=2
    {"TuyaReceived":{"Data":"55AA01070005030100010011","Cmnd":7,"CmndData":"0301000100","DpType1Id3":0,"3":{"DpId":3,"DpIdType":1,"DpIdData":"00"}}}
    TYA: fnId=0 is set for dpId=3
    {"TuyaReceived":{"Data":"55AA01070005040100010113","Cmnd":7,"CmndData":"0401000101","DpType1Id4":1,"4":{"DpId":4,"DpIdType":1,"DpIdData":"01"}}}
    TYA: fnId=0 is set for dpId=4
    {"TuyaReceived":{"Data":"55AA0107000807020004000000001C","Cmnd":7,"CmndData":"0702000400000000","DpType2Id7":0,"7":{"DpId":7,"DpIdType":2,"DpIdData":"00000000"}}}
    TYA: fnId=0 is set for dpId=7
    {"TuyaReceived":{"Data":"55AA0107000808020004000000001D","Cmnd":7,"CmndData":"0802000400000000","DpType2Id8":0,"8":{"DpId":8,"DpIdType":2,"DpIdData":"00000000"}}}
    TYA: fnId=0 is set for dpId=8
    {"TuyaReceived":{"Data":"55AA0107000809020004000000001E","Cmnd":7,"CmndData":"0902000400000000","DpType2Id9":0,"9":{"DpId":9,"DpIdType":2,"DpIdData":"00000000"}}}
    TYA: fnId=0 is set for dpId=9
    {"TuyaReceived":{"Data":"55AA010700080A020004000000001F","Cmnd":7,"CmndData":"0A02000400000000","DpType2Id10":0,"10":{"DpId":10,"DpIdType":2,"DpIdData":"00000000"}}}
    TYA: fnId=0 is set for dpId=10
    {"TuyaReceived":{"Data":"55AA0107000865020004000000007A","Cmnd":7,"CmndData":"6502000400000000","DpType2Id101":0,"101":{"DpId":101,"DpIdType":2,"DpIdData":"00000000"}}}
    TYA: fnId=0 is set for dpId=101
    {"TuyaReceived":{"Data":"55AA01070008660200040000009712","Cmnd":7,"CmndData":"6602000400000097","DpType2Id102":151,"102":{"DpId":102,"DpIdType":2,"DpIdData":"00000097"}}}
    TYA: fnId=0 is set for dpId=102
    {"TuyaReceived":{"Data":"55AA01070008670200040000017BF8","Cmnd":7,"CmndData":"670200040000017B","DpType2Id103":379,"103":{"DpId":103,"DpIdType":2,"DpIdData":"0000017B"}}}
    TYA: fnId=31 is set for dpId=103
    TYA: Rx ID=103 Active_Power=379
    {"TuyaReceived":{"Data":"55AA0107000868020004000009961C","Cmnd":7,"CmndData":"6802000400000996","DpType2Id104":2454,"104":{"DpId":104,"DpIdType":2,"DpIdData":"00000996"}}}
    TYA: fnId=33 is set for dpId=104
    TYA: Rx ID=104 Voltage=2454
    
  • To get the Id for the current, calculate Current = Power / Voltage ( 37.9 / 245.4 ) = ~0.1544 (Remember to divide each value by 10). Multiply this by 1000 = 154. Now convert 154 to hex which is 0x9A. This is closest to 97 which is Id "DpId":102.
  • Set the current FunctionId 32 using command TuyaMCU 32,102.
  • Observe the logs should start showing Current in addition to Active_Power and Voltage
    TYA: Heartbeat
    {"TuyaReceived":{"Data":"55AA0107000501010001000F","Cmnd":7,"CmndData":"0101000100","DpType1Id1":0,"1":{"DpId":1,"DpIdType":1,"DpIdData":"00"}}}
    TYA: fnId=11 is set for dpId=1
    TYA: RX Relay-1 --> MCU State: Off Current State:Off
    {"TuyaReceived":{"Data":"55AA01070005020100010111","Cmnd":7,"CmndData":"0201000101","DpType1Id2":1,"2":{"DpId":2,"DpIdType":1,"DpIdData":"01"}}}
    TYA: fnId=0 is set for dpId=2
    {"TuyaReceived":{"Data":"55AA01070005030100010011","Cmnd":7,"CmndData":"0301000100","DpType1Id3":0,"3":{"DpId":3,"DpIdType":1,"DpIdData":"00"}}}
    TYA: fnId=0 is set for dpId=3
    {"TuyaReceived":{"Data":"55AA01070005040100010113","Cmnd":7,"CmndData":"0401000101","DpType1Id4":1,"4":{"DpId":4,"DpIdType":1,"DpIdData":"01"}}}
    TYA: fnId=0 is set for dpId=4
    {"TuyaReceived":{"Data":"55AA0107000807020004000000001C","Cmnd":7,"CmndData":"0702000400000000","DpType2Id7":0,"7":{"DpId":7,"DpIdType":2,"DpIdData":"00000000"}}}
    TYA: fnId=0 is set for dpId=7
    {"TuyaReceived":{"Data":"55AA0107000808020004000000001D","Cmnd":7,"CmndData":"0802000400000000","DpType2Id8":0,"8":{"DpId":8,"DpIdType":2,"DpIdData":"00000000"}}}
    TYA: fnId=0 is set for dpId=8
    {"TuyaReceived":{"Data":"55AA0107000809020004000000001E","Cmnd":7,"CmndData":"0902000400000000","DpType2Id9":0,"9":{"DpId":9,"DpIdType":2,"DpIdData":"00000000"}}}
    TYA: fnId=0 is set for dpId=9
    {"TuyaReceived":{"Data":"55AA010700080A020004000000001F","Cmnd":7,"CmndData":"0A02000400000000","DpType2Id10":0,"10":{"DpId":10,"DpIdType":2,"DpIdData":"00000000"}}}
    TYA: fnId=0 is set for dpId=10
    {"TuyaReceived":{"Data":"55AA0107000865020004000000007A","Cmnd":7,"CmndData":"6502000400000000","DpType2Id101":0,"101":{"DpId":101,"DpIdType":2,"DpIdData":"00000000"}}}
    TYA: fnId=0 is set for dpId=101
    {"TuyaReceived":{"Data":"55AA01070008660200040000009712","Cmnd":7,"CmndData":"6602000400000097","DpType2Id102":151,"102":{"DpId":102,"DpIdType":2,"DpIdData":"00000097"}}}
    TYA: fnId=32 is set for dpId=102
    TYA: Rx ID=102 Current=151
    {"TuyaReceived":{"Data":"55AA01070008670200040000017BF8","Cmnd":7,"CmndData":"670200040000017B","DpType2Id103":379,"103":{"DpId":103,"DpIdType":2,"DpIdData":"0000017B"}}}
    TYA: fnId=31 is set for dpId=103
    TYA: Rx ID=103 Active_Power=379
    {"TuyaReceived":{"Data":"55AA0107000868020004000009961C","Cmnd":7,"CmndData":"6802000400000996","DpType2Id104":2454,"104":{"DpId":104,"DpIdType":2,"DpIdData":"00000996"}}}
    TYA: fnId=33 is set for dpId=104
    TYA: Rx ID=104 Voltage=2454
    
  • Power and current should change on dimming high / low or turning the device on and off. The Tasmota web UI should show power values now on the home page.

Battery Powered Sensors~

Specific Devices~

Tuya Protocols~

The MCU communicates with the Wi-Fi module through the serial port with a Tuya specified protocol. Those are classified into basic and functional protocols.

Basic protocols~

They are common protocols integrated in Tasmota's TuyaMCU module. They stay the same for each product and are mandatory for Tuya module to work correctly.

Functional protocols~

Functional protocols are used for delivering and reporting data of functions. These protocols differ between devices and manufacturers and might require configuration in Tasmota using TuyaMCU command or with TuyaSend<x> command.

Anatomy of Tuya Protocol~

Name Description
Frame Header Version Fixed value of 0x55aa
Command Word 0x06 - send commands
0x07 - report status
Data Length defines expected length of data
dpID numbered ID of a function (DP = Data Point or Define Product)
Data Type see Data Type table below
Function Length length of command
Function Command formatted according to Data Type
Verification Method checksum = remainder of the byte sum starting from Frame Header to 256

Data Type~

Hex Tasmota Command Description Max length
0x00 TuyaSend6 raw data unknown
0x01 TuyaSend1 boolean data 0/1 1 byte
0x02 TuyaSend2 value data. If a value contains less than 4 bytes, 0 is supplemented before 4 bytes
0x00 TuyaSend3 string data unknown
0x04 TuyaSend4 enum data 0/1/2/3/4/5 1 byte
0x05 ### fault data, report only 8 bytes

Let's dissect and explain the MCU protocol using serial command 55aa0006000501010001010e:

Frame Header Version Command Word Data Length dpID Data Type Function Length Function Command Verification Method
55aa00 06 0005 01 01 0001 01 0e

This is the command which powers on the device sending Function Command = 1 to dpID 1 (Switch):

  • Frame Header Version = 0x55aa00 which is a fixed value and always the same
  • Command Word = 0x06 because we're sending a command
  • Data Type = 0x01 since the command sent is a 1 byte boolean
  • Function Length = 0x001 instruct 1 character only for function command length
  • Function Command = 0x01 in hex which equals 1 in int
  • Verification Method = 0e is calculated

Protocol flow~

On device boot, TuyaMCU executes the required basic protocols and reads the functional protocol data received, which are used to update status of components mapped in TuyaMCU (Relays, dimmer, power monitoring data).

After receiving a command from Tasmota (Command Word 0x06), the MCU performs corresponding logical control. When the dpID status is changed, the MCU reports the data (Command Word 0x07) to TuyaMCU component.

dpId Function Tables~

This information is just for orientation. Functions are assigned by the manufacturer and can be on different dpId's

  • DP ID: dpId.
  • Function Point:Used to describe the product function.
  • Identifier: Function codename. Can only be letters, numbers and underscores
  • Data type:
  • Issue and report: command data can be sent and status data can be reported back to the Wi-Fi module
  • Report only: supports only status reporting, no control options

  • Function Type (Referred as Data Type):

  • Boolean (bool): non-true or false binary variable, such as: switch function, on / off
  • Value (value): suitable for linear adjustment of the type of data, such as: temperature regulation, temperature range 20-40 ℃
  • Enum (enum): custom finite set value, such as: working levels, low / mid / high
  • Fault (fault): dedicated to reporting and statistical failure of the function points. Support multi-fault, the data is reported only
  • Integer(integer): transmitted as integer
  • Transparent (raw): data in binary

Switches or Plugs/Power Strips~

DP ID Identifier Data type Function type Properties
1 switch_1 Control and report Boolean
2 switch_2 Control and report Boolean
3 switch_3 Control and report Boolean
4 switch_4 Control and report Boolean
5 switch_5 Control and report Boolean
9 countdown_1 Control and report Integer undefined0-86400, undefined1, Scale0, Unit:s
10 countdown_2 Control and report Integer undefined0-86400, undefined1, Scale0, Unit:s
11 countdown_3 Control and report Integer undefined0-86400, undefined1, Scale0, Unit:s
12 countdown_4 Control and report Integer undefined0-86400, undefined1, Scale0, Unit:s
13 countdown_5 Control and report Integer undefined0-86400, undefined1, Scale0, Unit:s

Aromatherapy Machine (Oil Diffuser)~

DP ID Function points Identifier Data type Function type Properties
1 Switch Power Issue and report Boolean
6 Amount of fog fog Issue and report Enum Enumerated values:small, large
11 Light Light Issue and report Boolean
12 Fault alarm fault Only report Fault Barrier values:1
13 Countdown countdown Issue and report Enum Enumerated values: 0, 1, 2, 3
14 Countdown remaining time countdown_left Only report Integer Values range: 0-360, Pitch1, Scale0, Unit:min
101 Light mode work_mode Issue and report Enum Enumerated values: white, colour, scene, scene1, scene2, scene3, scene4
102 Color value colour_data Issue and report Char type *see below
103 Light mode lightmode Issue and report Enum Enumerated values: 1, 2, 3
104 Brightness setting setlight Issue and report Integer Values range: 0-255, Pitch1, Scale0, Unit:\%

colour_data format of the lights is a string of 14 characters, for example, 00112233334455, where 00 indicates R, 11 indicates G, 22 indicates B, 3333 indicates the hue, 44 indicates the saturation, and 55 indicates the value. The initial value is saved by default. If you do not want to adjust the light, set the data to the maximum value 100% (0x64). The last four characters have fixed values.

Curtain Motor~

DP ID Function points Identifier Data type Function type Properties
1 Percentage percent_state Only report Integer Values range:0-100, Pitch1, Scale0, Unit:%
2 Motor Direction control_back Issue and report Boolean
3 Auto Power auto_power Issue and report Boolean
4 Left time countdown Issue and report Enum Enumerated values:cancel, 1, 2, 3, 4
5 Total Time time_total Only report Integer Values range:0-120000, Pitch1, Scale0, Unit:m

Complete document on protocols

DP ID Function points Identifier Data type Function type Properties
1 Control (required) control Issue and report Enum Enumerated values:open, stop, close, continue
2 Curtain position setting percent_control Issue and report Integer Values range:0-100, Pitch1, Scale0, Unit:%
3 Current curtain position percent_state Only report Integer Values range:0-100, Pitch1, Scale0, Unit:%
4 Mode mode Issue and report Enum Enumerated values:morning, night
5 Motor Direction control_back Issue and report Enum Enumerated values:forward, back
6 Auto Power auto_power Issue and report Boolean
7 Work State (required) work_state Only report Enum Enumerated values:opening, closing
11 Situation_set situation_set Only report Enum Enumerated values:fully_open, fully_close
12 Fault (required) fault Only report Fault Barrier values:motor_fault

Power Monitoring Plug~

DP ID Function points Identifier Data type Function type Properties
1 switch_1 switch_1 Control and report Boolean
9 countdown_1 countdown_1 Control and report Integer undefined0-86400, undefined1, Scale0, Unit:s
17 statistics Function add_ele Control and report Integer undefined0-50000, undefined100, Scale3, Unit:
18 current cur_current Data report Integer undefined0-30000, undefined1, Scale0, Unit:mA
19 power cur_power Data report Integer undefined0-50000, undefined1, Scale1, Unit:W
20 voltage cur_voltage Data report Integer undefined0-5000, undefined1, Scale1, Unit:V
21 test flag test_bit Data report Integer undefined0-5, undefined1, Scale0, Unit:
22 voltage coefficient voltage_coe Data report Integer undefined0-1000000, undefined1, Scale0, Unit:
23 current coefficient electric_coe Data report Integer undefined0-1000000, undefined1, Scale0, Unit:
24 power coefficient power_coe Data report Integer undefined0-1000000, undefined1, Scale0, Unit:
25 statistics coefficient electricity_coe Data report Integer undefined0-1000000, undefined1, Scale0, Unit:
26 warning fault Data report Fault Barrier values:ov_cr

Dehumidifier~

DP ID Function points Identifier Data type Function type Properties
1 Switch Switch Issue and report Boolean
2 PM2.5 PM25 Only report Integer Values range:0-999, Pitch1, Scale0, Unit:
3 Work mode Mode Issue and report Enum Enumerated values:Manual, Auto, Sleep
4 Wind speed Speed Issue and report Enum Enumerated values:speed1, speed2, speed3, speed4, speed5
5 Filter usage Filter Only report Integer Values range:0-100, Pitch1, Scale0, Unit:%
6 Fresh Anion Issue and report Boolean
7 Child lock Lock Issue and report Boolean
9 UV light UV Issue and report Boolean
11 Filter reset FilterReset Issue and report Boolean
12 indoor temp Temp Only report Integer Values range:-20-50, Pitch1, Scale0, Unit:℃
13 Indoor humidity Humidity Only report Integer Values range:0-100, Pitch1, Scale0, Unit:%

Lighting~

DP ID Function points Identifier Data type Function type Properties
1 Switch led_switch Control and report Boolean
2 Mode work_mode Control and report Enum Enumerated values:white, colour, scene, scene_1, scene_2, scene_3, scene_4
3 Bright bright_value Control and report Integer undefined25-255, undefined1, Scale0, Unit:
5 Colour mode colour_data Control and report Char type
6 Scene scene_data Control and report Char type
7 Scene1 flash_scene_1 Control and report Char type
8 Scene2 flash_scene_2 Control and report Char type
9 Scene3 flash_scene_3 Control and report Char type
10 Scene4 flash_scene_4 Control and report Char type

Contact Sensor~

DP ID Function points Identifier Data type Function type Properties
1 Door Sensor doorcontact_state Only report Boolean
2 Battery Level battery_percentage Only report Integer Values range:0-100, Pitch1, Scale0, Unit:%
3 Battery Level battery_state Only report Enum Enumerated values:low, middle, high
4 Anti-remove Alarm temper_alarm Only report Boolean

Air purifier~

DP ID Function points Identifier Data type Function type Properties
1 Switch Switch Issue and report Boolean
2 PM2.5 PM25 Only report Integer Values range:0-999, Pitch1, Scale0, Unit:
3 Work mode Mode Issue and report Enum Enumerated values:Manual, Auto, Sleep
4 Wind speed Speed Issue and report Enum Enumerated values:speed1, speed2, speed3, speed4, speed5
5 Filter usage Filter Only report Integer Values range:0-100, Pitch1, Scale0, Unit:%
6 Fresh Anion Issue and report Boolean
7 Child lock Lock Issue and report Boolean
9 UV light UV Issue and report Boolean
11 Filter reset FilterReset Issue and report Boolean
12 indoor temp Temp Only report Integer Values range:-20-50, Pitch1, Scale0, Unit:℃
13 Indoor humidity Humidity Only report Integer Values range:0-100, Pitch1, Scale0, Unit:%

Heater~

DP ID Function points Identifier Data type Function type Properties
1 Switch Power Issue and report Boolean
2 Target temperature TempSet Issue and report Integer Values range:0-37, Pitch1, Scale0, Unit:℃
3 Current Temperature TempCurrent Only report Integer Values range:-9-99, Pitch1, Scale0, Unit:℃
4 Mode Mode Issue and report Enum Enumerated values:m, p
5 Fault alarm Fault Only report Fault Barrier values:1, 2, 3
6 Gear position gear Issue and report Enum Enumerated values:low, mid, high, off
7 Conservation eco_mode Issue and report Boolean

Smart fan~

DP ID Function points Identifier Data type Function type Properties
1 Switch switch Issue and report Boolean
2 Wind Speed Level fan_speed Issue and report Enum Enumerated values:1, 2, 3, 4
3 Left-and-Right Swing fan_horizontal Issue and report Enum Enumerated values:on, off
4 Up-and-Down Swing fan_vertical Issue and report Enum Enumerated values:on, off
5 Fault Alarm fault Only report Fault Barrier values:1, 2
6 Anion anion Issue and report Boolean
7 Humidify humidifier Issue and report Boolean
8 Oxygen oxygan Issue and report Boolean
9 Child Lock lock Issue and report Boolean
10 Cool fan_cool Issue and report Boolean
11 Set Temperate temp Issue and report Integer Values range:0-50, Pitch1, Scale0, Unit:℃
12 Current Temperature temp_current Only report Integer Values range:0-50, Pitch1, Scale0, Unit:℃

Kettle~

DP ID Function points Identifier Data type Function type Properties
1 Working switch start Issue and report Boolean
2 Heat to target temperature shortcut (°C) temp_setting_quick_c Issue and report Enum Enumerated values:50, 65, 85, 90, 100
3 Heat to target temperature shortcut (°F) temp_setting_quick_f Issue and report Enum Enumerated values:122, 149, 185, 194, 212
4 Cool to the target temperature shortcut after boiling (°C) temp_boiling_quick_c Issue and report Enum Enumerated values:50, 65, 85, 90, 100
5 Cool to the target temperature shortcut after boiling (°F) temp_boiling_quick_f Issue and report Enum Enumerated values:122, 149, 185, 194, 212
6 Temperature scale switching temp_unit_convert Issue and report Enum Enumerated values:c, f
7 Insulation switch switch_keep_warm Issue and report Boolean
8 Holding time setting keep_warm_setting Issue and report Integer Values range:0-360, Pitch1, Scale0, Unit:min
9 Mode work_type Issue and report Enum Enumerated values: setting_quick, boiling_quick, temp_setting, temp_

BecaThermostat~

Work in progress

DP ID Function points Identifier Data type Function type Properties
1 Switch Power Issue and report Boolean
2 Target temperature TempSet Issue and report Integer Values range:0-37, Pitch1, Scale0, Unit:℃
3 Current Temperature TempCurrent Only report Integer Values range:-9-99, Pitch1, Scale0, Unit:℃
4 Mode Mode Issue and report Enum Enumerated values:m, p (wip)
102 Floor Temperature FloorCurrent Issue and report Integer Values range:0-37, Pitch1, Scale0, Unit:℃

Inkbird ITC-308-Wifi~

Temperature controller with individual plug in sockets for heating/cooling

DP ID Function points Identifier Data type Function type Properties
101 Temperature unit Cf Issue and report Integer 0=C, 1=F
102 Calibration Ca Issue and report Integer Unit is 0.1C
104 Temperature sensor Issue and report Integer Unit is 0.1C
106 Temperature set point Ts Issue and report Integer Unit is 0.1C
108 Compressor delay time Pt Issue and report Integer Unit is minutes
109 Alarm high temperature Ah Issue and report Integer Unit is 0.1C
110 Alarm low temperature Al Issue and report Integer Unit is 0.1C, For negative values use -(0xFFFFFFFF - value)
115 Relay status Only report Integer 01=cool, 02=off, 03=heating
116 Temperature sensor Issue and report Integer Unit is 0.1F
117 Heating differential value Hd Issue and report Integer Unit is 0.1C
118 Cooling differential value Cd Issue and report Integer Unit is 0.1C

The unit will constantly be sending the temperature sensor value in celsius and fahrenheit: 104 and 116. To trigger the unit to send all settings, send any value to a non-used register, e.g. TuyaSend1 2,1

Example:

Tasmota command Result
TuyaSend1 2,1 Trigger the unit to reveal all settings
TuyaSend2 106,250 Change set-point to 25.0C
TuyaSend2 101,1 Change units to Fahrenheit

Inkbird IHC-200-Wifi~

Humidity controller with two relay sockets very similar to the ITC-308-WIFI This unit ships with a RTL based WR3 module which cannot be flashed with Tasmota, however the WR3 module is pin compatible with an ESP12-F module and is on a daughter board similar to the one in the ITC-308-WIFI

DP ID Function points Identifier Data type Function type Properties
104 Humidity sensor Only report Integer Unit is 0.1C
106 Humidity set point HS Issue and report Integer Unit is 0.1C

Dpid 102,108,109,110,106,117,118 return data and are not yet reverse engineered but are likely similar to ITC-308 but related to humidity.

Further Reading~