Conditional call of services in template fan set_percentage

I have a xiaomi air purifier whose entities do not behave as I want. This is why I’d like to wrap it in a template fan. For the set_percentage action I have to call different services for different entities based on the set percentage. Unfortunately I could not figure out how to implement this condition.

This is what I currently have:

fan:
  - platform: template
    fans:
      air_purifier_virtual:
        friendly_name: "Air Purifier Virtual"
        value_template: "{{ states('fan.air_purifier') }}"
        percentage_template: >
          {{ ((states('number.air_purifier_favorite_level') | int + 1) * 100/15) | round(0) }}
        turn_on:
          - service: fan.set_preset_mode
            data:
              entity_id: fan.air_purifier
              preset_mode: Favorite
          - service: fan.turn_on
            data:
              entity_id: fan.air_purifier
        turn_off:
          service: fan.turn_off
          data:
            entity_id: fan.air_purifier
        set_percentage:
          - service_template: >
              {% if percentage > 0 %}
                number.set_value
              {% endif %}
            data_template:
              value: "{{ ((percentage - (100/15 | round(0))) * 15/100) | round(0) }}"
              entity_id: >
                {% if percentage > 0 %}
                  number.air_purifier_favorite_level
                {% else %}
                  none
                {% endif %}
          - service_template: >
              {% if percentage == 0 %}
                fan.turn_off
              {% endif %}
            data_template:
              entity_id: >
                {% if percentage == 0 %}
                  fan.air_purifier
                {% else %}
                  none
                {% endif %}
          - service: fan.set_preset_mode
            data:
              entity_id: fan.air_purifier
              preset_mode: Favorite
        speed_count: 15

What I want is that for percentages > 0 number.set_value on number.air_purifier_favorite_level is called. Else (i.e. for percentage == 0), fan.turn_off should be called on fan.air_purifier.

What I currently have does not work as there is no dummy or none entity that I can call. That means there is always one condition that works and another one where the template renders an invalid service. Any ideas on how to adapt this template to make it work?

Something like that?

Yes, basically. However I already tried this and it doesn’t work as the fan.turn_off service does not support the value key and extra keys are not allowed.

I did wonder about that - what happens if you change that to:

value: "{% if percentage > 0 %}{{ ((percentage - (100/15 | round(0))) * 15/100) | round(0) }}{% endif %}"

Does it accept an empty key value?

Unfortunately not. I get the same message: extra keys are not allowed.

Taking a look at the docs - Template Fan - Home Assistant they are using scripts as the service. That’s probably the way to go here. In the script we can use the choose in order to be able achieve this. Or else, just have the service set the percentage regardless of if it ends up being 0, and then have an automation that triggers on numeric_state change of the input_number ? But I’d like to see if @123 has any ideas - because they have a knack of taking something that looks really complicated and producing something elegant and neat…

Thanks for the hint using scripts! I built one that performs the required task. Here is my complete solution:

script:
  set_air_purifier_speed:
    fields:
      percentage:
        description: The percentage that should be set.
        example: '0'
    sequence:
    - choose:
      - conditions:
        - condition: template
          value_template: '{{ percentage == 0 }}'
        sequence:
        - service: fan.turn_off
          target:
            entity_id: fan.air_purifier
      - conditions:
        - condition: template
          value_template: '{{ percentage > 0 }}'
        sequence:
        - service: number.set_value
          target:
            entity_id: number.air_purifier_favorite_level
          data:
            value: '{{ ((percentage - (100/15 | round(0))) * 15/100) | round(0)}}'
        - service: fan.set_preset_mode
          target:
            entity_id: fan.air_purifier
          data:
            preset_mode: Favorite
        - service: fan.turn_on
          target:
            entity_id: fan.air_purifier
    mode: single
  turn_air_purifier_on:
    sequence:
    - choose:
      - conditions:
        - condition: template
          value_template: '{{ state_attr(''fan.air_purifier_virtual'', ''percentage'') == 0}}'
        sequence:
        - service: fan.set_percentage
          target:
            entity_id: fan.air_purifier_virtual
          data:
            percentage: 7
      - conditions:
        - condition: template
          value_template: '{{ state_attr(''fan.air_purifier_virtual'', ''percentage'') > 0 }}'
        sequence:
        - service: fan.set_preset_mode
          target:
            entity_id: fan.air_purifier
          data:
            preset_mode: Favorite
        - service: fan.turn_on
          data:
            entity_id: fan.air_purifier
    mode: single
fan:
  - platform: template
    fans:
      air_purifier_virtual:
        unique_id: "air_purifier_virtual"
        friendly_name: "Air Purifier Virtual"
        value_template: "{{ states('fan.air_purifier') }}"
        percentage_template: >
          {{ ((states('number.air_purifier_favorite_level') | int + 1) * 100/15) | round(0) }}
        turn_on:
          service: script.turn_air_purifier_on
        turn_off:
          service: fan.turn_off
          data:
            entity_id: fan.luftreiniger
        set_percentage:
          service: script.set_air_purifier_speed
          data_template:
            percentage: "{{ percentage }}"
        speed_count: 15
1 Like

That would be great! Can you show me how?

Well you can’t just copy-paste the script into the template, can you? For example there is no sequence option:

Invalid config for [fan.template]: [sequence] is an invalid option for [fan.template].