|
|
@@ -1,382 +1,4 @@
|
|
|
// 灵敏度
|
|
|
-const BLEDIS = 0.9;
|
|
|
-
|
|
|
-
|
|
|
-// 设备Id
|
|
|
-var deviceId = "";
|
|
|
-// 服务Id
|
|
|
-var serviceId = "";
|
|
|
-
|
|
|
-var notifyCharacteristicId = "";
|
|
|
-
|
|
|
-var writeCharacteristicId = "";
|
|
|
-
|
|
|
-var currentInstruction = "";
|
|
|
-
|
|
|
-var showToast = false;
|
|
|
-
|
|
|
-var bListenerUpdate = false;
|
|
|
-
|
|
|
-var bListenerJson = false;
|
|
|
-
|
|
|
-var bListenerMac = false;
|
|
|
-
|
|
|
-function initData() {
|
|
|
- // 设备Id
|
|
|
- this.deviceId = "";
|
|
|
- // 服务Id
|
|
|
- this.serviceId = "";
|
|
|
-
|
|
|
- this.notifyCharacteristicId = "";
|
|
|
-
|
|
|
- this.writeCharacteristicId = "";
|
|
|
-
|
|
|
- this.currentInstruction = "";
|
|
|
-
|
|
|
- this.showToast = false;
|
|
|
-
|
|
|
- this.bListenerUpdate = false;
|
|
|
-
|
|
|
- this.bListenerJson = false;
|
|
|
-
|
|
|
- this.bListenerMac = false;
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-function openBluetoothAdapter(context) {
|
|
|
-
|
|
|
- let {
|
|
|
- success,
|
|
|
- fail,
|
|
|
- complete
|
|
|
- } = context;
|
|
|
-
|
|
|
- //#ifdef H5
|
|
|
- console.warn('h5不加载蓝牙模块');
|
|
|
- return;
|
|
|
- //#endif
|
|
|
-
|
|
|
- let self = this;
|
|
|
- // 初始化蓝牙适配器
|
|
|
- uni.openBluetoothAdapter({
|
|
|
- success: res => {
|
|
|
- // console.log("初始化蓝牙成功:", res);
|
|
|
- if (success)
|
|
|
- success(res);
|
|
|
- },
|
|
|
- fail: res => {
|
|
|
- // console.error("openBluetoothAdapter == ", res);
|
|
|
- if (fail)
|
|
|
- fail(res);
|
|
|
- },
|
|
|
- complete: res => {
|
|
|
- // console.warn("************openBluetoothAdapter complete == ", res);
|
|
|
- if (complete)
|
|
|
- complete(res);
|
|
|
- }
|
|
|
- })
|
|
|
-}
|
|
|
-
|
|
|
-function onBLEConnectionStateChange() {
|
|
|
- //#ifdef H5
|
|
|
- console.warn('h5不加载蓝牙模块');
|
|
|
- return;
|
|
|
- //#endif
|
|
|
-
|
|
|
- uni.onBLEConnectionStateChange(res => {
|
|
|
- // 该方法回调中可以用于处理连接意外断开等异常情况
|
|
|
- console.log(`蓝牙连接状态 -------------------------->`, JSON.stringify(res));
|
|
|
- if (!res.connected) {
|
|
|
- // if (this.isStop) return;
|
|
|
- // console.log('断开低功耗蓝牙成功:');
|
|
|
- uni.$emit('callbackCloseBLE');
|
|
|
- //todo 在这里尝试重连
|
|
|
- //关闭连接
|
|
|
- // this.closeBluetoothAdapter();
|
|
|
- }
|
|
|
- });
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * 连接低功耗蓝牙设备。
|
|
|
- * 若APP在之前已有搜索过某个蓝牙设备,并成功建立连接,可直接传入之前搜索获取的 deviceId 直接尝试连接该设备,无需进行搜索操作。
|
|
|
- */
|
|
|
-function createBLEConnection(item, success, fail) {
|
|
|
- let self = this;
|
|
|
- self.initData();
|
|
|
- self.deviceId = item.deviceId;
|
|
|
- let timeout = 10000;
|
|
|
- uni.createBLEConnection({
|
|
|
- // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
|
|
|
- deviceId: self.deviceId,
|
|
|
- timeout,
|
|
|
- success: res => {
|
|
|
- if (success) {
|
|
|
- success(res);
|
|
|
- }
|
|
|
- },
|
|
|
- fail: res => {
|
|
|
- if (fail)
|
|
|
- fail(res);
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * 获取设备的服务ID
|
|
|
- */
|
|
|
-function getBLEDeviceServices(item, callback,getServiceList) {
|
|
|
- let serviceList = [];
|
|
|
- let self = this;
|
|
|
- // console.log("getBLEDeviceServices");
|
|
|
- uni.getBLEDeviceServices({
|
|
|
- deviceId: item.deviceId,
|
|
|
- success: res => {
|
|
|
- console.log("getBLEDeviceServices==", JSON.stringify(res), item);
|
|
|
- serviceList = res.services;
|
|
|
- // serviceList = [];
|
|
|
- if(serviceList.length == 0){
|
|
|
- uni.hideToast();
|
|
|
- uni.showModal({
|
|
|
- title:'失败',
|
|
|
- content:'获取服务失败,请尝试重新连接对应的模式。'
|
|
|
- })
|
|
|
- }
|
|
|
- if(getServiceList){
|
|
|
- getServiceList(serviceList);
|
|
|
- }
|
|
|
- for (let i = 0; i < serviceList.length; i++) {
|
|
|
- let service = serviceList[i];
|
|
|
- //比对service是否是F393服务
|
|
|
- // if (item.primaryUUID && service.uuid.indexOf(item.primaryUUID) != -1)
|
|
|
- if (service.uuid.toLocaleLowerCase() === item.PRIMARY_SERVICE.toLocaleLowerCase()) {
|
|
|
- self.serviceId = service.uuid;
|
|
|
- // console.log("设备的serviceId: " + self.serviceId);
|
|
|
- //开始获取指定服务的特征值
|
|
|
- self.getBLEDeviceCharacteristics(item, callback);
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- },
|
|
|
- fail: failRes => {
|
|
|
- console.log('device services:', failRes.services)
|
|
|
- uni.showModal({
|
|
|
- title:'连接失败',
|
|
|
- content:'未获取到相应服务,请继续尝试连接设备。'
|
|
|
- })
|
|
|
- }
|
|
|
- });
|
|
|
-}
|
|
|
-/**
|
|
|
- * 获取指定服务的特征值
|
|
|
- */
|
|
|
-function getBLEDeviceCharacteristics(item, callback) {
|
|
|
- let deviceId = this.deviceId;
|
|
|
- let serviceId = this.serviceId;
|
|
|
- let characteristicsList = [];
|
|
|
- let self = this;
|
|
|
- uni.getBLEDeviceCharacteristics({
|
|
|
- deviceId,
|
|
|
- serviceId,
|
|
|
- success: res => {
|
|
|
- // console.log(JSON.stringify(res));
|
|
|
- // console.log("获取的" + serviceId + "服务的特征值:" + JSON.stringify(res.characteristics)+JSON.stringify(item));
|
|
|
- // console.log(res.characteristics);
|
|
|
- // console.log(item);
|
|
|
- // characteristicsList = res.characteristics;
|
|
|
- // for (let i = 0; i < characteristicsList.length; i++) {
|
|
|
- // let characteristic = characteristicsList[i];
|
|
|
- // //该特征值是否支持 notify或indicate 操作
|
|
|
- // if (characteristic.properties.notify || characteristic.properties.indicate) {
|
|
|
- // console.log("该特征值支持 notify 操作:" + characteristic.uuid);
|
|
|
- // self.notifyCharacteristicId = characteristic.uuid;
|
|
|
- // self.notifyBLECharacteristicValueChange(deviceId, serviceId);
|
|
|
- // }
|
|
|
- // if (characteristic.properties.write) {
|
|
|
- // console.log("该特征值支持 write 操作:" + characteristic.uuid);
|
|
|
- // self.writeCharacteristicId = characteristic.uuid;
|
|
|
- // // break;
|
|
|
- // }
|
|
|
- // }
|
|
|
- if (item.PRIMARY_NOTIFY != '') {
|
|
|
- self.notifyCharacteristicId = item.PRIMARY_NOTIFY;
|
|
|
- self.notifyBLECharacteristicValueChange(callback);
|
|
|
- }
|
|
|
- if (item.PRIMARY_WRITE != '') {
|
|
|
- self.writeCharacteristicId = item.PRIMARY_WRITE;
|
|
|
- }
|
|
|
- },
|
|
|
- fail: res => {
|
|
|
- console.log('device getBLEDeviceCharacteristics failed:', JSON.stringify(res))
|
|
|
- }
|
|
|
- })
|
|
|
-}
|
|
|
-
|
|
|
-//启用低功耗蓝牙设备特征值变化时的 notify 功能,订阅特征值。
|
|
|
-//注意:必须设备的特征值支持notify或者indicate才可以成功调用,具体参照 characteristic 的 properties 属性
|
|
|
-function notifyBLECharacteristicValueChange(callback) {
|
|
|
- var _self = this;
|
|
|
- // 启用notify功能
|
|
|
- // console.log("启用notify功能");
|
|
|
- uni.notifyBLECharacteristicValueChange({
|
|
|
- state: true,
|
|
|
- deviceId: _self.deviceId,
|
|
|
- serviceId: _self.serviceId,
|
|
|
- characteristicId: _self.notifyCharacteristicId,
|
|
|
- success: function(res) {
|
|
|
- _self.onBLECharacteristicValueChange(callback); //监听特征值变化
|
|
|
- },
|
|
|
- fail: function(res) {
|
|
|
- uni.showToast({
|
|
|
- title: 'notify启动失败',
|
|
|
- icon: "none",
|
|
|
- mask: true
|
|
|
- });
|
|
|
-
|
|
|
- }
|
|
|
- })
|
|
|
-}
|
|
|
-//监听低功耗蓝牙设备的特征值变化。必须先启用notify接口才能接收到设备推送的notification。
|
|
|
-function onBLECharacteristicValueChange(callback) {
|
|
|
- var self = this;
|
|
|
- console.log("onBLECharacteristicValueChange success");
|
|
|
- if (callback) {
|
|
|
- callback({
|
|
|
- notifyCharacteristicId: self.notifyCharacteristicId,
|
|
|
- writeCharacteristicId: self.writeCharacteristicId
|
|
|
- })
|
|
|
- }
|
|
|
- uni.onBLECharacteristicValueChange(function(res) {
|
|
|
- let box = {};
|
|
|
- var resValue = ab2hext(res.value); //16进制字符串
|
|
|
- // console.log(self.currentInstruction +","+ self.bListenerUpdate+","+self.bListenerJson);
|
|
|
-
|
|
|
- if (self.currentInstruction == "V" && self.showToast) {
|
|
|
- var resValueStr = hexToString(resValue);
|
|
|
- // console.log("v resValueStr:" + resValueStr);
|
|
|
- // uni.showToast({
|
|
|
- // title: resValueStr.replace(/\{|}/g,'').trim(),
|
|
|
- // icon: 'none',
|
|
|
- // duration: 5000
|
|
|
- // })
|
|
|
- let _info = {
|
|
|
- type: 'version',
|
|
|
- instruction: 'V',
|
|
|
- value: resValueStr.replace(/\{|}/g, '').trim()
|
|
|
- }
|
|
|
- uni.$emit('listenerBLE', _info);
|
|
|
- self.currentInstruction = "";
|
|
|
- self.showToast = false;
|
|
|
- return;
|
|
|
- } else if (self.currentInstruction == 'M' && self.bListenerMac) {
|
|
|
- var resValueStr = hexToString(resValue);
|
|
|
- // console.log(resValue);
|
|
|
- // console.log("m:", resValueStr.replace(/\{|}/g,''));
|
|
|
- // uni.showToast({
|
|
|
- // title: resValueStr.replace(/\{|}/g,'').trim(),
|
|
|
- // icon: 'none',
|
|
|
- // duration: 5000
|
|
|
- // })
|
|
|
- let _info = {
|
|
|
- type: 'mac',
|
|
|
- instruction: 'M',
|
|
|
- value: resValueStr.replace(/\{|}/g, '').trim()
|
|
|
- }
|
|
|
- uni.$emit('listenerBLE', _info);
|
|
|
- self.currentInstruction = "";
|
|
|
- self.bListenerMac = false;
|
|
|
- return;
|
|
|
- }
|
|
|
- //步数数据解析
|
|
|
- if (self.bListenerJson) {
|
|
|
- var resValueStr = hexToString(resValue);
|
|
|
- // let _info = {
|
|
|
- // type: 'mac',
|
|
|
- // instruction: 'M',
|
|
|
- // value: resValueStr.replace(/\{|}/g, '').trim()
|
|
|
- // }
|
|
|
- console.log(resValueStr);
|
|
|
- box["Json"] = resValueStr;
|
|
|
- uni.$emit('updateBLEDeviceJson', box);
|
|
|
- }
|
|
|
- //原始数据解析
|
|
|
- if (self.bListenerUpdate) {
|
|
|
- // console.log("min:" + min+",s:"+s+",ms:"+ms);
|
|
|
-
|
|
|
- //R/L 左手还是右手
|
|
|
- let handle = resValue.substr(6, 2);
|
|
|
-
|
|
|
- let axStr = resValue.substr(8, 4);
|
|
|
- let ayStr = resValue.substr(12, 4);
|
|
|
- let azStr = resValue.substr(16, 4);
|
|
|
- // console.log("accStr:" + axStr+","+ayStr+","+azStr);
|
|
|
- // console.log("hex2int:" + hexToSignedInt(axStr)+","+hexToSignedInt(ayStr)+","+hexToSignedInt(azStr));
|
|
|
- //一个字节最大只能表示265 2个字节可以表示65536 然后你这边做一下转换 例如00 3E 3*16+14=62 ----->0.03 g
|
|
|
- //(真实值= AD值 /32768 * 16)
|
|
|
- //0.003 = 62 / 2768 * 16
|
|
|
- let ax = hexToSignedInt(axStr) / 32768 * 16;
|
|
|
- let ay = hexToSignedInt(ayStr) / 32768 * 16;
|
|
|
- let az = hexToSignedInt(azStr) / 32768 * 16;
|
|
|
-
|
|
|
- let gxStr = resValue.substr(20, 4);
|
|
|
- let gyStr = resValue.substr(24, 4);
|
|
|
- let gzStr = resValue.substr(28, 4);
|
|
|
-
|
|
|
- //角速度(AD值/32768 * 2000) 角速度单位是 °/s 范围是 正负2000
|
|
|
- let gx = hexToSignedInt(gxStr) / 32768 * 2000;
|
|
|
- let gy = hexToSignedInt(gyStr) / 32768 * 2000;
|
|
|
- let gz = hexToSignedInt(gzStr) / 32768 * 2000;
|
|
|
-
|
|
|
- //毫秒
|
|
|
- let ms = hex2int(resValue.substr(2, 4));
|
|
|
- //分
|
|
|
- let min = hex2int(resValue.substr(32, 2));
|
|
|
- //秒
|
|
|
- let s = hex2int(resValue.substr(34, 2));
|
|
|
-
|
|
|
- box["handle"] = hexToString(handle);
|
|
|
- box["acc"] = {
|
|
|
- ax,
|
|
|
- ay,
|
|
|
- az
|
|
|
- };
|
|
|
- box["gyro"] = {
|
|
|
- gx,
|
|
|
- gy,
|
|
|
- gz
|
|
|
- };
|
|
|
-
|
|
|
- box["min"] = min;
|
|
|
- box["s"] = s;
|
|
|
- box["ms"] = ms;
|
|
|
-
|
|
|
-
|
|
|
- // console.log("box:" + JSON.stringify(box));
|
|
|
-
|
|
|
- // if (typeof obj !== 'object' && obj) {
|
|
|
- // // console.log("连接错误")
|
|
|
- // //-1为错误
|
|
|
- // uni.$emit("callbackBLEState", {
|
|
|
- // state: -1,
|
|
|
- // msg: "设备数据错误"
|
|
|
- // });
|
|
|
- // return;
|
|
|
- // }
|
|
|
- // if (obj.hasOwnProperty("H")) {
|
|
|
- // console.log("HHHH:", obj.H);
|
|
|
- // }
|
|
|
- //更新数据给webview,在game-play-web||game-play-sub绑定
|
|
|
- //后面更新数据都用此接口
|
|
|
- uni.$emit('updateBLEDeviceData', box);
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- });
|
|
|
-}
|
|
|
-
|
|
|
// ArrayBuffer转16进制字符串示例
|
|
|
function ab2hext(buffer) {
|
|
|
var hexArr = Array.prototype.map.call(
|
|
|
@@ -497,189 +119,15 @@ function hexToString(str) {
|
|
|
}
|
|
|
|
|
|
|
|
|
-/**
|
|
|
- * 断开蓝牙模块连接
|
|
|
- */
|
|
|
-function closeBluetoothAdapter() {
|
|
|
- //#ifdef H5
|
|
|
- console.warn('h5不加载蓝牙模块');
|
|
|
- return;
|
|
|
- //#endif
|
|
|
-
|
|
|
- uni.closeBluetoothAdapter({
|
|
|
- success: res => {
|
|
|
- console.log('断开蓝牙模块成功');
|
|
|
-
|
|
|
- uni.showToast({
|
|
|
- icon: "none",
|
|
|
- title: "蓝牙已经断开!",
|
|
|
- mask: false,
|
|
|
- duration: 3000
|
|
|
- });
|
|
|
- }
|
|
|
- });
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-//向低功耗蓝牙设备特征值中写入二进制数据。注意:必须设备的特征值支持 write 才可以成功调用。
|
|
|
-function writeBLECharacteristicValue(value, retryCount, success, getFail) {
|
|
|
- var self = this;
|
|
|
- if (!value && value === '') {
|
|
|
- uni.showToast({
|
|
|
- title: "指令为空"
|
|
|
- })
|
|
|
- return;
|
|
|
- }
|
|
|
- //记录一下指令
|
|
|
- self.currentInstruction = value;
|
|
|
- //V 获取版本,M 获取mac 地址
|
|
|
- if (value == "V")
|
|
|
- self.showToast = true;
|
|
|
-
|
|
|
- if (value == "M") {
|
|
|
- self.showToast = true;
|
|
|
- self.bListenerMac = true;
|
|
|
- }
|
|
|
- if (value == "4") {
|
|
|
- self.bListenerUpdate = false;
|
|
|
- }
|
|
|
- if (value == "3") {
|
|
|
- if (self.bListenerUpdate) {
|
|
|
- uni.showToast({
|
|
|
- title: "原始数据已开启"
|
|
|
- })
|
|
|
- return;
|
|
|
- }
|
|
|
- self.bListenerUpdate = true;
|
|
|
- }
|
|
|
-
|
|
|
- if (value == "6") {
|
|
|
- self.bListenerJson = false;
|
|
|
- }
|
|
|
- if (value == "5") {
|
|
|
- if (self.bListenerJson) {
|
|
|
- uni.showToast({
|
|
|
- title: "步数数据已开启"
|
|
|
- })
|
|
|
- return;
|
|
|
- }
|
|
|
- self.bListenerJson = true;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- console.log("currentInstruction:", self.currentInstruction, value, self.bListenerUpdate, self.bListenerMac);
|
|
|
- console.log("self.deviceId:", self.deviceId, self.serviceId, self.writeCharacteristicId);
|
|
|
- uni.writeBLECharacteristicValue({
|
|
|
- deviceId: self.deviceId,
|
|
|
- serviceId: self.serviceId,
|
|
|
- // 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取
|
|
|
- characteristicId: self.writeCharacteristicId,
|
|
|
- // 这里的value是ArrayBuffer类型
|
|
|
- value: str2ab(value),
|
|
|
- success:(res)=> {
|
|
|
- console.log('writeBLECharacteristicValue success', res.errMsg, value,retryCount);
|
|
|
- if (success) {
|
|
|
- success(res);
|
|
|
- }
|
|
|
- },
|
|
|
- fail: (fail) => {
|
|
|
- console.log(fail)
|
|
|
- //重新写入
|
|
|
- // uni.showModal({
|
|
|
- // title:"提示",
|
|
|
- // content:"蓝牙通信失败,是否重新执行此操作。",
|
|
|
- // success: (resValue) => {
|
|
|
- // if(resValue.confirm){
|
|
|
- // self.writeBLECharacteristicValue(value, success);
|
|
|
- // }
|
|
|
- // }
|
|
|
- // })
|
|
|
- if(retryCount>0){
|
|
|
- console.log("writeBLECharacteristicValue Rewrite ===================>"+value+" == "+retryCount);
|
|
|
- retryCount--;
|
|
|
- setTimeout(()=>{
|
|
|
- self.writeBLECharacteristicValue(value,retryCount,success,getFail);
|
|
|
- },300);
|
|
|
- }
|
|
|
- if(getFail){
|
|
|
- getFail(fail);
|
|
|
- }
|
|
|
- }
|
|
|
- // ,
|
|
|
- // complete: (completeRes) => {
|
|
|
- // console.log(completeRes)
|
|
|
- // }
|
|
|
- })
|
|
|
-
|
|
|
- // uni.readBLECharacteristicValue({
|
|
|
- // deviceId:self.deviceId,
|
|
|
- // serviceId:self.serviceId,
|
|
|
- // characteristicId:self.notifyCharacteristicId,
|
|
|
- // success: (resValue) => {
|
|
|
- // console.log('read success!');
|
|
|
- // }
|
|
|
- // })
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * 断开蓝牙连接
|
|
|
- */
|
|
|
-function closeBLEConnection(deviceId, success) {
|
|
|
- uni.closeBLEConnection({
|
|
|
- deviceId,
|
|
|
- success: res => {
|
|
|
- if (success)
|
|
|
- success();
|
|
|
- },
|
|
|
- fail: (fail) => {
|
|
|
- console.log("关闭蓝牙失败",fail);
|
|
|
- }
|
|
|
- });
|
|
|
-}
|
|
|
|
|
|
function getRSSITransDistance(rssi) {
|
|
|
return Math.pow(Math.E, (Math.abs(rssi) - 66.78) / 16.56);
|
|
|
}
|
|
|
|
|
|
-/**
|
|
|
- * 获取在蓝牙模块生效期间所有已发现的蓝牙设备。包括已经和本机处于连接状态的设备。
|
|
|
- */
|
|
|
-function getBluetoothDevices() {
|
|
|
- uni.getBluetoothDevices({
|
|
|
- success(res) {
|
|
|
- console.log("getBluetoothDevices:", res)
|
|
|
- }
|
|
|
- })
|
|
|
-}
|
|
|
-
|
|
|
-export default {
|
|
|
- deviceId,
|
|
|
- serviceId,
|
|
|
- //蓝牙模块
|
|
|
- openBluetoothAdapter,
|
|
|
- closeBluetoothAdapter,
|
|
|
-
|
|
|
- onBLEConnectionStateChange,
|
|
|
- getBLEDeviceCharacteristics,
|
|
|
- notifyBLECharacteristicValueChange,
|
|
|
- onBLECharacteristicValueChange,
|
|
|
|
|
|
- //建立连接模块
|
|
|
- createBLEConnection,
|
|
|
- closeBLEConnection,
|
|
|
|
|
|
- getBLEDeviceServices,
|
|
|
+export default {
|
|
|
getRSSITransDistance,
|
|
|
-
|
|
|
- BLEDIS,
|
|
|
-
|
|
|
- //写入模块数据
|
|
|
- writeBLECharacteristicValue,
|
|
|
-
|
|
|
- //获取已经匹配的蓝牙
|
|
|
- getBluetoothDevices,
|
|
|
- //初始化this变量
|
|
|
- initData,
|
|
|
|
|
|
ab2hext,
|
|
|
str2ab,
|