var crc16 = function(buffer) {
var crc = 0x0000;
var odd;
for (var i = 0; i < buffer.length; i++) {
crc ^= (buffer[i] << 8)
for (var j = 0; j < 8; j++) {
odd = crc & 0x8000;
crc = crc << 1;
if (odd) {
crc = crc ^ 0x1021
}
}
}
var hi = ((crc & 0xFF00) >> 8);
var lo = (crc & 0x00FF);
var crcArr = []
crcArr.push(hi)
crcArr.push(lo)
crc &= 0xFFFF
return crcToString(crcArr, true)
};
function crcToString(arr, isReverse) {
if (typeof isReverse == 'undefined') {
isReverse = true;
}
var hi = arr[0],
lo = arr[1];
return padLeft((isReverse ? hi + lo * 0x100 : hi * 0x100 + lo).toString(16).toUpperCase(), 4, '0');
};
var padLeft = function(s, w, pc) {
if (pc == undefined) {
pc = '0';
}
for (var i = 0, c = w - s.length; i < c; i++) {
s = pc + s;
}
return s;
};
function hexString2Bytes(str) {
var pos = 0;
var len = str.length;
if (len % 2 != 0) {
return null;
}
len /= 2;
var arrBytes = new Array();
for (var i = 0; i < len; i++) {
var s = str.substr(pos, 2);
var v = parseInt(s, 16);
arrBytes.push(v);
pos += 2;
}
return arrBytes;
}
function buf2hex(buffer) {
return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join('')
}
function buf2string(buffer) {
var arr = Array.prototype.map.call(new Uint8Array(buffer), x => x)
var str = ''
for (var i = 0; i < arr.length; i++) {
str += String.fromCharCode(arr[i])
}
return str
}
function hexStringToArrayBuffer(str) {
if (!str) {
return new ArrayBuffer(0);
}
var buffer = new ArrayBuffer(20);
let dataView = new DataView(buffer)
let ind = 0;
for (var i = 0; i < str.length; i += 2) {
let code = parseInt(str.substr(i, 2), 16)
dataView.setUint8(ind, code)
ind++
}
return buffer;
}
function randomString(e) {
let randomStr = '';
e = e || 32;
var t = "123456789",
a = t.length,
n = "";
for (var i = 0; i < e; i++) n += t.charAt(Math.floor(Math.random() * a));
randomStr = n
console.log('当前随机数:' + randomStr);
return n
}
function zeroString(num) {
num = num || 32;
var n = "";
for (var i = 0; i < num; i++) n += '0';
return n
}
data() {
return {
searching: false,
currentBleDeviceName: 'JJ21040000',
connectedBleDevice: {
connectStatus: '连接中',
batPrecent: '获取中'
},
currentBleDevice: null,
connected: false,
devicesList: [],
currentBleDeviceMac: '000000000421',
}
},
onLoad() {
wx.onBluetoothAdapterStateChange(function(res) {
console.log("监听蓝牙res: ", res);
that.searching = res.discovering
if (!res.available) {
that.searching = res.false
}
})
wx.onBluetoothDeviceFound(function(devices) {
console.log('devices', devices)
var isnotexist = true
if (devices.deviceId) {
if (devices.advertisData) {
devices.advertisData = buf2hex(devices.advertisData)
} else {
devices.advertisData = ''
}
for (var i = 0; i < that.devicesList.length; i++) {
if (devices.deviceId == that.devicesList[i].deviceId) {
isnotexist = false
}
}
if (isnotexist) {
that.devicesList.push(devices)
}
if (isnotexist && that.currentBleDeviceName == devices.devices[0].localName) {
that.currentBleDevice = devices.devices[0]
that.currentBleDevice.mac = that.currentBleDevice.advertisData.slice(4, 16)
console.log('currentBleDevice', that.currentBleDevice)
that.connectBleDevice()
}
} else if (devices.devices) {
if (devices.devices[0].advertisData) {
devices.devices[0].advertisData = buf2hex(devices.devices[0].advertisData)
} else {
devices.devices[0].advertisData = ''
}
for (var i = 0; i < that.devicesList.length; i++) {
if (devices.devices[0].deviceId == that.devicesList[i].deviceId) {
isnotexist = false
}
}
if (isnotexist && devices.devices[0].localName) {
that.devicesList.push(devices.devices[0])
}
if (isnotexist && that.currentBleDeviceName == devices.devices[0].localName) {
that.currentBleDevice = devices.devices[0]
that.currentBleDevice.mac = that.currentBleDevice.advertisData.slice(4, 16)
console.log('currentBleDevice', that.currentBleDevice)
that.connectBleDevice()
}
} else if (devices[0]) {
if (devices[0].advertisData) {
devices[0].advertisData = buf2hex(devices[0].advertisData)
} else {
devices[0].advertisData = ''
}
for (var i = 0; i < devices_list.length; i++) {
if (devices[0].deviceId == that.devicesList[i].deviceId) {
isnotexist = false
}
}
if (isnotexist) {
that.devicesList.push(devices[0])
}
if (isnotexist && that.currentBleDeviceName == devices.devices[0].localName) {
that.currentBleDevice = devices.devices[0]
that.currentBleDevice.mac = that.currentBleDevice.advertisData.slice(4, 16)
console.log('currentBleDevice', that.currentBleDevice)
that.connectBleDevice()
}
}
})
wx.onAppHide(function(res) {
})
wx.onBLEConnectionStateChange(function(res) {
console.log(res.connected)
that.connected = res.connected
})
wx.onBLECharacteristicValueChange(function(res) {
console.log('notify接收到数据:')
console.log(res)
if (res.characteristicId.indexOf('F502') != -1) {
var arrayBuffer = res.value
var hexArray = Array.prototype.slice.call(new Uint8Array(arrayBuffer)).map(function(item,
index, ary) {
return (parseInt(item)).toString(16);
})
var type = hexArray[0] + hexArray[1]
switch (type) {
case '11':
that.handshakeNotify(hexArray)
break;
case '12':
that.checkBleDeviceNotify(hexArray)
break;
case '411':
that.batteryStatusNotify(hexArray)
break;
case '312':
that.unlockBleDeviceNotify(hexArray)
break;
default:
console.log(hexArray)
}
}
})
}
methods: {
searchBle() {
var that = this
if (!that.searching) {
wx.closeBluetoothAdapter({
complete: function(res) {
wx.openBluetoothAdapter({
success: function(res) {
wx.getBluetoothAdapterState({
success: function(res) {}
})
wx.startBluetoothDevicesDiscovery({
allowDuplicatesKey: false,
success: function(res) {
that.searching = true
that.devicesList = []
}
})
},
fail: function(res) {
wx.showModal({
title: '提示',
content: '请检查手机蓝牙是否打开',
showCancel: false,
success: function(res) {
that.searching = false
}
})
}
})
}
})
} else {
wx.stopBluetoothDevicesDiscovery({
success: function(res) {
that.searching = false
}
})
}
},
connectBleDevice() {
var that = this
wx.stopBluetoothDevicesDiscovery({
success: function(res) {
console.log(res)
that.searching = false
}
})
wx.createBLEConnection({
deviceId: that.currentBleDevice.deviceId,
success: function(res) {
that.getBleServices()
},
fail: function(res) {
wx.showModal({
title: '提示',
content: '连接失败',
showCancel: false
})
}
})
},
getBleServices() {
var that = this
var buffer = new ArrayBuffer(that.currentBleDevice.deviceId)
wx.getBLEDeviceServices({
deviceId: that.currentBleDevice.deviceId,
success: function(res) {
console.log('services', res.services)
that.services = res.services
wx.getBLEDeviceCharacteristics({
deviceId: that.currentBleDevice.deviceId,
serviceId: res.services[1].uuid,
success: function(res) {
console.log('characteristics', res.characteristics)
that.characteristics = res.characteristics
wx.notifyBLECharacteristicValueChange({
state: true,
deviceId: that.currentBleDevice.deviceId,
serviceId: that.services[1].uuid,
characteristicId: that.characteristics[1].uuid,
success: function(res) {
that.handshake()
}
})
}
})
}
})
},
sendBleCommand: function(arrayBuffer) {
var that = this
if (that.connected) {
console.log('deviceId: ' + that.currentBleDevice.deviceId)
console.log('serviceId: ' + that.services[1].uuid)
console.log('characteristicId: ' + that.characteristics[0].uuid)
wx.writeBLECharacteristicValue({
deviceId: that.currentBleDevice.deviceId,
serviceId: that.services[1].uuid,
characteristicId: that.characteristics[0].uuid,
value: arrayBuffer,
success: function(res) {
console.log(res)
console.log('发送成功')
},
fail: function(res) {
console.log('fail')
console.log(res)
}
})
} else {
wx.showModal({
title: '提示',
content: '蓝牙已断开',
showCancel: false,
success: function(res) {
that.searching = false
}
})
}
},
batteryStatusNotify(hexArray) {
this.connectedBleDevice.batPrecent = (parseInt(hexArray[7], 16) * 20) + '%'
},
handshake() {
var command = '0101' + randomString() + '0000'
console.log('命令内容: ' + command)
var arrayBuffer = hexStringToArrayBuffer(command)
console.log('转换arrayBuffer: ', arrayBuffer)
this.sendBleCommand(arrayBuffer)
},
handshakeNotify(hexArray) {
this.checkBleDevice()
},
checkBleDevice() {
var that = this
var buffer = new ArrayBuffer(20);
var dataView = new DataView(buffer)
var beginCommand = '0102'
var endCommand = '0000'
var ind = 0;
for (var i = 0; i < beginCommand.length; i += 2) {
let code = parseInt(beginCommand.substr(i, 2), 16)
dataView.setUint8(ind, code)
ind++
}
for (var i = 0; i < randomStr.length; i += 2) {
let code = randomStr.substr(i, 2)
var str = code + that.currentBleDevice.mac
const byteData = hexString2Bytes(str)
let tempCrc = crc16(byteData)
dataView.setUint8(ind, parseInt(tempCrc.slice(2, 4), 16))
ind++
}
for (var i = 0; i < endCommand.length; i += 2) {
let code = parseInt(endCommand.substr(i, 2), 16)
dataView.setUint8(ind, code)
ind++
}
console.log('转换arrayBuffer: ', buffer)
this.sendBleCommand(buffer)
},
checkBleDeviceNotify(hexArray) {
console.log(hexArray)
if ('1' == hexArray[2]) {
this.connectedBleDevice.connectStatus = '已连接'
wx.showToast({
title: '连接成功',
icon: 'success',
duration: 1000
})
} else {
wx.showToast({
title: '连接失败',
icon: 'fail',
duration: 1000
})
}
},
unlockBleDevice(code) {
console.log("code: ", code);
if (code == undefined) {
code = '00'
} else {
code = code + ''
if (code.length == 1) {
code = '0' + code
}
}
console.log("仓位code: ", code);
var command = '0312' + code + zeroString(34)
console.log('命令内容: ' + command)
var arrayBuffer = hexStringToArrayBuffer(command)
console.log('转换arrayBuffer: ', arrayBuffer)
this.sendBleCommand(arrayBuffer)
},
unlockBleDeviceNotify(hexArray) {
console.log(hexArray)
if ('1' == hexArray[2]) {
wx.showToast({
title: '开锁成功',
icon: 'success',
duration: 1000
})
} else {
wx.showToast({
title: '开锁失败',
icon: 'fail',
duration: 1000
})
}
},
}