PowerTodoist card for Home Assistant Lovelace UI. This card displays items from selected Todoist projects. This project uses the Todoist API but it is not created by, affiliated with, or supported by Doist.
https://github.com/pgorod/power-todoist-card/assets/15945027/d049b00a-d406-4b7c-8803-92695d88b1b2
This card is available in HACS (Home Assistant Community Store).
Just search for PowerTodoist Card
in the HACS list or click the badge below:
powertodoist-card.js
file from the latest release.powertodoist-card.js
file into your config/www
folder.powertodoist-card.js
in Lovelace. There are two ways to do that:
/local/powertodoist-card.js
→ Set Resource type as JavaScript Module
.lovelace
section.
resources:
- url: /local/powertodoist-card.js
type: module
custom:powertodoist-card
to Lovelace UI as any other card (using either editor or YAML configuration).This card can be configured using Lovelace UI editor.
Add the following code to configuration.yaml
:
sensor:
- name: To-do List
platform: rest
method: GET
resource: 'https://api.todoist.com/sync/v9/projects/get_data'
params:
project_id: TODOIST_PROJECT_ID
headers:
Authorization: !secret todoist_api_token
value_template: '{{ value_json[''project''][''id''] }}'
json_attributes:
- project
- items
- sections
- project_notes
scan_interval: 30
command_line:
- sensor:
name: label_colors
command: !secret todoist_cmd_with_api_token
value_template: >
{{ value_json.label_colors | length }}
json_attributes:
- label_colors
scan_interval: 200
rest_command:
todoist:
method: post
url: 'https://api.todoist.com/sync/v9/{{ url }}'
payload: '{{ payload }}'
headers:
Authorization: !secret todoist_api_token
content_type: 'application/x-www-form-urlencoded'
👉 The REST command and the label_colors
sensor are constant and need to be defined only once for each Todoist account used (I recommend using only one and handling any content separation with cleverly filtered projects, sections, and labels).
👉 The Sensor definition, on the other hand, can be cloned to allow for different projects, just make sure you set a unique entity name, and set the appropriate TODOIST_PROJECT_ID
for each one (see below).
configuration.yaml
, replace TODOIST_PROJECT_ID
with ID of your selected Todoist project.
You can get
TODOIST_PROJECT_ID
from project URL after logging in to your Todoist account in a browser. It usually looks like this:https://todoist.com/app/project/**TODOIST_PROJECT_ID**
orhttps://todoist.com/app/project/name_of_project-**TODOIST_PROJECT_ID**
secrets.yaml
:
todoist_api_token: 'Bearer TODOIST_API_TOKEN'
todoist_cmd_with_api_token: 'echo "{\"label_colors\":" $(curl -s https://api.todoist.com/rest/v2/labels -H "Accept: application/json" -H "Authorization: Bearer TODOIST_API_TOKEN") "}" '
secrets.yaml
, replace two instances of TODOIST_API_TOKEN
with your private API Token (click Developer
tab on that page).entity
.A basic example of using this card in YAML config could look like this:
type: 'custom:powertodoist-card'
entity: sensor.to_do_list
show_header: true
show_completed: 5
use_quick_add: true
Note that the to_do_list
entity name is what Home Assistant created based on the name: To-do List
you specified earlier in the sensor definition.
Spaces and hyphens turned into _
, and everything became lowercase. In case of doubt search your entities in HASS for the correct name.
Name | Type | Default | Description |
---|---|---|---|
type |
string |
required | custom:todoist-card |
entity |
string |
required | An entity_id within the sensor domain. |
show_completed |
integer |
5 |
Number of completed tasks shown at the end of the list (0 to disable). |
show_header |
boolean |
true |
Show friendly name of the selected sensor in the card header. |
show_item_add |
boolean |
true |
Show text input element for adding new items to the list. |
show_item_close |
boolean |
true |
Show close/complete and uncomplete buttons. |
show_item_delete |
boolean |
true |
Show delete buttons. |
show_item_labels |
boolean |
true |
Show item-level labels beneath each item (see filter_labels below). |
show_card_labels |
boolean |
true |
Show card-level labels on top (see filter_labels below). |
show_dates |
boolean |
false |
Show due dates on the labels row. |
use_quick_add |
boolean |
false |
Use the Quick Add implementation, available in the official Todoist clients. Note that Power-Todoist will automatically add your card's project tag, and your filter_section , if specified. |
sort_by_due_date |
string |
(none) | Sort the tasks by their due date. If it is undefined, or 'false' , no sorting occurs. If it is set to 'ascending' , it sorts oldest due dates first. Any other string (I suggest using 'descending' ) will sort older dates last. |
friendly_name |
string |
Todoist |
The card name shown on top uses a somewhat elaborate logic: the default is Todoist , if no name is specified. But if a Section filter is specified, then that section name will be used instead. Finally, if you do use the friendly_name option, it will override anything else. |
icons |
list |
A list of 4 icon names from the MDI Library, without the mdi: prefix. Icons will be used for the check mark of checkable items, the bullet of uncheckable items, the plus sign to add items, and the trash can to delete. Defaults as shown are ["checkbox-marked-circle-outline", "circle-medium", "plus-outline", "trash-can-outline"] |
|
filter_section_id |
integer |
(none) |
Only show tasks from one Todoist section, identified by its id. |
filter_section |
string |
(none) |
Only show tasks from one Todoist section, identified by its name. |
filter_labels |
list |
(none) |
Only show tasks with the specified Todoist labels. See Filtering by Labels below for details on this powerful option. |
filter_show_dates_starting filter_show_dates_ending |
integer or string |
(none) |
Only show tasks with the specified dates window. See Filtering by Dates below for details. |
filter_show_dates_empty |
boolean |
true |
Defines whether tasks without any specified date pass the filter or not. See Filtering by Dates below for details. |
Note that the completed tasks list is cleared when the page is refreshed.
Labels are colorful and beautiful. And useful! Define them in Todoist app, and don't forget to pick your favorite colors there - after some time, they will be picked up by PowerTodoist-card!
The filter_labels
option allows for several possibilities.
!
then it will exclude items with that label.*
to include items with any label (but not items without any labels at all).!*
to include items without any labels at all.Label Filter examples | Meaning |
---|---|
filter_labels: - "Blue" - "Green" |
Shows items with either a Green or a Blue label, or both. |
filter_labels: - "!Done" |
Shows items that don't have a Done label. |
filter_labels: - "!Hidden" - "%user%" - "Important" |
Shows items that don't have the Hidden label, and that either have the Important label or a label with the current HASS user name. |
filter_labels: - "For%user%" |
Shows items that have a label composed of the letters For and the current user name. For example, if user is called Joe then a label ForJoe would match. |
When you filter by a single label, that label won't appear graphically under each item; instead, it will appear on the top, next to the list name.
The options governing date filters are very powerful but also quite hard to understand. I believe this is due to inherent ambiguities in the ways we think and talk about time. Things get swapped if we think about a condition from the pespective of the task that has a due date, or from the threshold that we specified for the comparison. And we want to specify relative times (3 hours before), but relative to what? And time moves. And when we say a "within a day" we might mean two things: any time tomorrow, or strictly up to 24 hours from now, but not 25...
So, please bear with me and try to get into my term definitions. I promise I will provide a few simple, ready to use examples in the end, if the complexity is too much for you.
Basic notions:
Date Filter explanations and examples | Meaning |
---|---|
filter_show_dates_starting |
Defines the start of the dates window, which moves forward expiring tasks out of the view. If you use a number (like -8 or 24 ) it is interpreted as a number of hours. If you use a string like "1" it is interpreted as a number of days.If you omit this setting it won't filter anything, so tasks won't expire by date. |
filter_show_dates_ending |
Defines the end of the dates window, which moves forward bringing new tasks into the view. If you use a number (like -8 or 24 ) it is interpreted as a number of hours. If you use a string like "1" it is interpreted as a number of days.If you omit this setting it won't filter anything, so all future tasks will be visible. |
filter_show_dates_starting: 0 (without any defined filter_show_dates_ending ) |
This is a special case that I use to work with event durations. If the event does not have duration, it simply appears in view when the date arrives, and stays there. But if it has a duration defined (through the API), then it will appear when the date arrives, and expire after the duration ends. This way you can actually specify two moments in a single task, defining exact times for it to show and then disappear. |
filter_show_dates_ending: "0" |
Show items due Today, or already overdue |
filter_show_dates_ending: "5" |
Show items coming Due anytime in the next 5 days. |
Basic behaviour is this:
Enter
.But with this card, almost everything is programmable :-), so in the configurations you can optionally create lists of custom actions to run when the user does something. These action lists use the following headers according to the user event:
User Event | Triggered by | Default actions (if no custom actions are specified) |
---|---|---|
actions_close | A tap on the close button (checking a task as done) | Close (complete) the task as done in Todoist. |
actions_dbl_close | A double-tap on the close button (checking a task as done) | Nothing |
actions_content | A tap on the content (text) of the task | Open dialog box to update the text of the task. |
actions_dbl_content | A double-tap on the content (text) of the task | Nothing |
actions_description | A tap on the desciption text of the task, if it is defined in Todoist. | Open dialog box to update the description of the task. |
actions_dbl_description | A double-tap on the desciption text of the task, if it is defined in Todoist. | Nothing |
actions_label | A tap on any of the task's labels (currently it is not possible to differentiate taps on different labels). | Nothing |
actions_dbl_label | A double-tap on any of the task's labels (currently it is not possible to differentiate taps on different labels). | Nothing |
actions_delete | A tap on the delete button to the right of the task. | Delete the task in Todoist. |
actions_dbl_delete | A double-tap on the delete button to the right of the task. | Nothing |
actions_uncomplete | A tap on the task uncomplete button on a recently completed task (shown at the bottom). | Undo the task completion of a recently completed task. |
actions_dbl_uncomplete | A double-tap on the task uncomplete button on a recently completed task (shown at the bottom). | Nothing |
actions_yourActionName | Not really a user event, but rather a way to add your own "sub-routines" (as many as you want). Just give them unique names such as action_domystuff and list any desired actions inside.The way to call these subroutines from other places is by using the match action (see below). So a typical flow would be a user event such as action_close includes a match action, which then conditionally triggers action_domystuff . |
Nothing |
Under those headers, you can use a list of actions to specify custom behaviours. Your options for the actions are:
Custom Action | What it does |
---|---|
close |
Closes (completes) the item in Todoist. |
delete |
Deletes the item in Todoist. |
move |
Moves the item in Todoist to the next section. If it's currently in the last section, item will be moved to the special "(No section)" section. |
confirm |
Opens a dialog box asking the user to confirm the action. If the user approves, action continues, otherwise it is cancelled. Specify an optional string for a custom confirmation text. |
toast |
Flashes a message for a few seconds giving some information to the user. |
update |
Sets new values to the item's fields in Todoist. This is a list which allows all Todoist field types: content , description , priority , collapsed , assigned_by_uid , responsible_uid , day_order You can use variables here. One of the variables can be %input% which will cause the user to be prompted for the value. use prompt_texts to control the dialog box displayed. |
prompt_texts |
Not really an action, but you can use this to set a couple of strings to be used in other actions. Use two strings separated by the \| character. The first will be the dialog box title, the second will be the default value presented in the input box. The variable %content% will be useful here to show the current value. So, for example, "Insert new name:\|%content%" will set the prompt for an update action that references %input% , asking the user to give a new name, showing the current name in the input box, so it can be easily edited. |
service |
Calls the specified service in Home Assistant. This is very powerful, you can use it to trigger automations and scripts! It is the action that contains a thousand possibilities! 🚀 And this is what makes the PowerTodoist card really a Home Assistant thing - not just an interface to your Todoist. Examples: service: automation.notify_me or service: script.do_it_all |
label |
Here label is a verb! You use this action to label the current item as you prefer. Use a list of label names. If you prefix a label name with a ! that label will be removed, instead of added. Use !* to clear all labels, !_ to clear all labels starting with underscore, !! to clear all labels except those starting with underscore. |
add |
A list of texts that will be sent as Quick Add to Todoist. More details about the syntax below. Remember to specify Project, section and labels, as necessary to match your filters and ensure the new item is visible where you want it. |
allow |
A list of user names that will be allowed to execute all the actions in the handling of the current event. To allow everyone, simply don't use this option. |
match |
A list of triplets that describe conditions. Each triplet looks like this: [field, value, action_domystuff] .The field is one of the item fields as listed here. The value will be matched to that field (simple fields get simple comparisons, while array fields test if the value is included in the array). If there is a match, then the custom action gets executed. This is a very powerful way of creating conditions to invoke subroutines when handling an event, allowing you to do different things for different users, or according to some label on the item. Note that not everything is tested, and not everything will work, there are many scenarios and data types, and I am not building a full programming language here... but even the basic usage will prove very useful. |
emphasis |
Temporarily adds a CSS class to the item. For example, emphasis: special will add a CSS class called powertodoist-special . This class has to be defined in the card's code, which currently is a bit static and only has that specific "special" class. Later I can try to generalize this a bit. |
The items in this Actions table must always appear below a user Event from the previous table, like this:
- actions_delete
- confirm
- delete
Actions are executed in the order given. If you include a list of actions for an event, the default actions won't be executed unless you specify them explicitly.
This feature is undergoing a major re-factoring and might not work perfectly well in all places. But the general idea is that you can use these in any configuration option and they will get substituted, if the value is available (makes sense in that context). In case of doubt, just try it and see how it goes.
Variable name | Text that will be substituted |
---|---|
%was% |
Previous value |
%input% |
Value returned from a prompt shown to the user. The prompt can be customized with prompt_texts action. |
%line% |
A new line character. Allows breaking lines in places where it would be difficult to add a new line in YAML. |
%user% |
The current Home Assistant user name. This is also super powerful to build multi-user systems. You can create separate lists per user, and you can use labels with user names to move things from one to the other. Note that this is not the Todoist user names; it is meant for use with a single Todoist user, the trick is to use labels or sections to separate tasks by HASS users. |
%date% |
The current date, formatted as specified by the date_format option. Default format is "mmm dd H:mm" Complete formatting options are documented here. |
%str_labels% |
The current items labels, all concatenated as a comma-separated string. |
%project_notes% |
In Todoist, you can add notes at the Project level, not just at the item level. You can access the first of these notes with this variable. You can also use %project_notes_2% , %project_notes_3% , etc, to access the other notes. |
Let me know if you have other ideas for variables that could prove useful.
👉 Have a look at this demo file: https://github.com/pgorod/power-todoist-card/blob/main/todoist_demo.yaml
RESTful command: todoist
(internally, rest_command.todoist
which you defined in configuration.yaml
). service: rest_command.todoist
data:
url: quick/add
payload: "text=Auto created at ({{ now().strftime('%H:%M') }}) #myproject @mylabel"
You can use the full power of Todoist's Quick add feature that will parse the text of the task to be created. It can include...
To get this right, I suggest you try your text first directly in the Todoist app, before moving it into the HASS automation.
You can also use the power of Home Assistant's templating language enclosed in {{ }}
brackets, as my example shows.
You can use as many of these cards as you want in your dashboards, of course. But I find that this looks particularly cool, and works in a particularly functional way, if you combine this card with the HACS Swipe card. Just have a card for each Todoist section, and put them all together in a Swipe card, to get the feeling of a Kanban. Use the move
action to move items to the next card.
Or use one card per user (family member) for home tasks that you want everyone to be able to see. You can check everybody's progress by swiping sideways. I even like to use a final card which is a Markdown card with home rules or instructions for the use of the Task list.
This project is licensed under the MIT license.
Copyright for portions of project PowerTodoist-card are held by Konstantin Grinkevich as part of project Todoist-card. All other copyright for project PowerTodoist-card is held by pgorod
That was a lot of work 😅! If you enjoy and use this card, I'd appreciate it if you can sponsor my work. I'm actually trying to make a living from Github sponsorships, mostly from other projects, but Home Assistant users are numerous, every small donation will also help! Thanks, I really appreciate it!
Note that you pick a one-time amount and select any value you want.