Tasmota the desktop fan

Hope this will give other user ideas and a little bit of help

Ill keep add to this as I think of more ideas on making the FAN SMARTER
with the help of HA

2 replay 1 for on/off other one for speed (off= low / on=high


Yellow is the hot wire
red = low speed
black = high speed
Blue is power on/off


red vcc 5v form the Wemos
black gound form wemos
yellow D1 on the wemos relay1
other yellow D8 on the wemos relay2


red vcc 3+ on the wemos
yellow D2 on the wemos
black GND

red vcc 3+
yellow D4 of the wemos
black ground

need to of theres Capacitive Touch Switch

Black ground
Yellow D7 switch 1
red vcc 3+

other one
black ground
yellow D5 switch 2
red vcc 3+


with it hot glue in place had to take the old push switch on the inside


the DHT11 on the back of the fan


motion senser on the front

I flash the wemos with tasmota 5.13

setting up the GPIO pins in Tasmota

Switch3 is the motion senser how to add a relay3 to so it would send the MQTT commands

in the Console of tasmota
need to set the switchMode
Switchmode1 4
switchmode2 4

this make them puhbuttons

if job done right the home screen should look like this

toggle 1 is relay 1 fan on/off
toggle 2 is relay 2 fan speed on high off low
toggle 3 is the montion senser


yeap tasmota is sending the MQTT messages :slight_smile:

only problem had was the motion senser would send a ON and them send the OFF
dont want that
I used node-red to fix it

here is the commands

[{"id":"52127a09.656d34","type":"mqtt in","z":"52e056f1.f36ff8","name":"Office Motion","topic":"stat/SONOFF-FAN/POWER3","qos":"2","broker":"d3f7744e.a9cb78","x":70,"y":20,"wires":[["23361fe8.1754b"]]},{"id":"9e920ab6.f68048","type":"debug","z":"52e056f1.f36ff8","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":710,"y":100,"wires":[]},{"id":"cfe6a421.aa0598","type":"delay","z":"52e056f1.f36ff8","name":"","pauseType":"delay","timeout":"3","timeoutUnits":"minutes","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":120,"y":200,"wires":[["e681dcb8.4aa1c"]]},{"id":"e7c5d7f4.3c23e8","type":"mqtt out","z":"52e056f1.f36ff8","name":"","topic":"nodered/motion","qos":"","retain":"","broker":"d3f7744e.a9cb78","x":700,"y":20,"wires":[]},{"id":"23361fe8.1754b","type":"function","z":"52e056f1.f36ff8","name":"","func":"if (msg.payload ==\"ON\") {\n    msg.reset = true;\n    msg.payload = \"ON\"\n}\nelse{\n    \n    msg.payload = \"ON\"\n}\n\nreturn msg;","outputs":1,"noerr":0,"x":250,"y":20,"wires":[["e7c5d7f4.3c23e8","9e920ab6.f68048","cfe6a421.aa0598"]]},{"id":"96a290b2.7908f","type":"mqtt out","z":"52e056f1.f36ff8","name":"","topic":"nodered/motion","qos":"","retain":"","broker":"d3f7744e.a9cb78","x":700,"y":200,"wires":[]},{"id":"e681dcb8.4aa1c","type":"function","z":"52e056f1.f36ff8","name":"","func":"if (msg.payload ==\"ON\") {\n    msg.payload = \"OFF\"\n}\nelse{\n    msg.payload = \"OFF\"\n}\n\nreturn msg;","outputs":1,"noerr":0,"x":270,"y":200,"wires":[["96a290b2.7908f","9e920ab6.f68048"]]},{"id":"d3f7744e.a9cb78","type":"mqtt-broker","z":"","name":"","broker":"localhost","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"willTopic":"","willQos":"0","willPayload":"","birthTopic":"","birthQos":"0","birthPayload":""}]

it has a delay in it for 3 min ( and a rest of the msg.reset)

Node red wait for the topic
does its thing
then send out a ON/OFF to


Now the HA stuff
Switches for the fan

  - platform: mqtt
    entity_id: officefan
    name: "Office Fan"
    state_topic: "stat/SONOFF-FAN/POWER1"
    command_topic: "cmnd/SONOFF-FAN/POWER1"
    payload_on: "ON"
    payload_off: "OFF"
    optimistic: false
    qos: 0
  - platform: mqtt
    entity_id: officefanSpeed
    name: "Office Fan Speed"
    state_topic: "stat/SONOFF-FAN/POWER2"
    command_topic: "cmnd/SONOFF-FAN/POWER2"
    payload_on: "ON"
    payload_off: "OFF"
    optimistic: false
    qos: 0    


  - platform: mqtt
    name: "Office Motion"
    state_topic: "nodered/motion"
    qos: 2
    retain: true
    payload_on: "ON"
    payload_off: "OFF"


  - platform: mqtt
    name: "Office Temperature"
    state_topic: "tele/SONOFF-FAN/SENSOR"
    value_template: "{{value_json['DHT11'].Temperature }}"
    qos: 1
    unit_of_measurement : "°C"
  - platform: mqtt
    name: "Office Humidity"
    state_topic: "tele/SONOFF-FAN/SENSOR"
    value_template: "{{value_json['DHT11'].Humidity }}"
    qos: 1
    unit_of_measurement : "%"   

Now take it over the TOP
add the fan control

  - platform: mqtt
    name: "Office Fan"
    state_topic: "stat/SONOFF-FAN/POWER1"
    command_topic: "cmnd/SONOFF-FAN/POWER1"
    speed_state_topic: "stat/SONOFF-FAN/POWER2"
    speed_command_topic: "cmnd/SONOFF-FAN/POWER2"
    qos: 0
    payload_on: "ON"
    payload_off: "OFF"
    payload_low_speed: "OFF"
    payload_medium_speed: "ON"
      - "OFF"
      - "ON"

take it even more over the TOP
why not add climate to it

  - platform: generic_thermostat
    entity_id: office_temp
    name: "Office Temperature"
    heater: switch.office_fan
    target_sensor: sensor.office_temperature
    min_temp: 15
    max_temp: 30
    ac_mode: true
    target_temp: 22
    initial_operation_mode: "auto"
    away_temp: 16

now the customize.yaml

  - entity_id: binary_sensor.office_motion
  - entity_id: sensor.office_temperature
  - entity_id: sensor.office_humidity
  show_last_changed: true

Put all the bits into a group

    name: Office
    control: hidden
      - light.office_light
      - fan.office_fan
      - climate.office_temperature
      - binary_sensor.office_motion
      - sensor.office_computer

and i have ended up with this


And I powder it with one of these


AC tap into the Power line

-Vo GND on the wemos
+Vo 5v on the wemos

hope this turn the light on (fan) for someone else.

OK Now it let put some Automation behind it

As my office is dark I would like the Light to come on when I walk in

- id: Office Light On
  alias: Office Light On
  - entity_id: binary_sensor.office_motion
    platform: state
    to: 'on'
  - condition: state
    entity_id: light.office_light
    state: 'off'
  - data:
      entity_id: light.office_light
    service: light.turn_on

that fix it way cool walk in and light come on
(bugger walk pass the door light come on) fan can see me turn fan a bit that fix it.

now how can i get turn off the light when there no motion for x mins NO as my chair is in front of fan so motion can’t see and turn off light even if im there

thinking “what about when computer goes off line” that it

make a sensor

  - platform: command_line
    name: "Office Computer"
    command: ping -W 1 -c 1 IPADDRESS > /dev/null 2>&1 && echo success || echo fail
    device_class: connectivity
    payload_on: "success"
    payload_off: "fail"
    value_template: >-
      {% if value is equalto "success" %}
      {% else %}
      {% endif %}

have no idea how the above works found some on here and it does the job

so now the automation

- id: Office
  alias: 'Office '
  - entity_id: sensor.office_computer
    platform: state
    to: Off-Line
  condition: []
  - data:
      entity_id: light.office_light
    service: light.turn_off
  - data:
      entity_id: switch.office_fan
    service: switch.turn_off
  - data:
      entity_id: switch.office_fan_speed
    service: switch.turn_off

mite as well turn the fan off if the computer offline

way cool it works just got to remember to (window+L) Lock the computer walk way
and after some time the light goes off. Think ill have to play around with computer
to turn off when the computer is lock

the cool thing about this its just keep growing and growing

the bad part about is
Yes I could just lean across and turn the fan on
yes I could as i walk into the office turn light on/off
nop HA does it for me know :slight_smile:

if someone walks into office it turn ON light nice
But Want it to turn off if the computer is still offline


- id: 'Office Light Off No Motion'
  alias: Office Light Off No Motion
  - entity_id: binary_sensor.office_motion
    platform: state
    to: 'off'
  - condition: state
    entity_id: sensor.office_computer
    state: Off-Line
  - data:
      entity_id: light.office_light
    service: light.turn_off

awesome project
I was thinking about doing a similar thing but with an USB powered fan… I wonder if there’s any kind of “adapter” to connect the USB to the board

what about a USB HUB

dear, what is the name of the red module and what is it for? Its location is below the temperature sensor.

they Capacitive Touch Switch

here a ebay link

This looks great. I’ve been thinking of ripping apart one of my manual fans and ‘smartening’ it :smiley:

Go for it

only thing I didn’t think of was the red LED’s you can see them thou the casing

I have a Stand up fan also thinking doing it again to that one also

Nice idea!

I’ve been using Tasmota a lot, recently. It open’s up soooo many possibilities for cool DIY projects to integrate in to HASS.

1 Like

I’d like to do something like that for a 4-speed ceiling fan? do you indicate some tutorial with tasmota?

Ok will do just need a bit of thinking on the 4 speed settings with relays


this Is how I would set up the relays

Doing this way ONLY 1 speed can ON at any on time Now Thinking of the Tasmota bit
will report back

Hi @myle and @lscosta90br

I’m doing a similar thing. I have a 3 speed fan and had this idea of using a sonoff 4ch to control it. Its almost finished! Since to select the speed you just connect the “live” wire to one of 3 wires inside the fan, and since sonoff 4ch/tamosta has “interlock” feature I just had to took off the fan control box and put the sonoff in place:

The live is connected to the common of each relay and each wire from the fan in the “Normally Open”.

Now the tricky part: how to configure HA? The “easy” way would be to use template fan, but I would have to create one switch for each speed and so on. The MQTT fan should be a better option, but there’s no single “set speed” topic (you have to turn on relay1, 2 or 3 to select speed). Any hints?

1 Like

thinking …

What about nodered

node red to be the middle man

or what about the “Template Fan” then using script to turn on/off the switches

then just make the Switches Hidden in HA

Have the same fan for my next project.

I just did exactly this recently… Use MQTT Fan as the entity in HA and do your speed selection with whatever logic necessary in Node-Red.


Nice will have a play when I get home


Good news! I got it working and was not that difficult! The catch was that I had to compile a new tasmota firmware because it seems that the pre-compiled one doesn’t support “rules”. With the new firmware in place I wrote two sets of rules: one to select the correct relay based on a “event” and the other to publish the new status so HA could refresh the state correctly. I think there’s room to improve but right now is working :-). Here’s the config:

On tasmota:

(small disclaimer: I use to change the full mqtt topic of my tasmotas)

Topic: zfan
Full Topic: home/%topic%/%prefix%/

Rule1 on event#speed0 do Power1 Off endon on event#speed1 do Power1 On endon on event#speed2 do Power2 On endon on event#speed3 do Power3 On endon

Rule2 on Power1#State do status endon on Power2#State do status endon on Power3#State do status endon

Now the HA config:

  platform: mqtt
  name: "Zwift Fan"
  state_topic: "home/zfan/stat/STATUS"
  speed_state_topic: "home/zfan/stat/STATUS"
  state_value_template: '{% if value_json["Status"]["Power"] == 0 -%}speed0{%- elif value_json["Status"]["Power"] > 0 -%}speed1{%- endif %}'
  speed_value_template: '{% if value_json["Status"]["Power"] == 0 -%}speed0{%- elif value_json["Status"]["Power"] == 1 -%}speed1{%- elif value_json["Status"]["Power"] == 2 -%}speed2{%- elif value_json["Status"]["Power"] == 4 -%}speed3{%- endif %}'
  availability_topic: home/zfan/tele/LWT
  payload_available: Online
  payload_not_available: Offline
  speed_command_topic: "home/zfan/cmnd/Event"
  payload_low_speed: "speed1"
  payload_medium_speed: "speed2"
  payload_high_speed: "speed3"
  command_topic: "home/zfan/cmnd/Event"
  payload_off: "speed0"
  payload_on: "speed1"
    - low
    - medium
    - high

Oh, yes… I can do that with node red, but I’m kind reluctant to use it as it will add another moving part to my system.


That’s thinking outside fan - square

Here is my version to turn Tasmota ON/OFF to High/Low using nodred

keep the MQTT message a like only changing the nodered bits

and the code is

the tick is with the switch part

[{"id":"62131e57.6623c","type":"mqtt out","z":"56c41a67.50c164","name":"","topic":"cmnd/SONOFF-FAN/POWER2","qos":"","retain":"","broker":"94b63d61.de1e6","x":710,"y":260,"wires":[]},{"id":"9c5ac901.e3e538","type":"inject","z":"56c41a67.50c164","name":"Manual ON testing High","topic":"","payload":"ON","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":440,"y":360,"wires":[["62131e57.6623c"]]},{"id":"684573b6.035f1c","type":"inject","z":"56c41a67.50c164","name":"Manual OFF testing Low","topic":"","payload":"OFF","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":450,"y":180,"wires":[["62131e57.6623c"]]},{"id":"edf3bd30.4dd83","type":"mqtt in","z":"56c41a67.50c164","name":"","topic":"cmnd/nodered/Fan_speed","qos":"2","broker":"94b63d61.de1e6","x":210,"y":120,"wires":[["8a830af0.8abdd8","672dbbb1.307354"]]},{"id":"8a830af0.8abdd8","type":"debug","z":"56c41a67.50c164","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":650,"y":120,"wires":[]},{"id":"672dbbb1.307354","type":"switch","z":"56c41a67.50c164","name":"Switch 1","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"Low","vt":"str"},{"t":"eq","v":"High","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":240,"y":260,"wires":[["9b8ca532.d6c188"],["db6637af.3eb9b8"]]},{"id":"9b8ca532.d6c188","type":"change","z":"56c41a67.50c164","name":"Change to OFF","rules":[{"t":"set","p":"payload","pt":"msg","to":"OFF","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":400,"y":220,"wires":[["62131e57.6623c"]]},{"id":"db6637af.3eb9b8","type":"change","z":"56c41a67.50c164","name":"Change to ON","rules":[{"t":"set","p":"payload","pt":"msg","to":"ON","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":400,"y":300,"wires":[["62131e57.6623c"]]},{"id":"20880159.98163e","type":"comment","z":"56c41a67.50c164","name":"Turn HIGH/LOW to a ON/OFF From HA","info":"","x":470,"y":80,"wires":[]},{"id":"bcc49caa.70ceb","type":"mqtt in","z":"56c41a67.50c164","name":"","topic":"stat/SONOFF-FAN/POWER2","qos":"2","broker":"94b63d61.de1e6","x":200,"y":500,"wires":[["6ba86c56.853ea4"]]},{"id":"6ba86c56.853ea4","type":"switch","z":"56c41a67.50c164","name":"Switch 2","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"ON","vt":"str"},{"t":"eq","v":"OFF","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":400,"y":500,"wires":[["8d1ce8e0.6936e8"],["1062335c.3b50ed"]]},{"id":"8d1ce8e0.6936e8","type":"change","z":"56c41a67.50c164","name":"Change to High ","rules":[{"t":"set","p":"payload","pt":"msg","to":"High","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":580,"y":460,"wires":[["533a839f.aa0eac","d47baf0a.4df4e"]]},{"id":"1062335c.3b50ed","type":"change","z":"56c41a67.50c164","name":"Change to Low","rules":[{"t":"set","p":"payload","pt":"msg","to":"Low","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":580,"y":540,"wires":[["533a839f.aa0eac","d47baf0a.4df4e"]]},{"id":"f2ae3709.660988","type":"comment","z":"56c41a67.50c164","name":"Turn ON/OFF to a HIGH/LOW if Manualy Change it","info":"","x":470,"y":420,"wires":[]},{"id":"533a839f.aa0eac","type":"mqtt out","z":"56c41a67.50c164","name":"","topic":"stat/nodered/Fan_speed","qos":"","retain":"","broker":"94b63d61.de1e6","x":810,"y":500,"wires":[]},{"id":"d47baf0a.4df4e","type":"debug","z":"56c41a67.50c164","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":810,"y":420,"wires":[]},{"id":"db18d7f0.9221d8","type":"comment","z":"56c41a67.50c164","name":"Fan Control High / Low to Tasmota ON/OFF","info":"","x":490,"y":40,"wires":[]},{"id":"94b63d61.de1e6","type":"mqtt-broker","z":"","name":"","broker":"localhost","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closePayload":"","willTopic":"","willQos":"0","willPayload":""}]

hope this help someone