How to shorten/join this template?

HI trying to shorten this, but I can’t get the extension to concatenate after the number… what am i missing?

12
@petro could you please help me, in creating a mapper here? it’s somewhat different from the mappers with a fixed state, maybe not possible at all? If not, there must be a more intelligent way of doing this…:wink:

{% set degrees = states('sensor.br_wind_direction_azimuth')|float %}
          {% set path = '/local/weather/wind_compass/' %}
          {% set ext = '.png' %}
{{path-}}      
          {% if degrees <= 5.62 %}0
          {% elif degrees <= 16.87 %}11
          {% elif degrees <= 28.12 %}22
          {% elif degrees <= 39.37 %}33
          {% elif degrees <= 50.62 %}45
          {% elif degrees <= 61.87 %}56
          {% elif degrees <= 73.12 %}67
          {% elif degrees <= 84.37 %}78
          {% elif degrees <= 95.62 %}90
          {% elif degrees <= 106.87 %}101
          {% elif degrees <= 118.12 %}112
          {% elif degrees <= 129.37 %}123
          {% elif degrees <= 140.62 %}135
          {% elif degrees <= 151.87 %}146
          {% elif degrees <= 163.12 %}157
          {% elif degrees <= 174.37 %}168
          {% elif degrees <= 185.62 %}180
          {% elif degrees <= 196.87 %}191
          {% elif degrees <= 208.12 %}202
          {% elif degrees <= 219.37 %}213
          {% elif degrees <= 230.62 %}225
          {% elif degrees <= 241.87 %}236
          {% elif degrees <= 253.12 %}247
          {% elif degrees <= 264.37 %}258
          {% elif degrees <= 275.62 %}270
          {% elif degrees <= 286.87 %}281
          {% elif degrees <= 298.12 %}292
          {% elif degrees <= 309.37 %}303
          {% elif degrees <= 320.62 %}315
          {% elif degrees <= 331.87 %}326
          {% elif degrees <= 343.12 -%}337
          {% elif degrees <= 354.37 %}348
          {%- endif -%}
{{-ext-}}

this is what i do in other situations, both techniques work:

      {% set state = states('sensor.rsd_current') %}
      {% set weather = mapper[state] if state in mapper else 'weather' %}
      {% set path = '/local/weather/animated/' %}
      {% set ext = '.svg'%}
        {{[path,weather,ext]|join('')|lower}}

{% set state = states('sensor.rsd_current') %}
{% if state in mapper %}
{{ '/local/weather/animated/{}.svg'.format(mapper[state]) }}
{%else%} '/local/weather/animated/weather.svg'
{%endif%}

this might do it:

    entity_picture_template: >
      {% set degrees = states('sensor.br_wind_direction_azimuth')|float %}
      {% set path = '/local/weather/wind_compass/' %}
      {% set ext = '.png' %}
      {{path-}}
      {%- if degrees <= 5.62 -%} 0
      {%- elif degrees <= 16.87 -%} 11
      {%- elif degrees <= 28.12 -%} 22
      {%- elif degrees <= 39.37 -%} 33
      {%- elif degrees <= 50.62 -%} 45
      {%- elif degrees <= 61.87 -%} 56
      {%- elif degrees <= 73.12 -%} 67
      {%- elif degrees <= 84.37 -%} 78
      {%- elif degrees <= 95.62 -%} 90
      {%- elif degrees <= 106.87 -%} 101
      {%- elif degrees <= 118.12 -%} 112
      {%- elif degrees <= 129.37 -%} 123
      {%- elif degrees <= 140.62 -%} 135 
      {%- elif degrees <= 151.87 -%} 146
      {%- elif degrees <= 163.12 -%} 157
      {%- elif degrees <= 174.37 -%} 168
      {%- elif degrees <= 185.62 -%} 180
      {%- elif degrees <= 196.87 -%} 191
      {%- elif degrees <= 208.12 -%} 202
      {%- elif degrees <= 219.37 -%} 213
      {%- elif degrees <= 230.62 -%} 225
      {%- elif degrees <= 241.87 -%} 236
      {%- elif degrees <= 253.12 -%} 247
      {%- elif degrees <= 264.37 -%} 258
      {%- elif degrees <= 275.62 -%} 270
      {%- elif degrees <= 286.87 -%} 281
      {%- elif degrees <= 298.12 -%} 292
      {%- elif degrees <= 309.37 -%} 303
      {%- elif degrees <= 320.62 -%} 315
      {%- elif degrees <= 331.87 -%} 326
      {%- elif degrees <= 343.12 -%} 337
      {%- elif degrees <= 354.37 -%} 348
      {%- endif -%}
      {{-ext-}}

but it is still a bit heavy on the elif’s…

I assume you are trying to convert the degrees into equally spaced indicators on a compass rose?

How about this:

{{path-}}
{{  ( ((degrees/11.25)|round )*11.25 )| round  }}
{{-ext}}

returns:

/local/weather/wind_compass/68.png

there might be a sleeker mathematical expression, but it is close.
it does not match your numbers exactly, but I think you can make it work, maybe rename a few of your pictures. (and deal with 360)
These are the results I get:
0,11,23,34,45,56,68,79,90,101,113,124,135,146,158,169,180,191,203,214,225,236,248,259,270,281,293,304,315,326,338,349,360

a yes! that’s cool. If Id rename all image files 1-32, I guess I could even use:

{{ (degrees/11.25)|round }} ?

about 360: originally this was the first if: {% if 354.38 <= degrees <= 5.62 %} so maybe I should add that as the original if, and follow it with an else, with your template:

    entity_picture_template: >
      {% set degrees = states('sensor.br_wind_direction_azimuth')|float %}
      {% set path = '/local/weather/wind_compass/' %}
      {% set ext = '.png' %}
      {{path-}}
      {%- if 354.38 <= degrees <= 5.62 -%} 1
      {%- else -%}
      {{- (degrees/11.25)|round }}   # or {{ ( ((degrees/11.25)|round )*11.25 )| round }} for degrees in name
      {%- endif -%}
      {{-ext-}}

has one too many outcomes though and indeed doesn’t work for the 354,39 - 0 position…

this fixes that:

{% set degrees = states('sensor.br_wind_direction_azimuth')|float %}
{% set path = '/local/weather/wind_compass/' %}
{% set ext = '.png' %}
  {{path-}}
{%- if 354.38 <= degrees or degrees <= 5.62 -%} 0
{%- else -%}
  {{ degrees|int//11.25 | round}}
{%- endif -%}
  {{-ext-}}

see: Template Designer Documentation — Jinja Documentation (2.10.x) divide two integers and return the truncated integer result.
thanks a bunch!

guess we’re only left looking for a better way to write this:

{{ ( ((degrees/11.25)|round )*11.25 )| round}}

maybe @pnbruckner or @petro would know?

Or you just copy the 0 image and make it a 360 image. Same image, 2 names…

sure, done. makes the template even simpler. creative concept indeed. :+1:

      {% set degrees = states('sensor.br_wind_direction_azimuth')|float %}
      {% set path = '/local/weather/wind_compass/' %}
      {% set ext = '.png' %}
      {{path-}}
      {{ ( ((degrees/11.25)|round )*11.25 )| round}}
      {{-ext}}

Sorry about the late delay, but this is what I would have done. If you want to get exactly what your if statements have with just math:

    entity_picture_template: >
      {%- set degrees = states('sensor.br_wind_direction_azimuth')|float %}
      {%- set path = '/local/weather/wind_compass/' %}
      {%- set ext = '.png' %}
      {%- set num = '%f'%(((degrees - 5.62) / 11.25) | round(0) * 11.25) %}
      {%- set num = n[:n.index('.')] %}
      {%- set kwargs = { 'path':path,'ext':ext, 'num',num } %}
      {{ "{path}{num}{ext}".format(**kwargs) }}

That should be identical to your if statements, numerically.

hmmm, nt really it complains about n not being defined… (btw took out the small typo after ‘num’ and changed the , for :

entity_picture_template: >
  {%- set degrees = states('sensor.br_wind_direction_azimuth')|float %}
  {%- set path = '/local/weather/wind_compass/' %}
  {%- set ext = '.png' %}
  {%- set num = '%f'%(((degrees - 5.62) / 11.25) | round(0) * 11.25) %}
  {%- set num = n[:n.index('.')] %}
  {%- set kwargs = { 'path':path,'ext':ext, 'num':num } %}
  {{ "{path}{num}{ext}".format(**kwargs) }}

typo

    entity_picture_template: >
      {%- set degrees = states('sensor.br_wind_direction_azimuth')|float %}
      {%- set path = '/local/weather/wind_compass/' %}
      {%- set ext = '.png' %}
      {%- set num = '%f'%(((degrees - 5.62) / 11.25) | round(0) * 11.25) %}
      {%- set num = num[:num.index('.')] %}
      {%- set kwargs = { 'path':path,'ext':ext, 'num',num } %}
      {{ "{path}{num}{ext}".format(**kwargs) }}

cool, (yet the same : type taken out), now working.

  {%- set degrees = states('sensor.br_wind_direction_azimuth')|float %}
  {%- set path = '/local/weather/wind_compass/' %}
  {%- set ext = '.png' %}
  {%- set num = '%f'%(((degrees - 5.62) / 11.25) | round(0) * 11.25) %}
  {%- set num = num[:num.index('.')] %}
  {%- set kwargs = { 'path':path,'ext':ext, 'num':num } %}
  {{ "{path}{num}{ext}".format(**kwargs) }}

Cant help but wonder why this is your preferable way of doing it? seems much more complex? the kwargs/args is new to me in yaml templates, so have to readup on that

I mean, you don’t have to do the kwargs bs. That’s just a verbose way of writing it so you can see the path. I did it for myself when writing. This would be the ‘least amount’ of code:

    entity_picture_template: >
      {%- set degrees = states('sensor.br_wind_direction_azimuth')|float %}
      {%- set path = '/local/weather/wind_compass/' %}
      {%- set ext = '.png' %}
      {%- set num = '%f'%(((degrees - 5.62) / 11.25) | round(0) * 11.25) %}
      {%- set num = num[:num.index('.')] %}
      {{ "{}{}{}".format(path,num,ext) }}

ah ok, I see that now.

then only the math is left to wonder for me. I wrote:

 {{ ( ((degrees/11.25)|round )*11.25 )| round}}

and you write:

{%- set num = '%f'%(((degrees - 5.62) / 11.25) | round(0) * 11.25) %}
      {%- set num = n[:n.index('.')] %}

Not really sure yet what and why you are doing what you do…

btw this would be an option too?:

{{ ( ((degrees//11.25)*11.25)|round)}}

not the same I see now:

missed the -5.62… never realized that.

The number is subtracting 5.62 to make everything below 5.62 always zero, which is what your if statements do. Then I divide by 11.25 because your numbers are separated by 11.25. Then I round that to get everything to a solid integer. Then mulitply again by 11.25. Now we need to round everything to the floor instead of normal rounding, so that 11.75 would become 11 instead of 12 (this is what your orignal if statements technically do). There is no floor() method in jinja, so we have to fake it by truncating the string using [:n.index('.')].

1 Like

magic, thanks a lot (–>> cookbook)

hope you agree though that {{ ( ((degrees//11.25)*11.25)|round)}} is simpler ? this does do the same doesn’t it? Template Designer Documentation — Jinja Documentation (2.10.x)

Divide two numbers and return the truncated integer result

It does but your if statements take 5.62 to 16.87 as 11. So that’s why I’m subtracting the 5.62. Also, when you do that and use //, it will make the numbers under 5.62 negative 1 instead of zero.

Again, all that math is to match your if statements exactly. Your math does not, it’s offset by 5.62 essentially.

I suppose it could be written this way:

    entity_picture_template: >
      {%- set degrees = states('sensor.br_wind_direction_azimuth')|float %}
      {%- set path = '/local/weather/wind_compass/' %}
      {%- set ext = '.png' %}
      {%- set num = ((((degrees - 5.62) / 11.25 ) | round(0) * 11.25) // 1) | int %}
      {{ "{}{}{}".format(path,num,ext) }}

Nevermind, I had my math backwards. I was shifting to 0, 11.25.

This is the correct method:

    entity_picture_template: >
      {%- set degrees = states('sensor.br_wind_direction_azimuth')|float %}
      {%- set path = '/local/weather/wind_compass/' %}
      {%- set ext = '.png' %}
      {%- set num = ((degrees // 11.25) * 11.25 // 1) | int %}
      {{ "{}{}{}".format(path,num,ext) }}

ok, changed that, and some of the images 1 degree ;-).

only thing is now 360 = 360 and 0 = 0, which is not as it should be I guess.
this{{ ( ((degrees/11.25)|round )*11.25 )| round }}} does that nicely though?? confused now.

see this;

      {% set degrees = states('sensor.br_wind_direction_azimuth')|float %}
      {% if 354.38 <= degrees or degrees <= 5.62 %} N
      {% elif degrees <= 16.87 %} NNNO
      {% elif degrees <= 28.12 %} NNO
      {% elif degrees <= 39.37 %} ONNO
      {% elif degrees <= 50.62 %} NO
      {% elif degrees <= 61.87 %} NONO
      {% elif degrees <= 73.12 %} ONO
      {% elif degrees <= 84.37 %} OONO
      {% elif degrees <= 95.62 %} O
      {% elif degrees <= 106.87 %} OOZO
      {% elif degrees <= 118.12 %} OZO
      {% elif degrees <= 129.37 %} ZOZO
      {% elif degrees <= 140.62 %} ZO
      {% elif degrees <= 151.87 %} OZZO
      {% elif degrees <= 163.12 %} ZZO
      {% elif degrees <= 174.37 %} ZZZO
      {% elif degrees <= 185.62 %} Z
      {% elif degrees <= 196.87 %} ZZZW
      {% elif degrees <= 208.12 %} ZZW
      {% elif degrees <= 219.37 %} ZZW
      {% elif degrees <= 230.62 %} ZW
      {% elif degrees <= 241.87 %} ZWZW
      {% elif degrees <= 253.12 %} WZW
      {% elif degrees <= 264.37 %} WWZW
      {% elif degrees <= 275.62 %} W
      {% elif degrees <= 286.87 %} WWNW
      {% elif degrees <= 298.12 %} WNW
      {% elif degrees <= 309.37 %} NWNW
      {% elif degrees <= 320.62 %} NW
      {% elif degrees <= 331.87 %} WNNW
      {% elif degrees <= 343.12 %} NNW
      {% elif degrees <= 354.37 %} NNNW
      {% endif %}

Ok, Another mistake, we need to round instead of using // in 1 spot. Also, we need to convert 360 to zero or vice versa:

    entity_picture_template: >
      {%- set degrees = states('sensor.br_wind_direction_azimuth')|float %}
      {%- set path = '/local/weather/wind_compass/' %}
      {%- set ext = '.png' %}
      {%- set num = ((degrees / 11.25) | round(0) * 11.25 // 1) | int %}
      {%- set num  = 0 if num  == 360 else n %}
      {{ "{}{}{}".format(path,num,ext) }}

As for your second if statement:

{% set direction = ['N','NNNO','NNO','ONNO','NO','NONO','ONO','OONO','O','OOZO','OZO','ZOZO','ZO','OZZO','ZZO','ZZZO','Z','ZZZW','ZZW','ZZW','ZW','ZWZW','WZW','WWZW','W','WWNW','WNW','NWNW','NW','WNNW','NNW','NNNW' ] %}
{%- set degrees = states('sensor.br_wind_direction_azimuth')|float %}
{%- set i = ((degrees / 11.25) | round(0)) | int %}
{%- set i = 0 if i == 32 else i %}
{{ direction[i] }}
1 Like

this gives no result in the final template, if I take it out it shows the correct number , albeit with a decimal .0, while the template on its own shows the correctly formatted number…

—EDIT----

found it: {%- set num = 0 if num == 360 else num %}

as for the second: YES! that was exactly what I hoped for!!

have a third:-)

        {% set degrees = states('sensor.br_wind_direction_azimuth')|float %}
      {% set direction = ['Noord','Noord Ten Oosten','Noordnoordoost','Noordoost Ten Noorden','Noordoost',
                          'Noordoost Ten Oosten','Oostnoordoost','Oost Ten Noorden','Oost',
                          'Oost Ten Zuiden','Oostzuidoost','Zuidoost Ten Oosten','Zuidoost',
                          'Zuidoost Ten Zuiden','Zuidzuidoost','Zuid Ten Oosten','Zuid',
                          'Zuid Ten Westen','Zuidzuidwest','Zuidwest Ten Zuiden','Zuidwest',
                          'Zuidwest Ten Westen','Westzuidwest','West Ten Zuiden','West',
                          'West Ten Noorden','Westnoordwest','Noordwest Ten Westen','Noordwest',
                          'Noordwest Ten Noorden','Noordnoordwest','Noord Ten Westen'] %}
      {%- set i = ((degrees / 11.25) | round(0)) | int %}
      {%- set i = 0 if i == 32 else i %}
      {{ direction[i] }}
1 Like