Calendar.get_events response variable in developer-tools > template

I would like to suggest a feature that’d allow users to work with the response variable from calendar.get_events in developer-tools > template.

Let’s say I run this service


service: calendar.get_events
data:
  start_date_time: "{{ today_at() - timedelta(days=2) }}"
  end_date_time: "{{ now() }}"
target:
  entity_id: calendar.test123

Then I’ll receive this data

calendar.test123:
  events:
    - start: "2024-05-20T06:20:59+02:00"
      end: "2024-05-20T06:40:59+02:00"
      summary:This is
      description: ""
    - start: "2024-05-21T12:54:22+02:00"
      end: "2024-05-21T13:14:22+02:00"
      summary: a test
      description: ""
    - start: "2024-05-21T15:01:46+02:00"
      end: "2024-05-21T15:21:46+02:00"
      summary: remember to hoard potatoes for the next potatoe famine 
      description: ""

Currently, there is no way to work with this data straight away. Perhaps, Home Assistant could store the most recent calendar.get_events response variable, so that it would automatically be available for jinja2 testing in template.

For example, whatever the last manual service call (via developer-tools > service) returns could be saved to last_response.

Then, one could use it like

{% set events = last_response['calendar.test123']['events']
          | selectattr('summary', 'contains', 'potatoe') | list %}
          {{ (today_at() - (events | selectattr("summary", "contains", "potate")
          | sort(attribute='start', reverse=1) | first)['start']|as_datetime|as_local).days | default(0, 1) }}

Or did I miss something and this is possible already? I find it quite difficult to query the calendar (in fact, the code snippet above was 99% from this community, I just adapted it to my needs), and being able to have this data (= whatever the service calls returns) available in template would make things so much more simple.

This already exists.

See: https://www.home-assistant.io/integrations/calendar#service-calendarget_events

All you have to do is adjust your service call to this:

service: calendar.get_events
data:
  start_date_time: "{{ today_at() - timedelta(days=2) }}"
  end_date_time: "{{ now() }}"
target:
  entity_id: calendar.test123
response_variable: agenda  ### <------ Add this

Then use the data in the variable agenda in your template.

{% set events = agenda['calendar.test123']['events']
          | selectattr('summary', 'contains', 'potatoe') | list %}
          {{ (today_at() - (events | selectattr("summary", "contains", "potate")
          | sort(attribute='start', reverse=1) | first)['start']|as_datetime|as_local).days | default(0, 1) }}

Sorry, either I have explained this incorrectly, or the existing solution doesn’t work for me for some reason.

I went to developer-tools/service and ran the service as described by you (including response_variable: agenda.

Then I went to developer-tools/template and used the code as posted by you. All I get is UndefinedError: 'agenda' is undefined.

I am aware that I can use the response_variable within my scripts or templates. For example, the template below will work just fine


  - trigger:
      - platform: time_pattern
        minutes: /5
      - platform: homeassistant
        event: start
    action:
      - service: calendar.get_events
        data:
          start_date_time: "{{ today_at() - timedelta(days=60) }}"
          end_date_time: "{{ now() }}"
        target:
          entity_id: calendar.rudel
        response_variable: agenda
    sensor:
      - name: Mal drinnen
        state: |
          {% set events = agenda['calendar.rudel']['events']
          | selectattr('summary', 'contains', 'drinnen') | list %}
          {{ (today_at() - (events | selectattr("summary", "contains", "drinnen")
          | sort(attribute='start', reverse=1) | first)['start']|as_datetime|as_local).days | default(0, 1) }}

But what I’d like to do is manually get these calendar events via SERVICE call, then work on that response within TEMPLATE. So that before I create a template sensor (in this case in a dedicated yaml file), I can see what this template would actually return and/or whether or not my jinja2 code works.

The template editor cant call services. Thus agenda is not defined in the template editor. The way around this is to define it in the editor yourself manually.

{% set agenda = <your data here> %}

{{ <your template that includes the agenda variable to test here> }}

You can copy the data from the services tool into the template editor that way.

I understand that.

But then my feature request is valid: I would like to suggest that the most recent response_variable content will be saved to some pre-defined variable.

This could even work if one does not add response_variable in their service call at all.

Let’s say I make a service call without adding respone_variable; the contents could still be saved to (just to have a name) most_recent_response; and this could be available within Home Assistant, for instance, to use in the template editor.

Yes, one can copy and paste the data. But especially with complex responses, like the calendar.get_events reply, this isn’t easy, as you can see in the screenshots below.

I, as a hobbyist without professional programming knowledge, was not able to figure this out. Usually, I’d google something like “jinja2 multi line variable” or “multi line string jinja2”, but I didn’t find a solution.

I will keep looking later and I’m sure this can be achieved somehow.

But still, this isn’t simple copy&paste that anybody could “just do” while testing things. If Home Assistant were to provide this data whenever one executed a service call that returns anything other than an empty string, this data could be used right away.

(yeah, this isn’t a feature anybody’s live depends on; but I thought anything that makes the users’ experience a bit more simple might be worth suggesting)

1 Like

I want to second this request. I’ve run into the exact situation that @prankousky is having several times now, I want to use the output of the calendar.get_events in the Template editor.

Having some way for the response_variable to be available would make this trivially easy. And this would apply broadly to any service that sends response data.

@prankousky also pointed out another issue that I think may be worth solving. How does one make a multi-line variable in the Template editor? Addressing this could be a viable workaround for this feature request. I just want to get the response data in the Template tab to test with.

The output in the services tab is typical YAML. But I have not been successful in getting this data to be usable in the Template editor. To my knowledge, there’s no simple way to save the YAML as a variable, and have the YAML be preserved. The issue is repeatable: run calendar.get_services, copy the output, save it to a variable in Template tab, and then try to make a template that pulls out a specific bit of info.

A question I’d like to pose to anyone is how is one supposed to test services that produce response data? Right now, I have make an automation that and use a notification service that has my template in it. Adjust the template, manually trigger the automation, look at the notification. It’s a cumbersome process.

1 Like

This would turn the Template editor into something much more than it currently is. Ability to run service calls could be dangerous.

Workaround method to achieve what you want:

Call the service via Developer Tools / Service:

service: calendar.get_events
target:
  entity_id: calendar.xxx_district_council
data:
  start_date_time: 2024-06-22T20:00:00.000Z
  end_date_time: 2024-07-22T22:00:00.000Z

Copy the response YAML from below:

calendar.xxx_district_council:
  events:
    - start: "2024-06-26"
      end: "2024-06-27"
      summary: Brown Bin
    - start: "2024-06-26"
      end: "2024-06-27"
      summary: Blue Bin
    - start: "2024-06-26"
      end: "2024-06-27"
      summary: Blue Sack

Paste into a YAML-to-JSON converter like this one; and copy the JSON.

Paste into the template tool like this (using whatever variable name you want):

{% set value_json = 
{
  "calendar.xxx_district_council": {
    "events": [
      {
        "start": "2024-06-26",
        "end": "2024-06-27",
        "summary": "Brown Bin"
      },
      {
        "start": "2024-06-26",
        "end": "2024-06-27",
        "summary": "Blue Bin"
      },
      {
        "start": "2024-06-26",
        "end": "2024-06-27",
        "summary": "Blue Sack"
      }
    ]
  }
}
%}

It would be nice to have a JSON view of the YAML on the Services screen to avoid the external step.

3 Likes

Weren’t the responses originally in JSON, then users asked to have them in YAML…?

:laughing:

Maybe we can convince them to just add a “Copy as JSON” button next to the “Copy to Clipboard” button.

2 Likes