Using google.add_event within the Google Calendar integration? Two issues

Goal: Create a calendar event 12 hours out from when my dishwasher finishes.

I think I have two issues here - so I’ll break this in two sections:

1. What I really need figured out:
Does the google.add_event accept template values for the start_date_time & end_date_time service data attributes? The docs do not specify, as far as I can tell. If so, how can I calculate X hours from the current time? I’m terrible at templating, and worse at math - but I’ve got this:

  • {{ now().strftime("%Y-%m-%d %H:%M:%S") }}

which gives me the current time of:

  • 2020-02-14 14:58:00

This appears to be the same date_time format as the service data is asking for (manually entered date_time, tested working example below), but I get an error if I put this template in the start and end fields.

calendar_id: [email protected]
summary: test
start_date_time: 2020-02-14 20:00:00
end_date_time: 2020-02-14 21:00:00

2. What I would settle on if the above can’t be done:
Assuming I can’t figure out how to use specific date_time values in the start_date_time and end_date_time service data attributes, what is the proper formatting for the in: service data attribute? I have tried the following, all create the same error (log below):

in: "days": 2                #this is how the git docs have it in their example
in: '"days": 2'              #this is how the HA auto-populates "fill example data"
Log Details (ERROR)
Fri Feb 14 2020 15:27:26 GMT-0500 (Eastern Standard Time)
expected a dictionary for dictionary value @ data['in']
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/websocket_api/commands.py", line 134, in handle_call_service
    connection.context(msg),
  File "/usr/src/homeassistant/homeassistant/core.py", line 1204, in async_call
    processed_data = handler.schema(service_data)
  File "/usr/local/lib/python3.7/site-packages/voluptuous/schema_builder.py", line 272, in __call__
    return self._compiled([], data)
  File "/usr/local/lib/python3.7/site-packages/voluptuous/schema_builder.py", line 594, in validate_dict
    return base_validate(path, iteritems(data), out)
  File "/usr/local/lib/python3.7/site-packages/voluptuous/schema_builder.py", line 432, in validate_mapping
    raise er.MultipleInvalid(errors)
voluptuous.error.MultipleInvalid: expected a dictionary for dictionary value @ data['in']

Looking at the code, start_date_time can only be a datetime string and “EVENT_IN” can only be a positive integer. Neither can be a template :frowning:

This seems odd though. Why would anyone use this service? What events are you adding with a fixed datetime???

What error do you get when using the template with start_date_time?

Right? This service is basically useless without templated values. In what scenario is a user going to manually enter a date time string??

When I call the service with this service data, I get a “voluptuous.error”. I get the same error if I remove the double quotes around the template, too. :thinking:

calendar_id: [email protected]
summary: States - Sensor Test
start_date_time: "{{ states('sensor.date_time') }}"
end_date_time: "{{ states('sensor.date_time') }}"
Log Details (ERROR)
Fri Feb 14 2020 20:00:31 GMT-0500 (Eastern Standard Time)
Invalid datetime specified: {{ states('sensor.date_time') }} for dictionary value @ data['start_date_time']
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/websocket_api/commands.py", line 134, in handle_call_service
    connection.context(msg),
  File "/usr/src/homeassistant/homeassistant/core.py", line 1204, in async_call
    processed_data = handler.schema(service_data)
  File "/usr/local/lib/python3.7/site-packages/voluptuous/schema_builder.py", line 272, in __call__
    return self._compiled([], data)
  File "/usr/local/lib/python3.7/site-packages/voluptuous/schema_builder.py", line 594, in validate_dict
    return base_validate(path, iteritems(data), out)
  File "/usr/local/lib/python3.7/site-packages/voluptuous/schema_builder.py", line 432, in validate_mapping
    raise er.MultipleInvalid(errors)
voluptuous.error.MultipleInvalid: Invalid datetime specified: {{ states('sensor.date_time') }} for dictionary value @ data['start_date_time']

Are script templates evaluated before calling a service? Could try a script. I can test this later…but just a random thought. I’m not sure when the variables passed into a script get evaluated. Maybe the don’t and it just passes the template straight through to the service. That would be lame.

script:
  create_calendar_event:
    sequence:
      # This is Home Assistant Script Syntax
      - service: google.add_event
        data:
          calendar_id: [email protected]
          summary: "{{ summary }}"
          start_date_time: "{{ start_date}}"
          end_date_time: "{{ end_date }}"

Now try calling the script from services tab?

service: script.create_calendar_event
data_template: 
  summary: "My Summary"
  start_date: "{{ states('sensor.date_time') }}"
  end_date: "{{ states('sensor.date_time') }}"

Thanks Jim - I think I’m at my knowledge limit here :slight_smile: I’m not sure I understand this part of the script:

          start_date_time: {{ start_date}}
          end_date_time: {{ end_date }}

If you would be willing to test, that would be great! I’m starting to think we’ll discover additional lameness…

With scripts, you can pass in variables as data.

Check out below where I call the script. I pass in 3 variables which are exactly named the same as the values in the script wrapped around {{ }}

Ok, I think you were trying to use templates in the service tag in the gui. I don’t think those work…I was getting the same error as you. It doesn’t accept a data_template, only data.

I just created this automation to test it out…

- alias: Google Calendar Test

  trigger:
    platform: state
    entity_id: media_player.49_tcl_roku_tv
    to: 'invalid'
  action:
    service: google.add_event
    data_template:
      calendar_id: [email protected]
      summary: "Automation Test"
      start_date_time: "{{ now().strftime('%Y-%m-%d %H:%M:%S') }}"
      end_date_time: "{{ now().strftime('%Y-%m-%d %H:%M:%S') }}"

I created a trigger with some dummy entity_id and state that wont ever happen.

Then I called “service: automation.trigger” on this automation to skip the trigger. It added it to my calendar.

So, looks like I was wrong. It seems to accept templates just fine. Just not in the service tab gui.

Jim - you’ve done it, thank you so much! It’s kind of odd the service tab GUI doesn’t accept templates…I did not know that!

So, the other part of my question, now that we’ve you’ve got this portion working - is how to add a certain number of hours to now()?

as_timestamp will give you the current time in seconds (offset from a fixed value in jan 1 1970)

So just add that many seconds to it. Then convert it back to the timestamp string using timestamp_local

{% set hours = 1.5 %}
# Convert hours into seconds by multiplying by 60s/m * 60m/h
{{ (as_timestamp(now()) + (hours | float)*60*60) | timestamp_local }}

Replace hours with whatever sensor you want.

If you want it aligned on hour boundaries, might have to round the number to the nearest hour/half hour, whatever you want before converting to timestamp_local

1 Like

Thanks Jim - works perfectly.

Because this is the first search result when looking for more information on the in: service data attribute, I wanted to answer the question about how to use the attribute. Here’s how it should look:

automation:
...
  action:
    - service: google.add_event
      data:
        calendar_id: [email protected]
        summary: test
        in:
          days: 2

Note that in: creates an all-day event.

Thank you for posting this! It’s exactly what I needed. I had never been able to get it to work based on the documentation. Their use of quotation marks around “days” was confusing because they hadn’t used them anywhere else, so I thought they had to be there. Even using the Dev tools and filling the service call with the example data didn’t shed any light. Thanks for clearing it up!

I think this thread has my answer in it, but I’m stumbling @jocnnor.

service: google.create_event
data:
  summary: Took Morning Meds
  description: Took Morning Meds
  start_date_time: "{{ now().strftime('%Y-%m-%d %H:%M:%S') }}"
  end_date_time: {{ (as_timestamp(now()) + ( 1.5% | float)*60*60) | timestamp_local }}
target:
  entity_id: calendar.morgan_c_simmons

I’m trying to make this action - and I would like a single hour long event starting at the time that it’s triggered.

I’m just not sure how to enter the end date so it’s an hour later.

Any help will be greatly appreciated.