From cfa99599e23e988e9aef469e5df690b7d72c6366 Mon Sep 17 00:00:00 2001 From: G Johansson Date: Mon, 2 Sep 2024 12:16:03 +0300 Subject: [PATCH] Add merge_response templating (#34050) * Add merge_response templating * Update source/_docs/configuration/templating.markdown * Update * Fix * Fixes * More * Align with core pr * Mods * Fixes * Tiny tweaks --------- Co-authored-by: c0ffeeca7 <38767475+c0ffeeca7@users.noreply.github.com> --- .../_docs/configuration/templating.markdown | 172 ++++++++++++++++++ 1 file changed, 172 insertions(+) diff --git a/source/_docs/configuration/templating.markdown b/source/_docs/configuration/templating.markdown index 5c59113e367..a172e72a946 100644 --- a/source/_docs/configuration/templating.markdown +++ b/source/_docs/configuration/templating.markdown @@ -1180,6 +1180,178 @@ See: [Python regular expression operations](https://docs.python.org/3/library/re - Filter `value | regex_findall(find='', ignorecase=False)` will find all regex matches of the find expression in `value` and return the array of matches. - Filter `value | regex_findall_index(find='', index=0, ignorecase=False)` will do the same as `regex_findall` and return the match at index. +## Merge action responses + +Using action responses we can collect information from various entities at the same time. +Using the `merge_response` template we can merge several responses into one list. + +| Variable | Description | +| -------------- | ---------------------------------- | +| `value` | The incoming value (must be an action response). | + +The `entity_id` key is appended to each dictionary within the template output list as a reference of origin. If the input dictionary already contains an `entity_id` key, the template will fail. + +The `value_key` key is appended to each dictionary within the template output list as a reference of origin if the original service call was providing a list of dictionaries, for example, `calendar.get_events` or `weather.get_forecasts`. + +Examples of these two keys can be seen in [example merge calendar action response](#example-merge-calendar-action-response) template output. + + +### Example + +```yaml +{% raw %} + +{% set combined_forecast = merge_response(response) %} +{{ combined_forecast[0].precipitation | float(0) | round(1) }} + +{% endraw %} +``` + +### Example how to sort + +Sorting the dictionaries within the list based on a specific key can be done directly by using Jinja's `sort` filter. + +```yaml +{% raw %} + +{{ merge_response(calendar_response) | sort(attribute='start') | ... }} + +{% endraw %} +``` + +### Example merge calendar action response + +```json +{ + "calendar.sports": { + "events": [ + { + "start": "2024-02-27T17:00:00-06:00", + "end": "2024-02-27T18:00:00-06:00", + "summary": "Basketball vs. Rockets", + "description": "", + } + ] + }, + "calendar.local_furry_events": {"events": []}, + "calendar.yap_house_schedules": { + "events": [ + { + "start": "2024-02-26T08:00:00-06:00", + "end": "2024-02-26T09:00:00-06:00", + "summary": "Dr. Appt", + "description": "", + }, + { + "start": "2024-02-28T20:00:00-06:00", + "end": "2024-02-28T21:00:00-06:00", + "summary": "Bake a cake", + "description": "something good", + } + ] + }, +} +``` + +```yaml +{% raw %} +{{ merge_response(response_variable) }} +{% endraw %} +``` + +```json +[ + { + "description": "", + "end": "2024-02-27T18:00:00-06:00", + "entity_id": "calendar.sports", + "start": "2024-02-27T17:00:00-06:00", + "summary": "Basketball vs. Rockets", + "value_key": "events" + }, + { + "description": "", + "end": "2024-02-26T09:00:00-06:00", + "entity_id": "calendar.yap_house_schedules", + "start": "2024-02-26T08:00:00-06:00", + "summary": "Dr. Appt", + "value_key": "events" + }, + { + "description": "something good", + "end": "2024-02-28T21:00:00-06:00", + "entity_id": "calendar.yap_house_schedules", + "start": "2024-02-28T20:00:00-06:00", + "summary": "Bake a cake", + "value_key": "events" + } +] +``` + +### Example non-list action responses + +```json +{ + "vacuum.deebot_n8_plus_1": { + "header": { + "ver": "0.0.1", + }, + "payloadType": "j", + "resp": { + "body": { + "msg": "ok", + }, + }, + }, + "vacuum.deebot_n8_plus_2": { + "header": { + "ver": "0.0.1", + }, + "payloadType": "j", + "resp": { + "body": { + "msg": "ok", + }, + }, + }, +} +``` + +```yaml +{% raw %} +{{ merge_response(response_variable) }} +{% endraw %} +``` + +```json +[ + { + "entity_id": "vacuum.deebot_n8_plus_1", + "header": { + "ver": "0.0.1", + }, + "payloadType": "j", + "resp": { + "body": { + "msg": "ok", + }, + }, + }, + { + "entity_id": "vacuum.deebot_n8_plus_2", + "header": { + "ver": "0.0.1", + }, + "payloadType": "j", + "resp": { + "body": { + "msg": "ok", + }, + }, + }, +] +``` + ## Processing incoming data The other part of templating is processing incoming data. It allows you to modify incoming data and extract only the data you care about. This will only work for platforms and integrations that mention support for this in their documentation.