news 2026/9/13 15:37:13

WLED Si7021_MQTT_HA Usermod:将温湿度传感器数据发布到 MQTT 并自动注册 Home Assistant

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
WLED Si7021_MQTT_HA Usermod:将温湿度传感器数据发布到 MQTT 并自动注册 Home Assistant

WLED Si7021_MQTT_HA Usermod:将温湿度传感器数据发布到 MQTT 并自动注册 Home Assistant

【免费下载链接】WLEDControl WS2812B and many more types of digital RGB LEDs with an ESP32 over WiFi!项目地址: https://gitcode.com/GitHub_Trending/wl/WLED

WLED 不仅是一个灯带控制器,其 usermod 扩展机制还允许把 ESP32/ESP8266 变成通用传感器节点。本文以仓库中的 Si7021_MQTT_HA usermod 为主线,讲解如何通过 I²C 读取 Si7021 温湿度传感器、按固定周期发布到 WLED 内置 MQTT 设备主题,以及自动发布 Home Assistant MQTT Auto-Discovery 配置、让传感器在 Home Assistant 中免手动配置直接出现。读完本文,你可以完成从接线、PlatformIO 编译配置到 MQTT 主题与 HA 传感器注册的完整部署,并理解该 usermod 在源码层面的生命周期与调度细节。

功能定位与 MQTT 主题设计

该 usermod 实现了 Si7021 I²C 温湿度传感器 的支持。需要注意的是:传感器数据不会显示在 WLED 的 Web UI 上,它的作用纯粹是作为传感器数据的 MQTT 发布器。核心行为如下:

  • 基础数据(温度、湿度)发布到 WLED 内置 MQTT 设备主题($mqttDeviceTopic,即 WLED 自身 MQTT 功能所使用的设备前缀)下:
temperature: $mqttDeviceTopic/si7021_temperature humidity: $mqttDeviceTopic/si7021_humidity
  • 可选的衍生量(由代码调用EnvironmentCalculations库计算得出):
heat_index: $mqttDeviceTopic/si7021_heat_index dew_point: $mqttDeviceTopic/si7021_dew_point absolute_humidity: $mqttDeviceTopic/si7021_absolute_humidity
  • 传感器数据每60 秒更新并发布一次(对应源码loop()中的nextMeasure = tempTimer + 60000,见 Si7021_MQTT_HA.cpp)。
  • 同时支持 Home Assistant MQTT Auto-Discovery,无需在 HA 中手写 YAML 传感器定义。

从源码结构看,该文件头部注释说明它 remix 自 sensors_to_mqtt 与 multi_relay 两个 usermod,因此其 MQTT 发布与 I²C 初始化套路与这两个成熟 usermod 一致。

依赖与编译前提

该 usermod 的 library.json 声明了以下依赖,PlatformIO 编译时会自动拉取:

{ "name": "Si7021_MQTT_HA", "build": { "libArchive": false }, "dependencies": { "finitestate/BME280": "3.0.0", "adafruit/Adafruit Si7021 Library": "1.5.3", "SPI": "*", "adafruit/Adafruit BusIO": "1.17.1" } }

其中Adafruit Si7021 Library负责 I²C 寄存器级读写,EnvironmentCalculations(由 BME280 库提供)负责根据温湿度计算热指数、露点与绝对湿度。

还有一个硬性前提:构建时 MQTT 必须处于启用状态。源码开头有编译期检查:

#ifdef WLED_DISABLE_MQTT #error "This user mod requires MQTT to be enabled." #endif

也就是说,如果你的构建环境使用了-D WLED_DISABLE_MQTT(platformio_override.sample.ini 的注释中也列出了该开关),该 usermod 会直接编译失败——这是作者显式拒绝支持无 MQTT 场景的方式。

运行流程:从 WiFi 上线到周期发布

理解 Si7021_MQTT_HA.cpp 的四个生命周期回调,就能掌握其完整行为链:

  1. setup():仅在enabled为 true 时打印启动日志并调用si7021.begin()初始化 I²C 传感器(L173-L180)。此时并不触碰 MQTT。
  2. onMqttConnect():MQTT 连接建立后回调,若mqttDeviceTopic非空则执行_initializeMqtt()——拼接五个完整主题、立即执行一次「读数 + 发布」,并在开启 HA 发现时发布 discovery 配置(L168-L171)。
  3. connected():每次 WiFi(重新)连接后,将首次测量安排在 5 秒后(nextMeasure = millis() + 5000),保证 WiFi 就绪后很快就有第一份数据。
  4. loop():主循环中的看门狗逻辑(L188-L217):
    • 调用yield()让出,并在!enabled或灯带正在刷新(strip.isUpdating())时直接返回,避免在效果渲染高峰期占用 CPU;
    • 到达nextMeasure后将下一轮安排在 60 秒后;
    • 若传感器此前未初始化成功,会在 loop 中重试初始化(打印错误并等待下一轮),提供了启动时 I²C 总线尚未就绪的容错;
    • 只有WLED_MQTT_CONNECTED为真时才发布;MQTT 断开时会复位mqttInitialized并打印提示,重连后自动重新初始化主题与 discovery。

这种「MQTT 未连接就不发布、重连后自愈」的设计,使该 usermod 在断网重连场景下不需要人工干预。

Home Assistant Auto-Discovery 配置详解

开启Home Assistant MQTT Auto-Discovery后,_publishHAMqttSensor()(L71-L104)会向标准 discovery 主题homeassistant/sensor/{mqttClientID}/{name}/config发布传感器配置,其中mqttClientID是 WLED 的 MQTT 客户端 ID。配置载荷的字段如下:

字段取值说明
name{serverDescription} {友好名}如 "WLED Temperature"
state_topic对应数据主题与上文$mqttDeviceTopic/si7021_*一致
unique_id{mqttClientID}{name}HA 实体唯一标识
unit_of_measurement°C/%/g/m³绝对湿度单位为 g/m³
device_classtemperature/humidity仅温度类传感器携带
expire_after180030 分钟无更新则 HA 标记离线
device.name/model/manufacturer/identifiers/sw_versionWLED 相关信息将传感器挂到同一 WLED 设备下

几个值得注意的实现细节:

  • dew_pointabsolute_humiditydevice_class传空字符串,源码中对空device_class/unit_of_measurement会跳过对应字段(if (deviceClass != "")判断),因此 HA 中它们仍会显示单位,只是不被归类为标准温度传感器;
  • 发布使用mqtt->publish(topic, 0, true, ...)retained(保留)消息,而数据消息使用非保留发布(_publishSensorData()中 retain 参数为 false)——discovery 配置需要保留以便 HA 重启后仍能读到;
  • 温度、湿度两个基础传感器始终发布 discovery,heat_indexdew_pointabsolute_humidity三个附加传感器受sendAdditionalSensors开关控制(见 L58-L66)。

硬件接线与 I²C 引脚配置

将 Si7021 传感器接到 I²C 总线即可。README 给出的默认引脚为:

// ESP32 SCL_PIN = 22; SDA_PIN = 21; // ESP8266 SCL_PIN = 5; SDA_PIN = 4;

如果你的硬件使用其他 GPIO,可以通过 WLED 的构建宏I2CSCLPIN/I2CSDAPIN初始化 I²C 接口。wled00/wled.h 中可以看到全局 I²C 引脚变量由这两个宏驱动:

// global I2C SDA pin (used for usermods) WLED_GLOBAL int8_t i2c_sda _INIT(I2CSDAPIN); // global I2C SCL pin (used for usermods) WLED_GLOBAL int8_t i2c_scl _INIT(I2CSCLPIN);

platformio_override.sample.ini 中也给出了用法示例:

; -D I2CSDAPIN=33 # initialise interface ; -D I2CSCLPIN=35 # initialise interface

build_flags中加上-D I2CSDAPIN=xx -D I2CSCLPIN=xx即可切换到自定义引脚;而HW_PIN_SCL/HW_PIN_SDA仅用于告知 WebUI 默认引脚提示,不会真正初始化接口。

Usermod 设置项

编译烧录后,三个运行时设置项会出现在 WLED 的 usermod 配置区(对应源码中以PROGMEM常量定义的键名,见 Si7021_MQTT_HA.cpp,usermod 显示名为 "Si7021 MQTT (Home Assistant)",ID 为USERMOD_ID_SI7021_MQTT_HA = 29,定义于 wled00/const.h):

配置键作用源码默认值
enabled使能该 usermod(关闭后loop()直接返回,不读传感器也不发布)false
Send Dew Point, Abs. Humidity and Heat Index是否同时发布露点、绝对湿度、热指数三个衍生传感器(含其 discovery 配置与计算开销)true
Home Assistant MQTT Auto-Discovery是否在 MQTT 连接时发布 HA discovery 配置true

这三个布尔值同时通过addToConfig()/readFromConfig()持久化到 WLED 的 JSON 配置中,断电重启后保留。

安装步骤

  1. 接线:按上文将 Si7021 接到 I²C(SDA/SCL 各加 4.7kΩ 上拉电阻是常规做法,具体视模块而定);

  2. 编译配置:在platformio_override.ini(复制自 platformio_override.sample.ini)的目标环境段中加入Si7021_MQTT_HA

    custom_usermods = ${env:esp32dev.custom_usermods} Si7021_MQTT_HA

    注意custom_usermods是环境段的独立键,多个 usermod 用空格分隔(sample 文件注释中有专门说明)。仓库自带的 platformio.ini 中的[env:usermods]环境则使用custom_usermods = *一次性展开usermods/目录下全部 usermod,适合想整体体验的场景,但会占用更多 flash;

  3. 确认 MQTT 可用:确保构建未启用-D WLED_DISABLE_MQTT,并在 WLED 的同步设置中配置好 MQTT broker 与设备主题;

  4. 运行时启用:烧录后在 WLED 的 usermod 设置中打开enabled,按需保留或关闭另外两个开关;

  5. 验证:观察串口输出(初始化日志、MQTT 缺失告警),或在 MQTT 客户端订阅$mqttDeviceTopic/si7021_temperaturehomeassistant/sensor/主题树,确认数据与 discovery 配置均已到达。

边界与限制

  • 数据只走 MQTT,WLED UI 不显示传感器读数,这是该 usermod 的设计定位;
  • 发布节奏固定为 60 秒,且首次读数安排在 WiFi 连接后 5 秒,均写死在源码中,不提供运行时调节;
  • 每轮测量会阻塞式执行 I²C 读数与浮点计算,源码特意在strip.isUpdating()期间跳过本轮,以保护灯光效果流畅度——如果你的灯光负载重,可留意这一避让逻辑带来的测量时间抖动;
  • 该 usermod 属于社区贡献代码,位于usermods/目录,按 usermods 总说明 的约定,其维护责任在各自作者,随 WLED 主版本升级可能需要同步调整。

小结

Si7021_MQTT_HA 用不到 240 行源码(Si7021_MQTT_HA.cpp)展示了一个 WLED usermod 处理「外设 + 网络服务」的完整范式:library.json声明依赖、编译期宏检查硬性前提、setup/connected/onMqttConnect/loop四个回调各司其职、retained discovery 消息 + 非 retained 数据消息区分对待、PROGMEM字符串与F()宏控制 flash 占用。如果你想给 WLED 增加其他传感器并接入 Home Assistant,这个 usermod 连同 sensors_to_mqtt 都值得一读。

【免费下载链接】WLEDControl WS2812B and many more types of digital RGB LEDs with an ESP32 over WiFi!项目地址: https://gitcode.com/GitHub_Trending/wl/WLED

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/13 15:34:32

Java手写倒排索引搜索引擎教学系统

简介:本资源是一套完整的基于Java的搜索引擎毕业设计实现方案,面向计算机及相关专业(如人工智能、物联网、电子信息等)的本科生、研究生及初学者,解决课程设计、毕设选题与工程实践中的核心开发需求。压缩包共329个文件…

作者头像 李华
网站建设 2026/9/13 15:31:58

垂直GaN功率器件原理与工程落地全解析

1. 项目概述:为什么“垂直GaN”突然成了功率器件圈的高频词?最近在电源设计、快充模块和工业电机驱动的几个技术群里,几乎每天都有人贴出安森美(onsemi)新发布的NV6134A或NV6136A器件的实测波形图,配文往往…

作者头像 李华
网站建设 2026/9/13 15:29:33

国产电源芯片选型避坑指南:架构、工艺、支撑与FAE四维评估法

1. 为什么这份清单不叫“国产电源芯片推荐榜”,而叫“原厂摸底报告”“国产电源芯片”这六个字,这两年在BOM表、采购单、技术评审会上出现的频率,已经高到让很多资深电子工程师下意识皱眉的程度。不是因为不重要——恰恰相反,它太…

作者头像 李华