so back to this original template you posted, you should use
{{ states('sensor.boiler_amps')|float(0) > 1 }}
because it will end up with 0 > 1 as false and won’t trigger.
so back to this original template you posted, you should use
{{ states('sensor.boiler_amps')|float(0) > 1 }}
because it will end up with 0 > 1 as false and won’t trigger.
Then use an availability template to monitor the original sensor.
template:
- binary_sensor:
- name: "Has Unavailable States"
state: "{{ states.sensor | selectattr('state', 'in', ['unavailable', 'unknown', 'none']) | list | count }}"
I have to change quite few things but it will in the end simplify my notifications
To my shame I have rarely used availability
(templates) so bear with me here…
Am I right in thinking that the following template is ‘good’ i.e. it will either work without errors warnings or show as unavailable
?
Is the float(default='none')
and the round(2, default='none')
for the sensor a good choice because the availability
template will stop this even being evaluated if the sensor is 'unknown' or 'unavailable'
?
If the sensor is populated with anything other than a valid numeric there is a deeper problem that I need to know about.
As an observation, the float default seems to be unfortunate overkill (but obviously now required) for the input_number
entities as they can’t ever be anything other than number?
state: >
{% set unit_price = states('input_number.octopus_gas_unit_price') | float(default='none') %}
{% set standing_charge = states('input_number.octopus_gas_standing_charge') | float(default='none') %}
{% set calorific_value = states('input_number.octopus_gas_calorific_value') | float(default='none') %}
{% set cost = states('sensor.octopus_gas_consumption_kwh_yesterday') | float(default='none') * unit_price / 100 + standing_charge / 100 | round(2, default='none') %}
{{ '{:02.2f}'.format(cost) | string }}
availability: >
{{ states('sensor.octopus_gas_consumption_kwh_yesterday') not in ['unknown','unavailable'] }}
you want to make sure the are all available
I use this for my availability templates that require everything to be available:
{% set items = 'sensor.memory_free', 'sensor.memory_use' %}
{{ expand(items) | rejectattr('state','in',['unknown','unavailable']) | list | count == items | count }}
Then just add whatever you want to items.
i forgot to mention, then just use 0 as the default, the calc will be thrown out anyways
thats nice indeed. was thrown off at first by the order in | list | count == items | count
but then realized it is actually doing
{{ ((expand(items) | rejectattr('state','in',['unknown','unavailable'])) | list | count) == (items | count) }}
we can use this even in a 1 entity list but then need the on the items:
availability: >
{% set items = ['sensor.zp_actuele_opbrengst'] %}
{{expand(items)|rejectattr('state','in',['unknown','unavailable'])
|list|count == items|count}}
having had these for ages:
- binary_sensor:
- unique_id: ink_level_black_threshold
name: Ink level black threshold
state: >
{{states('sensor.epson_ink_level_black') is not none and
states('sensor.epson_ink_level_black')|int <
states('input_number.ink_level')|int}}
considering the above availability (which I supposedly checked with the is not none
and the upcoming defaults for |int, should I change these to
- unique_id: ink_level_black_threshold
name: Ink level black threshold
state: >
{{states('sensor.epson_ink_level_black')|int(default=0) <
states('input_number.ink_level')|int}}
availability: >
{% set items = ['sensor.epson_ink_level_black'] %}
{{expand(items)|rejectattr('state','in',['unknown','unavailable'])
|list|count == items|count}}
?
(where no default would be required on the input_number I guess?)
availability: >
{{states('sensor.epson_ink_level_black') not in ['unknown','unavailable']}}
might be simpler
Yes if the calculation only involves 1 other entity, no reason to use generators.
FYI, I made an edit to the original post that explains arguments better. Take a look.
yes, I did and thanks!
What might be an addition to that, is deciding whether one wants a template to return a value, and thus report an entity with a state, at all times, or, whether one wants a template to show unavailable when no valid input was received.
For your post eg this
{{ 1.43 | round(default=0) }}
returning 0 or
{{ 1.43 | round(default=none) }}
returning unavailable
currently, I find that choice to be the biggest challenge throughout the config. Especially so, when combined calculations are used, either inside the 1 template, or from 1 template entity to another
same goes for the |int(default=0)
in the next update. Seems logical to add that when the input is from an uncertain source, like another integration. But when used as a direct number like an input_number, which always has a value, why would a default be needed at all…
what about the input_numbers in the templates I use above, do I need a |int(default=50)
on those?
{{states('sensor.epson_ink_level_black')|int(default=0) <
states('input_number.ink_level')|int(default=50)}}
hope the warnings in the next updates logger will tell.
If it doesn’t produce a warning, no need to update it
side question: running the daily now contains those |int changes? what was the cli command again to run the daily’s? foreseeing a longer period of editing, Id like to have a go asap…
well thats a huge change on |int
1 question to be sure on the map(int):
{% 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')
|select('<',alert_level)
|list|count}}
should be:
{% 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}}
?
couldnt find the direct explanation on int in that form
this is really cool:
availability: >
{% set items = expand('group.doors') %}
{% set x = ['unavailable','unknown'] %}
{{expand(items)|rejectattr('state','in',x)|list|count == items|count}}
adding it to all binary template sensors, just for the fun of it
The Home Assistant’s current implementation of the int
filter takes only one argument, namely the default value,int
filter takes two arguments and the first one is the default value (the second one is the base), so there’s no obligation to supply “default=” when specifying the default value. map('int', 0)
is sufficient.
thanks, retesting as I write. guess I peaked too much at Petro’s changes https://github.com/Petro31/home-assistant-config/commit/5bde1c33b1fb2f52a3a91bc1c4a018c6c0a82288 and didnt think about the differences…
this error was huge, and took many hundreds of lines. somehow it must have been tested continously during startup.
nope still renders:
Template warning: 'int' got invalid input 'unknown' when rendering template '{% 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',0)
|select('<',alert_level)
|list|count}}' but no default was specified. Currently 'int' will return '0', however this template will fail to render in Home Assistant core 2022.1
If you wish, you can reduce it to this:
availability: >
{% set items = expand('group.doors') %}
{{ items|rejectattr('state','in',['unavailable','unknown'])|list == items }}
FWIW, even though it’s shorter (because it doesn’t use the count
filter) it might involve a few more CPU cycles because it’s comparing one list to another whereas petro’s original version compares one integer to another. If that concerns you, you can revert to comparing integers:
availability: >
{% set items = expand('group.doors') %}
{{ items|rejectattr('state','in',['unavailable','unknown'])|list|count == items|count }}
Doh!
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.