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

    範本進階:用 expand 和 selectattr 一行問出「哪些燈還開著」

    [複製鏈接]

    !lvup!   100%

    363

    主題

    27

    回帖

    2200萬

    積分

    管理員

    積分
    22005752
    發表於 3 天前 | 顯示全部樓層 |閱讀模式
    前面寫過範本入門,這篇講進階一點的。

    入門篇教的是 states()state_attr(),那是「問一個實體」。
    這篇講的是「問一整群實體」 —— 這才是範本真正有用的地方。



    問題:我想知道現在有哪些燈還開著

    最笨的寫法是一個一個列:
    1. {{ states('light.客廳') }}
    2. {{ states('light.餐廳') }}
    3. {{ states('light.書房') }}
    4. ...
    複製代碼

    裝置一多就崩潰,而且每次新增燈都要改。

    正確做法:states.light + selectattr
    1. {{ states.light
    2.    | selectattr('state', 'eq', 'on')
    3.    | map(attribute='name')
    4.    | list | join('、') }}
    複製代碼

    拆開來看:


    • states.light — 抓出所有 light 網域的實體物件
    • selectattr('state', 'eq', 'on') — 只留下 state 等於 on 的
    • map(attribute='name') — 把每個物件換成它的友善名稱
    • list | join('、') — 變成一串用頓號分隔的字


    結果會是:客廳燈、玄關燈、陽台燈

    再進一步:只要數量
    1. {{ states.light | selectattr('state', 'eq', 'on') | list | count }}
    複製代碼

    這個拿來做「離家提醒」超好用:
    1. alias: 離家提醒還有燈沒關
    2. triggers:
    3.   - trigger: state
    4.     entity_id: person.charles
    5.     to: not_home
    6. conditions:
    7.   - condition: template
    8.     value_template: >
    9.       {{ states.light | selectattr('state','eq','on') | list | count > 0 }}
    10. actions:
    11.   - action: notify.mobile_app_charles
    12.     data:
    13.       title: 出門了,但還有燈開著
    14.       message: >
    15.         {{ states.light | selectattr('state','eq','on')
    16.            | map(attribute='name') | list | join('、') }}
    17. mode: single
    複製代碼



    expand():把群組攤開

    如果你有一個群組 light.一樓所有燈,直接 states 它只會得到群組本身的狀態。
    要看裡面每一個成員,用 expand:
    1. {{ expand('light.一樓所有燈')
    2.    | selectattr('state','eq','on')
    3.    | map(attribute='name') | list }}
    複製代碼

    expand 也吃清單,可以混著放群組和單一實體:
    1. {{ expand('light.一樓所有燈', 'light.陽台', 'switch.電風扇')
    2.    | selectattr('state','eq','on') | list | count }}
    複製代碼

    常用的幾個組合

    電量低於 20% 的電池裝置
    1. {{ states.sensor
    2.    | selectattr('attributes.device_class','defined')
    3.    | selectattr('attributes.device_class','eq','battery')
    4.    | map(attribute='state') | map('int', 100)
    5.    | select('lt', 20) | list | count }}
    複製代碼

    這個寫法有個細節:先確認屬性存在(defined)再比較
    少了那行,遇到沒有 device_class 的感測器會整個範本報錯。

    超過一小時沒更新的實體(找出掉線的裝置)
    1. {{ states.sensor
    2.    | selectattr('last_updated', 'lt', now() - timedelta(hours=1))
    3.    | map(attribute='name') | list }}
    複製代碼

    所有不可用的實體
    1. {{ states
    2.    | selectattr('state', 'in', ['unavailable', 'unknown'])
    3.    | map(attribute='entity_id') | list }}
    複製代碼

    這個我做成一個 template sensor,每天早上推播一次。
    裝置掉線通常是默默發生的,不主動查不會知道。

    怎麼練

    開發者工具 → 範本。貼上去就即時看到結果,不用重啟、不會弄壞東西。

    我的建議是:一次只加一段管線
    先寫 states.light 看結果,再加 selectattr 看結果,再加 map。
    一次全部寫完然後出錯,你會不知道是哪一段的問題。

    ---

    selectattr 和 map 是 Jinja 的東西,不是 HA 自己發明的。
    所以搜尋的時候關鍵字打「jinja selectattr」會找到更多資料。

    有人有其他好用的組合嗎?貼出來大家收藏。
    您需要登入後纔可以回帖 登入 | 立即註冊

    本版積分規則

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

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

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