Serves me right for not checking the documentation.
According to the Jinja2 docs, default is second and base is last:
jinja-filters.int(value: Any, default: int = 0, base: int = 10 ) → int¶
Convert the value into an integer. If the conversion doesn’t work it will return 0. You can override this default using the first parameter. You can also override the default base (10) in the second parameter, which handles input with prefixes such as 0b, 0o and 0x for bases 2, 8 and 16 respectively. The base is ignored for decimal numbers and non-string values.
It can be confusing because the Jinja2 docs describe its filters like when they are used as functions, so in that case int can take three arguments. However, Home Assistant’s current implementation of int is only as a filter, not a function. As a filter, it can take two arguments where the first is the default value and the last is the base.
Ehh, just for me then… where does this leave my template? Why the error? And more importantly, how to fix ?
the 2 Int’s what do I set them to?
{%- set alert_level = states('input_number.battery_alert_level')|int(default=0) %} {%- set count = expand('group.battery_sensors')
|map(attribute='state')
|rejectattr('state','in',['unknown','unavailable'])
|map('int',0)
|select('<',alert_level)
|list|count %}
{% set phrase = 'battery is' if count == 1 else 'batteries are' %} {%- if count > 0 %} {%- for s in expand('group.battery_sensors')
if s.state not in ['unknown','unavailable','None'] and
s.state|int(default=0) < alert_level %}
{%- if loop.first %}{{loop.length}} {{phrase}} below {{alert_level}} %: {% endif %} {{s.name + ': ('+ s.state + '%),\n'}} {%- endfor %} {%- else %} All batteries above {{alert_level}} % {%- endif %}
Odd thing is, when I have a running system, I can’t force a warning on this template…So might it be some startup issue? Maybe I should add an availability template?
think this does it:
- unique_id: low_level_batteries
name: Low level batteries
state: >
{% set alert_level = states('input_number.battery_alert_level')|int(default=0) %}
{{expand('group.battery_sensors')
|map(attribute='state')
|rejectattr('state','in',['unknown','unavailable'])
|map('int',default=0)
|select('<',alert_level)
|list|count}}
icon: mdi:battery-alert
attributes:
list_low: >
{%- set alert_level = states('input_number.battery_alert_level')|int(default=0) %}
{%- set count = expand('group.battery_sensors')
|map(attribute='state')
|rejectattr('state','in',['unknown','unavailable'])
|map('int',default=0)
|select('<',alert_level)
|list|count %}
{% set phrase = 'battery is' if count == 1 else 'batteries are' %}
{%- if count > 0 %}
{%- for s in expand('group.battery_sensors')
if s.state not in ['unknown','unavailable','None'] and
s.state|int(default=0) < alert_level %}
{%- if loop.first %}{{loop.length}} {{phrase}} below {{alert_level}} %: {% endif %}
{{s.name + ': ('+ s.state + '%),\n'}}
{%- endfor %}
{%- else %} All batteries above {{alert_level}} %
{%- endif %}
list_all: >
{%- for s in expand('group.battery_sensors')%}
{{s.name + ': ('+ s.state + '%),\n'}}
{%- endfor %}
For a such a conceptually simple change this new templating update seems to be causing a lot of work and questions.
Can I ask a couple of simple(?) ones…
In general, when there is no way to provide a sensible default (i.e. it would produce a result that is no better than a guess) does it make sense to always provide default=none? There seems to be no way to guard against an invalid incoming date like you can for numbers (is_number).
The current example I am working on is strptime, There is no ‘sensible valid’ default for sensor.next_trains_estimated.
{% set estimated = strptime(states('sensor.next_trains_estimated'), "%H:%M") %}
{% set tnow = strptime(now().strftime('%H:%M'), "%H:%M") %}
{% set time_to_next_train = (estimated - tnow).total_seconds() / 60 %}
{% set time_to_next_train = time_to_next_train | round %}
And, am I reading this all correctly, the next version of HA introduces more of these e.g int? Why weren’t they all included at once?
And finally a minor rhetorical rant. I know all the stock answers but I do think this apparently-simple-but-actually-quite-seismic change could have been better documented. The OP here is obviously very instructive but surely this information should be in the docs at release time and not have to be buried in the forum where only a few will see it.
I do think HA let’s itself down on two issues. Communication (see the latest Tuya issue) and documentation. It is far better than it was but still not really good enough when things get added (I believe the main source of info to get the energy integration working is still the Blog post or the ‘Developer docs’) or ‘broken’ by upgrades (e.g. these templates).
might be wide of the mark here (and probably well out of my depth so be gentle ), but isn’t it a case the the Warning message currently only appears when a Template presents an invalid result…
So taking your template then the Memory Usage will pretty much always have an Integer Value (once HA is running on your device) so it’ll never throw an invalid result, etc therefore doesn’t warn in your logs.
(and following on from that it’ll only error if that sensor ever goes unavailable which I guess is unlikely)
“Technically” you should supply a default but operationally there is no need as the sensor is always(nearly always) providing a valid result
That’s my understanding of these new changes anyway…may be wrong so be grateful for confirmation/correction…
That’s an unnecessary use of the timestamp_custom() function.
'10:00' is not a timestamp, it’s a string and the function can’t do anything with it so it’s obligated to report a default value. There’s absolutely no need to use that function in this situation. Remove it.
In fact, your template doesn’t even need to use the sensor.time entity. It’s simply checking if the current hour is within a range of hours so it can use the now().hour.
Here’s a revised version of your automation employing everything I suggested plus a few additional ones:
WARNING (MainThread) [homeassistant.helpers.template] Template warning: 'int' got invalid input 'None' when rendering template '{{ ( state_attr('sensor.xxx', '4503') | int(base=16) / 90 * 255 ) | int }}' but no default was specified. Currently 'int' will return '0', however this template will fail to render in Home Assistant core 2022.1