Browse Source

optimize UI

master
elinkthings 4 years ago
parent
commit
07f3c5f65c

+ 1
- 1
ailink_demo/app.json View File

}, },
"plugins": { "plugins": {
"sdkPlugin": { "sdkPlugin": {
"version": "1.1.1",
"version": "1.1.2",
"provider": "wx17e93aad47cdae1a" "provider": "wx17e93aad47cdae1a"
} }
}, },

+ 157
- 57
ailink_demo/pages/index/index.js View File





function inArray(arr, key, val) { function inArray(arr, key, val) {
if (!arr || !arr.length || typeof arr != 'object' || !Array.isArray(arr)) {
return -1
}
for (let i = 0; i < arr.length; i++) { for (let i = 0; i < arr.length; i++) {
if (arr[i][key] === val) {
return i;
if (!key) {
if (arr[i] == val) {
return i
}
} else if (arr[i][key] === val) {
return i
} }
} }
return -1; return -1;
} }


// ArrayBuffer转16进度字符串示例 // ArrayBuffer转16进度字符串示例
function ab2hex(buffer, split = ',') {
function ab2hex(buffer, split) {
var hexArr = Array.prototype.map.call( var hexArr = Array.prototype.map.call(
new Uint8Array(buffer), new Uint8Array(buffer),
function (bit) { function (bit) {
], ],
connected: false, connected: false,
chs: [], chs: [],
cmd: '',
name: '',
deviceId: null,
historyList: [],
}, },
onLoad: function () { onLoad: function () {

let historyList = []
historyList = wx.getStorageSync('historyList')
this.setData({
historyList,
})
}, },


// 初始化蓝牙模块 // 初始化蓝牙模块
allowDuplicatesKey: true, allowDuplicatesKey: true,
services: [ services: [
"FFE0", "FFE0",
"F0A0",
// "F0A0", // BM30广播模块需加上,如使用连接模块可忽略
], ],
success: (res) => { success: (res) => {
console.log('startBluetoothDevicesDiscovery success', res) console.log('startBluetoothDevicesDiscovery success', res)
} else { } else {
let buff = device.advertisData.slice(-6) let buff = device.advertisData.slice(-6)
device.mac = new Uint8Array(buff) // 保存广播数据中的mac地址,这是由于iOS不直接返回mac地址 device.mac = new Uint8Array(buff) // 保存广播数据中的mac地址,这是由于iOS不直接返回mac地址
let tempMac = Array.from(device.mac)
tempMac.reverse()
device.macAddr = ab2hex(tempMac, ':').toUpperCase()
} }
if (idx === -1) { if (idx === -1) {
data[`devices[${foundDevices.length}]`] = device data[`devices[${foundDevices.length}]`] = device
}, },
// 连接低功耗蓝牙设备 // 连接低功耗蓝牙设备
createBLEConnection(e) { createBLEConnection(e) {
this._connLoading = true
wx.showLoading({
title: '连接中',
})
setTimeout(() => {
if (this._connLoading) {
this._connLoading = false
wx.hideLoading()
}
}, 6000)
const ds = e.currentTarget.dataset const ds = e.currentTarget.dataset
const index = ds.index const index = ds.index
// 保存当前连接的设备,注意不能从wxml的dataset中直接返回该对象,因为ArrarBuffer类型的数据无法保留 // 保存当前连接的设备,注意不能从wxml的dataset中直接返回该对象,因为ArrarBuffer类型的数据无法保留
}) })
console.log("createBLEConnection:success") console.log("createBLEConnection:success")
wx.stopBluetoothDevicesDiscovery() wx.stopBluetoothDevicesDiscovery()
this.onBLEConnectionStateChange()
this.getBLEDeviceServices(deviceId) this.getBLEDeviceServices(deviceId)
},
fail: res => {
this._connLoading = false
wx.hideLoading()
wx.showToast({
title: '连接失败',
icon: 'none'
})
} }
}) })
// 连接上设备就可以停止蓝牙搜索,减少功耗。 // 连接上设备就可以停止蓝牙搜索,减少功耗。
this.stopBluetoothDevicesDiscovery() this.stopBluetoothDevicesDiscovery()
}, },


onBLEConnectionStateChange() {
wx.onBLEConnectionStateChange((res) => {
console.log('wx.onBLEConnectionStateChange() ', res.deviceId, res.connected, res.errorCode, res.errorMsg)
// 该方法回调中可以用于处理连接意外断开等异常情况
// console.log(`%c device ${res.deviceId} state has changed, connected: ${res.connected}`, 'color: #F26363')
if (!res.connected) {
wx.showToast({
title: '连接已断开',
icon: 'none'
})
this.setData({
connected: false,
showWriteInput: false,
})
}
})
},

// 断开与低功耗蓝牙设备的连接 // 断开与低功耗蓝牙设备的连接
closeBLEConnection() { closeBLEConnection() {
wx.closeBLEConnection({ wx.closeBLEConnection({
this.setData({ this.setData({
connected: false, connected: false,
chs: [], chs: [],
showWriteInput: false,
}) })
}, },


wx.getBLEDeviceServices({ wx.getBLEDeviceServices({
deviceId, deviceId,
success: (res) => { success: (res) => {
console.log(res)
for (let i = 0; i < res.services.length; i++) { for (let i = 0; i < res.services.length; i++) {
if (res.services[i].isPrimary && res.services[i].uuid.indexOf("FFE0")>-1) {
if (res.services[i].isPrimary && res.services[i].uuid.indexOf('FFE0') > -1) {
this.getBLEDeviceCharacteristics(deviceId, res.services[i].uuid) this.getBLEDeviceCharacteristics(deviceId, res.services[i].uuid)
return return
} }


// 这部分功能在插件的 initPlugin 中已实现,如需用到其中的 uuid 也可取消注释 // 这部分功能在插件的 initPlugin 中已实现,如需用到其中的 uuid 也可取消注释
// // let uuid1, uuid2, uuid3; // // let uuid1, uuid2, uuid3;
// for (let i = 0; i < res.characteristics.length; i++) {
// let item = res.characteristics[i]
// if (item.uuid.indexOf('0000FFE1') != -1) {
// this.uuid1 = item.uuid //下发数据
// } else if (item.uuid.indexOf('0000FFE2') != -1) {
// this.uuid2 = item.uuid //监听数据
// } else if (item.uuid.indexOf('0000FFE3') != -1) {
// this.uuid3 = item.uuid //写入设置
// }
// }
// // 打开监听
// wx.notifyBLECharacteristicValueChange({
// deviceId,
// serviceId,
// characteristicId: this.uuid2,
// state: true,
// })
// wx.notifyBLECharacteristicValueChange({
// deviceId,
// serviceId,
// characteristicId: this.uuid3,
// state: true,
// })
for (let i = 0; i < res.characteristics.length; i++) {
let item = res.characteristics[i]
if (item.uuid.indexOf('0000FFE1') != -1) {
this.uuid1 = item.uuid //下发数据
} else if (item.uuid.indexOf('0000FFE2') != -1) {
this.uuid2 = item.uuid //监听数据
} else if (item.uuid.indexOf('0000FFE3') != -1) {
this.uuid3 = item.uuid //写入设置
}
}
// 打开监听
wx.notifyBLECharacteristicValueChange({
deviceId,
serviceId,
characteristicId: this.uuid2,
state: true,
})
wx.notifyBLECharacteristicValueChange({
deviceId,
serviceId,
characteristicId: this.uuid3,
state: true,
})


// 初始化插件 // 初始化插件
plugin.initPlugin(res.characteristics, this._device) plugin.initPlugin(res.characteristics, this._device)


wx.onBLECharacteristicValueChange((characteristic) => { wx.onBLECharacteristicValueChange((characteristic) => {
// 解析特征值,返回解密后的数据 // 解析特征值,返回解密后的数据
console.log("===" + plugin.ab2hex(characteristic.value))
let bleData = plugin.parseBleData(characteristic.value) let bleData = plugin.parseBleData(characteristic.value)
console.log(bleData)
if (bleData.status == 0) { if (bleData.status == 0) {
console.log("握手成功") console.log("握手成功")
this._connLoading = false
wx.hideLoading()
wx.showToast({
title: '连接成功',
})
} else if (bleData.status == 1) { } else if (bleData.status == 1) {
console.log(bleData)
let payload = bleData.data //对应协议中的payload数据,可以自行解析该数据 let payload = bleData.data //对应协议中的payload数据,可以自行解析该数据
console.log(ab2hex(payload, ' '))
console.log(ab2hex(bleData.completeData, ' '))
// console.log(ab2hex(payload, ' '))
// console.log(ab2hex(bleData.completeData, ' '))


// 以体脂秤数据解析为例 // 以体脂秤数据解析为例
let weight, adc; let weight, adc;
if (idx === -1) { if (idx === -1) {
data[`chs[${this.data.chs.length}]`] = { data[`chs[${this.data.chs.length}]`] = {
uuid: characteristic.characteristicId, uuid: characteristic.characteristicId,
value: ab2hex(payload, ' ')
value: ab2hex(bleData.completeData, ' ')
} }
} else { } else {
data[`chs[${idx}]`] = { data[`chs[${idx}]`] = {
uuid: characteristic.characteristicId, uuid: characteristic.characteristicId,
value: ab2hex(payload, ' ')
value: ab2hex(bleData.completeData, ' ')
} }
} }
this.setData(data) this.setData(data)
} else { } else {
console.log(bleData)
// console.log(bleData)
} }
}) })
}, },
value: buffer, value: buffer,
success(res) { success(res) {
console.log('writeBLECharacteristicValue success', res) console.log('writeBLECharacteristicValue success', res)
console.log(ab2hex(buffer))
console.log('下发指令==> ' + ab2hex(buffer))
} }
}) })
}, },
showWriteInput: false showWriteInput: false
}) })
}, },
// 指令输入
writingCmd(e) {
this._cmd = e.detail.value
},
// 指令下发 // 指令下发
submitCmd() {
if (!this._cmd) {
submitCmd(e, cmd) {
let arr = []
let temp = []
if (!cmd) {
cmd = this.data.cmd
}
console.log(cmd)
if(!cmd || !this.data.connected){
return return
} }
let arr = []
if (this._cmd.indexOf(",") == -1) {
arr = this._cmd.split(" ")
if(cmd.indexOf(",") == -1){
temp = cmd.split(" ")
} else { } else {
arr = this._cmd.split(",")
temp = cmd.split(",")
} }
for (let i in arr) {
arr[i] = parseInt(arr[i], 16)
let tempCmd = temp.join(' ')
for(let i = 0; i < temp.length; i++){
arr[i] = parseInt(temp[i],16)
} }
// let arr = [ // let arr = [
// 0xA6, // 0xA6,
// 0x6A, // 0x6A,
// //A6 01 28 29 6A // //A6 01 28 29 6A
// ] // ]
if (arr[0] == 0xA6) {
let payload = arr.slice(2, -2)
if(arr[0] == 0xA6){
let len = arr[1]
let payload = arr.slice(2, 2 + len)
plugin.sendDataOfA6(payload) plugin.sendDataOfA6(payload)
} else if (arr[0] == 0xA7) {
let cid = [arr[1], arr[2]] // 001E
let payload = arr.slice(4, -2)
// let buff = new Uint8Array(arr).buffer
// this.writeBLECharacteristicValue(buff, this.uuid3, this._deviceId, this._serviceId)
} else if(arr[0] == 0xA7) {
let len = arr[3]
let payload = arr.slice(4, 4 + len)
plugin.sendDataOfA7(payload) plugin.sendDataOfA7(payload)
// this.writeBLECharacteristicValue(buff, this.uuid1, this._deviceId, this._serviceId)
} }
return
let historyList = wx.getStorageSync('historyList') || []
let idx = historyList.findIndex(item => item.cmd == tempCmd)
if (idx < 0) {
historyList.push({cmd: tempCmd})
}
this.setData({
historyList
})
wx.setStorage({
data: historyList,
key: 'historyList',
})
wx.showToast({
title: '已发送',
icon: 'none'
})
},
history_delete(e) {
let index = e.currentTarget.dataset.index
this.data.historyList.splice(index, 1)
this.setData({
historyList: this.data.historyList
})
wx.setStorage({
data: this.data.historyList,
key: 'historyList',
})
},
history_copy(e) {
let index = e.currentTarget.dataset.index
wx.setClipboardData({
data: this.data.historyList[index].cmd
})
},
history_send(e) {
let index = e.currentTarget.dataset.index
let cmd = this.data.historyList[index].cmd
this.submitCmd(null, cmd)
}, },
}); });

+ 57
- 41
ailink_demo/pages/index/index.wxml View File

} }
</wxs> </wxs>
<button bindtap="openBluetoothAdapter">开始扫描</button>
<button bindtap="stopBluetoothDevicesDiscovery">停止扫描</button>
<button bindtap="closeBluetoothAdapter">结束流程</button>
<view class="devices_summary">已发现 {{devices.length}} 个外围设备:</view>
<scroll-view class="device_list" scroll-y scroll-with-animation>
<view wx:for="{{devices}}" wx:key="index"
data-device-id="{{item.deviceId}}"
data-name="{{item.name || item.localName}}"
data-mac="{{item.mac}}"
data-index="{{index}}"
bindtap="createBLEConnection"
class="device_item"
hover-class="device_item_hover">
<view style="font-size: 16px; color: #333;">{{item.name}}</view>
<view style="font-size: 10px">信号强度: {{item.RSSI}}dBm ({{utils.max(0, item.RSSI + 100)}}%)</view>
<view style="font-size: 10px">mac地址: {{item.deviceId}}</view>
<!-- <view style="font-size: 10px">Service数量: {{utils.len(item.advertisServiceUUIDs)}}</view> -->
<view style="font-size: 14px">广播数据:{{item.analyzeDataText}}</view>
<view class="container">
<view class="header">
<button bindtap="openBluetoothAdapter" style="font-size: 32rpx;line-height:100rpx;width: 100%;">开始扫描</button>
<button bindtap="stopBluetoothDevicesDiscovery" style="font-size: 32rpx;line-height:100rpx;width: 100%;">停止扫描</button>
<button bindtap="closeBluetoothAdapter" style="font-size: 32rpx;line-height:100rpx;width: 100%;">结束流程</button>
</view> </view>
</scroll-view>
<view class="connected_info" wx:if="{{connected}}">
<view>
<text>已连接到 {{name}}</text>
<view class="operation">
<!-- <button wx:if="{{canWrite}}" size="mini" bindtap="writeBLECharacteristicValue">写数据</button> -->
<button size="mini" bindtap="showWriteInputView">写入指令</button>
<button size="mini" bindtap="closeBLEConnection">断开连接</button>
<view class="devices_summary">已发现 {{devices.length}} 个外围设备:</view>
<scroll-view class="device_list" scroll-y scroll-with-animation>
<view wx:for="{{devices}}" wx:key="index"
data-device-id="{{item.deviceId}}"
data-name="{{item.name || item.localName}}"
data-mac="{{item.mac}}"
data-index="{{index}}"
bindtap="createBLEConnection"
class="device_item"
hover-class="device_item_hover">
<view style="font-size: 32rpx;">
<text style="color:#000;font-weight:bold">{{item.name}}</text>
<text style="font-size:26rpx">(信号强度: {{item.RSSI}}dBm)</text>
</view>
<view style="font-size: 26rpx">mac地址: {{item.macAddr || item.deviceId}}</view>
<!-- <view style="font-size: 10px">Service数量: {{utils.len(item.advertisServiceUUIDs)}}</view> -->
<view style="font-size: 26rpx">广播数据:{{item.analyzeDataText}}</view>
</view>
</scroll-view>
<view class="connected_info" wx:if="{{connected}}">
<view>
<text>已连接到 {{name}}</text>
<view class="operation">
<!-- <button wx:if="{{canWrite}}" size="mini" bindtap="writeBLECharacteristicValue">写数据</button> -->
<button size="mini" bindtap="showWriteInputView" style="line-height:54rpx; font-size:28rpx;padding:0 20rpx;margin-right:10rpx">写入指令</button>
<button size="mini" bindtap="closeBLEConnection" style="line-height:54rpx; font-size:28rpx;padding:0 20rpx;">断开连接</button>
</view>
</view>
<view wx:for="{{chs}}" wx:key="index" style="font-size: 26rpx; margin-top: 20rpx;">
<view>特性值: {{item.value}}</view>
</view> </view>
</view> </view>
<view wx:for="{{chs}}" wx:key="index" style="font-size: 12px; margin-top: 10px;">
<view>特性值: {{item.value}}</view>
</view>
</view>
<view class="writeInputViewBg" wx:if="{{showWriteInput}}"></view>
<view class="writeInputView" wx:if="{{showWriteInput}}">
<view class="writeInput">
<input bindinput="writingCmd"></input>
</view>
<view class="hint">请输入16进制数,Byte之间用空格或英文逗号分隔</view>
<view class="btns">
<button size="mini" bindtap="submitCmd">确定</button>
<button size="mini" bindtap="hideWriteInputView">取消</button>
<view class="writeInputView" wx:if="{{showWriteInput}}">
<view class="writeInput">
<input type="text" model:value="{{cmd}}"></input>
</view>
<view class="hint">请输入16进制数,Byte之间用空格或英文逗号分隔</view>
<view class="btns">
<button bindtap="submitCmd" style="line-height:70rpx; font-size:30rpx;padding:0 50rpx;margin-right:30rpx;">发送</button>
<button bindtap="hideWriteInputView" style="line-height:70rpx; font-size:30rpx;padding:0 50rpx;">取消</button>
</view>
<view class="history">
<view class="history_title">历史记录:</view>
<scroll-view class="history_wrap" scroll-y="true">
<view class="history_item" wx:for="{{historyList}}" wx:key="index">
<view class="history_cmd">{{item.cmd}}</view>
<view class="history_btns">
<button size="mini" bindtap="history_send" data-index="{{index}}" style="line-height:54rpx; font-size:24rpx;padding:0 30rpx;">发送</button>
<button size="mini" bindtap="history_delete" data-index="{{index}}" style="line-height:54rpx; font-size:24rpx;padding:0 30rpx;margin-left:20rpx">删除</button>
</view>
</view>
</scroll-view>
</view>
</view> </view>
</view> </view>

+ 105
- 26
ailink_demo/pages/index/index.wxss View File

page { page {
background: #f0f0f0;
color: #333; color: #333;
--safe-bottom: env(safe-area-inset-bottom);
}
view,
cover-view,
scroll-view,
swiper,
swiper-item,
movable-area,
movable-view,
button,
input,
textarea,
label,
navigator
{
box-sizing: border-box;
}
.container{
position: relative;
display: flex;
flex-direction: column;
align-items: center;
width: 100vw;
height: 100vh;
padding-bottom: 200rpx;
}
.header{
width: 100%;
}
.container button{
padding-top: 0;
padding-bottom: 0;
border: 1px solid #ddd;
} }
.devices_summary { .devices_summary {
margin-top: 30px;
padding: 10px;
font-size: 16px;
width: 100%;
line-height: 70rpx;
padding: 0 30rpx;
margin-top: 30rpx;
font-size: 32rpx;
} }
.device_list { .device_list {
height: 300px;
margin: 50px 5px;
flex: 1;
width: 100%;
height: calc(100vh - 600rpx);
margin-top: 0; margin-top: 0;
border: 1px solid #EEE;
border: 1px solid #fff;
border-radius: 5px; border-radius: 5px;
width: auto;
background: #fff;
} }
.device_item { .device_item {
line-height: 1.5;
padding: 10rpx 30rpx;
border-bottom: 1px solid #EEE; border-bottom: 1px solid #EEE;
padding: 10px;
color: #666;
} }
.device_item_hover { .device_item_hover {
background-color: rgba(0, 0, 0, .1); background-color: rgba(0, 0, 0, .1);
position: fixed; position: fixed;
bottom: 0; bottom: 0;
width: 100%; width: 100%;
background-color: #F0F0F0;
height: 200rpx;
padding: 10px; padding: 10px;
padding-bottom: 20px;
margin-bottom: env(safe-area-inset-bottom);
border-top: 1px solid #ddd;
background-color: #fff;
font-size: 14px; font-size: 14px;
min-height: 100px;
box-shadow: 0px 0px 3px 0px;
box-shadow: 0px -4rpx 4rpx 0px rgba(0,0,0,.05);
} }
.connected_info .operation { .connected_info .operation {
position: absolute; position: absolute;
display: inline-block; display: inline-block;
right: 30px;
right: 30rpx;
} }
.writeInputViewBg{ .writeInputViewBg{
position: fixed; position: fixed;
} }
.writeInputView{ .writeInputView{
position: fixed; position: fixed;
top: 30%;
left: 50%;
bottom: 200rpx;
left: 0;
z-index: 1001; z-index: 1001;
background-color: #fff;
width: 80vw;
height: 300rpx;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
transform: translateX(-50%);
width: 100%;
height: calc(100vh - 500rpx);
background-color: #fff;
border-top: 1px solid #ddd;
} }
.writeInput{
margin-top: 60rpx;
width: 90%;
.history{
position: relative;
flex: 1;
width: 690rpx;
padding-top: 60rpx;
border: 1px solid #ddd;
margin: 30rpx;
}
.history_title{
position: absolute;
top: 0;
left: 0;
padding: 0 30rpx;
line-height: 60rpx;
font-size: 30rpx;
}
.history_wrap{
width: 100%;
height: 100%;
}
.history_item{
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
height: 72rpx;
padding: 0 30rpx;
border-top: 1px solid #ddd;
}
.history_cmd{
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-size: 24rpx;
}
.history_btns{
height: 60rpx; height: 60rpx;
overflow: hidden;
}
.writeInput{
margin-top: 30rpx;
width: 690rpx;
height: 80rpx;
border: 1rpx solid #ccc; border: 1rpx solid #ccc;
} }
.writeInput input{ .writeInput input{
width: 100%; width: 100%;
height: 100%; height: 100%;
box-sizing: border-box;
padding: 10rpx;
font-size: 32rpx;
} }
.hint{ .hint{
padding-top: 10rpx; padding-top: 10rpx;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
width: 60%; width: 60%;
margin-top: 50rpx;
padding-bottom: 30rpx;
margin-top: 30rpx;
} }

Loading…
Cancel
Save