本帖最后由 无垠的广袤 于 2025-4-14 14:43 编辑  
 
ESP8266 采集 DHT11 和 DS18B20 温湿度数据 MQTT 上传至 Home Assistant 
 本文介绍了 ESP8266 开发板实现 DHT11 温湿度传感器和 DS18B20 温度传感器实现远程温度监测,通过 MQTT 协议上传至 EMQX 平台,发送 JSON 代码实现 HomeAssistant 智能家居平台数据收集和历史数据查看等功能。  
 硬件平台 
 开发板基于 ESP-12E/12F 设计,管脚功能示意图如下  
 实物图原理图 
 MQTT 
 消息队列遥测传输协议(Message Queuing Telemetry Transport,MQTT)是一种基于发布/订阅(publish/subscribe)模式的轻量级通讯协议。  
 DockerDocker 是一个开源的应用容器引擎,它允许开发者将应用及其依赖打包到一个轻量级、可移植的容器中,可以在任何流行操作系统中发布和运行。  
 安装 Docker Desktop 
 EMQXEMQX 是一款完全开源,高度可伸缩,高可用的分布式MQTT 消息服务器。  
 部署流程点击 EMQX 容器后的端口链接,登录 EMQX 后台,初始账号和密码分别为 admin 和 public   
 回到平台主界面,可观察节点和连接数目等信息  
 Home AssistantHome Assistant ,简称 HA,是一款基于 Python 的智能家居开源系统,支持众多品牌的智能家居设备,可以轻松实现硬件物联网、自动化等。  
 Docker 部署 Home Assistant 的主要流程  
 部署流程硬盘根目录新建文件夹 homeassistant ,解压 HA 镜像文件,得到 docker-compose.yml ; 当前目录下打开命令行终端,执行安装指令 - cd C:\homeassistant
 - docker-compose.yml
 - docker-compose up
 
  复制代码
  
  
 添加 MQTT 集成 
依次点击 设置 - 设备与服务 - 添加集成 - 搜索 MQTT - 填写代理信息;  
 创建成功后,可在 设备与服务 选项下看到 MQTT 应用图标;  
 根据开发板蓝牙发送的信息格式,配置 YAML 参数  
 打开 Home Assistant 安装根目录下的 configuration.yaml 文件,并添加如下代码  
 - mqtt:
 -   sensor:
 -     - name: "Temperature"
 -       state_topic: "home/sensor/"
 -       suggested_display_precision: 2
 -       unit_of_measurement: "C"
 -       value_template: "{{ value_json.temperature }}"
 -     - name: "Humidity"
 -       state_topic: "home/sensor/"
 -       suggested_display_precision: 2
 -       unit_of_measurement: "%"
 -       value_template: "{{ value_json.humidity }}"
 
  复制代码
  
 需要注意主题 state_topic 和 value_template 的定义。  
 在 开发者工具 界面 重新加载 YAML 所有配置 并刷新浏览器界面,即可看到传感器选项。  
 DHT11 
 采集 DHT11 温湿度数据并通过 MQTT 联网上传至 Home Assistant 智能家居平台;  
 Arduino Code- #include <ESP8266WiFi.h>
 - #include <PubSubClient.h>
 - #include <ArduinoJson.h>
 - #include <DHT.h>
 - 
 - // WiFi Configuration
 - const char* ssid = "xxx";
 - const char* password = "xxx";
 - 
 - // MQTT Configuration
 - const char* mqtt_server = "192.168.1.121";
 - const int mqtt_port = 1883;
 - const char* mqtt_user = "admin";
 - const char* mqtt_password = "admin";
 - 
 - // Device Configuration
 - const char* device_name = "esp8266_dht11";
 - const char* device_id = "livingroom_sensor";
 - 
 - // Topics
 - const char* state_topic = "home/sensor/";
 - const char* temp_config_topic = "home/sensor/";
 - const char* hum_config_topic = "home/sensor/";
 - 
 - // DHT Sensor
 - #define DHTPIN 5
 - #define DHTTYPE DHT11
 - DHT dht(DHTPIN, DHTTYPE);
 - 
 - WiFiClient espClient;
 - PubSubClient client(espClient);
 - 
 - 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("");
 -   Serial.println("WiFi connected");
 -   Serial.println("IP address: ");
 -   Serial.println(WiFi.localIP());
 - }
 - 
 - void reconnect() {
 -   while (!client.connected()) {
 -     Serial.print("Attempting MQTT connection...");
 -     if (client.connect(device_name, mqtt_user, mqtt_password)) {
 -       Serial.println("connected");
 -       // Send Home Assistant auto-discovery config
 -       sendAutoDiscoveryConfig();
 -     } else {
 -       Serial.print("failed, rc=");
 -       Serial.print(client.state());
 -       Serial.println(" try again in 5 seconds");
 -       delay(5000);
 -     }
 -   }
 - }
 - 
 - void sendAutoDiscoveryConfig() {
 -   // Configuration for temperature sensor
 -   DynamicJsonDocument temp_config(512);
 -   temp_config["name"] = "Living Room Temperature";
 -   temp_config["device_class"] = "temperature";
 -   temp_config["state_topic"] = state_topic;
 -   temp_config["unit_of_measurement"] = "°C";
 -   temp_config["value_template"] = "{{ value_json.temperature }}";
 -   temp_config["unique_id"] = String(device_id) + "_temperature";
 -   temp_config["device"]["identifiers"] = device_id;
 -   temp_config["device"]["name"] = "Living Room Sensor";
 -   temp_config["device"]["manufacturer"] = "DIY";
 -   temp_config["device"]["model"] = "ESP8266+DHT11";
 -   
 -   char temp_config_message[512];
 -   serializeJson(temp_config, temp_config_message);
 -   client.publish(temp_config_topic, temp_config_message, true);
 - 
 -   // Configuration for humidity sensor
 -   DynamicJsonDocument hum_config(512);
 -   hum_config["name"] = "Living Room Humidity";
 -   hum_config["device_class"] = "humidity";
 -   hum_config["state_topic"] = state_topic;
 -   hum_config["unit_of_measurement"] = "%";
 -   hum_config["value_template"] = "{{ value_json.humidity }}";
 -   hum_config["unique_id"] = String(device_id) + "_humidity";
 -   hum_config["device"] = temp_config["device"]; // Same device info
 -   
 -   char hum_config_message[512];
 -   serializeJson(hum_config, hum_config_message);
 -   client.publish(hum_config_topic, hum_config_message, true);
 - }
 - 
 - void setup() {
 -   Serial.begin(115200);
 -   dht.begin();
 -   setup_wifi();
 -   client.setServer(mqtt_server, mqtt_port);
 - }
 - 
 - void loop() {
 -   if (!client.connected()) {
 -     reconnect();
 -   }
 -   client.loop();
 - 
 -   delay(2000); // Wait between measurements
 - 
 -   float h = dht.readHumidity();
 -   float t = dht.readTemperature();
 - 
 -   if (isnan(h) || isnan(t)) {
 -     Serial.println("Failed to read from DHT sensor!");
 -     return;
 -   }
 - 
 -   // Create JSON payload
 -   DynamicJsonDocument doc(256);
 -   doc["temperature"] = t;
 -   doc["humidity"] = h;
 - 
 -   char json_string[256];
 -   serializeJson(doc, json_string);
 -   
 -   Serial.print("Publishing: ");
 -   Serial.println(json_string);
 -   
 -   client.publish(state_topic, json_string, true);
 - }
 
  复制代码
  
 
效果DS18B20 
采集 DS18B20 温度数据并通过 MQTT 联网上传至 Home Assistant 智能家居平台;  
 Arduino Code- #include <ESP8266WiFi.h>
 - #include <PubSubClient.h>
 - #include <ArduinoJson.h>
 - #include <OneWire.h>
 - #include <DallasTemperature.h>
 - 
 - // WiFi Configuration
 - const char* ssid = "B228-230";
 - const char* password = "LPSerB228";
 - 
 - // MQTT Configuration
 - const char* mqtt_server = "192.168.1.121";
 - const int mqtt_port = 1883;
 - const char* mqtt_user = "LJL";
 - const char* mqtt_password = "4421989g";
 - 
 - // Device Configuration
 - const char* device_name = "esp8266_ds18b20";
 - const char* device_id = "water_tank_sensor";
 - 
 - // Topics
 - const char* state_topic = "home/sensor/";
 - const char* temp_config_topic = "home/sensor/";
 - 
 - // DS18B20 Setup
 - #define ONE_WIRE_BUS 5
 - OneWire oneWire(ONE_WIRE_BUS);
 - DallasTemperature sensors(&oneWire);
 - 
 - WiFiClient espClient;
 - PubSubClient client(espClient);
 - 
 - 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("");
 -   Serial.println("WiFi connected");
 -   Serial.println("IP address: ");
 -   Serial.println(WiFi.localIP());
 - }
 - 
 - void reconnect() {
 -   while (!client.connected()) {
 -     Serial.print("Attempting MQTT connection...");
 -     if (client.connect(device_name, mqtt_user, mqtt_password)) {
 -       Serial.println("connected");
 -       // Send Home Assistant auto-discovery config
 -       sendAutoDiscoveryConfig();
 -     } else {
 -       Serial.print("failed, rc=");
 -       Serial.print(client.state());
 -       Serial.println(" try again in 5 seconds");
 -       delay(5000);
 -     }
 -   }
 - }
 - 
 - void sendAutoDiscoveryConfig() {
 -   // Configuration for temperature sensor
 -   DynamicJsonDocument temp_config(512);
 -   temp_config["name"] = "Water Tank Temperature";
 -   temp_config["device_class"] = "temperature";
 -   temp_config["state_topic"] = state_topic;
 -   temp_config["unit_of_measurement"] = "°C";
 -   temp_config["value_template"] = "{{ value_json.temperature }}";
 -   temp_config["unique_id"] = String(device_id) + "_temperature";
 -   temp_config["device"]["identifiers"] = device_id;
 -   temp_config["device"]["name"] = "Water Tank Sensor";
 -   temp_config["device"]["manufacturer"] = "DIY";
 -   temp_config["device"]["model"] = "ESP8266+DS18B20";
 -   
 -   char temp_config_message[512];
 -   serializeJson(temp_config, temp_config_message);
 -   client.publish(temp_config_topic, temp_config_message, true);
 - }
 - 
 - void setup() {
 -   Serial.begin(115200);
 -   sensors.begin();
 -   setup_wifi();
 -   client.setServer(mqtt_server, mqtt_port);
 - }
 - 
 - void loop() {
 -   if (!client.connected()) {
 -     reconnect();
 -   }
 -   client.loop();
 - 
 -   delay(2000); // Wait between measurements
 - 
 -   sensors.requestTemperatures(); 
 -   float t = sensors.getTempCByIndex(0);
 - 
 -   // Check if reading is valid
 -   if(t == DEVICE_DISCONNECTED_C) {
 -     Serial.println("Error: Could not read temperature data");
 -     return;
 -   }
 - 
 -   // Create JSON payload
 -   DynamicJsonDocument doc(128);
 -   doc["temperature"] = t;
 - 
 -   char json_string[128];
 -   serializeJson(doc, json_string);
 -   
 -   Serial.print("Temperature: ");
 -   Serial.print(t);
 -   Serial.println(" °C");
 -   Serial.print("Publishing: ");
 -   Serial.println(json_string);
 -   
 -   client.publish(state_topic, json_string, true);
 - }
 
  复制代码
  
 
OLED显示- #include <ESP8266WiFi.h>
 - #include <PubSubClient.h>
 - #include <ArduinoJson.h>
 - #include <OneWire.h>
 - #include <DallasTemperature.h>
 - // OLED
 - #include <Wire.h>
 - #include <Adafruit_GFX.h>
 - #include <Adafruit_SSD1306.h>
 - #include <Adafruit_Sensor.h>
 - 
 - #define SCREEN_WIDTH 128 // OLED display width, in pixels
 - #define SCREEN_HEIGHT 64 // OLED display height, in pixels
 - #define OLED_SDA 02                       // SDA引脚,gpio2(D4)
 - #define OLED_SCL 14                       // SCL引脚,gpio14(D5)
 - 
 - // Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
 - Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
 - 
 - // WiFi Configuration
 - const char* ssid = "B228-230";
 - const char* password = "LPSerB228";
 - 
 - // MQTT Configuration
 - const char* mqtt_server = "192.168.1.121";
 - const int mqtt_port = 1883;
 - const char* mqtt_user = "LJL";
 - const char* mqtt_password = "4421989g";
 - 
 - // Device Configuration
 - const char* device_name = "esp8266_ds18b20";
 - const char* device_id = "water_tank_sensor";
 - 
 - // Topics
 - const char* state_topic = "home/sensor/";
 - const char* temp_config_topic = "home/sensor/";
 - 
 - // DS18B20 Setup
 - #define ONE_WIRE_BUS 5
 - OneWire oneWire(ONE_WIRE_BUS);
 - DallasTemperature sensors(&oneWire);
 - 
 - WiFiClient espClient;
 - PubSubClient client(espClient);
 - 
 - 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("");
 -   Serial.println("WiFi connected");
 -   Serial.println("IP address: ");
 -   Serial.println(WiFi.localIP());
 - }
 - 
 - void reconnect() {
 -   while (!client.connected()) {
 -     Serial.print("Attempting MQTT connection...");
 -     if (client.connect(device_name, mqtt_user, mqtt_password)) {
 -       Serial.println("connected");
 -       // Send Home Assistant auto-discovery config
 -       sendAutoDiscoveryConfig();
 -     } else {
 -       Serial.print("failed, rc=");
 -       Serial.print(client.state());
 -       Serial.println(" try again in 5 seconds");
 -       delay(5000);
 -     }
 -   }
 - }
 - 
 - void sendAutoDiscoveryConfig() {
 -   // Configuration for temperature sensor
 -   DynamicJsonDocument temp_config(512);
 -   temp_config["name"] = "Water Tank Temperature";
 -   temp_config["device_class"] = "temperature";
 -   temp_config["state_topic"] = state_topic;
 -   temp_config["unit_of_measurement"] = "°C";
 -   temp_config["value_template"] = "{{ value_json.temperature }}";
 -   temp_config["unique_id"] = String(device_id) + "_temperature";
 -   temp_config["device"]["identifiers"] = device_id;
 -   temp_config["device"]["name"] = "Water Tank Sensor";
 -   temp_config["device"]["manufacturer"] = "DIY";
 -   temp_config["device"]["model"] = "ESP8266+DS18B20";
 -   
 -   char temp_config_message[512];
 -   serializeJson(temp_config, temp_config_message);
 -   client.publish(temp_config_topic, temp_config_message, true);
 - }
 - 
 - void setup() {
 -   Wire.begin(OLED_SDA, OLED_SCL);
 -   Serial.begin(115200);
 - 
 -   sensors.begin();
 - 
 -   if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
 -     Serial.println(F("SSD1306 allocation failed"));
 -     for(;;);
 -   }
 -   delay(2000);
 -   display.clearDisplay();
 -   display.setTextColor(WHITE);
 - 
 -   setup_wifi();
 -   client.setServer(mqtt_server, mqtt_port);
 - }
 - 
 - void loop() {
 -   //read temperature 
 -   Serial.print("Requesting temperatures...");
 -   sensors.requestTemperatures(); // Send the command to get temperatures
 -   Serial.println("DONE");
 - 
 -   if (!client.connected()) {
 -     reconnect();
 -   }
 -   client.loop();
 - 
 -   delay(2000); // Wait between measurements
 - 
 -   //sensors.requestTemperatures(); 
 -   float tempC = sensors.getTempCByIndex(0);
 - 
 -   // Check if reading is valid
 -   if (tempC != DEVICE_DISCONNECTED_C)
 -   {
 -     Serial.print("Temperature for the device 1 (index 0) is: ");
 -     Serial.println(tempC);
 -   }
 -   else
 -   {
 -     Serial.println("Error: Could not read temperature data");
 -     return;
 -   }
 -   /*
 -   if(tempC == DEVICE_DISCONNECTED_C) {
 -     Serial.println("Error: Could not read temperature data");
 -     return;
 -   }
 -   */
 -   // clear display
 -   display.clearDisplay();
 -   // display temperature
 -   display.setTextSize(1);
 -   display.setCursor(0,0);
 -   display.print("Temperature: ");
 -   display.setTextSize(2);
 -   display.setCursor(0,17);
 -   display.print(tempC);
 -   display.print(" ");
 -   display.setTextSize(1);
 -   display.cp437(true);
 -   display.write(167);
 -   display.setTextSize(2);
 -   display.print("C");
 -   
 -   display.display(); 
 - 
 -   // Create JSON payload
 -   DynamicJsonDocument doc(128);
 -   doc["temperature"] = tempC;
 - 
 -   char json_string[128];
 -   serializeJson(doc, json_string);
 -   
 -   Serial.print("Temperature: ");
 -   Serial.print(tempC);
 -   Serial.println(" °C");
 -   Serial.print("Publishing: ");
 -   Serial.println(json_string);
 -   
 -   client.publish(state_topic, json_string, true);
 - }
 
  复制代码
  
 
效果 
 
总结 
本文介绍了 ESP8266 开发板实现 DHT11 温湿度传感器和 DS18B20 温度传感器实现远程温度监测,通过 MQTT 协议上传至 EMQX 平台,发送 JSON 代码实现 HomeAssistant 智能家居平台数据收集和历史数据查看等功能,为物联网相关硬件部署和智能家居的开发和拓展提供了参考。  
 
 |