Appearance
蓝牙配网
蓝牙配网简化 2.0 是一套面向通用 BLE 设备的 WiFi 配网协议。设备通过 BLE 广播进入待配网状态,App 或小程序搜索设备后,连接设备并下发 WiFi 信息,设备连接成功后通过 BLE 返回结果。
适用场景
- 实现简单:只需要 BLE GATT 的
WRITE和NOTIFY - 兼容性好:适合 ESP32 等常见 BLE 芯片
- 用户体验清晰:先搜索设备,再填写 WiFi 信息
基础流程
用户流程
- 设备进入待配网模式并开始蓝牙广播
- App 或小程序搜索附近设备
- 用户选择设备
- App 或小程序连接设备并发送 WiFi 信息
- 设备连接 WiFi
- 设备通过 BLE 返回成功或失败状态
通信流程
text
App/小程序 设备
| |
| 扫描 BLE 广播 |
| 过滤指定 Service UUID |
| |
|--------- 连接设备 ------------->|
|--------- hello --------------->|
|<-------- hello ----------------|
|--------- wifi ---------------->|
|<-------- wifi -----------------|
|<-------- status ---------------|
|<-------- status ---------------|
|--------- finish -------------->|
|<-------- finish ---------------|BLE GATT 定义
设备需要实现 1 个 Service 和 2 个 Characteristic:
text
Service UUID: BEFA2000-BE35-4A5A-9C4A-BE0E02000000
RX Characteristic UUID: BEFA2001-BE35-4A5A-9C4A-BE0E02000000
属性: WRITE
方向: App -> Device
TX Characteristic UUID: BEFA2002-BE35-4A5A-9C4A-BE0E02000000
属性: NOTIFY
方向: Device -> App说明:
Service UUID用于 App 或小程序扫描过滤设备RX用于接收 App 下发的 JSON 命令TX用于设备通知响应和状态- 所有设备类型共用这一套 UUID,不通过不同 UUID 区分设备类型
广播要求
广播名称
推荐设备广播名称:
text
Bemfa_<短码>示例:
text
Bemfa_A3F2B2广播服务
设备广播中应携带完整 128-bit Service UUID:
text
BEFA2000-BE35-4A5A-9C4A-BE0E02000000App 或小程序扫描时,应优先通过该 Service UUID 过滤待配网设备。
Manufacturer Data
推荐广播中携带以下 Manufacturer Data:
| 字段 | 类型 | 说明 |
|---|---|---|
| company_id | uint16 | 固定 0xBEFA,小端序 |
| proto_major | uint8 | 协议主版本,固定 0x02 |
| proto_minor | uint8 | 协议次版本,固定 0x00 |
| device_type | uint8 | 设备类型 |
| setup_state | uint8 | 0=已配网,1=待配网,2=维护配网 |
| capability | uint8 | 能力位 |
| short_code | uint16 | 设备短码,小端序 |
字节示例:
text
FA BE 02 00 02 01 11 F2 A3字段说明:
FA BE表示company_id = 0xBEFA02 00表示协议版本2.002表示设备类型为灯01表示当前设备处于待配网状态11表示能力位F2 A3表示短码0xA3F2
设备类型对照表:
| 后三位 | 广播值 | 说明 |
|---|---|---|
| 001 | 0x01 | 插座 |
| 002 | 0x02 | 灯 |
| 003 | 0x03 | 风扇 |
| 004 | 0x04 | 传感器 |
| 005 | 0x05 | 空调 |
| 006 | 0x06 | 开关 |
| 009 | 0x09 | 窗帘 |
| 010 | 0x0A | 温控器 |
| 011 | 0x0B | 热水器 |
| 012 | 0x0C | 电视 |
| 013 | 0x0D | 空气净化器 |
推荐能力位:
| bit | 含义 |
|---|---|
| 0 | 支持基础 WiFi 配网 |
| 1 | 支持云端配置 |
| 4 | 支持隐藏 WiFi |
JSON 消息格式
所有消息使用 UTF-8 编码的 JSON 字符串,通过 BLE Characteristic 读写。
请求示例:
json
{
"cmd": "hello",
"seq": 1
}响应示例:
json
{
"cmd": "hello",
"seq": 1,
"code": 0
}通用字段:
| 字段 | 必填 | 说明 |
|---|---|---|
| cmd | 是 | 命令名称 |
| seq | 是 | 请求序号 |
| code | 响应必填 | 0 成功,非 0 失败 |
说明:
- JSON 字段名使用小写字母和下划线
- 不发送
null - 不要在日志中输出 WiFi 密码或用户 token
- 设备发送多条 JSON 指令时,建议每条消息之间至少间隔
200ms
JSON 发送节奏建议
为了保证 App 和小程序都能稳定接收并处理 BLE 通知,设备侧不要连续无间隔发送多条 JSON 消息。
建议:
- 每条 JSON 指令或状态通知之间,至少间隔
200ms - 特别是在连续上报
status、再发送finish时,不要紧挨着连续发送 - 如果设备状态变化很快,也建议按
200ms的最小间隔顺序上报
这样可以避免手机端因为消息过于密集,出现丢包、状态显示不完整或处理不及时的问题。
基础命令
1. hello
App -> Device:
json
{
"cmd": "hello",
"seq": 1,
"ver": 2,
"app": "behome",
"mtu": 185
}Device -> App:
json
{
"cmd": "hello",
"seq": 1,
"code": 0,
"ver": 2,
"device_id": "BH_A1B2C3",
"device_type": 2,
"name": "BeHome Switch",
"cap": ["wifi", "cloud"]
}字段说明:
| 字段 | 说明 |
|---|---|
| ver | 协议版本,固定为 2 |
| app | App 标识 |
| mtu | 当前可用 MTU |
| device_id | 设备唯一 ID |
| device_type | 设备类型 |
| name | 设备显示名称 |
| cap | 设备能力列表 |
2. wifi
App -> Device:
json
{
"cmd": "wifi",
"seq": 3,
"ssid": "Home-WiFi",
"password": "12345678",
"security": "auto",
"token": "xxxxxxxxxxxxx"
}字段说明:
| 字段 | 必填 | 说明 |
|---|---|---|
| ssid | 是 | 路由器名称 |
| password | 否 | WiFi 密码,开放网络可为空 |
| security | 否 | 推荐固定为 auto |
| bssid | 否 | 路由器 BSSID |
| token | 是 | 巴法云用户私钥 |
Device -> App:
json
{
"cmd": "wifi",
"seq": 3,
"code": 0,
"accepted": true
}设备收到 wifi 后,应开始连接 WiFi,并继续通过 status 上报进度。
3. status
Device -> App:
json
{
"cmd": "status",
"seq": 4,
"code": 0,
"stage": "wifi_connecting",
"progress": 40
}WiFi 连接成功:
json
{
"cmd": "status",
"seq": 5,
"code": 0,
"stage": "wifi_connected",
"progress": 100,
"ip": "192.168.1.100",
"rssi": -45
}WiFi 连接失败:
json
{
"cmd": "status",
"seq": 5,
"code": 1001,
"stage": "wifi_failed",
"reason": "wrong_password",
"retryable": true
}stage 取值:
| stage | 说明 |
|---|---|
| received | 已收到配置 |
| wifi_connecting | 正在连接 WiFi |
| wifi_connected | WiFi 已连接 |
| wifi_failed | WiFi 连接失败 |
| cloud_connecting | 正在连接云端 |
| cloud_failed | 云端连接失败 |
| done | 配网完成 |
4. finish
App -> Device:
json
{
"cmd": "finish",
"seq": 7
}Device -> App:
json
{
"cmd": "finish",
"seq": 7,
"code": 0,
"stage": "done"
}设备收到 finish 后,应关闭配网广播,并在短时间后断开 BLE。
推荐状态机
设备推荐按以下状态处理命令:
| 状态 | 说明 |
|---|---|
| idle | 等待配网 |
| connected | BLE 已连接 |
| ready | hello 已完成 |
| wifi_received | 已收到 WiFi |
| wifi_connecting | 正在连接 WiFi |
| wifi_connected | WiFi 已连接 |
| done | 配网完成 |
| failed | 配网失败 |
命令约束:
| 状态 | 允许命令 |
|---|---|
| connected | hello |
| ready | wifi, finish |
| wifi_connected | finish |
| failed | wifi, finish |
如果状态不合法,设备返回:
json
{
"cmd": "error",
"seq": 0,
"code": 3001,
"reason": "invalid_state"
}错误码
| 错误码 | reason | 说明 |
|---|---|---|
| 0 | ok | 成功 |
| 1001 | wrong_password | WiFi 密码错误 |
| 1002 | wifi_not_found | 找不到 WiFi |
| 1003 | wifi_timeout | WiFi 连接超时 |
| 1005 | unsupported_wifi | 不支持该 WiFi 类型或频段 |
| 2001 | cloud_failed | 云端连接失败 |
| 3001 | invalid_state | 当前状态不允许该命令 |
| 3002 | invalid_json | JSON 格式错误 |
| 3003 | unsupported_cmd | 不支持的命令 |
| 3004 | payload_too_large | 消息太大 |
| 9001 | internal_error | 设备内部错误 |
超时建议
| 阶段 | 建议超时 | 处理方式 |
|---|---|---|
| 扫描设备 | 10 秒 | 提示用户靠近设备或重置设备 |
| BLE 连接 | 10 秒 | 可重试 |
| hello | 5 秒 | 重新连接 |
| wifi 写入 | 5 秒 | 重试写入 |
| WiFi 连接 | 45 秒 | 提示失败,允许重新输入密码 |
设备实现要求
设备至少需要实现以下能力:
- BLE 广播
- GATT Server
- RX
WRITE - TX
NOTIFY - JSON 解析
- WiFi 连接
- 状态上报
配网模式建议
- 首次上电未配置 WiFi 时进入配网模式
- 用户长按按键可重新进入配网模式
- 配网成功后关闭广播
- 建议配网模式超时时间为 180 秒
持久化建议
设备建议保存以下信息:
- WiFi SSID
- WiFi 密码
- 配网完成标志
示例程序
下面给出一组适合 ESP32 Arduino 快速接入的参考工程。建议先跑通最小功能版本,再叠加 TCP、MQTT 或业务逻辑,避免一开始就把问题混在一起排查。
配网工具
- 巴法 App:点击下载
- 微信小程序:微信内搜索
一键配网
示例工程选择建议
1. 最小 BLE 配网示例
适合首次接入、验证 BLE 广播、GATT 通信和 WiFi 下发流程。
推荐优先使用 blu_NimBLE.zip,原因如下:
- 协议实现更轻量
- 更适合实际项目继续扩展
- 更容易和后续业务逻辑一起维护
blu.zip 可以作为兼容性参考,但编译产物通常更大。如果后续还要加入按键、联网、传感器或其他功能,可能会更快碰到 ESP32 的程序空间限制。
如果编译后空间不足,可在 Arduino IDE 中调整分区方案:
text
Tools -> Partition Scheme -> Minimal SPIFFS或:
text
Tools -> Partition Scheme -> Huge APP2. BLE 配网 + TCP 示例
适合设备配网成功后,需要直接接入 TCP 通信的项目。
- 下载地址:点击下载
需要提前安装以下库:
ArduinoJsonAceButtonNimBLE-Arduino
在 Arduino IDE 中依次打开:
text
工具 -> 管理库然后分别搜索并安装以上库。
3. BLE 配网 + MQTT 示例
适合设备配网成功后,直接接入 MQTT 平台的项目。
- 下载地址:点击下载
如果你只是想先验证蓝牙配网流程,不建议一开始就使用 MQTT 版本。更稳妥的做法是:
- 先跑通最小 BLE 配网示例
- 确认手机端可以发现设备、连接设备并成功下发 WiFi
- 再切换到 TCP 或 MQTT 版本继续集成
接入建议
- 先确认广播名称、Service UUID、Characteristic UUID 与本文定义一致
- 先验证
hello、wifi、status、finish这 4 类消息的收发 - 设备侧日志中不要打印 WiFi 密码、token 等敏感信息
status和finish连续发送时,仍应保留至少200ms间隔- 配网成功后建议立即关闭 BLE 广播,避免被重复配网
如果你要基于示例工程做产品化开发,建议优先保留以下模块边界:
- BLE 协议收发
- WiFi 配网状态机
- 按键或重置逻辑
- 云端接入逻辑
这样后续替换通信协议或扩展设备功能时,改动会更小。