第 16 章

待辦清單與行事曆

把「記得倒垃圾」「這個月要繳管理費」「冷氣濾網該洗了」從腦袋裡搬進 Home Assistant。這一章教你做出全家共用的待辦清單、本地行事曆,還有讓行事曆上的一格事件自己去開燈、發通知、生出一條待辦。

為什麼要學這個

你家現在的情況大概是這樣:媽媽在冰箱門上貼便利貼、你在手機備忘錄記東西、爸爸把繳費單塞在鞋櫃上。三個地方,三份資料,最後全部忘記。

Home Assistant 內建兩種東西可以收掉這個混亂:

  • 待辦清單(To-do list)—— 一堆「要做但還沒做」的事,可以打勾,可以設到期日。購物清單就是它的一種。
  • 行事曆(Calendar)—— 有明確時間的事件,垃圾車幾點來、會議幾點開、下週三要繳費。

把它們搬進 HA 最大的好處不是「看得到」,而是它們能當自動化的原料。行事曆上寫「倒垃圾 19:30」,HA 就能在 19:10 把玄關燈打開、推播到你手機;待辦清單被人加了東西,HA 就能通知全家。這是紙本便利貼永遠做不到的。

觀念:這一章是第 7 章(通知)第 8 章(第一個自動化)的延伸。第 8 章教你「觸發 → 條件 → 動作」的三段式,這一章只是換了新的觸發來源(行事曆事件、待辦項目變動)和新的動作(todo 這個 domain)。三段式的心法完全不變,沒看過的話建議先回去補。

讀完這章你會有:一份全家共用的購物清單、一份本地行事曆、至少三條「行事曆一到時間就自己動」的自動化,以及一張儀表板上看得到今天要做什麼的頁面。

待辦清單 vs 行事曆:什麼時候用哪個

很多人一開始會把兩個搞混,把「倒垃圾」放進待辦清單,然後發現它不會自己提醒。判斷方法很簡單:這件事有沒有「幾點幾分」?

問題待辦清單(todo)行事曆(calendar)
核心資料一條一條的「項目」,有/沒有打勾一格一格的「事件」,有開始與結束時間
時間可以設「到期日」,但沒有精確時刻概念時間是主角,精確到分鐘
實體狀態數字:目前還沒完成的項目數量on(現在正在某個事件中)或 off
典型內容買醬油、換濾網、繳水費倒垃圾 19:30、會議 14:00–15:00、家事輪值
怎麼觸發自動化項目被新增/完成/移除時事件開始或結束時(可以提前)
提示:兩個一起用最強。行事曆負責「什麼時候提醒」,待辦清單負責「還沒做完的東西堆在這裡」。本章後面的冷氣濾網情境就是這樣搭:行事曆時間到 → 自動塞一條待辦進清單。

還有一個名詞要先講清楚:領域(Domain)。HA 把實體依照類型分成 lightswitchsensor 這些領域,待辦清單的領域叫 todo,行事曆的領域叫 calendar。所以你之後會看到 todo.shopping_listcalendar.trash_day 這種實體 ID。領域圖鑑在第 12 章

注意:下面所有範例的實體 ID(像 todo.family_chores)都是示意。你自己建立的清單,實體 ID 會依你打的名稱自動產生,中文名稱產生的 ID 可能長得完全不一樣。動手前先去設定 → 工具 → 狀態(這區在 2026.8 之前叫「開發者工具」,在側邊欄)把真正的 ID 抄下來。命名與 entity_id 的規矩在第 4 章

動手一:建立第一份本地待辦清單

我們要用的整合叫 Local To-do(本地待辦清單)。「本地」的意思是資料完全存在你自己的 HA 裡,不上任何雲端,斷網也能用,也會跟著第 9 章的備份一起被帶走。

  1. 打開整合頁

    左邊側欄按 設定 → 裝置與服務,確認在最上面的「整合」分頁。

  2. 新增整合

    右下角的 「+ 新增整合」按鈕按下去,在搜尋框打「Local」或「待辦」,選 Local to-do(本地待辦清單)。這個整合是 Home Assistant 2023.11 加進來的,版本太舊會找不到。

    從整合頁新增 Local To-do
    圖 16-1設定 → 裝置與服務 → 右下角「新增整合」,搜尋 Local To-do 即可。
  3. 只要填一個欄位:清單名稱

    這個整合的設定畫面非常乾淨,只問你一件事——這份清單要叫什麼。打「家務」或「購物」都可以。按送出,清單就生出來了。

  4. 想要幾份就再做幾次

    Local To-do 一次只建一份清單。想要「家務」「購物」「爸媽交代」三份,就重複第 2~3 步三次。每一份都會變成一個獨立的 todo. 實體。

  5. 去側欄找「待辦清單」面板

    建好之後,HA 左邊側欄會出現一個待辦清單的專屬面板。點進去就能直接打字新增項目、打勾完成、設到期日。這個面板是 HA 內建的,不用你自己做儀表板。

    待辦清單面板
    圖 16-2側欄的「待辦清單」面板:左欄列出所有清單,右邊直接打字新增項目、打勾完成。
  6. 確認實體 ID

    設定 → 工具 → 狀態,在篩選框打 todo.,你會看到剛剛建的清單。狀態欄的那個數字,就是這份清單目前還沒完成的項目數量。把實體 ID 抄下來,後面自動化要用。

觀念:清單裡的每個項目最多可以帶四種資料:名稱(必填)、到期日描述(比名稱長的補充說明)、狀態(未完成 / 已完成)。不是每個整合都支援全部四種,Local To-do 支援得算完整。

購物清單(Shopping List)該用哪一個

HA 另外有一個叫 Shopping list(購物清單)的整合,年紀比 Local To-do 大很多。新手常問:這兩個到底差在哪、要用哪個?

Shopping listLocal to-do
能建幾份清單只有一份,固定的購物清單要幾份建幾份
到期日沒有
語音助理官方文件明講可以用「Add eggs to my shopping list」這類語音指令加東西語音支援要看你的語音助理設定
專屬動作有一整組 shopping_list.* 舊動作沒有專屬動作,只用通用的 todo.*
通用 todo.* 動作可以用(它也是 todo 實體)可以用

兩個整合目前都還在官方文件裡、都沒有被標記淘汰。建議這樣選:

  • 你只是想要一份買菜清單,而且很想用語音喊「加醬油到購物清單」 → 裝 Shopping list。
  • 你想要多份清單、想要到期日、想寫比較複雜的自動化 → 用 Local to-do。
  • 兩個都裝也完全沒問題,它們互不干擾。

Shopping list 有它自己的一組動作,這裡列出來讓你看得懂別人的舊教學,但寫新的自動化請一律用下一節的 todo.*,因為那組動作對所有待辦清單都通用:

shopping_list.add_item
shopping_list.complete_item
shopping_list.incomplete_item
shopping_list.remove_item
shopping_list.complete_all
shopping_list.incomplete_all
shopping_list.clear_completed_items
shopping_list.sort
提示:Shopping list 裝好之後同樣會產生一個 todo. 開頭的實體,所以你可以把它放進待辦清單卡片,也可以用 todo.add_item 對它下指令。它「是」一份待辦清單,只是多了一組專屬的舊動作而已。

todo 這個 domain 的動作速查

先講一個很重要的用詞更新:以前 HA 叫「服務(Service)」、YAML 裡寫 service:現在一律叫「動作(Action)」、YAML 裡寫 action:。你在網路上看到 service: todo.add_item 的教學,那是舊寫法。

動作做什麼主要參數
todo.add_item新增一個項目item(必填)、due_datedue_datetimedescription
todo.update_item改一個項目:改名、打勾、改到期日item(必填,名稱或 UID)、renamestatusdue_datedue_datetimedescription
todo.remove_item把一個項目整條刪掉item
todo.get_items讀出清單內容給後面的步驟用status,搭配 response_variable
todo.remove_completed_items一次清掉所有已完成的項目只要指定清單,沒有其他參數

新增一個項目

action: todo.add_item
target:
  entity_id: todo.family_chores
data:
  item: 換客廳冷氣濾網
  due_date: "2026-09-01"
  description: 拆下來用水沖乾淨,陰乾一天再裝回去
注意:due_date(只有日期,如 2026-09-01)和 due_datetime(日期加時間,如 2026-09-01 23:00:00只能二選一,不能同時寫,寫兩個會直接報錯。另外,到期日和描述這兩個欄位不是每種清單都支援,只有支援的清單才吃得下去。

把項目打勾(標記完成)

action: todo.update_item
target:
  entity_id: todo.family_chores
data:
  item: 換客廳冷氣濾網
  status: completed

status 只吃兩個值:needs_action(還沒做)和 completed(做完了)。想把做完的事「反悔」變回未完成,就把 status 改成 needs_action

注意:item 是用名稱去找的。如果你清單裡有兩個一模一樣叫「買牛奶」的項目,HA 不知道你要改哪一個。這時要改用項目的 UID(一長串亂碼般的唯一編號),UID 可以用下面的 todo.get_items 撈出來。

讀出清單內容

這個動作跟其他的不一樣,它會回傳資料,所以要搭配 response_variable 把結果存進一個變數:

action: todo.get_items
target:
  entity_id: todo.family_chores
data:
  status: needs_action
response_variable: my_items

status 不寫的話預設是 needs_action;要一次抓全部就寫成清單 [needs_action, completed]。回傳的資料長這樣:

todo.family_chores:
  items:
    - summary: 換客廳冷氣濾網
      uid: "01244b28-e604-11ee-a0a4-e45f0197c057"
      status: needs_action
      due: "2026-09-01"
      description: 拆下來用水沖乾淨
    - summary: 繳管理費
      uid: "ae993df4-e604-11ee-a0a4-e45f0197c057"
      status: needs_action

注意每個項目的欄位名稱:summary(不是 item)、uidstatus,另外還有兩個選配的 due(到期日)和 description

注意:看上面第二個項目——沒設到期日和描述的項目,那兩個欄位是整個不見的,不是留一個空值在那裡。這是寫範本最容易爆掉的地方:你以為每個項目都有 due 可以拿,結果某一項根本沒有這個欄位,範本就整條掛掉。所以下面繳費日那個範例,第一關一定要先用 selectattr('due', 'defined') 把沒有這個欄位的項目挑掉。

用待辦清單的變動當觸發

比較新的 HA 版本幫 todo 加了三個專屬觸發,在自動化編輯器裡選觸發時可以找到:

觸發什麼時候會跳拿來做什麼
todo.item_added清單被加進新項目有人加東西到購物清單,通知全家
todo.item_completed項目被打勾小孩把「倒垃圾」打勾了,通知家長
todo.item_removed項目被刪掉稽核用,看誰把東西刪了

YAML 寫法跟一般觸發不太一樣,它用 target: 而不是直接寫 entity_id:

alias: 購物清單有人加東西就通知
triggers:
  - trigger: todo.item_added
    target:
      entity_id: todo.shopping_list
actions:
  - action: notify.mobile_app_my_phone
    data:
      title: 購物清單更新
      message: 有人加了新東西,出門前記得看一下

觸發時可以拿到的資料是清單的 entity_id 和被影響的項目 ID(item_ids。想知道到底加了什麼名字,通常要在動作裡再呼叫一次 todo.get_items 去查。

注意:這三個觸發是比較新的功能。如果你的自動化編輯器裡找不到它們,代表你的 HA 版本還沒有,請先升級;不想升級的話,退而求其次的做法是用「狀態(State)」觸發去監看那個 todo. 實體的數字變化——因為清單狀態就是未完成項目數,加一項數字就 +1。
提示:如果你不確定自己這版有沒有,最快的驗證法是:新增一個自動化 → 加入觸發 → 在搜尋框打「to-do」或「待辦」。有就會跳出來,沒有就是沒有。這比查版本號快。

動手二:建立本地行事曆

接下來換行事曆。跟 Local To-do 一樣,官方有一個完全在地端跑的 Local Calendar(本地行事曆),是 Home Assistant 2022.12 加入的整合,資料存在你自己的 HA 設定目錄裡,不需要任何帳號、任何雲端。

  1. 新增整合

    設定 → 裝置與服務 → + 新增整合,搜尋 Local calendar(本地行事曆)。

  2. 取一個行事曆名稱

    照畫面指示填入行事曆名稱。建議依用途分開建,不要全部塞一個:「倒垃圾」「家事輪值」「繳費」「家具保養」各建一個。理由在下一步。

  3. 為什麼要分開建:因為觸發是綁「整個行事曆」的

    行事曆觸發沒辦法說「只有標題含某字才觸發」——它是這個行事曆任何事件開始就跳。所以把不同用途分成不同行事曆,自動化才乾淨。(真的想在同一個行事曆內分辨,就在自動化裡加條件去比對 trigger.calendar_event.summary。)

  4. 去側欄的「行事曆」面板加事件

    建好之後左邊側欄會有行事曆面板。點某一天就能新增事件,可以設全天事件、設起訖時間,也可以設重複(每週、每月之類)。倒垃圾這種每週固定的,就設成重複事件,設一次用一整年。

    行事曆面板
    圖 16-3側欄的「行事曆」面板:左欄勾選要顯示哪些行事曆,右邊點某一天即可新增/編輯事件。
  5. 確認實體 ID 與狀態

    設定 → 工具 → 狀態,篩選 calendar.。行事曆實體的狀態只有兩種:on 代表現在正好在某個事件進行中,off 代表沒有。

觀念:不要用「行事曆實體是不是 on」來做提醒,因為它一次只表達得了一個事件,而且無法提前。要提醒就用下一節的行事曆觸發,那個才有 offset(提前多久)可以設。

行事曆事件也可以用自動化自己生出來,這在「訂了餐廳就順手記進行事曆」這種情境很好用:

action: calendar.create_event
target:
  entity_id: calendar.family
data:
  summary: 家庭聚餐
  start_date_time: "2026-09-20 18:00:00"
  end_date_time: "2026-09-20 20:00:00"
  location: 阿嬤家

summary(標題)是唯一必填的。時間有三種指定方式,三選一

寫法用在哪範例
start_date_time + end_date_time有明確時刻的事件"2026-09-20 18:00:00"
start_date + end_date整天事件"2026-09-20"
in(含 daysweeks「幾天/幾週後」,不用算日期in: {days: 90}

接 Google Calendar 與 CalDAV

本地行事曆的缺點很明顯:手機上看不到。如果你全家已經在用 Google 日曆,把它接進 HA 會方便很多——在手機 Google 日曆上新增一格「倒垃圾」,HA 那邊就吃得到。

Google Calendar

老實說,這是這一章最麻煩的一步,而且麻煩不在 HA 這邊,是在 Google 那邊。HA 官方文件明講:你必須自己去 Google Cloud 開一個專案、啟用 Google Calendar API、產生一組 OAuth 用戶端憑證(Client ID 和 Client Secret),再把這組憑證貼回 HA。沒有捷徑,HA 不提供公用憑證。

危險:Client ID 和 Client Secret 等於你 Google 專案的鑰匙。絕對不要貼到論壇、Discord、YouTube 留言區或任何截圖裡。真的貼出去了,馬上回 Google Cloud Console 把那組憑證刪掉重建。
注意:這是最多人踩的坑。在 Google Cloud 設定「OAuth 同意畫面」時,如果發布狀態停在 Testing(測試中),官方文件明確警告:你的憑證每 7 天就會過期,HA 每週都會斷線一次要你重新授權。解法是在同意畫面那頁按 Publish app(發布應用程式),把狀態改掉。

接好之後,你 Google 帳號「我的日曆」底下每一個日曆,都會變成一個 calendar. 實體。它也提供一個專屬動作 google.create_event 用來新增事件。

提示:因為 Google 這條路要繳的「設定稅」不低,我的建議是:先用 Local Calendar 把整章跑一遍,把自動化寫熟、確定這套東西你真的會用,再回頭花那 20 分鐘串 Google。串接方式換掉,自動化的寫法完全不用改,因為兩邊都是 calendar. 實體。

CalDAV(Nextcloud、iCloud、Synology…)

如果你用的是 Nextcloud、Baikal、ownCloud、Synology Calendar 或 Apple iCloud,走 CalDAV 這個標準協定。官方文件說明,只要符合 RFC 4791 的伺服器基本上都能接。

設定方式怎麼做能不能拿到待辦清單
介面設定(建議)設定 → 裝置與服務 → 新增整合 → CalDAV可以,會產生 todo 實體
手動寫 YAML編輯 configuration.yaml不行,官方文件明講 YAML 這條路不支援待辦清單

主要欄位有 url(你日曆的完整網址)、usernamepassword,另外還有 calendars / custom_calendars 可以只挑特定日曆,以及 verify_ssl(預設 true,自簽憑證的自架伺服器才需要關掉)。還有一個 days(預設 1)決定往後抓幾天的事件,它只在 custom_calendars 底下才有用,很多人寫在外層然後納悶為什麼沒效果。

注意:接 iCloud 的話,官方文件建議使用 App 專用密碼(app-specific password),不要把 Apple 帳號的主密碼交給 HA。這是安全問題,也是很多人 iCloud 接不上的原因——主密碼配上兩階段驗證本來就會被擋。

Google Tasks(待辦清單,不是行事曆)

順帶一提,Google 的待辦事項也有官方整合叫 Google Tasks(Home Assistant 2023.11 加入),會把你的 Google 工作清單變成 todo. 實體。有兩個限制要先知道:

  • 只支援到期「日」,不支援到期「時間」——這是 Google Tasks API 本身的限制,不是 HA 的問題。
  • 它是輪詢(polling)的,官方文件寫的更新週期是每 30 分鐘。你在手機 Google Tasks 上加一項,HA 這邊不會立刻看到,要等下一次抓取。
提示:這個 30 分鐘的延遲只有「Google → HA」這個方向。官方文件明講,你在 HA 這邊做的變更會立刻反映到 Google Tasks。所以「用自動化往清單塞東西、然後在手機上看」是即時的,反過來「在手機上加、等 HA 觸發自動化」才要等。寫自動化的時候把這件事放在心上,可以少踩很多坑。

設定方式跟 Google Calendar 一樣要自建 Google Cloud 憑證,只是要啟用的是 Google Tasks API。

把清單和行事曆放上儀表板

側欄的內建面板已經很好用,但如果你想做一頁「早上起床看一眼就知道今天要幹嘛」的儀表板,就要用卡片。儀表板編輯的基本操作在第 6 章,這裡只講這兩張卡。

  1. 進入編輯模式

    打開你的儀表板,右上角鉛筆圖示進入編輯模式,然後按「+ 新增卡片」

  2. 加待辦清單卡片

    在卡片清單裡找 To-do list(待辦清單),選你的 todo. 實體。

  3. 加行事曆卡片

    再新增一張,找 Calendar(行事曆)。這張卡可以一次選好幾個行事曆疊在一起顯示,不同行事曆會用不同顏色區分。

  4. 用 YAML 微調

    卡片編輯視窗左下角有「顯示程式碼編輯器」,切過去就能貼下面的設定。

待辦清單卡片

type: todo-list
entity: todo.family_chores
title: 這週家務
hide_completed: true
display_order: duedate_asc
選項說明可填的值
entity要顯示哪份清單(必填)某個 todo. 實體
title卡片標題任意文字
hide_completed把已完成那一區藏起來true / false(預設 false)
hide_create藏掉最上面那個「新增項目」輸入框true / false(預設 false)
hide_section_headers藏掉「未完成/已完成」那兩排小標題true / false(預設 false)
display_order排序方式none(預設)、alpha_ascalpha_descduedate_ascduedate_desc
item_tap_action點一個項目時發生什麼事edit(預設,打開編輯視窗)、toggle(直接打勾/取消勾)
due_date_period只顯示某個時間範圍內到期的項目底下用 calendar,含 perioddayweekmonthyear)和選配的 offset
theme這張卡單獨換佈景任何已載入的佈景名稱
提示:做一張「只能看不能改」的牆上平板顯示卡,就把 hide_createtruehide_completedtrue,畫面會非常清爽。反過來,如果是給自己在手機上快速打勾用,把 item_tap_action 設成 toggle,點一下就打勾,不用再開編輯視窗按兩次。

另外一個很好用但常被忽略的是 due_date_period:它讓卡片只顯示「這個範圍內到期」的項目。想做一張「今天要做的事」的卡,就這樣寫:

type: todo-list
entity: todo.family_chores
title: 今天要做
hide_completed: true
due_date_period:
  calendar:
    period: day

period 換成 week 就變成「這週要做的事」。offset 是往前或往後推幾個週期,例如 period: weekoffset: 1 就是下一週。

行事曆卡片

type: calendar
title: 這個月
entities:
  - calendar.trash_day
  - calendar.family_chores
  - calendar.bills
initial_view: listWeek
選項說明可填的值
entities要顯示的行事曆清單(必填)一個以上的 calendar. 實體
title卡片標題任意文字
initial_view載入時預設顯示哪種檢視dayGridMonth(月曆格)、dayGridDay(單日)、listWeek(條列)
theme這張卡單獨換佈景任何已載入的佈景名稱
提示:手機上看,dayGridMonth(月曆格)字會小到看不清楚。牆上平板用月曆、手機用 listWeek 條列,體感差很多。
注意:listWeek 這個名字很容易誤會。官方文件說明它顯示的是接下來 7 天,不是「本週的週一到週日」。所以星期五打開它,看到的是週五到下週四,不會在週日晚上突然清空。這其實正是你要的行為,但第一次看到「怎麼跨到下禮拜了」不用緊張。

用行事曆事件觸發自動化

這是整章最有價值的一節。行事曆觸發的完整寫法就這幾行:

triggers:
  - trigger: calendar
    entity_id: calendar.trash_day
    event: start
    offset: "-00:20:00"
欄位意思
entity_id要盯哪個行事曆
eventstart(事件開始)或 end(事件結束)
offset時間偏移。格式是 "時:分:秒"前面加負號代表提前,不加負號代表延後。上面那個 -00:20:00 就是「事件開始前 20 分鐘」
注意:一定要知道的限制。官方文件寫得很清楚:行事曆是每 15 分鐘讀取一次的。這代表兩件事:(1) 你剛剛在手機上新增一個 5 分鐘後開始的事件,那次觸發很可能來不及跳;(2) 別把 offset 設成 -00:02:00 這種太貼身的值,實務上抓 10 分鐘以上比較保險。要拿來當精準鬧鐘請用「時間(Time)」觸發。

事件的內容可以直接拿來用

觸發之後,那格事件的資料會放在 trigger.calendar_event 底下,可以直接寫進通知訊息:

變數內容
trigger.calendar_event.summary事件標題
trigger.calendar_event.description事件的詳細說明(有填才有)
trigger.calendar_event.location地點(有填才有)
trigger.calendar_event.start開始時間的文字,例如 2026-04-102026-04-10 11:30:00-07:00
trigger.calendar_event.end結束時間的文字
trigger.calendar_event.all_day是不是整天事件

整天事件的 start 只有日期沒有時間,有時間的事件則會帶時區。想從裡面取出日期部分,最簡單的寫法是切前 10 個字:{{ trigger.calendar_event.start[:10] }}

提示:不確定範本寫出來是什麼字,別在自動化裡瞎猜。去設定 → 工具 → 範本那一頁貼上去試跑,那裡會即時顯示結果。這招在整個 HA 都適用,能省下你一半的除錯時間。

六個馬上能抄的實用情境

下面每一段都可以直接貼進自動化編輯器的 YAML 模式(右上角三個點 → 編輯 YAML)。記得把實體 ID 換成你自己的。

一、倒垃圾日提醒

先在 Local Calendar 建一個叫「倒垃圾」的行事曆,把垃圾車時間設成每週重複事件。

alias: 垃圾車快到了
triggers:
  - trigger: calendar
    entity_id: calendar.trash_day
    event: start
    offset: "-00:20:00"
actions:
  - action: notify.mobile_app_my_phone
    data:
      title: 20 分鐘後垃圾車
      message: "{{ trigger.calendar_event.summary }}|袋子拿了嗎"
  - action: light.turn_on
    target:
      entity_id: light.entrance
    data:
      brightness_pct: 80
mode: single

玄關燈亮起來這一招比推播更有用——推播會被忽略,但走過去看到燈亮著會想起來。

二、繳費日:到期日一到就提醒

這個情境用待辦清單而不是行事曆,因為繳費是「還沒做完就一直存在」的事。做法是每天早上八點掃一次清單,看有沒有今天到期的:

alias: 今天到期的待辦提醒
triggers:
  - trigger: time
    at: "08:00:00"
actions:
  - action: todo.get_items
    target:
      entity_id: todo.family_chores
    data:
      status: needs_action
    response_variable: result
  - variables:
      today: "{{ now().date() | string }}"
      due_today: >-
        {{ result['todo.family_chores']['items']
           | selectattr('due', 'defined')
           | rejectattr('due', 'none')
           | selectattr('due', 'search', today)
           | map(attribute='summary') | list }}
  - if:
      - condition: template
        value_template: "{{ due_today | count > 0 }}"
    then:
      - action: notify.mobile_app_my_phone
        data:
          title: 今天有 {{ due_today | count }} 件事到期
          message: "{{ due_today | join('、') }}"
mode: single

中間那三行過濾是整段的關鍵,一行一個任務:selectattr('due', 'defined') 先把「連 due 這個欄位都沒有」的項目挑掉,rejectattr('due', 'none') 再把有欄位但值是空的挑掉,最後 selectattr('due', 'search', today) 才留下到期日字串裡含今天日期的。少了前兩關,只要清單裡有一項沒設到期日,整條自動化就會報範本錯誤。

注意:不同來源的清單,due 撈出來可能是純文字(2026-09-01),也可能是帶時間的形式,過濾寫法會受影響。先去設定 → 工具 → 範本把這段貼上去試跑,看印出來是不是你要的名字,再貼進自動化,不要直接上線。

三、冷氣濾網更換:行事曆生出待辦

經典的「行事曆 + 待辦」組合技。行事曆負責記時間週期,時間一到就自動塞一條待辦進清單,你什麼時候有空什麼時候做,做完打勾:

alias: 保養行事曆自動生待辦
triggers:
  - trigger: calendar
    entity_id: calendar.maintenance
    event: start
actions:
  - action: todo.add_item
    target:
      entity_id: todo.family_chores
    data:
      item: "{{ trigger.calendar_event.summary }}"
      due_date: "{{ trigger.calendar_event.start[:10] }}"
      description: "{{ trigger.calendar_event.description }}"
mode: queued
max: 10

在「保養」行事曆裡設幾個每三個月重複的整天事件:「洗客廳冷氣濾網」「換淨水器濾芯」「清洗洗衣機」。設一次,之後每季自動出現在待辦清單裡。

提示:mode: queuedmax: 10 是為了應付「同一天有好幾個保養事件同時開始」的狀況。用預設的 single,第二個事件會被直接丟掉。執行模式的完整說明在第 10 章

四、家事輪值

在「家事輪值」行事曆裡,把事件標題直接寫成「這週輪到小明洗碗」,然後:

alias: 家事輪值提醒
triggers:
  - trigger: calendar
    entity_id: calendar.chore_rotation
    event: start
    offset: "-01:00:00"
actions:
  - action: todo.add_item
    target:
      entity_id: todo.family_chores
    data:
      item: "{{ trigger.calendar_event.summary }}"
  - action: notify.family_all
    data:
      title: 家事輪值
      message: "一小時後:{{ trigger.calendar_event.summary }}"
mode: queued
max: 10

notify.family_all 是把全家手機打包成一個通知群組的做法,設定方式在第 7 章

五、辦公室會議室:一格事件管燈跟冷氣

小型辦公室最實用的一條。把會議室預約行事曆接進 HA(Google Calendar 或 CalDAV 都可以),開會前十分鐘先把燈跟冷氣打開,散會就關掉:

alias: 會議室隨預約開關
triggers:
  - trigger: calendar
    id: meeting_start
    entity_id: calendar.meeting_room
    event: start
    offset: "-00:10:00"
  - trigger: calendar
    id: meeting_end
    entity_id: calendar.meeting_room
    event: end
actions:
  - choose:
      - conditions:
          - condition: trigger
            id: meeting_start
        sequence:
          - action: light.turn_on
            target:
              entity_id: light.meeting_room
          - action: climate.turn_on
            target:
              entity_id: climate.meeting_room
      - conditions:
          - condition: trigger
            id: meeting_end
        sequence:
          - action: light.turn_off
            target:
              entity_id: light.meeting_room
          - action: climate.turn_off
            target:
              entity_id: climate.meeting_room
mode: queued
max: 10

這裡示範了一個好習慣:一條自動化用 id 區分多個觸發,再用 choose 分岔,比拆成兩條分開維護清楚。冷氣如果不吃 climate.turn_on,改用 climate.set_hvac_mode,各 domain 的控制方式看第 12 章

六、每週把打勾的清掉

alias: 週日晚上清空已完成
triggers:
  - trigger: time
    at: "22:00:00"
conditions:
  - condition: time
    weekday:
      - sun
actions:
  - action: todo.remove_completed_items
    target:
      entity_id: todo.family_chores
mode: single
危險:todo.remove_completed_items真的刪掉,不會進回收桶。如果你有「想回頭看這個月做了哪些事」的需求,先別排這條自動化,或者改成一個月清一次。

串起通知與語音助理

通知:讓提醒真的被看到

上面所有情境的最後一哩路都是通知,而通知的完整設定(Companion App 安裝、notify.mobile_app_* 實體名稱怎麼查、通知群組)在第 7 章,這裡不重複。只補三個跟待辦/行事曆特別搭的技巧:

  • 把事件標題直接放進訊息——用 {{ trigger.calendar_event.summary }},一條自動化就能服務行事曆上所有事件,不用一個事件寫一條。
  • 加條件避免半夜吵人——在 conditions: 加時間條件,或加「有人在家」的條件。整天在外面的時候收到「垃圾車來了」只會讓人想關通知。
  • 通知不只手機——會議室情境裡,把燈閃兩下或用語音播報,比推播有效得多。

語音:用喊的加購物清單

語音助理是這一章的天然搭檔——手上沾著油、冰箱門開著的時候,喊一句比掏手機快多了。這部分的重點:

  • Shopping list 整合的官方文件明確提到可以用語音指令加東西,例句是英文的「Add eggs to my shopping list」。
  • 中文句型不保證開箱即用。HA 的內建語音句型各語言的完整度不一樣,你的版本、你的語音助理設定都會影響結果。想確認自己這套行不行,最快的方法是打開 HA 右上角的 Assist 對話框,直接打字(不用講)試一句,看它有沒有反應。
  • 如果內建句型不吃你想講的話,退路是自訂句子(custom sentences),把你習慣的講法對應到 todo.add_item。設定方式請看語音助理那一章。
提示:語音辨識出來的中文常常有錯字,「醬油」變「醬遊」很正常。所以購物清單類的自動化不要去比對項目名稱做判斷,把名字當成「給人看的字串」就好,判斷交給數量或狀態。

常見卡關

  1. Google 授權每 7 天就掉一次,一直叫我重新登入

    這幾乎百分之百是 OAuth 同意畫面停在 Testing(測試中)。官方文件明確警告這個狀態下憑證每 7 天過期。回 Google Cloud Console 的 OAuth 同意畫面,按 Publish app 把發布狀態改掉,再回 HA 重新授權一次。改完之後就不會再掉了。

  2. Google 授權當下就失敗,跳「redirect_uri_mismatch」或類似錯誤

    意思是你在 Google 那邊登記的重新導向網址,跟 HA 實際送出的對不起來。照官方文件指定的重新導向網址一字不差填進 Google 憑證設定,中英文大小寫、結尾有沒有斜線都算數。另外檢查有沒有把 Google Calendar API 啟用——很多人建了憑證卻忘了啟用 API。

  3. 事件時間整個差幾小時(時區錯位)

    這是第二常見的坑,而且有三個地方都可能出錯,要一個一個排:
    (1) HA 本身的時區——去 設定 → 系統 → 家庭資訊,在「地區(Region)」那一區確認時區是不是 Asia/Taipei。如果欄位是灰的改不動,代表它被寫死在 configuration.yaml 裡,要先把那行拿掉。這在第 2 章講過。
    (2) 來源行事曆的時區——Google 日曆本身有一個日曆時區設定,如果那邊是別的時區,整組事件都會偏。
    (3) 整天事件——整天事件本來就沒有時刻,all_day 會是 true,start 只有日期。拿它去跟時間比較一定怪,要先判斷 all_day 再決定怎麼處理。

  4. 行事曆自動化該跳的時候沒跳

    先想「我是多久前才建這個事件的?」官方文件寫明行事曆每 15 分鐘才讀一次。剛建好就要在 5 分鐘後觸發,來不及是正常的。第二個常見原因是 offset 寫錯——提前一定要有負號,"-00:30:00" 是提前半小時,"00:30:00" 是延後半小時。第三,去設定 → 自動化與場景點開那條自動化,右上角三個點 → 追蹤(Traces),看它到底有沒有被觸發、卡在哪一步。

  5. 待辦清單同步不同步、手機上加的東西 HA 看不到

    先分清楚你用的是哪一種:Local To-do 沒有同步問題,因為它只存在 HA 裡,沒有別的地方跟它同步。會有同步落差的是雲端來源——Google Tasks 官方文件寫的是每 30 分鐘輪詢一次,CalDAV 也是定期抓取。所以「手機加了 HA 沒看到」通常不是壞掉,是還沒到下次抓取時間。真的等太久還是沒有,去設定 → 裝置與服務找到該整合,三個點 → 重新載入,強迫它抓一次。

  6. todo.update_item 說找不到項目

    三個方向:(1) 名字要完全一樣,多一個空白、全形半形不同都算不一樣;(2) 清單裡有兩個同名項目,HA 不知道要改哪個,改用 uid——先用 todo.get_items 撈出 UID,再把 UID 填進 item 欄位;(3) 你打錯 entity_id,改到另一份清單去了。

  7. 加項目時報錯,說到期日的參數有問題

    最常見是due_datedue_datetime 同時寫了,這兩個只能二選一。第二種是你用的那份清單根本不支援到期日或描述——不是每個整合都支援全部欄位,例如 Google Tasks 就只支援日期不支援時間。拿掉那個參數再試一次就知道是不是這個原因。

  8. 刪掉整合之後,待辦清單面板一直報錯

    儀表板上的卡片還指著已經不存在的實體。去編輯模式把那張孤兒卡片刪掉。刪整合前先想一下有沒有哪張卡片、哪條自動化在用它,這個習慣可以省很多事。

常見問題

Local To-do 的資料存在哪裡?備份會帶走嗎?
存在 Home Assistant 自己的設定目錄裡,不在雲端。所以只要你有做完整備份,清單資料就會一起被備份走,還原之後項目都還在。備份的做法在第 9 章。要提醒的是:因為它只存在 HA 裡,HA 掛了你就看不到清單,所以真的很重要的東西(例如繳費期限)建議另外也記在手機上,或改用會同步到雲端的方案。
我一定要開 Google Cloud 專案才能用行事曆嗎?有沒有更簡單的路?
Google 日曆的話,是的,官方文件明講你得自己建 Google Cloud 專案、啟用 Google Calendar API、產生 OAuth 憑證。但如果你只是想要「行事曆事件觸發自動化」這個能力,完全不需要碰 Google——用 Local Calendar 就好,兩分鐘裝完,功能一模一樣,本章所有自動化範例都能跑。差別只在你手機上看不到那個行事曆。想要手機也看得到又不想碰 Google Cloud,第三條路是 CalDAV(例如自架的 Nextcloud 或 Synology Calendar),設定相對單純,只要填網址跟帳密。
為什麼我的行事曆卡片上明明看得到事件,自動化卻沒觸發?
卡片上看得到,只代表 HA 讀得到那個事件,不代表觸發會跳。三個最常見的原因:(1) 事件是剛剛才建的,而行事曆每 15 分鐘才讀取一次,那次觸發來不及;(2) offset 忘了寫負號,變成事件開始之後才觸發;(3) 你在卡片上看到的是另一個行事曆的事件——卡片可以同時顯示好幾個行事曆,但觸發只綁一個。把 entity_id 核對一下。真的排不出來,就去自動化的追蹤(Traces)看紀錄。
todo.get_items 撈出來的東西怎麼用?我看不懂那個 response_variable
大部分動作是「叫 HA 去做某件事」,做完就沒了;todo.get_items 特別的地方是它會回傳資料,而回傳的資料需要一個名字才能在後面的步驟裡引用,這個名字就是 response_variable。你寫 response_variable: result,後面就能用 result['todo.你的清單']['items'] 拿到項目陣列。每個項目一定有 summary(名稱)、uidstatus 三個欄位,另外兩個 due(到期日)和 description(描述)是選配的,沒設就整個欄位不會出現——這是新手寫範本最常爆的地方,記得先用 selectattr('due', 'defined') 擋一層。強烈建議先在設定 → 工具 → 動作那頁單獨跑一次 todo.get_items,把回傳結果看清楚,再去寫範本。
可以做「一直沒完成就每天煩我一次」的效果嗎?
可以,而且不用寫很複雜的東西。做法就是本章「繳費日」那條自動化——每天固定時間跑一次 todo.get_items,只抓 needs_action 狀態的項目,有東西就發通知。因為它每天都掃,只要你不打勾就會每天收到。不想被煩太久的話,可以在條件裡加上「只在到期日前三天內」的判斷,或者用附錄 B 的 Helper(例如切換開關)做一個「暫停提醒」的開關。
全家人可以共用同一份清單嗎?各自的手機都能改嗎?
可以。HA 的待辦清單是整個系統共用的,不是綁在使用者帳號上——只要有 HA 帳號、能登入,看到的就是同一份清單,誰改都會即時同步到所有人的畫面。所以家人要各自的帳號請看第 5 章。想要「爸媽可以改、小孩只能看」的話,比較實務的做法不是靠權限,而是做兩個儀表板分頁:小孩那個分頁上的待辦卡片設 hide_create: true,就不會有新增輸入框。這不是真正的權限鎖,但對家庭情境夠用了。
Shopping list 和 Local to-do 都裝了,會不會打架?
不會,它們是兩個獨立的整合,各自產生自己的實體,資料完全分開。你會在側欄的待辦清單面板裡同時看到兩份清單。唯一要注意的是別搞混實體 ID,寫自動化前先去設定 → 工具確認你指的是哪一份。另外,shopping_list.* 那組動作只對購物清單有效,對 Local to-do 建的清單無效;todo.* 那組則是兩邊都通用——所以能用 todo.* 就用它。
行事曆事件的標題我想拿來做判斷,例如只有標題含「倒垃圾」才觸發,怎麼做?
行事曆觸發本身沒有「只有標題符合才觸發」的選項,它是整個行事曆任一事件開始就跳。做法是觸發照跳,在條件裡篩:加一個範本條件 {{ '倒垃圾' in trigger.calendar_event.summary }},不符合的就會在條件那一關被擋下來。不過更推薦的做法還是把不同用途的事件分到不同的行事曆,自動化會單純很多,也不用寫範本。要用範本的話,記得先去設定 → 工具 → 範本試跑。