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

    wait_for_trigger 與 wait_template:寫出「會等待」的自動化

    [複製鏈接]

    !lvup!   100%

    363

    主題

    27

    回帖

    2200萬

    積分

    管理員

    積分
    22005764
    發表於 3 天前 | 顯示全部樓層 |閱讀模式
    一般的自動化是「觸發 → 做事 → 結束」。
    但有些流程是「做一件事 → 等某件事發生 → 再做下一件」。

    這時候就需要 wait。



    兩種等待


    • wait_for_trigger — 等一個「事件發生」(狀態從 A 變成 B)
    • wait_template — 等一個「條件成立」(現在就成立的話立刻通過)


    差別很重要:
    1. # wait_for_trigger:等「變成」 on
    2. - wait_for_trigger:
    3.     - trigger: state
    4.       entity_id: binary_sensor.門
    5.       to: "on"
    6. # 門「已經」是 on 的話,它會繼續等下一次變化(可能永遠等不到)
    7. # wait_template:等「是」 on
    8. - wait_template: "{{ is_state('binary_sensor.門', 'on') }}"
    9. # 門已經是 on 的話,立刻通過
    複製代碼

    九成的情況你要的是 wait_template,因為你在意的是狀態,不是變化的那一瞬間。

    一定要加 timeout
    1. - wait_template: "{{ is_state('binary_sensor.洗衣機', 'off') }}"
    2.   timeout: "02:00:00"
    3.   continue_on_timeout: true
    複製代碼

    沒有 timeout 的話,自動化會無限期卡在那裡。
    它會一直佔著一個執行位置,而且在「執行中」的自動化裡看得到,
    但你不會注意到 —— 直到某天發現這個自動化再也沒動過。


    • continue_on_timeout: true(預設)— 逾時就繼續往下跑
    • continue_on_timeout: false — 逾時就整個中止


    怎麼知道是等到了還是逾時

    wait 之後會有一個 wait.completed 變數:
    1. - wait_template: "{{ is_state('binary_sensor.洗衣機','off') }}"
    2.   timeout: "02:00:00"
    3. - choose:
    4.     - conditions: "{{ wait.completed }}"
    5.       sequence:
    6.         - action: notify.mobile_app_charles
    7.           data: {message: 洗衣完成}
    8.   default:
    9.     - action: notify.mobile_app_charles
    10.       data: {message: 洗衣機跑超過兩小時了,去看一下?}
    複製代碼

    用 wait_for_trigger 的話還有 wait.trigger
    裡面是「是哪個觸發器完成的」,可以配多個觸發器分流。



    完整範例一:洗衣機完成通知

    這個是用功率判斷,不需要洗衣機本身智能。
    1. alias: 洗衣機完成通知
    2. triggers:
    3.   # 功率超過 100W 持續 1 分鐘 = 開始洗了
    4.   - trigger: numeric_state
    5.     entity_id: sensor.洗衣機功率
    6.     above: 100
    7.     for: "00:01:00"
    8. actions:
    9.   - action: notify.mobile_app_charles
    10.     data:
    11.       message: 洗衣機開始運轉
    12.   # 等功率掉到 5W 以下並維持 3 分鐘 = 洗完了
    13.   # (中間脫水前會短暫低功率,所以 for 不能太短)
    14.   - wait_template: >
    15.       {{ states('sensor.洗衣機功率') | float(999) < 5 }}
    16.     timeout: "03:00:00"
    17.     continue_on_timeout: true
    18.   - choose:
    19.       - conditions: "{{ wait.completed }}"
    20.         sequence:
    21.           - action: notify.mobile_app_charles
    22.             data:
    23.               title: 洗衣完成
    24.               message: 衣服放太久會有味道,記得去晾
    25.               data:
    26.                 actions:
    27.                   - action: SNOOZE_LAUNDRY
    28.                     title: 十分鐘後再提醒
    29.     default:
    30.       - action: notify.mobile_app_charles
    31.         data:
    32.           message: 洗衣機跑三小時了還沒停,可能卡住了
    33. mode: single
    複製代碼

    那個 for: 3 分鐘是重點。
    洗衣機在換程序的時候功率會短暫歸零,沒有 for 的話會提早通知。

    完整範例二:離家後確認門鎖
    1. alias: 離家後五分鐘確認門鎖
    2. triggers:
    3.   - trigger: state
    4.     entity_id: person.charles
    5.     to: not_home
    6. actions:
    7.   - delay: "00:05:00"
    8.   - if:
    9.       - condition: state
    10.         entity_id: lock.前門
    11.         state: unlocked
    12.     then:
    13.       - action: notify.mobile_app_charles
    14.         data:
    15.           title: 門沒鎖
    16.           message: 要幫你鎖嗎?
    17.           data:
    18.             actions:
    19.               - action: LOCK_DOOR
    20.                 title: 鎖上
    21.       # 等使用者按按鈕,最多等 10 分鐘
    22.       - wait_for_trigger:
    23.           - trigger: event
    24.             event_type: mobile_app_notification_action
    25.             event_data:
    26.               action: LOCK_DOOR
    27.         timeout: "00:10:00"
    28.       - if: "{{ wait.completed }}"
    29.         then:
    30.           - action: lock.lock
    31.             target: {entity_id: lock.前門}
    32.           - action: notify.mobile_app_charles
    33.             data: {message: 已鎖上}
    34. mode: single
    複製代碼

    這個用 wait_for_trigger 是對的,因為「按下按鈕」本來就是一個事件,不是狀態。

    範例三:等多個條件其中之一

    wait_for_trigger 可以放多個觸發器,任一個成立就繼續:
    1. - wait_for_trigger:
    2.     - trigger: state
    3.       entity_id: binary_sensor.前門
    4.       to: "on"
    5.       id: 前門
    6.     - trigger: state
    7.       entity_id: binary_sensor.後門
    8.       to: "on"
    9.       id: 後門
    10.   timeout: "00:30:00"
    11. - action: notify.mobile_app_charles
    12.   data:
    13.     message: >
    14.       {{ wait.trigger.id if wait.completed else '半小時內沒人回來' }} 有動靜
    複製代碼

    mode 要怎麼配

    有 wait 的自動化一定要想清楚 mode


    • 同時只該有一個在等 → single(洗衣機那個)
    • 重新觸發要重新計時 → restart
    • 多個對象各自等 → parallel(多扇門各自計時)


    用 single 而且經常重複觸發的話,去日誌搜 already running
    看看是不是一直在漏。

    wait 跟 delay 的差別


    • delay — 固定等多久,時間到就繼續
    • wait — 等到某件事,可能三秒也可能兩小時


    有些人用 delay 30 分鐘 來等洗衣機,那是猜的。
    用 wait 才是真的知道它洗完了。

    ---

    一個小提醒:wait 期間如果你重新載入自動化或重啟 HA,那次執行就沒了。

    所以「等很久」的流程(例如等三小時)要有容錯 ——
    我的洗衣機自動化另外加了一個「每天晚上檢查一次洗衣機功率是不是異常」的保險。
    您需要登入後纔可以回帖 登入 | 立即註冊

    本版積分規則

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

    GMT+8, 2026-9-24 13:20 , Processed in 0.081676 second(s), 24 queries .

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