Templating changes in 2021.10.0

.19…20…

do we already have consensus on that that would be ‘correcty’ ?

I mean we can set |float(0) but that would only mean the template always succeeds, not perse the value is useful or even correct . If the value of an mqtt sensor would be unavailable and we float it to default, it still is evaluated as 0, with rather undesired consequences…

need to default to float(none) after all then?

even worse: ive got a group with power sensors, some of which are turned off , as in dont have a power reading at all, being unavailable. the template sensor returns

Template warning: 'float' got invalid input 'unavailable' when rendering template '{{(expand('group.lights_inside_total_device_power')

on those:

          {{states('sensor.lights_inside_total_device_power')|float +
            states('sensor.lights_outside_total_device_power')|float}}

based on

          {{(expand('group.lights_inside_total_device_power')
             |map(attribute='state')|map('float')|sum)|round(2)}}

where to set a (which) default…?
testing this for a reload

|map('float',0)

which should be fine for the individual power sensors, but not for the energy sensors (they are total_increasing…)

also, the all lights power sensor (derived from the expand group template) shouldn’t default to 0 either, because it never can/will/should be 0…

I would hope we do. Like any computer language there are rules, definitions, etc. The problem with most of us (myself included) I really did not understand what the code was doing when I copied different examples and modified them to my system. I would think if you follow the rules and you understand what each statement is doing it “should” work. If it doesn’t I believe with the experts here someone will be able to explain why.
I am still trying to understand what each line in my “copied code” does. Most of my errors have to do with command line sensors used to show updates on core, system, hacs, etc. Other errors have to do with markdown cards that are using templates. Again, I justed edited them and changed the sensors to my sensors. This worked well for me until this release.

So this template…

{{ max|round(0,default='none')}}°/{{ min|round(0,default='none')}}°/{{states('sensor.kariong_rain_chance_0')|round(0,default='none')}}%

I previously used round(0) to round to 0 decimal places (I thought) Now I added the default=‘none’ as I don’t want it using 0 as the default. It also wouldn’t work without the default= part.
In the docs for round it seems that round(x,y,z) is the syntax? Where x is the rounding, y could be floor or ceiling and z is the default but I am only seeing the default in the above examples. Why do I have to use default=?

If you don’t provide the second argument, you need to provide the word default so that the code knows it’s the value for default.

2 Likes

thanks that simplifies it quite a bit.

btw, no rest allowed: https://github.com/home-assistant/core/pull/57470

only a few left, this being a prominent one in the log:

          {%- set tracker_timestamp = as_timestamp(strptime(states('sensor.afvalwijzer_next_date'),'%d-%m-%Y')) %}
          {%  set months = ['Januari','Februari','Maart','April','Mei','Juni','Juli','Augustus','September','Oktober','November','December'] %}
          {%- set wdays = ['Zondag','Maandag','Dinsdag','Woensdag','Donderdag','Vrijdag','Zaterdag'] %}
          {%- set wday = tracker_timestamp|timestamp_custom('%w')|int %}
          {%- set month = tracker_timestamp |timestamp_custom('%m')|int %}
          {{tracker_timestamp|timestamp_custom(wdays[wday]  ~ ' ' '%-d' ' ' ~ months[month-1])}}

it sees 3 warnings:

2021-10-12 00:53:36 WARNING (MainThread) [homeassistant.helpers.template] Template warning: 'strptime' got invalid input 'Geen' when rendering template '{%- set tracker_timestamp = as_timestamp(strptime(states('sensor.afvalwijzer_next_date'),'%d-%m-%Y')) %} {%  set months = ['Januari','Februari','Maart','April','Mei','Juni','Juli','Augustus','September','Oktober','November','December'] %} {%- set wdays = ['Zondag','Maandag','Dinsdag','Woensdag','Donderdag','Vrijdag','Zaterdag'] %} {%- set wday = tracker_timestamp|timestamp_custom('%w')|int %} {%- set month = tracker_timestamp |timestamp_custom('%m')|int %} {{tracker_timestamp|timestamp_custom(wdays[wday]  ~ ' ' '%-d' ' ' ~ months[month-1])}}' but no default was specified. Currently 'strptime' will return 'Geen', however this template will fail to render in Home Assistant core 2021.12
2021-10-12 00:53:36 WARNING (MainThread) [homeassistant.helpers.template] Template warning: 'as_timestamp' got invalid input 'Geen' when rendering template '{%- set tracker_timestamp = as_timestamp(strptime(states('sensor.afvalwijzer_next_date'),'%d-%m-%Y')) %} {%  set months = ['Januari','Februari','Maart','April','Mei','Juni','Juli','Augustus','September','Oktober','November','December'] %} {%- set wdays = ['Zondag','Maandag','Dinsdag','Woensdag','Donderdag','Vrijdag','Zaterdag'] %} {%- set wday = tracker_timestamp|timestamp_custom('%w')|int %} {%- set month = tracker_timestamp |timestamp_custom('%m')|int %} {{tracker_timestamp|timestamp_custom(wdays[wday]  ~ ' ' '%-d' ' ' ~ months[month-1])}}' but no default was specified. Currently 'as_timestamp' will return 'None', however this template will fail to render in Home Assistant core 2021.12
2021-10-12 00:53:36 WARNING (MainThread) [homeassistant.helpers.template] Template warning: 'timestamp_custom' got invalid input 'None' when rendering template '{%- set tracker_timestamp = as_timestamp(strptime(states('sensor.afvalwijzer_next_date'),'%d-%m-%Y')) %} {%  set months = ['Januari','Februari','Maart','April','Mei','Juni','Juli','Augustus','September','Oktober','November','December'] %} {%- set wdays = ['Zondag','Maandag','Dinsdag','Woensdag','Donderdag','Vrijdag','Zaterdag'] %} {%- set wday = tracker_timestamp|timestamp_custom('%w')|int %} {%- set month = tracker_timestamp |timestamp_custom('%m')|int %} {{tracker_timestamp|timestamp_custom(wdays[wday]  ~ ' ' '%-d' ' ' ~ months[month-1])}}' but no default was specified. Currently 'timestamp_custom' will return 'None', however this template will fail to render in Home Assistant core 2021.12

please help me out where to ad some defaults? Though this mentions the input being invalid, and I am not sure how to handle that. The input is ok however, and currently as intended…

the only other warningI get is on the DST sensor:

2021-10-12 00:53:37 WARNING (MainThread) [homeassistant.helpers.template] Template warning: 'timestamp_local' got invalid input '167 days, 0:00:00' when rendering template '{%- set ns = namespace(previous=2,spring=none,fall=none) %} {%- set today = strptime(states('sensor.date'),'%Y-%m-%d').astimezone().replace(hour=ns.previous) %} {%- for i in range(365) %} {%- set day = (today + timedelta(days=i)).astimezone() %} {%- if ns.previous - day.hour == -1 %} {%- set ns.spring = today + timedelta(days=i)|timestamp_local %} {%- elif ns.previous - day.hour == 1 %} {%- set ns.fall = today + timedelta(days=i)|timestamp_local %} {%- endif %} {%- set ns.previous = day.hour %} {%- endfor %} {{([ns.spring,ns.fall]|min).isoformat()}}' but no default was specified. Currently 'timestamp_local' will return '167 days, 0:00:00', however this template will fail to render in Home Assistant core 2021.12

but that was before I deleted |timestamp_local. Must re-read this thread again to understand why I can now take that out, or why that caused the error…

I though I understood what to do but I have a simple sensor that is giving a warning.

platform: template
sensors:

  total_distance_mtr_miles:
    friendly_name: "miles_walked"
    unit_of_measurement: 'miles'
#added round(2,default=0) 10/8/2021
    value_template: "{{ states('sensor.total_distance_mtr') | multiply (1/1609.3444) | float(2) | round(2,default=0)}}"
  • Template warning: ‘multiply’ got invalid input ‘unavailable’ when rendering template ‘{{ states(‘sensor.total_distance_mtr’) | multiply (1/1609.3444) | float(2) | round(2,default=0)}}’ but no default was specified. Currently ‘multiply’ will return ‘unavailable’, however this template will fail to render in Home Assistant core 2021.12
    Tried float (defaultt=0) and it didn’t help.

It’s saying that the value multiply received was unavailable. That means the result of states('sensor.total_distance_mtr') was unavailable.

Even if it wasn’t unavailable, the sensor’s state value is a string and you can’t do arithmetic with strings (you have to first convert them to numbers using float or int).

I thought I did with the float? It has worked for several years as is. Is the order wrong in the statement? I tried float | multiply (changed order) and no difference. It is just converting the garmin meters to miles. Why would the Meters be a string?

The float is applied to what comes before it. That’s how filters work.

what_filter_is_apply_to | filter

You’re applying the filter to

multiply (1/1609.3444) | float(2)

it should be

states('sensor.total_distance_mtr') | float(2) | multiply (1/1609.3444) | round(2,default=0)

also, I think multiply needs a default too.

Also multiply converts strings to floats for you.

so…

states('sensor.total_distance_mtr') | multiply (1/1609.3444, 0) | round(2,default=0)

On multiple you don’t need , default=0?

No, multiply only takes 2 arguments. So you don’t need to call out the names because you aren’t omitting an argument.

See:

the only reason you need to use the word default is when the argument you are trying to set is not the next argument that’s required.

I.e. my_method(arg1, arg2=True, arg3=47) requires 3 arguments named arg1, arg2, and arg3. arg1 is required and arg2 and arg3 are optional, because they have a default value for them. When you omit arg2 and arg3, they auto populate my_method with True and 47. Meaning if you call my_method with my_method(7), arg1 will have 7, arg2 will have True, and arg3 will have 47. Well, what happens when you want to supply my_method with arg3 as 50 instead of 47? Well you have 2 options. Populate all 3 arguments; my_method(7, True, 50) or supply the single argument you want to populate my_method(7, arg3=50).

This is why you see default used and not used all over the place. FYI you can also supply all 3 and it still works; my_method(7, arg2=True, arg3=50).

1 Like

Thank you @petro and @123 you both have been very helpful in getting me through this learning curve. I am finally starting to understand what each line means in the template (still making mistakes) but getting there. This site has help me

https://jinja.palletsprojects.com/en/2.10.x/templates/#forceescape

I still don’t understand some of the arguments. Is HA using a combination of Python / Jinja for what is allowed? For example I had used the word multiply in my template ( must have copied it from someones code) and I can’t understand why instead of just using " * ". Where can I get more information on “allowed” operations?

multiply is just a filter that was added to home assistant. I’m sure someone had a reason. You’re welcome to just use *.

Where do I find the filters that were added to HA?

I would think now that they are making sure the code has the correct defaults, maybe there should be some documentation if HA is allowing differences than what is in the Jinja docs.

When you do markdown cards do they follow the jinja docs, CSS or a combination?

For those curious, the multiply filter seems to make its first appearance in a PR from 2015:

It’s not clear from the PR what problem it was intended to solve. Perhaps the only notable thing is that it automatically converts strings to float before performing the multiplication. I don’t see any reference to it in the documentation.

1 Like

Hello guys!
I have same problem as many here, and i can’t find a solution for my case anywhere. I have date and time “assembled” together and currently it works fine, but of course it will need change in December. But, all options i tried - none of them work. My code, which now results in warning:

  sensors:
    danes:
      friendly_name: "Ime dneva"
      value_template: >-
        {% set danes = ["Ponedeljek", "Torek", "Sreda", "Četrtek", "Petek", "Sobota", "Nedelja"] %}
        {{danes[now().weekday()]}}

    mesec_number:
      friendly_name: "mesec kot številka"
      value_template: >-
        {% set mesec = ["Jan", "Feb", "Mar", "Apr", "Maj", "Jun", "Jul", "Avg", "Sep", "Okt", "Nov", "Dec"] %}
        {{mesec[now().month-1]}}


value_template: "{{float (states('sensor.danes'), default='0') + ', '
        }}{{ now().day }}.{{float (states('sensor.mesec_number'), default='Januar')
        }} - {{ now().hour }}:{{as_timestamp(states('sensor.date_time_iso')) | timestamp_custom('%M')}}"

If i try "float(‘Pon’) is an error. If i insert "default = “Pon” at the end i always get “Pon”, no matter what day it is (Pon meand Mon in my language).

Some help would be very appreciated…

Why is that value_template trying to do? Give an example of the output you want it to produce.

I think it’s a phonetic date

Exactly. Above “composition” gives me today’s date and current time:

Sre, 13. Okt - 20:53

Which would be (in english) : Wed, 13th. Oct - 20:53
If there’s any easier way i’m very open to suggestions. I’m not skilled programmer, i manage to “assemble” thing like this with internet searh&help (from you, guys!) and that’s pretty much it…