找回密碼
 立即註冊
惟家LINE群QRCODE
    查看: 1|回覆: 0

    用 Google 行事曆觸發家裡的自動化(完整設定)

    [複製鏈接]

    !lvup!   100%

    363

    主題

    27

    回帖

    2200萬

    積分

    管理員

    積分
    22005752
    發表於 3 天前 | 顯示全部樓層 |閱讀模式
    行事曆是一個被低估的觸發來源。

    它知道你「明天要早起」「今天有客人來」「下週要出差」——
    這些資訊沒有任何感測器抓得到。




    先接進來

    設定 → 裝置與服務 → 新增整合 → Google Calendar

    設定步驟


    • 需要 Google Cloud 專案和 OAuth 憑證
    • HA 的文件有詳細步驟(大概十分鐘)
    • 授權之後會問你要匯入哪些行事曆


    重點:建立專用的行事曆

    不要用你的主行事曆當觸發來源。

    理由:


    • 主行事曆有一堆不相關的活動
    • 會員工作行程混在一起
    • 隱私(HA 會讀取活動標題)


    在 Google 行事曆裡新建一個叫「家」的行事曆
    專門放要觸發自動化的事件。

    觸發器怎麼寫

    HA 的行事曆觸發器有兩種:
    1. triggers:
    2.   # 活動開始時
    3.   - trigger: calendar
    4.     entity_id: calendar.家
    5.     event: start
    6.     offset: "-00:30:00"       # 提前 30 分鐘
    7.   # 活動結束時
    8.   - trigger: calendar
    9.     entity_id: calendar.家
    10.     event: end
    11.     offset: "00:00:00"
    複製代碼

    offset 可以是負的(提前)或正的(延後)。

    用活動標題分流

    一個行事曆可以放各種事件,用標題來分:
    1. alias: 行事曆自動化總處理
    2. id: calendar_dispatcher
    3. triggers:
    4.   - trigger: calendar
    5.     entity_id: calendar.家
    6.     event: start
    7.     id: 開始
    8.   - trigger: calendar
    9.     entity_id: calendar.家
    10.     event: end
    11.     id: 結束
    12. actions:
    13.   - variables:
    14.       標題: "{{ trigger.calendar_event.summary }}"
    15.       描述: "{{ trigger.calendar_event.description | default('') }}"
    16.   - choose:
    17.       # --- 有客人來 ---
    18.       - conditions:
    19.           - condition: trigger
    20.             id: 開始
    21.           - "{{ '客人' in 標題 or '訪客' in 標題 }}"
    22.         sequence:
    23.           - action: scene.turn_on
    24.             target: {entity_id: scene.訪客模式}
    25.           - action: camera.turn_off
    26.             target: {entity_id: camera.客廳}      # 隱私
    27.           - action: script.smart_announce
    28.             data:
    29.               area: all
    30.               message: 訪客模式已啟動
    31.       # --- 出差 / 旅行 ---
    32.       - conditions:
    33.           - condition: trigger
    34.             id: 開始
    35.           - "{{ '出差' in 標題 or '旅行' in 標題 }}"
    36.         sequence:
    37.           - action: input_select.select_option
    38.             target: {entity_id: input_select.house_mode}
    39.             data: {option: 度假}
    40.       - conditions:
    41.           - condition: trigger
    42.             id: 結束
    43.           - "{{ '出差' in 標題 or '旅行' in 標題 }}"
    44.         sequence:
    45.           - action: input_select.select_option
    46.             target: {entity_id: input_select.house_mode}
    47.             data: {option: 在家-日間}
    48.           - action: climate.set_temperature
    49.             target: {entity_id: climate.主臥}
    50.             data: {temperature: 26, hvac_mode: cool}   # 提前降溫
    51.       # --- 早班(提前 30 分鐘觸發) ---
    52.       - conditions:
    53.           - condition: trigger
    54.             id: 開始
    55.           - "{{ '早班' in 標題 }}"
    56.         sequence:
    57.           - action: input_datetime.set_datetime
    58.             target: {entity_id: input_datetime.鬧鐘時間}
    59.             data:
    60.               time: >
    61.                 {{ (trigger.calendar_event.start | as_datetime
    62.                     - timedelta(hours=1, minutes=30)).strftime('%H:%M:%S') }}
    63. mode: queued
    64. max: 5
    複製代碼



    trigger.calendar_event 裡有什麼
    1. {
    2.   "summary": "客人來訪",
    3.   "description": "王先生一家",
    4.   "start": "2026-09-25T18:00:00+08:00",
    5.   "end": "2026-09-25T21:00:00+08:00",
    6.   "location": "家",
    7.   "all_day": false
    8. }
    複製代碼

    description 可以拿來放參數,這是一個好用的技巧:
    1. # 行事曆活動的描述欄位填:
    2. temp=24
    3. lights=warm
    4. # 自動化裡解析
    5. - variables:
    6.     設定: >
    7.       {% set d = trigger.calendar_event.description | default('') %}
    8.       {% set result = namespace(dict={}) %}
    9.       {% for line in d.split('\n') %}
    10.         {% if '=' in line %}
    11.           {% set k, v = line.split('=', 1) %}
    12.           {% set result.dict = dict(result.dict, **{k.strip(): v.strip()}) %}
    13.         {% endif %}
    14.       {% endfor %}
    15.       {{ result.dict }}
    16. - action: climate.set_temperature
    17.   target: {entity_id: climate.客廳}
    18.   data:
    19.     temperature: "{{ 設定.temp | default(26) | int }}"
    複製代碼

    不用觸發器,直接查詢行事曆

    有時候你不是要「活動開始時做事」,
    而是要「判斷今天有沒有某個活動」。

    行事曆實體的狀態


    • on —— 現在正在某個活動中
    • off —— 現在沒有活動


    屬性裡有:message、start_time、end_time、description、all_day。
    1. conditions:
    2.   - condition: state
    3.     entity_id: calendar.家
    4.     state: "on"
    5.   - condition: template
    6.     value_template: >
    7.       {{ '在家工作' in state_attr('calendar.家', 'message') }}
    複製代碼

    查詢未來的活動(用服務)
    1. - action: calendar.get_events
    2.   target:
    3.     entity_id: calendar.家
    4.   data:
    5.     start_date_time: "{{ today_at('00:00') }}"
    6.     end_date_time: "{{ today_at('00:00') + timedelta(days=1) }}"
    7.   response_variable: 今日活動
    8. - action: notify.mobile_app_charles
    9.   data:
    10.     title: 今天的行程
    11.     message: >
    12.       {% set evs = 今日活動['calendar.家'].events %}
    13.       {% if evs | count == 0 %}
    14.       今天沒有安排
    15.       {% else %}
    16.       {% for e in evs %}
    17.       {{ e.start[11:16] }} {{ e.summary }}
    18.       {% endfor %}
    19.       {% endif %}
    複製代碼

    response_variable 是比較新的功能
    讓服務可以回傳資料給後續步驟用。



    五個實際好用的場景

    1. 垃圾車提醒

    在行事曆建一個週期性活動「倒垃圾」。
    1. triggers:
    2.   - trigger: calendar
    3.     entity_id: calendar.家
    4.     event: start
    5.     offset: "-00:45:00"
    6. conditions:
    7.   - "{{ '垃圾' in trigger.calendar_event.summary }}"
    8. actions:
    9.   - action: script.smart_announce
    10.     data:
    11.       area: occupied
    12.       message: 四十五分鐘後垃圾車會來,記得準備
    複製代碼

    2. 出差前的檢查
    1. triggers:
    2.   - trigger: calendar
    3.     entity_id: calendar.家
    4.     event: start
    5.     offset: "-04:00:00"      # 提前四小時
    6. conditions:
    7.   - "{{ '出差' in trigger.calendar_event.summary }}"
    8. actions:
    9.   - action: notify.mobile_app_charles
    10.     data:
    11.       title: 出差前檢查
    12.       message: >
    13.         {% set problems = [] %}
    14.         {% if states.light | selectattr('state','eq','on') | list | count > 0 %}
    15.         有燈沒關。
    16.         {% endif %}
    17.         {% set low = states.sensor
    18.            | selectattr('attributes.device_class','defined')
    19.            | selectattr('attributes.device_class','eq','battery')
    20.            | map(attribute='state') | map('int',100)
    21.            | select('lt', 30) | list | count %}
    22.         {% if low > 0 %}
    23.         有 {{ low }} 個裝置電量低於 30%,建議先換電池。
    24.         {% endif %}
    25.         記得檢查冰箱、關窗、設定度假模式。
    複製代碼

    3. 在家工作日
    1. conditions:
    2.   - "{{ '在家工作' in trigger.calendar_event.summary }}"
    3. actions:
    4.   # 書房提前開冷氣和除濕
    5.   - action: climate.set_temperature
    6.     target: {entity_id: climate.書房}
    7.     data: {temperature: 26, hvac_mode: cool}
    8.   # 通知降級(工作時不要一直被打斷)
    9.   - action: input_boolean.turn_on
    10.     target: {entity_id: input_boolean.勿擾模式}
    複製代碼

    4. 小孩的課表

    把課表放進行事曆,做「提醒帶什麼」:
    1. message: >
    2.   明天 {{ trigger.calendar_event.summary }},
    3.   {{ trigger.calendar_event.description }}
    複製代碼

    描述欄位填「記得帶直笛和體育服」。

    5. 生日和紀念日
    1. triggers:
    2.   - trigger: time
    3.     at: "08:00:00"
    4. actions:
    5.   - action: calendar.get_events
    6.     target: {entity_id: calendar.紀念日}
    7.     data:
    8.       start_date_time: "{{ today_at('00:00') }}"
    9.       end_date_time: "{{ today_at('00:00') + timedelta(days=1) }}"
    10.     response_variable: 今日
    11.   - condition: "{{ 今日['calendar.紀念日'].events | count > 0 }}"
    12.   - action: script.smart_announce
    13.     data:
    14.       area: all
    15.       message: >
    16.         今天是{{ 今日['calendar.紀念日'].events[0].summary }}
    複製代碼

    注意事項

    1. 同步延遲

    Google Calendar 整合預設每 15 分鐘同步一次。

    所以「臨時加一個五分鐘後開始的活動」可能不會觸發。

    要立刻同步的話:
    1. - action: homeassistant.update_entity
    2.   target:
    3.     entity_id: calendar.家
    複製代碼

    2. 全天活動的時間

    全天活動的 start 是 日期(沒有時間),
    而不是 datetime。處理的時候要注意。
    1. {% if trigger.calendar_event.all_day %}
    2.   # 全天活動,start 是 "2026-09-25"
    3. {% else %}
    4.   # 一般活動,start 是 "2026-09-25T18:00:00+08:00"
    5. {% endif %}
    複製代碼

    3. 隱私


    • HA 會讀取活動標題和描述
    • 這些資料會進 recorder
    • 不要把敏感內容放在觸發用的行事曆


    4. 本地行事曆的替代方案

    不想用 Google 的話,HA 有內建的本地行事曆

    設定 → 裝置與服務 → 新增整合 → Local Calendar

    完全本地、不用授權、不用網路。
    缺點是只能在 HA 裡編輯(不能用手機的行事曆 App)。

    我的做法是兩個都用
    週期性的固定事項(倒垃圾、換濾網)放本地行事曆,
    需要隨時在手機上改的放 Google。

    ---

    行事曆觸發的價值在於:它是唯一能讓家裡「預知未來」的來源。

    感測器只知道「現在」,行事曆知道「等一下會發生什麼」。

    用得好的話,可以做出「你還沒回到家,冷氣已經先開好」
    這種真的很有感的自動化。
    您需要登入後纔可以回帖 登入 | 立即註冊

    本版積分規則

    Archiver|手機版|惟家的智能論壇

    GMT+8, 2026-9-24 11:29 , Processed in 0.078552 second(s), 24 queries .

    快速回覆 返回頂部 返回列表