2022年12月13日 星期二

MicroPython 學習筆記 : ESP8266/ESP32 網路存取測試 (四)

本篇繼續使用陳會安老師大作 "超簡單Python/MicroPython物聯網應用" 這本書中提供的 xtools.py 模組來傳送 Line 訊息, 只要呼叫此模組中的 line_msg(token, message) 函式並傳入 Line Notify 權杖 (token) 與要傳送的字串 (message), 即可傳送 Line 訊息給特定人或群組. 在進行以下測試之前需先到  Line Notify 官網申請權杖 (token), 申請程序參考 : 


xtools.py 模組我有加以修改客製化, 並添加一些常用函式, 可從 GitHub 下載 : 


書中所附原始 xtools.py 我將其改名為 xtools_orig.py :


本系列全部文章參考 :


Line Notify 是免費服務, 每小時可傳送 1000 則訊息, 相當於每 3.6 秒可傳一則, 對於物聯網應用來說能夠每 5 秒傳一則其實就夠用了. 

xtools 中的 line_msg(token, message) 函式內容如下 :

def line_msg(token, message):
    headers = {
        "Authorization": "Bearer " + token,
        "Content-Type": "application/x-www-form-urlencoded"
    } 
    params = {"message": message}
    from xrequests import post
    r = post("https://notify-api.line.me/api/notify",
                    params=params, headers=headers)  
    if r is not None and r.status_code == 200:
        print("Message sent...")
    else:
        print("Error! Failed to send notification message...")  

這與我之前在 "Python 學習筆記 : Line Notify 訊息推播 (一) : 文字" 中 CPython 上測試時所用的 notify() 類似 : 

def notify(msg, token):
    url="https://notify-api.line.me/api/notify"                          # Line Notify API 網址
    headers={"Authorization": "Bearer " + token}                   # HTTPS 表頭
    payload={"message": msg}                                                # HTTPS 承載 (內容)
    r=requests.post(url, headers=headers, params=payload)    # 提出 POST 請求
    return "訊息發送成功!"

只不過此處向 Line Notify 提出 POST 請求時使用的是自訂的 xrequest.py 模組而非 MicrPython 內建的 urequests, 原因是 urequests 的 post() 函式不能使用 params 參數, 所以 "超簡單Python/MicroPython物聯網應用" 這本書作者將 urequest 添加 params 功能後改名為 xrequests, 參考 :


因為 xrequest.py 用到了自訂的 urlencode.py 模組, 所以也必須上傳此模組 :


總之, 欲使用 xtools 中的 line_msg() 函式傳送 Line 訊息基本上必須先將 xtools.py, xrequests.py, urlencode.py 這三個模組都上傳到 ESP32/ESP8266 開發板的根目錄下才行 (還要連線 WiFi 用的 config.py) :





以下使用 Witty Cloud 開發板進行測試, 因為此板內建一個按鈕 (GPIO4), 全彩 LED (GPIO12, 13, 15), 與光敏電阻 (A0), 如果要測試按一下傳送訊息, 或讀取亮度訊息, 不需要另外準備感測器. 關於 Witty Cloud 參考 :





從 MicroPython 開發板傳送 Line NotiFy 訊息的作法很簡單, 只要呼叫 xtools 的兩個函式即可. 首先呼叫 xtools.connect_wifi_led() 連線 WiFi 基地台, 然後定義權杖變數 token 與要傳送的訊息變數 message, 呼叫 xtools.line_msg(token, message) 即可 :

MicroPython v1.19.1 on 2022-06-18; ESP module with ESP8266

Type "help()" for more information.
>>> import xtools    
>>> xtools.connect_wifi_led()    
network config: ('192.168.43.98', '255.255.255.0', '192.168.43.1', '192.168.43.1')
'192.168.43.98'   
>>> token='ud7PaDL45fz849A0e1f4oaMCbRIkxMXapQCt3PfNkzz'        
>>> message='這是 MicroPython 開發板送出的訊息'      
>>> xtools.line_msg(token, message)     
Message sent... 
>>> xtools.line_msg(token, message)     
Message sent... 

結果如下 :




可以連續呼叫 line_msg(), 此處呼叫了兩次故收到兩個訊息. 

2023-01-01 補充 :

下面範例利用 Witty Cloud 開發板內建按鈕 (GPIO4) 之便, 測試按一下按鈕便傳送 Line 訊息, 關於按鈕用法參考後來寫的這篇 : 



程式碼如下 :

# main.py
import xtools    
import config
from machine import Pin, ADC
import time

ip=xtools.connect_wifi_led(config.SSID, config.PASSWORD)
token='ud7PaDL45fz849A0e1f4oaMCbRIkxMXapQCt3PfNkXX'
message='這是 MicroPython 開發板送出的訊息'
led=Pin(2, Pin.OUT)      
button=Pin(4, Pin.IN)
led.value(1)  # 預設熄滅 LED
send=False  #

while True:
    value=button.value()
    if value:              # 1=按鈕放開
        print("按鈕狀態 :", value)
        led.value(1)    # 熄滅 LED
        send=False
    else:                    # 0=按鈕按下
        print("按鈕狀態 :", value)
        led.value(0)     # 點亮 LED
        send=True
    if send:
        xtools.line_msg(token, message)
        time.sleep(5)
        send=False
    time.sleep_ms(200)    #

此處用 send 變數紀錄按鈕狀態 (預設 False), 內建按鈕按下時 GPIO4 為 0, 這時 send 會被設為 True, 會呼叫 lin_msg() 傳出 Line 訊息, 接著會暫停 3 秒 (因 Line Notify 限制最快 5 秒傳一個訊息, 此處設 5 秒), 然後將狀態改回 False, 無限迴圈最底下暫停 200 ms 目的是在測試時不要跑太快, 以免 Thonny 無回應. 




結果如下 : 




哇太棒了, 添加一個 repeater 後 WiFi 信號加強, 連頂樓也能順利連上網路了, 這樣就可以開始在頂樓安裝各種感測器, 然後用 Line Notify 將監控資訊傳到手機, 例如 : 
  • 頂樓自來水塔水位是否正常
  • 頂樓雨水收集桶水位高低
  • 氣候偵測器 (風速, 風向, 溫度, 濕度, 亮度, 雨量)
  • 大門來客報知器
  • 電話來電報知器
  • ATS 狀態 (太陽能/市電) 顯示器
新的一年希望一步步來實現這些專案. 

4 則留言 :

FCLu 提到...

您好,
我按步驟在ESP32上執行,
message='這是 MicroPython 開發板送出的訊息'
不知為何line收到只顯示英文" MicroPython "
若我先將上述message先自行轉成urlencoded
%E9%80%99%E6%98%AF%20MicroPython%20%E9%96%8B%E7%99%BC%E6%9D%BF%E9%80%81%E5%87%BA%E7%9A%84%E8%A8%8A%E6%81%AF
收到也是
%E9%80%99%E6%98%AF%20MicroPython%20%E9%96%8B%E7%99%BC%E6%9D%BF%E9%80%81%E5%87%BA%E7%9A%84%E8%A8%8A%E6%81%AF
請問可能是哪裡的問題?
Gary

小狐狸事務所 提到...

Hi, 我用 ESP32 開發板 ESP-WROOM-32 重新測試是正常的, 這應該與板子無關. 看來似乎與中文編碼有關, 您可以將程式寫在 main.py 檔案, 但要注意存成 utf-8 編碼之檔案, 然後按 reset 鈕試試看.

FCLu 提到...

謝謝您,因測試程式時是在VS code pymakr terminal下執行,line 始終看不到中文,upload後就正常可見到,真是有點奇怪

小狐狸事務所 提到...

了解, 聽說 VS CODE 很好用, 但我用慣了 Thonny 就懶得換了.