Just wanted to share how I extract unfinished tasks from Google Tasks

I’ve recently moved from the HACS gtasks integration to the official integration with Google Tasks now that Home Assistant supports due dates.

This should probably work with any todo lists that have due_dates, used on a pixel clock as a long string but could probably be edited to display on a screen through ESPHome or anything else with a physical display.

The reason I’m sharing is because I spent more than a few hours muddling through trying to get it working and hoping it helps anyone else.

  - service: todo.get_items
    target:
      entity_id: todo.to_do
    data:
      status:
        - needs_action
    response_variable: mylist
    continue_on_error: true
  - service: esphome.pixelclock_text_screen
    data:
      default_font: false
      text: |-
        {% for items in mylist['todo.to_do']['items'] -%}
          {% if "due" in items and items.due <= states('sensor.date') -%}
            {{"~"}} {{ items.summary }} {{" "}}
          {%- endif %}
        {%- endfor %}
      lifetime: 1
      screen_time: 3
      r: 255
      g: 128
      b: 128
    continue_on_error: true
3 Likes

Thanks for sharing. Could I tweak what you have done to create a template that returns a count of the ToDo list items that have a due_date equal to today’s date?

Currently working on a template to get a better list for a sensor:

I posted the gist here: Home Assistant configuration.yaml to pull todo data · GitHub

But you could probbaly change the first one to:

          today: >
            {%- set todo_today_counter = namespace(total = 0) %}
            {%- set todo_today = namespace(todo = []) %}
            {%- for items in mylist["todo.to_do"]["items"] %}
              {%- if "due" in items and items.due <= states('sensor.date') %}
                {%- set todo_today.todo = todo_today.todo + [(items.summary)] %}
                {%- set todo_today_counter.total = todo_today_counter.total + 1 %}
              {%- endif %}
            {%- endfor %}
            {{todo_today_counter.total}}
1 Like

Thank you.
I’m trying to use the counter as a boolean value_template in an automation.

Is the namespace(total = 0) a way of specifying the type for the variable?

action:
  - service: todo.get_items
    target:
      entity_id: todo.tasks
    data:
      status: needs_action
    response_variable: todo_items
  - if:
      - condition: template
        value_template: |-
          {% set todo_today_counter = namespace(total = 0) %}
          {% for item in todo_items["todo.tasks"]["items"] %}
          {% if "due" in item and item.due <= states('sensor.date') %}
          {% set todo_today_counter.total = todo_today_counter.total + 1 %}
          {% endif %}
          {% endfor %}
          {% if todo_today_counter.total > 0 %}true{% else %}false{% endif %}
    then:

No. In my attempts to avoid using the namespace, the value was reset to 0 when exiting the ‘for’ loop.

BTW, if you’d like to avoid doing the entire loop you can probably add an ‘if’ in the loop to check for the value and then {break} the loop. You’re only checking if there’s 1 or more right?

If you’d like to experiment with the template, here’s a great guide on how to use the “new” way of getting a starting variable that will match what ends up in your yaml: Debugging templates and service response_variables

Thank you. The if and break is a sensible idea. :man_facepalming:

So that little thing turned into this:

The template yaml has much better examples hwo to extract data from todo lists.

2 Likes

Hi darkpoet78,

I’m working on a little project to help me in the mornings. I have adhd, get distracted and with little kids that need to go to school every morning i need some help so im working on a todo list in my living area which will come up every morning with all the regular and one time tasks for the morning (there is way bigger explanation about my project in the link below)

I really want to use google tasks at the back bone of the list as i work with google apps for mail, calendar, drive etc.

so now i have a problem: the standard todo-list card from HA doesn’t have enough options to limit/filter my google tasks as i like and i cant find any card on HACS which does the job properly for google tasks.

I have been looking at your code for inspiration because (as i understand correctly) you are able to filter the tasks you want into a “new” list/sensor. as i cannot find a card that does the job i would like to try it like you have managed it for your project.

but then my problem: I’m self thought and I’m quite a noob concerning everything that isn’t the frontend and i dont really understand the cade (at all).

I’m here:
do i understand correctly you configured a “sensor” in your template.yaml? added the template.yaml to configuration.yaml? and the theory is the sensor requests the tasks that fit your filter in your code into a new list every 15 mins?

in theory, if i understand how to make the sensor, i should be able to get a configure a todolist in HA frontend exactly the way i like.

sorry for the long message, im hoping you can point me in the right direction on the architecture/flow of it all, as you seem to understand what your doing xD

link to my project plan
https://www.reddit.com/r/homeassistant/comments/1h1u8u6/project_dashboard_with_taskschecklists_adhd_tool/?utm_source=share&utm_medium=web3x&utm_name=web3xcss&utm_term=1&utm_content=share_button

Yup, you’ve got it right. It steps through multiple lists searching for today’s date and then adds them as attribute today of the sensor.eink_tasksboard_data sensor then does the same thing for upcoming starting with tomorrow, the next day, etc. On the second run, it extracts those 2 attributes into more attributes like today_0 and upcoming_0 so that the ESPHome device can read it more cleanly.

If I remember, I think it’s actually set to run every 3 minutes (so 6 minutes to fully populate)… but Home Assistant syncs with Google Tasks far less often.

In the YAML file, you should see ways to use different lists. I’m pretty sure Google Tasks and Home Assistant’s native Todo lists work in the same way.

By the way, a big part of how I organize my lists is with https://fullscreen-for-googletasks.com/ - makes it a bit easier to set dates for tasks than trying to deal with Google’s calendar integration. At some point, I’ll probably just end up using Home Assistant’s native lists anyway since it has due dates.

Addition: This could be a rabbit hole but I know for a fact that you can actually make automations that add and delete tasks (based on name so they better have the same name).

First, need this script (no editing required):

alias: "To-do: Item exists"
sequence:
  - target:
      entity_id: "{{ list }}"
    response_variable: todo
    action: todo.get_items
  - variables:
      result: >
        {% set x = (item in todo[list]['items'] | map(attribute='summary')) %}
        {% set item = todo[list]['items'] | selectattr('summary', 'eq', item) |
        list | first | default([]) %} {{ {'exists': x, 'item': item} }}
  - stop: Finished
    response_variable: result
mode: single
icon: mdi:checkbox-marked-circle-auto-outline
fields:
  item:
    selector:
      text: null
    name: Item
    description: The todo item to check
    required: true
  list:
    selector:
      entity:
        filter:
          - integration: todo
    name: List
    required: true
    description: The todo list entity

I use this automation to add devices with low batteries to my todo.to_do list (actually a Google Task list):

alias: Battery Actions
description: ""
mode: queued
max: 10
triggers:
  - type: battery_level
    device_id: 6c243272196f29f225e06c71dac7e8e5
    entity_id: 769104ac11666f0ef74a4bee2556ee0e
    domain: sensor
    below: 10
    trigger: device
  - entity_id:
      - sensor.zb_laundry_sensor_temperature
    to: unavailable
    for:
      hours: 1
      minutes: 0
      seconds: 0
    enabled: false
    trigger: state
  - entity_id:
      - binary_sensor.rf_motion_1_battery_warning
      - binary_sensor.rf_motion_2_battery_warning
    to: "on"
    enabled: false
    trigger: state
conditions: []
actions:
  - data:
      item: "{{ trigger.from_state.attributes.friendly_name }}"
      list: todo.to_do
    response_variable: result
    action: script.to_do_item_exists
  - if:
      - condition: template
        value_template: "{{ result.exists == true }}"
    then:
      - metadata: {}
        data:
          item: "{{ trigger.from_state.attributes.friendly_name }}"
        target:
          entity_id: todo.to_do
        action: todo.remove_item
  - metadata: {}
    data:
      item: "{{ trigger.from_state.attributes.friendly_name }}"
      due_date: >-
        {{ (as_timestamp(now()) + (0*3600)) | timestamp_custom('%Y-%m-%d', True)
        }}
    target:
      entity_id: todo.to_do
    action: todo.add_item

I keep thinking I should use kind of thing to make repeatable tasks… press a physical button and have it delete that task, re-add it with a due date of tomorrow.

Oh and I think that timestamp weirdness might have to with UTC? I can’t honestly remember what’s up with that. I feel like it was adding it with yesterday’s date but I can’t remember… haha. But it’s definitely there for a reason and it’s not to add it with tomorrow’s date.