339 lines
8.8 KiB
Vue
339 lines
8.8 KiB
Vue
![]() |
<template>
|
|||
|
<page-meta>
|
|||
|
<navigation-bar :title="$tt('navBar.connectResult')" title-align="center" background-color="#F1F3F9"
|
|||
|
front-color="#000000" />
|
|||
|
</page-meta>
|
|||
|
<view class="set-wifi">
|
|||
|
<view class="img-wrap">
|
|||
|
<u-loading-icon size="70"></u-loading-icon>
|
|||
|
</view>
|
|||
|
<view class="progress">
|
|||
|
<view>
|
|||
|
<text class="num">{{progress}}</text>
|
|||
|
<text class="unit">%</text>
|
|||
|
</view>
|
|||
|
<view class="dec">{{infoText}}</view>
|
|||
|
<view class="tip">{{$tt('bleConnect.sureMobileCloseDevAndNetworkUnobstructed')}}</view>
|
|||
|
</view>
|
|||
|
<view class="btn-wrap">
|
|||
|
<button class="back" @click="handleGoBack">{{$tt('bleConnect.goBack')}}</button>
|
|||
|
<button class="restart" @click="handleRelocation">{{$tt('bleConnect.reconfigNetwork')}}</button>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
</template>
|
|||
|
|
|||
|
<script>
|
|||
|
export default {
|
|||
|
data() {
|
|||
|
return {
|
|||
|
progress: 0,
|
|||
|
deviceId: '',
|
|||
|
ssid: '',
|
|||
|
pass: '',
|
|||
|
infoText: this.$tt('bleConnect.devRegistering'),
|
|||
|
interval: null, // 定时器
|
|||
|
};
|
|||
|
},
|
|||
|
onLoad(option) {
|
|||
|
const { deviceId, ssid, pass } = option;
|
|||
|
this.deviceId = deviceId;
|
|||
|
this.ssid = ssid;
|
|||
|
this.pass = pass;
|
|||
|
},
|
|||
|
mounted() {
|
|||
|
this.simulateLoading();
|
|||
|
this.connectBlueTooth(this.deviceId);
|
|||
|
},
|
|||
|
methods: {
|
|||
|
// 模拟进度条
|
|||
|
simulateLoading() {
|
|||
|
let currentProgress = 0;
|
|||
|
this.interval = setInterval(() => {
|
|||
|
currentProgress += 10;
|
|||
|
this.progress = currentProgress;
|
|||
|
if (currentProgress >= 100) {
|
|||
|
clearInterval(this.interval);
|
|||
|
}
|
|||
|
}, 1300); // 每500毫秒更新一次进度
|
|||
|
},
|
|||
|
// 连接蓝牙设备
|
|||
|
connectBlueTooth(deviceId) {
|
|||
|
this.infoText = this.$tt('bleConnect.devBeginsToConnect');
|
|||
|
this.closeBlueTooth(deviceId, () => {
|
|||
|
setTimeout(() => {
|
|||
|
uni.createBLEConnection({
|
|||
|
deviceId: deviceId,
|
|||
|
success: (res) => {
|
|||
|
this.infoText = this.$tt('bleConnect.devConnectSuccess');
|
|||
|
this.getBlueToothService(deviceId);
|
|||
|
},
|
|||
|
fail: (res) => {
|
|||
|
clearInterval(this.interval);
|
|||
|
this.infoText = this.$tt('bleConnect.devConnectFailed') +
|
|||
|
`:${res.errMsg}`;
|
|||
|
},
|
|||
|
});
|
|||
|
}, 2000);
|
|||
|
});
|
|||
|
},
|
|||
|
// 关闭蓝牙设备(手机端可以同时连接多个蓝牙设备,但是同一个蓝牙设备不能被多次连接,所以需要在每次连接前关闭BLE连接)
|
|||
|
closeBlueTooth(deviceId, callback) {
|
|||
|
uni.closeBLEConnection({
|
|||
|
deviceId: deviceId,
|
|||
|
success: (res) => {
|
|||
|
console.log('closeBLEConnection', res);
|
|||
|
},
|
|||
|
fail: (res) => {
|
|||
|
console.log('closeBLEConnection', res);
|
|||
|
},
|
|||
|
complete: callback,
|
|||
|
});
|
|||
|
},
|
|||
|
// 获取蓝牙设备服务uuid
|
|||
|
getBlueToothService(deviceId) {
|
|||
|
this.infoText = this.$tt('bleConnect.discoveryService');
|
|||
|
setTimeout(() => {
|
|||
|
uni.getBLEDeviceServices({
|
|||
|
deviceId: deviceId,
|
|||
|
success: (res) => {
|
|||
|
const services = res.services;
|
|||
|
if (services.length <= 0) {
|
|||
|
this.infoText = this.$tt('bleConnect.mainServiceNoFound');
|
|||
|
return;
|
|||
|
}
|
|||
|
this.infoText = this.$tt('bleConnect.findServiceLists') +
|
|||
|
`:${services.length}`;
|
|||
|
for (let i = 0; i < services.length; i++) {
|
|||
|
if (services[i].isPrimary) {
|
|||
|
this.infoText = this.$tt('bleConnect.uuid') +
|
|||
|
`:${services[i].uuid}`;
|
|||
|
this.getBlueToothCharacteristics(deviceId, services[i].uuid);
|
|||
|
}
|
|||
|
}
|
|||
|
},
|
|||
|
fail: (res) => {
|
|||
|
clearInterval(this.interval);
|
|||
|
this.infoText = this.$tt('bleConnect.obtainServiceFailed') +
|
|||
|
`:${res.errMsg}`;
|
|||
|
},
|
|||
|
});
|
|||
|
}, 5000)
|
|||
|
},
|
|||
|
// 获取设备特征值
|
|||
|
getBlueToothCharacteristics(deviceId, uuid) {
|
|||
|
this.infoText = this.$tt('bleConnect.keyExchange');
|
|||
|
uni.getBLEDeviceCharacteristics({
|
|||
|
deviceId: deviceId,
|
|||
|
serviceId: uuid,
|
|||
|
success: (res) => {
|
|||
|
// 这里会获取到两个特征值,一个用来写,一个用来读
|
|||
|
const chars = res.characteristics;
|
|||
|
if (chars.length <= 0) {
|
|||
|
this.infoText = this.$tt('bleConnect.signatureCodeNoFound');
|
|||
|
return;
|
|||
|
}
|
|||
|
this.infoText = this.$tt('bleConnect.findFeatureCode') +
|
|||
|
`:${chars.length}`;
|
|||
|
if (chars.length >= 1) {
|
|||
|
chars.forEach((item) => {
|
|||
|
const prop = item.properties;
|
|||
|
if (prop.notify === true || prop.notify === true) {
|
|||
|
this.receiveData(deviceId, uuid, item.uuid);
|
|||
|
} else if (prop.write === true) {
|
|||
|
this.sendData(deviceId, uuid, item.uuid);
|
|||
|
}
|
|||
|
});
|
|||
|
}
|
|||
|
},
|
|||
|
fail: (res) => {
|
|||
|
clearInterval(this.interval);
|
|||
|
this.infoText = this.$tt('bleConnect.findFeatureCodeFailed') +
|
|||
|
`:${res.errMsg}`;
|
|||
|
}
|
|||
|
});
|
|||
|
},
|
|||
|
// 接受蓝牙设备发送过来的数据
|
|||
|
receiveData(deviceId, serviceId, charId) {
|
|||
|
const timeOut = setTimeout(() => {
|
|||
|
this.infoText = this.$tt('bleConnect.acceptDataTimeout');
|
|||
|
this.closeBlueTooth(this.deviceId);
|
|||
|
}, 13000);
|
|||
|
uni.notifyBLECharacteristicValueChange({
|
|||
|
deviceId: deviceId,
|
|||
|
serviceId: serviceId,
|
|||
|
characteristicId: charId,
|
|||
|
state: true,
|
|||
|
success: (res) => {
|
|||
|
uni.onBLECharacteristicValueChange((data) => {
|
|||
|
const resHex = this.ab2hex(data.value);
|
|||
|
let result = this.hexCharCodeToStr(resHex)
|
|||
|
result = JSON.parse(result);
|
|||
|
if (result) {
|
|||
|
this.infoText = this.$tt('bleConnect.configurationSuccess');
|
|||
|
} else {
|
|||
|
this.infoText = this.$tt('bleConnect.configurationFailed');
|
|||
|
}
|
|||
|
this.progress = 100;
|
|||
|
clearInterval(this.interval);
|
|||
|
clearTimeout(timeOut);
|
|||
|
});
|
|||
|
},
|
|||
|
fail: (res) => {
|
|||
|
clearInterval(this.interval);
|
|||
|
this.infoText = this.$tt('bleConnect.receiveDataFailed') + `:${res.errMsg}`;
|
|||
|
}
|
|||
|
});
|
|||
|
},
|
|||
|
// 向蓝牙设备发送数据
|
|||
|
sendData(deviceId, serviceId, charId) {
|
|||
|
this.infoText = this.$tt('bleConnect.sendConfigurationData');
|
|||
|
const data = {
|
|||
|
ssid: this.ssid,
|
|||
|
password: this.pass
|
|||
|
};
|
|||
|
const buffer = this.toBuffer(data);
|
|||
|
setTimeout(() => {
|
|||
|
uni.writeBLECharacteristicValue({
|
|||
|
value: buffer,
|
|||
|
deviceId: deviceId,
|
|||
|
serviceId: serviceId,
|
|||
|
characteristicId: charId,
|
|||
|
success: (res) => {
|
|||
|
this.infoText = this.$tt('bleConnect.sendSuccess');
|
|||
|
},
|
|||
|
fail: (res) => {
|
|||
|
clearInterval(this.interval);
|
|||
|
this.infoText = this.$tt('bleConnect.sendFailed') + `:${res.errMsg}`;
|
|||
|
},
|
|||
|
});
|
|||
|
}, 1000);
|
|||
|
},
|
|||
|
toBuffer(data) {
|
|||
|
const dataStr = JSON.stringify(data);
|
|||
|
const buffer = new ArrayBuffer(dataStr.length);
|
|||
|
let bufView = new Uint8Array(buffer);
|
|||
|
for (var i = 0; i < dataStr.length; i++) {
|
|||
|
bufView[i] = dataStr.charCodeAt(i);
|
|||
|
}
|
|||
|
return buffer;
|
|||
|
},
|
|||
|
// ArrayBuffer转16进度字符串
|
|||
|
ab2hex(buffer) {
|
|||
|
const hexArr = Array.prototype.map.call(
|
|||
|
new Uint8Array(buffer),
|
|||
|
function(bit) {
|
|||
|
return ('00' + bit.toString(16)).slice(-2)
|
|||
|
}
|
|||
|
)
|
|||
|
return hexArr.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) {
|
|||
|
return "";
|
|||
|
}
|
|||
|
var curCharCode;
|
|||
|
var resultStr = [];
|
|||
|
for (var i = 0; i < len; i = i + 2) {
|
|||
|
curCharCode = parseInt(rawStr.substr(i, 2), 16);
|
|||
|
resultStr.push(String.fromCharCode(curCharCode));
|
|||
|
}
|
|||
|
return resultStr.join("");
|
|||
|
},
|
|||
|
// 返回
|
|||
|
handleGoBack() {
|
|||
|
this.closeBlueTooth(this.deviceId);
|
|||
|
uni.switchTab({
|
|||
|
url: '/pages/tabBar/home/index'
|
|||
|
});
|
|||
|
},
|
|||
|
// 重新配网
|
|||
|
handleRelocation() {
|
|||
|
this.closeBlueTooth(this.deviceId);
|
|||
|
uni.reLaunch({
|
|||
|
url: `/pagesB/home/device/add/bleConnect/index`
|
|||
|
});
|
|||
|
}
|
|||
|
},
|
|||
|
}
|
|||
|
</script>
|
|||
|
|
|||
|
<style lang="scss">
|
|||
|
page {
|
|||
|
height: 100%;
|
|||
|
background: $uni-bg-color-grey;
|
|||
|
}
|
|||
|
</style>
|
|||
|
<style lang="scss" scoped>
|
|||
|
.set-wifi {
|
|||
|
.img-wrap {
|
|||
|
padding: 160rpx 0;
|
|||
|
text-align: center;
|
|||
|
}
|
|||
|
|
|||
|
.progress {
|
|||
|
text-align: center;
|
|||
|
padding: 0 20rpx;
|
|||
|
|
|||
|
.num {
|
|||
|
font-size: 80rpx;
|
|||
|
line-height: 100rpx;
|
|||
|
}
|
|||
|
|
|||
|
.unit {
|
|||
|
margin-left: 10rpx;
|
|||
|
}
|
|||
|
|
|||
|
.dec {
|
|||
|
font-size: 28rpx;
|
|||
|
line-height: 48rpx;
|
|||
|
color: #7e7e7e;
|
|||
|
}
|
|||
|
|
|||
|
.tip {
|
|||
|
margin-top: 20rpx;
|
|||
|
font-size: 32rpx;
|
|||
|
line-height: 52rpx;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
.btn-wrap {
|
|||
|
position: fixed;
|
|||
|
left: 80rpx;
|
|||
|
right: 80rpx;
|
|||
|
bottom: 160rpx;
|
|||
|
|
|||
|
.restart {
|
|||
|
display: flex;
|
|||
|
justify-content: center;
|
|||
|
align-items: center;
|
|||
|
height: 98rpx;
|
|||
|
border-radius: 18rpx;
|
|||
|
color: #486FF2;
|
|||
|
background-color: #fff;
|
|||
|
font-weight: 400;
|
|||
|
font-size: 32rpx;
|
|||
|
letter-spacing: 0.6rpx;
|
|||
|
border: 2rpx solid #486FF2;
|
|||
|
margin-top: 36rpx;
|
|||
|
}
|
|||
|
|
|||
|
.back {
|
|||
|
display: flex;
|
|||
|
justify-content: center;
|
|||
|
align-items: center;
|
|||
|
height: 98rpx;
|
|||
|
border-radius: 18rpx;
|
|||
|
color: #fff;
|
|||
|
background-color: #486FF2;
|
|||
|
font-weight: 400;
|
|||
|
font-size: 32rpx;
|
|||
|
letter-spacing: 0.6rpx;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
</style>
|