Is it not possible to concatenate some text in a template sensor with nested ifs and show it correctly in a markdown card?

I’m trying to create a textual representation of all my covers. I have created here for a template sensor with nested ifs:

template:
  - sensor:
      - name: "Rolluiken_status"
        state: >
          {% set masterbedroom = state_attr('cover.master_bedroom', 'current_position' ) | int %}
          {% set voorraamklein = state_attr('cover.voorraam_klein', 'current_position' ) | int %}
          {% set vooraamgroot = state_attr('cover.voorraam_groot', 'current_position' ) | int %}
          {% set computerkamer = state_attr('cover.computer_kamer', 'current_position' ) | int %}
          {% set hal1eetage = state_attr('cover.hal_1e_etage', 'current_position' ) | int %}
          {% set zijraam = state_attr('cover.zijraam', 'current_position' ) | int %}
          {% set badkamer = state_attr('cover.badkamer', 'current_position' ) | int %}
          {% set logeerkamer = state_attr('cover.logeerkamer', 'current_position' ) | int %}
          {% set achterdeur = state_attr('cover.achterdeur', 'current_position' ) | int %}
          {% set achterraam = state_attr('cover.achterraam', 'current_position' ) | int %}
          
          {% if masterbedroom == 100 and voorraamklein == 100 and vooraamgroot == 100 and computerkamer == 100 and hal1eetage == 100 and
                zijraam == 100 and badkamer == 100 and logeerkamer == 100 and achterdeur == 100 and achterraam == 100 %}
            Alle rolluiken zijn **OPEN**.
          {% elif masterbedroom == 0 and voorraamklein == 0 and vooraamgroot == 0 and computerkamer == 0 and hal1eetage == 0 and
                zijraam == 0 and badkamer == 0 and logeerkamer == 0 and achterdeur == 0 and achterraam == 0 %}
            Alle rolluiken zijn **GESLOTEN**.
          {% else %}
          
            {% if masterbedroom == 100 and voorraamklein == 100 and vooraamgroot == 100 %}
              Voorkant **OPEN**.
            {% elif masterbedroom == 0 and voorraamklein == 0 and vooraamgroot == 0 %}
              Voorkant **GESLOTEN**.
            {% else %}
              TODO: specify....
            {% endif %}
          
            {% if computerkamer == 100 and hal1eetage == 100 and zijraam == 100 %}
              Westkant **OPEN**.
            {% elif computerkamer == 0 and hal1eetage == 0 and zijraam == 0 %}
              Westkant **GESLOTEN**.
            {% else %}
              TODO: specify....
            {% endif %}

            {% if logeerkamer == 100 and badkamer == 100 and achterdeur == 100 and achterraam == 100 %}
              Achterkant **OPEN**.
            {% elif logeerkamer == 0 and badkamer == 0 and achterdeur == 0 and achterraam == 0 %}
              Achterkant **GESLOTEN**.
            {% elif logeerkamer == 0 and badkamer == 0 %}
              Dakkapel **GESLOTEN**.
            {% else %}
              TODO: specify....
            {% endif %}
          {% endif %}


But you see that it is not showed correctly in the markdown card in the frontend. It this a bug or is not possible or do I something wrong?

markdown_covers1

I used to have something similar before. But it worked for me.
If I remember correctly I had the text in an attribute. Not sure if that makes a difference.

The Markdown card has some style codes and ** could be one of them.
If you want it to be bold, then try to put in front and behind the text instead.

Yes I know. I use that kind of codes.

But you see that the second and tirth line of text are not correctly aligned (indented) and not marked up and you see some gray background color.

Okay found it!

The nested ifs were 2 steps indented instead of 1.

I have still one problem. In the template sensor I want to concatenate a integer to some text and set it in a variable:

             {% set computerkamerStatus = '' %}

.....some other script.....

               {% set computerkamerStatus = '**' + {{computerkamer}} + '**' %}

computerkamer is an integer. So I want to surround it with ** (for the bold text)

The problem is that it is not accepted.

So how do you concatenate integer and text values?

First, you don’t need the curly brackets when you’re already in a Jinja block. Second, you can only concatenate strings together, so you need to use the string filter. Also, don’t forget about the template editor in developer tools, it is pretty helpful for debugging.

Here is an example:

{% set example_int = 7 %}
{% set example_string = "**" + (example_int | string) + "**" %}
The example string is {{ example_string }}.

Or just replace + with ~.
+ is used for math but is also understood when it’s strings, but as soon as you mix strings and integers it doesn’t know what you actually want to do.
~ is to concatenate strings.

{% set computerkamer = 2 %}
{% set computerkamerStatus = '**' ~ computerkamer ~ '**' %}
{{ computerkamerStatus }}
1 Like

@r-j-taylor @Hellis81 Thanks, both solutions works!

But I notice that my sensor representing in a markdown card gives sometimes not the correct information but shows: “unavailable” in stead of my created text.

There is a lot of text in my sensor (and i’m still not ready). Is that the problem? Is there a maximum? Is it to complex?

template:
  - sensor:
      - name: "Rolluiken_status"
        state: >
          {% set masterbedroom = state_attr('cover.master_bedroom', 'current_position' ) | int %}
          {% set voorraamklein = state_attr('cover.voorraam_klein', 'current_position' ) | int %}
          {% set voorraamgroot = state_attr('cover.voorraam_groot', 'current_position' ) | int %}
          {% set computerkamer = state_attr('cover.computer_kamer', 'current_position' ) | int %}
          {% set hal1eetage = state_attr('cover.hal_1e_etage', 'current_position' ) | int %}
          {% set zijraam = state_attr('cover.zijraam', 'current_position' ) | int %}
          {% set badkamer = state_attr('cover.badkamer', 'current_position' ) | int %}
          {% set logeerkamer = state_attr('cover.logeerkamer', 'current_position' ) | int %}
          {% set achterdeur = state_attr('cover.achterdeur', 'current_position' ) | int %}
          {% set achterraam = state_attr('cover.achterraam', 'current_position' ) | int %}
          
          {% if masterbedroom == 100 and voorraamklein == 100 and vooraamgroot == 100 and computerkamer == 100 and hal1eetage == 100 and
                zijraam == 100 and badkamer == 100 and logeerkamer == 100 and achterdeur == 100 and achterraam == 100 %}
            Alle rolluiken zijn **OPEN**.
          {% elif masterbedroom == 0 and voorraamklein == 0 and vooraamgroot == 0 and computerkamer == 0 and hal1eetage == 0 and
                zijraam == 0 and badkamer == 0 and logeerkamer == 0 and achterdeur == 0 and achterraam == 0 %}
            Alle rolluiken zijn **GESLOTEN**.
          {% else %}



           {% set master_bedroom_ventilatie = states('input_number.master_bedroom_cover_ventilatie_positie') | int %}
           {% set voorraam_klein_ventilatie = states('input_number.voorraam_klein_cover_ventilatie_positie') | int %}
           {% set voorraam_groot_ventilatie = states('input_number.voorraam_groot_cover_ventilatie_positie') | int %}

           {% if masterbedroom == 100 and voorraamklein == 100 and voorraamgroot == 100 %}
             Voorkant **OPEN**.
           {% elif masterbedroom == 0 and voorraamklein == 0 and voorraamgroot == 0 %}
             Voorkant **GESLOTEN**.
           {% elif masterbedroom == master_bedroom_ventilatie and voorraamklein == voorraam_klein_ventilatie and voorraamgroot == voorraam_groot_ventilatie %}
             Voorkant **VENTILATIE**.
           {% else %}
             {% set master_bedroomStatus = '' %}
             {% set voorraam_kleinStatus = '' %}
             {% set voorraam_grootStatus = '' %}
             
             {% if masterbedroom == 100 %}
              {% set master_bedroomStatus = 'OPEN' %}
             {% elif masterbedroom == 0 %}
              {% set master_bedroomStatus = 'GESLOTEN' %}
             {% elif masterbedroom == master_bedroom_ventilatie %}
              {% set master_bedroomStatus = 'VENTI' %}
             {% else %}
              {% set master_bedroomStatus = ((100 - masterbedroom) | string) + "%" %}
             {% endif %}
             
             {% if voorraamklein == 100 %}
              {% set voorraam_kleinStatus = 'OPEN' %}
             {% elif voorraamklein == 0 %}
              {% set voorraam_kleinStatus = 'GESLOTEN' %}
             {% elif voorraamklein == voorraam_klein_ventilatie %}
              {% set voorraam_kleinStatus = 'VENTI' %}
             {% else %}
              {% set voorraam_kleinStatus = ((100 - voorraamklein) | string) + "%" %}
             {% endif %}
             
             {% if voorraamgroot == 100 %}
              {% set voorraam_grootStatus = 'OPEN' %}
             {% elif voorraamgroot == 0 %}
              {% set voorraam_grootStatus = 'GESLOTEN' %}
             {% elif voorraamgroot == voorraam_groot_ventilatie %}
              {% set voorraam_grootStatus = 'VENTI' %}
             {% else %}
              {% set voorraam_grootStatus = ((100 - voorraamgroot) | string) + "%" %}
             {% endif %}

             Master: **{{master_bedroomStatus}}** / Voor. kl: **{{voorraam_kleinStatus}}** / Voor. gr: **{{voorraam_grootStatus}}**
           {% endif %}








           {% set computer_kamer_ventilatie = states('input_number.computer_kamer_cover_ventilatie_positie') | int %}
           {% set hal_1e_etage_ventilatie = states('input_number.hal_1e_etage_cover_ventilatie_positie') | int %}
           {% set zijraam_ventilatie = states('input_number.zijraam_cover_ventilatie_positie') | int %}
           
           {% if computerkamer == 100 and hal1eetage == 100 and zijraam == 100 %}
             Westkant **OPEN**.
           {% elif computerkamer == 0 and hal1eetage == 0 and zijraam == 0 %}
             Westkant **GESLOTEN**.
           {% elif computerkamer == computer_kamer_ventilatie and hal1eetage == hal_1e_etage_ventilatie and zijraam == zijraam_ventilatie %}
             Westkant **VENTILATIE**.
           {% else %}
             {% set computerkamerStatus = '' %}
             {% set halStatus = '' %}
             {% set zijraamStatus = '' %}
             
             {% if computerkamer == 100 %}
               {% set computerkamerStatus = 'OPEN' %}
             {% elif computerkamer == 0 %}
               {% set computerkamerStatus = 'GESLOTEN' %}
             {% elif computerkamer == computer_kamer_ventilatie %}
               {% set computerkamerStatus = 'VENTI' %}
             {% else %}
               {% set computerkamerStatus = ((100 - computerkamer) | string) + "%" %}
             {% endif %}
             
             {% if hal1eetage == 100 %}
               {% set halStatus = 'OPEN' %}
             {% elif hal1eetage == 0 %}
               {% set halStatus = 'GESLOTEN' %}
             {% elif hal1eetage == hal_1e_etage_ventilatie %}
               {% set halStatus = 'VENTI' %}
             {% else %}
               {% set halStatus = ((100 - hal1eetage) | string) + "%" %}
             {% endif %}
             
             {% if zijraam == 100 %}
               {% set zijraamStatus = 'OPEN' %}
             {% elif zijraam == 0 %}
               {% set zijraamStatus = 'GESLOTEN' %}
             {% elif zijraam == zijraam_ventilatie %}
               {% set zijraamStatus = 'VENTI' %}
             {% else %}
               {% set zijraamStatus = ((100 - zijraam) | string) +  "%" %}
             {% endif %}

             Computerkr: **{{computerkamerStatus}}** / Hal: **{{halStatus}}** / Zijraam: **{{zijraamStatus}}**
           {% endif %}







           {% if logeerkamer == 100 and badkamer == 100 and achterdeur == 100 and achterraam == 100 %}
             Achterkant **OPEN**.
           {% elif logeerkamer == 0 and badkamer == 0 and achterdeur == 0 and achterraam == 0 %}
             Achterkant **GESLOTEN**.
           {% elif logeerkamer == 0 and badkamer == 0 %}
             Dakkapel **GESLOTEN**.
           {% else %}
             TODO: specify....
           {% endif %}

          {% endif %}



I’m unaware of any size limitations in HA, but there is almost always a better way to do something like this than a bunch of if statements, usually using lists and loops. This would cut down on the amount of repeated code and make it easier to maintain and debug. Hiding it if you want to ignore my advice, but you could start with something like the below snippet to pull all the current cover positions into a list.

Code Snippet and Explanation
{% set covers = states.cover %}
{% set positions = covers | map(attribute = 'attributes.current_position') | list %}
{% set names = cover | map(attribute='attributes.friendly_name') | list %}
{{ names }}
{{ positions }}

If you put the above in the template editor, you’ll see that you now have two lists, mapped by their indexes, with the name and position of each cover. There are also ways to filter those lists down, using selectattr(), if you don’t want every cover or something.

Also, there’s probably a way to put these into an actual map, instead of two lists, I just don’t know it off the top of my head and didn’t feel like searching :sweat_smile:


Anyway, on to your actual question:

As far as why you are seeing “unavailable”, sensors use a concept of availability. In fact, when making a custom sensor, you can define a template to determine the availability of the sensor.

My guess is that the sensor you are defining, Rolluiken_status, is at some point trying to use a different sensor that is currently unavailable, causing an error and making Rolluiken_status unavailable. This is just a guess though, I’m not the most familiar with this specific use of sensors. It should be pretty easily verifiable on your end though, just copy your block of sets over to the template editor in developer tools and then print all the values, along with the value of Rolluiken_status. This should let you see if anything funky is going on.

Also, often, when people use sensors in templates like this, they will first check that the sensor is available and define someway to handle it if it is not.

I get the text in my front end: “unknown” or “unavailable”.

The strange thing is that it works perfectly in the developer tools.

Could you try setting the availability template for your sensor to the following:

{{ not states.cover | selectattr('state', 'in', ['unavailable', 'unknown', 'none']) | list | length }}

You can also put that in the template editor to check for yourself if any of your covers are unavailable. The below snippet will list the unavailable ones out for you, if any exist:

{{ states.cover | selectattr('state', 'in', ['unavailable', 'unknown', 'none']) | map(attribute="attributes.entity_id") | join(", ") }}

The first one results true in the developer tools.

The second one shows nothing (so is good)

Hm, well, without thoroughly reading and/or testing your code, I don’t think I can be of much more help. Someone more knowledgeable than me may come along though.

If I were you, I’d start by minimizing the size of that sensor. Instead of having one sensor that contains all of your values, you could break it up into multiple entities, like one for each room. This would allow most of them to be available even if one of them has a problem, and would help pinpoint the problem when one occurs.

Okay thanks for your help.

1 Like

It works now perfectly. The solution was indeed to break one sensor to multiple sensors.

It seems to be that my full sensor was to complex for HA.

Thanks.

1 Like

I’ve created some complex sensor templates over the past several years and I don’t think your template is too complex for Home Assistant but it is needlessly over-complicated. There’s an important distinction between the two.

For example, all of this:

{% if voorraamklein == 100 %}
{% set voorraam_kleinStatus = 'OPEN' %}
{% elif voorraamklein == 0 %}
{% set voorraam_kleinStatus = 'GESLOTEN' %}
{% elif voorraamklein == voorraam_klein_ventilatie %}
{% set voorraam_kleinStatus = 'VENTI' %}
{% else %}
{% set voorraam_kleinStatus = ((100 - voorraamklein) | string) + "%" %}
{% endif %}

can be reduced to this one line:

{% set voorraam_kleinStatus =  {100:'OPEN', 0:'GESLOTEN', voorraam_klein_ventilatie:'VENTI'}.get(voorraamklein, (100 - voorraamklein) ~ '%') %}
1 Like

Thanks Taras…that kind of syntax looks much much much cleaner to read!

I have updated my sensor template with this kind of syntax.

For now in testing mode:

  1. I have 1 template sensor with all the states of my 10 covers.
  2. I have created also 3 extra template sensors with all the script of option 1 (it is exactly the same code) but splitted in 3 separate sensor (covers front, covers west side, covers south side)

When I control some covers then there are still issues with option 1 that the system doesn’t notice that the sensor should be updated which means that my text in the markdown card is not correct.
I have also showed the 3 seperate sensors in this markdown card and they show the correct information!

So I don’t know if my script of the complete sensor is still over-complicated? Do you have more tips for making it cleaner/simpel?

This is now the complete code of the full template sensor:

  - sensor:
      - name: "Rolluiken_status"
        state: >
          {% set masterbedroom = state_attr('cover.master_bedroom', 'current_position' ) | int %}
          {% set voorraamklein = state_attr('cover.voorraam_klein', 'current_position' ) | int %}
          {% set voorraamgroot = state_attr('cover.voorraam_groot', 'current_position' ) | int %}
          {% set computerkamer = state_attr('cover.computer_kamer', 'current_position' ) | int %}
          {% set hal1eetage = state_attr('cover.hal_1e_etage', 'current_position' ) | int %}
          {% set zijraam = state_attr('cover.zijraam', 'current_position' ) | int %}
          {% set badkamer = state_attr('cover.badkamer', 'current_position' ) | int %}
          {% set logeerkamer = state_attr('cover.logeerkamer', 'current_position' ) | int %}
          {% set achterdeur = state_attr('cover.achterdeur', 'current_position' ) | int %}
          {% set achterraam = state_attr('cover.achterraam', 'current_position' ) | int %}
          
          {% if masterbedroom == 100 and voorraamklein == 100 and voorraamgroot == 100 and computerkamer == 100 and hal1eetage == 100 and
                zijraam == 100 and badkamer == 100 and logeerkamer == 100 and achterdeur == 100 and achterraam == 100 %}
            Alle rolluiken zijn **OPEN**.
          {% elif masterbedroom == 0 and voorraamklein == 0 and voorraamgroot == 0 and computerkamer == 0 and hal1eetage == 0 and
                zijraam == 0 and badkamer == 0 and logeerkamer == 0 and achterdeur == 0 and achterraam == 0 %}
            Alle rolluiken zijn **GESLOTEN**.
          {% else %}

           {% set master_bedroom_ventilatie = states('input_number.master_bedroom_cover_ventilatie_positie') | int %}
           {% set voorraam_klein_ventilatie = states('input_number.voorraam_klein_cover_ventilatie_positie') | int %}
           {% set voorraam_groot_ventilatie = states('input_number.voorraam_groot_cover_ventilatie_positie') | int %}

           {% if masterbedroom == 100 and voorraamklein == 100 and voorraamgroot == 100 %}
             Voorkant **OPEN**.
           {% elif masterbedroom == 0 and voorraamklein == 0 and voorraamgroot == 0 %}
             Voorkant **GESLOTEN**.
           {% elif masterbedroom == master_bedroom_ventilatie and voorraamklein == voorraam_klein_ventilatie and voorraamgroot == voorraam_groot_ventilatie %}
             Voorkant **VENTILATIE**.
           {% else %}
             {% set master_bedroomStatus = {100:'OPEN', 0:'GESLOTEN', master_bedroom_ventilatie:'VENTI'}.get(masterbedroom, (100 - masterbedroom) ~ '%') %}             
             {% set voorraam_kleinStatus = {100:'OPEN', 0:'GESLOTEN', voorraam_klein_ventilatie:'VENTI'}.get(voorraamklein, (100 - voorraamklein) ~ '%') %}             
             {% set voorraam_grootStatus = {100:'OPEN', 0:'GESLOTEN', voorraam_groot_ventilatie:'VENTI'}.get(voorraamgroot, (100 - voorraamgroot) ~ '%') %}             

             Master: **{{master_bedroomStatus}}** / Klein: **{{voorraam_kleinStatus}}** / Groot: **{{voorraam_grootStatus}}**
           {% endif %}


           {% set computer_kamer_ventilatie = states('input_number.computer_kamer_cover_ventilatie_positie') | int %}
           {% set hal_1e_etage_ventilatie = states('input_number.hal_1e_etage_cover_ventilatie_positie') | int %}
           {% set zijraam_ventilatie = states('input_number.zijraam_cover_ventilatie_positie') | int %}
           
           {% if computerkamer == 100 and hal1eetage == 100 and zijraam == 100 %}
             Westkant **OPEN**.
           {% elif computerkamer == 0 and hal1eetage == 0 and zijraam == 0 %}
             Westkant **GESLOTEN**.
           {% elif computerkamer == computer_kamer_ventilatie and hal1eetage == hal_1e_etage_ventilatie and zijraam == zijraam_ventilatie %}
             Westkant **VENTILATIE**.
           {% else %}
             {% set computerkamerStatus = {100:'OPEN', 0:'GESLOTEN', computer_kamer_ventilatie:'VENTI'}.get(computerkamer, (100 - computerkamer) ~ '%') %}             
             {% set halStatus = {100:'OPEN', 0:'GESLOTEN', hal_1e_etage_ventilatie:'VENTI'}.get(hal1eetage, (100 - hal1eetage) ~ '%') %}             
             {% set zijraamStatus = {100:'OPEN', 0:'GESLOTEN', zijraam_ventilatie:'VENTI'}.get(zijraam, (100 - zijraam) ~ '%') %}             

             Computerkr: **{{computerkamerStatus}}** / Hal: **{{halStatus}}** / Zijraam: **{{zijraamStatus}}**
           {% endif %}


           {% set badkamer_ventilatie = states('input_number.badkamer_cover_ventilatie_positie') | int %}
           {% set logeerkamer_ventilatie = states('input_number.logeerkamer_cover_ventilatie_positie') | int %}
           {% set achterdeur_ventilatie = states('input_number.achterdeur_cover_ventilatie_positie') | int %}
           {% set achterraam_ventilatie = states('input_number.achterraam_ventilatie_positie') | int %}

           {% if badkamer == 100 and logeerkamer == 100 and achterdeur == 100 and achterraam == 100 %}
             Achterkant **OPEN**.
           {% elif badkamer == 0 and logeerkamer == 0 and achterdeur == 0 and achterraam == 0 %}
             Achterkant **GESLOTEN**.
           {% elif badkamer == badkamer_ventilatie and logeerkamer == logeerkamer_ventilatie and achterdeur == achterdeur_ventilatie and achterraam == achterraam_ventilatie %}
             Achterkant **VENTILATIE**.
           {% else %}
           
             {% set badkamerStatus = {100:'OPEN', 0:'GESLOTEN', badkamer_ventilatie:'VENTI'}.get(badkamer, (100 - badkamer) ~ '%') %}             
             {% set logeerkamerStatus = {100:'OPEN', 0:'GESLOTEN', logeerkamer_ventilatie:'VENTI'}.get(logeerkamer, (100 - logeerkamer) ~ '%') %}             
             {% set achterdeurStatus = {100:'OPEN', 0:'GESLOTEN', achterdeur_ventilatie:'VENTI'}.get(achterdeur, (100 - achterdeur) ~ '%') %}             
             {% set achterraamStatus = {100:'OPEN', 0:'GESLOTEN', achterraam_ventilatie:'VENTI'}.get(achterraam, (100 - achterraam) ~ '%') %}             

             Badkamer: **{{badkamerStatus}}** / Logeerkamer: **{{logeerkamerStatus}}**
             Achterdeur: **{{achterdeurStatus}}** / Achterraam: **{{achterraamStatus}}**
             
           {% endif %}
          {% endif %}

If you have some time, I would appreciate it if you could try this version. I don’t have ten cover entities to test it but I used another method and it seems to produce correct results. However, I would like to know if it actually works in your environment. You’ll notice it’s quite short but that won’t matter much if it fails to work properly. :slightly_smiling_face:

  - sensor:
      - name: "Rolluiken_status"
        state: >
          {%- macro staat(a, av, plaats, naam) -%}
          {%- set x = a | average -%}
          {%- if x in [0,100] -%}
          {{ plaats }} **{{'OPEN' if x == 100 else 'GESLOTEN'}}**.
          {%- elif a == av -%}
          {{ plaats }} **VENTILATIE**.
          {%- else -%}
          {%- set ns = namespace(s=[]) -%}
          {%- for i in range(0, a | length) -%}
          {%- set ns.s = ns.s + ['{}: **{}**'.format(naam[i], {100:'OPEN', 0:'GESLOTEN', av[i]:'VENTI'}.get(a[i], (100 - a[i]) ~ '%'))] -%}
          {%- endfor -%}
          {{ ns.s | join(' / ') }}
          {%- endif -%}
          {%- endmacro -%}

          {% set alle = expand(
              'cover.master_bedroom', 'cover.voorraam_klein', 'cover.voorraam_groot',
              'cover.computer_kamer', 'cover.hal_1e_etage', 'cover.zijraam',
              'cover.badkamer', 'cover.logeerkamer', 'cover.achterdeur', 'cover.achterraam')
              | map(attribute='current_position') | map('int', 0) | list %}

          {% set alle_ventilatie = expand(
              'input_number.master_bedroom_cover_ventilatie_positie', 'input_number.voorraam_klein_cover_ventilatie_positie', 'input_number.voorraam_groot_cover_ventilatie_positie',
              'input_number.computer_kamer_cover_ventilatie_positie', 'input_number.hal_1e_etage_cover_ventilatie_positie', 'input_number.zijraam_cover_ventilatie_positie',
              'input_number.badkamer_cover_ventilatie_positie', 'input_number.logeerkamer_cover_ventilatie_positie',
              'input_number.achterdeur_cover_ventilatie_positie', 'input_number.achterraam_ventilatie_positie')
              | map('int', 0) | list %}

          {%- set x = alle | average -%}
          {%- if x in [0,100] -%}
          Alle rolluiken zijn **{{'OPEN' if x == 100 else 'GESLOTEN'}}**.
          {%- else -%}
          {{ staat(alle[0:3], alle_ventilatie[0:3], 'Voorkant', ['Master', 'Klein', 'Groot']) }}
          {{ staat(alle[3:6], alle_ventilatie[3:6], 'Westkant', ['Computerkr', 'Hal', 'Zijraam']) }}
          {{ staat(alle[6:], alle_ventilatie[6:], 'Acterkant', ['Badkamer', 'Logeerkamer', 'Achterdeur', 'Achterraam']) }}
          {%- endif -%}

It contains a macro, named staat, which does most of the work. It uses a list to store all the covers and another list to store all the input_numbers.

The one significant difference from your version is that for “Achterkant” the status of all four rooms is shown on one line (as opposed to two lines). This was necessary to allow the macro to be consistent with how the status of “Voorkant” and “Westkant” are displayed (on one line).

Wow…that is impressive script :slight_smile:

But i tried it and it reports directly “unavailable”.

In the develepor tools I get this message:

UndefinedError: ‘homeassistant.helpers.template.TemplateState object’ has no attribute ‘current_position’