完整实战指南)
基于 ESP Weaver 构建 Home Assistant 智能灯LED 灯示例esp-iot-solution完整实战指南【免费下载链接】esp-iot-solutionEspressif IoT Library. IoT Device Drivers, Documentations and Solutions.项目地址: https://gitcode.com/GitHub_Trending/es/esp-iot-solution本指南围绕 esp-iot-solution 仓库中 examples/weaver/led_light 示例展开讲解如何用 ESP Weaver 组件esp_weaver_*API esp_local_ctrl mDNS将一颗 RGB LEDWS2812 或三引脚 RGB 模块打造成支持电源开关、亮度调节与 HSV 颜色控制的智能灯并接入 Home Assistant 实现局域网内自动发现与本地控制。读完本文你将掌握 Weaver 设备/参数模型的组织方式、LED 驱动的接入细节、PoP 安全配对流程以及从编译烧录到 Home Assistant 联调的完整链路。适用芯片ESP32 / ESP32-C2 / ESP32-C3 / ESP32-C5 / ESP32-C6 / ESP32-C61 / ESP32-S3开发环境ESP-IDF v5.5组件 components/esp_weaver/README_CN.md 声明的支持版本。示例能做什么led_light示例实现的是一台标准的智能灯泡设备核心能力有三项电源开/关控制通过按钮或 Home Assistant 开关实体切换灯的亮灭亮度调节0–100%以百分比滑块形式暴露给上层应用HSV 颜色控制色相 0–360°、饱和度 0–100%可直接在 Home Assistant 颜色控件中调色。这些能力不是写在固件里的一次性行为而是通过 Weaver 的设备/参数模型暴露为标准属性Home Assistant 会自动渲染成对应的电源开关、亮度滑块、颜色选择器等实体。设备联网后通过 mDNS 广播服务Home Assistant 安装 ESP-Weaver 集成后即可自动发现并配对全程走局域网内 esp_local_ctrl 协议不依赖任何云服务。硬件准备硬件说明开发板搭载上表任一 SoC 的乐鑫官方开发板如 ESP32-S3-DevKitC-1、ESP32-C6-DevKitC-1 等RGB LEDWS2812 可寻址灯条或 3 引脚 RGB 模块数据线USB 数据线用于供电和烧录网络WiFi 路由器设备与 Home Assistant 需在同一局域网按钮直接复用开发板上的 BOOT 按钮不同开发板的板载 LED 情况不同ESP32 DevKit 无板载 RGB需外接 3 引脚 RGB 模块ESP8684-DevKitM-1ESP32-C2板载三引脚 RGBESP32-S3/C3/C6/C61 等开发板通常板载 WS2812。LED 类型和对应 GPIO 均可在idf.py menuconfig→ Example Configuration 中调整详见下文配置详解无需改代码。示例代码结构示例位于 examples/weaver/led_lightmain/目录下按职责拆分为四个模块文件职责main/app_main.c应用入口NVS、硬件、Weaver 节点初始化连接 WiFi 并启动本地控制main/app_light.c构建灯泡设备与参数模型处理来自 Home Assistant 的批量写入回调main/app_driver.cLED 硬件驱动RGB / WS2812 两种后端、HSV 换算、BOOT 按钮逻辑main/Kconfig.projbuild示例级配置菜单节点名、LED 类型、GPIO 等此外还有 sdkconfig.defaults默认安全版本与 WiFi 凭据和 partitions_4mb_optimised.csv4MB 优化分区表。启动流程从 app_main.c 可以清晰看到完整的初始化顺序nvs_flash_init()初始化 NVS失败且报ESP_ERR_NVS_NO_FREE_PAGES或ESP_ERR_NVS_NEW_VERSION_FOUND时先擦除再初始化——PoP 码与持久化参数都依赖它app_driver_init()初始化 LED 和按钮硬件esp_weaver_node_init()以ESP_WEAVER_CONFIG_DEFAULT()配置创建 Weaver 节点单例整个进程仅支持一个节点节点名/类型来自CONFIG_EXAMPLE_NODE_NAME/CONFIG_EXAMPLE_NODE_TYPEapp_led_light_init()创建灯泡设备并加入节点esp_netif_init()esp_event_loop_create_default()example_connect()建立 TCP/IP 栈、事件循环并连接 WiFiesp_weaver_local_ctrl_start()启动本地控制HTTP 服务 mDNS 广播成功后通过esp_weaver_local_ctrl_set_txt(device_name, ...)把设备显示名写入 mDNS TXT 记录供发现使用。值得注意的是示例把创建节点/设备放在连接 WiFi之前说明设备模型与网络状态解耦——先定义设备是什么再接入网络最后才对外提供服务。编译、配置与烧录设置芯片目标编译前务必先用idf.py set-target指定目标芯片idf.py set-target esp32s3 # 按实际开发板替换如 esp32c6 / esp32c3 / esp32c2 等配置项目idf.py menuconfigExample Connection Configuration菜单来自 IDF 自带的 example_connect 组件设置 Wi-Fi SSID设置 Wi-Fi 密码。也可以在 sdkconfig.defaults 中直接修改CONFIG_EXAMPLE_WIFI_SSID/CONFIG_EXAMPLE_WIFI_PASSWORD后重新构建但注意 sdkconfig.defaults 中的值是构建默认值已生成的 sdkconfig 需清理后才会重新生效。ESP Weaver菜单可选设置安全版本SEC0无安全性仅开发/测试或 SEC1带 PoP 认证与加密。默认即 SEC1由 sdkconfig.defaults 中的CONFIG_ESP_WEAVER_LOCAL_CTRL_SECURITY_VERSION1指定实现位于 components/esp_weaver/Kconfig。Example Configuration菜单示例自定义配置定义见 Kconfig.projbuild配置项默认值说明EXAMPLE_NODE_NAMEESP Weaver DeviceWeaver 节点名称用于设备标识EXAMPLE_NODE_TYPELightbulb节点类型Lightbulb / Sensor / Switch 等EXAMPLE_DEVICE_NAMELight通过 mDNS TXT 记录广播的设备显示名EXAMPLE_BOARD_BUTTON_GPIO随芯片变化BOOT 按钮 GPIOESP32-C5 为 28C2/C3/C6/C61 为 9其余为 0LED_TYPEchoiceESP32/C2 默认 RGB其余默认 WS2812选择RGB LED、WS2812 LED Strip或No LED无硬件联调用RGB_LED_RED/GREEN/BLUE_GPIOESP32 为 25/26/27三引脚 RGB 各通道 GPIORGB_LED_ACTIVE_LEVEL_HIGHESP32 默认 y其余 ny 表示共阴极高电平点亮n 表示共阳极低电平点亮WS2812_LED_GPIO随芯片变化WS2812 数据脚S3 为 38C2/C3/C6/C61 为 8C5 为 27其余为 18WS2812_LED_COUNT1范围 1–256WS2812 灯条上的 LED 数量这些默认值均与乐鑫官方 DevKit 的板载硬件一一对应例如 ESP32-S3-DevKitC-1 的板载 WS2812 接在 GPIO38。编译与烧录idf.py -p PORT flash monitor退出串口监视器请输入Ctrl-]。关于 ESP-IDF 的完整环境配置与使用步骤可参考仓库内 docs/en/gettingstarted.rst中文见 docs/zh_CN/gettingstarted.rst。烧录后示例依赖自定义分区表CONFIG_PARTITION_TABLE_CUSTOM见 sdkconfig.defaults其中 nvs 分区大小为 0x6000用于存放 PoP 与持久化参数。设备模型与参数定义源码级解析理解这个示例的关键是 Weaver 的Node → Device → Param三级模型。app_light_device_create()app_light.c完整展示了智能灯的参数建模方式esp_weaver_device_t *app_light_device_create(bool default_power, int default_brightness, int default_hue, int default_saturation) { s_light_device esp_weaver_device_create(Light, ESP_WEAVER_DEVICE_LIGHTBULB, NULL); ... /* 名称参数只读文本 */ p esp_weaver_param_create(ESP_WEAVER_DEF_NAME_PARAM, ESP_WEAVER_PARAM_NAME, esp_weaver_str(Light), PROP_FLAG_READ); esp_weaver_param_add_ui_type(p, ESP_WEAVER_UI_TEXT); /* 电源参数可读写 持久化且被指定为主参数 */ p esp_weaver_param_create(ESP_WEAVER_DEF_POWER_NAME, ESP_WEAVER_PARAM_POWER, esp_weaver_bool(default_power), PROP_FLAG_READ | PROP_FLAG_WRITE | PROP_FLAG_PERSIST); esp_weaver_param_add_ui_type(p, ESP_WEAVER_UI_TOGGLE); esp_weaver_device_assign_primary_param(s_light_device, p); /* 亮度参数0-100步进 1 */ p esp_weaver_param_create(ESP_WEAVER_DEF_BRIGHTNESS_NAME, ESP_WEAVER_PARAM_BRIGHTNESS, esp_weaver_int(default_brightness), PROP_FLAG_READ | PROP_FLAG_WRITE | PROP_FLAG_PERSIST); esp_weaver_param_add_ui_type(p, ESP_WEAVER_UI_SLIDER); esp_weaver_param_add_bounds(p, esp_weaver_int(0), esp_weaver_int(100), esp_weaver_int(1)); /* 色相0-360饱和度0-100 */ p esp_weaver_param_create(ESP_WEAVER_DEF_HUE_NAME, ESP_WEAVER_PARAM_HUE, ...); esp_weaver_param_add_ui_type(p, ESP_WEAVER_UI_HUE_SLIDER); esp_weaver_param_add_bounds(p, esp_weaver_int(0), esp_weaver_int(360), esp_weaver_int(1)); p esp_weaver_param_create(ESP_WEAVER_DEF_SATURATION_NAME, ESP_WEAVER_PARAM_SATURATION, ...); esp_weaver_param_add_ui_type(p, ESP_WEAVER_UI_SLIDER); esp_weaver_param_add_bounds(p, esp_weaver_int(0), esp_weaver_int(100), esp_weaver_int(1)); ... }几个关键设计点属性标志位PROP_FLAG_READ可读、PROP_FLAG_WRITE可写、PROP_FLAG_PERSIST持久化到 NVS重启后恢复上次状态。亮度、色相、饱和度、电源均带 PERSISTUI 类型ESP_WEAVER_UI_TOGGLE开关、ESP_WEAVER_UI_SLIDER滑块、ESP_WEAVER_UI_HUE_SLIDER色相滑块、ESP_WEAVER_UI_TEXT文本Home Assistant 会据此渲染实体控件主参数primary param电源被esp_weaver_device_assign_primary_param()指定为主参数对应 Home Assistant 中设备的核心开关标准参数名ESP_WEAVER_DEF_POWER_NAME等宏定义在 components/esp_weaver/include/esp_weaver_standard_params.hPower、Brightness、Hue、Saturation、CCT、Name等参数类型宏ESP_WEAVER_PARAM_POWER等与 UI 类型宏ESP_WEAVER_UI_*定义在 components/esp_weaver/include/esp_weaver_standard_types.h。写入回调一条命令如何变成灯光变化设备通过esp_weaver_device_add_bulk_cb()注册批量写入回调bulk_write_cbapp_light.c。Home Assistant 下发控制指令时可能一次携带多个参数回调中按参数名分发if (strcmp(param_name, ESP_WEAVER_DEF_POWER_NAME) 0) { app_light_set_power(val.val.b); } else if (strcmp(param_name, ESP_WEAVER_DEF_BRIGHTNESS_NAME) 0) { app_light_set_brightness(val.val.i); } else if (strcmp(param_name, ESP_WEAVER_DEF_HUE_NAME) 0) { app_light_set_hue(val.val.i); } else if (strcmp(param_name, ESP_WEAVER_DEF_SATURATION_NAME) 0) { app_light_set_saturation(val.val.i); } ... esp_weaver_param_update(param, val);每处理一个参数就调用esp_weaver_param_update()同步本地模型值未知参数会打Unknown parameter警告并跳过。这样协议层解析 → 应用层回调 → 硬件驱动三层就串起来了。LED 驱动与 HSV 换算app_driver.capp_driver.c负责把抽象参数落到真实硬件支持三种后端由 Kconfig 的LED_TYPE选择RGB 三引脚 LED基于led_indicator_new_rgb_device()三个通道各占一个 LEDC PWM 通道LEDC_CHANNEL_0/1/2、LEDC_TIMER_0并通过RGB_LED_ACTIVE_LEVEL_HIGH适配共阳/共阴接法WS2812 灯条基于led_indicator_new_strips_device()底层按芯片能力自动选择驱动后端——支持 RMT 的芯片用LED_STRIP_RMT10 MHz 时钟不支持 RMT 的芯片如 ESP32-C2、ESP32-C61自动退化为 SPI 后端LED_STRIP_SPISPI2_HOST 总线这是示例能在全系芯片上运行的硬件兼容性关键无 LEDCONFIG_LED_TYPE_NONE时drive_led()直接返回ESP_OK方便在没有 LED 硬件时先行联调协议。HSV 值域换算Weaver 参数层使用色相 0–360、饱和度 0–100、亮度 0–100的业务值域而led_indicator使用色相 0–359、饱和度 0–255、亮度 0–255的驱动值域两者在set_led_hsv()app_driver.c中完成换算uint16_t hue_359 hue % 360; /* 360° → 359 */ uint16_t sat_255 (saturation * 255) / 100; /* 百分比 → 0-255 */ uint16_t val_255 (brightness * 255) / 100; return led_indicator_set_hsv(g_led_indicator, SET_IHSV(MAX_INDEX, hue_359, sat_255, val_255));关灯则直接把亮度置 0led_indicator_set_brightness(g_led_indicator, 0)避免切换时产生错误的颜色残留。BOOT 按钮本地实体控制app_driver_init()app_driver.c基于 iot_button 组件iot_button_new_gpio_device()BUTTON_SINGLE_CLICK回调注册按钮。单按 BOOT 按钮会翻转电源状态并通过esp_weaver_param_update_and_report()主动把新状态推送给已连接的 Home Assistant 客户端——这是本地按键 → 云端实体状态同步的完整闭环也是update与update_and_report两个 API 的典型使用区别。获取 PoP 码并接入 Home AssistantPoP拥有证明机制设备首次启动时串口会输出类似日志I (10592) esp_weaver_local_ctrl: No PoP in NVS. Generating a new one. I (10592) esp_weaver_local_ctrl: PoP for local control: 8f820513PoP 是 SEC1 安全模式下的设备认证凭证首次启动自动随机生成并持久化到 NVS后续重启日志变为PoP read from NVS值保持不变也可以在启动本地控制前调用esp_weaver_local_ctrl_set_pop()手动指定。SEC1 协议基于 Curve25519 密钥交换与 AES-CTR 加密实现见 components/esp_weaver/src/esp_weaver_local_ctrl.c配对时输入 PoP 即可在局域网内建立端到端加密通道。添加设备到 Home Assistant在 Home Assistant 中安装 ESP-Weaver 集成仓库根目录 README.md 有项目总览ESP-Weaver 是乐鑫提供的对应自定义集成设备连接 WiFi 后会通过 mDNS 自动广播服务默认 HTTP 端口 8080Home Assistant 自动发现设备输入设备串口日志中的 PoP 码完成配对设备实体电源、亮度、颜色出现在 Home Assistant 中即可开始控制。示例输出解读启动日志程序正常启动后串口输出如下地址为示例环境实际以你的路由器分配为准I (10502) esp_netif_handlers: example_netif_sta ip: 192.168.30.11, mask: 255.255.255.0, gw: 192.168.30.1 I (10502) example_connect: Got IPv4 event: Interface example_netif_sta address: 192.168.30.11 I (10532) example_connect: Got IPv6 event: Interface example_netif_sta address: fe80:0000:0000:0000:6255:f9ff:fef9:19ec, type: ESP_IP6_ADDR_IS_LINK_LOCAL I (10532) example_common: Connected to example_netif_sta I (10532) example_common: - IPv4 address: 192.168.30.11, I (10542) example_common: - IPv6 address: fe80:0000:0000:0000:6255:f9ff:fef9:19ec, type: ESP_IP6_ADDR_IS_LINK_LOCAL I (10552) esp_weaver: Weaver initialized: ESP Weaver Device (Lightbulb), node_id: 6055F9F919EC I (10562) app_main: Node ID: 6055F9F919EC I (10562) esp_weaver: Device created: Light (esp.device.lightbulb) I (10572) esp_weaver: Device added to node: Light I (10572) esp_weaver_local_ctrl: Starting local control with HTTP transport and security version: 1 I (10582) mdns_mem: mDNS task will be created from internal RAM I (10592) esp_weaver_local_ctrl: No PoP in NVS. Generating a new one. I (10592) esp_weaver_local_ctrl: PoP for local control: 8f820513 I (10602) esp_weaver_local_ctrl: Local control started on port 8080, node_id: 6055F9F919EC I (10612) app_main: Local control started successfully日志关键点Node ID默认由 MAC 地址自动生成如6055F9F919EC也可通过esp_weaver_config_t.node_id字段自定义PoPSEC1 模式下首次启动生成并持久化后续重启读 NVS也可用esp_weaver_local_ctrl_set_pop()在启动前手动设置安全模式security version: 1表示当前运行在 SEC1可通过idf.py menuconfig→ ESP Weaver 切换 SEC0/SEC1端口本地控制 HTTP 服务默认端口 8080同样在 ESP Weaver 菜单中可改。控制日志通过 Home Assistant或任何本地控制客户端控制灯时设备端输出I (37132) app_light: Light received 1 params in write I (37132) app_light: Light.Power false I (38062) app_light: Light received 1 params in write I (38062) app_light: Light.Power true I (40532) app_light: Light received 1 params in write I (40532) app_light: Light.Brightness 63 I (42272) app_light: Light received 1 params in write I (42272) app_light: Light.Hue 141 I (42342) app_light: Light received 1 params in write I (42342) app_light: Light.Saturation 38这组日志对应 Home Assistant 依次执行的开灯、关灯、调亮度、调色相、调饱和度操作每条都印证了批量写入回调bulk_write_cb的参数分发逻辑。故障排除WiFi 连接失败检查menuconfig中的 WiFi 凭据Example Connection Configuration确保设备在 WiFi 覆盖范围内设备未被发现确认 Home Assistant 与 ESP 设备在同一局域网且已安装 ESP-Weaver 集成可进一步检查设备端日志中Local control started on port 8080是否出现确认 mDNS 广播已启动PoP 码被拒绝核对输入值与串口日志中显示的 PoP 是否完全一致注意区分大小写与易混淆字符Home Assistant 中实体不更新若通过本地按钮开关灯确认控制日志中Light.Power ...正常输出检查esp_weaver_param_update_and_report()是否正确触发对应 app_driver.c 的按钮回调逻辑。从示例到你自己的设备led_light是理解 ESP Weaver 的最佳起点也是后续开发其他智能设备的模板。想把它改造成自己的产品只需在 app_light.c 的app_light_device_create()中增删参数比如增加色温参数可用ESP_WEAVER_DEF_CCT_NAME/ESP_WEAVER_PARAM_CCT在bulk_write_cb中对接自己的执行器。设备类型、参数类型、UI 类型与值辅助宏esp_weaver_bool/esp_weaver_int/esp_weaver_str等的完整清单见 components/esp_weaver/README_CN.md组件的测试套件位于 components/esp_weaver/test_apps覆盖初始化、设备/参数 API 与完整集成流程可作为 API 行为验证的参考。仓库中另一个相关示例 examples/weaver/imu_gesture 展示了手势传感器类设备如何以相同模型接入。需要说明的是ESP Weaver 不是 ESP RainMaker 的直接替代品它移除了一切云端能力MQTT、OTA、定时任务、场景等API 命名空间为esp_weaver_*专注于通过 esp_local_ctrl mDNS 实现纯局域网的 Home Assistant 本地发现与控制——这也正是本示例无云、离线可用、毫秒级响应特性背后的设计取舍。【免费下载链接】esp-iot-solutionEspressif IoT Library. IoT Device Drivers, Documentations and Solutions.项目地址: https://gitcode.com/GitHub_Trending/es/esp-iot-solution创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考