名词解释
名词 | 含义 |
serviceId | 服务 id,蓝牙服务的 uuid,搜索设备时主要通过 serviceId 来过滤我们需要的设备。 |
deviceId | 小程序 API 搜索出来的设备的标识,连接设备时主要通过 deviceId 来标识需要连接的设备。 |
explorerDeviceId | 物联网开发平台侧定义的设备 ID,查询设备数据和上报设备数据时以设备 ID 作为设备标识。 |
BlueToothAdapter 蓝牙适配器 | 全局单例,实例上声明了蓝牙搜索、连接等方法。 |
DeviceAdapter 设备适配器 | 真正用来连接设备以及跟设备进行通信的模块,每一个设备连接对应一个设备适配器实例,设备适配器会在连接设备后实例化,并在设备断开连接后销毁。根据不同的 serviceId 来区别不同类型设备的适配器构造函数。 |
蓝牙适配器
添加设备适配器
添加一个设备适配器。使用蓝牙模块时需要根据具体设备情况创建一个设备适配器,并调用本接口将其构造函数添加到蓝牙适配器中。H5 SDK 默认添加了一个支持 LLSync 蓝牙协议的设备适配器。
接口定义
sdk.blueToothAdapter.addAdapter(deviceAdapter: DeviceAdapterConstructor) => void
参数说明
参数名 | 参数描述 | 类型 | 必填 |
deviceAdapter | 要添加的设备适配器的构造函数。 | DeviceAdapterConstructor | 是 |
示例代码
class DemoDeviceAdapter extends DeviceAdapter {static serviceId = '0000FFF0-0000-1000-8000-00805F9B34CC';static deviceFilter(deviceInfo) {if (deviceInfo.advertisServiceUUIDs) {const matchedServiceId = deviceInfo.advertisServiceUUIDs.find(id => id === DemoDeviceAdapter.serviceId);if (matchedServiceId && deviceInfo.advertisData) {try {const macArr = deviceInfo.advertisData.slice(2);const mac = macArr.join(':');return {...deviceInfo,deviceName: mac,serviceId: matchedServiceId,};} catch (err) {console.error('parse mac error', err);}}}}handleBLEMessage(hex) {return {type: 'unknown',data: hex,};}}sdk.blueToothAdapter.addAdapter(DemoDeviceAdapter);
初始化蓝牙模块
初始化蓝牙模块,包括初始化蓝牙模块、打通小程序间蓝牙通信以及注册全局回调等。本接口可重复调用,可在每次使用蓝牙模块前调用。
接口定义
sdk.blueToothAdapter.init() => Promise<void>
返回值
返回一个带缓存的 Promise,初始化成功后 resolve。若初始化未完成或已初始化成功,则多次调用后返回同一个 Promise。若初始化失败,则该缓存的 Promise 在 reject 之后会被释放,再次调用则将重新初始化。
示例代码
sdk.blueToothAdapter.init().then(() => {// 调用蓝牙模块能力});
开始搜索蓝牙设备
接口定义
sdk.blueToothAdapter.startSearch({serviceId?: string,serviceIds?: string[],ignoreDeviceIds?: string[],onSearch: (DeviceInfo[]) => void,onError: (Error) => void,timeout: number}) => Promise<void>
参数说明
参数名 | 参数描述 | 类型 | 必填 |
serviceId | 指定需要搜索的 serviceId,不传的话会使用当前支持的所有 DeviceAdapter 的 serviceId 来匹配。 | string | 否 |
serviceIds | 参数描述同 serviceId。 | string[] | 否 |
ignoreDeviceIds | 可选,需要过滤掉的 deviceId 列表(例如刚添加完的设备),搜索结果中将不会出现这些设备。 | string[] | 否 |
onSearch | 当搜索结果更新后调用,返回搜索到的设备列表。 | (DeviceInfo[]) => void | 是 |
onError | 当搜索过程中发生错误后调用,触发后设备搜索将会中止。 | (Error) => void | 是 |
timeout | 可选,默认20000,单位毫秒,超过指定时长没有搜索到设备后将会触发超时错误。 | number | 是 |
返回值
返回一个 Promise。
停止搜索蓝牙设备
接口定义
sdk.blueToothAdapter.stopSearch() => void
搜索单个蓝牙设备
开始搜索蓝牙设备,并在搜索到第一个满足条件的设备后停止搜索。
接口定义
sdk.blueToothAdapter.searchDevice({deviceName: string,serviceId?: string,serviceIds?: string[],ignoreDeviceIds?: string[]}) => Promise<DeviceInfo>
参数说明
参数名 | 参数描述 | 类型 | 必填 |
deviceName | 指定需要搜索的设备 deviceName。 | string | 是 |
serviceId | 指定需要搜索的 serviceId,不传的话会使用当前支持的所有 DeviceAdapter 的 serviceId 来匹配。 | string | 否 |
serviceIds | 参数描述同 serviceId。 | string[] | 否 |
ignoreDeviceIds | 可选,需要过滤掉的 deviceId 列表(例如刚添加完的设备),搜索结果中将不会出现这些设备。 | string[] | 否 |
返回值
返回一个 Promise,在找到第一个满足条件的设备后 resolve。
连接蓝牙设备
连接指定蓝牙设备。
接口定义
blueToothAdapter.connectDevice(deviceInfo: DeviceInfo, options?: { autoNotify?: boolean }) => Promise<DeviceAdapter>
参数说明
参数名 | 参数描述 | 类型 | 必填 |
deviceInfo | DeviceInfo | 是 | |
options.autoNotify | 可选,默认为 true。指定为 true 时,在连接设备后,会自动去拉取服务列表,以及主服务下的特征值列表,并会自动订阅第一个 notifyId 或 indicateId 特征值的 notify。若设备含有多个服务或多个 notify 特征值,请传 false,并自行通过 getBLEDeviceServices、getBLEDeviceCharacteristics、notifyBLECharacteristicValueChange 等方法获取及订阅特征值。 | boolean | 否 |
返回值
返回一个 Promise,连接成功后返回设备适配器。
获取设备适配器实例
根据
deviceId
查询对应的设备适配器实例。接口定义
sdk.blueToothAdapter.getDeviceAdapter({ explorerDeviceId: string }) => DeviceAdapter
参数说明
参数名 | 参数描述 | 类型 | 必填 |
explorerDeviceId | 设备适配器实例的 explorerDeviceId,可以通过 sdk.deviceId 获得。 | string | 是 |
返回值
返回与传入
explorerDeviceId
相匹配的设备适配器实例,如果找不到,则返回 undefined
。上报设备信息
蓝牙设备不能通过mqtt直接上报设备的mac地址等信息,所以需要H5端进行上报,对应的是设备详情里面的设备信息
注意:
图片里面厂家名称和产品型号是在设备量产时在控制台填写的,mac 地址,固件版本等由 H5 端进行上报
接口定义
sdk.blueToothAdapter.reportDeviceInfo({ productId: string, deviceName: string, deviceInfo: any }) => Promise;
参数说明
参数名 | 参数描述 | 类型 |
productId | 产品 ID。 | string |
deviceName | 设备名称。 | string |
deviceInfo | 设备信息。 | any,详情见下面示例 |
deviceInfo: {"module_hardinfo": "模组具体硬件型号 N10","module_softinfo": "模组软件版本","fw_ver": "mcu 固件版本","imei": "设备 imei 号,可选上报","mac": "设备 mac 地址,可选上报","device_label": {"append_info": "设备商自定义的产品附加信息"}}
监听蓝牙适配器事件
监听蓝牙适配器事件。
接口定义
sdk.blueToothAdapter.on(type: string, listener: (...args) => void) => void
参数说明
参数名 | 参数描述 | 类型 | 必填 |
type | 要监听的事件。 | string | 是 |
listener | 事件触发时的回调函数。 | (...args) => void | 是 |
取消监听蓝牙适配器事件
取消监听蓝牙适配器事件。
接口定义
sdk.blueToothAdapter.off(type: string, listener: (...args) => void) => void
参数说明
参数名 | 参数描述 | 类型 | 必填 |
type | 要取消监听的事件。 | string | 是 |
listener | 要取消监听的事件的回调函数,不传则清除该事件的所有回调函数。 | (...args) => void | 否 |
蓝牙适配器事件
adapterStateChange 事件:当适配器状态变化时触发。
参数名 | 参数描述 | 类型 |
available | 蓝牙适配器是否可用 | boolean |
discovering | 蓝牙适配器是否处于搜索状态 | boolean |
设备适配器
自定义设备适配器
自定义设备适配器类需要继承
DeviceAdapter
,并补充以下实现。serviceId:自定义设备适配器类需要设置该属性,代表该设备的主服务 ID。
deviceFilter:自定义设备适配器类需要实现该静态方法,在搜索蓝牙设备时会将每个搜出的设备信息传入该方法,如果判断是本产品的设备,则需在除入参 deviceInfo 之外返回设备唯一标识 deviceName 及 serviceId,否则返回空。
DeviceAdapter.deviceFilter: (deviceInfo: DeviceInfo) => {deviceName: string,serviceId: string,...deviceInfo}
handleBLEMessage:自定义设备适配器类需要实现该方法,用于处理收到
onBLECharacteristicValueChange
回调后的协议解析。DeviceAdapter.handleBLEMessage: (hexString, { serviceId, characteristicId }) => {reportData?: any,...any}
返回值中如果返回
reportData
,则会将该部分数据上报到云端(注意需与产品定义物模型匹配),其他字段则会透传到 message
事件的 payload 中。设备适配器属性
属性名 | 属性描述 | 类型 |
explorerDeviceId | 只读,设备的 explorerDeviceId。 | string |
isConnected | 只读,当前是否已连接设备。 | boolean |
deviceId | 只读,设备的 deviceId。 | string |
serviceId | 只读,设备的主服务 ID,与构造函数上的静态属性 DeviceAdapter.serviceId 一致。 | string |
originName | 只读,设备的原始名称,即小程序接口搜索出来时的 name 字段。 | string |
断开设备连接
接口定义
deviceAdapter.disconnectDevice() => void
获取设备服务列表
接口定义
deviceAdapter.getBLEDeviceServices() => Promise<ServiceList>
返回值
获取设备指定服务的特征值列表
获取设备指定服务中的特征值列表,并将特征值存放在
deviceAdapter
实例上。接口定义
deviceAdapter.getBLEDeviceCharacteristics({ serviceId: string }) => Promise<CharacteristicsList>
参数说明
参数名 | 参数描述 | 类型 | 必填 |
serviceId | 可选,指定要获取特征值列表的服务 ID,默认为主服务 ID。 | string | 否 |
返回值
说明
将获取到的特征值按照如下数据结构存放在
deviceAdapter
实例上。deviceAdapter.characteristicsMap[serviceId] = {notifyIds: string[],indicateIds: string[],writeIds: string[],readIds: string[]}
协商设置蓝牙最大传输单元
本接口仅支持在 Android 系统下调用,iOS 因系统限制不支持。
接口定义
deviceAdapter.setBLEMTU({ mtu: number }) => Promise
参数说明
参数名 | 参数描述 | 类型 | 必填 |
mtu | 最大传输单元。设置范围为 (22,512) 区间内,单位为 bytes。 | number | 是 |
返回值
返回一个 Promise。
读取指定特征值的二进制数据
接口定义
deviceAdapter.readBLECharacteristicValue({serviceId?: string,characteristicId: string}) => Promise<void>
参数说明
参数名 | 参数描述 | 类型 | 必填 |
serviceId | 可选,默认为主服务 ID。 | string | 否 |
characteristicId | 需要读取的特征值 ID,默认会取主服务下的第一个 read 特征值。 | string | 是 |
返回值
返回一个 Promise。接口读取到的信息需要在
onBLECharacteristicValueChange
方法注册的回调中获取,具体参见 wx.readBLECharacteristicValue。获取蓝牙设备信号强度
接口定义
deviceAdapter.getBLEDeviceRSSI() => Promise
返回值
启用特征值变化时的 notify 功能
接口定义
deviceAdapter.notifyBLECharacteristicValueChange({characteristicId?: string,serviceId?: string,state?: boolean}) => Promise<void>
参数说明
参数名 | 参数描述 | 类型 | 必填 |
serviceId | 需要订阅的服务 ID,默认会取主服务 ID。 | string | 否 |
characteristicId | 需要订阅的特征值 ID,默认会取主服务下的第一个 notify 或 indicate 特征值。 | string | 否 |
state | 是否启用 notify,默认为 true。 | boolean | 否 |
返回值
返回一个 Promise。
写入二进制数据到指定特征值中
接口定义
deviceAdapter.write(hexString: string, options?: {writeId?: string,serviceId?: string}) => Promise
参数说明
参数名 | 参数描述 | 类型 | 必填 |
hexString | 需要写给蓝牙设备的十六进制字符串。 | string | 是 |
options.writeId | 可选,需要写入的特征值 ID,默认会取主服务下的第一个 writeId。 | string | 否 |
options.serviceId | 可选,需要写入的服务 ID,默认会取主服务 ID。 | string | 否 |
监听事件
接口定义
deviceAdapter.on(type: string, listener: (...args) => void) => void
参数说明
参数名 | 参数描述 | 类型 | 必填 |
type | 要监听的事件。 | string | 是 |
listener | 事件触发时的回调函数。 | (...args) => void | 是 |
取消监听事件
取消监听设备适配器事件。
接口定义
deviceAdapter.off(type: string, listener: (...args) => void) => void
参数说明
参数名 | 参数描述 | 类型 | 必填 |
type | 要取消监听的事件。 | string | 是 |
listener | 要取消监听的事件的回调函数,不传则清除该事件的所有回调函数。 | (...args) => void | 否 |
设备适配器事件
connect 事件:设备连接后触发。
disconnect 事件:设备断开后触发。
message 事件:当收到
onBLECharacteristicValueChange
回调,并经过 handleBLEMessage
处理后触发。参数名 | 参数描述 | 类型 |
timestamp | 收到设备消息的时间戳,单位毫秒。 | number |
dataReported | 收到设备的消息是否已上报云端。 | boolean |
(其他) | handleBLEMessage 函数返回的其他参数将会透传到 message 事件中。 | any |
bLEConnectionStateChange 事件:当
onBleConnectionStateChange
触发时触发,若 connected
为 true,则接下来会触发 connect
事件,否则会触发 disconnect
事件。参数名 | 参数描述 | 类型 |
connected | 设备是否连接。 | boolean |
标准蓝牙协议
LLSync 标准蓝牙协议设备的绑定流程在小程序中进行,开发者只需在自定义 H5 面板中关注设备的连接、控制操作与事件监听。自定义 H5 面板已默认添加 LLSync 标准蓝牙协议的设备适配器(StandardDeviceAdapter),支持通过 LLSync 标准蓝牙协议与设备通信。H5 面板 Demo 中提供了 标准蓝牙协议 demo 供开发者参考。
搜索并连接设备
与标准蓝牙协议设备建立连接的过程分为三个步骤:搜索设备、连接设备、连接鉴权。示例代码如下:
import { StandardDeviceAdapter } from 'qcloud-iotexplorer-h5-panel-sdk';// 初始化蓝牙适配器await sdk.blueToothAdapter.init();// 搜索设备const deviceInfo = await sdk.blueToothAdapter.searchDevice({deviceName: sdk.deviceName,serviceId: StandardDeviceAdapter.serviceId,productId: sdk.productId,disableCache: true,});if (!deviceInfo) {throw new Error('未搜索到设备');}// 连接设备const deviceAdapter = await sdk.blueToothAdapter.connectDevice({...device,productId: sdk.productId,});// 连接鉴权if (!deviceAdapter.authorized) {await deviceAdapter.authenticateConnection({deviceName: sdk.deviceName,});}
设备通信
通过上述流程与设备建立连接后,H5 面板即可控制设备,接收设备的属性、事件上报。
控制设备
sdk.controlDeviceData({// 要控制的设备属性power_switch: 1});
监听设备事件
接口定义请参见 事件监听,示例代码如下:
// 监听设备属性上报sdk.on('wsReport', ({ deviceId, deviceData }) => {console.log('device', deviceId, 'report_property', deviceData);});// 监听设备事件上报sdk.on('wsEventReport', ({ deviceId, Payload }) => {console.log('device', deviceId, 'report_event', Payload);});
设备适配器属性
属性名 | 属性描述 | 类型 |
explorerDeviceId | 只读,设备在物联网开发平台的 DeviceId。 | string |
isConnected | 只读,当前是否已连接设备。 | boolean |
deviceId | 只读,小程序蓝牙接口提供的 deviceId。 | string |
serviceId | 只读,设备的主服务 ID,与构造函数上的静态属性 DeviceAdapter.serviceId 一致。 | string |
originName | 只读,设备的原始名称,即小程序接口搜索出来时的 name 字段。 | string |
bleVersion | 只读,LLSync 协议版本号。 | number |
mtu | 只读,设备要求设置的最大传输单元 (MTU) 大小。 | number |
otaVersion | 只读,设备固件版本号。 | string |
extendInfo.macStr | 只读,设备的 mac 地址。 | string |
authorized | 只读,是否与设备完成鉴权。 | boolean |
BLE + WIFI 双路通信
针对 Wi-Fi + BLE Combo 模组,提供设备端 SDK 和 H5 SDK,支持设备 Wi- Fi 离线状态下,小程序通过 LLSync 标准蓝牙协议与设备通信,为用户提供 Wi-Fi 断网下的更佳体验。设备端 SDK 请参考 开发指引。
对于自定义 H5 面板,配网流程无需开发者关注,开发者需要在面板中关注:
1. 监听设备在线状态,wifi连接是否正常。
2. 当设备离线时启用蓝牙进行通信。下面分开说明。
监听设备在线状态
sdk.on('wsStatusChange', ({deviceId, deviceStatus}) => {if (deviceStatus === 0) {// 设备已离线,开始启用蓝牙连接进行通信,见第二步}})
启用蓝牙通信
1. 添加 BleComboDualModeDeviceAdapter4H5
import { BleComboDualModeDeviceAdapter4H5 } from 'qcloud-iotexplorer-appdev-plugin-wificonf-blecombo/lib/protocols/BleComboDualMode';const sdk = window.h5PanelSdk;BleComboDualModeDeviceAdapter4H5.injectOptions({ appDevSdk: sdk.appDevSdk });sdk.blueToothAdapter.addAdapter(BleComboDualModeDeviceAdapter4H5, true);
2. 搜索设备
await blueToothAdapter.init();console.log('开始搜索设备', sdk.deviceName);const deviceInfo = await blueToothAdapter.searchDevice({deviceName: sdk.deviceName,serviceId: BleComboDualModeDeviceAdapter4H5.serviceId,productId: sdk.productId,disableCache: true,});
3. 连接设备
const deviceAdapter = await blueToothAdapter.connectDevice({...device,productId: sdk.productId,});console.log('deviceAdapter:', deviceAdapter);// authorized之后,才能向设备发送控制数据if (!deviceAdapter.authorized) {await deviceAdapter.authenticateConnection({deviceName: sdk.deviceName,});}
当小程序和设备间的蓝牙连接成功后,面板就可以对设备进行控制了,sdk会将控制数据通过蓝牙发送到设备。例如进行开关的控制:
sdk.controlDeviceData({ power_switch: 1 });