8 Port Telegram 告警機
Wokwi Wi-Fi 設置 (
Wokwi-GUEST/"")。硬編碼 的 8 組警報訊息內容。
使用
HTTPClient庫手動發送 Telegram 訊息。8 個輸入腳位 (
INPUT_PULLUP,LOW觸發)。
#include <Arduino.h>
#include <WiFi.h>
#include <HTTPClient.h> // 使用 HTTPClient 庫手動發送 Telegram API 請求
// --- Wokwi Wi-Fi 設置 (硬編碼) ---
const char* ssid = "Wokwi-GUEST";
const char* password = "";
// --- 內定 Telegram 配置 (已替換為您的有效值) ---
const String DEFAULT_TELEGRAM_TOKEN = "8022700986:AAGymymK9_d1HcTGJWl3mtqHmilxB64_5Zw";
const String DEFAULT_CHAT_ID = "7965218469"; // Chat ID 建議使用 long 類型
// --- 硬體定義 ---
struct InputPin {
int id; // 警報訊息組編號 (1 to 8)
int pin; // 實際連接的 ESP32 GPIO
};
// 您的硬體連接定義
InputPin inputMap[] = {
{1, 34}, {2, 35}, {3, 32}, {4, 33},
{5, 25}, {6, 26}, {7, 27}, {8, 14}
};
const int NUM_INPUTS = sizeof(inputMap) / sizeof(inputMap[0]);
// --- 配置變數 ---
String telegramToken = DEFAULT_TELEGRAM_TOKEN;
String chatID = DEFAULT_CHAT_ID;
// 警報解除與持續旗標 (這裡預設關閉)
bool sendOnRelease = false;
bool sendOnPersist = false;
// 硬編碼 8 組警報訊息內容
String alarmMessages[NUM_INPUTS];
// --- 狀態變數 ---
int lastPinState[NUM_INPUTS];
unsigned long lastTriggerTime[NUM_INPUTS] = {0};
const unsigned long PERSIST_INTERVAL = 60000; // 警報持續發送間隔 (60 秒)
// ----------------------------------------------------
// 函式宣告
// ----------------------------------------------------
void initializeAlarmMessages();
void initializeInputs();
void connectWifi();
void checkAndSendAlarm(int index);
void sendTelegramMessage(const String& msg);
// ----------------------------------------------------
// SETUP
// ----------------------------------------------------
void setup() {
Serial.begin(115200);
// 增加延遲,確保 Wokwi 核心啟動穩定
delay(500);
Serial.println("\n--- Wokwi ESP32 Alarm System Booting ---");
// 1. 初始化 8 組警報訊息
initializeAlarmMessages();
// 2. 初始化輸入腳位 (設置為上拉輸入)
initializeInputs();
// 3. 連接 Wi-Fi
connectWifi();
Serial.println("System Ready.");
}
// ----------------------------------------------------
// LOOP
// ----------------------------------------------------
void loop() {
// 1. 確保 Wi-Fi 連線
if (WiFi.status() != WL_CONNECTED) {
connectWifi();
delay(1000);
return;
}
// 2. 監控硬體輸入
for (int i = 0; i < NUM_INPUTS; i++) {
checkAndSendAlarm(i);
}
delay(10);
}
// ----------------------------------------------------
// 配置與初始化
// ----------------------------------------------------
void initializeAlarmMessages() {
// 設置 8 組警報訊息內容
for (int i = 0; i < NUM_INPUTS; i++) {
// 修正字串串接錯誤
alarmMessages[i] = String("警報觸發測試第") +
(i + 1 < 10 ? "0" : "") +
String(i + 1) +
"組";
Serial.print("Alarm Message "); Serial.print(i + 1); Serial.print(": "); Serial.println(alarmMessages[i]);
}
}
void initializeInputs() {
for (int i = 0; i < NUM_INPUTS; i++) {
// 設置為 INPUT_PULLUP,連接 LOW 時觸發
pinMode(inputMap[i].pin, INPUT_PULLUP);
lastPinState[i] = digitalRead(inputMap[i].pin);
}
}
void connectWifi() {
if (WiFi.status() == WL_CONNECTED) {
return;
}
Serial.print("Connecting to Wokwi Wi-Fi SSID: ");
Serial.println(ssid);
WiFi.begin(ssid, password);
int attempts = 0;
while (WiFi.status() != WL_CONNECTED && attempts < 30) {
delay(500);
Serial.print(".");
attempts++;
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("\nWiFi Connected!");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
} else {
Serial.println("\nWiFi Connection Failed! Will retry in loop.");
}
}
// ----------------------------------------------------
// 硬體與警報處理
// ----------------------------------------------------
void checkAndSendAlarm(int index) {
int currentState = digitalRead(inputMap[index].pin);
String message = alarmMessages[index];
unsigned long currentTime = millis();
// 警報觸發 (狀態從 HIGH 變為 LOW)
if (lastPinState[index] == HIGH && currentState == LOW) {
String triggerMsg = "[🚨 警報觸發] " + message + " (Port " + String(inputMap[index].id) + ")";
sendTelegramMessage(triggerMsg);
lastTriggerTime[index] = currentTime;
// 警報解除 (狀態從 LOW 變為 HIGH)
} else if (lastPinState[index] == LOW && currentState == HIGH) {
if (sendOnRelease) {
String releaseMsg = "[✅ 警報解除] " + message + " (Port " + String(inputMap[index].id) + ")";
sendTelegramMessage(releaseMsg);
}
lastTriggerTime[index] = 0; // 重置計時器
// 警報持續 (狀態持續為 LOW)
} else if (lastPinState[index] == LOW && currentState == LOW) {
if (sendOnPersist && (currentTime - lastTriggerTime[index] >= PERSIST_INTERVAL)) {
String persistMsg = "[⚠️ 持續警告] " + message + " (Port " + String(inputMap[index].id) + ")";
sendTelegramMessage(persistMsg);
lastTriggerTime[index] = currentTime; // 更新發送時間
}
}
// 更新狀態
lastPinState[index] = currentState;
}
// ----------------------------------------------------
// Telegram 函式 (使用 HTTPClient)
// ----------------------------------------------------
void sendTelegramMessage(const String& msg) {
// 移除強制阻擋檢查,因為用戶已提供真實值
if (WiFi.status() != WL_CONNECTED) {
Serial.println("Error: WiFi is not connected. Cannot send Telegram message.");
return;
}
HTTPClient http;
// URL 編碼訊息內容
String encodedMsg = "";
for (char c : msg) {
if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') {
encodedMsg += c;
} else {
encodedMsg += '%';
if ((byte)c < 16) encodedMsg += '0';
encodedMsg += String((byte)c, HEX);
}
}
// 構建 Telegram API URL
String telegramApiUrl = "https://api.telegram.org/bot" + telegramToken +
"/sendMessage?chat_id=" + chatID +
"&text=" + encodedMsg;
http.begin(telegramApiUrl);
Serial.print("Sending Telegram message...");
int httpCode = http.GET(); // 發送 HTTP GET 請求
if (httpCode > 0) {
Serial.printf(" [HTTP Code: %d]\n", httpCode);
if (httpCode == HTTP_CODE_OK) {
Serial.println("Telegram API Success. Message sent.");
} else {
Serial.print("Telegram API Error. Response: ");
Serial.println(http.getString());
}
} else {
Serial.printf(" [HTTP Error: %s]\n", http.errorToString(httpCode).c_str());
}
http.end();
}


沒有留言:
張貼留言