I use Google tasks for my To-do lists and one thing that it does not support that some other To-do lists do - like todoist - is recurring to-do’s based on completion date. I find those types of tasks usefull for things like home/automotive maintenance where you may complete the task before or after the scheduled date. I’ve only tested this with Google tasks but it should also work fine for other To-do lists as well.
I first create a To-do list specifically for this type of recurring tasks. The recurrance interval, in days, in embedded in the task summary between square braces, for example - “Check Subaru Oil [180]”. I originally was storing the interval in the description but that makes it more difficult if you want to use that field for actual task details.
It’s triggered by any state change (item count) in the list, and also triggers once per hour in case an item is created and then completed quickly before the To-do integration polls the list. It then gets the list of completed items, and loops through them, updating the due date to the current date + interval days, and the status to needs_action. It also adds a calendar entry with a checkmark so I can find any historical entries.
I’m sure it can be improved on but it’s working fine for my needs now. Hopefully others will find this simple automation useful:
alias: Recurring Todo List
description: ""
triggers:
- trigger: state
entity_id:
- todo.recurring
- trigger: time_pattern
hours: /1
conditions: []
actions:
- action: todo.get_items
data:
status:
- completed
target:
entity_id: todo.recurring
response_variable: mylist
- repeat:
sequence:
- action: todo.update_item
data:
item: "{{repeat.item.summary}}"
status: needs_action
due_date: >-
{{ (now() + timedelta(days=repeat.item.summary.split('[',
1)[1].split(']')[0]|int)).strftime('%Y-%m-%d')}}
target:
entity_id: todo.recurring
- action: calendar.create_event
target:
entity_id: calendar.google_calendar
data:
summary: ✔ {{repeat.item.summary.split('[', 1)[0]}}
description: event detail
start_date: "{{ now().strftime('%Y-%m-%d')}}"
end_date: "{{ (now() + timedelta(days=1)).strftime('%Y-%m-%d')}}"
for_each: "{{ mylist['todo.recurring']['items'] }}"
mode: single