ESPHome 蓝牙网关实战:BLE 传感器到 MQTT 的完整配置与排障
【免费下载链接】esphomeESPHome is a system to control your ESP32, ESP8266, BK72xx, RP2040 by simple yet powerful configuration files and control them remotely through Home Automation systems.项目地址: https://gitcode.com/GitHub_Trending/es/esphome
清晨六点,厨房温湿度在 Home Assistant 里卡在昨天晚上的数值。Aqara 门窗传感器显示"未知",因为家里唯一连了蓝牙的笔记本正在关机充电。ESPHome 蓝牙网关就是为这个场景准备的:一块 ESP32 常驻家里,把 BLE(低功耗蓝牙)设备的数据持续转进 MQTT,不再依赖手机中转。
🎯 交付物清单
- 接入小米等广播型 BLE 温湿度传感器,数据经 ESPHome 网关进入 MQTT
- 用
ble_client主动连接 BLE 开关并控制,状态可订阅可回写 - 调整连接槽位与扫描参数,让 BLE 与 WiFi 共存不互相挤占
- 按故障速查表在 3 分钟内定位"设备离线"类问题
✅ 前置条件
| 项目 | 要求 | 备注 |
|---|---|---|
| 主控芯片 | ESP32(带 BLE,如 esp32dev、ESP32-C3) | ESP8266 无 BLE,不可用 |
| 编译环境 | Python +pip install esphome | 或直接用 Home Assistant 的 ESPHome 集成 |
| 消息通道 | 局域网 MQTT broker | 网关固件本身不直连 broker,发布由 HA 完成 |
| WiFi | 2.4 GHz,信号 -65 dBm 以上 | BLE 与 WiFi 共用射频,信号弱会互相影响 |
| 目标设备 | 已确认 MAC 地址的 BLE 设备 | 加密设备(小米系)还需 bindkey(解密密钥) |
pip install esphome esphome version📡 原理速览
网关固件只做两件事:扫描、连接。桥接层(源码 bluetooth_proxy)把广播包按批打包,经 ESPHome API 推给 Home Assistant;由 HA 把数据发布到 MQTT,控制指令原路返回。
🛠 分场景实施
场景一:接入第一个广播型传感器
这类设备周期性广播温度、湿度、电量,网关不需要连接它,监听即可。
esp32: board: esp32dev bluetooth_proxy: active: true connection_slots: 3 # 给后续主动连接预留 esp32_ble_tracker: scan_parameters: interval: 320ms window: 320ms sensor: - platform: xiaomi_lywsd02mmc mac_address: "A4:C1:38:XX:XX:XX" bindkey: "0123456789abcdef" # 小米设备解密密钥,从米家 App 获取 temperature: name: "厨房温度" humidity: name: "厨房湿度" battery_level: name: "传感器电量"验证:刷写固件 → Home Assistant 的 ESPHome 集成里确认网关在线 → 传感器实体出现数值 → 拿设备贴近网关再远移 5 米,观察更新间隔变化。数据没变化先看 bindkey 对不对。
场景二:主动连接并控制一个 BLE 设备
广播型设备只"读",开关、锁这类设备要"写"。用ble_client(组件 ble_client)建立 GATT 连接:每个客户端占一个连接槽位,auto_connect默认开启,断线自动重连。
ble_client: - mac_address: "00:1A:7D:DA:71:13" id: ble_switch on_disconnect: then: - lambda: "ESP_LOGW(\"ble\", \"disconnected, will retry\");" switch: - platform: ble_client name: "车库门磁" ble_client_id: ble_switch service_uuid: "0000ffe0-0000-1000-8000-00805f9b34fb" characteristic_uuid: "0000ffe1-0000-1000-8000-00805f9b34fb" value_on: [0x01] value_off: [0x00] on_notify: - switch.template: # 设备主动上报时同步状态验证:在 HA 切换开关 → 日志出现 connect、write 事件 → 再让设备端主动上报,看on_notify是否触发。
场景三:多设备并发与参数调优
ESP32 同时跑扫描、WiFi、多个 BLE 连接,所有客户端共享 9 个连接槽位(esp32_ble_tracker 的射频仲裁器负责分配)。槽位不够时,日志会提示设备在排队。
bluetooth_proxy: connection_slots: 3 # 代理占用 3 槽 + 3 个 ble_client 各 1 槽 = 6 ≤ 9 ble_client: - mac_address: "AA:BB:CC:DD:EE:01" id: client_a - mac_address: "AA:BB:CC:DD:EE:02" id: client_b - mac_address: "AA:BB:CC:DD:EE:03" id: client_c调参顺序:先保 WiFi,再谈 BLE。扫描窗口超过 600 ms 会长时间占用射频,导致 WiFi 掉包;默认 30 ms 窗口在较新 ESP-IDF 下利用率低,又容易漏广播。interval设为 320 ms 并让两个参数相等,交给软件共存仲裁器按 WiFi 空闲自动分配时隙。验证:多设备跑满 24 小时,日志无wifi: Disconnecting、无槽位告警。
⚙️ 参数速查表
| 参数 | 作用 | 推荐值 | 影响范围 |
|---|---|---|---|
active | 代理是否转发广播 | true | 全部 BLE 设备 |
connection_slots | 代理预留连接槽数,1~9 | 3 | 远端主动连接能力 |
cache_services | 服务信息落盘缓存,加快重连(ESP32 专属) | true | 重连时延 |
scan_parameters.interval | 扫描周期 | 320ms | 射频占用、漏包率 |
scan_parameters.window | 单次扫描时长 | ≤600ms,与 interval 相等 | WiFi 共存稳定性 |
ble_client.auto_connect | 断线自动重连 | true | 单个客户端 |
esp32_ble_tracker扫描 active | 主动/被动扫描 | 按设备类型 | 功耗、可发现性 |
🔧 故障速查
| 现象 | 原因 | 动作 |
|---|---|---|
| 传感器数据不更新 | bindkey 错、MAC 写错、信号弱 | 核对 bindkey 与 MAC,把设备贴近网关测试 |
| WiFi 间歇掉线 | 扫描窗口过长挤占射频 | window压到 600 ms 内,interval/window 都设 320 ms |
| 设备偶发连不上 | 9 个槽位被占满,连接排队 | 降低connection_slots或减少ble_client数量 |
| 网关在 HA 离线 | WiFi 断连或 API 超时 | 看日志中api/wifi段,重启网关,检查电源是否 5V/2A |
🚀 进阶清单
window压到 600 ms 内:保住 WiFi 不掉线- 保持
cache_services: true:BLE 重连从秒级降到亚秒级 - MQTT 侧启用 TLS:8883 端口 +
certificate_authority - OTA 加密码并开
safe_mode:防误刷、防劫持 - 日志分级:常态 INFO,排障时仅给
bluetooth_proxy、esp32_ble_tracker开 DEBUG - 大户型按楼层分区部署多台网关:BLE 广播半径有限,就近扫描最稳
收尾
本文覆盖 ESP32 网关上 BLE 转 MQTT 的完整链路:广播采集、主动读写、槽位调度、共存调参与故障排查。网关只负责 BLE 到 ESPHome API 这一段,MQTT 发布由 Home Assistant 完成。下一步:查仓库内bluetooth_proxy组件文档;遇 schema 校验报错,把完整编译输出贴到仓库 issue。
【免费下载链接】esphomeESPHome is a system to control your ESP32, ESP8266, BK72xx, RP2040 by simple yet powerful configuration files and control them remotely through Home Automation systems.项目地址: https://gitcode.com/GitHub_Trending/es/esphome
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考