WLED Usermod 实战:用 wizlights 模块让 ESP32 同步控制 WiZ 智能灯
【免费下载链接】WLEDControl WS2812B and many more types of digital RGB LEDs with an ESP32 over WiFi!项目地址: https://gitcode.com/GitHub_Trending/wl/WLED
本文以 WLED 仓库中的usermods/wizlights用户模块(usermod)为核心,讲解如何在 ESP32 上通过 UDP 控制与 WLED 控制器处于同一局域网的 WiZ 智能灯。读完后,你将掌握该模块的完整配置参数(含默认值与源码依据)、WiZ 灯的 UDP JSON 控制协议格式、模块主循环的更新判定逻辑,以及如何在 PlatformIO 构建系统中启用该模块。
模块定位:把 WLED 像素颜色"投影"到 WiZ 灯
WiZ 是一款带 WiFi 功能的智能灯泡品牌。wizlights 模块的功能非常聚焦:读取 WLED 灯带上前几个像素的颜色,并以 UDP 报文的形式发送给同一网络内的 WiZ 灯,从而让"真实灯泡"与 ESP32 控制的灯带同步变色。从源码看,模块维护一个 IP 地址数组,最多支持 15 盏灯(由MAX_WIZ_LIGHTS宏定义),第 N 个 IP 对应灯带第 N 个像素的颜色(见 wizlights.cpp 中的strip.getPixelColor(i))。
配置参数详解
该模块通过 WLED 的 usermod 设置页写入cfg.json,配置节名为wizLightsUsermod。以下参数说明继承自官方 readme,默认值与取值说明均来自 wizlights.cpp 的 readFromConfig:
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
Interval (ms) | 整数 | 1000 | WiZ 灯的更新周期(毫秒)。官方提示:设置过低可能导致 ESP 无响应 |
Send Delay (ms) | 整数 | 0 | 每更新一盏 WiZ 灯后的可选延时,用于在灯数量较多时平滑过渡 |
Use Enhanced White | 布尔 | false | 当颜色为白色时,使用 WiZ 灯板载的白光灯珠(而非 RGB 满值混合);可结合暖光/冷光灯珠调节。注意:只有 RGB 最大值被设为满值(即关闭自动亮度限制)时才会下发白色 |
Warm White Value (0-255) | 整数 | 0 | 增强白色模式下的暖光灯珠值(配置项前带*,仅在启用增强白色时生效) |
Cold White Value (0-255) | 整数 | 50 | 增强白色模式下的冷光灯珠值 |
Always Force Update | 布尔 | false | 即使新旧颜色相同也强制发送更新报文 |
Force Update Every x Minutes | 整数 | 5 | 颜色未变化时的兜底强制重发周期,替代默认 5 分钟;设为 0 等价于开启 Always Force Update |
WiZ Light IP #1…WiZ Light IP #15 | IP 字符串 | 0.0.0.0 | 按顺序填写要控制的灯 IP;无效 IP 会被置为0.0.0.0并跳过 |
其中 IP 上限 15 由源码宏MAX_WIZ_LIGHTS 15决定(wizlights.cpp),官方文档也说明该数值可通过修改宏轻易调整。配置写入逻辑在addToConfig()中:7 个参数加上循环生成的WiZ Light IP #1~#15标签(getJsonLabel(i)返回"WiZ Light IP #" + String(i+1)),全部挂在wizLightsUsermod节点下(wizlights.cpp)。
WiZ 灯的 UDP 控制协议
模块的核心发送函数wizSendColor()(wizlights.cpp)通过WiFiUDP向灯的38899 端口发送 JSON 报文,采用setPilot方法,共四种形态:
// 关灯(color == 0)。灯自身的 "Off fade-out" 设置仍会生效 {"method":"setPilot","params":{"state":false}} // 暖光 + 冷光白光灯珠(增强白色模式) {"method":"setPilot","params":{"c":50,"w":128}} // 仅冷光 / 仅暖光:分别只带 "c" 或只带 "w" 字段 {"method":"setPilot","params":{"c":50}} // 普通 RGB 颜色 {"method":"setPilot","params":{"r":255,"g":128,"b":0}}分支判定逻辑值得注意:
color == 0→ 关灯;color == 1677215(即 0xFFFFFF 纯白)且useEnhancedWhite为 true → 按coldWhite/warmWhite的组合下发c/w字段,两者均为 0 时不发送任何白场参数;- 其余情况 → 用
R(color)/G(color)/B(color)宏拆开 32 位颜色值,下发 RGB。
这与官方文档"Use Enhanced White … Only sent when max RGB value is set, the automatic brightness limiter must be disabled"的提示完全对应:WLED 的亮度限制或 2D 模式下像素达不到 0xFFFFFF 时,会退回 RGB 分支。源码中同时留有 TODO 注释,说明作者计划更好地复用 WLED 既有的白色混合逻辑(wizlights.cpp)。
主循环:更新判定的三重条件
模块在 WLED 主循环中被周期性调用,loop()的判定链(wizlights.cpp)如下:
- 连接前置:
if (!WLED_CONNECTED) return;—— 宏WLED_CONNECTED展开为WLEDNetwork.isConnected()(见 wled.h),Wi-Fi 未连接时不发送任何报文; - 周期门限:
millis() - lastTime > updateInterval才进入一轮扫描。注意lastTime仅在本轮确实发出了报文(update == true)后刷新,若所有灯颜色都未变化,下一毫秒仍会进入扫描做判定,直到forceUpdateMinutes超时兜底; - 逐灯判定:对每个 IP 有效的灯,取
strip.getPixelColor(i),满足以下任一条件即发送——forceUpdate(Always Force Update)为真、新颜色与colorsSent[i]不同、或距上次发送超过forceUpdateMinutes * 60000毫秒(即"Force update every x minutes"的兜底重发)。发送后更新colorsSent[i]并delay(sendDelay),对应"Send Delay"参数在灯与灯之间的错峰效果。
setup()被实现为空函数,注释写明"Override definition so it compiles"——这是 WLED 基类Usermod的两个纯虚函数之一,必须重写才能实例化(见 fcn_declare.h 中virtual void setup() = 0;)。此外,源码中loop()上方留有// TODO: Check millis() rollover的待办注释,提示超长时间运行下 32 位毫秒计数的回绕是作者已知的潜在关注点。
模块通过static WizLightsUsermod wizlights;与REGISTER_USERMOD(wizlights)完成自注册,getId()返回的USERMOD_ID_WIZLIGHTS在 const.h 中定义为26,这是它与其他 usermod 共存时的唯一标识。
在构建中启用 wizlights
WLED 的 usermod 通过 PlatformIO 的custom_usermods变量接入。启用方式:在项目的platformio_override.ini(参考 platformio_override.sample.ini)中为所选环境添加:
[env:esp32dev] custom_usermods = wizlights构建时 load_usermods.py 会做以下事情:
- 在
usermods/目录下按wizlights、wizlights_v2、usermod_v2_wizlights三种命名依次查找模块目录(find_usermods,load_usermods.py),并转换为symlink://依赖注入lib_deps; - 该脚本还会强制校验每个 usermod 的
library.json必须含"build": {"libArchive": false},否则直接报错退出——因为 usermod 需要以静态目标形式直接链接进主程序,而不是打包成库归档。wizlights 的 library.json 正符合此要求:
{ "name": "wizlights", "build": { "libArchive": false } }- 仓库自带的 usermods/platformio_override.usermods.ini 则演示了
usermods_*系列调试环境(如usermods_esp32),其中custom_usermods = ${usermods.custom_usermods}留待 CI 填充。官方 usermod 贡献指南(usermods/readme.md)建议新模块优先采用 v2 API,wizlights 正是符合setup/loop/addToConfig/readFromConfig接口的 v2 风格实现。
适用前提与限制
- WiZ 灯必须与 ESP32 处于同一二层网络,且 IP 需稳定(静态 IP 或 DHCP 固定分配),模块按 IP 直连,不做服务发现;
- 灯带像素数决定可同步的灯数上限(第 i 个像素 → 第 i 盏灯),灯数硬上限 15;
- 增强白色仅在像素达到纯白 0xFFFFFF 时生效,因此需按上文说明处理 WLED 的亮度上限;
- 每轮更新是阻塞式的(含
delay(sendDelay)),Interval设置过低时官方文档明确警告可能导致 ESP 无响应; - 该模块属于 usermods 目录,随 WLED 主版本升级可能失效,维护责任在作者——这是 usermods/readme.md 对全部 usermod 的统一声明。
延伸:pywizlight
官方文档还建议:如果你同时使用 Python 与 WiZ 灯,可以了解pywizlight开源项目来学习 WiZ 灯控制报文的具体格式——本文列出的setPilotJSON 结构正是该协议的实践示例,两者可互为参照。
【免费下载链接】WLEDControl WS2812B and many more types of digital RGB LEDs with an ESP32 over WiFi!项目地址: https://gitcode.com/GitHub_Trending/wl/WLED
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考