Closed andrewjswan closed 1 year ago
template documentation template source (message by IssueLinks)
Hey there @phracturedblue, @tetienne, @home-assistant/core, mind taking a look at this issue as it has been labeled with an integration (template
) you are listed as a code owner for? Thanks!
(message by CodeOwnersMention)
@tdejneka in my case icon always mdi:home-outline'
Why, trigger fired, state on, on | bool -> true, and icon should be mdi:home-plus
In other sensors this template work without problem
@tdejneka Look:
2022.9.4 the some ...
Without auto_off it doesn't update, or rather it does, but only once ...
template:
- trigger:
- platform: event
event_type: calendar_event_list_updated
sensor:
- name: calendar_events
state: "{{ (state_attr('input_select.calendar_events_list', 'options') | join('|') | replace ('Нет событий','')).split('|') | select('ne', '') | unique | list | count }}"
attributes:
events: "{{ state_attr('input_select.calendar_events_list', 'options') | list }}"
icon: "{{ (this.state | int(0) > 0) | iif('mdi:calendar-star', 'mdi:calendar-blank') }}"
unique_id: calendar_events
PS: It seems that when the sensor is updated, the icon based on this.sate
is updated first, and then the state of the sensor itself is updated
This sensor also has a status of unavailable all the time.
template:
- name: "Ragweed pollen"
unit_of_measurement: "p/m³"
icon: mdi:sprout
unique_id: ragweed_pollen
state: >
{{ states('sensor.accuweather_ragweed_pollen_0d') }}
attributes:
level: >-
{%- set pollen = { 'Low':'Низкий', 'Hight':'Высокий' } -%}
{%- set state = state_attr('sensor.accuweather_ragweed_pollen_0d','level') -%}
{{ pollen[state] if state in pollen else state }}
availability: >
{{ this.state | is_number }}
core- 2022.9.6 The some
Test sensor:
template:
- trigger:
- platform: time_pattern
minutes: "/1"
sensor:
- name: Test Template Sensor
state: "{{ now().minute }}"
icon: "{{ (this.state | int(0) % 2 == 0) | iif('mdi:home-floor-0','mdi:home-floor-1') }}"
unique_id: test_template_sensor
Test card:
type: vertical-stack
cards:
- type: markdown
content: >-
{{ states("sensor.test_template_sensor") }} % 2 == 0 -> {{
states("sensor.test_template_sensor") | int(0) % 2 == 0 }}
title: TEST
- type: entity
entity: sensor.test_template_sensor
state_color: true
Result:
Same when using trigger in sensors, first the state of this.sate or this.attributes.xxxxxx is updated based on the old value, and only then the state is updated.
template:
- trigger:
- platform: template
value_template: "{{ now().minute == 0 }}"
sensor:
- name: Disks - Lower space
state: "{{ this.attributes.disks | count }}"
attributes:
disks: >
{%- macro disk_space() -%}
{%- set ns = namespace(disks=[]) -%}
{% set threshold = (states('input_number.discs_free_space_lower') | int(10)) * 1024 * 1024 * 1024 %}
{%- for disk in states['sensor'] if ('_disk_' in disk.entity_id and state_attr(disk.entity_id, 'avail') != None and state_attr(disk.entity_id, 'avail') | int(0) < threshold ) -%}
{%- set json = {disk.name: (state_attr(disk.entity_id, 'avail') | int(0) / 1024 / 1024 / 1024) | round(1) ~ "Gb" } -%}
{%- set ns.disks = ns.disks + [ json ] -%}
{% endfor %}
{{ ns.disks }}
{%- endmacro -%}
{{ disk_space() }}
icon: mdi:harddisk
Hi! @PhracturedBlue, @tetienne, any ideas?
Hi! @akloeckner any ides?
Yes: both the attributes (e.g. icon
) and the state
update at the same time. In this case, when anyone_came_in_home
. During the update, the variable this
holds data from before the update! So, this.state
is off
in this case.
I can think of three approaches:
state_changed
of your binary sensor. state
template for icon
, too. state(this.entity_id)
, but this depends on whether attributes
are updated internally first or state
. So, better not rely on this.I think, this is mentioned somewhere in the docs. And the issue has been discovered previously. Maybe, someone could clarify the docs further? Hacktoberfest 2022 is on! ;-)
I couldn't find it in the documentation, nor could I find Issue.
But since the state is remembered before, which is very strange, it seems a bit pointless. And not logical.
After all, we expect this.state
to be updated when the state changes, but it doesn't.
See also: #60382
Thanks, I'll have a look and try it, but so far it feels like crutches, and unnecessary action. It made more sense to do it in the sensor itself.
@akloeckner But there's no trigger here, but it doesn't work either https://github.com/home-assistant/core/issues/78358#issuecomment-1257918708
I agree, it is not very intuitive.
But it's also not easy to address in a general way. We would need, e.g.
So, currently, the iteration must be enabled for selected self-references only. From the top of my head, I don't see a general improvement to it.
I'll check you links later!
I'll check you links later!
It seems to me that here we will get a permanent status of On:
- trigger:
- platform: event
event_type: anyone_came_in_home
- platform: state
entity_id: binary_sensor.anyone_came_in_home
binary_sensor:
- name: Anyone Came In Home
auto_off: '00:03:00'
state: "true"
icon: "{{ this.state | bool(false) | iif('mdi:home-plus', 'mdi:home-outline') }}"
unique_id: anyone_came_in_home
I.e. the trigger is triggered, we update the status, after some time, the sensor is switched off i.e. the status has changed and the trigger is triggered again, and there in a loop.
Checked, recursive constant updating.
- to use
state(this.entity_id)
, but
state(this.entity_id)
or states(this.entity_id)
I try states
- icon in not updated ...
- trigger:
- platform: event
event_type: anyone_came_in_home
binary_sensor:
- name: Anyone Came In Home
auto_off: '00:03:00'
state: "true"
icon: "{{ states(this.entity_id) | bool(false) | iif('mdi:home-plus', 'mdi:home-outline') }}"
unique_id: anyone_came_in_home
And in another sensor i get error on start:
2022-10-04 17:37:47.945 ERROR (MainThread) [homeassistant.helpers.template_entity] TemplateError('UndefinedError: 'homeassistant.util.read_only_dict.ReadOnlyDict object' has no attribute 'temperature'') while processing template ...
In attributes like:
steam_pressure: >-
{%- set temperature = this.attributes.temperature | float(0) -%}
.....
When i use state_attr('sensor.xxxx', 'temperature')
i dont have this error ...
This is how it works, but of course it looks like crutches. :(
- trigger:
- platform: event
event_type: anyone_came_in_home
id: "true"
- platform: state
entity_id: binary_sensor.anyone_came_in_home
to: 'on'
id: "true"
- platform: state
entity_id: binary_sensor.anyone_came_in_home
to: 'off'
id: "false"
binary_sensor:
- name: Anyone Came In Home
auto_off: '00:03:00'
state: "{{ trigger.id }}"
icon: "{{ trigger.id | bool(false) | iif('mdi:home-plus', 'mdi:home-outline') }}"
unique_id: anyone_came_in_home
this.state
- gave beauty and brevity, but it turns out that it is almost impossible to use.
Just replaced almost all the sensors that worked strangely with this.state
, this.attributes
with direct use of HA functions, a shame.
As I admitted earlier: yes, it is still somewhat unintuitive. But it's better than before. (You had to repeatedly type the sensor's name in the templates before.) And I have currently no idea how to make it perfect with a reasonable amount of effort. Some tipps:
unavailable
. I believe your unavailable
sensor might just be a faulty template. Try this syntax instead: variable is number
.unknown
with no attributes defined. So, this.attributes.my_attribute
will always give errors during startup. You can avoid this by using if 'my_attribute' in this.attributes
or by using the function state_attr(this.entity_id, 'my_attribute')
. Both these variants will gracefully handle the undefined attribute. The same holds true for states(this.entity_id)
.to: ~
. This will avoid some unnecessary iterations, possibly.default()
filters with this tipp.I tried to optimize your code with these remarks in mind:
- trigger:
- platform: event
event_type: anyone_came_in_home
- platform: state
entity_id: binary_sensor.anyone_came_in_home
to: ~
binary_sensor:
- name: Anyone Came In Home
auto_off: '00:03:00'
state: "{{ trigger.type == 'event' or this.state == 'on' }}"
icon: "{{ this.state | bool(false) | iif('mdi:home-plus', 'mdi:home-outline') }}"
It's untested, but something in these lines should work.
PS: When re-reading this, I get the feeling that registering a default state trigger for each sensor using this
might already be a good improvement.
- If any of the templates generate an error when rendered, the sensor will become
unavailable
. I believe yourunavailable
sensor might just be a faulty template. Try this syntax instead:variable is number
.
There's a complex design there, lots of attributes used in other attributes, and they end up being used in getting the state, avaliable template
checks all states, but you can see that at startup it's not as good as you wanted and at some point an error occurs. Adding checks is to complicate the code, using state_attr
removes all these errors, but the code becomes less nice.
- The initial state of a trigger-based sensor will be just
unknown
with no attributes defined. So,this.attributes.my_attribute
will always give errors during startup. You can avoid this by usingif 'my_attribute' in this.attributes
or by using the functionstate_attr(this.entity_id, 'my_attribute')
. Both these variants will gracefully handle the undefined attribute. The same holds true forstates(this.entity_id)
.
The documentation says that all template-based sensors retain their state when the Home Assistant is restarted.
If you want to trigger an update on state change, but ignore attribute changes, define
to: ~
. This will avoid some unnecessary iterations, possibly.In general, try to define your states and attributes as a fix-point iteration. This means: when you accidentally trigger an update while the sensor is already in its target state, it should not change. Home Assistant has a safeguard to stop endless re-triggering of updates, which will not be activated this way. As a rule of thumb, Home Assistant allows as many repeated updates as there are attributes defined on the sensor. You will probably end up using
default()
filters with this tipp.
I know that and will use it, thank you. :)
It's untested, but something in these lines should work.
I'll try to check it out. Thanks.
Architecturally, I would try to solve this problem roughly as follows
It's untested, but something in these lines should work.
Checked it, it's not working at all. The status and icon don't change. :(
Checked it, it's not working at all. The status and icon don't change. :(
Maybe try trigger.platform
instead of trigger.type
? (Our stick to the id
approach. I wanted to save as many lines as possible. 😉 )
I dont know. But this sensor will work for everyone who adds it to the configuration and sends an event from the developer tools. You can check.
I'm just trying to help find the most elegant solution, which is currently feasible. I have no use for that sensor (yet). But if you have a working version, let's leave it as is. 👍
Ok, Yes, my version looks like Frankenstein on crutches, but it works :) I would like a more beautiful solution, but alas.
The problem
Icon not updating on trigger binary sensor with auto off, the state changes as expected, but the icon does not change.
What version of Home Assistant Core has the issue?
core- 2022.9.2
What was the last working version of Home Assistant Core?
No response
What type of installation are you running?
Home Assistant OS
Integration causing the issue
Template
Link to integration documentation on our website
https://www.home-assistant.io/integrations/template/
Diagnostics information
No response
Example YAML snippet
Anything in the logs that might be useful for us?
No response
Additional information
No response