依照往例到 wiki 去查了一下:https://zh.wikipedia.org/zh-tw/MQTT
大致上先瀏覽一下內容,初學者看不懂很正常,知道一些歷史以及有一些不懂的名詞即可。我們將從最簡單的地方着手,所以先不考慮一些網路上的安全性,純粹如何利用 MQTT 來獲取風扇的訊息,或者透過網路來控制風扇。
ESP32-S3 的 Micropython 韌體 的韌體已經內建了 MQTT 程式庫模組(事實上,連 ESP8266 的韌體也內建),因此我們通常 import 進來就可以使用了。而在內建的 MQTT 還分 simple 與 robust 模組,到底有何區別與作用,您可以參考這篇文章:umqtt 連線/斷線的的注意事項,我們在此電風扇的應用上,就只使用 robust 模組。
我們對於 MQTT 的機制,透過實際的操作來說明:
首先,會有個提供 MQTT 服務的主機,這台主機通常在外網,有固定的外網 IP 或是 domain name, 例如我們這次測試的主機是免費的 "test.mosquitto.org"
訂閱者 可以根據主題向 MQTT 服務主機 訂閱,例如我們的風扇開發板可以向 “test.mosquitto.org" 訂閱 "FanControl" 這個主題。當有發佈者 發佈訊息到這個主題時,訂閱者可以收到傳來的訊息。例如,手機程式爲發佈者,傳送 "speed=3" 這個訊息到 ”FanControl" 主題,那我們的開發板將收到訊息。此時,我們可以解析此訊息,知道要調轉速爲 “3”,這樣就達到利用 MQTT 的機制來控制電風扇了!
發佈者程式示範:
import network
import time
from umqtt.robust import MQTTClient
import ubinascii
import machine
from secrets import WIFI_NAME, WIFI_PASS
print('Connecting to WiFi', end='')
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
if not wlan.isconnected():
wlan.connect(WIFI_NAME, WIFI_PASS)
t0 = 0
while (not wlan.isconnected()):
time.sleep(1)
t0 = t0 + 1
if (t0 > 10):
print('failed')
break
else:
pass
else:
print('connected')
#if (t0 > 10):
# Enable AP here
print('network config:', wlan.ifconfig())
client = MQTTClient(
client_id="client_test_fan_pub",
keepalive=6,
server="test.mosquitto.org",
ssl=False)
client.connect()
client.publish(b'FanControl', b'speed=3')
client.disconnect()
訂閱者程式示範:
import network
import time
from umqtt.robust import MQTTClient
import ubinascii
import machine
from secrets import WIFI_NAME, WIFI_PASS
print('Connecting to WiFi', end='')
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
if not wlan.isconnected():
wlan.connect(WIFI_NAME, WIFI_PASS)
t0 = 0
while (not wlan.isconnected()):
time.sleep(1)
t0 = t0 + 1
if (t0 > 10):
print('failed')
break
else:
pass
else:
print('connected')
#if (t0 > 10):
# Enable AP here
print('network config:', wlan.ifconfig())
client = MQTTClient(
client_id="client_test_fan_sub",
keepalive=60,
server="test.mosquitto.org",
ssl=False)
client.connect(False) # robust 模組,這裡填 False
def get_msg(topic, msg):
print(msg)
# 解析訊息,控制風扇
client.set_callback(get_msg)
client.subscribe(b'FanControl')
while True:
......
client.check_msg()
......
我們明天再來完善這兩個例子,融入風扇的控制流程中。