Time-based templates update automatically now (#15360)

This commit is contained in:
Anders Melchiorsen 2020-10-24 14:53:54 +02:00 committed by Franck Nijhof
parent d98c6fb960
commit c06dd5ef4b
No known key found for this signature in database
GPG Key ID: D62583BA8AB11CA3
10 changed files with 4 additions and 164 deletions

View File

@ -174,8 +174,10 @@ The same thing can also be expressed as a filter:
- `now()` returns a datetime object that represents the current time in your time zone.
- You can also use: `now().second`, `now().minute`, `now().hour`, `now().day`, `now().month`, `now().year`, `now().weekday()` and `now().isoweekday()` and other [`datetime`](https://docs.python.org/3.8/library/datetime.html#datetime.datetime) attributes and functions.
- Using `now()` will cause templates to be refreshed at the start of every new minute.
- `utcnow()` returns a datetime object of the current time in the UTC timezone.
- For specific values: `utcnow().second`, `utcnow().minute`, `utcnow().hour`, `utcnow().day`, `utcnow().month`, `utcnow().year`, `utcnow().weekday()` and `utcnow().isoweekday()`.
- Using `utcnow()` will cause templates to be refreshed at the start of every new minute.
- `as_timestamp()` converts datetime object or string to UNIX timestamp. This function also be used as a filter.
- `as_local()` converts datetime object to local time. This function also be used as a filter.
- `strptime(string, format)` parses a string based on a [format](https://docs.python.org/3.8/library/datetime.html#strftime-and-strptime-behavior) and returns a datetime object.
@ -460,10 +462,6 @@ To evaluate a response, go to **Developer Tools** -> **Template**, create your o
If your template uses an `entity_id` that begins with a number (example: `states.device_tracker.2008_gmc`) you must use a bracket syntax to avoid errors caused by rendering the `entity_id` improperly. In the example given, the correct syntax for the device tracker would be: `states.device_tracker['2008_gmc']`
### Templates without entities using `now()`
Note that templates that depend on time (`now()`) and do not use any entities will not be updated as it only happens on entity state changes. For more information and examples refer to [`template` sensor documentation](/integrations/template/#working-without-entities)
### Priority of operators
The default priority of operators is that the filter (`|`) has priority over everything except brackets. This means that:

View File

@ -108,7 +108,3 @@ panels:
If you are using the state of a integration that takes extra time to load, the Template Alarm Control Panel may get an `unknown` state during startup. This results in error messages in your log file until that integration has completed loading. If you use `is_state()` function in your template, you can avoid this situation.
For example, you would replace {% raw %}`{{ states.switch.source.state == 'on' }}`{% endraw %} with this equivalent that returns `true`/`false` and never gives an unknown result: {% raw %}`{{ is_state('switch.source', 'on') }}`{% endraw %}
### Working without entities
If you use a template that depends on the current time or some other non-deterministic result not sourced from entities, the template won't repeatedly update but will only update when the state of a referenced entity updates. For ways to deal with this issue, see [Working without entities](/integrations/binary_sensor.template/#working-without-entities) in the Template Binary Sensor integration.

View File

@ -106,13 +106,6 @@ with this equivalent that returns `true`/`false` and never gives an unknown
result:
{% raw %}`{{ is_state('switch.source', 'on') }}`{% endraw %}
### Sensor state updates
The template engine works out what entities are used to trigger an update of the sensor and recalculates the result when one of those entities change.
If you use a template that depends on the current time or some other non-deterministic result not sourced from entities, create an interval-based
automation that calls the service `homeassistant.update_entity` for the sensor requiring updates. See the [example below](#working-without-entities).
## Examples
In this section you find some real-life examples of how to use this sensor.
@ -322,82 +315,3 @@ binary_sensor:
{% endraw %}
If the template accesses every state on the system, a rate limit of one update per minute is applied. If the template accesses all states under a specific domain, a rate limit of one update per second is applied. If the template only accesses specific states, receives update events for specifically referenced entities, or the `homeassistant.update_entity` service is used, no rate limit is applied.
### Working without entities
The `template` sensors are not limited to use attributes from other entities but can also work with [Home Assistant's template extensions](/docs/configuration/templating/#home-assistant-template-extensions). If the template includes some non-deterministic property such as time in its calculation, the result will not continually update, but will only update when some entity referenced by the template updates.
There's a couple of options to manage this issue. This first example creates a `sensor.time` from the [Time & Date](/integrations/time_date/) component which updates every minute, and the binary sensor is triggered by this updating. The binary sensor returns true if in the first half of the hour:
{% raw %}
```yaml
sensor:
- platform: time_date
display_options:
- 'time'
binary_sensor:
- platform: template
sensors:
half_hour:
value_template: '{{ (states("sensor.time")[3:] | int) < 30 }}'
```
{% endraw %}
An alternative to this is to create an interval-based automation that calls the service `homeassistant.update_entity` for the entities requiring updates:
{% raw %}
```yaml
binary_sensor:
- platform: template
sensors:
half_hour:
value_template: '{{ now().minute < 30 }}'
automation:
- alias: 'Update half_hour'
trigger:
- platform: time_pattern
minutes: /30
action:
- service: homeassistant.update_entity
entity_id: binary_sensor.half_hour
```
{% endraw %}
In the case where the template should be updated every minute, just reading `states("sensor.time")` can achieve the desired result without the need to create an automation:
{% raw %}
```yaml
sensor:
- platform: time_date
display_options:
- 'time'
binary_sensor:
- platform: template
sensors:
minute_is_odd:
value_template: >-
{% set dummy = states("sensor.time") %}
{{ now().minute % 2 == 1 }}
```
{% endraw %}
A similar trick of ignoring the sensor value can be used with `states("sensor.date")` for templates that should update at midnight.
The `time_date` sensors are always true so here we use `and` to ignore the result in a more condensed way:
{% raw %}
```yaml
sensor:
- platform: time_date
display_options:
- 'date'
binary_sensor:
- platform: template
sensors:
weekend:
value_template: {{ states("sensor.date") and now().isoweekday() > 5 }}
```
{% endraw %}

View File

@ -126,10 +126,6 @@ with this equivalent that returns `true`/`false` and never gives an unknown
result:
{% raw %}`{{ is_state('cover.source', 'open') }}`{% endraw %}
### Working without entities
If you use a template that depends on the current time or some other non-deterministic result not sourced from entities, the template won't repeatedly update but will only update when the state of a referenced entity updates. For ways to deal with this issue, see [Working without entities](/integrations/binary_sensor.template/#working-without-entities) in the Template Binary Sensor integration.
## Optimistic Mode
In optimistic mode, the cover position state is maintained internally. This mode

View File

@ -114,7 +114,3 @@ fan:
type: [string, list]
default: ['low', 'medium', 'high']
{% endconfiguration %}
### Working without entities
If you use a template that depends on the current time or some other non-deterministic result not sourced from entities, the template won't repeatedly update but will only update when the state of a referenced entity updates. For ways to deal with this issue, see [Working without entities](/integrations/binary_sensor.template/#working-without-entities) in the Template Binary Sensor integration.

View File

@ -146,10 +146,6 @@ with this equivalent that returns `true`/`false` and never gives an unknown
result:
{% raw %}`{{ is_state('switch.source', 'on') }}`{% endraw %}
### Working without entities
If you use a template that depends on the current time or some other non-deterministic result not sourced from entities, the template won't repeatedly update but will only update when the state of a referenced entity updates. For ways to deal with this issue, see [Working without entities](/integrations/binary_sensor.template/#working-without-entities) in the Template Binary Sensor integration.
## Examples
In this section you will find some real-life examples of how to use this light.

View File

@ -79,10 +79,6 @@ lock:
If you are using the state of a platform that takes extra time to load, the Template Lock may get an `unknown` state during startup. This results in error messages in your log file until that platform has completed loading. If you use `is_state()` function in your template, you can avoid this situation. For example, you would replace {% raw %}`{{ is_state('switch.source', 'on') }}`{% endraw %} with this equivalent that returns `true`/`false` and never gives an unknown result: {% raw %}`{{ is_state('switch.source', 'on') }}`{% endraw %}
### Working without entities
If you use a template that depends on the current time or some other non-deterministic result not sourced from entities, the template won't repeatedly update but will only update when the state of a referenced entity updates. For ways to deal with this issue, see [Working without entities](/integrations/binary_sensor.template/#working-without-entities) in the Template Binary Sensor integration.
## Examples
In this section, you find some real-life examples of how to use this lock.

View File

@ -86,10 +86,6 @@ switch:
If you are using the state of a platform that takes extra time to load, the Template Switch may get an `unknown` state during startup. This results in error messages in your log file until that platform has completed loading. If you use `is_state()` function in your template, you can avoid this situation. For example, you would replace {% raw %}`{{ states.switch.source.state == 'on') }}`{% endraw %} with this equivalent that returns `true`/`false` and never gives an unknown result: {% raw %}`{{ is_state('switch.source', 'on') }}`{% endraw %}
### Working without entities
If you use a template that depends on the current time or some other non-deterministic result not sourced from entities, the template won't repeatedly update but will only update when the state of a referenced entity updates. For ways to deal with this issue, see [Working without entities](/integrations/binary_sensor.template/#working-without-entities) in the Template Binary Sensor integration.
## Examples
In this section you find some real-life examples of how to use this switch.

View File

@ -321,7 +321,7 @@ sensor:
The `template` sensors are not limited to use attributes from other entities but can also work with [Home Assistant's template extensions](/docs/configuration/templating/#home-assistant-template-extensions).
This template contains no entities that will trigger an update, so we add in a reference to the `sensor.date` sensor from the [Time & Date](/integrations/time_date/), which will update once a day.
This template contains no entities that will trigger an update but the `now()` will cause it to update every minute:
{% raw %}
@ -333,53 +333,9 @@ sensor:
- platform: template
sensors:
nonsmoker:
value_template: '{{ states('sensor.date') and (( as_timestamp(now()) - as_timestamp(strptime("06.07.2018", "%d.%m.%Y")) ) / 86400 ) | round(2) }}'
value_template: '{{ ( ( as_timestamp(now()) - as_timestamp(strptime("06.07.2018", "%d.%m.%Y")) ) / 86400 ) | round(2) }}'
friendly_name: 'Not smoking'
unit_of_measurement: "Days"
```
{% endraw %}
In this case it is also possible to convert the entity-less template above into one that will be updated automatically:
{% raw %}
````yaml
sensor:
- platform: template
sensors:
nonsmoker:
value_template: "{{ (( as_timestamp(strptime(states('sensor.date'), '%Y-%m-%d')) - as_timestamp(strptime('06.07.2018', '%d.%m.%Y')) ) / 86400 ) | round(2) }}"
friendly_name: 'Not smoking'
unit_of_measurement: "Days"
````
{% endraw %}
Useful entities to choose might be `sensor.date` which update once per day or `sensor.time`, which updates once per minute.
Please note that the resulting template will be evaluated by Home Assistant state engine on every state change of these sensors, which in case of `sensor.time` happens every minute and might have a negative impact on performance.
An alternative to this is to create an interval-based automation that calls the service `homeassistant.update_entity` for the entities requiring updates. This modified example updates every 5 minutes:
{% raw %}
```yaml
sensor:
- platform: template
sensors:
nonsmoker:
value_template: '{{ (( as_timestamp(now()) - as_timestamp(strptime("06.07.2018", "%d.%m.%Y")) ) / 86400 ) | round(2) }}'
friendly_name: 'Not smoking'
unit_of_measurement: "Days"
automation:
- alias: 'nonsmoker_update'
trigger:
- platform: time_pattern
minutes: '/5'
action:
- service: homeassistant.update_entity
entity_id: sensor.nonsmoker
```
{% endraw %}

View File

@ -103,10 +103,6 @@ vacuum:
type: [string, list]
{% endconfiguration %}
### Working without entities
If you use a template that depends on the current time or some other non-deterministic result not sourced from entities, the template won't repeatedly update but will only update when the state of a referenced entity updates. For ways to deal with this issue, see [Working without entities](/integrations/template/#working-without-entities) in the Template Sensor integration.
## Examples
### Control vacuum with Harmony Hub