From b908b87c7d8cd1addd29d9021aa0f7a542699239 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 3 Sep 2020 11:51:07 -0500 Subject: [PATCH] Update template entity docs for entity_id removal and guidance on working without entities (#14343) Co-authored-by: Anders Melchiorsen Co-authored-by: Swamp-Ig --- source/_docs/scripts.markdown | 2 + .../alarm_control_panel.template.markdown | 4 ++ source/_integrations/bayesian.markdown | 7 ++- .../binary_sensor.template.markdown | 52 ++++++++++++++++--- source/_integrations/cover.template.markdown | 11 ++-- source/_integrations/fan.template.markdown | 4 ++ source/_integrations/light.template.markdown | 8 +-- source/_integrations/lock.template.markdown | 4 ++ source/_integrations/switch.template.markdown | 8 +-- source/_integrations/template.markdown | 22 ++++---- source/_integrations/universal.markdown | 2 + source/_integrations/vacuum.template.markdown | 4 ++ 12 files changed, 94 insertions(+), 34 deletions(-) diff --git a/source/_docs/scripts.markdown b/source/_docs/scripts.markdown index c31b73b8133..d50c2fab103 100644 --- a/source/_docs/scripts.markdown +++ b/source/_docs/scripts.markdown @@ -114,6 +114,8 @@ When used within an automation the `trigger` variable is available. See [Availab This action evaluates the template, and if true, the script will continue. If not, then it will wait until it is true. +The template is re-evaluated whenever an entity ID that it references changes state. If you use non-deterministic functions like `now()` in the template it will not be continuously re-evaluated, but only when an entity ID that is referenced is changed. If you need to periodically re-evaluate the template, reference a sensor from the (Time and Date)[/integrations/time_date/] component that will update minutely or daily. + {% raw %} ```yaml # Wait until media player have stop the playing diff --git a/source/_integrations/alarm_control_panel.template.markdown b/source/_integrations/alarm_control_panel.template.markdown index 4789b200013..4a4f47ceb71 100644 --- a/source/_integrations/alarm_control_panel.template.markdown +++ b/source/_integrations/alarm_control_panel.template.markdown @@ -106,3 +106,7 @@ 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. \ No newline at end of file diff --git a/source/_integrations/bayesian.markdown b/source/_integrations/bayesian.markdown index b55e097cfc0..5b78e1fadf2 100644 --- a/source/_integrations/bayesian.markdown +++ b/source/_integrations/bayesian.markdown @@ -132,8 +132,7 @@ binary_sensor: below: 50 ``` -Finally, here's an example for `template` observation platform, -as seen in the configuration it requires `value_template` and does not use `entity_id`. +Finally, here's an example for `template` observation platform, as seen in the configuration it requires `value_template`. {% raw %} ```yaml @@ -150,3 +149,7 @@ binary_sensor: prob_given_true: 0.95 ``` {% endraw %} + +The template is re-evaluated whenever an entity ID that it references changes state. If you use non-deterministic functions like `now()` in the template it will not be continuously re-evaluated, but only when an entity ID that is referenced is updated. + +In this example, since the template is only evaluated on state change of `device_tracker.paulus` the template won't change state after 5 mins like intended. The ways to force template reevaluation are documented in the [template binary_sensor](/integrations/binary_sensor.template/#working-without-entities). diff --git a/source/_integrations/binary_sensor.template.markdown b/source/_integrations/binary_sensor.template.markdown index 66c0e0e400e..81c298124fd 100644 --- a/source/_integrations/binary_sensor.template.markdown +++ b/source/_integrations/binary_sensor.template.markdown @@ -110,13 +110,12 @@ with this equivalent that returns `true`/`false` and never gives an unknown result: {% raw %}`{{ is_state('switch.source', 'on') }}`{% endraw %} -### Entity IDs +### Sensor state updates -The template engine will attempt to work out what entities should trigger an -update of the sensor. This can fail, for example if your template loops over -the contents of a group. In this case you can use `entity_id` to provide a -list of entity IDs that will cause the sensor to update or you can run the -service `homeassistant.update_entity` to update the sensor at will. +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 @@ -294,3 +293,44 @@ binary_sensor: ``` {% endraw %} + +### 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.state[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. This modified example updates every 2 minutes: + +{% raw %} +```yaml +binary_sensor: +- platform: template + sensors: + minute_is_odd: + value_template: '{{ now().minute % 2 }}' + +automation: + - alias: 'Update minute_is_odd' + trigger: + - platform: time_pattern + minutes: '*' + action: + - service: homeassistant.update_entity + entity_id: binary_sensor.minute_is_odd +{% endraw %} diff --git a/source/_integrations/cover.template.markdown b/source/_integrations/cover.template.markdown index ae2811bf43d..b24686c2fa6 100644 --- a/source/_integrations/cover.template.markdown +++ b/source/_integrations/cover.template.markdown @@ -49,10 +49,6 @@ cover: description: Name to use in the frontend. required: false type: string - entity_id: - description: A list of entity IDs so the cover only reacts to state changes of these entities. This can be used if the automatic analysis fails to find all relevant entities. - required: false - type: [string, list] unique_id: description: An ID that uniquely identifies this cover. Set this to an unique value to allow customisation trough the UI. required: false @@ -126,6 +122,10 @@ 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 @@ -219,9 +219,6 @@ cover: {% else %} mdi:window-closed {% endif %} - entity_id: - - cover.bedroom - - cover.livingroom sensor: - platform: template diff --git a/source/_integrations/fan.template.markdown b/source/_integrations/fan.template.markdown index 6dee002938c..dfade983c16 100644 --- a/source/_integrations/fan.template.markdown +++ b/source/_integrations/fan.template.markdown @@ -114,3 +114,7 @@ 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. \ No newline at end of file diff --git a/source/_integrations/light.template.markdown b/source/_integrations/light.template.markdown index 84d3d20423d..3b2741af6d0 100644 --- a/source/_integrations/light.template.markdown +++ b/source/_integrations/light.template.markdown @@ -70,10 +70,6 @@ light: description: Name to use in the frontend. required: false type: string - entity_id: - description: A list of entity IDs so the light only reacts to state changes of these entities. This can be used if the automatic analysis fails to find all relevant entities. - required: false - type: [string, list] unique_id: description: An ID that uniquely identifies this light. Set this to an unique value to allow customisation trough the UI. required: false @@ -150,6 +146,10 @@ 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. diff --git a/source/_integrations/lock.template.markdown b/source/_integrations/lock.template.markdown index f263dd65af7..50aadb136db 100644 --- a/source/_integrations/lock.template.markdown +++ b/source/_integrations/lock.template.markdown @@ -79,6 +79,10 @@ 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. diff --git a/source/_integrations/switch.template.markdown b/source/_integrations/switch.template.markdown index 4721779aecb..7f02ce20fdd 100644 --- a/source/_integrations/switch.template.markdown +++ b/source/_integrations/switch.template.markdown @@ -50,10 +50,6 @@ switch: description: Name to use in the frontend. required: false type: string - entity_id: - description: A list of entity IDs so the switch only reacts to state changes of these entities. This can be used if the automatic analysis fails to find all relevant entities. - required: false - type: [string, list] unique_id: description: An ID that uniquely identifies this switch. Set this to an unique value to allow customisation trough the UI. required: false @@ -90,6 +86,10 @@ 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. diff --git a/source/_integrations/template.markdown b/source/_integrations/template.markdown index 9fd036cb54a..cdbc80d42fc 100644 --- a/source/_integrations/template.markdown +++ b/source/_integrations/template.markdown @@ -50,10 +50,6 @@ sensor: description: Defines a template for the name to be used in the frontend (this overrides friendly_name). required: false type: template - entity_id: - description: A list of entity IDs so the sensor only reacts to state changes of these entities. This can be used if the automatic analysis fails to find all relevant entities. - required: false - type: [string, list] unique_id: description: An ID that uniquely identifies this sensor. Set this to an unique value to allow customisation trough the UI. required: false @@ -104,9 +100,12 @@ If you are using the state of a platform that takes extra time to load, the Temp {% raw %}`{{ is_state('switch.source', 'on') }}`{% endraw %} -### Entity IDs +### Sensor state updates -The template engine will attempt to work out what entities should trigger an update of the sensor. This can fail, for example, if your template loops over the contents of a group. In this case, you can use `entity_id` to provide a list of entity IDs that will cause the sensor to update or you can run the service `homeassistant.update_entity` to update the sensor at will. +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). ### Unique ID @@ -322,17 +321,19 @@ 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 (as `now()` is a function), so we add an `entity_id:` line with an entity that will force an update - here we're using a [date sensor](/integrations/time_date) to get a daily update: +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. {% raw %} ```yaml sensor: + - platform: time_date + display_options: + - 'date' - platform: template sensors: nonsmoker: - value_template: "{{ (( as_timestamp(now()) - as_timestamp(strptime('06.07.2018', '%d.%m.%Y')) ) / 86400 ) | round(2) }}" - entity_id: sensor.date + 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" ``` @@ -367,8 +368,7 @@ sensor: - platform: template sensors: nonsmoker: - value_template: "{{ (( as_timestamp(now()) - as_timestamp(strptime('06.07.2018', '%d.%m.%Y')) ) / 86400 ) | round(2) }}" - entity_id: [] + 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" diff --git a/source/_integrations/universal.markdown b/source/_integrations/universal.markdown index ccdf7118aad..8bbec5a864d 100644 --- a/source/_integrations/universal.markdown +++ b/source/_integrations/universal.markdown @@ -74,6 +74,8 @@ It is also recommended that the command `volume_up`, the command `volume_down`, When providing `select_source` as a command, it is recommended to also provide the attributes `source`, and `source_list`. The `source` attribute is the currently select source, while the `source_list` attribute is a list of all available sources. +When using `state_template`, 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 the [example](/integrations/binary_sensor.template/#working-without-entities) in the template binary_sensor. + ## Usage examples ### Chromecast & Kodi control with switches diff --git a/source/_integrations/vacuum.template.markdown b/source/_integrations/vacuum.template.markdown index 6e83c71b77b..8ad670f3e3a 100644 --- a/source/_integrations/vacuum.template.markdown +++ b/source/_integrations/vacuum.template.markdown @@ -103,6 +103,10 @@ 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