[教學] 認識 MicroPython (二) - 啟用 WebREPL 遠端 WebSocket 服務

安裝了 MicroPython 之後,花了一點時間,參考官網介紹的那些模組與指令,粗淺了解一下支援 NodeMCU、ESP8266 的 Python 模組,同時也想試驗一下,把 Arduino IDE 中,最簡單的 Blink 範例程式移植到 MicroPython 來。
要在 MicroPython 裡面寫入程式,你可以直接用 Python 語言的寫檔語法:
fp = open('main.py', 'w')
fp.writeline('import time\n")
fp.writeline('from machine import Pin\n')
...
只是這樣的搞法,程式出現小錯誤,要用上述寫檔方法改正,會很麻煩。WebREPL目前有上傳、下載檔案的功能,還不如在電腦編輯好,再用這個工具上傳比較方便。

啟用 WebREPL

為了方便上傳我們第一個程式 main.py,先在直譯器裡面,開啟 WebREPL 服務。開啟的方式很容易,就是執行匯入 webrepl_setup 模組:
import webrepl_setup
執行這個模組之前,我們先看一下開機自動執行檔 boot.py,裡面的內容長什麼樣?
在 REPL 介面中,先看看目前檔案系統存在哪些檔案,以及 boot.py 檔案內容。
>>> import uos
>>> uos.listdir()
['boot.py']
>>> fp=open('boot.py','r')
>>> fp.readlines()
['# This file is executed on every boot (including wake-boot from deepsleep)\n', '#import esp\n', '#esp.osdebug(None)\n', 'import uos, machine\n', '#uos.dupterm(None, 1) # disable REPL on UART(0)\n', 'import gc\n', '#import webrepl\n', '#webrepl.start()\n', 'gc.collect()\n']
可以看到,目前 import webrepl 這行前面被打了一個井號,webrepl.start也是,目前沒有被啟用。

在 REPL介面中,啟用 WebREPL

利用內建的設定模組,啟用 WEBREPL

讓我們正式啟用 WebREPL,並 (E)nable 開機時就自動啟動,輸入安全密碼 (以下示範用 mynodemcu 當密碼),最後決定要不要馬上重開機。
>>> import webrepl_setup
WebREPL daemon auto-start status: disabled

Would you like to (E)nable or (D)isable it running on boot?
(Empty line to quit)
> E
To enable WebREPL, you must set password for it
New password (4-9 chars): mynodemcu
Confirm password: mynodemcu
Changes will be activated after reboot
Would you like to reboot now? (y/n) n

到此為止,WebREPL 已經啟用了。以後每次 NodeMCU 重新上電,都會自動啟用 WebREPL。
先別急著重開機,看看上面的動作,造成哪些變化?
造成哪些變化?

啟用後,檔案被改變,而且多了webrepl_cfg.py 這個檔案

檔案的部份,多了 webrepl_cfg.py:
>>> uos.listdir()
['boot.py', 'webrepl_cfg.py']

webrepl_cfg.py的內容

用下面指令,查看 webrepl_cfg.py的內容

>>>
>>> fp = open('webrepl_cfg.py','r')
>>> webreplcfg = fp.readlines()
>>> print(*webreplcfg)
PASS = 'mynodemcu'

原來,裡面放的是 WebREPL 連線登入密碼。為了安全起見,稍後你可以自己把這個密碼改掉,免得未來NodeMCU被駭客透過 WebREPL 入侵。

開機執行檔 boot.py 的 webrepl 已經被啟用

原來的開機執行檔 boot.py 發生哪些變化:

>>> fp = open('boot.py','r')
>>> bootfile = fp.readlines()
>>> print(*bootfile)
# This file is executed on every boot (including wake-boot from deepsleep)
 #import esp
 #esp.osdebug(None)
 import uos, machine
 #uos.dupterm(None, 1) # disable REPL on UART(0)
 import gc
 import webrepl
 webrepl.start()
 gc.collect()
>>>

可以發現,boot.py 其中兩行,前面的註解#符號被拿掉了:
import webrepl
webrepl.start()
開機時,boot.py 會自動啟動 WebREPL。而 webrepl.start() 會去比對 webrepl_cfg.py 裡面設定的密碼。
現在可以按下 Ctrl-D ,把 NodeMCU 重開機。
重開機之後,WebREPL 已經啟動,並以 ws://192.168.4.1:8266 為網址。
MPY: soft reboot
WebREPL daemon started on ws://192.168.4.1:8266
Started webrepl in normal mode
MicroPython v1.12 on 2019-12-20; ESP module with ESP8266
Type "help()" for more information.
>>>
NodeMCU 裡面這個微型的遠端通訊界面,走的是單一連線的 WebSocket 通訊協定,因為目的只是讓管理者從內網連線進來執行相關系統設定,所以只提供單一連線服務,一次一個連線,安全性也沒有特別被考量。建議程式正式上線時,不要預設開機啟動 WebREPL。
而且 WebSocket 是在背景執行,會佔用 CPU 時間,因此原來系統中其他已經在運作中的程式,會受到影響。在某些繁重的程式執行下,WebREPL 有可能停止運作而沒反應。連線 WebREPL,必須使用 client 用戶端程式,這用戶端程式,是包含在一個網頁檔案中,直接用官方網址,便可開啟這個用戶端程式,不用特別安裝在你的電腦:

連接 WiFi 內網,將 NodeMCU 設定成 Station Mode

除了連線 NodeMCU 的 WebREPL 設定檔案之外,我希望同時使用一般的網際網路連線,所以我不會想把 NodeMCU 變成 AP 模式,變成 AP 模式,你的電腦就必須直接連線到 NodeMCU的 WiFi SSID。
以下操作,我會把 NodeMCU 的 WiFi,設定為 Station 模式,透過以下幾個步驟,連線到你的 WiFi AP 主機。這些指令不用背,按一下 help(),就可以直接複製貼上這些指令。

第一步 匯入 Network 模組,起始一個 Station 模式的 WLAN,active。

>>> import network
>>> sta_if = network.WLAN(network.STA_IF)
>>> sta_if.active(True)
#6 ets_task(4020f4d8, 28, 3fff9590, 10)

第二步 掃描附近的 WiFi AP,確認你要連線的 WiFi

>>> sta_if.scan()
[(b'crown', b'<7\x86B4\xb5', 4, -72, 3, 0), (b'infopro-107', b'\xf4\x8c\xeb\xa8\x81\xc2', 5, -76, 4, 0), (b'HP-Print-40-Color LaserJet Pro', b'\xb0\x10A\n\xc6@', 6, -61, 1, 0), (b'WK_Test', b'\x9c\\\x8e\xb4t\xb8', 6, -89, 3, 0), (b'bossla', b'`cLxn,', 8, -85, 4, 0), (b'infopro103-2', b'\xb0n\xbfe\xbc ', 10, -63, 3, 0), (b'dlink-9884_Sunrich', b'\x10b\xeb\x97\x98\x84', 11, -75, 4, 0), (b'dlink-guest_Sunrich', b'\x10b\xeb\x97\x98\x85', 11, -69, 4, 0), (b'infopro105A', b'\x04\xd4\xc4\x08\xca\xb8', 11, -66, 3, 0), (b'WK_191', b'xDv\xd6q%', 11, -88, 4, 0), (b'infopro106N', b'\xb09V\xcf%\x92', 13, -85, 3, 0)]

第三步 連線我家那台 D-LINK 的 WiFi AP,並確認已經連線

下面用密碼 12345678 連線 dlink-guest_Sunrich 這台 WiFi AP
>>> sta_if.connect("dlink-guest_Sunrich", "12345678")
>>> sta_if.isconnected()
True

第四步 查看目前 DHCP 配置給 NodeMCU 的 IP Address

>>> sta_if.ifconfig()
('192.168.0.132', '255.255.255.0', '192.168.0.1', '192.168.0.1')
>>>
可以看到,目前 NodeMCU 的 IP address 是 192.168.0.132,WebREPL的網址因此變為ws://192.168.0.132:8266

基本上,當你執行了以上指令之後,下次重新開機,或者斷電重開,都會自動連線。
你也可以直接把以上連線指令,寫入 boot.py 中,這樣每次開機,NodeMCU 就會確保自動連線。

第五步 執行 WebREPL 用戶端 Client 程式

你可以用瀏覽器,直接連線以下 micropython 網址,開啟用戶端程式:
http://micropython.org/webrepl/
或者你習慣先下載用戶端程式後,在自己電腦開啟 webrep.html 來執行用戶端也行:
https://github.com/micropython/webrepl/archive/master.zip
之後,你會看到瀏覽器出現以下畫面:
WebREPL 用戶端 Client 程式
WebREPL 用戶端畫面

第六步 輸入網址 ws://192.168.0.132:8266 連線

在畫面左上角的網址列,輸入網址,然後按 Connect 連線後,用戶端程式會要求輸入你之前啟用 WebREPL 所設定的那組密碼,輸入後,就可以利用網路,在遠端控制你的 NodeMCU 了,或者上傳、下載檔案。

到此為止,又多了一種可以跟 NodeMCU 互動的方式,馬上可以開始試著寫入第一個小程式了。


沒有留言:

張貼留言