diff --git a/pages/6155/deviceDetail.vue b/pages/6155/deviceDetail.vue index 4716c31..83c41cf 100644 --- a/pages/6155/deviceDetail.vue +++ b/pages/6155/deviceDetail.vue @@ -181,7 +181,8 @@ visiblePrompt: false, promptTitle: '设备名称', modelValue: '', - visibleClose: false + visibleClose: false, + okCallback:null }, BottomMenu: { show: false, diff --git a/pages/650/HBY650.vue b/pages/650/HBY650.vue index 91eafda..41bafca 100644 --- a/pages/650/HBY650.vue +++ b/pages/650/HBY650.vue @@ -200,7 +200,8 @@ visiblePrompt: false, promptTitle: '设备名称', modelValue: '', - visibleClose: false + visibleClose: false, + okCallback:null }, BottomMenu: { show: false, @@ -393,7 +394,7 @@ return className; }, bleValueNotify: function(receive, device, path) { //订阅消息 - console.log("收到设备的数据", data) + console.log("收到设备的数据", receive) let data = recei.ReceiveData(receive, device, pagePath); if (data) { @@ -1144,9 +1145,12 @@ if (this.Status.Pop.clickEvt == 'SendUsr') { } - + console.log("1111"); this.Status.Pop.showPop = false; + if(this.Status.Pop.okCallback){ + this.Status.Pop.okCallback(); + } }, showPop: function(option) { diff --git a/pages/7305/BJQ7305.vue b/pages/7305/BJQ7305.vue index d99ccf6..53ff44e 100644 --- a/pages/7305/BJQ7305.vue +++ b/pages/7305/BJQ7305.vue @@ -181,7 +181,8 @@ visiblePrompt: false, promptTitle: '设备名称', modelValue: '', - visibleClose: false + visibleClose: false, + okCallback:null }, BottomMenu: { show: false, diff --git a/pages/common/addBLE/LinkBle.vue b/pages/common/addBLE/LinkBle.vue index 38cb20a..aca3b43 100644 --- a/pages/common/addBLE/LinkBle.vue +++ b/pages/common/addBLE/LinkBle.vue @@ -8,6 +8,9 @@ 蓝牙名:{{device.name}} + + 状态:{{deviceStatu}} + 设备名:{{device.deviceName}} @@ -40,12 +43,14 @@ var these = null; var eventChannel = null; var ble = null; - var timeInteval = null; + export default { data() { return { Statu: { - bound: null + bound: null, + timeInteval:null, + isSearch:false }, device: { "deviceId": "", @@ -57,7 +62,8 @@ ], "linkStatu": false, - "macAddress": "" + "macAddress": "", + "communicationMode":"" }, serverDevice:null } @@ -72,15 +78,36 @@ } else { return "red"; } + }, + deviceStatu:function(){ + if(!this.device.name){ + return ""; + } + if(!this.device.macAddress){ + return '等待设备上报Mac地址'; + } + + if(!this.device.deviceName ){ + if(this.Statu.isSearch){ + return "无效设备"; + }else{ + if(this.Statu.timeInteval===null){ + return "等待查询设备" + }else{ + return "正在查询设备"; + } + } + }else{ + return "找到有效设备" + } + + return ""; } }, - onBackPress() { - console.log("返回时断开蓝牙连接,取消订阅"); - ble.disconnectDevice(these.device.deviceId); - ble.removeReceiveCallback(pagePath); - }, + onUnload() { console.log("返回时断开蓝牙连接,取消订阅"); + ble.disconnectDevice(these.device.deviceId); ble.removeReceiveCallback(pagePath); }, onLoad(option) { @@ -96,6 +123,7 @@ if (f && f.macAddress) { these.device.macAddress = f.macAddress; console.log("222222"); + these.Statu.isSearch=false; these.initDevice(); } } @@ -112,9 +140,9 @@ keys.forEach((v, index) => { these.device[v] = f[v]; }) - console.log("LinkedList=", ble.data.LinkedList) - console.log("f=", f); - console.log("获取到设备", these.device); + // console.log("LinkedList=", ble.data.LinkedList) + // console.log("f=", f); + // console.log("获取到设备", these.device); if (f.macAddress) { these.device.macAddress = f.macAddress; @@ -130,9 +158,10 @@ methods: { initDevice: function() { - clearTimeout(timeInteval); + clearTimeout(this.Statu.timeInteval); - timeInteval = setTimeout(() => { + this.Statu.timeInteval = setTimeout(() => { + this.Statu.isSearch=true; showLoading(these, { text: '正在获取设备信息' }); @@ -144,6 +173,7 @@ deviceMac: these.device.macAddress } }).then(res => { + console.log("获取设备信息", res); if (res && res.code == 200) { let data = res.data; @@ -180,6 +210,8 @@ }).catch((ex) => { console.log("获取设备出现异常:", ex); }).finally(() => { + this.Statu.timeInteval=null; + this.Statu.isSearch=false; hideLoading(these); }); @@ -202,11 +234,16 @@ these.Statu.boundRemark = "设备上报Mac地址异常"; return; } + if(!this.device.deviceName){ + these.Statu.bound = false; + these.Statu.boundRemark = "设备未入库"; + return; + } these.Statu.bound = null; these.Statu.boundRemark = ""; showLoading(these, { - text: "连接中..." + text: "绑定中..." }) let promise = request({ url: '/app/device/bind', diff --git a/pages/common/addBLE/addEquip.vue b/pages/common/addBLE/addEquip.vue index 00c1942..98e706f 100644 --- a/pages/common/addBLE/addEquip.vue +++ b/pages/common/addBLE/addEquip.vue @@ -10,7 +10,7 @@ - + @@ -27,7 +27,7 @@ - + @@ -49,7 +49,7 @@ - + @@ -81,8 +81,8 @@ - - + + @@ -94,10 +94,10 @@ hideLoading, updateLoading } from '@/utils/loading.js' - const pagePath="pages/common/addBLE/addEquip"; + const pagePath = "pages/common/addBLE/addEquip"; var ble = null; var these = null; - var eventChannel=null; + var eventChannel = null; export default { data() { return { @@ -130,9 +130,9 @@ }, PairEquip: [], //已配对设备 EquipMents: [], //搜索出来的设备 - device:null, - item:{ - deviceId:'' + device: null, + item: { + deviceId: '' } } }, @@ -141,28 +141,25 @@ }, onHide: function() { ble.StopSearch(); - + }, - onBackPress: (e) => { + + onUnload() { ble.StopSearch(); ble.removeDeviceFound(pagePath); ble.removeReceiveCallback(pagePath); }, - onUnload(){ - ble.StopSearch(); - ble.removeDeviceFound(pagePath); - ble.removeReceiveCallback(pagePath); - }, onLoad() { these = this; + this.EquipMents = []; ble = bleTool.getBleTool(); ble.addDeviceFound((arr) => { - + arr = arr.devices; for (var i = 0; i < arr.length; i++) { arr[i].linkStatu = false; - if(!arr[i].name){ + if (!arr[i].name) { continue; } let f = these.EquipMents.find(function(v) { @@ -170,51 +167,56 @@ }); if (!f) { - + these.EquipMents.push(arr[i]); } else { } } + console.log("equip=", these.EquipMents) }, pagePath); // console.log("addEquip") - // ble.addReceiveCallback((receivData,f,path,arr) => { - // console.log("收到数据了:", receivData);//数据格式:{bytes:[109,97],str:"",hexs:"FA 01"} - // if (this.item.deviceId == receivData.deviceId) { - // console.log("11111:",receivData); - - - // } - - // }); + ble.addReceiveCallback((receivData, f, path, arr) => { + if (f.macAddress) { + showLoading(these, { + text: '正在验证设备' + }); + + setTimeout(() => { + these.DeviceVerdict(f.deviceId); + }, 0); + } + + + }, pagePath); eventChannel = this.getOpenerEventChannel(); - + eventChannel.on('detailData', function(rec) { - console.log("接收到父页面的参数:",rec); - these.device=rec.data; - }); + console.log("接收到父页面的参数:", rec); + these.device = rec.data; + }); }, - + onShow: function() { - - - this.EquipMents=[]; - this.PairEquip=[]; - ble.StartSearch().catch((ex) => { + + + this.EquipMents = []; + this.PairEquip = []; + ble && ble.StartSearch().catch((ex) => { if (ex.code == 10001) { these.showOpenSetting(); } }); - - - - + + + + }, methods: { isItemLink: function(item, index) { let src = '/static/images/BLEAdd/noLink.png'; - + if (this.PairEquip && this.PairEquip.length) { if (this.PairEquip.length > 0) { let f = this.PairEquip.find(function(v) { @@ -229,7 +231,7 @@ } return src; }, - + showOpenSetting: function() { this.Status.BottomMenu.show = true; @@ -238,57 +240,121 @@ this.Status.BottomMenu.show = false; ble.showBlueSetting(false); }, - Link: function(item, index) { - this.item.deviceId=item.deviceId; - showLoading(this,{ - text: "正在连接" - }); - setTimeout(() => { - let serviceid=null; - if(item.advertisServiceUUIDs.length>0){ - serviceid=item.advertisServiceUUIDs[0]; - } - ble.LinkBlue(item.deviceId,serviceid).then((res) => { - let c = these.PairEquip.find(function(v) { - return v.deviceId == item.deviceId; - }); - if (!c) { - - these.PairEquip.push(item); + DeviceVerdict(deviceId) { //判断是否是目标设备 + if (these.device) { //从设备详情过来的,回设备详情去 + let f = ble.data.LinkedList.find(v => { + if (v.deviceId == deviceId) { + v.device = these.device; + return true; } - console.log("连接成功"); - if(these.device){//从设备详情过来的,回设备详情去 - ble.data.LinkedList.find(v=>{ - if(v.deviceId==item.deviceId){ - v.device=these.device; - return true; - } - return false; - }); - ble.updateCache(); - uni.navigateBack(); + return false; + }); + if (f.macAddress) { + + + if (f.macAddress != these.device.deviceMac) { + ble.disconnectDevice(deviceId); + updateLoading(these, { + text: "设备Mac地址错误,请重选设备连接" + }) + return; } + + hideLoading(these); + + ble.updateCache(); + uni.navigateBack(); + return true; + } else { + updateLoading(these, { + text: "等待设备上报Mac地址" + }) + return undefined; + } + } + + return false; + }, + Link: function(item) { + this.item.deviceId = item.deviceId; + showLoading(this, { + text: "正在连接:第1次" + }); + + let index = 1; + let total = 5; + + let linkCallback = (res) => { + let c = these.PairEquip.find(function(v) { + return v.deviceId == item.deviceId; + }); + if (!c) { + + these.PairEquip.push(item); + } + console.log("连接成功", these.device); + if (!these.device) { + console.log("跳转到绑定") + hideLoading(these); uni.navigateTo({ - url:"/pages/common/addBLE/LinkBle", - events:{ - + url: "/pages/common/addBLE/LinkBle", + events: { + }, success(res) { - - res.eventChannel.emit('LinkItem', item); + + res.eventChannel.emit('LinkItem', item); } }); + return; + } + console.log("验证设备") + these.DeviceVerdict(item.deviceId); + } + let execLink = () => { + return new Promise((resolve, reject) => { + + + if (index > total) { + reject({ + msg: "连接超时" + }); + return; + } + ble.LinkBlue(item.deviceId).then((res) => { + console.log("连接成功"); + + resolve(res); + }).catch((ex) => { + if (index == total) { + console.log("连接了N次都没连上"); + reject(ex); + return; + } + index++; + updateLoading(this, { + text: ex.msg + ",正在重试第" + index + "次" + }) + execLink().then(resolve).catch(reject); + + }) - }).catch((ex) => { - console.log("ex=",ex) - uni.showModal({ - content:"连接失败:"+ex.msg - }); - }).finally(()=>{ - hideLoading(this); }); - }, 0); + + } + + execLink().then((res) => { + linkCallback(res); + }).catch(ex => { + console.log("ex=", ex) + uni.showModal({ + content: "连接失败:" + ex.msg + }); + hideLoading(these); + }); + + } @@ -463,8 +529,8 @@ } .list .item .leftImg { - width: 100rpx; - height: 70rpx; + width: 60rpx; + height: 60rpx; } .list .item .centertxt { @@ -496,7 +562,7 @@ font-family: "PingFang SC"; font-size: 26rpx; font-weight: 400; - line-height: 50rpx; + line-height: 36rpx; text-align: left; } @@ -505,14 +571,14 @@ font-family: "PingFang SC"; font-size: 24rpx; font-weight: 400; - line-height: 30rpx; + line-height: 36rpx; text-align: left; } .list .item .rightIco .img { - width: 50rpx; - height: 50rpx; + width: 45rpx; + height: 45rpx; } .openBlue { diff --git a/utils/BleHelper.js b/utils/BleHelper.js index 9e44800..baa1528 100644 --- a/utils/BleHelper.js +++ b/utils/BleHelper.js @@ -1,5 +1,18 @@ import receivTool from "@/utils/BleReceive.js" var recei = null; +const serviceDic = [ //合作供应商的蓝牙主服务 + { + "serviceId": "0000AE30-0000-1000-8000-00805F9B34FB", + "writeId": "0000AE03-0000-1000-8000-00805F9B34FB", + "notifyId": "0000AE02-0000-1000-8000-00805F9B34FB" + }, + { + "serviceId": "0000FFE0-0000-1000-8000-00805F9B34FB", + "writeId": "0000FFE1-0000-1000-8000-00805F9B34FB", + "notifyId": "0000FFE2-0000-1000-8000-00805F9B34FB" + } +]; + class BleHelper { constructor() { this.StorageKey = "linkedDevices"; @@ -130,7 +143,7 @@ class BleHelper { } updateCache() { - console.log("this.StorageKey=", this.StorageKey) + // console.log("this.StorageKey=", this.StorageKey) uni.setStorageSync(this.StorageKey, this.data.LinkedList); } @@ -414,18 +427,18 @@ class BleHelper { } uni.onBluetoothAdapterStateChange((state) => { - console.log('蓝牙状态发生变化:' + JSON.stringify(state)); - if(this.data.available==state.available){ - return; - } - this.data.available = state.available; - this.data.discovering = state.discovering; - if (this.data.available && this.data - .isOpenBlue) { //蓝牙状态再次可用,重连所有设备 - this.linkAllDevices(); + // console.log('蓝牙状态发生变化:' + JSON.stringify(state)); + if (this.data.available !== state.available) { + this.data.available = state.available; + this.data.discovering = state.discovering; + if (this.data.available && this.data + .isOpenBlue) { //蓝牙状态再次可用,重连所有设备 + this.linkAllDevices(); + } } + if (!state.available) { //蓝牙状态不可用了,将所有设备标记为断开连接 this.data.LinkedList.filter((v) => { v.Linked = false; @@ -442,7 +455,7 @@ class BleHelper { if (!res.connected) { console.log("蓝牙连接已断开", res); - this.data.LinkedList.find((v) => { + let f=this.data.LinkedList.find((v) => { if (v.deviceId == res.deviceId) { v.Linked = false; v.notifyState = false; @@ -451,13 +464,15 @@ class BleHelper { return false; }); this.updateCache(); + console.log("尝试5次恢复连接"); + this.LinkBlue(res.deviceId,f.writeServiceId,f.wirteCharactId,f.notifyCharactId,5) } else { - // console.log("蓝牙连接已恢复,", res); + console.log("蓝牙连接已恢复,", res); } }); uni.onBluetoothDeviceFound((devices) => { - // ////console.log("发现新设备:" + JSON.stringify(devices)); + // console.log("发现新设备:" + JSON.stringify(devices)); this.data.searchList = this.data.searchList.concat( devices); if (this.cfg.onDeviceFound) { @@ -556,16 +571,18 @@ class BleHelper { console.log("有人订阅消息") this.cfg.receivDataCallback.forEach(( rec) => { - console.log("有人订阅消息111",) + console.log("有人订阅消息111", ) if (rec.callback) { - try{ - rec.callback(recData, f, - path, this.cfg - .receivDataCallback); - }catch(err){ - console.log("订阅消息出现异常",err); + try { + rec.callback(recData, f, + path, this.cfg + .receivDataCallback + ); + } catch (err) { + console.log("订阅消息出现异常", + err); } - + } }) } else { @@ -643,22 +660,42 @@ class BleHelper { var these = this; //开始搜索 var Search = () => { - console.log("Search........"); - return new Promise((resolve, reject) => { - uni.startBluetoothDevicesDiscovery({ - services: [], - allowDuplicatesKey: false, - success: (res) => { - //console.log('开始搜索蓝牙设备成功'); - resolve(res); + //只搜索合作供应商的服务id + let serviceIds = serviceDic.map(v => { + return v.serviceId + }); - }, - fail: (err) => { - console.log(`搜索蓝牙设备失败:`, err); + //搜索一个服务id的设备,循环调用 + let RunSearch = (serviceId) => { + return new Promise((resolve, reject) => { + uni.startBluetoothDevicesDiscovery({ + services: [serviceId], + allowDuplicatesKey: false, + success: (res) => { + //console.log('开始搜索蓝牙设备成功'); + resolve(res); - reject(this.getError(err)); - } + }, + fail: (err) => { + console.log(`搜索蓝牙设备失败:`, err); + + reject(this.getError(err)); + } + }); }); + + } + + + return new Promise((resolve, reject) => { + let promises = []; + for (let i = 0; i < serviceIds.length; i++) { + + promises.push(RunSearch(serviceIds[i])); + } + + Promise.all(promises).then(resolve).catch(reject); + }); @@ -667,13 +704,15 @@ class BleHelper { return this.OpenBlue().then((res) => { - console.log("蓝牙适配器状态", res) + // console.log("蓝牙适配器状态", res) return Search(); }); } + + //停止搜索 StopSearch() { return new Promise((resolve, reject) => { @@ -717,21 +756,24 @@ class BleHelper { //订阅消息 subScribe(deviceId, state) { + console.log("开始订阅消息"); return new Promise((resolve, reject) => { setTimeout(() => { + let c = this.data.LinkedList.find((v) => { return v.deviceId == deviceId; }); + if (state) { if (c.notifyState) { resolve(); return; } } - // console.log("c=", c); + let startSubScribe = (id, serviceId, characteristicId) => { - // console.log("serviceId=", serviceId); - // console.log("characteristicId=", characteristicId); + console.log("serviceId=", serviceId); + console.log("characteristicId=", characteristicId); let p1 = new Promise((succ, err) => { uni.notifyBLECharacteristicValueChange({ @@ -790,33 +832,36 @@ class BleHelper { if (item.properties.notify) { promies.push(startSubScribe(deviceId, serviceId, characteristicId)); + } } + }else{ + promies.push(startSubScribe(c.deviceId, c.notifyServiceid, c.notifyCharactId)); } if (promies.length > 0) { - // console.log("234324324324"); + Promise.allSettled(promies).then((results) => { - // console.log("11111"); + results.forEach((result, index) => { if (result.status === "fulfilled") { - // console.log(`操作${index + 1}成功:`, result.value); + // console.log(`操作${index + 1}成功:`, result.value); } else { - // console.log(`操作${index + 1}失败:`, result.reason - // .message); + // console.log(`操作${index + 1}失败:`, result.reason + // .message); } }); - + // console.log("订阅消息成功"); resolve(); }).catch((ex) => { - // console.log("222222"); + console.log("ex=",ex); reject(ex); }).finally(() => { // console.log("finally") }); } else { - // console.log("33333"); + console.log("没有特征需要订阅"); resolve(); } @@ -848,16 +893,44 @@ class BleHelper { v.services = res.services; } }); - this.updateCache(); + //this.updateCache(); var promises = []; + let s = null; let se = res.services.find((v) => { - return v.uuid.indexOf(targetServiceId) > -1; + + s = serviceDic.find(k => { + + return k.serviceId == v.uuid; + }) + if (s) { + return true; + } + return false; + // return v.uuid.indexOf(targetServiceId) > -1; }); + if (se) { - promises.push(this.getFeatrus(id, se.uuid, writeCharId, - notifyCharId)); + console.log("合作供应商的",s) + this.data.LinkedList.find((v) => { + if (v.deviceId == id) { + v.writeServiceId = s.serviceId; + v.wirteCharactId = s.writeId; + v.notifyServiceid = s.serviceId; + v.notifyCharactId = s.notifyId; + } + }); + this.updateCache(); + + //合作供应商的设备,直接订阅消息,不走发现特征了 + promises.push(this.subScribe(id, true)); + + // promises.push(this.getFeatrus(id, se.uuid, writeCharId, + // notifyCharId)); + + } else { + console.log("预设的蓝牙服务和特征中找不到"); for (var i = 0; i < res.services.length; i++) { let service = res.services[i]; promises.push(this.getFeatrus(id, service.uuid, @@ -876,13 +949,19 @@ class BleHelper { Promise.all(promises) .then(results => { + if (!s) { + //非指定供应商的设备,走订阅消息 + return this.subScribe(id, true); + } else { + //指定供应商的设备已经订阅过了 + return Promise.resolve(); + } - return this.subScribe(id, true); }) .then((res) => { - console.log('设备连接成功,初始化完成', res); - console.log("LinkedList=", this.data + console.log('设备连接成功,初始化完成', this.data .LinkedList); + resolve(); }) .catch(error => { @@ -928,28 +1007,47 @@ class BleHelper { deviceId: id, serviceId: serviceId, success: (res) => { + console.log("获取到特征:" + JSON.stringify(res)); - res.characteristics.forEach((v) => { - v.serviceId = serviceId; - }); + // res.characteristics.forEach((v) => { + // v.serviceId = serviceId; + // }); + //写特征 let writeChar = res.characteristics.find(char => { - return char.uuid.indexOf(writeCharId) > -1 + let fe = serviceDic.find(v => { + return v.serviceId == serviceId && v.writeId == char + .uuid; + }) + // return char.uuid.indexOf(writeCharId) > -1 + if (fe) { + return true; + } + return false; }); - if (!writeChar) { - writeChar = res.characteristics.find(char => { - return char.properties.write; - }); - } + // if (!writeChar) { + // writeChar = res.characteristics.find(char => { + // return char.properties.write; + // }); + // } //通知特征 let notiChar = res.characteristics.find(char => { - return char.uuid.indexOf(notifyCharId) > -1; + let fe = serviceDic.find(v => { + return v.serviceId == serviceId && v.notifyId == + char.uuid; + }) + // return char.uuid.indexOf(writeCharId) > -1 + if (fe) { + return true; + } + return false; + // return char.uuid.indexOf(notifyCharId) > -1; }); - if (!notiChar) { - notiChar = res.characteristics.find(char => { - return char.properties.notify; - }); - } + // if (!notiChar) { + // notiChar = res.characteristics.find(char => { + // return char.properties.notify; + // }); + // } this.data.LinkedList.find(function(v) { if (v.deviceId == id) { if (!v.Characteristics) { @@ -1001,9 +1099,11 @@ class BleHelper { } //连接某个设备 - LinkBlue(deviceId, targetServiceId, writeCharId, notifyCharId) { - + LinkBlue(deviceId, targetServiceId, writeCharId, notifyCharId, maxRetries) { + if (maxRetries === undefined) { + maxRetries = 0; // 最大重试次数 + } if (!writeCharId) { writeCharId = "xxxx"; // "FFE1"; } @@ -1030,7 +1130,7 @@ class BleHelper { var linkDevice = () => { // 添加重试次数限制 let retryCount = 0; - const maxRetries = 5; // 最大重试次数 + const connect = () => { return new Promise((resolve, reject) => { @@ -1050,7 +1150,7 @@ class BleHelper { console.log("正在连接" + deviceId); uni.createBLEConnection({ deviceId: deviceId, - timeout: 30000, + timeout: 3000, success: (info) => { console.log("新连接成功", this.data.LinkedList); this.getLinkBlue().then((arr) => { @@ -1078,8 +1178,7 @@ class BleHelper { deviceId: deviceId, mtu: 512, success: (mtu) => { - console.log("mtu设置成功", - mtu); + resolve(true); }, fail: () => { @@ -1098,7 +1197,7 @@ class BleHelper { }, fail: (ex) => { ex = this.getError(ex); - console.log("蓝牙"+deviceId+"连接失败" + JSON.stringify(ex)); + console.log("蓝牙" + deviceId + "连接失败" + JSON.stringify(ex)); // 连接超时后自动重试 if (ex.code === 10012 && retryCount < maxRetries) {