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

    variables 和 repeat:在自動化裡寫出變數與迴圈

    [複製鏈接]

    !lvup!   100%

    363

    主題

    27

    回帖

    2200萬

    積分

    管理員

    積分
    22005752
    發表於 3 天前 | 顯示全部樓層 |閱讀模式
    自動化寫久了會遇到兩種需求:
    同一個值要用好幾次、還有同一件事要做很多次

    這篇講 variables 和 repeat。



    variables:先算好再用

    沒有變數的時候:
    1. actions:
    2.   - action: light.turn_on
    3.     target: {entity_id: light.客廳}
    4.     data:
    5.       brightness_pct: >
    6.         {{ 5 if (now().hour >= 22 or now().hour < 6) else 80 }}
    7.   - action: light.turn_on
    8.     target: {entity_id: light.餐廳}
    9.     data:
    10.       brightness_pct: >
    11.         {{ 5 if (now().hour >= 22 or now().hour < 6) else 80 }}
    複製代碼

    同一段判斷寫兩次,改的時候一定會漏掉一個。

    有變數:
    1. actions:
    2.   - variables:
    3.       is_night: "{{ now().hour >= 22 or now().hour < 6 }}"
    4.       bri: "{{ 5 if is_night else 80 }}"
    5.       kelvin: "{{ 2200 if is_night else 4000 }}"
    6.   - action: light.turn_on
    7.     target: {entity_id: light.客廳}
    8.     data:
    9.       brightness_pct: "{{ bri }}"
    10.       color_temp_kelvin: "{{ kelvin }}"
    11.   - action: light.turn_on
    12.     target: {entity_id: light.餐廳}
    13.     data:
    14.       brightness_pct: "{{ bri }}"
    15.       color_temp_kelvin: "{{ kelvin }}"
    複製代碼

    變數可以參照前面定義的變數(上面 bri 用了 is_night),
    這讓你可以一層一層把邏輯拆開。

    作用範圍


    • 寫在 actions 裡的 variables — 從那一步之後到結束都能用
    • 寫在自動化最外層的 variables — 整個自動化都能用,但觸發時就算好了
    • 寫在 chooserepeat 的 sequence 裡 — 只有那個區塊內有效


    外層 variables 的時機很重要:
    1. alias: 例子
    2. variables:
    3.   開始時的溫度: "{{ states('sensor.客廳溫度') }}"   # 觸發當下就固定了
    4. triggers: ...
    5. actions:
    6.   - delay: "00:10:00"
    7.   - action: notify.mobile_app_charles
    8.     data:
    9.       message: >
    10.         十分鐘前 {{ 開始時的溫度 }} 度,
    11.         現在 {{ states('sensor.客廳溫度') }} 度
    複製代碼

    這是外層 variables 最有用的地方:記住「當時」的值。



    repeat:三種迴圈

    1. count — 跑固定次數
    1. - repeat:
    2.     count: 3
    3.     sequence:
    4.       - action: light.turn_on
    5.         target: {entity_id: light.客廳}
    6.       - delay: "00:00:01"
    7.       - action: light.turn_off
    8.         target: {entity_id: light.客廳}
    9.       - delay: "00:00:01"
    複製代碼

    閃三下。repeat.index 是第幾次(從 1 開始)。

    2. for_each — 跑一個清單
    1. - repeat:
    2.     for_each:
    3.       - light.客廳
    4.       - light.餐廳
    5.       - light.書房
    6.     sequence:
    7.       - action: light.turn_on
    8.         target:
    9.           entity_id: "{{ repeat.item }}"
    10.         data:
    11.           brightness_pct: 30
    12.       - delay: "00:00:02"
    複製代碼

    repeat.item 是目前這一項。

    這個配範本很強:
    1. - repeat:
    2.     for_each: >
    3.       {{ states.light
    4.          | selectattr('state','eq','on')
    5.          | map(attribute='entity_id') | list }}
    6.     sequence:
    7.       - action: light.turn_off
    8.         target: {entity_id: "{{ repeat.item }}"}
    9.       - delay: "00:00:01"
    複製代碼

    為什麼不直接 target 一整串?
    因為有些 Zigbee 網路一次收到三十個指令會塞車,
    一個一個發、中間加延遲反而比較可靠。

    for_each 也可以是字典清單:
    1. - repeat:
    2.     for_each:
    3.       - {entity: light.客廳, bri: 60}
    4.       - {entity: light.餐廳, bri: 40}
    5.       - {entity: light.書房, bri: 80}
    6.     sequence:
    7.       - action: light.turn_on
    8.         target: {entity_id: "{{ repeat.item.entity }}"}
    9.         data: {brightness_pct: "{{ repeat.item.bri }}"}
    複製代碼

    3. while / until — 條件迴圈
    1. # while:條件成立就一直跑(先判斷再跑)
    2. - repeat:
    3.     while: "{{ states('sensor.濕度') | float(0) > 60 }}"
    4.     sequence:
    5.       - delay: "00:05:00"
    6.       - action: switch.turn_on
    7.         target: {entity_id: switch.除濕機}
    8. # until:跑到條件成立為止(先跑再判斷,至少跑一次)
    9. - repeat:
    10.     until: "{{ is_state('binary_sensor.門','off') }}"
    11.     sequence:
    12.       - action: notify.mobile_app_charles
    13.         data: {message: 門還開著}
    14.       - delay: "00:05:00"
    複製代碼

    危險警告:while / until 一定要有出口
    1. - repeat:
    2.     while: >
    3.       {{ states('sensor.濕度') | float(0) > 60
    4.          and repeat.index < 24 }}          # ← 這行是保險絲
    5.     sequence: ...
    複製代碼

    沒有次數上限的話,感測器壞掉回傳固定值,你的自動化就永遠跑下去
    而且會一直佔著執行位置。我強烈建議每個 while 都加 repeat.index 上限

    HA 本身有一個保護:repeat 超過一定次數會中止並在日誌警告,
    但那個上限很高,等它救你之前系統可能已經很難受了。

    實際範例:漸進式提醒
    1. alias: 門沒關漸進提醒
    2. triggers:
    3.   - trigger: state
    4.     entity_id: binary_sensor.後門
    5.     to: "on"
    6.     for: "00:05:00"
    7. actions:
    8.   - variables:
    9.       門: binary_sensor.後門
    10.   - repeat:
    11.       sequence:
    12.         - action: notify.mobile_app_charles
    13.           data:
    14.             title: "{{ '後門沒關' if repeat.index < 3 else '後門還是沒關!' }}"
    15.             message: >
    16.               已經開著 {{ 5 + repeat.index * 5 }} 分鐘
    17.             data:
    18.               tag: back_door
    19.               push:
    20.                 interruption-level: >
    21.                   {{ 'active' if repeat.index < 3 else 'time-sensitive' }}
    22.         - delay: "00:05:00"
    23.       until: >
    24.         {{ is_state(門, 'off') or repeat.index >= 6 }}
    25.   - if: "{{ is_state(門, 'off') }}"
    26.     then:
    27.       - action: notify.mobile_app_charles
    28.         data:
    29.           message: clear_notification
    30.           data: {tag: back_door}
    31. mode: single
    複製代碼

    這個會每五分鐘提醒一次、語氣逐漸加強、最多六次,
    門關了就自動把通知清掉。

    repeat 裡面可以用的變數


    • repeat.index — 第幾次(從 1)
    • repeat.first — 是不是第一次(布林)
    • repeat.last — 是不是最後一次(只有 count 和 for_each 有)
    • repeat.item — 目前這一項(只有 for_each 有)


    repeat.first 拿來做「第一次要多做一件事」很方便
    1.       sequence:
    2.         - if: "{{ repeat.first }}"
    3.           then:
    4.             - action: light.turn_on
    5.               target: {entity_id: light.玄關}
    6.         - ...
    複製代碼

    ---

    我覺得 repeat 最好用的場景是漸進式的東西
    漸亮的鬧鐘、逐漸加強的提醒、慢慢降溫的冷氣。

    固定值的東西用 repeat 反而是殺雞用牛刀,直接寫清單就好。
    您需要登入後纔可以回帖 登入 | 立即註冊

    本版積分規則

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

    GMT+8, 2026-9-24 12:11 , Processed in 0.078595 second(s), 23 queries .

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