本文簡要介紹了搭建 EMQX 服務器實現基于 MQTT 協議遠程控制 NodeMCU ESP8266 板載 LED 的解決方案。
簡介
1. MQTT
MQTT(Message Queuing Telemetry Transport)是一種基于 publish/subscribe (發布/訂閱) 模式的 輕量級 通訊協議,構建于 TCP/IP 協議上,由 IBM 在1999年發布。
1MQTT.png (154.63 KB, 下載次數: 2)
下載附件
2024-9-24 20:14 上傳
MQTT 可以實現用極少的代碼和有限的帶寬,為連接遠程設備提供實時可靠的消息服務 。
2. EMQXEMQX 是一款大規模分布式物聯網 MQTT 服務器,單集群支持 1 億物聯網設備連接,消息分發時延低于 1 毫秒。為高可靠、高性能的物聯網實時數據移動、處理和集成提供動力。
3. Home AssistantHome Assistant (HA) 家庭助理,是一款基于 Python 的智能家居開源系統,可以方便地連接各種外部設備,支持眾多品牌的智能家居設備。
方案
安裝 Home Assistant
使用 Docker 容器安裝 Home Assistant , 下載 Docker 軟件; C 盤根目錄新建文件夾 homeassistant ; 下載部署文件 GitHub 并解壓得到 docker-compose.yml 保存至上述 homeassistant 文件夾; Windows 打開 命令提示符 或 Windows PowerShell,輸入如下代碼實現自動下載鏡像 - cd C:\homeassistant
- docker-compose.yml
- docker-compose up
復制代碼
安裝過程需大約 30 分鐘,即可在 Docker 容器中創建 Home Assistant 鏡像; 自動從鏡像安裝 Home Assistant 到容器。代碼文件 docker-compose.yml 將映射 Home Assistant 配置文件到 C:/homeassistant 文件夾; 瀏覽器輸入網址 http://localhost:8123/ 進入Home Assistant 主界面,創建智能家居賬號。
詳見:How to run Home Assistant Container on Windows using Docker - Kiril Peyanski's Blog .
安裝 EMQX
使用 EMQX 最簡單的方式是在 EMQX Cloud 上創建完全托管的 MQTT 服務。 這里我們使用 Docker 運行 EMQX Windows 命令行或 PowerShell 輸入并執行如下代碼 - docker run -d --name emqx -p 1883:1883 -p 8083:8083 -p 8084:8084 -p 8883:8883 -p 18083:18083 emqx/emqx:latest
復制代碼
等待進度條下載和部署完成(大約5分鐘),即可獲得 EMQX 服務器。 Docker 內的 localhost 或 127.0.0.1 指向的是容器內部地址,如需訪問宿主機地址請使用宿主機的真實 IP .
詳見:Gitee .
配置 EMQX
(1)瀏覽器打開網址 http://localhost:18083/ ,初始登錄賬戶名 admin 密碼 public ; (2)依次打開 訪問控制 - 客戶端認證 - 創建 - Password-Based - 內置數據庫 - (默認配置)- 創建 ; (3)用戶管理 - 新建用戶 - 自定義用戶名和密碼(建議 admin).
連接 EMQX 與 HA(1)命令行或 PowerShell 輸入 ipconfig 獲取本地計算機 IPv4 地址,如 42.34.25.153 (2)配置 Home Assistant ,依次點擊設置 - 設備與服務 - 添加集成 - 搜索 MQTT - 填寫代理信息。 代理欄輸入計算機 IP 地址,端口 1883,用戶名和密碼為 EMQX 中創建的用戶信息。
(3)點擊 提交 后顯示 成功創建 MQTT ,此時 集成 選項下出現 MQTT 條目,EMQX 網頁 集群 的 總連接數 和 在線連接數 由 0 變為 1,表明 MQTT 設備已連接。
參考:MQTT 接入 Home Assistant .
連接 ESP8266 與 EMQX
將如下代碼下載至 ESP8266 開發板, - #include <ESP8266WiFi.h>
- #include <PubSubClient.h>
- #define LED 2 // on-board LED D4
- // WiFi
- const char *ssid = "xxx"; // Enter your WiFi name
- const char *password = "xxxxxx"; // Enter WiFi password
- // MQTT Broker
- const char *mqtt_broker = "xx.xx.xx.xx"; // EMQX Server IP
- const char *topic = "emqx/esp8266"; // MQTTX topic
- const char *mqtt_username = "UART"; // EMQX Server User Name
- const char *mqtt_password = "123456"; //EMQX Server User Password
- const int mqtt_port = 1883;
- bool ledState = false;
- WiFiClient espClient;
- PubSubClient client(espClient);
- void setup() {
- // Set software serial baud to 115200;
- Serial.begin(115200);
- delay(1000); // Delay for stability
- // Connecting to a WiFi network
- WiFi.begin(ssid, password);
- while (WiFi.status() != WL_CONNECTED) {
- delay(500);
- Serial.println("Connecting to WiFi...");
- }
- Serial.println("Connected to the WiFi network");
- // Setting LED pin as output
- pinMode(LED, OUTPUT);
- digitalWrite(LED, LOW); // Turn off the LED initially
- // Connecting to an MQTT broker
- client.setServer(mqtt_broker, mqtt_port);
- client.setCallback(callback);
- while (!client.connected()) {
- String client_id = "esp8266-client-";
- client_id += String(WiFi.macAddress());
- Serial.printf("The client %s connects to the public MQTT broker\n", client_id.c_str());
- if (client.connect(client_id.c_str(), mqtt_username, mqtt_password)) {
- Serial.println("Public EMQX MQTT broker connected");
- } else {
- Serial.print("Failed with state ");
- Serial.print(client.state());
- delay(2000);
- }
- }
- // Publish and subscribe
- client.publish(topic, "hello emqx");
- client.subscribe(topic);
- }
- void callback(char *topic, byte *payload, unsigned int length) {
- Serial.print("Message arrived in topic: ");
- Serial.println(topic);
- Serial.print("Message: ");
- String message;
- for (int i = 0; i < length; i++) {
- message += (char) payload[i]; // Convert *byte to string
- }
- Serial.print(message);
- if (message == "on" && !ledState) {
- digitalWrite(LED, LOW); // Turn on the LED
- ledState = true;
- }
- if (message == "off" && ledState) {
- digitalWrite(LED, HIGH); // Turn off the LED
- ledState = false;
- }
- Serial.println();
- Serial.println("-----------------------");
- }
- void loop() {
- client.loop();
- delay(100); // Delay for a short period in each loop iteration
- }
復制代碼
需要注意 MQTT 服務器地址,若是 EMQX Cloud,則根據創建遠程節點填寫地址;若是本地計算機或Docker容器,則填寫本地物理 IP 地址。 主題為 MQTTX 客戶端定義的訂閱名稱,客戶名和密碼則對應 EMQX 服務器客戶端用戶定義。
測試
在 MQTTX 客戶端向目標主題發送控制文本 on 和 off 以控制板載 LED
esp8266_MQTT_led.png (37.57 KB, 下載次數: 0)
下載附件
2024-9-24 20:16 上傳
注意發送文本格式選項更改為 Plaintext .
Arduino IDE 的串口助手監控可以觀察到反饋信息
esp8266_MQTT_UART_led.png (25.96 KB, 下載次數: 4)
下載附件
2024-9-24 20:16 上傳
與 MQTTX 客戶端操作類似,在 HomeAssistant 的 MQTT 設置 中向目標主題發送消息,即可控制 LED 的亮滅
esp8266_HA_MQTT_LED.png (38.88 KB, 下載次數: 2)
下載附件
2024-9-24 20:16 上傳
參考:ESP8266 + MQTT :如何實現 LED 燈的遠程控制 | EMQ
視頻https://www.bilibili.com/video/BV1CrsYeHEsZ/
總結
完成該項目的關鍵在于環境搭建,即 HomeAssistant 和 EMQX 服務器的安裝,由于是在 Windows 操作系統環境下,需要將其安裝于 Docker 容器中運行,而 Docker 軟件通過檢索實現鏡像安裝需要科學上網,因此環境搭建是關鍵。 此外,該項目可進行擴展連接智能家居平臺 HomeAssistant,同樣安裝于 Docker 容器,只需要進行 MQTT 配置即可實現開關可視化和 APP 遠程 LED 控制。
HA_esp8266_LED.png (16.03 KB, 下載次數: 2)
下載附件
2024-9-24 20:16 上傳
|