Updating Templates with the new default values in 2021.10.x

darn… quite simply overlooked that… :blush:

thought the issue might also have been that because of this, the system looped in unavailable devices/integrations. I had not guarded the if b.state not in ['unavailable','unknown'] which I now added too.

but, wait, yes, I had changed that. What I hadn’t done yet, was refresh the frontend! I ran into this before, with the template-entity-row card. Log showing an error, of a config version not yet updated/refreshed.

Ive refreshed now, the unavailable sensor has left the markdown, and I’ll restart the HA instance once more.

thanks for your keen eye.

I would like to hear how I can improve this sensor template, specifically the strptime's default in a meaningful way:

        {% set reversed_file_list = state_attr('sensor.home_assistant', 'file_list') | sort(reverse=True) %}
        {% set files_exist = (reversed_file_list | length) > 0 %}
        {% if (files_exist) %}
          {% set last_backup_dt = strptime(reversed_file_list[0] | regex_findall_index(find='\d{8}_\d{6}'), '%Y%m%d_%H%M%S') | as_local %}
          {{ last_backup_dt.isoformat() }}
        {% else %}
          unknown
        {% endif %}

I could set the default as 0 or None, but in either case it seems like I’ll have another if statement to check for that before trying to call isoformat on it. It seems cumbersome and I’m wondering how I can do this more cleanly.

I’ve read klogg’s post that seems related, but unanswered.

What a mess

Heheee

Please post a few examples of the values in file_contents so we can understand the data’s format.

@123 here you go. I’m extracting the datetime from the filename.

path: /mnt/nas/Backups/home_assistant/
filter: hass-config_*.zip
number_of_files: 136
bytes: 1286294837
file_list:
  - /mnt/nas/Backups/home_assistant/hass-config_20210804_000500.zip
  - /mnt/nas/Backups/home_assistant/hass-config_20210620_000500.zip
  - /mnt/nas/Backups/home_assistant/hass-config_20200729_030001.zip

Copy-paste this into the Template Editor and see if it reports the desired result:

{% set f = state_attr('sensor.home_assistant', 'file_list') | sort(reverse=True) | first %}
{{ 'unknown' if f is not defined else (f[-19:-4].replace('_', ' ') | as_datetime).astimezone().isoformat() }}
2 Likes

Yeah, that works perfectly. Thank you. Avoiding the strptime completely – I didn’t think of that.

Hi, i have a warning error with this sensor template:

- platform: template
  sensors:  
    apc2_time_remaining:
      friendly_name: 'APC Scrivania Remaining'
      value_template: >-
        {% set time = (states.sensor.apc2_battery_runtime.state | int) | int %}
        {% set minutes = ((time % 3600) / 60) | int %}
        {% set hours = ((time % 86400) / 3600) | int %}
        {% set days = (time / 86400) | int %}
        {%- if time < 60 -%}
          meno di un minuto
          {%- else -%}
          {%- if days > 0 -%}
            {{ days }} d
          {%- endif -%}
          {%- if hours > 0 -%}
            {%- if days > 0 -%}
              {{ ' ' }}
            {%- endif -%}
            {{ hours }} h
          {%- endif -%}
          {%- if minutes > 0 -%}
            {%- if days > 0 or hours > 0 -%}
              {{ ' ' }}
            {%- endif -%}
            {{ minutes }} m
          {%- endif -%}
        {%- endif -%}

In log have this warning:
Logger: homeassistant.helpers.template
Source: helpers/template.py:1291
First occurred: 17 dicembre 2021, 19:44:10 (1 occurrences)
Last logged: 17 dicembre 2021, 19:44:10

Template warning: ‘int’ got invalid input ‘unavailable’ when rendering template ‘{% set time = (states.sensor.apc2_battery_runtime.state | int) | int %} {% set minutes = ((time % 3600) / 60) | int %} {% set hours = ((time % 86400) / 3600) | int %} {% set days = (time / 86400) | int %} {%- if time < 60 -%} meno di un minuto {%- else -%} {%- if days > 0 -%} {{ days }} d {%- endif -%} {%- if hours > 0 -%} {%- if days > 0 -%} {{ ’ ’ }} {%- endif -%} {{ hours }} h {%- endif -%} {%- if minutes > 0 -%} {%- if days > 0 or hours > 0 -%} {{ ’ ’ }} {%- endif -%} {{ minutes }} m {%- endif -%} {%- endif -%}’ but no default was specified. Currently ‘int’ will return ‘0’, however this template will fail to render in Home Assistant core 2022.1

how can i fix the template to make the error disappear?
Thanks

Did you read the post or are you expecting us to fix it for you? This post is meant as a guide to show you how to update your template.

I have read the guide, but honestly, already having problems with the English language, I am Italian, and not having much familiarity with programming, I did not understand how to set the default value. If someone could kindly solve the problem for me I would be very happy.

I’ll save petro the understandable angst (it’ll be karma for all the angst I’ve caused him over the years).

It looks like your sensor isn’t returning something that can be interpreted as an integer (and you don’t need the second | int on the first line)

You need to check if the sensor is a number and/or provide a default:

{% if is_number(states.sensor.apc2_battery_runtime.state) %}
... do something
{% else %}
... do something else
{% endif%}

or

        {% set time = (states.sensor.apc2_battery_runtime.state) | int(0) %}
        {% set minutes = ((time % 3600) / 60) %}
        {% set hours = ((time % 86400) / 3600) %}
        {% set days = (time / 86400) %}

time defaults here to zero, you can change that to any number. And once it is an integer you don’t need to keep converting it.

1 Like

Also, heeding this warning may help:

https://www.home-assistant.io/docs/configuration/templating/#states

2 Likes

Hi, i chnge te template sensor with:

  {% set time = (states.sensor.apc2_battery_runtime.state) | int(0) %}
  {% set minutes = ((time % 3600) / 60) %}
  {% set hours = ((time % 86400) / 3600) %}
  {% set days = (time / 86400) %}

But now, instead of having as a result: 4h 20m
have: 0.18055555555555555 d 4.333333333333333 h 20.0 m
Where is the problem?

sensor.apc2_battery_runtime have 15.600 s value.

Would the division not keep creating a float, which Marco is now seeing?

I believe that, for integer division, one must use two slashes instead of the one, like ((time % 3600) // 60). Or just go back to converting it after :slight_smile:.

1 Like

Is states.sensor.apc2_battery_runtime.state in seconds??

if it is I did the following in developer tools → templates

{% set mynow = as_timestamp( now()) %}
{{ mynow }}
{% set years = (mynow/31556925)| int %}
{{years}}
{% set f_year = (mynow%31556925) %}
{{f_year}}
{% set f_day = (f_year%86400) %}
{{ f_day }}
{% set time = f_day %}
{{ time }}
{% set days = ( (time / 86400)) | int %}
{% set hours = ((time / 3600) | int) %}
{% set minutes = (((time % 3600)/60)|int) %}
{{minutes}}
{{hours}}
{{days}}

and I got this result.

the seconds divisor 31556925 is the seconds in a solar year. Close enough for an example

I was working down to fractional days. I assume the APC battery is not running over a day.

So in the example I get 0 days 9 hours 54 minutes. Is this what you were looking for?

EDIT: Removed timestamp_custom

Bringing my rant from here over here, to avoid pissing off nice people like @petro.

I want to understand something. The warning says: “this template will fail to render in Home Assistant core 2022.1”. Does this mean:
a. The template will give a warning/error in the logs and will not have a default value anymore
or
b. The system will refuse to start when it sees such a construct (w/o a default)
?

If a), then I don’t really see the reason for the warning, and I, for my part, won’t need to make any changes, because I don’t want to hide “default” assignments to zero.

If b), that is IMHO a very poor decision, because “fixing” this warning will hide actual bugs.

I still believe this change is not warranted and it’s been implemented as a workaround for a specific problem, but it will affect a lot of HA deployments out there.

I believe it is option “a”.

the only reason I can see for the change is that there were some users who were getting erroneous results in their templates and had no idea it was happening or why.

I think I would have handled it differently if that was the case.

I think it would have been sufficient to maintain the default “defaults” but also log a warning/error that the template was forced to fall back to the default values.

that way it shows users where (and if) they made a mistake but also provides for using the built-in default if that was already sufficient for what someone needs without the need for extra coding or trying to figure out the complexities of which defaults are needed and the required syntax.

the “make it easy” mantra always seems to be undermined by these types of changes.

2 Likes

It will produce an error instead of a warning. If it happens at startup (likely) you’re entity won’t be created. If it happens randomly but the entity already exists (i.e. after startup), you’ll just get an error.

I have this template sensor with availability template:

template:
  - sensor:
      - name: Living TV Volume Level
        unit_of_measurement: "%"
        availability: >-
          {{ state_attr("media_player.living_tv", "volume_level") not in 
            [None, unknown, 'none', 'unknown', 'unavailable'] }}
        state: >
            {{ (state_attr("media_player.living_tv", "volume_level") * 100)
              | int }}
        icon: >
          {% set vol = states('sensor.living_tv_volume_level')
            | int %}
          {% set lvl = (( (vol-1) // (100/3) ) | int) + 1 %}
          {% set icons = ['off','low','medium','high'] %}
          {% if 0 <= lvl <= 3 %}
          mdi:volume-{{ icons[lvl] }}
          {% else %}
          mdi:volume-{{ icons[1] }}
          {% endif %}

The log shows this entry:

Logger: homeassistant.helpers.template
Source: helpers/template.py:1291 
First occurred: 22:45:38 (5 occurrences) 
Last logged: 22:45:53

...

Template warning: 'int' got invalid input 'unknown' when rendering template '{% set vol = states('sensor.living_tv_volume_level') | int %} {% set lvl = (( (vol-1) // (100/3) ) | int) + 1 %} {% set icons = ['off','low','medium','high'] %} {% if 0 <= lvl <= 3 %} mdi:volume-{{ icons[lvl] }} {% else %} mdi:volume-{{ icons[1] }} {% endif %}' but no default was specified. Currently 'int' will return '0', however this template will fail to render in Home Assistant core 2022.1

Can someone explain why I see the error?

An availability template does not stop the state template from attempting to resolve. It just masks the result. I think there is a PR in progress to alter this behaviour. Either way your issue is with the icon template that this PR will not address. Just supply a default value for your use of |int in this template.

    icon: >
      {% set vol = states('sensor.living_tv_volume_level')
        | int(0) %}
      {% set lvl = (( (vol-1) // (100/3) ) | int) + 1 %}
      {% set icons = ['off','low','medium','high'] %}
      {% if 0 <= lvl <= 3 %}
      mdi:volume-{{ icons[lvl] }}
      {% else %}
      mdi:volume-{{ icons[1] }}
      {% endif %}