ESP32 教學 | MicroPython | 透過 IFTTT – Line 通知 DHT11 溫濕度資訊 | 306

當我們的 ESP32 可以連上網後,便可以開始透過雲端服務來體驗不同的應用,結合我們生活常用的 Line 就是其中一種。Line Notify 為 Line 推出的訊息通知服務,它可以連動 IFTTT、Github 等來傳送所需要的訊息,這篇文章就來分享如何將 ESP32 DHT11溫濕度透過 IFTTT – Line Notify 服務,傳送訊息到我們手機上的 LINE,實現智慧化通知的功能。

Tips: 本文使用到之前的文章內容,有需要的朋友可以參考下面:

1. IFTTT 服務設定

IFTTT 是什麼? IFTTT 是 『If this, then that』的簡稱,它是一個網路服務平台的供應商,功用就是針對不同條件的網路應用,做出相對的反應,這有點像是程式邏輯 IF的概念 –> 如果…..發生什麼,那接下來就做什麼。一般程式是根據內部的條件做出判斷,IFTTT 服務就是把這個判斷的條件轉換成網路條件,很神奇吧!?

回到我們今天在 ESP32 想要實作的目標: 透過 LINE 通知 ESP32 的 DHT11 感測器資訊。 這個就可以藉由 IFTTT 網路服務來完成,而我們需要的 service 有兩個: webhooksline notify, webhooks 就是負責接收 http request 用的機制, line notify 負責訊息通知的工作,想到要怎麼做了嗎? 沒錯,就是 If 『webhook 接收到來自 ESP32 的 http request』,Then 『line notity 發出訊息通知到用戶』,概念就是這樣,接下來就先到 IFTTT 官網來申請與設定相關的參數。

Step1: 打開瀏覽器連上 https://ifttt.com/ ,打入 email 帳號,按下 Get Started。(如果有Google、Apple、Facebook 帳號可以直接登入)

ifttt

Step 2: 輸入欲設定的密碼。

Step 3: 登入後,選擇右上方 Create 按鈕,建立一個新的 Applet(也就是新增一個 If-Then 機制)。

Step 4:在 IF This 欄位中,按下 Add,增加 If 的條件。

Step 5: 在 service 中,選擇 webhooks 服務。

Step 6: 因為我們要接受來自 ESP32 發出的 http request,所以按下 Receive a web request 按鈕。

Step 7: 按下 Connect。

Step 8: 輸入 Event 的名稱,這邊注意一下,這個名稱會使用在等一下 ESP32 傳送的 Http GET Request 的網址列,最後完成 If Trigger 條件設定。(此次範例採用 room_status 作為事件名稱)

Step 9: 接著進行關於 Then 的程序,一樣按下 Add 按鈕新增。

Step10:找到 Line 服務,按下按鈕。

Step11: 按下 Send message,這個就是 Line Notify 服務。

Step 12: 一樣按下 Connect。

Step 13: 因為需要用到 Line的服務,此時就要登入自己的 Line。

Step 14: 按下同意連動 IFTTT 跟 LINE 的個人服務。

Step 15:填入 接受訊息者訊息內容定義,訊息接收可以設定為群組,這邊設定為 LINE Notify 1對1的聊天室 ; 訊息定義可以自訂想要的格式,因為我們想要傳送溫度與濕度兩個數值,{{value1}} 跟 {{value2}} 就分別代表 ESP32 Http GET Request 的上傳參數,< br >就是換行的意思,修改完成後按下 Create Action。

Step 16:接著按下 Continue 完成 IF-THEN 的條件設定。

Step 17:將這個 IF-THEN 的動作設定一個容易理解的名稱, 也就是 Applet 命名。

Step 18:如果一切都順利完成後,回到首頁,點選 MyApplet 應該就會看到剛剛設定的項目。

2. 如何使用 Webhooks API

現在我們已經設定好 IFTTT 的 Applet,一旦 webhooks 被觸發,Line Notify 就會傳遞訊息給我們,所以現在先確定一下 webhooks 的相關 API 怎麼使用。

一樣登入後,點選右上方帳號圖示,找到 My Services:

接著點選 webhooks 圖示:

Webhooks 的 API 使用就放在 Documentation 內:

這邊就有個人專屬的 API Key 跟 簡單觸發事件的 GET 或 POST 範例。

在 HTTP GET 的範例中,{ event } 就是填入事件的名稱,以我們上節的範例就是 room_status,如果要上傳數值的話,則將網址最後面加入” ?value1=xxx&value2=xxx“,完整的觸發事件網址就會變成:https://maker.ifttt.com/trigger/room_status/with/key/{persional_key}?value1={xx}&value2={xx}

3. 透過 IFTTT – Line Notify 通知 DHT11溫濕度資訊

現在可以開始進行今天的的測試,電路連接的方式與先前都相同,將 DHT11 感測器的資料線與 ESP32 的 GPIO14 連接,連接圖如下:

https://jimirobot.com.tw/image/esp32/306/ps_dhckt.jpg

>> 完整程式碼

import machine,dht,utime,time,network,urequests
import gc

def go_wifi():
    try:
        wifi.active(False)
        wifi.active(True)
        wifi.connect('tp_station','00xx00xx')
        print('start to connect wifi')
        for i in range(20):
            print('try to connect wifi in {}s'.format(i))
            utime.sleep(1)
            if wifi.isconnected():
                break          
        if wifi.isconnected():
            print('WiFi connection OK!')
            print('Network Config=',wifi.ifconfig())
        else:
            print('WiFi connection Error') 
    except Exception as e: print(e)
        
api_key='diwxxxxx-bLDxxxxxxx'		# personal api_key
d11=dht.DHT11(machine.Pin(14))      # GPIO14 as the DHT11 dataline
wifi= network.WLAN(network.STA_IF)
go_wifi()

while 1:
    d11.measure()
    line_url='https://maker.ifttt.com/trigger/room_status/with/key/{}?value1={}&value2={}'.format(api_key,d11.temperature(),d11.humidity())  
    try:
        gc.collect()
        line_res= urequests.get(line_url)
        print('code={},content={}'.format(line_res.status_code,line_res.text))
    except Exception as e: 
        print(e)
        go_wifi()  
    line_res.close()
    time.sleep(10)

>> 程式解說

import machine,dht,utime,time,network,urequests
import gc

def go_wifi():
    try:
        wifi.active(False)
        wifi.active(True)
        wifi.connect('tp_station','00xx00xx')
        print('start to connect wifi')
        for i in range(20):
            print('try to connect wifi in {}s'.format(i))
            utime.sleep(1)
            if wifi.isconnected():
                break          
        if wifi.isconnected():
            print('WiFi connection OK!')
            print('Network Config=',wifi.ifconfig())
        else:
            print('WiFi connection Error') 
    except Exception as e: print(e)

首先匯入一些會用到的 module, 像是 dht、time、urequests 等,這邊多匯入一個 gc module,gc 為記憶體回收相關用途,由於發出 https 請求時需較大的記憶體,後面程序將會採用 gc 內的方法來避免記憶體不足現象發生。go_wifi() 為自定義的 wifi 連線函數,同時寫一個 20秒 的 timeout 機制,一旦連線成功後,顯示 ip 相關參數。

api_key='diwxxxxx-bLDxxxxxxx'		# personal api_key
d11=dht.DHT11(machine.Pin(14))      # GPIO14 as the DHT11 dataline
wifi= network.WLAN(network.STA_IF)
go_wifi()

while 1:
    d11.measure()
    line_url='https://maker.ifttt.com/trigger/room_status/with/key/{}?value1={}&value2={}'.format(api_key,d11.temperature(),d11.humidity()) 

api_key 填入在 IFTTT 的 Webhooks 服務所查到的 api_key,接著建立 dht11與 wifi 的物件,wifi 設定為 station 模式,執行 go_wifi() 來連上指定的基地台,取得網路位置。

while 迴圈內的第一個動作為進行 DHT11的溫濕度量測,溫濕度將透過 d11.temperature() 與 d11.humidity() 回傳出,後續放入 http request 的 GET 網址內,line_url 參考上節的 api 範例建立。 ifttt 需要使用 HTTPS 的通訊,網址內的開頭為 https://,{} 的3個變數就帶入 api_key、溫度、濕度,value1 跟 value2 會對應到我們在在設定 IFTTT line-notify 服務的 value1 跟 value2。

    try:
        gc.collect()
        line_res= urequests.get(line_url)
        print('code={},content={}'.format(line_res.status_code,line_res.text))
    except Exception as e: 
        print(e)
        go_wifi()  
    line_res.close()
    time.sleep(10)

為在發出 HTTPS 請求過程中,出現系統意外時可以知道詳細資訊(大部分是記憶體不足),這邊使用 try -except 來執行網路動作。gc.collect() 可以手動回收不再使用的物件(記憶體空間),因此將其用在 requests 前,確保 ESP32 記憶體充足性。之後將伺服器 response 的內容,存成 line_res 的物件,同時 print 輸出狀態碼( 如200、202、400等)跟訊息內容參考。如果發生程式的系統意外(Exception),程式第 35 行 print(e) 將印出對應的錯誤訊息,並再一次執行 go_wifi(),確保穩定連線狀態。

最後完成 IFTTT 資料上傳後,line_res.close() 關閉 http 連線,time.sleep(10) 為等待10秒,再次連線 IFTTT 伺服器更新最新的溫濕度值。

>> 執行結果

在啟動程式後,開啟 Line 程式,順利的話,每隔十秒就會陸續收到來自 LineNotity 訊息:

4. 總結

本篇主要分享 如果想要透過 Line 來接收 ESP32 上傳訊息時, 可以採用 IFTTT 連接 LineNotify 的解決方案來實現, IFTTT 免費的版本可以使用 3 個 Applet,對於基本測試上來說應該夠用。以我們本次的實驗來說,實務上當然不需要每隔 10 秒就更新訊息,而應設計在程式內設定判斷邏輯,如溫度或濕度超過設定數值時,才進行通知會比較合理,這部分就看各位如何去應用囉!

今天的內容就到這邊,如果各位有遇到什麼問題或想看那些教學內容,也歡迎在下面留言或寫信與我討論囉~

↓↓↓↓↓↓賣場連結↓↓↓↓↓↓

歡迎大家有需要的話,可以多多支持一下我們的蝦皮賣場喔! 😀 

吉米家官方店-創客機器人材料專賣 https://shopee.tw/jimirobot.tw

Follow JIMI哥 Twitter : https://twitter.com/jimirobot  <–得到最新文章通知

This Post Has 7 Comments

  1. 使用thonny python 執行程式時一直跳出
    Traceback (most recent call last):
    File “”, line 28, in
    File “dht.py”, line 17, in measure
    OSError: [Errno 116] ETIMEDOUT

    1. HI~

      這個訊息是指出 ESP32 與 DHT11 兩者的通訊發生了 Timeout (也就是ESP32接收DHT11訊息有異常),這部分可以檢查硬體(電路)和軟體兩個地方,電路上可檢查DHT11腳位是否接好,電源/GND是否接對, 軟體部分就是要檢查設定 DHT11的腳位是否為指定的 GPIO (本篇文章為 GPIO14, 程式碼第23行)。

      希望有幫助到你這邊。

  2. 不好意思,為什麼程式照抄了,line仍然無法接收到通知呢?

  3. Network Config= (‘192.168.216.206’, ‘255.255.255.0’, ‘192.168.216.154’, ‘192.168.216.154’)
    code=200,content=Congratulations! You’ve fired the %E6%BF%95%E5%BA%A6%E7%9B%A3%E6%8E%A7 event
    網路成功連接,但後面一直跳出You’ve fired the %E6%BF%95%E5%BA%A6%E7%9B%A3%E6%8E%A7 event
    我成功觸發一個事件,但LINE就是跳不出通知來?

    1. HI ~
      在這個範例中,ESP32只是作為一個發出 HTTP Request 的裝置,從您的留言來判斷,看起來像是 IFTTT 後端處理的問題(因為有順利接收 IFTTT回傳成功 Fired Event),所以可以再次檢查一下關於 IFTTT 服務的細部設定是否OK(比如webhook -> line 的連接,或 line 發出訊息的格式,或兩個觸發條件是否都 Connected 等等),測試IFTTT 事件也可以透過Chrome/ Firefox 做就可,在網址列打入 https://maker.ifttt.com/trigger/room_status/with/key/{personal_key}?value1=123&value2=123 (當然{personal_key}換成自己申請到的)類似的東西就可以進行測試,如果有其他問題的話,後續歡迎再提出討論~

  4. 使用thonny python 進行 但網路成功連結上了
    可是有時會出現’module’ object has no attribute ‘IPPROTO_SEC’
    或是function takes 3 positional arguments but 2 were given
    最後會NameError: name ‘line_res’ isn’t defined

    1. HI~ 這個訊息我目前在測試時還沒遇過,如果可以的話,跟我說一下 你測試時用的硬體 + Micropython 韌體版本 + 測試的完整code + Thonny 版本 , 我再找時間測試一下,看是否可以找出問題根源,TKS!

發佈留言

Close Menu