[作品提交] 【Follow me第二季第2期】 进阶任务 智能家居3 MQTT接入HA(homeassistant)

zarkx   2024-9-24 17:16 楼主

 

任务可以分为3个阶段

1安装HA  https://bbs.eeworld.com.cn/thread-1293173-1-1.html

2传感器接入ardiuno  https://bbs.eeworld.com.cn/thread-1294525-1-1.html

3MQTT接入HA,合并接入系统

 

当前是MQTT接入HA

 

看了好多,摸索出一个比较完整的模式,可以先看看最后的结论

安装MQTT的方案很多,如果是镜像版的HA( Home Assistant Operating system)可以通过Mosquitto来安装。在HA的设置界面会多一个选项

 

参考置顶帖子,可以安装一下EMQX。

 

docker拉取代码

docker pull emqx

docker运行起来

docker run -d --name="EMQX_admin” -p 1883:1883 -p 8083:8083 -p 8883:8883 -p 8084:8084 -p 18083:18083 emqx

进入管理界面http://localhost:18083/ 默认账号:admin 默认密码:public  第一次需要改下密码。

完成初始化,具体内容不再赘述。

 

 

在HA界面点击设置-->设备与服务,搜索框输入MQTT,找不到点击添加集成,点击MQTT,MQTT,代理写你HA所在的电脑的ip地址,这里也有的填写EMQX配置的ip比如127.0.0.2
我的HA安装在mac电脑上,用户名密码写一个,要记住。

image.png

添加完成以后,可以测试一下 ,设置,设备与服务,MQTT,配置。发送主题和监听主题随便写,要写一样的。点击开始监听,点发送,可以看到接受的跟发送的东西一样。这是同页面测试。

Pasted Graphic.png  

 

下载一个MQTTX,这是一个软件在官网下载即可https://mqttx.app/zh/downloads,我下载的是mac版本,英特尔CPU的,下载后安装打开

image.png  

名称自己写一个,ip改成刚刚配置的HA所在电脑的ip

账号密码写刚刚上面MQTT配置的那个,点右上角连接即可。

 

Pasted Graphic 1.png  

 

可以测试一下。在MQTT那边开启监听,test的,在MQTTX上发送可以看到监听到一样的数据

Pasted Graphic 2.png  

 

我们需要在HA中的MQTT创建一个设备,

发送一个标准的PUB,就自动添加设备到HA的MQTT了

在topic栏写

homeassistant/sensor/sensorBedroom/config

发送内容写下面这个

{
    "device_class": "humidity",
    "name": "Humidity",
    "state_topic": "homeassistant/sensor/sensorBedroom/state",
    "unit_of_measurement": "%",
    "value_template": "{{ value_json.humidity }}",
    "unique_id": "hum01ae",
    "device": {
        "identifiers": [
            "bedroom01ae"
        ],
        "name": "Bedroom"
    }
}

下面这个是创建温度的

{
    "device_class": "temperature",
    "name": "Temperature",
    "state_topic": "homeassistant/sensor/sensorBedroom/state",
    "unit_of_measurement": "°C",
    "value_template": "{{ value_json.temperature }}",
    "unique_id": "temp01ae",
    "device": {
        "identifiers": [
            "bedroom01ae"
        ],
        "name": "Bedroom"
    }
}

如图所示

 

 

image.png  

可以看到发送以后MQTT那边直接出现一个实体设备

image.png  

这样就是添加成功了。回到首页可以看到设备在仪表盘上了,目前没有数据

image.png  

 

同样的方法发送湿度的代码,我测试的时候要么湿度要么文档会被替换,

 

最终我只能去修改配置文件yaml,


mqtt:
  - button:
      - unique_id: arduino uno button A
        name: "Arduino点击"
        command_topic: "UNO/arduino/myButtonA/cmd_t"
        payload_press: "restart"
        
  - sensor:
      - unique_id: bedroom humidity
        name: "Bedroom Humidity"
        state_topic: "homeassistant/sensor/sensorBedroom/state"
        suggested_display_precision: 1
        unit_of_measurement: "%"
        value_template: "{{ value_json.humidity }}"
        device_class: humidity
       
      - unique_id: bedroom temperature
        name: "Bedroom Temperature"
        state_topic: "homeassistant/sensor/sensorBedroom/state"
        suggested_display_precision: 3
        unit_of_measurement: "°C"
        value_template: "{{ value_json.temperature }}"
        device_class: temperature
        

修改以后保存,在开发者工具,点击所有yaml配置。如果配置有问题会报错,出现绿色的说明没问题。

 

image.png  

 

 

 

复制下面的代码,记得更改WIFI和MQTT相关的配置信息,然后下载到板子上。代码上写了备注需要根据实际修改

里面是测试代码让湿度写死44.8,温度22.5

(让AI写代码会有很多bug要自己检查)

mac电脑没有串口输出,没办法我在成功的时候加入了LED矩阵的笑脸。这样可以在板子上看到状态,大家可以把LED相关的删掉。



//wifi test--ok 温湿度写死的

#include <WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>

// 替换为你的网络信息
const char* ssid = "TP-LINK_F060";
const char* password = "hsta8888";

// 替换为你的Mosquitto broker信息
const char* mqtt_server = "192.168.2.178";
const int mqtt_port = 1883;
const char* mqtt_user = "admin";
const char* mqtt_password = "admin";

#include "Arduino_LED_Matrix.h" //led

ArduinoLEDMatrix matrix;  //led

uint8_t smile[8][12] = {
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0 },
  { 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};//led

// 初始化WiFi和MQTT客户端
WiFiClient espClient;
PubSubClient client(espClient);

// 传感器数据发布主题
const char* topic = "homeassistant/sensor/sensorBedroom/state";

void setup() {
  Serial.begin(115200);
  matrix.begin();  //led
  setup_wifi();
  client.setServer(mqtt_server, mqtt_port);
}

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.loop();

  // 假设你有一个温度传感器,获取温度数据
  float temperature11 = 50;
  float humidity11 = 26.8;

  StaticJsonDocument<200> jsonDoc;
  jsonDoc["humidity"] = humidity11;
  jsonDoc["temperature"] = temperature11;

  char jsonBuffer[512];
  serializeJson(jsonDoc, jsonBuffer);

  client.publish(topic, jsonBuffer);

  matrix.renderBitmap(smile, 8, 12);  //led
  // 每隔5秒发送一次数据
  delay(5000);
}

void setup_wifi() {
  delay(10);
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("Connected!");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
}

void reconnect() {
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    if (client.connect("ArduinoClient", mqtt_user, mqtt_password)) {
      Serial.println("connected");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      delay(5000);
    }
  }
}

如果代码报错,需要搜索安装对应的库即可,这两个是需要安装的。

image.png  

 

编译,上传。

 

image.png   

可以打开串口工具查看输出,有连结成功WIFI,上传等信息。

 

没错上面这个还是测试用的,ardiuno写死数据传到HA展示

看到首页湿度50,温度26.8说明是成功了。

 

 

下面来改实际的代码吧,

//完整的wifi+接收数据

#include <WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
#include "Adafruit_SHT4x.h"

// 初始化SHT40传感器
Adafruit_SHT4x sht4 = Adafruit_SHT4x();


// 替换为你的网络信息
const char* ssid = "TP-LINK_F060";
const char* password = "hsta8888";

// 替换为你的Mosquitto broker信息
const char* mqtt_server = "192.168.2.178";
const int mqtt_port = 1883;
const char* mqtt_user = "admin";
const char* mqtt_password = "admin";

// 初始化WiFi和MQTT客户端
WiFiClient espClient;
PubSubClient client(espClient);

// 传感器数据发布主题
const char* topic = "homeassistant/sensor/sensorBedroom/state";



void setup() {
  Serial.begin(115200);

  while (!Serial)
    delay(10);  // will pause Zero, Leonardo, etc until serial console opens

  Serial.println("Adafruit SHT4x test");
  if (!sht4.begin()) {
    Serial.println("Couldn't find SHT4x");
    while (1) delay(1);
  }
  Serial.println("Found SHT4x sensor");

  setup_wifi();
  client.setServer(mqtt_server, mqtt_port);
}

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.loop();

  // 从SHT40传感器读取温度和湿度数据
  sensors_event_t humidity, temp;
  sht4.getEvent(&humidity, &temp);  // populate temp and humidity objects with fresh data

  Serial.print("Temperature: ");
  Serial.print(temp.temperature);
  Serial.println(" degrees C");
  Serial.print("Humidity: ");
  Serial.print(humidity.relative_humidity);
  Serial.println("% rH");


  // sensors_event_t humidity_event, temp_event;
  // sht4.getEvent(&humidity_event, &temp_event);

  StaticJsonDocument<200> jsonDoc;
  // jsonDoc["temperature"] = temp_event.temperature;
  // jsonDoc["humidity"] = humidity_event.relative_humidity;
   jsonDoc["temperature"] = temp.temperature;
  jsonDoc["humidity"] = humidity.relative_humidity;

  char jsonBuffer[512];
  serializeJson(jsonDoc, jsonBuffer);

  client.publish(topic, jsonBuffer);

  // 每隔2秒发送一次数据
  delay(2000);
}


void setup_wifi() {
  delay(10);
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("Connected!");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
}

void reconnect() {
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    if (client.connect("ArduinoClient", mqtt_user, mqtt_password)) {
      Serial.println("connected");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      delay(5000);
    }
  }
}

 

 

 

总结

一。ardiuno连接温湿度模块,读取数据,

二。HA链接MQTT,ardiuno上传写死的数据到HA展示出来

三。合并代码,让ardiuno采集的数据发送到HA上面来展示

PS:注意不要用MQTTX创建,创建的会覆盖。直接改yaml文件最方便。

另外 QWIIC排线接线的需要把 sht4.begin() 改为 sht4.begin(&Wire1) ,自己焊接接线的不要改。

 

 

 

踩坑

后面我遇到一个情况就是MQTT怎么都链接不上,后面搜docker安装MQTT相关的,https://blog.csdn.net/qq_43917690/article/details/136705488 参考这个把EMQX重新安装,Websocket客户端那边重新配置账号和密码,用MQTTX测试成功,在链接就好。希望对遇到相同问题的朋友有帮助。

 

放上最终的视频,我对着传感器哈了口气,很快湿度上升,用手摸着传感器温度也慢慢上升。效果还不错。本以为很简单的,设备不齐,整了好几天。
不过也学到很多东西,欢迎大家讨论


 

 

 

 

 

本帖最后由 zarkx 于 2024-9-26 16:15 编辑

回复评论

暂无评论,赶紧抢沙发吧
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复