Template Fan for AC

I agree.

and the lack responses from the developers to these valid questions is quite annoying.

You would think that if they completely change the fan control paradigm then they would be a bit more forthcoming on the support in these kinds of threads instead of allowing us to flail around until someone finally stumbles on the correct answers.

It’s very clear if you actually read the fan docs about the service calls. You don’t need a dev to hand hold you with this. I don’t know why you keep posting this. These are the services. They work like every other service. There’s nothing complicated about this. A service requires specific keys. You can only use specific keys for the service.

As for the available variables, they are displayed in the example. All template devices are like this. E.g. set_speeed had the variable speed built into the set_speed action list. This is no different with these new action lists set_preset_mode and set_percentage. So, if set_speed’s variable was speed… that means set_preset_modes variable is… preset_mode.

Your issue is that set_preset_mode requires the key preset_mode. See the links above for the correct way to format the service calls:

set_preset_mode takes preset_mod as a key.
set_percentage takes percentage as a key.

Also, you’re mixing your service calls up, the service you’re calling below is climate.set_swing_mode, yet you’re supplying the service with the key preset_mode in the data section. climate.set_swing_mode does not accept that as a key.

You’ll notice that the key climate.set_swing_mode is swing_mode. So your template should look at the variable preset_mode and properly push the correct swing mode to swing_mode. E.g.

swing_mode: >
  {% if preset_mode == 'A' %}
     Swing Mode 1
  {% elif preset_mode == 'B' %}
     Swing Mode 2
  {% else %}
     Swing Mode 3
  {% endif %}

YOu have this same issue in the other service calls you’re making:

If it was just me then there wouldn’t be a bunch of these threads that I would keep posting in. And if those questions would have been answered there would be no reason to say they weren’t.

I don’t expect anyone to “hold my hand”. And frankly, that’s pretty damn insulting.

I do, however, have some expectation that if someone has a legitimate question and ask honestly then someone might be able to answer that question.

I spend A LOT of time on these forums helping others (and, yes, even “holding their hands” if necessary) for things that they don’t get even tho someone, somewhere thinks that it must be obvious because they themselves read the docs and could understand it.

All I ask is the few times I actually ask for help myself that I don’t get blown off or ignored.

I’ve been here on these forums over three years and have posted over 8,500 posts and gotten 228 Solution checkmarks but I’ve only ever created 119 threads. And not all of those threads are me asking for help. Some of those are threads - useful threads - that I posted are to help others preemptively or posting about stuff I’ve created myself to help this community. I’ve even figured out most of the new stuff enough to build another Lovelace plugin to use the new percentages. That doesn’t look like I need my hand held very often does it?

I don’t think it’s too much to ask for help (from someone other than you because you really have been extremely helpful on the few times I have needed the help - so I really do appreciate your input) and not be blown off. Even if it was just me then answering my questions would certainly help other people later who would likely have the same questions.

Case in point tho on asking a clarifying question:

In another thread where I asaked about speeds still being left in as an option you said it wasn’t needed because they created preset modes and those could be used for that purpose. Fine.

Then I see in another thread (of the many about this topic…) that a dev contradicted your statement and specifically said preset modes shouldn’t be used for speeds and even added that statement to the docs. OK, fine.

Who is correct?

I asked a question to clarify that contradiction

I replied directly to the person who made that post over 3 days ago. No response.

I haven’t been answered one time (beside you) in any thread I’ve posted in about this topic and now you tell me I’m asking for my hand to be held. Oh, please.

All I ask for is a little common courtesy. I’m not the one being rude…

You aren’t. But you can’t expect the ‘devs’ to sit here and cruise the forums. Had I saw your post, I would have replied to your question. You have to be patient or seek help elsewhere. If you want immediate help, the best course of action is to go to discord. Usually, the people who help on ALL the platforms (facebook, reddit, forums, twitter, and discord) sit there and look at stuff.

It’s not a contradiction. He’s explaining how to correlate percentage to deprecated speed modes. Each platform that interfaces with home assistant is going to use either preset_mode or percentage, these come from the hardware. Those will fork into different abilities depending on where in home assistant it’s being used. The fan you’re using just happens to only supply percentage, so that’s what you need to use.

This is identical to supported features on a light. Does a non-color light support colors? No. Does preset_mode fan support percentage? No. Do you want a percentage fan to support preset modes? If yes, make a template fan that extends the preset_modes into percentages.

I don’t necessarily expect that but let me give you a scenario…

I’ve created a few lovelace plugins and have taken over maintaining a previously created custom integration. So in a limited sense I’m a “dev” too.

Whenever I make a change to one of my “things” it’s only reasonable that I skim thru the forum thread titles to see if anyone is mentioning my “things” to see if it’s caused any issues that I need to address.

I’m the dev. It’s my responsibility to at least check to make sure I didn’t break something.

And it’s even more important if I intentionally made a breaking change so that people understand how to migrate between the two versions.

With this fan thing nothing like that happened. It was mentioned that there was a breaking change in the release and to see the docs (the docs are pretty slim on how to transition between the two versions as well so that doesn’t help at all). Then a few people in that thread asked a couple of questions and some were given cursory answers (I was one in that thread that asked a few questions and never got answered. OK, fine…).

Then there are a bunch of threads that got started outside of the release thread so It’s obvious that the docs aren’t nearly as obvious as they needed to be to handle a known breaking change.

So wouldn’t it be reasonable to expect the people who know the most about the transition to look thru the threads to see who is having issues so they can help out during the transition?

I think I have been pretty damn patient.

Like I said I asked several questions in the release thread and never got any answers. How long ago was that? Can the devs not even be expected to “cruise” even one thread on the forum once a month to help people who ask questions about that release?

And I specifically replied to the person who I saw in a few of the github threads about the breaking changes so assumed that they might know the answer and that was 3 days ago.

I’m not trying to take it personally but I kind of think it is. Eh, whatever…

If the forum moderators/devs only want “yes men” and for anyone to never ask hard questions then so be it. But that’s not me. I love this software or I wouldn’t be here so much. But I’m not going to be blindly loyal. If I see something I don’t agree with I’m going to say something and offer my arguments on why I think I’m right.

But that’s off the topic so whatever.

As far as Discord I’m not a fan. I’ve never been able to master the “flow of consciousness” format and can’t figure out how to watch for the answers to my posts. Maybe I am an idiot… :wink:

But it is.

My comment was:

You replied:

Implying that you could use the presets to continue using speeds as those presets.

the “dev” in that other thread said:

that’s pretty contradictory.

And that’s what makes it even worse right now because MQTT fans still have speeds but you get an error in the logs when you use the service.

Fine, it’s in transition.

But it doesn’t.

I only have mqtt fans that don’t have percentages according to the docs (well I have one zigbee fan that I haven’t even tried to tackle yet) so I can’t update those.

Right now I think people are creating template fans from the mqtt fans to get it to work. I think I even saw one person create a template light that used the fan as the device to update the states and used the brightness as the speeds. That’s not confusing at all…

And right now everything still works using speeds for those fans but it’s going away (supposedly) so I’m trying to get ahead of it.

But I also would really like to figure out a way to not have to say “set the fan to 33% for low speed”. And I’m not the only one. even “sparkydave” said they weren’t going to upgrade because of this specific change. Whether that’s still true I really don’t know.

But the point is I’ve tried to offer some feedback on requesting that we try to keep the backwards compatibility for people who use voice assistants and use speeds instead of forcing them to remember the percentages when they want to control their fans. And I’ve been met with a wall of silence.

At least if people use my fan control rows they are configurable enough to still list low, med, high in the frontend even if the fan forces them to use percentages in the background. So it’s not like I’m not thinking of others to solve this for them. I just can’t figure out a way to still use speeds via voice control.

Or why I can’t use speeds thru the presets.

Hence the question above that never got answered.

it’s not even about that either.

My mqtt fans support a discreet off, low, med, high settings. They have no percentages at all.

My zigbee fan has off, low, med, high, not percentages at all.

how can I use the presets to control those speeds settings?

according to bdraco I can’t. I have to use percentages. But why not?

What I want is a speed fan to support preset modes. Which shouldn’t be a problem I wouldn’t think.

But it might be. But I don’t know because no one will answer a question.

And if I get those questions answered I’ll create another fan control row for people who use presets. I just need to know a bit more about what is and isn’t used.

Why can’t you be that guy? Demanding support is not the way to go. In fact, that gets people to ignore you. Especially when you trash talk them left and right. I’ve tried explaining this to you in DMs in the past, maybe this time you’ll understand that your actions have consequences. I personally try to look past this and continue to help those that upset me. Others are not like that.

He replied to you as a literal conversion. Everything that speeds was is now percentages. Adding a preset mode is exactly like using low, medium, or high. It’s a preset value of the percentage. Have you tried adding this to solve the issue with voice below?

Sorry, I can’t help you here as I don’t use MQTT fans. However, I would consider creating an issue about it if you’re getting exceptions. Also requesting a preset_mode template wouldn’t be out of the question for MQTT fans. It could exist already, I have no idea.

If the above doesn’t work with preset_mode, have you reported this as an issue yet? I’ve mentioned reporting this at least 2 times to you. This would require a change to the smart_home alexa library or the cloud configuration (alexa/google home). It has little to do with fans. If you don’t want to take the proper avenues to report an issue, there’s not much that can be done.

I have no problem with that. but we all have to get the information from somewhere. Usually we aren’t born with the information for everything already in our heads. That’s why we ask the experts who already know the stuff.

I’ve never “demanded” anything.

I’ve asked questions. got ignored. asked some more questions because I got ignored on the first ones. and got ignored some more. THen pointed out as much in a few threads on the subject that I asked those questions about.

That’s not demanding anything.

I’ve never trash talked about anyone.

Show me where I did it.

Just because I disagree, even vehemently, isn’t trash talking.

I’m not sure who you are thinking of but I’ve looked thru all of our private messages over the last couple of years (there’s not that many…) and from what I saw we always had a decent good natured exchange in those messages. As a matter of fact there was some bit of trash talking of others in those messages by you. I saw nowhere that you needed to explain anything about this.

Again not every exchange has been 100% positive because we have had our disagreements but I wouldn’t call many of our interactions overly contentious.

He didn’t reply to me at all. Maybe you thought that the response was to me but it wasn’t. It was directed at cybergrimes.

And that’s what I was trying to get clarification on. From his post it didn’t seem to me that’s what he was saying.

Not yet since I wasn’t sure what I needed to do.

I could but from my limited understanding of how things are moving toward not using speeds it’s lilely to e closed since it is a feature not a bug.

Or maybe it’s not and the MQTT fans will always keep a speed list like they do now. I really don’t know since that question wasn’t answered. I’d hate to submit a bug report on something that isn’t and waste everyone’s time. I figured I’d try to find out how it’s supposed to work before I decided it’s broken. But I haven’t gotten that resolved yet.

I’ll give it a try but we all know how the FR’s get handled.

And before it’s said. no I don’t have the technical knowledge to write a PR for it.

Again, I don’t even know if it is an issue.

According to the official docs you aren’t supposed to use presets for speeds. Again, looking for clarification before wasting peoples time.

(But then again here we are now…so there’s that…)

I’m not sure I follow you on that.

Why would those need changed?

Speeds commands (low, medium, high) worked perfectly fine before (and still do so far) thru the Alexa integration.

But whatever…I see no reason to keep this going any further if you don’t.

I guess I’ll go off and live with the consequences now. :wink:

No, you aren’t born with it but you can handle it like other users by researching the functionality or trial and error. That’s what other ‘top’ users do.

As for the rest of your response:

Even if you don’t know it’s a bug, it doesn’t mean you should avoid writing up the issue. Issue’s and PRs are a direct line to answers on functionality regardless how you look at it. Especially if you don’t fully know the process or the code.

Hmm, I did manage to get it to work but the values are not showing correctly. I guess I don’t understand the way this works.
I tested more and I found out that the speed_count variable sets the percentage step.
It is kinda confusing because you are defining the steps manually anyway.
I have a couple of questions too if you don’t mind answering.
The first problem I noticed is that the fan cannot set its default values from climate entity.
They are all null.
The climate entity has following values initially:

hvac_modes: fan_only, dry, cool, heat, heat_cool, off
min_temp: 7
max_temp: 35
target_temp_step: 1
fan_modes: Auto, Silence, 1, 2, 3, 4, 5
preset_modes: none, away, eco, boost
swing_modes: Off, Vertical, Horizontal, 3D
current_temperature: 25.5
temperature: 27
fan_mode: 1
preset_mode: none
swing_mode: Vertical

But the fan entity has these values:

speed_list: off, low, medium, high
preset_modes: Off, Vertical
speed: null
percentage: 0
percentage_step: 10
preset_mode: null

Here the percentage is 0, speed is null and preset_mode is null which are not correct.
Am I wrong to assume that the percentage_template variable should convert the appropriate value for the percentage and speed?

      percentage_template: >-
        {% if is_state_attr('climate.daikinac', 'fan_mode', 'Silence')  %}
          5
        {% elif is_state_attr('climate.daikinac', 'fan_mode', 1) %}
          20
        {% elif is_state_attr('climate.daikinac', 'fan_mode', 2) %}
          40
        {% elif is_state_attr('climate.daikinac', 'fan_mode', 3) %}
          60
        {% elif is_state_attr('climate.daikinac', 'fan_mode', 4) %}
          80
        {% elif is_state_attr('climate.daikinac', 'fan_mode', 5) %}
          100
        {% endif %}

The current fan_mode is 1, so it should reflect as 5 in the template fan value right?
Same with the preset_mode:

      preset_mode_template: >-
        {% if is_state_attr('climate.daikinac', 'swing_mode', 'Vertical') %}
          Vertical
        {% else %}
          Off
        {% endif %}

Current swing_mode on the climate entity is Vertical, so it should be Vertical instead of null right?
Another thing I want to ask is, if we adjust the fan percentage to zero, how can we convert that to a turn off command for the climate entity?
Btw, your advise was spot on, thank you for that. At least, now I can send commands instead of getting errors.
I assumed that set_percentage was always expecting a percentage.
Current full code is below.

- platform: template
  fans:
    daikinac_fan:
      friendly_name: "Daikin AC Fan"
      unique_id: "Daikin AC Fan"
      value_template: >-
        {% if states('climate.daikinac') in ['fan_only', 'dry', 'cool', 'heat', 'heat_cool']  %}
          on
        {% else %}
          off
        {% endif %}
      availability_template: >-
        {% if states('climate.daikinac') in ['fan_only', 'dry', 'cool', 'heat', 'heat_cool', 'off']  %}
          true
        {% else %}
          false
        {% endif %}
      percentage_template: >-
        {% if is_state_attr('climate.daikinac', 'fan_mode', 'Silence')  %}
          5
        {% elif is_state_attr('climate.daikinac', 'fan_mode', 1) %}
          20
        {% elif is_state_attr('climate.daikinac', 'fan_mode', 2) %}
          40
        {% elif is_state_attr('climate.daikinac', 'fan_mode', 3) %}
          60
        {% elif is_state_attr('climate.daikinac', 'fan_mode', 4) %}
          80
        {% elif is_state_attr('climate.daikinac', 'fan_mode', 5) %}
          100
        {% endif %}

      turn_on:
        service: climate.turn_on
        target:
          entity_id: climate.daikinac

      turn_off:
        service: climate.turn_off
        target:
          entity_id: climate.daikinac

      set_percentage:
        service: climate.set_fan_mode
        target:
          entity_id: climate.daikinac
        data_template:
          fan_mode: >-
            {% if percentage <= 5  %}
              Silence
            {% elif 5 < percentage <= 20 %}
              1
            {% elif 20 < percentage <= 40 %}
              2
            {% elif 40 < percentage <= 60 %}
              3
            {% elif 60 < percentage <= 80 %}
              4
            {% elif 80 < percentage <= 100 %}
              5
            {% endif %}

      preset_mode_template: >-
        {% if is_state_attr('climate.daikinac', 'swing_mode', 'Vertical') %}
          Vertical
        {% else %}
          Off
        {% endif %}

      preset_modes:
        - 'Off'
        - 'Vertical'

      set_preset_mode:
        service: climate.set_swing_mode
        target:
          entity_id: climate.daikinac
        data_template:
          swing_mode: >
            {% if preset_mode == 'Off' %}
              Off
            {% elif preset_mode == 'Vertical' %}
              Vertical
            {% else %}
              Off
            {% endif %}

      speed_count: 100

The value in the attributes come from the templates. So your speed attribute comes from the speed_template, which you don’t have. So that’s null. And the preset mode comes from preset_mode_template.

FYI you can simplify your swing_mode template to swing_mode: "{{ preset_mode }}" without the if statements.

Your speed_count is off. It should be 5 (possibly 6, i’d need to play around). and here’s a quick template that gets you the actual calc.

      set_percentage:
        service: climate.set_fan_mode
        target:
          entity_id: climate.daikinac
        data_template:
          fan_mode: >-
            {% set idx = (percentage / ( 100 / 5 )) | int %}
            {% if idx == 0 %}
              Silence
            {% else %}
              {{ idx }}
            {% endif %}

      percentage_template: >-
        {% set attr = state_attr('climate.daikinac', 'fan_mode') %}
        {% if attr == 'Silence' %}
          0
        {% else %}
          {% set attr = attr | int %}
          {{ attr * 100 / 5 }}
        {% endif %}

If you need to change it to 6, then you’ll have to adjust the equations. Either way, speed_count determines the number of sections for percentage. At least that’s how I understood it.

Oh, this actually worked.
But why does this work

but this doesn’t work?

Again same with the fan_mode:
this doesn’t work:

        data_template:
          fan_mode: >-
            {% if 0 >= percentage >= 5 %}
              Silence
            {% elif 5 > percentage >= 20 %}
              1
            {% elif 20 > percentage >= 40 %}
              2
            {% elif 40 > percentage >= 60 %}
              3
            {% elif 60 > percentage >= 80 %}
              4
            {% elif 80 > percentage >= 100 %}
              5
            {% else %}
              Error
            {% endif %}

but this works:

It is using the same logic. Where am I wrong?

Another problem, why does preset mode still gets the null value? It does not take the value from the climate entity.
I tried this:

preset_mode_template: "{{ state_attr('climate.daikinac', 'swing_mode') }}"

and this:

      preset_mode_template: >-
        {% if is_state_attr('climate.daikinac', 'swing_mode', 'Vertical') %}
          Vertical
        {% else %}
          Off
        {% endif %}

none of them works.

Well, it could be a number of things. But essentially everything is tied together. When you set speed_count to a number, 100 is divided by that number and those the percentages that are fed to the percentage variable. The code I wrote takes 5 distinct percentages and maps them to 5 values. Your version takes 100 values and you only map that to 5 (and vice versa). Also, it’s not clear if ‘fan_mode’ is strings or ints. Your version assumes they are ints. My version ensures they are ints.

I’m not sure, I’ll have to investigate. What you have should work.

I am not so sure about that. Logically percentage_template should take a value from somewhere. In this case, it is a climate entity where you have defined precise values to select from because you know which values climate entity will have.
So, using this should work but there is no clear explanation why it doesn’t work. It is pretty straightforward. Your version does the same thing with a formula. The only thing I can think of would be integers and strings being mixed but I don’t think so.

 percentage_template: >-
        {% if is_state_attr('climate.daikinac', 'fan_mode', 'Silence')  %}
          5
        {% elif is_state_attr('climate.daikinac', 'fan_mode', 1) %}
          20
        {% elif is_state_attr('climate.daikinac', 'fan_mode', 2) %}
          40
        {% elif is_state_attr('climate.daikinac', 'fan_mode', 3) %}
          60
        {% elif is_state_attr('climate.daikinac', 'fan_mode', 4) %}
          80
        {% elif is_state_attr('climate.daikinac', 'fan_mode', 5) %}
          100
        {% endif %}

I am just confused about this. I don’t know if there are inherit problems with this new “template fan” integration or there is something wrong with my logic here.

I’m 100% positive what I said is why it does work. It’s very unlikely that it’s anything else. See the explanation below.

There’s nothing wrong with the integration. The templating is handled just like every other template field. Here are the 2 things wrong with your logic:

  1. You assume fan_mode returns an int. If it’s a string, those elif’s will never be hit. The likely hood of an attribute returning a string and an int based on the context is low. So changing those numbers to strings would probably work. This is why my template always works, I cast everything that’s not silence as an int. Which leads to #2
  2. You don’t have an else statement. So when 1 ultimately occurs the value gets set to nothing. I believe that defaults it to zero.

Here are the results after more testing:
1- preset_mode_template doesn’t get the value from the climate entity. It is null.
2- set_preset_mode does work but for some reason whenever you select a preset during the operation (like selecting Vertical) sets the percentage null. I don’t see any relation between them so why does setting preset to something affect the percentage?

Also for some reason, when you select a preset mode like Vertical or Off, preset_mode is reflected on the speed variable? Why?

speed_list: off, low, medium, high
preset_modes: Off, Vertical
speed: Vertical
percentage: null
percentage_step: 1
preset_mode: Vertical

I have been using home assistant for some time now, but this fan integration made me sweat.

1 Like

Have you found out why this doesn’t work? I’ve run into the same issue where preset_mode_template always sets preset_mode to null. The template works, so it’s not that.

what’s your template? It’s most definitely your template. That state is only pulled from the template and it will only be null if the template is wrong or the output does not match a preset mode.

Post your entire configuration for the template fan, not just the template.

I have similar issues with the fan_template
I think this thing is buggy or I don’t understand how it works.

preset_mode remains “null”

This is my template fan:

fan:
  - platform: template
    fans:
      mechanische_ventilatie:
        friendly_name: Mechanische ventilatie
        value_template: >
          {{ states('sensor.mechanische_ventilatie_status') }}
        availability_template: >
          {{ states('sensor.mechanische_ventilatie_status') }}
        percentage_template: >
          {{ state_attr('sensor.mechanische_ventilatie_status', 'percentage') }}
        preset_mode_template: >
          {{ state_attr('sensor.mechanische_ventilatie_status', 'preset') }}
        turn_on:
          service: script.ventilation_turn_on_off_dummy
        turn_off:
          service: script.ventilation_turn_on_off_dummy
        set_percentage:
          service: script.ventilation_set_voltage
          data:
            voltage: '{{ percentage / 10 }}'
        set_preset_mode:
          service: script.ventilation_set_preset_mode
          data:
            preset_mode: '{{ preset_mode }}'
        preset_modes:
          - 'lo'
          - 'med'
          - 'hi'
          - 'max'

Data looks like this:

speed_list:
  - 'off'
  - low
  - medium
  - high
preset_modes:
  - lo
  - med
  - hi
  - max
speed: medium
percentage: 35
percentage_step: 1
preset_mode: null
friendly_name: Mechanische ventilatie
supported_features: 1

Should we somehow do something with that “supported features” property?

I see quite some code in the template/fan.py doing the stuff we experience:

from line 305

    @property
    def preset_modes(self) -> list:
        """Get the list of available preset modes."""
        if self._preset_modes is not None:
            return self._preset_modes
        return preset_modes_from_speed_list(self._speed_list)

line 416:

self._speed = preset_mode

line 531:

 self._preset_mode = speed if speed in self.preset_modes else None

etc.

I also read this. Still I don’t understand what I’m doing wrong.

Deprecated Properties#

The fan entity model has changed to use percentages in the range from 0 (off) to 100 instead of the named speeds. The new model replaces speed and speed_list with percentage, preset_mode, and preset_modes. This change allowed us to expand the number of supported speeds to accommodate additional fan models in Home Assistant.

To maintain backwards compatibility with integrations that have not updated to the new model, the deprecated properties will remain until at least the end of 2021. Integrations must update their Turn on function to consume percentage or preset_mode instead of speed.

does sensor.mechanische_ventilatie_status have preset attribute? That’s the only reason why this would show up null.

To further clarify:

preset_mode_template is what populates the attribute preset_mode in the state object.
set_preset_mode is what is called when you change the preset mode via the dropdown/combobox or the service for the entity.
preset_modes is the list of values that appear in the dropdown/combobox

1 Like