Sonoff IFan02 (Tasmota) MQTT Fan

I think it needs an elif at the end for power1 on and off. Just a hunch. Can we use pass in the imposed state in a template?

I’m not sure I understand.

Examples?

@finity
I was thinking something like this

{% if value_json.FanSpeed == 0 -%}0{%- elif value_json.FanSpeed > 0 -%}4{%- elif 
value_json.POWER1 == "ON" -%}
{%- elif value_json.POWER1 == "OFF" -%}{%- endif %}

I wondered if it would template without a value after the if and it does. If it didn’t, I was thinking pass (from python) might work.

If this is the mqtt message, maybe it would quash the error if we gave it a meaningless dict value that fit the mqtt messages (listed below):

stat/iFan1/POWER1 ON
cmnd/iFan1/POWER1 OFF
stat/iFan1/RESULT {"POWER1":"OFF"}
stat/iFan1/POWER1 OFF

EDIT: It’s the conditional "value_json.FanSpeed > 0 " that causes the error to be thrown and this keeps any abberant statement like POWER1 from reaching an else endpoint. I’m not really clear how to get around this hurdle and keep everything working. .

@finity
Something tells me that we’re going at the fan component wrong and that’s why it’s giving the error. While the error is innocuous, it says that something isn’t right the way it’s set up.

My understanding of it is that because tasmota published all results to one topic and that topic includes both light and fan, the fan component fails. It’s weird because it’s parsing the JSON incorrectly and trying to read the “POWER1”:“ON” component as fanspeed. To me, this seems like a problem on the HA end but I’m not familiar enough with the codebase to try to find why it parses incorrectly.

If you agree, I guess we should think about reporting an issue on github.

I didnt like the fan component/card so I set it up with switches, automation, script and input_number

the switches

- platform: mqtt
  name: "Room Two FanLight"
  command_topic: "cmnd/sonoffifan/roomtwo/power1"
  state_topic: "stat/sonoffifan/roomtwo/POWER1"
  optimistic: false
  qos: 1
  payload_on: "ON"
  payload_off: "OFF"
  retain: false  
- platform: mqtt
  name: "Room Two FanSpeed1"
  command_topic: "cmnd/sonoffifan/roomtwo/result/fanspeed"
  state_topic: "stat/sonoffifan/roomtwo/RESULT"
  optimistic: false
  qos: 1
  payload_on: 1
  payload_off: 0
  value_template: '{%- if value_json.FanSpeed == 1 -%}1{%- elif value_json.FanSpeed == 2 or value_json.FanSpeed == 3 or value_json.FanSpeed == 0 -%}0{%- endif -%}'
  retain: false  
- platform: mqtt
  name: "Room Two FanSpeed2"
  command_topic: "cmnd/sonoffifan/roomtwo/result/fanspeed"
  state_topic: "stat/sonoffifan/roomtwo/RESULT"
  optimistic: false
  qos: 1
  payload_on: 2
  payload_off: 0
  value_template: '{%- if value_json.FanSpeed == 2 -%}2{%- elif value_json.FanSpeed == 1 or value_json.FanSpeed == 3 or value_json.FanSpeed == 0 -%}0{%- endif -%}'
  retain: false
- platform: mqtt
  name: "Room Two FanSpeed3"
  command_topic: "cmnd/sonoffifan/roomtwo/result/fanspeed"
  state_topic: "stat/sonoffifan/roomtwo/RESULT"
  optimistic: false
  qos: 1
  payload_on: 3
  payload_off: 0
  value_template: '{%- if value_json.FanSpeed == 3 -%}3{%- elif value_json.FanSpeed == 1 or value_json.FanSpeed == 2 or value_json.FanSpeed == 0 -%}0{%- endif -%}' 
  retain: false

The input number

office_fan:
  name: Fan Speed
  initial: 0
  min: 0
  max: 3
  step: 1
  mode: slider
  unit_of_measurement: step
  icon: mdi:fan

the automaiton

- id: office_fan_presets
  alias: Office fan input slider
  trigger:
  - platform: state
    entity_id: input_number.office_fan
  action:
  - service_template: script.office_fan_speed_{{ trigger.to_state.state|int }}

scripts

office_fan_speed_0:
  sequence:
  - service: switch.turn_off
    entity_id: switch.room_two_fanspeed1
office_fan_speed_1:
  sequence:
  - service: switch.turn_on
    entity_id: switch.room_two_fanspeed1
office_fan_speed_2:
  sequence:
  - service: switch.turn_on
    entity_id: switch.room_two_fanspeed2
office_fan_speed_3:
  sequence:
  - service: switch.turn_on
    entity_id: switch.room_two_fanspeed3

I’ve posted another thread trying to get some help working this out:

But so far I’m not figuring out why it’s not working.

What’s really strange is that even with the error popping up the fan component isn’t really technically “failing”. everything still works. It just complains that the message doesn’t contain the “FanSpeed” key.

Aside from figuring out how to prevent the log entry from popping up I’m not even sure it’s worth trying to put much more time into it. :thinking:

And I’m not even sure it’s an “issue” since the error is actually valid.

I’ll try some more things tho to see if I can get it worked out.

Appreciate the effort. I’m thinking the problem might be in the MQTT fan component. JSON parsers shouldn’t look at other keys, but I can understand why it would throw an error if it wasn’t in the dictionary. I’ve tried several times to add it to the dictionary using the template various ways but nothing has worked.

Just to finalize this thread, here is the code that works correctly and gets rid of the json error:

- platform: mqtt  
    name: "Master Bedroom Fan"
    command_topic: "cmnd/sonoff_MBR_fan/FanSpeed"
    speed_command_topic: "cmnd/sonoff_MBR_fan/FanSpeed"    
    state_topic: "stat/sonoff_MBR_fan/RESULT"
    speed_state_topic: "stat/sonoff_MBR_fan/RESULT"
    state_value_template: >
      {% if value_json.FanSpeed is defined %}
        {% if value_json.FanSpeed == 0 -%}0{%- elif value_json.FanSpeed > 0 -%}4{%- endif %}
      {% else %}
        {% if states.fan.master_bedroom_fan.state == 'off' -%}0{%- elif states.fan.master_bedroom_fan.state == 'on' -%}4{%- endif %}
      {% endif %}
    speed_value_template: "{{ value_json.FanSpeed }}"
    availability_topic: tele/sonoff_MBR_fan/LWT
    payload_off: "0"
    payload_on: "4"
    payload_low_speed: "1"
    payload_medium_speed: "2"
    payload_high_speed: "3"
    payload_available: Online
    payload_not_available: Offline
    speeds:
      - off
      - low
      - medium
      - high

I ended up having to remove the " from inside the “if” statement but I’m still not sure exactly why.

Thanks to @gpbenton in the other thread for helping me work thru this.

5 Likes

man! That is so many if statements we can call it AI. Tested just now and works great. Just formatted the block a little different:

  state_value_template: >-
                        {% if value_json.FanSpeed is defined %}
                            {% if value_json.FanSpeed == 0 -%}0
                            {%- elif value_json.FanSpeed > 0 -%}2
                            {%- endif %}
                        {%- else -%}
                            {% if states.fan.iFan1.state == 'off' -%}0
                            {%- elif states.fan.iFan1.state == 'on' -%}2
                            {%- endif %}
                        {%- endif %}
1 Like

This would be great to merge into the iFan02 entry on the Tasmota wiki!

1 Like

Did it yesterday. Used Finity post as the reference. Anyone can edit the wiki, so feel free. :smile:

@jumblies

That’s weird. So did I…:thinking:

Thanks for the info, I was annoyed by this error.
Another thing I suggest adding to the configuration is querying the fan state at startup, since tasmota send different topic for telemetry and command result, if HASS is restarted while the fan is on, it will never update with the correct status unless a command is issued.
To over come this I add the following to the automations:

- id: Startup_Automations
  alias: Startup Automations
  hide_entity: True
  trigger:
    platform: homeassistant
    event: start
  action:
   - service: mqtt.publish
     data:
      topic: 'cmnd/sonoff_MBR_fan/FanSpeed'
      payload: ''

This will send a command at startup to request the current fan speed.

Another nice option is to use packages folder so the fan configuration can be under one file, example at:
https://www.home-assistant.io/docs/configuration/packages/

1 Like

Thanks for the suggestion on the query at startup but I’m already doing that. That was something I found out about over on the tasmota ifan02 issues thread.

I haven’t spent any time trying to figure out packages yet. Maybe I will someday as it looks like a way to uncomplicated things a bit.

@finity
I missed this. I wonder if we’re editing different wiki pages. I put mine on the iFan page. Did you put yours on the HA page? If so, Probably clearer for me to link to yours there? Open source documentation is messy enough and if we can just have one working template, I think it’ll reduce user frustration.

I have this unit in my gym and what I want is if there is a humidity and/or temp differential between floor and ceiling, it runs the fan to cool off a rider on excercise bike. I’ve looked and there is a definite “sweat” gradient from floor to ceiling during exercise.

Nope. I looked and you edited the same one I did after me. It’s OK but probably ought to still give credit to @kbickar for coming up with the original config that I just modified a bit.

That’s the way I had it before you edited it.

Are you asking for help with the automation or is the last part just an FYI?

Just an FYI but I sure do appreciate the offer of help. I’m thinking to just have the automation detect the delta between temp and hum from top to bottom. I don’t even think it’ll require a “new” template sensor. I’ll cogitate on it for a while since I don’t use the bike indoor unless there is foul weather.

I’m also considering, and bear with me here, a pendant fan hooked to the light on the iFan02. One that hangs down and is directed right below. It’s kooky, I know, but the ceiling fan just doesn’t generate enough direct airflow, nor is it designed to.

@finity @jumblies
Do the .yaml examples you guys posted in the Tasmota wiki (also shown above) work without having to set up that custom 4-button card?
e.g. sending a “4” in the “on” command.

I was just thinking that if those examples do require the custom card then you might want to include info/links to that as well.

Would you guys mind if I added an example on the wiki using kbickar’s original .yaml with the state_value_template json-error-cleanup? I don’t want to step on any toes but feel that example should be readily available as well.

No. They don’t require the card. Iirc you’ll get a switch for fan and light but when you click on fan the entity will open allowing you to chose speed. Visit the thread on github and you can see some evolution as we worked it out.

You never have to ask about editing a wiki. Please do. Ha docs are sparse and always need updating

Hi,

I have used the code form the tasmota wiki for my ifan but i only see one button. (see image)

fan:
  - platform: mqtt  
    name: "Master Bedroom Fan"
    command_topic: "cmnd/sonoff_MBR_fan/FanSpeed"
    speed_command_topic: "cmnd/sonoff_MBR_fan/FanSpeed"    
    state_topic: "stat/sonoff_MBR_fan/RESULT"
    speed_state_topic: "stat/sonoff_MBR_fan/RESULT"
    state_value_template: >
      {% if value_json.FanSpeed is defined %}
        {% if value_json.FanSpeed == 0 -%}0{%- elif value_json.FanSpeed > 0 -%}4{%- endif %}
      {% else %}
        {% if states.fan.master_bedroom_fan.state == 'off' -%}0{%- elif states.fan.master_bedroom_fan.state == 'on' -%}4{%- endif %}
      {% endif %}
    speed_value_template: "{{ value_json.FanSpeed }}"
    availability_topic: tele/sonoff_MBR_fan/LWT
    payload_off: "0"
    payload_on: "4"
    payload_low_speed: "1"
    payload_medium_speed: "2"
    payload_high_speed: "3"
    payload_available: Online
    payload_not_available: Offline
    speeds:
      - off
      - low
      - medium
      - high

fan