溫度異常自動告警:Lambda + SNS 實作工廠即時警報系統
工廠IT技術人員專用AWS Lambda + SNS即時告警系統ATLANTIS 自有品牌
溫度異常自動告警:Lambda + SNS 實作工廠即時警報系統
「Re-Atlantis」的品牌精神,是重現古代理想文明對精密秩序的追求——而秩序不只在於量測準確,更在於異常發生時系統能立即反應。過去工廠依賴人工巡檢與警報燈,如今我們可以用AWS SNS(簡易通知服務)在幾秒內把異常訊息送到工程師手機上。詳見 ATLANTIS 品牌故事。
一、為什麼要用SNS,而不是自己寫發簡訊的程式?
在第三篇的Lambda範例中,我們只用print()把異常訊息印到CloudWatch日誌,工程師仍必須主動打開主控台才能看到。本篇要解決的問題是:如何讓異常訊息主動找上工程師,而不是工程師主動找異常訊息。
到簡訊送達手機
通知管道
告警訊息
免費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是目前最快能把告警機制做出來的方式。
二、架構總覽:從溫度異常到手機通知
整條架構的關鍵在於③:SNS主題扮演「扇出(Fan-out)」的角色——Lambda函式只需要發布一次訊息,SNS就會自動把同一則訊息同時送給所有已訂閱的管道,不需要為每個通知管道分別寫程式碼。
三、建立SNS主題與訂閱者
步驟一:建立SNS主題
登入AWS主控台搜尋「SNS」,選擇「主題(Topics)」→「建立主題」,類型選擇「標準(Standard)」(相對於「先進先出FIFO」,一般告警通知場景使用標準類型即可),命名為例如factory-temp-alert。
步驟二:新增訂閱者
建立主題後,點擊「建立訂閱」,可以選擇的協定類型如下表:
| 訂閱協定 | 接收對象 | 適用情境 |
|---|---|---|
| SMS | 手機門號 | 需要最快速引起注意的緊急告警 |
| 電子郵件信箱 | 不需要立即反應但需要留存記錄的告警 | |
| Lambda | 另一個Lambda函式 | 需要進一步處理告警邏輯(如轉發至企業通訊軟體) |
| HTTP/HTTPS | 自訂Webhook端點 | 整合企業內部系統或第三方通知平台 |
對於工廠現場的溫度告警,我們建議同時訂閱SMS與Email:SMS確保值班人員第一時間收到通知,Email則留下完整的異常記錄供後續分析與稽核使用。
四、Lambda程式碼:判斷異常並發送SNS通知
以下範例延續第三篇的最小Lambda函式,加上呼叫SNS發布告警訊息的邏輯。
範例一:溫度異常判斷並發送SNS告警
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秒轟炸一次值班人員的手機。
簡易概念示範:狀態變化觸發邏輯(需搭配資料庫使用)
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訊息範例
TopicArn=TOPIC_ARN,
Subject="工廠溫度異常告警",
Message=message,
MessageAttributes={
"severity": {
"DataType": "String",
"StringValue": "critical"
}
}
)
接著在訂閱端設定「篩選政策」,例如某個Email訂閱只想接收severity為critical的訊息,即可在SNS主控台的訂閱設定中填入對應的篩選JSON,SNS會自動只轉發符合條件的訊息給該訂閱者,其餘訊息不會送達,也不會產生該訂閱者的額外通知費用。
七、ATLANTIS 具備本地告警功能,適合搭配雲端SNS雙重防護的產品

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

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

DPS-ED3.0 數位壓力開關 —— 集成壓力警報、過程控制與訊號輸出功能,數位輸出可同步觸發本地繼電器與雲端SNS通知
PS-2100X系列 防爆圓盲型壓力開關 —— 高設定點可重複性防爆壓力開關,適合危險環境下需要雙重告警保障的關鍵製程
完整規格請參考 ATLANTIS 產品型錄與壓力開關完整選型指南。
為什麼建議「本地告警」與「雲端告警」雙重並行?
雲端告警系統依賴網路連線、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主題有什麼差別?告警系統該選哪一種?
2. SMS訂閱需要事先驗證手機號碼嗎?
3. 一個SNS主題最多可以有幾個訂閱者?
4. 為什麼我的Lambda呼叫sns.publish()會出現權限錯誤?
sns:Publish動作,或授權的Resource範圍與實際使用的Topic ARN不一致,請檢查IAM政策的Action與Resource設定是否正確對應。5. 告警疲勞具體會造成什麼後果?
6. 簡易冷卻時間(Cooldown)邏輯要怎麼實作,Lambda本身不是無狀態的嗎?
7. SNS訊息篩選政策(Filter Policy)要在哪裡設定?
severity屬性為critical的訊息,設定後該訂閱者只會收到符合條件的通知。8. Email通知的內容可以是HTML格式嗎?
9. 我可以讓SNS通知同時轉發到企業內部的通訊軟體嗎?
10. 告警訊息裡應該包含哪些資訊,才能讓工程師快速判斷?
11. 如果Lambda執行時sns.publish()失敗,異常通知會遺失嗎?
12. 狀態變化觸發(Edge-Triggered)邏輯,跟簡易冷卻時間哪個比較好?
13. SNS的訊息大小有限制嗎?
14. 我可以用SNS通知Line或企業通訊軟體的Bot嗎?
15. 告警門檻應該設定多嚴格?有沒有建議做法?
16. SNS主題的ARN寫死在程式碼裡安全嗎?
17. 可以用同一個SNS主題處理溫度和壓力兩種告警嗎?
alert_type: "temperature"或"pressure"),訂閱者可依篩選政策決定要接收哪一類告警,或在單一通知中直接說明告警類型。18. 值班人員離職或換手機號碼,訂閱設定要怎麼更新?
19. 我該把告警邏輯放在解析Lambda裡,還是拆成獨立的Lambda函式?
20. 學會SNS告警後,下一步該學什麼?
十一、下一步:讓 ATLANTIS 協助你規劃兼具本地與雲端的雙重告警架構
31年工業儀錶製造經驗 × 本地告警與雲端通知雙重防護
從變送器警報功能選型、SNS告警門檻設定,到告警疲勞抑制邏輯規劃,我們可以陪工廠IT團隊打造真正可靠的即時警報系統。
📞 02-2820-3405 免費選型諮詢 📧 線上快速詢價
業務一部 Ian:ian@atlantis.com.tw | 業務二部 Nori:nori@atlantis.com.tw
文章更新時間:2026年7月|作者:ATLANTIS 應用工程團隊|本文為系列教學文章第五篇,下一篇將深入「把壓力溫度數據寫入DynamoDB:打造無伺服器歷史記錄資料庫」。