Hi folks, I have these (specifically the DCF4002WHA) working 100% as desired using Tasmota, but avoiding Tasmota autodiscovery (as the support for the MCU is poor), and also leaning heavily on raw TuyaMCU commands. This setup works in real-time and any settings applied via the remote control for the fan are reflected immediately in HomeAssistant. Fan speeds work perfectly, brightness works perfectly, and colour temps work perfectly.
The Console commands for TuyaMCU only need to enable the light and fan power. The rest is done using raw TuyaMCU commands in the MQTT config within HA.
Backlog TuyaMCU 11,1; TuyaMCU 12,9
DO NOT use the console command “TuyaMCU 21,10”. As of Tasmota 12.4.0.5 it crashes the MCU and the entire unit will not work after a power cycle. If you ever accidentally enter this command it must be zeroed out with the console command “TuyaMCU 21,0” and power cycling the device.
You must also enable Option 66 via the Tasmota console and “SetOption66 1”.
The Tasmota template is:
{"NAME":"Arlec DCF4002WHA","GPIO":[1,1,1,1,1,1,0,0,1,1,1,1,1,0],"FLAG":0,"BASE":54}
The following MQTT code works for these devices, noting you need to change your topic and device name to suit your device.
fan:
name: "Theatre Fan"
unique_id: "Theatre Fan"
state_topic: "tele/tasmota_C23047/RESULT"
state_value_template: "{{ 'ON' if '1' in value_json.TuyaReceived and value_json.TuyaReceived['1'].DpIdData == '01' else 'OFF' if '1' in value_json.TuyaReceived and value_json.TuyaReceived['1'].DpIdData == '00' }}"
command_topic: "cmnd/tasmota_C23047/POWER1"
payload_on: 'ON'
payload_off: 'OFF'
percentage_command_topic: "cmnd/tasmota_C23047/TuyaSend4"
percentage_command_template: "{{ {1: '3,0', 2: '3,1', 3: '3,2', 4: '3,3', 5: '3,4', 6: '3,5'}[value] | default('1') }}"
percentage_state_topic: "tele/tasmota_C23047/RESULT"
percentage_value_template: "{{ (value_json.TuyaReceived['3'].DpIdData | int) + 1 if '3' in value_json.TuyaReceived }}"
speed_range_min: 1
speed_range_max: 6
preset_modes:
- "Summer"
- "Winter"
preset_mode_command_topic: "cmnd/tasmota_C23047/TuyaSend4"
preset_mode_command_template: >
{% if value == 'Winter' %}4,1
{% elif value == 'Summer' %}4,0
{% endif %}
preset_mode_state_topic: "tele/tasmota_C23047/RESULT"
preset_mode_value_template: >
{%- if '4' in value_json.TuyaReceived %}
{%- if value_json.TuyaReceived['4'].DpIdData | int == 1 %}Winter
{%- elif value_json.TuyaReceived['4'].DpIdData | int == 0 %}Summer
{%- endif %}
{%- endif %}
light:
name: "Theatre Light"
unique_id: "Theatre Light"
state_topic: "stat/tasmota_C23047/POWER2"
command_topic: "cmnd/tasmota_C23047/POWER2"
payload_on: 'ON'
payload_off: 'OFF'
brightness_command_topic: "cmnd/tasmota_C23047/TuyaSend2"
brightness_command_template: "{{ '10,' ~ (((value | int) // 2) * 2) }}"
brightness_state_topic: "tele/tasmota_C23047/RESULT"
brightness_scale: 100
brightness_value_template: "{{ (value_json.TuyaReceived['10'].DpIdData | int(base=16)) if '10' in value_json.TuyaReceived else None }}"
color_temp_command_topic: "cmnd/tasmota_C23047/TuyaSend2"
color_temp_command_template: "{{ '11,' ~ ((value - 154) * 100 / (370 - 154)) | round }}"
color_temp_state_topic: "tele/tasmota_C23047/RESULT"
color_temp_value_template: "{{ (154 + (value_json.TuyaReceived['11'].DpIdData | int(base=16)) * (370 - 154) / 100) | round if '11' in value_json.TuyaReceived else None }}"
min_mireds: 154
max_mireds: 370
A summary of the code is that it uses raw TuyaSend commands to make changes, and reviews the Tasmota MQTT Tele commands which - via the use of Option 66 for TuyaMCU - includes the raw status of all the dpIds and parses those for the value it is looking for.