移至主內容

溫度異常自動告警:Lambda + SNS 實作工廠即時警報系統

工廠IT技術人員專用AWS Lambda + SNS即時告警系統ATLANTIS 自有品牌

溫度異常自動告警:Lambda + SNS 實作工廠即時警報系統

台灣31年工業儀錶製造商 ATLANTIS 昶特有限公司系列教學文章第五篇:前四篇我們完成了「感測器發布」「MQTT訂閱驗證」「Lambda事件觸發」與「Modbus封包解析」,資料現在已經是乾淨、正確的溫度數值。本篇要補上最後一塊拼圖——當溫度異常時,如何讓值班人員的手機在幾秒內收到簡訊或Email通知,而不是等到下一次巡檢才發現問題。

「Re-Atlantis」的品牌精神,是重現古代理想文明對精密秩序的追求——而秩序不只在於量測準確,更在於異常發生時系統能立即反應。過去工廠依賴人工巡檢與警報燈,如今我們可以用AWS SNS(簡易通知服務)在幾秒內把異常訊息送到工程師手機上。詳見 ATLANTIS 品牌故事

一、為什麼要用SNS,而不是自己寫發簡訊的程式?

第三篇的Lambda範例中,我們只用print()把異常訊息印到CloudWatch日誌,工程師仍必須主動打開主控台才能看到。本篇要解決的問題是:如何讓異常訊息主動找上工程師,而不是工程師主動找異常訊息。

數秒
從Lambda判斷異常
到簡訊送達手機
3種
SNS原生支援的
通知管道
1行程式碼
呼叫SNS發送
告警訊息
每月免費額度
SNS提供一定量
免費Email/HTTP通知

Amazon SNS是什麼?

Amazon SNS(Simple Notification Service)是AWS的發布/訂閱式通知服務。你只需要建立一個「主題(Topic)」,並讓需要接收通知的對象(手機號碼、Email信箱、其他Lambda函式等)訂閱這個主題,之後只要有程式發布訊息到這個主題,所有訂閱者都會同時收到通知——這正好與MQTT的Pub/Sub概念相通,只是SNS專門服務於「通知」場景,而非高頻率的感測器數據流。

自己寫發簡訊程式 vs 使用SNS

若自行串接簡訊服務商API,工廠IT需要處理帳號申請、額度管理、失敗重試、多管道整合等瑣事;使用SNS則只需要在AWS主控台建立主題與訂閱者,程式端只需呼叫一次API,AWS會處理底層的傳送邏輯與管道整合。對於工廠IT技術人員而言,SNS是目前最快能把告警機制做出來的方式

二、架構總覽:從溫度異常到手機通知

① 溫度數據抵達 AWS IoT Core 規則引擎觸發 ② Lambda函式 解析並判斷是否 超過溫度警戒值 呼叫sns.publish() ③ SNS主題 factory-temp-alert 扇出至所有訂閱者 ④ 訂閱者 SMS 手機簡訊 Email 電子郵件 Lambda 二次處理 ⑤ 值班工程師 手機即時收到 異常通知

整條架構的關鍵在於③:SNS主題扮演「扇出(Fan-out)」的角色——Lambda函式只需要發布一次訊息,SNS就會自動把同一則訊息同時送給所有已訂閱的管道,不需要為每個通知管道分別寫程式碼。

三、建立SNS主題與訂閱者

步驟一:建立SNS主題

登入AWS主控台搜尋「SNS」,選擇「主題(Topics)」→「建立主題」,類型選擇「標準(Standard)」(相對於「先進先出FIFO」,一般告警通知場景使用標準類型即可),命名為例如factory-temp-alert

步驟二:新增訂閱者

建立主題後,點擊「建立訂閱」,可以選擇的協定類型如下表:

訂閱協定接收對象適用情境
SMS手機門號需要最快速引起注意的緊急告警
Email電子郵件信箱不需要立即反應但需要留存記錄的告警
Lambda另一個Lambda函式需要進一步處理告警邏輯(如轉發至企業通訊軟體)
HTTP/HTTPS自訂Webhook端點整合企業內部系統或第三方通知平台

對於工廠現場的溫度告警,我們建議同時訂閱SMS與Email:SMS確保值班人員第一時間收到通知,Email則留下完整的異常記錄供後續分析與稽核使用。

四、Lambda程式碼:判斷異常並發送SNS通知

以下範例延續第三篇的最小Lambda函式,加上呼叫SNS發布告警訊息的邏輯。

範例一:溫度異常判斷並發送SNS告警

import json
import boto3

sns_client = boto3.client("sns", region_name="ap-northeast-1")
TOPIC_ARN = "arn:aws:sns:ap-northeast-1:123456789012:factory-temp-alert"
THRESHOLD = 80.0

def lambda_handler(event, context):
    device_id = event.get("device_id", "unknown")
    temperature = event.get("temperature")
    source_topic = event.get("source_topic", "")

    if temperature is None:
        return {"statusCode": 400, "body": "缺少temperature欄位"}

    if temperature > THRESHOLD:
        message = (
            f"[ATLANTIS雲端監控告警]\n"
            f"裝置:{device_id}\n"
            f"目前溫度:{temperature}°C(警戒值:{THRESHOLD}°C)\n"
            f"來源主題:{source_topic}"
        )

        sns_client.publish(
            TopicArn=TOPIC_ARN,
            Subject="工廠溫度異常告警",
            Message=message
        )
        print(f"已發送SNS告警:裝置{device_id}溫度{temperature}°C")
    else:
        print(f"裝置 {device_id} 溫度正常:{temperature}°C")

    return {"statusCode": 200, "body": json.dumps("處理完成")}

這段程式碼與第三篇的差異只在於:當溫度超過警戒值時,多呼叫了一次sns_client.publish()。你需要在Lambda的執行角色(Execution Role)中額外授權sns:Publish的權限,資源範圍限定為該SNS主題的ARN,遵循最小權限原則。

IAM權限設定範例

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "sns:Publish",
            "Resource": "arn:aws:sns:ap-northeast-1:123456789012:factory-temp-alert"
        }
    ]
}

五、避免「告警疲勞」:防止同一異常反覆發送通知

實作告警系統時,工廠IT技術人員最常忽略的一個問題是:如果溫度持續超標30分鐘,且每30秒觸發一次Lambda,值班人員可能在30分鐘內收到60則重複簡訊。這種「告警疲勞(Alert Fatigue)」會讓真正重要的通知被淹沒,甚至讓工程師養成忽略簡訊的習慣。

三種常見的抑制策略

策略作法優點限制
簡易冷卻時間(Cooldown)記錄上次告警時間,未超過設定間隔(如15分鐘)不重複發送實作簡單需要額外的狀態儲存(如DynamoDB),Lambda本身無狀態
SNS訊息篩選(Message Filtering)用訊息屬性標記告警等級,訂閱者依篩選政策決定是否接收可依裝置或嚴重程度分流通知對象無法單獨解決「同一異常重複觸發」的問題
狀態變化觸發(Edge-Triggered)只在「從正常變異常」的那一刻發送通知,而非每次判斷都發送大幅減少通知數量需要記錄裝置的前一次狀態(正常/異常)

本篇範例為求簡潔,尚未實作狀態記錄機制——這也是為什麼我們把「把壓力溫度數據寫入DynamoDB」安排為系列文章下一篇的原因:有了狀態儲存,才能真正實作「只在異常剛發生時通知一次」的智慧告警邏輯,而不是每30秒轟炸一次值班人員的手機。

簡易概念示範:狀態變化觸發邏輯(需搭配資料庫使用)

# 概念示範,previous_state實際應從DynamoDB等資料庫讀取,下一篇文章會展開完整實作
def should_send_alert(device_id: str, is_abnormal: bool, previous_state: dict) -> bool:
    last_state = previous_state.get(device_id, "normal")
    current_state = "abnormal" if is_abnormal else "normal"

    # 只有從normal變成abnormal的那一刻才發送通知
    should_notify = (last_state == "normal" and current_state == "abnormal")

    previous_state[device_id] = current_state
    return should_notify

六、SNS訊息篩選:讓不同嚴重程度的告警送給不同的人

SNS支援「訊息屬性(Message Attributes)」與「篩選政策(Filter Policy)」機制,可以讓同一個主題的訊息依標籤分流給不同訂閱者,而不需要為每種告警等級建立獨立主題。

告警等級訊息屬性範例建議接收對象
Critical(嚴重)severity: "critical"值班工程師SMS + 主管Email
Warning(警告)severity: "warning"值班工程師Email
Info(一般資訊)severity: "info"僅記錄,不主動通知

發布帶有篩選屬性的SNS訊息範例

sns_client.publish(
    TopicArn=TOPIC_ARN,
    Subject="工廠溫度異常告警",
    Message=message,
    MessageAttributes={
        "severity": {
            "DataType": "String",
            "StringValue": "critical"
        }
    }
)

接著在訂閱端設定「篩選政策」,例如某個Email訂閱只想接收severitycritical的訊息,即可在SNS主控台的訂閱設定中填入對應的篩選JSON,SNS會自動只轉發符合條件的訊息給該訂閱者,其餘訊息不會送達,也不會產生該訂閱者的額外通知費用。

七、ATLANTIS 具備本地告警功能,適合搭配雲端SNS雙重防護的產品

ECS 滑動式接點壓力錶

ECS 滑動式接點壓力錶 —— 配備蜂鳴器響鈴警告功能,可選配指示燈閃動或繼電器控制,本地告警與雲端SNS通知並行,形成雙重防護

MSPS 全不鏽鋼接點壓力錶(微動開關型)

MSPS 全不鏽鋼接點壓力錶(微動開關型) —— 較佳的指示精度與設定點重複性,適合作為雲端告警系統之外的現場最後一道防線

DPS-ED3.0 數位壓力開關

DPS-ED3.0 數位壓力開關 —— 集成壓力警報、過程控制與訊號輸出功能,數位輸出可同步觸發本地繼電器與雲端SNS通知

PS-2100X系列 防爆圓盲型壓力開關

PS-2100X系列 防爆圓盲型壓力開關 —— 高設定點可重複性防爆壓力開關,適合危險環境下需要雙重告警保障的關鍵製程

為什麼建議「本地告警」與「雲端告警」雙重並行?

雲端告警系統依賴網路連線、AWS服務可用性與Lambda執行邏輯,理論上仍存在極低機率的故障可能;而變送器本身的機械式或電子式警報輸出(如蜂鳴器、警示燈)不依賴任何網路或雲端服務,是最後一道防線。兩者並行,才是真正符合工業安全思維的告警架構,這也是ATLANTIS在產品設計上一貫的堅持。

八、SNS費用試算與案例分享

通知管道計費方式(依AWS官方公告,實際費率請以最新公告為準)小規模工廠估算(每月約50則異常通知)
Email通知每月有一定免費額度,超過依請求數計費通常落在免費額度內
SMS簡訊依目的地國家/地區與訊息數量計費,費率因地區而異依實際簡訊數量產生費用,建議先用小規模測試估算
Lambda訂閱(二次處理)依Lambda本身的請求與運算費用計費通常落在Lambda免費額度內

對於多數工廠而言,異常通知的數量遠低於感測器原始數據的傳輸量(因為只有真正超標才會觸發),因此SNS的費用通常遠低於IoT Core與Lambda的基礎費用,是整條資料管線中相對經濟的一環。

案例分享:某中部塑膠射出成型廠的告警系統導入

階段作法導入前導入後
模具冷卻水溫監控Lambda判斷溫度異常後發布SNS通知值班工程師手機依賴巡檢每2小時一次,異常平均1.5小時後才被發現異常發生後平均10秒內簡訊送達
告警疲勞抑制加入簡易冷卻時間邏輯,15分鐘內同一裝置不重複發送模擬測試顯示原始邏輯30分鐘內發送60則簡訊同一異常事件僅發送1~2則通知

資深工程師賴祥德分享:「很多工廠一開始導入告警系統時,會把警戒值設得很嚴格,結果第一週工程師的手機被灌爆,後來乾脆把通知關掉,等於白做了。我們建議告警門檻要先保守設定,並務必加上抑制邏輯,讓工程師願意持續信任這套系統送出的每一則通知。」

資料來源與延伸閱讀

本文技術架構參考 AWS SNS 官方文件(docs.aws.amazon.com/sns)與 AWS Lambda IAM 權限設定官方指南。費用資訊請以AWS官網最新公告為準。ATLANTIS產品告警功能規格引用自內部產品規格書。

十、20 大常見問題 FAQ(Lambda + SNS 告警系統)

1. SNS的Standard與FIFO主題有什麼差別?告警系統該選哪一種?
Standard主題支援高吞吐量但不保證嚴格順序與去重;FIFO主題保證訊息順序與去重,但吞吐量較低且僅支援特定訂閱協定。一般告警通知場景使用Standard主題已足夠,FIFO較適合對順序要求嚴格的交易類應用。
2. SMS訂閱需要事先驗證手機號碼嗎?
部分地區與帳號設定下,SNS SMS訂閱可直接發送而不需事先驗證;但帳號若仍處於SNS沙盒(Sandbox)模式,可能需要先驗證目標號碼才能接收簡訊,正式上線前建議申請提高帳號限制並確認沙盒狀態。
3. 一個SNS主題最多可以有幾個訂閱者?
SNS對每個主題的訂閱數量有配額限制(實際數值請查閱AWS官方文件的服務配額頁面),一般工廠告警場景(數個到數十個訂閱者)通常遠低於預設限制。
4. 為什麼我的Lambda呼叫sns.publish()會出現權限錯誤?
最常見原因是Lambda執行角色未被授權sns:Publish動作,或授權的Resource範圍與實際使用的Topic ARN不一致,請檢查IAM政策的Action與Resource設定是否正確對應。
5. 告警疲勞具體會造成什麼後果?
當工程師持續收到大量重複或不重要的通知,會逐漸養成忽略通知的習慣,導致真正重要的異常事件也被忽視,這是告警系統設計中最需要提防的反效果,務必搭配適當的抑制邏輯。
6. 簡易冷卻時間(Cooldown)邏輯要怎麼實作,Lambda本身不是無狀態的嗎?
沒錯,Lambda函式本身在每次調用之間不保證狀態保留,因此冷卻時間邏輯需要搭配外部狀態儲存(如DynamoDB)記錄「上次告警時間」,這也是系列文章下一篇要展開的主題。
7. SNS訊息篩選政策(Filter Policy)要在哪裡設定?
在SNS主控台的訂閱設定頁面,找到「訂閱篩選政策」欄位,填入JSON格式的篩選條件,例如指定只接收severity屬性為critical的訊息,設定後該訂閱者只會收到符合條件的通知。
8. Email通知的內容可以是HTML格式嗎?
SNS的Email訂閱預設為純文字格式,若需要HTML格式的精美通知信件,可以改用「Email-JSON」協定並自行在下游(如另一個Lambda函式)組裝HTML內容,或改用其他專門的Email服務(如Amazon SES)處理格式化郵件。
9. 我可以讓SNS通知同時轉發到企業內部的通訊軟體嗎?
可以,透過HTTP/HTTPS訂閱協定或Lambda訂閱,將SNS訊息轉發至自訂的Webhook端點,再由該端點程式呼叫企業通訊軟體的API發送訊息,實現跨平台通知整合。
10. 告警訊息裡應該包含哪些資訊,才能讓工程師快速判斷?
建議至少包含:裝置ID、目前讀值、警戒門檻、資料來源主題(或產線位置)與時間戳記,讓工程師不需要另外查詢就能初步判斷異常的位置與嚴重程度。
11. 如果Lambda執行時sns.publish()失敗,異常通知會遺失嗎?
若未妥善處理例外,發布失敗確實可能導致該次告警遺失。建議在呼叫SNS時加上try/except,並將失敗記錄寫入CloudWatch Logs或另一個備援通知管道,避免單一環節故障導致告警完全消失。
12. 狀態變化觸發(Edge-Triggered)邏輯,跟簡易冷卻時間哪個比較好?
兩者可以搭配使用:狀態變化觸發確保只在「由正常轉異常」時發送第一次通知,冷卻時間則確保若異常持續一段時間後,仍會定期提醒工程師(例如每30分鐘一次),而非完全靜默直到恢復正常。
13. SNS的訊息大小有限制嗎?
有,SNS對每則訊息的大小有上限(實際數值請查閱AWS官方文件),一般文字告警訊息遠低於此限制,不需特別擔心,但若嘗試夾帶大量附加資訊(如完整歷史數據),需留意是否超出限制。
14. 我可以用SNS通知Line或企業通訊軟體的Bot嗎?
可以,透過Lambda訂閱SNS主題,在該Lambda函式內呼叫對應通訊軟體的Bot API(如Webhook URL),將SNS訊息內容轉發過去,這是常見的跨平台整合作法,需自行撰寫轉發邏輯。
15. 告警門檻應該設定多嚴格?有沒有建議做法?
建議先參考設備規格書的安全操作範圍,並保守設定門檻(例如比實際危險值提前一段緩衝空間),上線初期密切觀察誤報率,再依實際運作情況逐步調整門檻與抑制邏輯,避免一開始就設定過於敏感的條件。
16. SNS主題的ARN寫死在程式碼裡安全嗎?
ARN本身不是機敏資訊(需要搭配IAM權限才能實際操作),但仍建議使用環境變數而非寫死在程式碼中,方便在不同環境(測試/正式)間切換設定,也符合較佳的程式維護實務。
17. 可以用同一個SNS主題處理溫度和壓力兩種告警嗎?
可以,搭配訊息屬性標記告警類型(如alert_type: "temperature""pressure"),訂閱者可依篩選政策決定要接收哪一類告警,或在單一通知中直接說明告警類型。
18. 值班人員離職或換手機號碼,訂閱設定要怎麼更新?
在SNS主控台的訂閱清單中,取消舊訂閱並新增新的訂閱者即可,不需要修改Lambda程式碼或Topic ARN,這也是SNS架構的優點之一——通知對象的異動與告警邏輯完全解耦。
19. 我該把告警邏輯放在解析Lambda裡,還是拆成獨立的Lambda函式?
兩種做法皆可。放在同一函式簡化架構,適合邏輯單純的場景;拆成獨立函式(解析Lambda透過另一條規則或SNS觸發告警Lambda)則有更好的關注點分離,方便獨立測試與版本更新,可依團隊架構偏好選擇。
20. 學會SNS告警後,下一步該學什麼?
建議接續學習如何把壓力溫度數據寫入DynamoDB,這不僅能實作本文提到的狀態變化觸發與冷卻時間邏輯,也是後續歷史趨勢分析與儀表板串接的基礎,這正是本系列文章下一篇的主題。

十一、下一步:讓 ATLANTIS 協助你規劃兼具本地與雲端的雙重告警架構

31年工業儀錶製造經驗 × 本地告警與雲端通知雙重防護

從變送器警報功能選型、SNS告警門檻設定,到告警疲勞抑制邏輯規劃,我們可以陪工廠IT團隊打造真正可靠的即時警報系統。

📞 02-2820-3405 免費選型諮詢 📧 線上快速詢價

業務一部 Ian:ian@atlantis.com.tw | 業務二部 Nori:nori@atlantis.com.tw


文章更新時間:2026年7月|作者:ATLANTIS 應用工程團隊|本文為系列教學文章第五篇,下一篇將深入「把壓力溫度數據寫入DynamoDB:打造無伺服器歷史記錄資料庫」。