@ray-js/wechat-bluetooth-sdk
v2.1.9
Published
微信小程序面向开发者封装的业务蓝牙包,目前支持 蓝牙 LE 、 蓝牙 LE + Beacon 、Tuya Beacon 设备的本地连接控制,及蓝牙通道入网
Downloads
5
Readme
本文介绍了涂鸦 IoT 微信小程序蓝牙 SDK,该 SDK 提供了一些蓝牙功能的封装,方便小程序开发者更加快速地连接涂鸦生态中的智能硬件产品。您可以基于该 SDK 快速地实现小程序蓝牙交互功能的开发,实现对智能蓝牙设备的连接、控制、固件升级等操作。
蓝牙 SDK
该 SDK 根据涂鸦蓝牙协议提供高度封装的 API,方便小程序开发者快速实现小程序蓝牙功能。
安装 SDK
使用 NPM 包管理器下载 SDK。
npm install @ray-js/wechat-bluetooth-sdk
使用示例
若您已安装小程序开发者工具,点此打开微信官方代码片段,即可查看完整示例,若按如下步骤操作,还可生成小程序二维码进行真机体验。
- 修改
project.config.json
文件中的appid
字段为您在涂鸦 IoT 平台授权过的小程序AppID
。 - 使用
npm install
命令安装 NPM 包。 - 在开发者工具中按如下路径构建 NPM 包:工具 > 构建 npm。
- SDK 完整使用示例在代码片段的目录
pages/home_center/common_panel/index.js
下。
若您未安装小程序开发者工具,也可参考以下示例代码:
import BleService from '@ray-js/wechat-bluetooth-sdk'
BleService.initParams({ access_token, uid });
// 小程序生命周期钩子
onLoad: async function () {
// 抽象的蓝牙设备实例
const instance = BleService.setNewInstance(device_id, home_id)
// 蓝牙连接
instance.connectBlue()
// 监听蓝牙通信
instance.onReceivePackage((parseReceiveData) => {
const { type, status, dpState, deviceId } = parseReceiveData
if (type === 'connect' && status === 'fail') {
if (deviceId) {
return { msg: '连接失败 或 连接后又断开' }
} else {
return { msg: '未发现当前蓝牙设备' }
}
} else if (type === 'connect' && status === 'connected') {
// 连接成功
wx.showToast({
title: '蓝牙连接成功',
icon: 'success',
duration: 2000
})
// 如果连接成功后需要下发 DP
instance.sendDp({ dpCode: 'code', dpValue: 123 })
} else if (!(deviceId in parseReceiveData) && dpState) {
// 一般为 DP 上报事件,可在此处处理数据 or 走业务逻辑
this.handleData(dpState)
}
})
},
handleData(dpState) {
// todo....
}
引入服务
import BleService from '@ray-js/wechat-bluetooth-sdk'
BleService
BleService
是一个实例对象,该实例维护了下文所提到的设备实例列表,以及创建设备实例、销毁设备实例等 API。
设置接口请求参数(initParams)
BleService.initParams({ access_token, uid });
参数说明
| 字段 | 数据类型 | 说明 | | ---- | :--- | :--- | | access_token | String | 登录凭证 | | uid | String | 用户 ID |
返回值:无
在蓝牙连接认证流程中,需要通过 云函数
接口拉取部分蓝牙连接所需要的数据(具体数据可点此查看蓝牙通信建立流程图的示意)。为方便开发者使用,SDK 已内部封装通信流程所涉及的接口请求,但由于 用户 ID
、access_token
为云函数接口鉴权必需参数,因此需要调用方传入该参数以便 SDK 顺利发起请求。用户 ID
、access_token
的获取请 点此查看。
创建蓝牙 LE 设备实例(setNewInstance)
const instance = BleService.setNewInstance(device_id, home_id)
参数说明
| 字段 | 数据类型 | 说明 | | ---- | ---- | ---- | | device_id | String | 蓝牙设备配网后生成的虚拟 ID | | home_id | Number | 蓝牙设备所在家庭 ID |
返回值:设备实例
通过调用该方法,将生成一个设备实例。每个蓝牙 LE 设备对应一个实例。该设备的连接状态等数据都将维护在该实例中。同时,设备连接、设备指令下发、OTA 升级等相关 API 也维护在该设备实例中。
涂鸦小程序家庭、设备相关云函数,请参考 全屋管理。
:::info 若当前设备 ID 对应的实例已经被创建过,则会销毁原有实例,并创建新的实例返回。 :::
获取已创建的蓝牙 LE 实例(BleService.instance)
const instance = BleService.instance[device_id]
if(!instance) reutrn false
参数说明
| 字段 | 数据类型 | 说明 | | ---- | ---- | ---- | | device_id | String | 蓝牙设备配网后生成的虚拟 ID |
返回值:设备实例
也可通过该方式获取已生成的设备实例。BleService.instance
为 BleService
维护的设备实例列表。
创建 Tuya Beacon 设备实例(creatBeacon)
const instance = BleService.creatBeacon(device_id, home_id)
参数说明
| 字段 | 数据类型 | 说明 | | ---- | ---- | ---- | | device_id | String | 蓝牙设备配网后生成的虚拟 ID | | home_id | Number | 蓝牙设备所在家庭 ID |
返回值:设备实例
通过调用该方法,将生成一个 Tuya Beacon 设备实例,该实例具有的能力与蓝牙 LE 设备实例大同小异。但由两种通信协议间的差异所致,两种设备实例的 API
,其调用产生的内部逻辑稍有不同。
:::info 若当前设备 ID 对应的实例已经被创建过,则重复调用只会返回旧实例。 :::
获取已创建的 Tuya Beacon 实例(BleService.beaconInstance)
const instance = BleService.beaconInstance[device_id]
if(!instance) reutrn false
参数说明
| 字段 | 数据类型 | 说明 | | ---- | ---- | ---- | | device_id | String | 蓝牙设备配网后生成的虚拟 ID |
返回值:设备实例
也可通过该方式获取已生成的设备实例。BleService.beaconInstance
为 BleService
维护的 Tuya Beacon 设备实例列表。
销毁设备实例(destroyInstance)
BleService.destroyInstance(device_id)
参数说明
| 字段 | 数据类型 | 说明 | | ---- | ---- | ---- | | device_id | String | 蓝牙设备配网后生成的虚拟 ID |
返回值:无
设备实例
蓝牙连接(connectBlue)
const res = await instance.connectBlue()
返回值:
Promise
该方法为异步函数,设备连接结果需要等待 Promise 对象处理完成。
Promise 对象处理结果
| 字段 | 数据类型 | 说明 | | ---- | ---- | ---- | | success | Boolean | 蓝牙是否成功连接 | | errMsg | String | 蓝牙连接失败时的错误信息 |
差异化说明
| 设备通信类型 | 说明 | | ---- | ---- | | 蓝牙 LE | 调用该
API
会发起本地蓝牙连接。蓝牙连接过程中的连接状态变化,会通过下文提到的回调事件进行回调,建议监听该事件回调,以便监控连接过程。 | | Tuya Beacon | 由于 Tuya Beacon 并无连接特性,因此调用该API
仅是对设备发出一个ping
请求,若设备在超时时间内(目前默认为 60s 超时,暂不支持修改)回复了心跳,则会回调 'success: true'。 |
主动断开设备连接(connectionBreak)
instance.connectionBreak()
返回值:
Promise
该方法为异步函数,执行结果需要等待 Promise 对象处理完成。
Promise 对象处理结果
| 字段 | 数据类型 | 说明 | | ---- | ---- | ---- | | success | Boolean | 蓝牙是否成功断开连接 | | errMsg | String | 蓝牙断开连接失败时的错误信息 |
差异化说明
| 设备通信类型 | 说明 | | ---- | ---- | | 蓝牙 LE | 调用该
API
会断开本地蓝牙连接。后续可通过connectBlue
重新发起连接。 | | Tuya Beacon | 由于 Tuya Beacon 并无连接特性,因此调用该API
会固定回调一个设备离线消息,并屏蔽后续所有设备状态上报。若想重新收取设备消息,可调用connectBlue
恢复。 |
发送 DP(sendDp)
// 发送标准 DP
const res = instance.sendDp({ dpCode, dpValue })
// 发送自定义 DP( v1.0.4 以上 )
const res = instance.sendDp({ dpId, dpType, dpValue })
参数说明
| 字段 | 数据类型 | 说明 | | ---- | ---- | ---- | | dpValue | any | 要下发的数据 | | dpCode | string | dpcode,发送标准 DP 时,传入 dpCode 与 dpValue 即可 | | dpId | number | dpid,发送自定义 dp(
v1.0.4
以上 )时,必传此项 | | dpType | string | dpValue 所对应的数据类型,发送自定义 dp(v1.0.4
以上 )时,必传此项 |参数举例
// 发送标准 dp,假设 DP 为: dpcode: 'welcome_words', dpType: 'string', dpId: 18 instance.sendDp({ dpCode: 'welcome_words', dpValue: 'hello world' }) // 发送自定义 dp,假设 DP 为:dpcode: 'switch_1', dpType: 'boolean', dpid: 101 instance.sendDp({ dpId: 101, dpType: 'Boolean', dpValue: true })
返回值:
Promise
Promise 对象处理结果
| 字段 | 数据类型 | 说明 | | ---- | ---- | ---- | | success | Boolean | 数据下发是否成功 | | errMsg | String | 蓝牙数据下发失败时的错误信息 |
:::info 处理结果为
true
仅代表数据单方面下发成功,不代表蓝牙设备正确接收到了数据并校验成功,因此,在遇到数据下发成功但设备无反应时,请先自查所下发数据是否有效。 :::
注册蓝牙回调事件(onReceivePackage)
instance.onReceivePackage(parseReceiveData => {
const { type, status, dpState, deviceId } = parseReceiveData;
if (type === 'connect' && status === 'fail') {
// 连接失败 或 连接后又断开
} else if (type === 'connect' && status === 'connected') {
// 连接成功
wx.showToast({
title: '蓝牙连接成功',
icon: 'success',
duration: 2000
})
} else if (!(deviceId in parseReceiveData)) {
// 一般为 DP 上报事件,可在此处处理数据 or 走业务逻辑
// 上报的数据会被处理成 dpState 对象,dpState 对象下面有举例
// todo...
}
});
回调参数说明
| 字段 | 数据类型 | 说明 | | ---- | ---- | ---- | | type | string | 状态类型: connect:连接状态 otaStatus:OTA 升级状态 send:发送状态 | | status | string | 状态值 | | deviceId | string | 蓝牙设备 ID,安卓下为 mac 地址 | | dpState | Object | 当前蓝牙设备的功能状态集 | | online | boolean | Tuya Beacon 设备是否在线 |
回调参数
status
数值说明| type | status 数值 | 说明 | | ---- | ---- | ---- | | connect | ready | SDK 准备进行蓝牙连接,进入此状态后,请勿再重复调用 connectBlue 进行连接,否则可能会导致连接失败 | | -- | connecting | 连接中 | | -- | connected | 蓝牙连接成功 | | -- | fail | 蓝牙连接失败 | | otaStatus | updating | OTA 中 | | -- | updated | OTA 成功 | | -- | fail | OTA 失败 | | -- | ready | 准备开始 OTA,此阶段将先进行设备状态校验(
v1.1.0
以上) | | -- | check | 向设备发送 OTA 请求,等待设备同意(v1.1.0
以上) | | send | sending | 数据发送中 | | -- | sended | 数据发送完毕 |回调参数 dpState 举例
dpState: { [dpcode1]: true, [dpcode2]: 100 }
取消监听蓝牙回调事件(offReceivePackage)
instance.offReceivePackage(cb);
参数说明
| 字段 | 数据类型 | 说明 | | ---- | ---- | ---- | | cb | Function | 注册监听时传入的回调函数 |
注册蓝牙错误事件(onError)
instance.onError(cb);
参数说明
| 字段 | 数据类型 | 说明 | | ---- | ---- | ---- | | cb | function | 回调函数 |
回调参数举例
{ errCode: 1000, errMsg: 'error' }
蓝牙交互时出现的异常情况都将在此处进行回调。
取消监听蓝牙回调事件(offError)
instance.offError(cb);
参数说明
| 字段 | 数据类型 | 说明 | | ---- | ---- | ---- | | cb | Function | 注册监听时传入的回调函数 |
获取设备本地状态(getBlueStatus)
instance.getBlueStatus()
返回值:
Promise
Promise 对象处理结果
| 字段 | 数据类型 | 说明 | | ---- | ---- | ---- | | success | Boolean | 设备本地状态查询请求下发是否成功 | | errMsg | String | 设备本地状态查询请求下发失败时的错误信息 |
差异化说明
| 设备通信类型 | 说明 | | ---- | ---- | | 蓝牙 LE | 正常可调用。 | | Tuya Beacon | Tuya Beacon 设备不支持使用该
API
。 |
建议在蓝牙连接成功之后,调用该 API 查询设备本地最新状态,如:设备电量信息等。
设备上报的最新状态也将会通过上文提到的 onReceivePackage
进行回调。
:::info 此 API 原理不能简单等同为“调接口拿数据”。
它只是向设备发出一个本地状态上报请求,设备收到这个请求之后,是否要上报本地状态,上报哪些本地状态,由设备决定。但无论上报哪些状态,最终这些数据都将由 SDK 的 onReceivePackage
进行回调。
:::
OTA 升级(sendOtaRequestOrder)
instance.sendOtaRequestOrder(url, version);
参数说明
| 字段 | 数据类型 | 说明 | | ----| ---- | ---- | | url | String | OTA 升级文件 URL 地址 | | version | String | OTA 升级文件版本号 |
OTA 升级过程复杂,涉及多个蓝牙指令下发,请务必通过 onReceivePackage
监听 OTA 升级过程的状态变化。
差异化说明
| 设备通信类型 | 说明 | | ---- | ---- | | 蓝牙 LE | 正常可调用。 | | Tuya Beacon | Tuya Beacon 设备暂不支持 OTA。 |
设备解绑(unboundBlue)
instance.unboundBlue(type);
参数说明
| 字段 | 数据类型 | 说明 | | ---- | ---- | ---- | | type | String | 共有两种解绑类型,分别对应不同的 type 数值: unbound(默认值):与设备正常解绑。 reset:设备重置,该类型除了解绑外,还会删除设备本地历史数据。 |
返回值:
Promise
Promise 对象处理结果
| 字段 | 数据类型 | 说明 | | ---- | ---- | ---- | | success | Boolean | 蓝牙解绑命令是否下发成功 | | errMsg | String | 蓝牙解绑失败时的错误信息 |
差异化说明
| 设备通信类型 | 说明 | | ---- | ---- | | 蓝牙 LE | 正常可调用。 | | Tuya Beacon | Tuya Beacon 设备场景下,该
API
无参数。 |
其他功能
Raw 类型数据加解密(encryptRawData、decryptRawData)
// 数据下发前,对 Raw 类型数据加密
BleService.encryptRawData(raw_data)
// 数据上报后,对回调数据进行解密
BleService.decryptRawData(value)
参数说明
| 字段 | 数据类型 | 说明 |
| ---- | ---- | ---- |
| raw_data | String | Raw 类型数据 |
| value | String | 通过 onReceivePackage
回调监听到的 Raw 类型数据 |
:::info Raw 表示透传类型数据。对某些设备来说,Raw 类型数据可能会包含密码等较为敏感的信息,在数据下发及上报云端时,应对其进行安全加密处理。因此,SDK 要求 Raw 类型数据应加密下发,同时 SDK 自身也会对设备上报的 Raw 类型数据进行加密后返回。 :::
错误码
| errCode | 说明 | | ---- | ---- | | 1001 | 蓝牙连接过程中,调用微信 API 失败 | | 1002 | 未授予地理位置权限(安卓特有) | | 1003 | 未搜索到蓝牙设备 | | 1004 | 设备信息获取失败 | | 1005 | 获取蓝牙 services 列表失败 | | 1006 | 获取 characteristics 列表失败 | | 1007 | write characteristic uuid 获取失败 | | 1008 | 当前设备具有 SDK 不支持的蓝牙特性 | | 1009 | 获取云端实时时间失败 | | 1010 | 蓝牙连接过程中,下发命令失败 | | 1011 | 云端随机数获取失败 | | 1012 | 初始化蓝牙适配器失败 | | 1013 | 未授予蓝牙权限 | | 1014 | 蓝牙 LE + Beacon 设备连接时,获取 BeaconKey 失败 | | 2001 | 蓝牙下发 DP 数据时,下发命令失败 | | 2003 | 蓝牙 DP 上报云端时,调用接口失败 | | 2004 | 设备解绑、重置时,下发命令失败 | | 2005 | 获取设备本地状态信息时,下发命令失败 | | 3001 | 发送 OTA 升级请求时,下发命令失败 | | 3002 | 蓝牙拒绝 OTA 升级 | | 3003 | 不支持 OTA 升级的蓝牙协议版本 | | 3004 | 不支持的 OTA 升级类型 | | 3005 | 发送 OTA 升级文件信息时,下发命令失败 | | 3006 | 发送 OTA 升级文件偏移请求时,下发命令失败 | | 3007 | 分包发送 OTA 升级数据包时,下发命令失败 | | 3008 | 发送 OTA 升级停止指令时,下发命令失败 | | 4001 | 从机服务创建失败,此失败会导致无法本地控制 Tuya Beacon 设备 | | 5001 | 配网扫描开启失败,原因:当前已有扫描进程 | | 5002 | 本次配网流程启动失败,原因:未设置homeId | | 5003 | 本次配网流程启动失败,原因:无设备成功进入配网队列 | | 5004 | 本次配网流程启动失败,原因:参数类型有误 | | 5005 | 配网失败:未设置wifi信息,双模设备无法配网 | | 5006 | 配网失败:配网密钥获取失败 | | 5007 | 配网失败:设备已被绑定,无法配网 | | 5008 | 配网失败:蓝牙认证失败 | | 5009 | 配网失败:设备数据返回有误 | | 5010 | 配网失败:不支持的协议版本 | | 5011 | 配网失败:设备云端注册失败 | | 5012 | 配网失败:设备云端激活失败 | | 5013 | 配网失败:蓝牙能力上报失败 | | 5014 | 配网失败:beaconKey获取失败 | | 5015 | 配网失败:获取加密公钥失败 | | 5016 | 配网失败:获取配网token失败 | | 5017 | 配网失败:轮询超时,配网失败 | | 5018 | 配网失败:多模设备配网失败 | | 5019 | 配网失败:配网超时 | | 5020 | 配网失败:多模设备获取配网配置失败 | | 5021 | 配网失败:Wi-Fi 密码错误,设备无法连接网络 | | 5022 | 配网失败:beaconKey异常 | | 5023 | 配网失败:beaconKey发送失败 |
:::info
涉及微信原生 API 的错误码,都将以 wxErrCode
与 wxErrMsg
这两个字段透传微信侧提供的错误信息,方便错误排查。
:::
版本更新
| 版本号 | 更新说明 |
| ---- | ---- |
| 1.2.0 | 支持 Tuya Beacon
设备进行本地蓝牙控制 |
| 1.1.0 | 支持 蓝牙 LE + Beacon
设备通过蓝牙 LE 通道进行本地蓝牙控制 |
| 1.0.4 | 支持设备自定义 DP 下发 |
| 1.0.1 | 支持 蓝牙 LE 3/.* 与 4/.* 协议版本的设备的本地控制能力 |