337|0

10

帖子

2

TA的资源

一粒金砂(中级)

楼主
 

【Follow me第二季第2期】MQTT协议接入到开源的智能家居平台HA [复制链接]

  本帖最后由 cqut面码 于 2024-9-29 22:06 编辑

一、Home Assistant 的安装

为了方便操作,这里直接在电脑上使用Docker进行安装。

官网上下载 https://www.docker.com/products/docker-desktop/ Docker安装包。

安装好了Docker之后,就需要在Docker中拉取Home Assistant 镜像了。可以参考大佬博主的一篇文章,有详细的介绍命令行的使用,我这里只是展示效果了。

https://bbs.eeworld.com.cn/thread-1293807-1-1.html

 

(1) 第一步先用cmd 搜索镜像

docker search home-assistant

 

(2)第二步进行拉取最新的镜像

docker pull homeassistant/home-assistant

 

 

漫长的等Docker中拉取Home Assistant镜像中。

 

(3)第三步进行进行创建容器

其中HA_container为可自定义的容器名称,D:/ProgramData/HA为可自定义配置保存路径(注意是右斜杠)

docker run -d --name="HA_container" -v D:/ProgramData/HA:/config -p 8123:8123 homeassistant/home-assistant

 

(4)最后一步在浏览器中输入 http://localhost:8123/    就可看到成功了。

 

接着注册用户,进入主页就好了,具体如下:

 

二、EMQX 的安装

(1)第一步在Docker中拉取EMQX镜像

CMD中输入命令行,选择第一个进行安装

docker search emqx
docker pull emqx

 

 

然后又是漫长的拉取等待

 

(2)第二步创建EMQX容器

cmd输入以下命令,其中HA为可自定义的容器名称,D:/ProgramData/HA为可自定义配置保存路径(注意是右斜杠)

 (3)第三步测试EMQX是否OK

浏览器中输入网址  http://localhost:18083/   默认账号:admin 默认密码:public,成功的界面如下

  (4)设置EMQ

 

  一路默认创建我们的内置数据库

  再创建一个用户

 

 

然后打开docker 就可以看到我们安装的 home assistant 和 EMQ

 

(5)然后进行EMQ和HA之间的连接

找到EMQ的集群概览。找到节点的信息,如下

 

打开HA,设置添加MQTT

 

   

 

 

代理名字填前面在EMQ中获取到的地址,然后创建就OK了。

回到EMQ,可以发现HA已经通过MQTT接入可EMQ,说明HA与EMQ已经成功链接了。

 

三、实现WIFI联网功能

一步一来做,想要MQTT上传数据,就需要先学会怎么把板子通过WIFI连接上网络。

直接如下面所示,使用开发板的官方示例来进行连接。我们只要修改相应的参数即可了

 

/*
  This example connects to an unencrypted WiFi network.
  Then it prints the MAC address of the WiFi module,
  the IP address obtained, and other network details.

  created 13 July 2010
  by dlf (Metodo2 srl)
  modified 31 May 2012
  by Tom Igoe

  Find the full UNO R4 WiFi Network documentation here:
  https://docs.arduino.cc/tutorials/uno-r4-wifi/wifi-examples#connect-with-wpa
 */
#include <WiFiS3.h>

#include "arduino_secrets.h" 
///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = SECRET_SSID;        // your network SSID (name)
char pass[] = SECRET_PASS;    // your network password (use for WPA, or use as key for WEP)
int status = WL_IDLE_STATUS;     // the WiFi radio's status

void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  // check for the WiFi module:
  if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("Communication with WiFi module failed!");
    // don't continue
    while (true);
  }

  String fv = WiFi.firmwareVersion();
  if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
    Serial.println("Please upgrade the firmware");
  }

  // attempt to connect to WiFi network:
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network:
    status = WiFi.begin(ssid, pass);

    // wait 10 seconds for connection:
    delay(10000);
  }

  // you're connected now, so print out the data:
  Serial.print("You're connected to the network");
  printCurrentNet();
  printWifiData();

}

void loop() {
  // check the network connection once every 10 seconds:
  delay(10000);
  printCurrentNet();
}

void printWifiData() {
  // print your board's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  
  Serial.println(ip);

  // print your MAC address:
  byte mac[6];
  WiFi.macAddress(mac);
  Serial.print("MAC address: ");
  printMacAddress(mac);
}

void printCurrentNet() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print the MAC address of the router you're attached to:
  byte bssid[6];
  WiFi.BSSID(bssid);
  Serial.print("BSSID: ");
  printMacAddress(bssid);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.println(rssi);

  // print the encryption type:
  byte encryption = WiFi.encryptionType();
  Serial.print("Encryption Type:");
  Serial.println(encryption, HEX);
  Serial.println();
}

void printMacAddress(byte mac[]) {
  for (int i = 0; i < 6; i++) {
    if (i > 0) {
      Serial.print(":");
    }
    if (mac[i] < 16) {
      Serial.print("0");
    }
    Serial.print(mac[i], HEX);
  }
  Serial.println();
}

唯一的修改点就是把 SECRET_SSID 和  SECRET_PASS分别替换为自己家里的WIFI名称和密码。注意,不要使用5G频段的WIFI,使用2.4G的WIFI,5G频段WIFI连接不上,应该是硬件不支持的原因。

修改如下:

#define SECRET_SSID "ChinaNet-T6zw"
#define SECRET_PASS "chu7p4s9"

编译下载,打开串口监视器,可以看到已经获取到了MAC地址和WIFI的强度,说明连接成功了

 

 

四、MQTT上传数据的准备工作

接着就需要开始准备MQTT相关的东西了

(1) MQTT BOX 的下载准备

MQTTBUX是一个客户端,方便我们调试的时候看MQTT发布的数据,下载链接如下:

https://apps.microsoft.com/detail/9nblggh55jzg?hl=zh-mo&gl=MO

安装之后,就进行一些基本的配置就可以使用了。

 

MQTT服务器的账户和密码就是我们前面设置的,服务器地址就是我们电脑的本机IP地址。EMQ(MQTT服务器)是通过docker安装在自己本地电脑上的,所有地址是本机电脑地址,直接使用ipconfig 命令可查。如果是把EMQ装在了树莓派上,需要填写树莓派的IP会地址。

 

 

设置好之后直接订阅一个主题就好了

 

这里我们订阅了这个主题 UNO/arduino/myAnalogInput/stat_t,等会开发板向这个主题发送数据,这个客户端就可以收到。

  

 

 

(2) Arduino IDE 安装 ArduinoMqttClient 库

具体如下图

 

 

五、代码实战实现数据上MQTT

实现了通过ADC A3接口来读取A0接口 DAC输出sin信号的电压值,然后把这个值通过MQTT协议发布出去,

实际的物理连接如下:

 

具体的实现代码如下

#include <ArduinoMqttClient.h>
#include <WiFiS3.h>
#include <WiFiClient.h>
#include "Arduino_LED_Matrix.h"  /*包含官方的驱动库*/
#include "analogWave.h" // 包含波形输出的模拟文件

///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = "ChinaNet-T6zw";  //WIFI名字
char pass[] = "chu7p4s9";       //WIFI密码
int status = WL_IDLE_STATUS;

//实例化
WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);
analogWave wave(DAC);   //实例化一个对象

const char broker[] = "192.168.1.11";                //MQTT服务器地址
int port = 1883;                                     //MQTT服务器端口
const char topic[] = "UNO/arduino/myAnalogInput/stat_t";  //发布的主题
const char mqttuser[] = "lang.you";                  //MQTT服务器的用户名
const char mqttpassword[] = "123456789";        //MQTT服务器密码

//set interval for sending messages (milliseconds)
const long interval = 8000;
unsigned long previousMillis = 0;

int count = 0;

void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(2000000);
  while (!Serial) {
    ;  // wait for serial port to connect. Needed for native USB port only
  }

  //A0 DAC 输出一个波形
  wave.sine(50);     //产生一个50HZ的sin波形
  wave.amplitude(0.25); //设置幅度值为4.7 的1/4

  // 设置ADC的分辨率
  analogReadResolution(14); //change to 14-bit resolution


  // attempt to connect to Wifi network:
  Serial.print("Attempting to connect to WPA SSID: ");
  Serial.println(ssid);
  while (WiFi.begin(ssid, pass) != WL_CONNECTED) {
    // failed, retry
    Serial.print(".");
    delay(5000);
  }

  Serial.println("You're connected to the network");
  Serial.println();

  Serial.print("Attempting to connect to the MQTT broker: ");
  Serial.println(broker);

  mqttClient.setUsernamePassword(mqttuser, mqttpassword);

  while (!mqttClient.connect(broker, port)) {
    Serial.print("MQTT connection failed! Error code = ");
    Serial.println(mqttClient.connectError());
    delay(1000);
  }

  Serial.println("You're connected to the MQTT broker!");
  Serial.println();
}

void loop() {
  // call poll() regularly to allow the library to send MQTT keep alive which
  // avoids being disconnected by the broker

  mqttClient.poll();

  //通过ADC采集 A0上输出的sin波形
  float Rvalue = analogRead(A3) * 4.7/16383;  //读取A0引脚的值  A3和 A0连接 14bit ADC采样
  mqttClient.beginMessage(topic);
  mqttClient.print(Rvalue);   //把读取的值进行上传到MQTT服务器
  mqttClient.endMessage();
  delay(10);
}

 

查看MQTT BOX,并订阅UNO/arduino/myAnalogInput/stat_t主题下面的数据,可以看到数据一直在推送刷新

 

 

 

打开HA查看上传的电压数据是一直在刷新的

 再来看看我们实际的HA上显示的sin信号的电压值

 

 

 

这里为什么我的HA会有这个值的显示呢,其实可以参考直播大佬的配置,详情可见下面链接。实际配置了configuration.yaml文件,增加以下代码保存。

https://bbs.eeworld.com.cn/thread-1293807-1-1.html

mqtt:
  - button:
      - unique_id: arduino uno button A
        name: "Arduino Click me A"
        command_topic: "UNO/arduino/myButtonA/cmd_t"
        payload_press: "restart"
      - unique_id: arduino uno button B
        name: "Arduino Click me B"
        command_topic: "UNO/arduino/myButtonB/cmd_t"
        payload_press: "restart"
  - sensor:
      - unique_id: arduino uno Time
        name: "arduino Time"
        state_topic: "UNO/arduino/myUptime/stat_t"
        suggested_display_precision: 1
        unit_of_measurement: "s"
        value_template: "{{ value }}"

      - unique_id: arduino uno Voltage
        name: "arduino Volt"
        state_topic: "UNO/arduino/myAnalogInput/stat_t"
        suggested_display_precision: 3
        unit_of_measurement: "V"
        value_template: "{{ value }}"

再来看看EMQ的情况

实际显示了3设备连接,一个就是我们板子,一个HA,一个是MQTT BOX,三个都作为了MQTT的客户端连接到了MQTT服务器

 

六、视频展示和最终工程代码代码


 

 

 

unor4_mqtt.7z

1.43 KB, 下载次数: 0

本次MQTT实验代码

点赞 关注
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

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

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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

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

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

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