#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <DHT.h>
// 連接資訊----------------------------------------------------
#define WIFI_SSID "Wokwi-GUEST"
#define WIFI_PASSWORD ""
#define WIFI_CHANNEL 6
const char* Linetoken = "bX3jP0YvL9f3sSBmGZRfhdY8c6eq4hnK56EqPlYvTey";
//------------------------------------------------------------
WiFiClientSecure client; // 網路連線物件
char host[] = "notify-bot.line.me"; // LINE Notify API網址
#define DHTPIN 4 // 定義DHT22連接到ESP32的引腳
#define DHTTYPE DHT22 // 定義使用的感測器類型
#define LED_PIN 13 // 定義LED連接到ESP32的引腳
#define PHOTO_PIN 33 // 定義光敏電阻連接到ESP32的引腳
DHT dht(DHTPIN, DHTTYPE);
void setup() {
Serial.begin(115200);
while(!Serial){delay(100);}
Serial.println();
Serial.println("******************************************************");
Serial.print("Connecting to ");
Serial.println(WIFI_SSID);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD, WIFI_CHANNEL);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
client.setInsecure();
dht.begin(); // 初始化DHT感測器
pinMode(LED_PIN, OUTPUT); // 設置LED引腳為輸出
}
void sendLineMessage(String message) {
if (message.isEmpty()) {
Serial.println(F("Error: The message to be sent is empty."));
return;
}
Serial.println(F("Connecting to LINE API..."));
if (client.connect(host, 443)) {
Serial.println(F("Connected to LINE API"));
String url = "/api/notify";
String payload = "message=" + message;
client.println("POST " + url + " HTTP/1.1");
client.print("Host: "); client.println(host);
client.print("Authorization: Bearer "); client.println(Linetoken);
client.println("Content-Type: application/x-www-form-urlencoded");
client.print("Content-Length: "); client.println(payload.length());
client.println();
client.print(payload);
delay(2000); // 等待回應
String response = client.readString();
Serial.println(F("Response from LINE API:"));
Serial.println(response);
client.stop();
} else {
Serial.println(F("Connection to LINE API failed"));
}
}
void loop() {
delay(2000); // 等待2秒,因為DHT22感測器的讀取間隔是2秒
float humidity = dht.readHumidity(); // 讀取濕度
float temperature = dht.readTemperature(); // 讀取溫度
int lightLevel = analogRead(PHOTO_PIN); // 讀取光照強度
if (isnan(humidity) || isnan(temperature)) { // 檢查是否讀取到正確的數值
Serial.println("Failed to read from DHT sensor!");
return;
}
// 如果讀取到的溫度或濕度超過合理範圍(例如:濕度<0 或 >100%,溫度<0°C 或 >50°C),則發送LINE訊息
if (humidity < 0 || humidity > 100 || temperature < 0 || temperature > 50) {
String errorMessage = "溫濕度超過合理範圍,請檢查設備狀態!";
errorMessage += "\n溫度=" + String(temperature) + "°C";
errorMessage += "\n濕度=" + String(humidity) + "%";
errorMessage += "\n光照強度=" + String(lightLevel);
sendLineMessage(errorMessage);
}
Serial.print("Humidity: ");
Serial.print(humidity);
Serial.print("%\t");
Serial.print("Temperature: ");
Serial.print(temperature);
Serial.print("°C\t");
Serial.print("Light Level: ");
Serial.println(lightLevel);
// 使用光敏電阻的讀數來控制LED亮燈,如果光照強度超過800,則點亮LED
if (lightLevel < 2900) {
digitalWrite(LED_PIN, HIGH);
} else {
digitalWrite(LED_PIN, LOW);
}
// 發送LINE訊息,如果光照強度超過2000
if (lightLevel > 2900) {
String message = "檢測環境光照強度過高,請協助儘速派人查看處理,目前環境狀態:";
message += "\n溫度=" + String(temperature) + "°C";
message += "\n濕度=" + String(humidity) + "%";
message += "\n光照強度=" + String(lightLevel);
sendLineMessage(urlEncode(message));
}
}
String urlEncode(String str) {
String encodedString = "";
char c;
char code0;
char code1;
char code2;
for (int i = 0; i < str.length(); i++) {
c = str.charAt(i);
if (c == ' ') {
encodedString += '+';
} else if (isalnum(c)) {
encodedString += c;
} else {
code1 = (c & 0xf) + '0';
if ((c & 0xf) > 9) {
code1 = (c & 0xf) - 10 + 'A';
}
c = (c >> 4) & 0xf;
code0 = c + '0';
if (c > 9) {
code0 = c - 10 + 'A';
}
code2 = '\0';
encodedString += '%';
encodedString += code0;
encodedString += code1;
}
yield();
}
return encodedString;
}