【Follow me第二季第2期】开发板通过 MQTT 协议接入 Home Assistant
根据任务要求,完成环境搭建和开发板接入。具体包括
- Docker 安装(Linux系统环境)
- HomeAssistant安装
- EMQX服务器安装
- MQTT协议连接
- 开发板连接
一、简介
介绍本任务使用的平台和协议,包括 MQTT协议、EMQX服务器、HomeAssistant.
1. MQTT
MQTT(Message Queuing Telemetry Transport)即消息队列遥测传输协议,是一种基于 publish/subscribe
(发布/订阅) 模式的 轻量级 通讯协议,适用于资源受限的设备下使用,特别是嵌入式领域。该协议构建于 TCP/IP 协议上,由 IBM 在1999年发布。
MQTT 最大优点在于,用极少的代码和有限的带宽,为连接远程设备提供实时可靠的消息服务 。
MQTT 工作流程
客户端建立连接
客户端发布消息,或订阅主题以接收消息
MQTT Broker 接收发布的信息
在本项目中,Arduino UNO R4 WiFi 开发板是发布者(Publisher),主题是温湿度传感器(Sensor),子级别是温度(Temperature)和湿度(Humidity),接收者为 HomeAssistant .
其他
QoS (Quality of Service levels) 即服务质量级别,一般设置为 0 ,等级越高,传输越复杂。
MQTT 数据包结构
固定头 Eixed header 包含消息类型 message type,标识位 DUP,QoS Level,RET,剩余长度 remain length .
可变头 Variable header
消息体 Payload
包括 CONNECT, SUBSCRIBE, SUBACK, UNSUBSCRIBE 四种类型
CONNECT
,消息体内容主要包括:客户端 ClientID、订阅 Topic、Message、用户名和密码
SUBSCRIBE
,消息体内容是一系列订阅主题以及 QoS
;
SUBACK
,消息体内容是服务器对于SUBSCRIBE
所申请的主题及 QoS
进行确认和回复。
UNSUBSCRIBE
,消息体内容是要订阅的主题。
MQTT 服务器搭建
目前MQTT代理的主流平台有下面几个:
免费的公共 MQTT 服务器 (仅用于测试,请勿在生产环境中使用)该服务器信息
- Broker 地址:broker.emqx.io
- TCP 端口:1883
- WebSocket端口:8083
- SSL/TLS 端口:8883
- WebSocket Secure 端口:8084
- QUIC 端口:14567
- CA 证书文件:broker.emqx.io-ca.crt
这里我们使用本地计算机 Docker 容器安装的 EMQX 服务器作为 MQTT 的代理平台,安装步骤将在下一章节进行介绍。
2. EMQX
EMQX 是一款全球下载量超千万的大规模分布式物联网 MQTT 服务器,单集群支持 1 亿物联网设备连接,消息分发时延低于 1 毫秒。为高可靠、高性能的物联网实时数据移动、处理和集成提供动力,助力企业构建关键业务的 IoT 平台与应用。
3. Home Assistant
Home Assistant 家庭助理,HA,是一款基于 Python 的智能家居开源系统,可以方便地连接各种外部设备,如智能设备、摄像头、邮件、短消息、云服务等,支持众多品牌的智能家居设备,按照自己的需求手动或自动化地联动这些外部设备,构建随心所欲的智慧空间。
二、方案
1. 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 主界面,创建智能家居账号。
详见:Docker run Home Assistant in Windows .
2. EMQX
EMQX 是一款全球下载量超千万的大规模分布式物联网 MQTT 服务器,单集群支持 1 亿物联网设备连接,消息分发时延低于 1 毫秒。为高可靠、高性能的物联网实时数据移动、处理和集成提供动力,助力企业构建关键业务的 IoT 平台与应用。
(1) 安装 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 .
(2) 配置 EMQX
(1)浏览器打开网址 http://localhost:18083/
,初始登录账户名 admin
密码 public
;
(2)依次打开 访问控制
- 客户端认证
- 创建
- Password-Based
- 内置数据库
- (默认配置)- 创建
;
(3)用户管理
- 新建用户
- 自定义用户名和密码(建议 admin).
(3) 连接 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 .
(4) 测试 EMQX
新建连接分别作为发送端和接收端,参数设置如下
用户可以是同一个,也可以是不同的用户,需要在 EMQX 网页界面 客户端认证
- 用户管理
- 新建用户
接收端点击 添加订阅
自定义 Topic,如 test
,其他选项默认即可
点击右上角分别 连接
发送端和接收端,在发送端对话窗口 Topic 栏输入接收端订阅名称 test
,在对话框中输入代码并点击发送,
接收端将收到相同的信息
至此测试表明我们搭建的 EMQX 客户端可以实现正常的信息发送与接收功能,为后面连接 Arduino UNO R4 WiFi 开发板并上传传感器数据奠定基础。
MQTT 协议根据 主题
来转发消息,主题通过 /
来区分层级,如 chat/room/first
, sensor/+/temperature
.
详见:MQTT 客户端工具演示 和 MQTT 协议入门:基础知识和快速教程 .
(5) 测试 EMQX 与 HA
进入 Home Assistant 设置
- 设备与服务
- MQTT
- 配置
界面
依次设置 发送端主题
、监听端主题
、点击 开始监听
、输入传输信息、点击 发送
,若监听对话框弹出发送端发送的信息,则表明发送端与接收端连接成功。
详见:MQTT协议 .
(6) 连接开发板
测试远程服务器的连通效果后,下一步便是将开发板与 EMQX 服务器连接,并上传数据至客户端和 Home Assistant 平台。
具体操作
打开 Arduino IDE ,安装 ArduinoMqttClient.h
库文件
打开该库文件的例程 WiFiSimpleSender.ino
,并对其进行修改,用于上传数据
代码
#include <ArduinoMqttClient.h>
#if defined(ARDUINO_SAMD_MKRWIFI1010) || defined(ARDUINO_SAMD_NANO_33_IOT) || defined(ARDUINO_AVR_UNO_WIFI_REV2)
#include <WiFiNINA.h>
#elif defined(ARDUINO_SAMD_MKR1000)
#include <WiFi101.h>
#elif defined(ARDUINO_ARCH_ESP8266)
#include <ESP8266WiFi.h>
#elif defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_NICLA_VISION) || defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_GIGA) || defined(ARDUINO_OPTA)
#include <WiFi.h>
#elif defined(ARDUINO_PORTENTA_C33)
#include <WiFiC3.h>
#elif defined(ARDUINO_UNOR4_WIFI)
#include <WiFiS3.h>
#endif
char ssid[] = SECRET_SSID;
char pass[] = SECRET_PASS;
WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);
const char broker[] = "49.52.23.140";
int port = 1883;
const char topic[]= "UNOR4/Send";
const long interval = 1000;
unsigned long previousMillis = 0;
int count = 0;
void setup() {
Serial.begin(115200);
while (!Serial) {
;
}
Serial.print("Attempting to connect to WPA SSID: ");
Serial.println(ssid);
while (WiFi.begin(ssid, pass) != WL_CONNECTED) {
Serial.print(".");
delay(5000);
}
Serial.println("You're connected to the network");
Serial.println();
Serial.println(WiFi.localIP());
mqttClient.setUsernamePassword("UNOR4", "123456");
Serial.print("Attempting to connect to the MQTT broker: ");
Serial.println(broker);
if (!mqttClient.connect(broker, port)) {
Serial.print("MQTT connection failed! Error code = ");
Serial.println(mqttClient.connectError());
while (1);
}
Serial.println("You're connected to the MQTT broker!");
Serial.println();
}
void loop() {
mqttClient.poll();
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
Serial.print("Sending message to topic: ");
Serial.println(topic);
Serial.print("temperature: ");
Serial.println(count);
Serial.print("humidity: ");
Serial.println(count);
mqttClient.beginMessage(topic);
mqttClient.print("Temperature: ");
mqttClient.print(count);
mqttClient.print("Humidity: ");
mqttClient.print(count);
mqttClient.endMessage();
Serial.println();
count++;
}
}
注意修改 arduino_secrets.h
中的 WiFi 账号和密码,IP 地址、端口号、发送端主题、MQTT用户名和密码。
程序下载至 Arduino UNO R4 WiFi 开发板,通过串口监视器查看发送的信息,效果如下
MQTTX 客户端测试
新建连接,填写IP地址、EMQX服务器客户端用户名和密码,添加订阅,主题与代码中设置的一致。
参考:EMQX Platform 文档 . ESP8266 + MQTT : LED 灯的远程控制
3. 连接HA
将发送的信息显示到 Home Assistant 智能家居平台,依次选择
设置
- 设备与服务
- MQTT
- 配置
- 监听主题
- 输入主题
名称 - 点击 开始监听
,
便可接收信息,如下图所示