|
|
模板(template)是 HA 最強也最容易出錯的地方。
這篇整理實際會用到的,還有那些「看起來對但會壞」的。

先講最重要的工具
開發者工具 → 模板
- 左邊寫,右邊即時顯示結果
- 所有模板都該先在這裡測過再貼進設定檔
- 錯誤訊息在這裡看得到,寫進 YAML 之後就只剩「自動化沒反應」
這個習慣可以省下八成的除錯時間。
基本的取值
- {{ states('sensor.客廳溫度') }}
- → 取狀態,回傳字串
- {{ states.sensor.客廳溫度.state }}
- → 一樣的東西,但實體不存在時會報錯(上面那個回傳 'unknown')
- {{ state_attr('light.客廳', 'brightness') }}
- → 取屬性
- {{ is_state('light.客廳', 'on') }}
- → 回傳 true / false,比 states(...) == 'on' 好讀
- {{ is_state_attr('climate.客廳', 'hvac_action', 'cooling') }}
- → 屬性的比對
複製代碼

陷阱一:狀態全部是字串
這是第一名的坑。
- {{ states('sensor.溫度') > 25 }}
- → 錯!字串跟數字不能比,會報錯或給錯的答案
- {{ states('sensor.溫度') | float(0) > 25 }}
- → 對。float(0) 的 0 是「轉不出來就當 0」
複製代碼
一定要加預設值:
- float(0) —— 轉小數,失敗給 0
- int(0) —— 轉整數
- 沒加預設值的話,感測器變 unavailable 就整個模板爆掉
字串比較的災難:
- '30' > '9' → false (因為 '3' < '9')
複製代碼
所以溫度 30 度會被判定為「小於 9 度」。
陷阱二:unavailable 和 unknown
感測器不是只有「有值」和「沒值」:
- unavailable —— 裝置離線、整合出錯
- unknown —— 還沒有值(剛重啟)
- none —— 實體不存在
保險的寫法:
- {% set t = states('sensor.溫度') %}
- {% if t not in ['unknown', 'unavailable', 'none'] %}
- {{ t | float(0) }}
- {% else %}
- 0
- {% endif %}
複製代碼
或者用 has_value(HA 2023.9 之後有):
- {{ has_value('sensor.溫度') }}
複製代碼
在自動化的條件裡也可以直接用:
- conditions:
- - condition: template
- value_template: "{{ has_value('sensor.溫度') }}"
複製代碼
陷阱三:空白和換行
YAML 的多行模板會留下換行:
- message: >
- {{ states('sensor.溫度') }}
- → 結果是 "26.5\n"(後面有換行)
複製代碼
解法:
- message: >-
- {{ states('sensor.溫度') }}
- → >- 會把結尾的換行拿掉
複製代碼
或者在模板裡用 trim:
- {{ states('sensor.溫度') | trim }}
複製代碼
控制 Jinja 的空白:
- {%- if ... -%} 左右兩邊的空白都吃掉
- {%- if ... %} 只吃左邊
- {% if ... -%} 只吃右邊
複製代碼
寫長模板的時候這個很重要,不然輸出會亂七八糟。
陷阱四:now() 不會觸發更新
這個很陰險。
- template:
- - sensor:
- - name: 現在幾點
- state: "{{ now().hour }}"
複製代碼
這個感測器不會自己更新 ——
HA 不知道「時間」是什麼東西,不會監聽它。
解法一:加 trigger
- template:
- - triggers:
- - trigger: time_pattern
- minutes: "/1"
- sensor:
- - name: 現在幾點
- state: "{{ now().hour }}"
複製代碼
解法二:讓它依賴一個會變的實體
- state: >
- {% set _ = states('sensor.time') %}
- {{ now().hour }}
複製代碼
sensor.time 來自「時間與日期」整合,每分鐘更新。
同樣的問題會出現在:
- now()、utcnow()
- today_at()
- as_timestamp(now())

陷阱五:模板自己觸發自己
- template:
- - sensor:
- - name: 總用電
- state: >
- {{ states('sensor.總用電') | float(0) + 1 }}
複製代碼
這會無限迴圈。
模板感測器會監聽「模板裡出現的所有實體」,
包含它自己。
要累加的話用 utility_meter 或 statistics,不要自己算。
實用的寫法集
一、找出所有開著的燈
- {{ states.light
- | selectattr('state', 'eq', 'on')
- | map(attribute='name')
- | list | join('、') }}
複製代碼
二、算數量
- {{ states.light | selectattr('state', 'eq', 'on') | list | count }}
複製代碼
三、找出某個區域的實體
- {{ area_entities('客廳') }}
- {{ area_entities('客廳') | select('match', 'light\\.') | list }}
複製代碼
四、找出開了很久的燈
- {{ states.light
- | selectattr('state', 'eq', 'on')
- | selectattr('last_changed', 'lt', now() - timedelta(hours=2))
- | map(attribute='name') | list }}
複製代碼
五、取多個感測器的平均
- {% set ids = ['sensor.客廳溫度', 'sensor.臥室溫度', 'sensor.書房溫度'] %}
- {{ (ids | map('states') | map('float', 0) | sum / ids | count) | round(1) }}
複製代碼
六、取最大 / 最小
- {{ [states('sensor.a') | float(0),
- states('sensor.b') | float(0)] | max }}
複製代碼
七、標籤(label)篩選(HA 2024.4 之後)
- {{ label_entities('夜間照明') }}
複製代碼
標籤比區域彈性 —— 一個實體可以有很多標籤。
八、時間判斷
- {{ now().hour >= 22 or now().hour < 7 }} 深夜
- {{ now().weekday() >= 5 }} 週末(0=週一)
- {{ now().strftime('%Y-%m-%d %H:%M') }} 格式化
- {{ (now() - states.light.客廳.last_changed).total_seconds() / 60 }}
- 開了幾分鐘
複製代碼
九、條件式的值
- {{ '開著' if is_state('light.客廳', 'on') else '關著' }}
複製代碼
十、四捨五入與格式
- {{ 26.567 | round(1) }} 26.6
- {{ 1234567 | round(0) }} 1234567
- {{ "%.1f" | format(26.567) }} 26.6
- {{ 0.856 * 100 | round(0) }} 86
複製代碼
十一、判斷實體存不存在
- {{ states('sensor.可能不存在') not in ['unknown', 'unavailable'] }}
- {{ 'sensor.某某' in states.sensor | map(attribute='entity_id') | list }}
複製代碼
十二、取觸發的資訊(在自動化裡)
- {{ trigger.entity_id }}
- {{ trigger.to_state.state }}
- {{ trigger.from_state.state }}
- {{ trigger.to_state.attributes.friendly_name }}
- {{ trigger.id }}
複製代碼
十三、裝置與區域的對應
- {{ area_name(trigger.entity_id) }} 這個實體在哪個區域
- {{ device_id(trigger.entity_id) }} 實體屬於哪個裝置
- {{ device_entities(device_id) }} 那個裝置有哪些實體
複製代碼
這組很好用:一個自動化服務全家的人體感應器,
用 area_name(trigger.entity_id) 就知道要開哪個房間的燈。
除錯的技巧
一、拆開來測
長模板出錯的時候,一段一段貼到模板工具裡測。
二、用 | list 看中間結果
- {{ states.light | selectattr('state', 'eq', 'on') | list }}
複製代碼
先看篩選出什麼,再接後面的處理。
三、在自動化裡插通知
- - action: persistent_notification.create
- data:
- message: "現在的值是 {{ 你的模板 }}"
複製代碼
四、看日誌
設定 → 系統 → 日誌,模板錯誤會寫在裡面。
---
下一篇:HA 的藍圖(Blueprint) ——
把你的自動化包裝成可以重複使用、可以分享的模板。 |
|