634 lines
17 KiB
Vue
634 lines
17 KiB
Vue
<template>
|
||
<!-- 已废弃 -->
|
||
<view class="qualitySpringback">
|
||
<headers :showBack="true">
|
||
<view class="headerName">
|
||
回弹仪
|
||
</view>
|
||
</headers>
|
||
<view class="content">
|
||
<view class="chart_wrap">
|
||
<view class="title" style="color: #488DEC;">·测量情况·</view>
|
||
<view class="flex">
|
||
<view class="chart">
|
||
<image class="chart_img" src="../../../static/measure1.png"></image>
|
||
<view class="chart_text">
|
||
<view class="value">{{totalSurveyNum}}</view>
|
||
<view class="name">全部测量<br />构件</view>
|
||
</view>
|
||
</view>
|
||
<view class="chart">
|
||
<image class="chart_img" src="../../../static/measure2.png" style="height: 257rpx;"></image>
|
||
<view class="chart_text">
|
||
<view class="value">{{abnormalSurveyNum}}</view>
|
||
<view class="name">不合格<br />构件</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="title" style="color: #2A2B5B; opacity: 0.4;">·设备列表·</view>
|
||
|
||
<input type="text" v-model="sendData" placeholder="" style="border:1px solid red;padding: 10rpx 20rpx;margin-bottom: 20rpx;" />
|
||
<button type="default" @click="writeBLECharacteristicValue()">发送数据</button>
|
||
<view class="item" v-if="bluetooth" v-for="(item,index) in bluetooth" @click="createBLEConnection(item.deviceId,index)">
|
||
<view class="item_name">蓝牙编码:<text class="value">{{item.name?item.name:item.deviceId}}</text></view>
|
||
<view class="item_name">信号强度:<text class="value">{{item.RSSI}}</text></view>
|
||
<view class="item_name">边接状态:<text class="value">{{isLink[index]==0?'未连接':isLink[index]==1?'连接中...':isLink[index]==2?'已连接':
|
||
isLink[index]==3?'连接失败':isLink[index]==4?'已断开':''
|
||
}}</text></view>
|
||
</view>
|
||
</view>
|
||
<view class="start_wrap">
|
||
<view class="start_btn" @click="measureBtn">开始测量</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import {
|
||
getBlooth,
|
||
createBLE,
|
||
DeviceFound,
|
||
closeBle,
|
||
writeBLE
|
||
} from '@/utils/socket/BLEConn.js';
|
||
export default {
|
||
data() {
|
||
return {
|
||
projectDetail: '',
|
||
bluetooth: [],
|
||
isLink: [],
|
||
// 调试数据
|
||
serverList: [],
|
||
characteristics: [],
|
||
readCode: '',
|
||
readCodeMsg: '',
|
||
serviceId: '',
|
||
characteristicId: '',
|
||
value: '0102',
|
||
returnMessage: '',
|
||
macAddress: "",
|
||
macValue: '',
|
||
totalSurveyNum: 0,
|
||
abnormalSurveyNum: 0,
|
||
sendData:'$RDI?#\r\n'
|
||
}
|
||
},
|
||
onLoad() {
|
||
this.projectDetail = JSON.parse(uni.getStorageSync('projectDetail'));
|
||
//在页面加载时候初始化蓝牙适配器
|
||
uni.openBluetoothAdapter({
|
||
success: (e) => {
|
||
console.log('初始化蓝牙成功:' + e.errMsg);
|
||
// 初始化完毕开始搜索
|
||
this.startBluetoothDeviceDiscovery()
|
||
},
|
||
});
|
||
this.getDevTotal();
|
||
},
|
||
methods: {
|
||
// 搜索蓝牙列表
|
||
async getList() {
|
||
uni.showLoading({
|
||
title: '搜索蓝牙中...',
|
||
icon: 'none'
|
||
})
|
||
var flag = false // 标记是否进入了getBLooth
|
||
await getBlooth().then(res => {
|
||
console.log(res)
|
||
flag = true
|
||
console.log('第' + times + '次')
|
||
if (res.devices.length == 0 && times <= 3) {
|
||
times++
|
||
this.getList()
|
||
} else {
|
||
this.bluetooth = res.devices
|
||
console.log('蓝牙设备列表')
|
||
console.log(this.bluetooth)
|
||
uni.hideLoading()
|
||
times = 1
|
||
// // 打开弹框
|
||
// this.$refs.popup.open()
|
||
// this.scanBLE = true
|
||
}
|
||
}).catch(err => {
|
||
flag = false
|
||
times = 1
|
||
})
|
||
console.log(flag)
|
||
if (!flag) {
|
||
uni.hideLoading()
|
||
uni.showToast({
|
||
title: '请先开启手机蓝牙',
|
||
icon: 'none',
|
||
mask: true
|
||
})
|
||
console.log('没有进入getBlooth')
|
||
}
|
||
},
|
||
getDevTotal() {
|
||
let that = this;
|
||
this.sendRequest({
|
||
url: 'xmgl/massReboundSurveyArea/selectProjectCount',
|
||
method: 'post',
|
||
data: {
|
||
projectSn: that.projectDetail.projectSn
|
||
},
|
||
success: res => {
|
||
that.totalSurveyNum = res.result.totalSurveyNum;
|
||
that.abnormalSurveyNum = res.result.abnormalSurveyNum;
|
||
}
|
||
})
|
||
},
|
||
|
||
|
||
|
||
startBluetoothDeviceDiscovery() {
|
||
//在页面显示的时候判断是都已经初始化完成蓝牙适配器若成功,则开始查找设备
|
||
uni.startBluetoothDevicesDiscovery({
|
||
success: res => {
|
||
console.log(res)
|
||
this.onBluetoothDeviceFound();
|
||
},
|
||
fail: res => {
|
||
uni.showToast({
|
||
icon: "none",
|
||
title: "查找设备失败!",
|
||
duration: 3000
|
||
})
|
||
}
|
||
});
|
||
},
|
||
/**
|
||
* 停止搜索蓝牙设备
|
||
*/
|
||
stopBluetoothDevicesDiscovery() {
|
||
uni.stopBluetoothDevicesDiscovery({
|
||
success: e => {
|
||
console.log('停止搜索蓝牙设备:' + e.errMsg);
|
||
},
|
||
fail: e => {
|
||
console.log('停止搜索蓝牙设备失败,错误码:' + e.errCode);
|
||
}
|
||
});
|
||
},
|
||
/**
|
||
* 发现外围设备
|
||
*/
|
||
onBluetoothDeviceFound() {
|
||
console.log("监听寻找新设备");
|
||
// this.getBluetoothDevices();
|
||
uni.onBluetoothDeviceFound(devices => {
|
||
console.log('开始监听寻找到新设备的事件');
|
||
console.log(devices)
|
||
this.getBluetoothDevices();
|
||
});
|
||
},
|
||
/**
|
||
* 获取在蓝牙模块生效期间所有已发现的蓝牙设备。包括已经和本机处于连接状态的设备。
|
||
*/
|
||
getBluetoothDevices() {
|
||
// console.log("获取蓝牙设备");
|
||
uni.getBluetoothDevices({
|
||
success: res => {
|
||
// console.log('获取蓝牙设备成功:' + res);
|
||
this.bluetooth = res.devices;
|
||
console.log(this.bluetooth)
|
||
this.bluetooth.forEach((item) => {
|
||
this.isLink.push(0)
|
||
})
|
||
// this.stopBluetoothDevicesDiscovery();
|
||
}
|
||
});
|
||
},
|
||
//断开蓝牙连接
|
||
closeBLEConnection(deviceId, index) {
|
||
uni.closeBLEConnection({
|
||
deviceId: deviceId,
|
||
success: res => {
|
||
this.isLink.splice(index, 1, 4)
|
||
console.log(res)
|
||
}
|
||
})
|
||
},
|
||
// 连接蓝牙设备
|
||
createBLEConnection(deviceId, index) {
|
||
this.deviceId = deviceId;
|
||
if (this.isLink[index] == 2) {
|
||
return;
|
||
}
|
||
this.isLink.splice(index, 1, 1)
|
||
uni.createBLEConnection({
|
||
deviceId: this.deviceId,
|
||
success: res => {
|
||
|
||
|
||
this.isLink.splice(index, 1, 2)
|
||
this.stopBluetoothDevicesDiscovery();
|
||
this.getBLEDeviceServices(this.deviceId, index);
|
||
},
|
||
fail: res => {
|
||
this.isLink.splice(index, 1, 3)
|
||
console.log(res)
|
||
}
|
||
})
|
||
},
|
||
//获取蓝牙设备所有服务(service)。
|
||
getBLEDeviceServices(deviceId, index) {
|
||
setTimeout(() => {
|
||
uni.getBLEDeviceServices({
|
||
// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
|
||
deviceId: deviceId,
|
||
success: (res) => {
|
||
console.log('所有的服务数据', res)
|
||
this.serverList = res.services
|
||
|
||
this.serviceId = this.serverList[this.serverList.length - 1].uuid;
|
||
// console.log('serverId:', this.serviceId)
|
||
this.getBLEDeviceCharacteristics(this.deviceId)
|
||
|
||
// res.services.forEach((item) => {
|
||
// if (item.uuid.indexOf("FFE0") != -1) {
|
||
// this.serviceId = item.uuid;
|
||
// console.log('serverId:', this.serviceId)
|
||
// this.getBLEDeviceCharacteristics(this.deviceId)
|
||
// return
|
||
// }
|
||
// })
|
||
}
|
||
})
|
||
}, 1000)
|
||
|
||
},
|
||
// 获取蓝牙特征值
|
||
getBLEDeviceCharacteristics(deviceId) {
|
||
console.log("获取蓝牙特征值");
|
||
setTimeout(() => {
|
||
uni.getBLEDeviceCharacteristics({
|
||
// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
|
||
deviceId: deviceId,
|
||
// 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
|
||
serviceId: this.serviceId,
|
||
success: (res) => {
|
||
console.log('蓝牙特征值数据', res)
|
||
this.characteristics = res.characteristics
|
||
// this.characteristicId = this.characteristics[0].uuid;
|
||
// console.log('characteristicId:', this.characteristicId)
|
||
// this.notifyBLECharacteristicValueChange(this.deviceId)
|
||
res.characteristics.forEach((item) => {
|
||
if (item.properties.write&&item.properties.notify) {
|
||
this.characteristicId = item.uuid;
|
||
console.log('characteristicId:', this.characteristicId)
|
||
this.notifyBLECharacteristicValueChange(this.deviceId)
|
||
}
|
||
})
|
||
},
|
||
fail: (res) => {
|
||
console.log(res)
|
||
}
|
||
})
|
||
}, 2000)
|
||
},
|
||
// 启用 notify 功能
|
||
notifyBLECharacteristicValueChange(deviceId) {
|
||
|
||
uni.notifyBLECharacteristicValueChange({
|
||
state: true, // 启用 notify 功能
|
||
// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
|
||
deviceId: deviceId,
|
||
// 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
|
||
serviceId: this.serviceId,
|
||
// 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取
|
||
characteristicId: this.characteristicId,
|
||
success: (res) => {
|
||
console.log('启用 notify 功能 成功', res)
|
||
// setTimeout(()=>{
|
||
this.onBLECharacteristicValueChange(this.deviceId);
|
||
// },1000)
|
||
|
||
|
||
// this.readBLECharacteristicValue(this.deviceId)
|
||
},
|
||
fail: (res) => {
|
||
console.log('启用 notify 功能 失败', res)
|
||
}
|
||
})
|
||
},
|
||
ab2hex(buffer) {
|
||
const hexArr = Array.prototype.map.call(
|
||
new Uint8Array(buffer),
|
||
function(bit) {
|
||
return ('00' + bit.toString(16)).slice(-2)
|
||
}
|
||
)
|
||
return hexArr.join('')
|
||
},
|
||
|
||
// 监听低功耗蓝牙设备的特征值变化
|
||
onBLECharacteristicValueChange(deviceId) {
|
||
console.log('监听低功耗蓝牙设备的特征值变化')
|
||
uni.onBLECharacteristicValueChange((res) => {
|
||
// console.log(`characteristic ${res.characteristicId} has changed, now is ${res.value}`)
|
||
|
||
console.log('设备返回的数据')
|
||
console.log(res)
|
||
// console.log(this.ab2hex(res.value))
|
||
// for (var i = 0; i < res.value.length; i++) {
|
||
|
||
// console.log(this.hexCharCodeToStr(this.ab2hex(res.value)))
|
||
|
||
// }
|
||
|
||
// let buffer = res.value
|
||
// var binary = '';
|
||
// var bytes = new Uint8Array(buffer);
|
||
|
||
// var len = bytes.byteLength;
|
||
// for (var i = 0; i < len; i++) {
|
||
// binary += String.fromCharCode(bytes[i]);
|
||
// }
|
||
// console.log('binary',binary)
|
||
|
||
// this.macAddress = res.deviceId;
|
||
// this.macValue = this.ab2hex(res.value);
|
||
// this.readBLECharacteristicValue()
|
||
})
|
||
},
|
||
// 读取设备二进制数据
|
||
readBLECharacteristicValue() {
|
||
console.log('进入读取');
|
||
// setTimeout(()=>{
|
||
uni.readBLECharacteristicValue({
|
||
// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
|
||
deviceId: this.deviceId,
|
||
// 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
|
||
serviceId: this.serviceId,
|
||
// 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取
|
||
characteristicId: this.characteristics[4].uuid,
|
||
success: (res) => {
|
||
console.log('readBLECharacteristicValue:', res)
|
||
this.readCode = res.errCode;
|
||
this.readCodeMsg = res.errMsg;
|
||
// this.onBLECharacteristicValueChange(this.deviceId);
|
||
},
|
||
fail: (res) => {
|
||
console.log('readBLECharacteristicValue:', res)
|
||
this.readCode = res.errCode;
|
||
this.readCodeMsg = res.errMsg;
|
||
// this.onBLECharacteristicValueChange(this.deviceId);
|
||
}
|
||
})
|
||
// },200)
|
||
|
||
},
|
||
|
||
string2buffer(str) {
|
||
// 首先将字符串转为16进制
|
||
let val = ""
|
||
for (let i = 0; i < str.length; i++) {
|
||
if (val === '') {
|
||
val = str.charCodeAt(i).toString(16)
|
||
} else {
|
||
val += ',' + str.charCodeAt(i).toString(16)
|
||
}
|
||
}
|
||
console.log('val',val)
|
||
// 将16进制转化为ArrayBuffer
|
||
return new Uint8Array(val.match(/[\da-f]{2}/gi).map(function (h) {
|
||
return parseInt(h, 16)
|
||
})).buffer
|
||
},
|
||
str2Bytes(str)
|
||
{
|
||
var pos = 0;
|
||
str = str.replace(/\s*/g,"");
|
||
var len = str.length;
|
||
if(len %2 != 0)
|
||
{
|
||
return null;
|
||
}
|
||
len /= 2;
|
||
var hexA = new Array();
|
||
for(var i=0; i<len; i++)
|
||
{
|
||
var s = str.substr(pos, 2);
|
||
var v = parseInt(s, 16);
|
||
hexA.push(v);
|
||
pos += 2;
|
||
}
|
||
return hexA;
|
||
},
|
||
// 发送二进制数据
|
||
writeBLECharacteristicValue() {
|
||
var data=this.sendData
|
||
// var buffer=this.str2Bytes(data)
|
||
// console.log('buffer',buffer)
|
||
// var data='24524449DF230D0A'
|
||
// var data ='10010001010010010001000100100111011111001000110000111000000000'
|
||
// var data16 = this.strToHexCharCode(data)+this.strToHexCharCode('#')+'0D0A'
|
||
var buffer = new ArrayBuffer(data.length)
|
||
var dataView = new DataView(buffer)
|
||
|
||
// const buffer = new ArrayBuffer(1)
|
||
// const dataView = new DataView(buffer)
|
||
// dataView.setUint8(0, 0)
|
||
|
||
for (var j = 0; j < data.length; j++) {
|
||
dataView.setUint8(j, data[j]);
|
||
// console.log('aaa',data[j],j)
|
||
|
||
}
|
||
// debugger
|
||
// console.log(dataView.getUint16(1))
|
||
// for (let i in data) {
|
||
// dataView.setUint8(i, data[i].charCodeAt() | 0);
|
||
// }
|
||
// console.log('buffer', dataView)
|
||
uni.writeBLECharacteristicValue({
|
||
// 这里的 deviceId 需要在 getBluetoothDevices 或 onBluetoothDeviceFound 接口中获取
|
||
deviceId: this.deviceId,
|
||
// 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
|
||
serviceId: this.serviceId,
|
||
// 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取
|
||
characteristicId: this.characteristicId,
|
||
// characteristicId: this.characteristics[3].uuid,
|
||
// 这里的value是ArrayBuffer类型
|
||
value: buffer,
|
||
success: (res) => {
|
||
this.returnMessage = res.errMsg;
|
||
console.log('发送数据 success', res)
|
||
// setTimeout(()=>{
|
||
// this.readBLECharacteristicValue()
|
||
// },2000)
|
||
|
||
},
|
||
fail: (res) => {
|
||
this.returnMessage = res.errMsg;
|
||
console.log('发送数据 fail', res)
|
||
}
|
||
})
|
||
},
|
||
// 字符串和16进制的互相转换
|
||
strToHexCharCode(str) {
|
||
if (str === "")
|
||
return "";
|
||
var hexCharCode = [];
|
||
hexCharCode.push("0x");
|
||
for (var i = 0; i < str.length; i++) {
|
||
hexCharCode.push((str.charCodeAt(i)).toString(16));
|
||
}
|
||
return hexCharCode.join("");
|
||
},
|
||
// 16进制转字符串
|
||
hexCharCodeToStr(hexCharCodeStr) {
|
||
var trimedStr = hexCharCodeStr.trim();
|
||
var rawStr =
|
||
trimedStr.substr(0, 2).toLowerCase() === "0x" ?
|
||
trimedStr.substr(2) :
|
||
trimedStr;
|
||
var len = rawStr.length;
|
||
if (len % 2 !== 0) {
|
||
alert("Illegal Format ASCII Code!");
|
||
return "";
|
||
}
|
||
var curCharCode;
|
||
var resultStr = [];
|
||
for (var i = 0; i < len; i = i + 2) {
|
||
curCharCode = parseInt(rawStr.substr(i, 2), 16); // ASCII Code Value
|
||
resultStr.push(String.fromCharCode(curCharCode));
|
||
}
|
||
return resultStr.join("");
|
||
},
|
||
|
||
measureBtn() {
|
||
uni.navigateTo({
|
||
url: './selectPage'
|
||
});
|
||
this.stopBluetoothDevicesDiscovery();
|
||
},
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
.flex {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-around;
|
||
}
|
||
|
||
.flex2 {
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.flex3 {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
}
|
||
|
||
.title {
|
||
text-align: center;
|
||
font-size: 30rpx;
|
||
letter-spacing: 1.4px;
|
||
line-height: 21px;
|
||
margin-bottom: 16rpx;
|
||
}
|
||
|
||
.content {
|
||
padding: 20rpx 30rpx;
|
||
box-sizing: border-box;
|
||
width: 100%;
|
||
}
|
||
|
||
.chart_wrap {
|
||
width: 100%;
|
||
box-shadow: 0 4rpx 20rpx 0 rgba(212, 220, 236, 0.65);
|
||
border-radius: 16rpx;
|
||
background-color: rgba(251, 251, 255, 1);
|
||
box-sizing: border-box;
|
||
padding: 20rpx 0 40rpx;
|
||
margin-top: 20rpx;
|
||
margin-bottom: 40rpx;
|
||
}
|
||
|
||
.chart {
|
||
position: relative;
|
||
width: 266rpx;
|
||
height: 269rpx;
|
||
}
|
||
|
||
|
||
.chart_img {
|
||
width: 266rpx;
|
||
height: 269rpx;
|
||
position: absolute;
|
||
top: 0;
|
||
right: 0;
|
||
left: 0;
|
||
bottom: 0;
|
||
z-index: 2;
|
||
}
|
||
|
||
.chart_text {
|
||
z-index: 999;
|
||
text-align: center;
|
||
position: relative;
|
||
top: 50%;
|
||
/*偏移*/
|
||
margin-top: -38px;
|
||
}
|
||
|
||
.chart_text .value {
|
||
font-size: 60rpx;
|
||
font-weight: 700;
|
||
}
|
||
|
||
.chart_text .name {
|
||
color: #54547C;
|
||
font-size: 30rpx;
|
||
line-height: 36rpx;
|
||
}
|
||
|
||
.item {
|
||
line-height: 52rpx;
|
||
margin-top: 30rpx;
|
||
box-shadow: 0 4rpx 20rpx 0 rgba(212, 220, 236, 0.65);
|
||
border-radius: 10rpx;
|
||
padding: 20rpx 30rpx;
|
||
font-size: 28rpx;
|
||
}
|
||
|
||
.item_name {
|
||
color: rgba(42, 43, 91, 0.6);
|
||
}
|
||
|
||
.item .value {
|
||
color: #2A2B5B;
|
||
}
|
||
|
||
.start_wrap {
|
||
margin-top: 80rpx;
|
||
margin-bottom: 80rpx;
|
||
}
|
||
|
||
.start_btn {
|
||
text-align: center;
|
||
pos-bottom: 40rpx;
|
||
line-height: 90rpx;
|
||
width: 60%;
|
||
margin: 0 auto;
|
||
background-color: rgba(72, 141, 236, 1);
|
||
color: #fff;
|
||
border-radius: 70rpx;
|
||
box-shadow: 0 4rpx 4px 0 rgba(43, 141, 243, 0.42);
|
||
|
||
}
|
||
|
||
.start_btn:active {
|
||
background-color: rgba(65, 129, 254, 0.8);
|
||
}
|
||
</style>
|