Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions source/_docs/configuration/templating.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ Extensions allow templates to access all of the Home Assistant specific states a
- `state_attr('device_tracker.paulus', 'battery')` will return the value of the attribute or None if it doesn't exist.
- `is_state_attr('device_tracker.paulus', 'battery', 40)` will test if the given entity attribute is the specified state (in this case, a numeric value). Note that the attribute can be `None` and you want to check if it is `None`, you need to use `state_attr('sensor.my_sensor', 'attr') == None`.
- `rate_limit` - limits re-renders of the template. Returns an empty string and accepts the same arguments as the Python `datetime.timedelta` function -- days, seconds, microseconds, milliseconds, minutes, hours, weeks.
- `track_time_pattern` - Switch template updates to a specific time pattern. Returns an empty string and accepts the same arguments as [Time Pattern Triggers](/docs/automation/trigger/#time-pattern-trigger) along with either `None` or `off` to disable all template updates.
<div class='note warning'>

Avoid using `states.sensor.temperature.state`, instead use `states('sensor.temperature')`. It is strongly advised to use the `states()`, `is_state()`, `state_attr()` and `is_state_attr()` as much as possible, to avoid errors and error message when the entity isn't ready yet (e.g., during Home Assistant startup).
Expand Down
66 changes: 28 additions & 38 deletions source/_integrations/binary_sensor.template.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -323,79 +323,69 @@ If the template accesses every state on the system or all states under a specifi

### 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.
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 does not include any entities, and references `now()` or `utcnow()`, by default it will be updated once per minute. If the template does not include any entities, `now()`, or `utcnow()`, the template will not update automaticlly.

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:
The `track_time_pattern` directive can be used to control when the template should be updated.

`track_time_pattern` accepts the same arguments as [Time Pattern Triggers](/docs/automation/trigger/#time-pattern-trigger) along with either `None` or `off` to disable all template updates.

In the below example, the template will be updated on the half 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 }}'
value_template: '{{ track_time_pattern(minutes=30) }}{{ now() }}'
```
{% endraw %}

An alternative to this is to create an interval-based automation that calls the service `homeassistant.update_entity` for the entities requiring updates:
In the case where the template should only be updated at the top of the hour:

{% 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
in_the_midnight_hour:
value_template: >-
{{ track_time_pattern(hours=0) }}
{{ now().hour == 0 }}
```
{% 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:
In the case where the template should only be updated at 30 second mark for minutes divisible by 5:

{% raw %}
```yaml
sensor:
- platform: time_date
display_options:
- 'time'

binary_sensor:
- platform: template
sensors:
minute_is_odd:
is_charging:
value_template: >-
{% set dummy = states("sensor.time") %}
{{ now().minute % 2 == 1 }}
{{ track_time_pattern(minutes="/5", seconds=30) }}
{{ states("sensor.inflow_power") | float > 5 }}
```
{% 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:
For more complex updates, automatic template updates can be disabled with `track_time_pattern(None)` and updates can be done manually by calling the `homeassistant.update_entity` service:

{% raw %}
```yaml
sensor:
- platform: time_date
display_options:
- 'date'

binary_sensor:
- platform: template
sensors:
weekend:
value_template: {{ states("sensor.date") and now().isoweekday() > 5 }}
half_hour:
value_template: '{{ track_time_pattern(None) }}{{ 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 %}
54 changes: 6 additions & 48 deletions source/_integrations/template.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -321,65 +321,23 @@ 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.
When a template contains no entities, and references `now()`, by default it will be updated once per minute. If the template does not include any entities, `now()`, or `utcnow()`, the template will not update automaticlly.

{% raw %}

```yaml
sensor:
- platform: time_date
display_options:
- 'date'
- 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) }}'
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.
The `track_time_pattern` directive can be used to control when the template should be updated.

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:
The below example will update once per day at `00:00:00`:

{% raw %}

```yaml
sensor:
- platform: template
sensors:
nonsmoker:
value_template: '{{ (( as_timestamp(now()) - as_timestamp(strptime("06.07.2018", "%d.%m.%Y")) ) / 86400 ) | round(2) }}'
value_template: '{{ track_time_pattern(hours=0, minutes=0, seconds=0) }}{{(( 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 %}

See [Working without entities](/integrations/binary_sensor.template/#working-without-entities) in the Template Binary Sensor integration for additional examples.