To do list automation error - from calendar

Greetings folks,

I have tried to create an automation using the service call:

todo.add_item

and keep running into an error:

Error while executing automation automation.to_do_list: extra keys not allowed @ data[‘title’]

Here is the *test automation:

alias: "To-Do List"
trigger:
  - platform: time_pattern
    minutes: "/1"
action:
  - service: todo.add_item
    data_template:
      entity_id: todo.bills
      title: "Test Task"
      status: "pending"

Any thoughts on what is causing this? Am I totally missing something?

i think the issue is exactly what the error says. :slight_smile: you have an extra key. that’s not allowed. ‘title’
perhaps you mean ‘item’ instead of title?

btw, “data_template” is phasing out. can just use ‘data’

1 Like

Thank you, that was helpful. I also had to change a few additional variables:

item, description, and due_date

I ended up using a template sensor like this:

template:
  - trigger:
      - hours: /1
    action:
      - service: calendar.get_events
        data:
          duration:
            hours: 336
            minutes: 0
            seconds: 0
          start_date_time: "{{ today_at() }}"
        target:
          entity_id: calendar.bills
        response_variable: raw_events
      - variables:
          scheduled_events: "{{ raw_events['calendar.bills'] }}"
    sensor:
      - name: Calendar Scheduled Events
        unique_id: calendar_scheduled_events
        state: "{{ scheduled_events.events | count() }}"
        attributes:
          scheduled_events: "{{ scheduled_events.events }}"
        icon: mdi:calendar'

Then inputting that as a variable in the automation like this:

alias: To-Do List from Cal
description: "Creates to-do list items from calendar events"
trigger:
  - platform: time_pattern
    hours: /23
    minutes: "59"
    seconds: "59"
action:
  - variables:
      scheduled_events: "{{ state_attr('sensor.calendar_scheduled_events', 'scheduled_events') }}"
  - repeat:
      count: "{{ scheduled_events | count }}"
      sequence:
        - service: todo.add_item
          data:
            entity_id: todo.bills
            item: |
              {{ scheduled_events[repeat.index - 1].summary }}
            description: |
              {{ scheduled_events[repeat.index - 1].description }}
            due_date: |
              {{ scheduled_events[repeat.index - 1].start }}

Using the following, or something similar, I would like it to only add items which do not exist already to the list, to avoid duplicates.

alias: To-Do List from Cal
description: "Creates to-do list items from calendar events"
trigger:
  - platform: time_pattern
    hours: /23
    minutes: "59"
    seconds: "59"
action:
  - variables:
      scheduled_events: "{{ state_attr('sensor.calendar_scheduled_events', 'scheduled_events') }}"
  - repeat:
      count: "{{ scheduled_events | count }}"
      sequence:
        - service: todo.add_item
          data:
            entity_id: todo.bills
            item: |
              {{ scheduled_events[repeat.index - 1].summary }}
            description: |
              {{ scheduled_events[repeat.index - 1].description }}
            due_date: |
              {{ scheduled_events[repeat.index - 1].start }}

hey @Spr0ckEt i think you would be best off to start a new thread for this questoin, as i think it’s a completely diff question. that may also get attention from other folks who are particularly good at this sort of stuff.

to your specific question, what key do you want to use to identify duplicates? matching summary?

1 Like

Instead of using a counted Repeat, use a Repeat for Each. The for_each value can be templated as long as it returns a simple object.

alias: To-Do List from Cal
description: "Creates to-do list items from calendar events"
trigger:
  - platform: time_pattern
    hours: /23
    minutes: "59"
    seconds: "59"
action:
  - service: todo.get_items
    target:
      entity_id: todo.bills
    data:
      status: needs_action
    response_variable: bills_list
  - variables:
      current_bills: "{{ bills_list['todo.bills']['items'] | map(attribute='summary') | list }}"
      scheduled_events: "{{ state_attr('sensor.calendar_scheduled_events', 'scheduled_events') }}"
  - repeat:
      for_each: |
        {{ scheduled_events | rejectattr('summary', 'in', current_bills) | list }}
      sequence:
        - service: todo.add_item
          data:
            entity_id: todo.bills
            item: |
              {{ repeat.item['summary'] }}
            description: |
              {{ repeat.item['description'] }}
            due_date: |
              {{ repeat.item['start'] }}
1 Like

Using your edits, I made a couple more. Now it works just as intended! It gets the items from the template sensor.calendar_scheduled_events, and filters out ones which are already on the to-do list (even completed ones) before adding them.

alias: To-Do List from Cal
description: "Creates to-do list items from calendar events"
trigger:
  - platform: time_pattern
    hours: /23
    minutes: "59"
    seconds: "59"
action:
  - service: todo.get_items
    target:
      entity_id: todo.bills
    data: {}
    response_variable: bills_list
  - variables:
      current_bills: "{{ bills_list['todo.bills']['items'] | map(attribute='summary') | map('lower') | map('trim') | list }}"
      scheduled_events: "{{ state_attr('sensor.calendar_scheduled_events', 'scheduled_events') }}"
  - repeat:
      for_each: "{{ scheduled_events }}"
      sequence:
        - condition: template
          value_template: >
            {{ repeat.item['summary'] | lower | trim not in current_bills }}
        - service: todo.add_item
          data:
            entity_id: todo.bills
            item: "{{ repeat.item['summary'] }}"
            description: "{{ repeat.item['description'] }}"
            due_date: "{{ repeat.item['start'] }}"
1 Like

I added conditional logic to filter ‘summary’ and ‘description’

alias: To-Do List from Cal
description: "Creates to-do list items from calendar events"
trigger:
  - platform: time_pattern
    hours: /23
    minutes: "59"
    seconds: "59"
action:
  - service: todo.get_items
    target:
      entity_id: todo.bills
    data: {}
    response_variable: bills_list
  - variables:
      current_bills: "{{ bills_list['todo.bills']['items'] }}"
      scheduled_events: "{{ state_attr('sensor.calendar_scheduled_events', 'scheduled_events') }}"
  - repeat:
      for_each: "{{ scheduled_events }}"
      sequence:
        - condition: template
          value_template: >-
            {% set summary_exists = current_bills | map(attribute='summary') | map('lower') | map('trim') | list %}
            {% set description_exists = current_bills | map(attribute='description') | map('default', '', true) | map('lower') | map('trim') | list %}
            {% set summary = repeat.item.summary | lower | trim %}
            {% set description = repeat.item.description | default('', true) | lower | trim %}
            {% if summary not in summary_exists or description not in description_exists %}
              true
            {% else %}
              false
            {% endif %}
        - service: todo.add_item
          data:
            entity_id: todo.bills
            item: "{{ repeat.item['summary'] }}"
            description: "{{ repeat.item['description'] }}"
            due_date: "{{ repeat.item['start'] }}"

1 Like