diff --git a/source/_docs/configuration/templating.markdown b/source/_docs/configuration/templating.markdown index 832132b5109c..4a4383fd3111 100644 --- a/source/_docs/configuration/templating.markdown +++ b/source/_docs/configuration/templating.markdown @@ -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.
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). diff --git a/source/_integrations/binary_sensor.template.markdown b/source/_integrations/binary_sensor.template.markdown index d96740e06a50..461c1363e4fd 100644 --- a/source/_integrations/binary_sensor.template.markdown +++ b/source/_integrations/binary_sensor.template.markdown @@ -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 %} diff --git a/source/_integrations/template.markdown b/source/_integrations/template.markdown index 63dd72d78c9b..016b2bae7ebf 100644 --- a/source/_integrations/template.markdown +++ b/source/_integrations/template.markdown @@ -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.