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

    ESPHome 濾波器完全指南:讓數值不要一直跳

    [複製鏈接]

    !lvup!   100%

    363

    主題

    27

    回帖

    2200萬

    積分

    管理員

    積分
    22005752
    發表於 3 天前 | 顯示全部樓層 |閱讀模式
    自己做的感測器最常見的抱怨:數字一直跳

    溫度 26.1 → 26.4 → 26.0 → 26.3……每秒都在變。

    濾波器就是解決這個的。



    為什麼要濾波

    三個理由:


    • 看起來不專業 —— 數字一直跳,讓人覺得不準
    • 塞爆資料庫 —— 每次變化都是一筆記錄
    • 誤觸發自動化 —— 「溫度超過 28 度」的條件會一直反覆觸發


    第三個最嚴重。

    濾波器怎麼寫
    1. sensor:
    2.   - platform: aht10
    3.     temperature:
    4.       name: "溫度"
    5.       filters:
    6.         - median:
    7.             window_size: 5
    8.             send_every: 5
    9.         - delta: 0.2
    複製代碼

    filters 是一個清單,會依序執行 ——
    前一個的輸出是後一個的輸入。

    最常用的六個濾波器



    一、median(中位數)—— 最推薦
    1.         - median:
    2.             window_size: 5
    3.             send_every: 5
    複製代碼

    收集 5 筆,取中位數,然後送出去。

    為什麼用中位數而不是平均


    • 中位數不受極端值影響
    • 如果有一筆讀到 99 度(雜訊),平均會被拉高,中位數不受影響


    這是我最常用的濾波器。

    window_size 和 send_every 的關係


    • window_size: 5, send_every: 5 → 每 5 筆送一次(回報頻率變 1/5
    • window_size: 5, send_every: 1 → 每筆都送,但用最近 5 筆算(頻率不變但平滑


    二、sliding_window_moving_average(滑動平均)
    1.         - sliding_window_moving_average:
    2.             window_size: 10
    3.             send_every: 10
    複製代碼

    平均值,適合變化平緩的東西(溫度、濕度、氣壓)。

    不適合會有突波的東西(功率、PM2.5)—— 用 median 比較好。

    三、delta(變化量門檻)—— 最省資料庫
    1.         - delta: 0.2
    複製代碼

    變化超過 0.2 才送出去。

    這個是省資料庫的關鍵。

    我的建議值


    • 溫度:0.2 或 0.3
    • 濕度:1.0
    • CO2:20
    • PM2.5:2
    • 功率:5(瓦)
    • 光照:可以用百分比,例如 delta: 5%


    delta 也可以寫成百分比
    1.         - delta: 5%
    複製代碼

    意思是「變化超過目前值的 5% 才回報」。

    四、throttle(限流)
    1.         - throttle: 60s
    複製代碼

    不管怎樣,60 秒內最多送一次。

    適合:感測器本身更新很快但你不需要那麼頻繁的情況。

    五、heartbeat(心跳)
    1.         - heartbeat: 5min
    複製代碼

    不管有沒有變化,每 5 分鐘一定送一次。

    為什麼需要

    如果你用了 delta,數值穩定的時候可能好幾小時都不回報

    HA 會以為那個感測器掛了(last_updated 很久以前)。

    所以 delta 通常要配 heartbeat
    1.       filters:
    2.         - median:
    3.             window_size: 5
    4.             send_every: 5
    5.         - delta: 0.2
    6.         - heartbeat: 5min
    複製代碼

    六、calibrate_linear(線性校正)
    1.         - calibrate_linear:
    2.             - 0.0 -> 0.0
    3.             - 25.0 -> 26.5
    複製代碼

    用已知的對照點校正讀值。

    怎麼用


    • 拿一個你信任的溫度計放旁邊
    • 記下兩組對照(你的感測器讀 25.0,標準的讀 26.5)
    • 填進去


    DIY 感測器常常會有固定偏移(例如 ESP32 發熱影響),這個可以修正。



    實用的組合配方

    溫濕度(最常用)
    1.     temperature:
    2.       name: "溫度"
    3.       filters:
    4.         - median:
    5.             window_size: 5
    6.             send_every: 5
    7.         - delta: 0.2
    8.         - heartbeat: 5min
    9.     humidity:
    10.       name: "濕度"
    11.       filters:
    12.         - median:
    13.             window_size: 5
    14.             send_every: 5
    15.         - delta: 1.0
    16.         - heartbeat: 5min
    複製代碼

    CO2
    1.       filters:
    2.         - median:
    3.             window_size: 3
    4.             send_every: 3
    5.         - delta: 20
    6.         - heartbeat: 5min
    複製代碼

    CO2 變化比較慢,window 不用太大。

    PM2.5(雜訊很大)
    1.       filters:
    2.         - median:
    3.             window_size: 10
    4.             send_every: 10
    5.         - delta: 2
    6.         - heartbeat: 5min
    複製代碼

    PMS5003 的原始讀值跳動非常大,window 要開大一點。

    功率(有突波)
    1.       filters:
    2.         - median:
    3.             window_size: 7
    4.             send_every: 3
    5.         - delta: 5
    6.         - heartbeat: 60s
    複製代碼

    send_every 比 window_size 小 ——
    這樣回報還算頻繁(才能及時偵測電器開關),但數值已經平滑過。

    光照(變化範圍很大)
    1.       filters:
    2.         - median:
    3.             window_size: 5
    4.             send_every: 5
    5.         - delta: 8%
    6.         - heartbeat: 5min
    複製代碼

    用百分比,因為 10 lux 和 10000 lux 的「有意義變化」差很多。

    電池電壓
    1.       filters:
    2.         - sliding_window_moving_average:
    3.             window_size: 20
    4.             send_every: 20
    5.         - delta: 0.05
    6.         - throttle: 10min
    複製代碼

    電壓變化很慢,可以大量平滑。



    進階:自訂濾波器(lambda)
    1.       filters:
    2.         - lambda: |-
    3.             // 濾掉明顯錯誤的讀值
    4.             if (x < -40 || x > 80) return {};   // 回傳空 = 丟掉這筆
    5.             return x;
    複製代碼

    return {} 代表「丟掉這筆,不要往下傳」。

    另一個實用的:單位換算
    1.       filters:
    2.         - lambda: return x * 9.0 / 5.0 + 32.0;   # 攝氏轉華氏
    複製代碼

    或者做補償
    1.       filters:
    2.         # ESP32 發熱會讓溫度偏高,減掉 1.5 度
    3.         - lambda: return x - 1.5;
    複製代碼

    ESP32 發熱的問題(很重要)

    這是自己做溫度感測器最常見的問題。


    • ESP32 運作時會發熱
    • 感測器如果離晶片太近,讀到的溫度會偏高 2-5 度
    • 而且 Wi-Fi 傳輸時更熱,讀值會跟著網路活動起伏


    三個解法(由好到差)


    • 用杜邦線把感測器拉遠(至少 10 公分)—— 最有效
    • 降低 CPU 頻率(設定裡可以調)
    • 用 calibrate_linear 或 lambda 補償 —— 治標,因為偏移量會隨負載變化


    我的做法:用 20 公分的排線把感測器拉出盒子外面。
    這樣完全不用校正。

    濾波之後對資料庫的影響

    實際測試(一個溫度感測器,跑一天):


    • 沒有濾波,10 秒更新 → 8,640 筆
    • median 5/5,30 秒更新 → 2,880 筆
    • 再加 delta 0.2 → 約 200-400 筆


    差 20 倍以上。

    十個感測器的話,一年差幾千萬筆。

    怎麼驗證濾波有沒有效


    • 在 HA 開那個實體的歷史
    • 濾波前:曲線鋸齒狀、密密麻麻
    • 濾波後:平滑的線、資料點明顯變少


    或者用 SQL 查(前面有一篇講過):
    1. SELECT sm.entity_id, COUNT(*) AS 筆數
    2. FROM states s
    3. JOIN states_meta sm ON s.metadata_id = sm.metadata_id
    4. WHERE sm.entity_id = 'sensor.bedroom_temperature'
    5.   AND s.last_updated_ts >= strftime('%s','now','-1 day');
    複製代碼

    ---

    下一篇:自訂按鍵行為 ——
    單擊、雙擊、長按、多擊,一個按鈕做四件事。
    您需要登入後纔可以回帖 登入 | 立即註冊

    本版積分規則

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

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

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