Moving templating Calendar.get_events

This has been a project I have been attempting for a couple days now. I have an automation that successfully uses calendar.get_events. However, to clean things up and make it more versatile in the future, I would like to template the get_events call along with checking a string against the list of events. Ideally I would like to pass in a calendar, as the entity_id, along with a string, and have it return true or false.

I have added the automation that currently works.

trigger:
  - platform: time
    at: "06:45:00"
condition: []
action:
  - service: calendar.get_events
    data:
      duration:
        hours: 24
        minutes: 0
        seconds: 0
    response_variable: cal_events
    target:
      entity_id:
        - calendar.bartley_events
  - if:
      - condition: or
        conditions:
          - condition: template
            value_template: |-
              {%- set fms = namespace(event=false) %}
              {%- for key, value in cal_events.items() %}
                {%- for event in value.events if 'No School' in event.summary %}
                  {%- set fms.event = true %}
                {%- endfor %}
              {%- endfor %}
              {{ fms.event }} 
          - condition: time
            weekday:
              - sat
              - sun
    then:
      - delay:
          hours: 1
          minutes: 15
          seconds: 0
          milliseconds: 0
      - service: script.heater_on_sequence
        data: {}
    else:
      - service: script.heater_on_sequence
        data: {}

I think you’re talking about something like:

alias: Calendar Content Check
sequence:
  - service: calendar.get_events
    data:
      start_date_time: "{{ now() }}"
      duration:
        hours: "{{ hours }}"
        minutes: 0
        seconds: 0
    response_variable: cal_events
    target:
      entity_id: "{{ calendars }}"
  - variables:
      c: |
        {%- set fms = namespace(event=false) %}
        {%- for key, value in cal_events.items() %}
          {%- for event in value.events if search_term in event[calendar_element] %}
            {%- set fms.event = true %}
          {%- endfor %}
        {%- endfor %}
        {{ {"match": fms.event} }}
  - stop: Respond with content match
    response_variable: c
mode: parallel
fields:
  calendars:
    selector:
      entity:
        multiple: true
        filter:
          - domain: calendar
    name: Calendars
    required: true
  search_term:
    selector:
      text: null
    name: Search Term
    default: No School
    required: true
  calendar_element:
    selector:
      select:
        options:
          - summary
          - description
          - location
    name: Calendar Element
    required: true
  hours:
    selector:
      number:
        min: 1
        max: 168
    name: Hours
    default: 24
    required: true

You would then call that as a service:

alias: zTest calendar content
sequence:
  - service: script.calendar_content_check
    data:
      search_term: No School
      hours: 24
      calendars:
        - calendar.bartly_events
      calendar_element: summary
    response_variable: "results"
  - if:
      - or: 
          - condition: template
            value_template: "{{ results.match }}"
          - condition: time
            weekday:
              - sat
              - sun
    then:
      - delay:
          hours: 1
          minutes: 15
          seconds: 0
          milliseconds: 0
      - service: script.heater_on_sequence
        data: {}
    else:
      - service: script.heater_on_sequence
        data: {}
mode: single

Though such an extended delay is not advised.

1 Like

The purpose of the delay in this specific case is because the wife and kids sleep in on none school days. The heater is out in the barn, and is only used for the duration while they are doing chores. Most days they will turn if off when complete. If they don’t, I have a step to turn it off after they should be done with chores.
I have have other automations I want to trigger at different times depending upon what is on the calendar, hence figuring out this script.

If there are better ways of having the trigger fire off at different times it I’m always willing to learn.

I’ve been trying to figure out how to do this kind of thing for months. I’d love to see this filtering capability built into the HA calendar integration as a core service. I slightly modified this to return all filtered matches as a list of date objects. I’m using this to determine my first meeting of the day, and enable/disable some automations depending on if I’m out of office or not.

alias: Search calendar
sequence:
  - service: calendar.get_events
    data:
      start_date_time: "{{ now() }}"
      duration:
        hours: "{{ days*24 }}"
        minutes: 0
        seconds: 0
    response_variable: cal_events
    target:
      entity_id: "{{ calendars }}"
  - variables:
      c: |
        {%- set fms = namespace(events=[]) %}
        {%- for key, value in cal_events.items() %}
          {%- for event in value.events if search_term in event["summary"] %}
            {%- set fms.events = fms.events + [event] %}
          {%- endfor %}
        {%- endfor %}
        {{ {"match": fms.events} }}
  - stop: Respond with content match
    response_variable: c
mode: parallel
fields:
  calendars:
    selector:
      entity:
        multiple: true
        filter:
          - domain: calendar
    name: Calendars
    required: true
  days:
    selector:
      number:
        min: 1
        max: 365
    name: Days
    default: 1
    required: true
  search_term:
    selector:
      text: null
    name: Search Term
    default: Busy
    required: true
icon: mdi:calendar