我的ESP32實做書籍:我出書了 ESP32 物聯網專題
博客來網址:https://www.books.com.tw/products/0010901195
實做說明
當我們從上一章學習如何利用ESP32所具備的WiFi上網能力,並到公開資訊網站上取得台灣各地PM2.5的數值,本章則要介紹如何讓ESP32成為一個小幫手,能幫我們監看倉庫的溫濕度,並在發生異常時發訊息通知我們,讓我們能立即處理異常,避免災害擴大,這樣是不是很方便呢?
而在台灣幾乎每個人都有手機,不管是Apple或是Android,也都會安裝Line通訊軟體來跟家人朋友聯繫,利用Line來打打字或是語音通訊都是免費的,而且還有可愛的貼圖可以用,所以發送Line訊息可以說是最方便即時的,不過ESP32要如何串接Line的訊息呢?ESP32又沒有手指是要如何打字呢?
Line-API工具
Line有提供一個官方的網站工具,可以讓我們透過該網站傳遞參數,參數則包括訊息內容及權杖,權杖則是代表要傳遞的Line群組,當網站收到這些參數之後就會將訊息傳遞到指定的Line群組。也就是說,ESP32並不是直接把訊息傳到某個人手機的Line裡面,而是透過某個網站協助中間轉傳訊息,通常這類的網站就通稱為API(Application Programming Interface),使用這些API工具我們就可以省去學習Line APP內複雜的通訊協定、機制、格式、架構…等等,只需要把資料傳給API,而API就會處理所有的通訊過程,讓我們省下很多程式開發的時間。
整理上面的內容,也就是說首先我們利用ESP32及DHT11監看現場的溫濕度(也可以再加上氣體偵測MQ2、水位感測…等),當發現異常時(例如溫度>40或濕度>85)就發送到Line的API網站,Line API收到我們的訊息之後,就會轉傳到指定的Line群組中,讓相關的管理人員收到訊息,然後立即處理。
一、申請Line Notify權杖
Line Notify的網站申請開通服務,首先在瀏覽器中輸入網址:https://notify-bot.line.me/,並點選右上角的登入。
輸入Line帳號密碼後,按下方的登入
完成登入,點選右上角的登入帳號/個人頁面,即可進入「已連動服務」管理頁面
Line群組通訊的密碼,若無此密碼,我們的Line可能每天都會收到一堆廣告訊息。
在設定權杖頁面分別輸入
- 名稱:未來發訊訊息通知時,會出現的名稱
- 對象:要發送訊息的群組,此處練習時先選擇「透過1對1聊天接收LINE Notify通知」
- 也就是傳訊給自己,另外這裡你會發現在清單中找不到你某個特定的朋友,而只能選「群組」來發送訊息,這是因為我們目前使用的Line通知是免費的Notify功能,若您要通知特定的「人」則必須申請Line Bot,這部份則較為複雜,本書先略過。
完成輸入後,按下方的發行即可獲得一組密碼,此即為權杖。
拿到權杖後,點選下方的複製按鈕將密碼複製起來,並貼在記事本上,避免遺失,若遺失也不用緊張,重新申請一次即可,不過就算申請的對象是同一個,每次的權杖密碼都是不相同的,但功能是一樣的,後面申請的也不會使之前申請的權杖失效。
確認申請完成,將會產生一個連動服務。
二、手動測試Line Notify
Line Notify權杖是否正常,也順便了解Line API的運作方式(如需要更詳細的Line Notify API可參閱網址:https://notify-bot.line.me/doc/)
首先我們先到連線到知名的API測試網址API Tester:https://apitester.com/(或者安裝POSTMAN API測試軟體),並依照規定輸入Line Notify的相關設定如下圖。
- 修改傳遞方式POST
- 輸入Line Notify API網站:https://notify-api.line.me/api/notify
- 輸入傳遞的訊息內容:message=這是測試
- 點選「+」號,增加一個表頭Request Header,我們會將密碼放在表頭與Line API做驗證
- -輸入表頭名稱:Authorization
- -輸入認證內容:Bearer 權杖密碼,要注意的是Bearer與權杖密碼中間有一個空白。
完成設定後後,按下下方的藍色Test按鈕,即可在手機收到LINE傳來的訊息。
其中前面【】內的名稱就是一開始申請時的名稱(圖X),而後方的訊息「這是測試」則是在API tester網站輸入的內容。
經由上面的測試可以發現,用ESP32傳LINE的方式就是將資料傳遞到LINE的API網站https://notify-api.line.me/api/notify,並將訊息內容及權杖密碼以參數方式夾帶給網站,網站收到後就會將訊息傳遞給權杖所對應的使用者。
下一節我們使用ESP32自動傳LINE時,也是一樣要指定這些訊息,就可以資訊傳遞給相關的人員。
另外如果您選擇傳訊的對象是一個群組,那麼要多一個動作:邀請LINE Notify進入群組內,否則會出現一個錯誤訊息是:此帳號尚未被邀請至已連動的群組。
三、ESP32 DHT11線路佈置
本部份參考前篇內容:第九篇-esp32-溫濕度顯示器(dht11+1602-lcd) ,完成線路佈置並測試讀取成功後,再進行下一個步驟。
四、程式撰寫
就如第二節所展示,這次我們的程式將使用wificlientsecure進行實做,wificlientsecure跟上一章的httpclient不同的地方在於wificlientsecure可以支援https加密協定,而httpclient只能用HTTP GET協定做參數傳遞,wificlientsecure及wificlient可以用來做POST協定。
程式主要分成幾4個流程
- 初始化設定:設定無線網路SSID, Password, LINE API網址, 權杖密碼等資訊
- 連線Wifi網路
- 在Loop中重複監看DHT11溫濕度資料
- 發現DHT11溫度或濕度過高,則利用wificlientsecure將資料POST到LINE網址
五、注意事項
最近很多夥伴說程式無法執行,會遇到「Connection Failed」的問題,主要是因為ESP32的1.0.6的核心會強迫使用SSL認證
此時可以先透過在Setup()內加上「client.setInsecure();」語法來解決,如下方紅色字的部份。
//請注意,ESP32 1.0.6版WiFiClientSecure有些問題,建議安裝1.0.4版
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <SimpleDHT.h>
//請修改以下參數--------------------------------------------
char SSID[] = "YourSSID";
char PASSWORD[] = "YourPassword";
String Linetoken = "Your Line Token";
int pinDHT11 = 14;//假設DHT11接在腳位GPIO14,麵包板左側序號8
//---------------------------------------------------------
SimpleDHT11 dht11(pinDHT11);//DHT11物件
WiFiClientSecure client;//網路連線物件
char host[] = "notify-api.line.me";//LINE Notify API網址
void setup() {
Serial.begin(115200);
//連線到指定的WiFi SSID
Serial.print("Connecting Wifi: ");
Serial.println(SSID);
WiFi.begin(SSID, PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(500);
}
//連線成功,顯示取得的IP
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
IPAddress ip = WiFi.localIP();
Serial.println(ip);
//client.setInsecure();//ESP32核心 1.0.6以上
}
void loop() {
//嘗試讀取溫濕度內容
byte temperature = 0;
byte humidity = 0;
int err = SimpleDHTErrSuccess;
if ((err = dht11.read(&temperature, &humidity, NULL)) != SimpleDHTErrSuccess) {
Serial.print("Read DHT11 failed, err="); Serial.println(err); delay(1000);
return;
}
//讀取成功,將溫濕度顯示在序列視窗
Serial.print("Sample OK: ");
Serial.print((int)temperature); Serial.print(" *C, ");
Serial.print((int)humidity); Serial.println(" H");
//設定觸發LINE訊息條件為溫度超過30或濕度超過80
if ((int)temperature >= 30 || (int)humidity >= 80) {
//組成Line訊息內容
String message = "檢測環境發生異常,請協助儘速派人查看處理,目前環境狀態:";
message += "\n溫度=" + String(((int)temperature)) + " *C";
message += "\n濕度=" + String(((int)humidity)) + " H";
Serial.println(message);
if (client.connect(host, 443)) {
int LEN = message.length();
//傳遞POST表頭
String url = "/api/notify";
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( String((LEN + 8)) );
client.println();
client.print("message="); client.println(message);
client.println();
//等候回應
delay(2000);
String response = client.readString();
//顯示傳遞結果
Serial.println(response);
client.stop(); //斷線,否則只能傳5次
}
else {
//傳送失敗
Serial.println("connected fail");
}
}
//每5秒讀取一次溫濕度
delay(5000);
}
除了傳遞文字之外,也可以傳遞貼圖或照片喔,此外也可使用LINE Library的方式則更為簡單,使用者可自行Google 「Line-Notify-ESP32」就會有更多的資訊喔。