584|2

7

帖子

1

TA的资源

一粒金砂(中级)

楼主
 

【Follow me第二季第2期】Arduino Uno R4 WiFi 通过MQTT连入Home Assistant [复制链接]

  本帖最后由 一只小跳帽 于 2024-9-22 14:52 编辑

今天,我们将细致而有序地完成一个项目——搭建Home Assistant平台,并通过MQTT协议实现设备接入。整个过程将分为四个清晰、连贯的步骤,确保每一步都精准无误,助力您成功构建智能家居生态系统。

第一步:安装Home Assistant
首先,我们将着手安装Home Assistant。这一步骤是构建智能家居中枢的关键,Home Assistant以其强大的集成能力和灵活的自定义选项而闻名,能够轻松管理家中的各种智能设备。我们将按照官方指南或选择适合您操作系统的安装方法,确保Home Assistant能够稳定运行在您的设备上。

第二步:部署MQTT服务器
紧接着,我们将安装并配置MQTT服务器。MQTT,即消息队列遥测传输,是一种轻量级的、基于发布/订阅模式的消息协议,非常适合物联网(IoT)设备的通信。我们将选择一个稳定可靠的MQTT服务器软件(如Mosquitto),并根据实际需求进行配置,确保它能够高效、安全地处理来自智能家居设备的消息。

第三步:将Home Assistant连接到MQTT服务器
在成功部署MQTT服务器后,下一步是将Home Assistant与之连接起来。这一步骤至关重要,因为它将使得Home Assistant能够接收并处理来自MQTT服务器的消息,进而实现对智能家居设备的控制。我们将通过Home Assistant的配置界面,添加MQTT集成,并填写MQTT服务器的相关信息,完成连接设置。

第四步:使用MQTT客户端进行连接测试
为了确保MQTT服务器的正常运行以及Home Assistant与MQTT服务器的成功连接,我们将使用MQTT客户端工具进行连接测试。这一步骤不仅验证了通信链路的通畅性,还让我们有机会熟悉MQTT的基本操作,为后续的设备接入打下坚实基础。

最后一步:使用Arduino R4 WiFi开发板接入系统
作为整个项目的亮点,我们将使用Arduino R4 WiFi开发板,通过编程使其能够通过MQTT协议与Home Assistant进行通信。通过编写相应的代码,Arduino R4 WiFi将能够发送状态信息至MQTT服务器,并接收来自Home Assistant的控制指令,实现智能家居设备的智能化控制。这一步骤将充分展示MQTT在物联网应用中的强大潜力。

首先,我们将通过安装Linux虚拟机来启动我们的Home Assistant部署之旅,这里特别选择Ubuntu系统作为我们的基础平台。Ubuntu以其完善的生态系统、广泛的用户群体以及丰富的解决方案而著称,这使得它成为部署智能家居控制中心——Home Assistant的理想选择。

在准备阶段,我们将确保Ubuntu虚拟机被正确安装并配置,以便为后续步骤提供一个稳定、可靠的环境。通过选择Ubuntu,我们不仅能够享受到其强大的功能和灵活性,还能轻松获取到来自全球开发者和社区的支持与帮助,这对于解决在部署过程中可能遇到的各种问题至关重要。

接下来,我们将利用容器技术来安装和运行Home Assistant。容器化部署以其轻量级、可移植性和易于管理的特点,在现代软件开发和运维中得到了广泛应用。通过容器,我们可以将Home Assistant及其依赖项封装在一个独立的虚拟环境中,从而避免与系统其他部分的潜在冲突,并确保其稳定运行。

综上所述,选择Ubuntu系统作为Linux虚拟机的基础,并结合容器技术来安装Home Assistant,将为我们提供一个强大、灵活且易于维护的智能家居控制中心解决方案。

  下面进行安装docker 

#安装前先卸载操作系统默认安装的docker,
sudo apt-get remove docker docker-engine docker.io containerd runc

#安装必要支持
sudo apt install apt-transport-https ca-certificates curl software-properties-common gnupg lsb-release

#添加 Docker 官方 GPG key (可能国内现在访问会存在问题)
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

# 阿里源(推荐使用阿里的gpg KEY)
curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

#添加 apt 源:
#Docker官方源
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null


#阿里apt源
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null


#更新源
sudo apt update
sudo apt-get update

#安装最新版本的Docker
sudo apt install docker-ce docker-ce-cli containerd.io
#等待安装完成

#查看Docker版本
sudo docker version

#查看Docker运行状态
sudo systemctl status docker
 

 

现在安装好docker 下面安装docker版的Home Assistant

docker search homeassistant

2、拉取docker镜像

docker pull homeassistant/home-assistant:latest

3、创建容器并运行

docker run -d --name="hass" -v /path/to/config:/config -v /etc/localtime:/etc/localtime:ro -p 8123:8123 --net

-d: 表示在后台运行容器。
--name my_home_assistant_instance: 指定容器的名称为 "my_home_assistant_instance",你可以根据需要修改。
-v /path/to/config:/config: 将本地配置目录映射到容器内的 /config 目录。确保将 /path/to/config 替换为你的 Home Assistant 配置目录的实际路径。
-v /etc/localtime:/etc/localtime:ro: 将主机的时间配置映射到容器内,保持容器和主机时间同步。
--net=host: 使用主机网络模式,使得容器可以直接使用主机的网络配

-p:映射端口(容器内的端口直接映射到本地主机端口最后便是刚才下载的镜像了,运行该容器。
注:这里启动docker容器之后每次启动docker容器都会数据初始化建议-v进行数据挂载

docker 查看并启动容器

//查看容器信息
docker ps -a  
 
//docker 使用<container_id>启动容器
docker start <container_id>
//使用容器名称启动--name 参数指定容器的名称为 "my_container_instance"。my_image:tag 是你要启动的 Docker 镜像的名称和标签。
docker run --name my_container_instance my_image:tag
 
docker stop <container_id>

  通过上面看到我们已经创建 了Home Assistant 的镜像下面进行启动 

  这里我们已经启动了Home Assistant 下面我们使用浏览器进行打开首先使用ifconfig 查看ip再使用端口8123 进行访问

  现在安装好了 但是还没有mqtt服务因此不能使用mqtt连接下面安装mqtt服务器

1 认识EMQX
1.1 EMQX 简介
EMQX 是一款开源的大规模分布式 MQTT 消息服务器,功能丰富,专为物联网和实时通信应用而设计。EMQX 5.0 单集群支持 MQTT 并发连接数高达 1 亿条,单服务器的传输与处理吞吐量可达每秒百万级 MQTT 消息,同时保证毫秒级的低时延。

EMQX 支持多种协议,包括 MQTT (3.1、3.1.1 和 5.0)、HTTP、QUIC 和 WebSocket 等,保证各种网络环境和硬件设备的可访问性。EMQX 还提供了全面的 SSL/TLS 功能支持,比如双向认证以及多种身份验证机制,为物联网设备和应用程序提供可靠和高效的通信基础设施。

1.2 EMQX 版本类型
EMQX 有 4 种部署模式,包括两种云服务模式(EMQX Cloud Serverless 和 EMQX Cloud 专有版)和两种自托管模式(EMQX 开源版 和 EMQX 企业版)。以下表格列出了这些部署模式的对比,以帮助您根据业务需求进行选择。想进一步了解具体的功能对比,参考功能对比。

对于非企业级应用,使用EMQX开源版即可,本文也是以该版本作为Demo,介绍其搭建和使用方法。

2 Ubuntu搭建EMQX 平台
2.1 下载和安装
2.1.1 下载
下载地址:

https://www.emqx.io/zh/downloads
打开网站,选择安装环境:

2.1.2 安装
使用如下三个步骤在Ubuntu上安装EMQX:

Step 1: 从软件链接源下载软件包,并装载安装环境

curl -s https://assets.emqx.com/scripts/install-emqx-deb.sh | sudo bash
下载完成后,可以看见如下log:

Step-2: 安装软件

sudo apt-get install emqx


Step-3: 运行软件

执行如下代码,如果没有任何信息打印出来,说明EMAX已经正常启动了

sudo systemctl start emqx


2.2 查看运行端口
和EMQX相关的端口有如下这些:

端口号    介绍
1883    MQTT 协议端口
8883    MQTT/SSL 端口
8083    MQTT/WebSocket 端口
8080    HTTP API 端口
18083    Dashboard 管理控制台端口
查看EMQX的运行端口:

netstat -ap | grep 18083


查看MQTT 协议端口:

netstat -ap | grep 1883


3 运行Dashboard 管理控制台
要在第三方终端上运行Dashboard 管理控制台,必须保证18083端口运行被访问,那么怎么做呢?检查该端口是否被允许外网访问。

3.1 查看Ubuntu上的防火墙
首先确保ufw 已经安装在当前的Ubuntu系统中,如果没有安装,使用如下命令:

sudo apt update
sudo apt install ufw
一种最简单的方式就是关闭防火墙,如果允许外网访问,不建议这样做:

sudo ufw disable


3.2 运行Dashboard 管理控制台
step-1: 查看当前Ubuntu主机的ip,使用命令:

ifconfig 
执行命令后,终端会打印当前主机所有网卡相关的IP信息,找到主机的实际ip,然后在第三方电脑主机上登录

step-2: 登录服务器

打开浏览器,输入相应IP和端口号,就能打开网页了。举个例子,以笔者本人测试主机为例

192.168.1.11:18083

如果安装成功,可以看见如下页面,说明EMQX可以正常工作了。

 第三步使用 Home Assistant 连接到mqtt 服务器

在设置的设备与服务中搜索mqtt 进行配置 ip地址就是自己本地的ip 端口使用的是mqtt统一端口1883 密码和用户名使用自己设置的就可以设置成功后就可以看到集群中连接的设备和订阅的主题

 

 

 

这个就是Home Assistant 的设备

 

下面我们先使用mqtt的客户端连接到mqtt服务器 这里我使用的是mqtt客户端工具

  使用这个工具我们可以很简单的模拟我们的开发板如何配置mqtt和发送的主题

首先我们先配置端口ip地址然后进行连接

 

然后点击连接在浏览器上查看节点是否连接成功

  这里看到已经有两个节点了有一个就是我们刚刚连接的客户端

下面我们要把这个设备连接到我们的 Home Assistant 中这里很多人选择直接配置设备文件但是我发现这种方法十分的不麻烦而且也不利于我们后续的设备自己连接函数需要我们一个一个的配置下面我使用的方法是使用设置自动的添加到我们这个系统中 只需要向特定的主题发送对应的内容就可以下面我来试一下

 

 

这里我们选择配置成我们下一个任务的 温湿度传感器类型进行发现

 

 

 

 

这里看到我们已经成功的添加了一个设备并且配置他的两个状态为 一个是温度一个是湿度下面我们对其进行发送状态

 


 

这个已经有数值了 下面我们先通过开发板连接上mqtt 下一节我们再上传报文

首先我们使用PubSubClient 库进行连接下面简单介绍一下连接的流程首先创建一个实体类

WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);

后续的所有操作都是使用的这个实体

下一步进行连接到mqtt服务器

void connectMQTTServer(){
  String clientId = "UNOR4";
 
  // 连接MQTT服务器

  if (mqttClient.connect(clientId.c_str())) { 
    Serial.println("MQTT Server Connected.");
    Serial.println("Server Address: ");
    Serial.println(mqttServer);
    Serial.println("ClientId:");
    Serial.println(clientId);
  } else {
    Serial.print("MQTT Server Connect Failed. Client State:");
    Serial.println(mqttClient.state());
    delay(3000);
  }  
}

后面再进行学习上面的mqtt客户端发送给服务器的主题和内容进行发送让Home Assistant 自发现的方式

注意我后面因为网关的原因自己进行配置了一次网络

void Register_temp()
{
  // Stream& output;
  const char * topics="homeassistant/sensor/sensorBedroomT/config";
String output;
JsonDocument doc;

doc["device_class"] = "temperature";
doc["name"] = "Temperature";
doc["state_topic"] = "homeassistant/sensor/sensorroom/state";
doc["value_template"] = "{{ value_json.temperature}}";
doc["unique_id"] = "temp01ae";

JsonObject device = doc["device"].to<JsonObject>();
device["identifiers"][0] = "room01";
device["name"] = "room";

doc.shrinkToFit();  // optional

serializeJson(doc, output);
Serial.println(output.length());


  if(mqttClient.publish(topics, output.c_str())){
    Serial.println("Publish topic:");Serial.println(topics);
    Serial.println("Publish message:");Serial.println(output);    
  } else {
    Serial.println("Message Publish Failed."); 
  }






}

void Register_hum()
{
  // Stream& output;
    const char * topics="homeassistant/sensor/sensorBedroomH/config";
String output;
JsonDocument doc;

doc["device_class"] = "humidity";
doc["name"] = "Humidity";
doc["state_topic"] = "homeassistant/sensor/sensorroom/state";
doc["unit_of_measurement"] = "%";
doc["value_template"] = "{{ value_json.humidity}}";
doc["unique_id"] = "hum01ae";

JsonObject device = doc["device"].to<JsonObject>();
device["identifiers"][0] = "room01";
device["name"] = "room";

doc.shrinkToFit();  // optional

serializeJson(doc, output);
Serial.println(output);
Serial.println(output.length());


  if(mqttClient.publish(topics, output.c_str())){
    Serial.println("Publish topic:");Serial.println(topics);
    Serial.println("Publish message:");Serial.println(output);    
  } else {
    Serial.println("Message Publish Failed."); 
  }



}

 

  运行后已经连接上了

 

 

到这里已经完全了下面是整个的代码

//#include <WiFiS3.h>
#include <PubSubClient.h>
 #include <WiFi.h>
 #define ARDUINOJSON_SLOT_ID_SIZE 1
#define ARDUINOJSON_STRING_LENGTH_SIZE 1
#define ARDUINOJSON_USE_DOUBLE 0
#define ARDUINOJSON_USE_LONG_LONG 0
#include <ArduinoJson.h>
// 设置wifi接入信息(请根据您的WiFi信息进行修改)
const char* ssid = "aaaa";
const char* password = "aaaaaaaa";
const char* mqttServer = "broker.emqx.io";
IPAddress server(192,168,31 ,200);

WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);
 
void setup() {
  Serial.begin(9600);
  // 连接WiFi
  connectWifi();
  
  // 设置MQTT服务器和端口号
  mqttClient.setServer(server, 1883);
 
  // 连接MQTT服务器
  connectMQTTServer();
  Register_temp();
  Register_hum();

}
 
void loop() { 
  if (mqttClient.connected()) { // 如果开发板成功连接服务器    
    mqttClient.loop();          // 保持客户端心跳
  } else {                  // 如果开发板未能成功连接服务器
    connectMQTTServer();    // 则尝试连接服务器
  }
}
 
void connectMQTTServer(){
  String clientId = "UNOR4";
 
  // 连接MQTT服务器

  if (mqttClient.connect(clientId.c_str())) { 
    Serial.println("MQTT Server Connected.");
    Serial.println("Server Address: ");
    Serial.println(mqttServer);
    Serial.println("ClientId:");
    Serial.println(clientId);
  } else {
    Serial.print("MQTT Server Connect Failed. Client State:");
    Serial.println(mqttClient.state());
    delay(3000);
  }  
}
 
void connectWifi(){
 
  WiFi.begin(ssid, password);
 
  //等待WiFi连接,成功连接后输出成功信息
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi Connected!");  
  Serial.println(""); 
  Serial.println(WiFi.localIP());
}
void Register_temp()
{
  // Stream& output;
  const char * topics="homeassistant/sensor/sensorBedroomT/config";
String output;
JsonDocument doc;

doc["device_class"] = "temperature";
doc["name"] = "Temperature";
doc["state_topic"] = "homeassistant/sensor/sensorroom/state";
doc["value_template"] = "{{ value_json.temperature}}";
doc["unique_id"] = "temp01ae";

JsonObject device = doc["device"].to<JsonObject>();
device["identifiers"][0] = "room01";
device["name"] = "room";

doc.shrinkToFit();  // optional

serializeJson(doc, output);
Serial.println(output.length());


  if(mqttClient.publish(topics, output.c_str())){
    Serial.println("Publish topic:");Serial.println(topics);
    Serial.println("Publish message:");Serial.println(output);    
  } else {
    Serial.println("Message Publish Failed."); 
  }






}

void Register_hum()
{
  // Stream& output;
    const char * topics="homeassistant/sensor/sensorBedroomH/config";
String output;
JsonDocument doc;

doc["device_class"] = "humidity";
doc["name"] = "Humidity";
doc["state_topic"] = "homeassistant/sensor/sensorroom/state";
doc["unit_of_measurement"] = "%";
doc["value_template"] = "{{ value_json.humidity}}";
doc["unique_id"] = "hum01ae";

JsonObject device = doc["device"].to<JsonObject>();
device["identifiers"][0] = "room01";
device["name"] = "room";

doc.shrinkToFit();  // optional

serializeJson(doc, output);
Serial.println(output);
Serial.println(output.length());


  if(mqttClient.publish(topics, output.c_str())){
    Serial.println("Publish topic:");Serial.println(topics);
    Serial.println("Publish message:");Serial.println(output);    
  } else {
    Serial.println("Message Publish Failed."); 
  }



}








 

 

 

最新回复

容器技术来安装和运行Home Assistant这个看来是有技巧的   详情 回复 发表于 2024-9-23 07:28
点赞 关注
 
 

回复
举报

6555

帖子

0

TA的资源

五彩晶圆(高级)

沙发
 

容器技术来安装和运行Home Assistant这个看来是有技巧的

点评

主要是安装后配置文件太麻烦了 还是自发现比较适合实际应用  详情 回复 发表于 2024-9-23 09:39
 
 
 

回复

7

帖子

1

TA的资源

一粒金砂(中级)

板凳
 
Jacktang 发表于 2024-9-23 07:28 容器技术来安装和运行Home Assistant这个看来是有技巧的

主要是安装后配置文件太麻烦了 还是自发现比较适合实际应用

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表