2.1.9 • Published 2 months ago

@ray-js/wechat-bluetooth-sdk v2.1.9

Weekly downloads
-
License
MIT
Repository
-
Last release
2 months ago

本文介绍了涂鸦 IoT 微信小程序蓝牙 SDK,该 SDK 提供了一些蓝牙功能的封装,方便小程序开发者更加快速地连接涂鸦生态中的智能硬件产品。您可以基于该 SDK 快速地实现小程序蓝牙交互功能的开发,实现对智能蓝牙设备的连接、控制、固件升级等操作。

蓝牙 SDK

该 SDK 根据涂鸦蓝牙协议提供高度封装的 API,方便小程序开发者快速实现小程序蓝牙功能。

安装 SDK

使用 NPM 包管理器下载 SDK。

npm install @ray-js/wechat-bluetooth-sdk

使用示例

若您已安装小程序开发者工具,点此打开微信官方代码片段,即可查看完整示例,若按如下步骤操作,还可生成小程序二维码进行真机体验。

  1. 修改 project.config.json 文件中的 appid 字段为您在涂鸦 IoT 平台授权过的小程序 AppID
  2. 使用 npm install 命令安装 NPM 包。
  3. 在开发者工具中按如下路径构建 NPM 包:工具 > 构建 npm
  4. 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 已内部封装通信流程所涉及的接口请求,但由于 用户 IDaccess_token 为云函数接口鉴权必需参数,因此需要调用方传入该参数以便 SDK 顺利发起请求。用户 IDaccess_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.instanceBleService 维护的设备实例列表。

创建 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.beaconInstanceBleService 维护的 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` 以上 )时,必传此项 |
  • 参数举例

    	```js
    	// 发送标准 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 | 状态类型: <ul><li> connect:连接状态</li><li> otaStatus:OTA 升级状态 </li><li> send:发送状态  </li></ul> |
    	| 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 举例

    	```js
    	dpState: {
    		[dpcode1]: true,
    		[dpcode2]: 100
    	}
    	```

取消监听蓝牙回调事件(offReceivePackage)

instance.offReceivePackage(cb);

参数说明

字段数据类型说明
cbFunction注册监听时传入的回调函数

注册蓝牙错误事件(onError)

instance.onError(cb);
  • 参数说明

    	| 字段 | 数据类型 | 说明 |
    	| ---- | ---- | ---- |
    	| cb | function | 回调函数 |
  • 回调参数举例

    	```js
    	{
    	errCode: 1000,
    	errMsg: 'error'
    	}
    	```
    
    	蓝牙交互时出现的异常情况都将在此处进行回调。

取消监听蓝牙回调事件(offError)

instance.offError(cb);
  • 参数说明

    	| 字段 | 数据类型 | 说明 |
    	| ---- | ---- | ---- |
    	| cb | Function | 注册监听时传入的回调函数 |

获取设备本地状态(getBlueStatus)

instance.getBlueStatus()
  • 返回值:Promise

  • Promise 对象处理结果

    	| 字段 | 数据类型 | 说明 |
    	| ---- | ---- | ---- |
    	| success | Boolean | 设备本地状态查询请求下发是否成功 |
    	| errMsg | String | 设备本地状态查询请求下发失败时的错误信息 |
  • 差异化说明

    设备通信类型说明
    蓝牙 LE正常可调用。
    Tuya BeaconTuya 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 BeaconTuya Beacon 设备暂不支持 OTA。

设备解绑(unboundBlue)

instance.unboundBlue(type);
  • 参数说明

    	| 字段 | 数据类型 | 说明 |
    	| ---- | ---- | ---- |
    	| type | String | 共有两种解绑类型,分别对应不同的 type 数值: <ul><li> unbound(默认值):与设备正常解绑。 </li><li> reset:设备重置,该类型除了解绑外,还会删除设备本地历史数据。 </li></ul> |
  • 返回值:Promise

  • Promise 对象处理结果

    	| 字段 | 数据类型 | 说明 |
    	| ---- | ---- | ---- |
    	| success | Boolean | 蓝牙解绑命令是否下发成功 |
    	| errMsg | String | 蓝牙解绑失败时的错误信息 |
  • 差异化说明

    设备通信类型说明
    蓝牙 LE正常可调用。
    Tuya BeaconTuya Beacon 设备场景下,该 API 无参数。

其他功能

Raw 类型数据加解密(encryptRawData、decryptRawData)

// 数据下发前,对 Raw 类型数据加密
BleService.encryptRawData(raw_data)
// 数据上报后,对回调数据进行解密
BleService.decryptRawData(value)

参数说明

字段数据类型说明
raw_dataStringRaw 类型数据
valueString通过 onReceivePackage 回调监听到的 Raw 类型数据

:::info Raw 表示透传类型数据。对某些设备来说,Raw 类型数据可能会包含密码等较为敏感的信息,在数据下发及上报云端时,应对其进行安全加密处理。因此,SDK 要求 Raw 类型数据应加密下发,同时 SDK 自身也会对设备上报的 Raw 类型数据进行加密后返回。 :::

错误码

errCode说明
1001蓝牙连接过程中,调用微信 API 失败
1002未授予地理位置权限(安卓特有)
1003未搜索到蓝牙设备
1004设备信息获取失败
1005获取蓝牙 services 列表失败
1006获取 characteristics 列表失败
1007write 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 的错误码,都将以 wxErrCodewxErrMsg 这两个字段透传微信侧提供的错误信息,方便错误排查。 :::

版本更新

版本号更新说明
1.2.0支持 Tuya Beacon 设备进行本地蓝牙控制
1.1.0支持 蓝牙 LE + Beacon 设备通过蓝牙 LE 通道进行本地蓝牙控制
1.0.4支持设备自定义 DP 下发
1.0.1支持 蓝牙 LE 3/. 与 4/. 协议版本的设备的本地控制能力
2.1.9

2 months ago

2.1.8

4 months ago

2.1.3-beta-1

9 months ago

2.1.2

9 months ago

2.1.1

9 months ago

2.1.4

7 months ago

2.1.3

8 months ago

2.1.6

7 months ago

2.1.5

7 months ago

2.1.7

7 months ago

2.1.0

1 year ago

2.1.0-beta-1

1 year ago

2.0.19

1 year ago

2.0.18

1 year ago

2.0.17

1 year ago

2.0.16

1 year ago

2.0.16-beta-1

1 year ago