|
@@ -0,0 +1,479 @@
|
|
|
+<template>
|
|
|
+ <view class="box">
|
|
|
+ <view class="content">
|
|
|
+ <view>
|
|
|
+ <label class="radio" @click="isWifi=true">
|
|
|
+ <radio value="wifi" :checked="isWifi" />wifi
|
|
|
+ </label>
|
|
|
+ <label class="radio" @click="isWifi=false">
|
|
|
+ <radio value="4G" :checked="!isWifi" />4G
|
|
|
+ </label>
|
|
|
+ </view>
|
|
|
+ <view class="input-row">
|
|
|
+ <text>wifi名称:</text>
|
|
|
+ <input class="edittext" v-model="wifiName" />
|
|
|
+ </view>
|
|
|
+ <view class="input-row">
|
|
|
+ <text>wifi密码:</text>
|
|
|
+ <input class="edittext" v-model="wifiPwd" />
|
|
|
+ </view>
|
|
|
+ <view style="margin-top: 10rpx;">
|
|
|
+ <button @click="connectBle()">下一步</button>
|
|
|
+ </view>
|
|
|
+ <text style="margin-top: 10rpx;">{{errorText}}</text>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view class="loadView" v-if="showLoading">
|
|
|
+ <image class="rotateAnim" src="../../static/loading.svg"></image>
|
|
|
+ <text style="margin-left: 10rpx;">{{loadingText}}</text>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ </view>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+ const server_uuid = "0000FFE5-0000-1000-8000-00805F9B34FB";
|
|
|
+ //const baidu_server_uuid = "00001111-0000-1000-8000-00805f9b34fb";
|
|
|
+ export default {
|
|
|
+
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ deviceName: "",
|
|
|
+ deviceId: "",
|
|
|
+ isWifi: true,
|
|
|
+ wifiName: "JackieHou_Mac",
|
|
|
+ wifiPwd: "1234567890",
|
|
|
+ connected: false,
|
|
|
+ connecting: false,
|
|
|
+ iccid: '',
|
|
|
+ withoutWifiInterval: undefined,
|
|
|
+ configTimeout: undefined,
|
|
|
+ showLoading: false, //是否显示loading
|
|
|
+ loadingText: '正在连接设备', //load框的文字提示
|
|
|
+ errorText: "",
|
|
|
+
|
|
|
+ }
|
|
|
+ },
|
|
|
+ onLoad(option) {
|
|
|
+ this.deviceName = option.name;
|
|
|
+ this.deviceId = option.mac
|
|
|
+ console.log(`name = ${this.deviceName},mac = ${this.deviceId}`);
|
|
|
+ //this.getWifiBuffer()
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ test2() {
|
|
|
+ function doSomething(str) {
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
+ setTimeout(() => {
|
|
|
+ resolve(str.toUpperCase());
|
|
|
+ }, 2000)
|
|
|
+
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ let strs = ['aaaa', 'bbbbb', 'ccccc', 'ddddd', 'eeeeeee'];
|
|
|
+ let promiseList = strs.map(doSomething);
|
|
|
+ let time = Date.now();
|
|
|
+ (async () => {
|
|
|
+ let res = await Promise.allSettled(promiseList)
|
|
|
+ console.log(Date.now() - time);
|
|
|
+ console.log(res);
|
|
|
+ })();
|
|
|
+ },
|
|
|
+ test() {
|
|
|
+ let buffer = Buffer.from(
|
|
|
+ "1abcdefghijklmnopqrstuvwxyz2abcdefghijklmnopqrstuvwxyz3abcdefghijklmnopqrstuvwxyz")
|
|
|
+ console.log(buffer.length);
|
|
|
+ let count = Math.ceil(buffer.length / 20)
|
|
|
+ let buffers = []
|
|
|
+ for (var i = 0; i < count; i++) {
|
|
|
+ let size = Math.min(20, buffer.length - i * 20)
|
|
|
+ console.log(size);
|
|
|
+ let buf = buffer.slice(i * 20, size + i * 20)
|
|
|
+ buffers.push(buf)
|
|
|
+ }
|
|
|
+ for (let b of buffers) {
|
|
|
+ console.log(b);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ connectBle() {
|
|
|
+ let that = this
|
|
|
+ if (!that.connecting && !that.connected) {
|
|
|
+ console.log('创建连接')
|
|
|
+ clearInterval(that.withoutWifiInterval)
|
|
|
+ clearTimeout(that.configTimeout)
|
|
|
+ that.connecting = true
|
|
|
+ that.showLoading = true
|
|
|
+ that.loadingText = '正在连接设备'
|
|
|
+ that.errorText = ""
|
|
|
+ uni.createBLEConnection({
|
|
|
+ // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
|
|
|
+ deviceId: that.deviceId,
|
|
|
+ success(res) {
|
|
|
+ that.connected = true
|
|
|
+ console.log('连接成功')
|
|
|
+ console.log(res)
|
|
|
+ that.connecting = false
|
|
|
+ that.loadingText = '正在获取服务'
|
|
|
+ //获取服务
|
|
|
+ that.getBleDeviceServices()
|
|
|
+ },
|
|
|
+ fail(err) {
|
|
|
+ console.log('连接失败')
|
|
|
+ console.log(err)
|
|
|
+ that.connecting = false
|
|
|
+ that.showLoading = false
|
|
|
+ that.errorText = '连接失败!请将手机靠近设备'
|
|
|
+ uni.showToast({
|
|
|
+ title: '连接失败!请将手机靠近设备',
|
|
|
+ icon: 'none',
|
|
|
+ duration: 2000
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ },
|
|
|
+ listenBleConnectState() {
|
|
|
+ uni.onBLEConnectionStateChange(function(res) {
|
|
|
+ // 该方法回调中可以用于处理连接意外断开等异常情况
|
|
|
+ console.log(`device ${res.deviceId} state has changed, connected: ${res.connected}`)
|
|
|
+ that.connected = res.connected
|
|
|
+ if (res.connected === false) {
|
|
|
+ clearInterval(that.withoutWifiInterval)
|
|
|
+ clearTimeout(that.configTimeout)
|
|
|
+ that.showLoading = false
|
|
|
+ that.errorText = '连接已断开,请重试!'
|
|
|
+ uni.showToast({
|
|
|
+ title: '连接已断开,请重试!',
|
|
|
+ icon: 'none',
|
|
|
+ duration: 2000
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ getBleDeviceServices() {
|
|
|
+ let that = this
|
|
|
+ setTimeout(() => {
|
|
|
+ uni.getBLEDeviceServices({
|
|
|
+ deviceId: that.deviceId,
|
|
|
+ success(res) {
|
|
|
+ console.log('获取服务成功')
|
|
|
+ console.log(res)
|
|
|
+ for (let service of res.services) {
|
|
|
+ console.log(service)
|
|
|
+ if (server_uuid.toUpperCase() == service.uuid.toUpperCase()) {
|
|
|
+ that.loadingText = '正在获取特征'
|
|
|
+ //获取特征
|
|
|
+ that.getBLEDeviceCharacteristics(server_uuid)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ fail(err) {
|
|
|
+ console.log('获取服务失败')
|
|
|
+ console.log(err);
|
|
|
+ that.closeBLEConnection()
|
|
|
+ that.errorText = '获取服务失败'
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }, 1000)
|
|
|
+
|
|
|
+ },
|
|
|
+ getBLEDeviceCharacteristics(uuid) {
|
|
|
+ console.log("获取特征");
|
|
|
+ let that = this
|
|
|
+ //setTimeout(() => {
|
|
|
+ uni.getBLEDeviceCharacteristics({
|
|
|
+ deviceId: that.deviceId,
|
|
|
+ serviceId: uuid,
|
|
|
+ success(res) {
|
|
|
+ console.log('获取特征成功');
|
|
|
+ console.log(res);
|
|
|
+ //todo直接写入数据
|
|
|
+ //that.sendCongifComm(res.characteristics[0].uuid)
|
|
|
+ that.notifyBLECharacteristicValueChange(res.characteristics[0].uuid)
|
|
|
+ },
|
|
|
+ fail(err) {
|
|
|
+ console.log('获取特征失败');
|
|
|
+ console.log(err);
|
|
|
+ that.closeBLEConnection()
|
|
|
+ that.errorText = '获取特征失败'
|
|
|
+ }
|
|
|
+ })
|
|
|
+ //}, 1000)
|
|
|
+ },
|
|
|
+ notifyBLECharacteristicValueChange(characteristicId) {
|
|
|
+ let that = this
|
|
|
+ setTimeout(() => {
|
|
|
+ that.loadingText = '正在配网'
|
|
|
+
|
|
|
+ //设置一个超时配网的时间
|
|
|
+ that.configTimeout = setTimeout(() => {
|
|
|
+ that.closeBLEConnection()
|
|
|
+ uni.showToast({
|
|
|
+ title: "配网超时,请重试",
|
|
|
+ icon: 'none',
|
|
|
+ duration: 1000
|
|
|
+ })
|
|
|
+ that.errorText = '配网超时,请重试'
|
|
|
+ }, 20 * 1000)
|
|
|
+
|
|
|
+ uni.notifyBLECharacteristicValueChange({
|
|
|
+ state: true,
|
|
|
+ deviceId: that.deviceId,
|
|
|
+ serviceId: server_uuid,
|
|
|
+ characteristicId: characteristicId,
|
|
|
+ }).then(res => {
|
|
|
+ console.log("notify成功");
|
|
|
+ console.log(res);
|
|
|
+ }).catch(err => {
|
|
|
+ console.log("notify失败");
|
|
|
+ console.log(err);
|
|
|
+ })
|
|
|
+
|
|
|
+ //监听设备发送过来的数据
|
|
|
+ uni.onBLECharacteristicValueChange(function(res) {
|
|
|
+ //console.warn('收到设备发送过来的数据');
|
|
|
+ //console.log(res);
|
|
|
+ let buf = Buffer.from(res.value);
|
|
|
+ let receiveStr = buf.toString()
|
|
|
+ console.log(`收到数据:${receiveStr}`);
|
|
|
+ if (receiveStr === 'connect_success') {
|
|
|
+ let text = `${that.isWifi ? 'WIFI' : '4g'}配网成功`
|
|
|
+ uni.showToast({
|
|
|
+ title: text,
|
|
|
+ icon: 'none',
|
|
|
+ duration: 1000
|
|
|
+ })
|
|
|
+ that.closeBLEConnection()
|
|
|
+ that.errorText = text
|
|
|
+ } else if (receiveStr.indexOf('failure') >= 0) {
|
|
|
+ uni.showToast({
|
|
|
+ title: '配网失败',
|
|
|
+ icon: 'none',
|
|
|
+ duration: 1000
|
|
|
+ })
|
|
|
+ that.closeBLEConnection()
|
|
|
+ that.errorText = '配网失败'
|
|
|
+ } else if (receiveStr.indexOf('ic0:') >= 0) { //用来获取iccid的
|
|
|
+ that.iccid = receiveStr.substring(4, receiveStr.length);
|
|
|
+ } else if (receiveStr.indexOf('ic1:') >= 0) { //用来获取iccid的 把ic0 和ic1拼接起来
|
|
|
+ let ic1 = receiveStr.substring(4, receiveStr.length);
|
|
|
+ that.iccid = that.iccid + ic1;
|
|
|
+ //发送4G配网指令
|
|
|
+ //let buf = Buffer.from('without_WiFi')
|
|
|
+ //setTimeout(() =>{that.sendCongifCmd(characteristicId,buf.buffer)},800)
|
|
|
+ setTimeout(() => {
|
|
|
+ that.sendWithoutWifiCommand(characteristicId);
|
|
|
+ }, 800)
|
|
|
+ } else if (receiveStr.indexOf('start_network') >= 0 || receiveStr.indexOf(
|
|
|
+ 'recv_finish') >= 0) {
|
|
|
+ //发送 AIrSMArT_CLOSE指令
|
|
|
+ setTimeout(() => {
|
|
|
+ let buf = Buffer.from('AIrSMArT_CLOSE')
|
|
|
+ that.sendCongifCmd(characteristicId,buf.buffer)
|
|
|
+ }, 2000)
|
|
|
+ } else if (receiveStr.indexOf('without_WiFi_OK') >= 0) {
|
|
|
+ let text = `4G配网成功`
|
|
|
+ uni.showToast({
|
|
|
+ title: text,
|
|
|
+ icon: 'none',
|
|
|
+ duration: 1000
|
|
|
+ })
|
|
|
+ that.errorText = text
|
|
|
+ that.closeBLEConnection()
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ //发送数据给设备
|
|
|
+ setTimeout(() => {
|
|
|
+ let buffer
|
|
|
+ if (that.isWifi) {
|
|
|
+ buffer = that.getWifiBuffer()
|
|
|
+ //that.sendCongifCmd(characteristicId,buffer)
|
|
|
+ } else {
|
|
|
+ //4G设备先获取iccid
|
|
|
+ let buf = Buffer.from('get_iccid')
|
|
|
+ buffer = buf.buffer
|
|
|
+ }
|
|
|
+ that.sendCongifCmd(characteristicId, buffer)
|
|
|
+ }, 800)
|
|
|
+ }, 1000)
|
|
|
+ },
|
|
|
+ sendCongifCmd(characteristicId, buffer) { //发送配网指令
|
|
|
+ let that = this
|
|
|
+
|
|
|
+ let count = Math.ceil(buffer.byteLength / 20)
|
|
|
+ //拆分成的ArrayBuffer数组,每个ArrayBuffer不超过20个字节
|
|
|
+ let buffers = []
|
|
|
+ for (var i = 0; i < count; i++) {
|
|
|
+ let size = Math.min(20, buffer.byteLength - i * 20)
|
|
|
+ let buf = buffer.slice(i * 20, size + i * 20)
|
|
|
+ buffers.push(buf)
|
|
|
+ }
|
|
|
+
|
|
|
+ //返回的是一个promise对象
|
|
|
+ function sendData(buffer) {
|
|
|
+ return uni.writeBLECharacteristicValue({
|
|
|
+ deviceId: that.deviceId,
|
|
|
+ serviceId: server_uuid,
|
|
|
+ characteristicId: characteristicId,
|
|
|
+ value: buffer,
|
|
|
+ })
|
|
|
+ };
|
|
|
+
|
|
|
+ (async () => {
|
|
|
+ for (let b of buffers) {
|
|
|
+ let res = await sendData(b)
|
|
|
+ //console.log(res);
|
|
|
+ console.log(`发送的数据为:${Buffer.from(b)} errorCode: ${res[res.length-1].errCode}`);
|
|
|
+ }
|
|
|
+ // let promises = buffers.map((b) => sendData(b))
|
|
|
+ // let res = await Promise.all(promises)
|
|
|
+ })();
|
|
|
+ },
|
|
|
+ sendCongifCmd1(characteristicId, buffer) { //发送配网指令
|
|
|
+ let that = this
|
|
|
+ uni.writeBLECharacteristicValue({
|
|
|
+ deviceId: that.deviceId,
|
|
|
+ serviceId: server_uuid,
|
|
|
+ characteristicId: characteristicId,
|
|
|
+ value: buffer,
|
|
|
+ success(res) {
|
|
|
+ console.log(`发送数据成功 ${Buffer.from(buffer)}`);
|
|
|
+ console.log(res)
|
|
|
+ },
|
|
|
+ fail(err) {
|
|
|
+ console.log(`发送数据失败 ${Buffer.from(buffer)}`);
|
|
|
+ console.log(err)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ sendWithoutWifiCommand(characteristicId) { //间隔2S发送WithoutWifi指令,直到设备有返回指令
|
|
|
+ let that = this
|
|
|
+
|
|
|
+ function sendWithoutWifi(uuid) {
|
|
|
+ let buf = Buffer.from('without_WiFi')
|
|
|
+ that.sendCongifCmd(characteristicId, buf.buffer)
|
|
|
+ }
|
|
|
+ if (that.withoutWifiInterval === undefined) {
|
|
|
+ that.withoutWifiInterval = setInterval(sendWithoutWifi, 2000, characteristicId)
|
|
|
+ }
|
|
|
+ sendWithoutWifi()
|
|
|
+ },
|
|
|
+ getWifiBuffer() {
|
|
|
+ let ssidBuf = Buffer.from(this.wifiName)
|
|
|
+ console.log(ssidBuf.length);
|
|
|
+
|
|
|
+ let pwdBuf = Buffer.from(this.wifiPwd)
|
|
|
+ console.log(pwdBuf.length);
|
|
|
+
|
|
|
+ let buffer = new ArrayBuffer(ssidBuf.length + pwdBuf.length + 6);
|
|
|
+ let dataView = new DataView(buffer);
|
|
|
+
|
|
|
+ dataView.setUint8(0, 0x22)
|
|
|
+ dataView.setUint8(1, ssidBuf.length + pwdBuf.length + 6)
|
|
|
+ dataView.setUint8(2, 0x33)
|
|
|
+ dataView.setUint8(3, ssidBuf.length)
|
|
|
+ let j = 0
|
|
|
+ for (var i = 4; i < ssidBuf.length + 4; ++i) {
|
|
|
+ dataView.setUint8(i, ssidBuf[j++])
|
|
|
+ }
|
|
|
+
|
|
|
+ dataView.setUint8(ssidBuf.length + 4, 0x44)
|
|
|
+ dataView.setUint8(ssidBuf.length + 5, pwdBuf.length)
|
|
|
+ j = 0
|
|
|
+ for (var i = ssidBuf.length + 6; i < ssidBuf.length + pwdBuf.length + 6; ++i) {
|
|
|
+ dataView.setUint8(i, pwdBuf[j++])
|
|
|
+ }
|
|
|
+ //打印arrayBuffer
|
|
|
+ // let buf = Buffer.from(buffer);
|
|
|
+ // console.log(buf);
|
|
|
+
|
|
|
+ //console.log(buffer.byteLength)
|
|
|
+ return buffer;
|
|
|
+ },
|
|
|
+ closeBLEConnection() {
|
|
|
+ let that = this
|
|
|
+ uni.closeBLEConnection({
|
|
|
+ deviceId: that.deviceId,
|
|
|
+ success(res) {
|
|
|
+ console.log('关闭连接成功');
|
|
|
+ console.log(res)
|
|
|
+ },
|
|
|
+ fail(err) {
|
|
|
+ console.log(err)
|
|
|
+ console.log('关闭连接失败');
|
|
|
+ }
|
|
|
+ })
|
|
|
+ clearInterval(that.withoutWifiInterval)
|
|
|
+ clearTimeout(that.configTimeout)
|
|
|
+ that.connected = false
|
|
|
+ that.showLoading = false
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+</script>
|
|
|
+
|
|
|
+<style>
|
|
|
+ .box {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ width: 100vw;
|
|
|
+ height: 100vh;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ .content {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+
|
|
|
+ /* align-items: center;
|
|
|
+ justify-content: center; */
|
|
|
+ }
|
|
|
+
|
|
|
+ .input-row {
|
|
|
+ display: flex;
|
|
|
+ margin-top: 10rpx;
|
|
|
+ flex-direction: row;
|
|
|
+ align-items: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ .loadView {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-self: center;
|
|
|
+ align-items: center;
|
|
|
+ /* margin-top: 35vh; */
|
|
|
+ }
|
|
|
+
|
|
|
+ .edittext {
|
|
|
+ display: flex;
|
|
|
+ width: 60vw;
|
|
|
+ height: 50rpx;
|
|
|
+
|
|
|
+ border: 1rpx solid #333333;
|
|
|
+ }
|
|
|
+
|
|
|
+ .rotateAnim {
|
|
|
+ width: 60rpx;
|
|
|
+ height: 60rpx;
|
|
|
+ animation: turn 1200ms linear infinite;
|
|
|
+ }
|
|
|
+
|
|
|
+ @keyframes turn {
|
|
|
+ 0% {
|
|
|
+ transform: rotate(0deg);
|
|
|
+ }
|
|
|
+
|
|
|
+ 50% {
|
|
|
+ transform: rotate(180deg);
|
|
|
+ }
|
|
|
+
|
|
|
+ 100% {
|
|
|
+ transform: rotate(360deg);
|
|
|
+ }
|
|
|
+ }
|
|
|
+</style>
|