774 lines
24 KiB
Vue
774 lines
24 KiB
Vue
|
|
<template>
|
|||
|
|
<view class="container">
|
|||
|
|
<view v-if="!blueTooth.blueConn">
|
|||
|
|
<uni-row>
|
|||
|
|
<uni-col :span="24">
|
|||
|
|
<uni-icons type="info" size="100" color="#b4b4b4" class="unconn-icon"></uni-icons>
|
|||
|
|
</uni-col>
|
|||
|
|
<uni-col :span="24">
|
|||
|
|
<text class="unconn-text">蓝牙未开启或未授权</text>
|
|||
|
|
</uni-col>
|
|||
|
|
</uni-row>
|
|||
|
|
</view>
|
|||
|
|
<view v-if="blueTooth.blueConn">
|
|||
|
|
<uni-forms ref="bluetoothForm" :modelValue="blueTooth" labelWidth="100px">
|
|||
|
|
<uni-forms-item label="车辆编号" name="bikeCode">
|
|||
|
|
<bikeCodeScan @scan-change="bikeCodeScanChange" :codeValue="blueTooth.bikeCode" ref="bikeCodeScanRef" />
|
|||
|
|
</uni-forms-item>
|
|||
|
|
<uni-forms-item label="中控编号" name="ecuCode">
|
|||
|
|
<uni-easyinput v-model="blueTooth.ecuCode" placeholder="-" disabled />
|
|||
|
|
</uni-forms-item>
|
|||
|
|
<uni-forms-item label="蓝牙信号" name="blueSignal">
|
|||
|
|
<uni-easyinput v-model="blueTooth.blueSignal" placeholder="-" disabled />
|
|||
|
|
</uni-forms-item>
|
|||
|
|
</uni-forms>
|
|||
|
|
<view>
|
|||
|
|
<uni-list :border="true">
|
|||
|
|
<view class="flex" style="padding: 10px 0 10px 0;">
|
|||
|
|
<view class="lt-title">
|
|||
|
|
蓝牙状态
|
|||
|
|
</view>
|
|||
|
|
<view class="lt-state">
|
|||
|
|
<uni-load-more v-if="blueTooth.blueState.load=='loading'" :status="blueTooth.blueState.load"
|
|||
|
|
iconType="circle" :icon-size="20" :content-text="contentText" />
|
|||
|
|
<view class="cu-info" v-if="blueTooth.blueState.detectionState=='close'">
|
|||
|
|
<text class="cuIcon-roundclosefill text-red"></text>{{blueTooth.blueState.msg}}
|
|||
|
|
</view>
|
|||
|
|
<view class="cu-info" v-if="blueTooth.blueState.detectionState=='open'">
|
|||
|
|
<text class="cuIcon-roundcheckfill text-green"></text>{{blueTooth.blueState.msg}}
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
<view class="lt-but">
|
|||
|
|
<view style="bottom: 10rpx;width:100%">
|
|||
|
|
<button v-if="blueTooth.blueState.detectionState !='open'"
|
|||
|
|
:disabled="blueTooth.blueState.btuDisabled"
|
|||
|
|
style="width: 60px;height: 35px;font-size: 15px;" type="primary"
|
|||
|
|
@click="getEbikeInfo">连接</button>
|
|||
|
|
<button v-if="blueTooth.blueState.detectionState =='open'"
|
|||
|
|
:disabled="blueTooth.blueState.btuDisabled"
|
|||
|
|
style="width: 60px;height: 35px;font-size: 15px;" type="primary"
|
|||
|
|
@click="closeConn">断开</button>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
</uni-list>
|
|||
|
|
<uni-list :border="true">
|
|||
|
|
<view class="flex" style="padding: 10px 0 10px 0;">
|
|||
|
|
<view class="lt-title">
|
|||
|
|
车锁开
|
|||
|
|
</view>
|
|||
|
|
<view class="lt-state">
|
|||
|
|
<uni-load-more v-if="blueTooth.openLock.load=='loading'" :status="blueTooth.openLock.load"
|
|||
|
|
iconType="circle" :icon-size="20" :content-text="contentText" />
|
|||
|
|
<view class="cu-info">
|
|||
|
|
<text v-if="blueTooth.openLock.detectionState=='error'"
|
|||
|
|
class="cuIcon-roundclosefill text-red"></text>{{blueTooth.openLock.msg}}
|
|||
|
|
</view>
|
|||
|
|
<view class="cu-info">
|
|||
|
|
<text v-if="blueTooth.openLock.detectionState=='success'"
|
|||
|
|
class="cuIcon-roundcheckfill text-green"></text>{{blueTooth.openLock.msg}}
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
<view class="lt-but">
|
|||
|
|
<view style="bottom: 10rpx;width:100%">
|
|||
|
|
<button :disabled="blueTooth.openLock.btuDisabled"
|
|||
|
|
style="width: 60px;height: 35px;font-size: 15px;" type="primary"
|
|||
|
|
@click="execCommon('openLock')">执行</button>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
</uni-list>
|
|||
|
|
<uni-list :border="true">
|
|||
|
|
<view class="flex" style="padding: 10px 0 10px 0;">
|
|||
|
|
<view class="lt-title">
|
|||
|
|
车锁关
|
|||
|
|
</view>
|
|||
|
|
<view class="lt-state">
|
|||
|
|
<uni-load-more v-if="blueTooth.closeLock.load=='loading'" :status="blueTooth.closeLock.load"
|
|||
|
|
iconType="circle" :icon-size="20" :content-text="contentText" />
|
|||
|
|
<view class="cu-info">
|
|||
|
|
<text v-if="blueTooth.closeLock.detectionState=='error'"
|
|||
|
|
class="cuIcon-roundclosefill text-red"></text>{{blueTooth.closeLock.msg}}
|
|||
|
|
</view>
|
|||
|
|
<view class="cu-info">
|
|||
|
|
<text v-if="blueTooth.closeLock.detectionState=='success'"
|
|||
|
|
class="cuIcon-roundcheckfill text-green"></text>{{blueTooth.closeLock.msg}}
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
<view class="lt-but">
|
|||
|
|
<view style="bottom: 10rpx;width:100%">
|
|||
|
|
<button :disabled="blueTooth.closeLock.btuDisabled"
|
|||
|
|
style="width: 60px;height: 35px;font-size: 15px;" type="primary"
|
|||
|
|
@click="execCommon('closeLock')">执行</button>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
</uni-list>
|
|||
|
|
<uni-list :border="true">
|
|||
|
|
<view class="flex" style="padding: 10px 0 10px 0;">
|
|||
|
|
<view class="lt-title">
|
|||
|
|
打开电池仓
|
|||
|
|
</view>
|
|||
|
|
<view class="lt-state">
|
|||
|
|
<uni-load-more v-if="blueTooth.openBatteryHouse.load=='loading'" :status="blueTooth.openBatteryHouse.load"
|
|||
|
|
iconType="circle" :icon-size="20" :content-text="contentText" />
|
|||
|
|
<view class="cu-info">
|
|||
|
|
<text v-if="blueTooth.openBatteryHouse.detectionState=='error'"
|
|||
|
|
class="cuIcon-roundclosefill text-red"></text>{{blueTooth.openBatteryHouse.msg}}
|
|||
|
|
</view>
|
|||
|
|
<view class="cu-info">
|
|||
|
|
<text v-if="blueTooth.openBatteryHouse.detectionState=='success'"
|
|||
|
|
class="cuIcon-roundcheckfill text-green"></text>{{blueTooth.openBatteryHouse.msg}}
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
<view class="lt-but">
|
|||
|
|
<view style="bottom: 10rpx;width:100%">
|
|||
|
|
<button :disabled="blueTooth.openBatteryHouse.btuDisabled"
|
|||
|
|
style="width: 60px;height: 35px;font-size: 15px;" type="primary"
|
|||
|
|
@click="execCommon('openBatteryHouse')">执行</button>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
</uni-list>
|
|||
|
|
<uni-list :border="true">
|
|||
|
|
<view class="flex" style="padding: 10px 0 10px 0;">
|
|||
|
|
<view class="lt-title">
|
|||
|
|
关闭电池仓
|
|||
|
|
</view>
|
|||
|
|
<view class="lt-state">
|
|||
|
|
<uni-load-more v-if="blueTooth.closeBatteryHouse.load=='loading'" :status="blueTooth.closeBatteryHouse.load"
|
|||
|
|
iconType="circle" :icon-size="20" :content-text="contentText" />
|
|||
|
|
<view class="cu-info">
|
|||
|
|
<text v-if="blueTooth.closeBatteryHouse.detectionState=='error'"
|
|||
|
|
class="cuIcon-roundclosefill text-red"></text>{{blueTooth.closeBatteryHouse.msg}}
|
|||
|
|
</view>
|
|||
|
|
<view class="cu-info">
|
|||
|
|
<text v-if="blueTooth.closeBatteryHouse.detectionState=='success'"
|
|||
|
|
class="cuIcon-roundcheckfill text-green"></text>{{blueTooth.closeBatteryHouse.msg}}
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
<view class="lt-but">
|
|||
|
|
<view style="bottom: 10rpx;width:100%">
|
|||
|
|
<button :disabled="blueTooth.openBatteryHouse.btuDisabled"
|
|||
|
|
style="width: 60px;height: 35px;font-size: 15px;" type="primary"
|
|||
|
|
@click="execCommon('closeBatteryHouse')">执行</button>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
</uni-list>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<script setup>
|
|||
|
|
import { ref, onMounted } from 'vue';
|
|||
|
|
import {
|
|||
|
|
showModelMessage
|
|||
|
|
} from '@/utils/tools.js';
|
|||
|
|
import * as api from '@/utils/api.js';
|
|||
|
|
import { AES128ECBEncrypt } from '@/utils/aes_util.js';
|
|||
|
|
const bluetoothForm = ref(null);
|
|||
|
|
const bikeCodeScanRef = ref(null);
|
|||
|
|
const serviceId = '0000FFF0-0000-1000-8000-00805F9B34FB';
|
|||
|
|
const characteristicId = '0000FFF6-0000-1000-8000-00805F9B34FB';
|
|||
|
|
|
|||
|
|
const blueTooth = ref({
|
|||
|
|
blueConn:false,
|
|||
|
|
deviceId: '',
|
|||
|
|
bikeCode: '',
|
|||
|
|
ecuCode: '-',
|
|||
|
|
ecuSn: '-',
|
|||
|
|
blueSignal:'-',
|
|||
|
|
autoBlueState: true,
|
|||
|
|
blueState: {
|
|||
|
|
load: '',
|
|||
|
|
btuDisabled: true,
|
|||
|
|
detectionState: '',
|
|||
|
|
msg: "已断开"
|
|||
|
|
},
|
|||
|
|
openLock: {
|
|||
|
|
load: '',
|
|||
|
|
btuDisabled: true,
|
|||
|
|
detectionState: '',
|
|||
|
|
msg: ""
|
|||
|
|
},
|
|||
|
|
closeLock: {
|
|||
|
|
load: '',
|
|||
|
|
btuDisabled: true,
|
|||
|
|
detectionState: '',
|
|||
|
|
msg: ""
|
|||
|
|
},
|
|||
|
|
openBatteryHouse: {
|
|||
|
|
load: '',
|
|||
|
|
btuDisabled: true,
|
|||
|
|
detectionState: '',
|
|||
|
|
msg: ""
|
|||
|
|
},
|
|||
|
|
closeBatteryHouse: {
|
|||
|
|
load: '',
|
|||
|
|
btuDisabled: true,
|
|||
|
|
detectionState: '',
|
|||
|
|
msg: ""
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
const contentText = ref({
|
|||
|
|
contentdown: '',
|
|||
|
|
contentrefresh: '读取中',
|
|||
|
|
contentnomore: ''
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
onMounted(() => {
|
|||
|
|
uni.openBluetoothAdapter({
|
|||
|
|
success(res) {
|
|||
|
|
if(res.errno == 0){
|
|||
|
|
blueTooth.value.blueConn = true;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
//showModelMessage("蓝牙未就绪");
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
fail(err) {
|
|||
|
|
let errmsg = err.errMsg;
|
|||
|
|
if(err.errCode == 10001){
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
errmsg = "蓝牙未就绪";
|
|||
|
|
//showModelMessage("蓝牙未就绪");
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
uni.onBluetoothAdapterStateChange(function (res) {
|
|||
|
|
if(res["available"]){
|
|||
|
|
blueTooth.value.blueConn = true;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
blueTooth.value.blueConn = false;
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
let timer;
|
|||
|
|
const bikeCodeScanChange = (data) => {
|
|||
|
|
clearTimeout(timer);
|
|||
|
|
blueTooth.value.bikeCode = data;
|
|||
|
|
if(data != ""){
|
|||
|
|
timer = setTimeout(function () {
|
|||
|
|
getEbikeInfo();
|
|||
|
|
}, 5000);
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const getEbikeInfo = () => {
|
|||
|
|
if(blueTooth.value.deviceId != ""){
|
|||
|
|
createBLEConnection();
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
api.callEbikeInfo("getBikeINfoData?bikeCode=" + blueTooth.value.bikeCode).then((res)=>{
|
|||
|
|
if(res.code == 200 && res.data){
|
|||
|
|
if(res.data.ecuCode != ""){
|
|||
|
|
blueTooth.value.ecuCode = res.data.ecuCode;
|
|||
|
|
blueTooth.value.ecuSn = res.data.ecuSn;
|
|||
|
|
blueTooth.value.blueState.load=='loading';
|
|||
|
|
setTimeout(function () {
|
|||
|
|
startBluetoothDevicesDiscovery("ECU-" + res.data.ecuSn);
|
|||
|
|
}, 2000);
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
showModelMessage("该车辆未绑定中控");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
showModelMessage("该车辆未绑定中控");
|
|||
|
|
}
|
|||
|
|
}).catch((err)=>{
|
|||
|
|
showModelMessage("该车辆未绑定中控");
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const stopBluetoothDevicesDiscovery =() =>{
|
|||
|
|
uni.stopBluetoothDevicesDiscovery({
|
|||
|
|
success(res) {
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const closeConn =() =>{
|
|||
|
|
uni.closeBLEConnection({
|
|||
|
|
deviceId: blueTooth.value.deviceId,
|
|||
|
|
success(res) {
|
|||
|
|
blueTooth.value.autoBlueState = false;
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const execCommon = (comm) => {
|
|||
|
|
switch(comm){
|
|||
|
|
case "openLock": //开锁
|
|||
|
|
var buffer = new ArrayBuffer(5);
|
|||
|
|
var dataView = new DataView(buffer);
|
|||
|
|
dataView.setUint32(0, 0X67740082);
|
|||
|
|
dataView.setUint8(4, 0x82);
|
|||
|
|
writeBLECharacteristicValueWithBuff(buffer);
|
|||
|
|
break;
|
|||
|
|
case "closeLock": //关锁
|
|||
|
|
var buffer = new ArrayBuffer(5);
|
|||
|
|
var dataView = new DataView(buffer);
|
|||
|
|
dataView.setUint32(0, 0X67740081);
|
|||
|
|
dataView.setUint8(4, 0x81);
|
|||
|
|
writeBLECharacteristicValueWithBuff(buffer);
|
|||
|
|
break;
|
|||
|
|
case "openBatteryHouse": //打开电池仓
|
|||
|
|
var buffer = new ArrayBuffer(6);
|
|||
|
|
var dataView = new DataView(buffer);
|
|||
|
|
dataView.setUint32(0, 0X67740189);
|
|||
|
|
dataView.setUint8(4, 0);
|
|||
|
|
var i;
|
|||
|
|
var bcc;
|
|||
|
|
for (i = 0; i < 2; i++) {
|
|||
|
|
bcc ^= dataView.getInt8(i + 3);
|
|||
|
|
}
|
|||
|
|
dataView.setInt8(5, bcc);
|
|||
|
|
writeBLECharacteristicValueWithBuff(buffer);
|
|||
|
|
break;
|
|||
|
|
case "closeBatteryHouse": //关闭电池仓
|
|||
|
|
var buffer = new ArrayBuffer(6);
|
|||
|
|
var dataView = new DataView(buffer);
|
|||
|
|
dataView.setUint32(0, 0X67740189);
|
|||
|
|
dataView.setUint8(4, 1);
|
|||
|
|
var i;
|
|||
|
|
var bcc;
|
|||
|
|
for (i = 0; i < 2; i++) {
|
|||
|
|
bcc ^= dataView.getInt8(i + 3);
|
|||
|
|
}
|
|||
|
|
dataView.setInt8(5, bcc);
|
|||
|
|
writeBLECharacteristicValueWithBuff(buffer);
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const startBluetoothDevicesDiscovery = (sn) =>{
|
|||
|
|
uni.startBluetoothDevicesDiscovery({
|
|||
|
|
success(res) {
|
|||
|
|
if(res.errno == 0){
|
|||
|
|
uni.onBluetoothDeviceFound(function (res) {
|
|||
|
|
const devices = res.devices;
|
|||
|
|
for(let i=0;i < devices.length; i++){
|
|||
|
|
if(devices[i].localName == sn){
|
|||
|
|
// 停止搜索
|
|||
|
|
stopBluetoothDevicesDiscovery();
|
|||
|
|
blueTooth.value.deviceId = devices[i].deviceId;
|
|||
|
|
blueTooth.value.blueSignal = devices[i].RSSI;
|
|||
|
|
createBLEConnection();
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
setTimeout(function () {
|
|||
|
|
//showModelMessage("未发现蓝牙设备");
|
|||
|
|
//停止搜索
|
|||
|
|
stopBluetoothDevicesDiscovery();
|
|||
|
|
}, 120000);
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
fail(err) {
|
|||
|
|
//showModelMessage("未发现蓝牙设备");
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const createBLEConnection =() =>{
|
|||
|
|
blueTooth.value.autoBlueState = true;
|
|||
|
|
uni.createBLEConnection({
|
|||
|
|
deviceId: blueTooth.value.deviceId,
|
|||
|
|
success(res) {
|
|||
|
|
//console.log("createBLEConnection success",res);
|
|||
|
|
blueTooth.value.blueState.load=='';
|
|||
|
|
blueTooth.value.blueState.detectionState = "open";
|
|||
|
|
blueTooth.value.blueState.msg = "已连接";
|
|||
|
|
blueTooth.value.blueState.btuDisabled = false;
|
|||
|
|
blueTooth.value.openLock.btuDisabled = false;
|
|||
|
|
blueTooth.value.closeLock.btuDisabled = false;
|
|||
|
|
blueTooth.value.openBatteryHouse.btuDisabled = false;
|
|||
|
|
blueTooth.value.closeBatteryHouse.btuDisabled = false;
|
|||
|
|
uni.onBLEConnectionStateChange(function (res) {
|
|||
|
|
//console.log("onBLEConnectionStateChange",res);
|
|||
|
|
if(!res.connected && blueTooth.value.autoBlueState){
|
|||
|
|
blueTooth.value.blueState.btuDisabled = false;
|
|||
|
|
blueTooth.value.openLock.btuDisabled = true;
|
|||
|
|
blueTooth.value.closeLock.btuDisabled = true;
|
|||
|
|
blueTooth.value.openBatteryHouse.btuDisabled = true;
|
|||
|
|
blueTooth.value.closeBatteryHouse.btuDisabled = true;
|
|||
|
|
blueTooth.value.blueState.detectionState = "close";
|
|||
|
|
blueTooth.value.blueState.msg = "已断开";
|
|||
|
|
createBLEConnection();
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
startNotify();
|
|||
|
|
},
|
|||
|
|
fail(err) {
|
|||
|
|
//console.log("createBLEConnection err",err);
|
|||
|
|
blueTooth.value.blueSignal = "-";
|
|||
|
|
blueTooth.value.blueState.btuDisabled = false;
|
|||
|
|
blueTooth.value.openLock.btuDisabled = true;
|
|||
|
|
blueTooth.value.closeLock.btuDisabled = true;
|
|||
|
|
blueTooth.value.openBatteryHouse.btuDisabled = true;
|
|||
|
|
blueTooth.value.closeBatteryHouse.btuDisabled = true;
|
|||
|
|
blueTooth.value.blueState.detectionState = "close";
|
|||
|
|
blueTooth.value.blueState.msg = "已断开";
|
|||
|
|
showModelMessage("蓝牙连接失败");
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const startNotify = () => {
|
|||
|
|
uni.notifyBLECharacteristicValueChange({
|
|||
|
|
state:true,
|
|||
|
|
deviceId: blueTooth.value.deviceId,
|
|||
|
|
serviceId: serviceId,
|
|||
|
|
characteristicId: characteristicId,
|
|||
|
|
success(res) {
|
|||
|
|
//console.log("notifyBLECharacteristicValueChange success",res);
|
|||
|
|
//stopDiscovery();
|
|||
|
|
uni.onBLECharacteristicValueChange(function(res){
|
|||
|
|
var hex = bufTohex(res.value);
|
|||
|
|
//console.log("特征改变:", hex);
|
|||
|
|
if (hex.length > 10) {
|
|||
|
|
var header = hex.substring(0, 4);
|
|||
|
|
if (header == '6774') {
|
|||
|
|
var contentL1 = hex.substring(4, 6);
|
|||
|
|
var contentL = parseInt(contentL1, 16);
|
|||
|
|
//console.log('+++++++++++=', (contentL + 5), hex.length)
|
|||
|
|
if ((contentL + 5) * 2 == hex.length) {
|
|||
|
|
//console.log('完整的一条数据contentL=', contentL)
|
|||
|
|
distributeCommandsWithDataStr(hex)
|
|||
|
|
} else if ((contentL + 5) * 2 > hex.length) { //需要分包接受数据
|
|||
|
|
// 第一次接受分包数据
|
|||
|
|
self.responseStr = hex;
|
|||
|
|
//console.log('分包接受数据未实现', hex)
|
|||
|
|
//console.log('第一次接受分包数据contentL2=', contentL)
|
|||
|
|
} else { //数据异常 ,查看
|
|||
|
|
//console.log('数据异常 ,查看1', hex)
|
|||
|
|
}
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
//console.log('分包接受数据未实现', hex)
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
verification();
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const verification = (mac, key1, key2) => {
|
|||
|
|
if (mac && key1 && key2) {
|
|||
|
|
//数据总长度为21,第一天长度20
|
|||
|
|
var buffer = new ArrayBuffer(20)
|
|||
|
|
var dataView = new DataView(buffer)
|
|||
|
|
dataView.setUint32(0, 0X6774108a)
|
|||
|
|
var sourceKey1 = mac + key1
|
|||
|
|
var AESEncrypt = AES128ECBEncrypt(sourceKey1, key2)
|
|||
|
|
if (AESEncrypt.length != 32) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
for (var i = 0; i < 4; i++) {
|
|||
|
|
var subStr = AESEncrypt.substring(i * 8, i * 8 + 8, 16);
|
|||
|
|
dataView.setUint32(i * 4 + 4, parseInt(subStr, 16)); //4字节01523947(16进制)-->>10进制数字-->放入dateView
|
|||
|
|
}
|
|||
|
|
var i;
|
|||
|
|
var bcc;//17为数据长度16+1
|
|||
|
|
for (i = 0; i < 17; i++) {
|
|||
|
|
bcc ^= dataView.getInt8(i + 3);
|
|||
|
|
}
|
|||
|
|
var buffer2 = new ArrayBuffer(1)
|
|||
|
|
var dataView2 = new DataView(buffer2)
|
|||
|
|
dataView2.setUint8(0, bcc)
|
|||
|
|
console.log('验证', bufTohex(buffer));
|
|||
|
|
writeBLECharacteristicValueWithBuff(buffer);
|
|||
|
|
setTimeout(() => {
|
|||
|
|
writeBLECharacteristicValueWithBuff(buffer2);
|
|||
|
|
}, 300);
|
|||
|
|
} else {
|
|||
|
|
var buffer = new ArrayBuffer(5)
|
|||
|
|
var dataView = new DataView(buffer)
|
|||
|
|
dataView.setUint32(0, 0X6774008a)
|
|||
|
|
dataView.setUint8(4, 0x8a)
|
|||
|
|
writeBLECharacteristicValueWithBuff(buffer);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const writeBLECharacteristicValueWithBuff = (buffer) => {
|
|||
|
|
uni.writeBLECharacteristicValue({
|
|||
|
|
deviceId: blueTooth.value.deviceId,
|
|||
|
|
serviceId: serviceId,
|
|||
|
|
characteristicId: characteristicId,
|
|||
|
|
value: buffer,
|
|||
|
|
success: function (res) {
|
|||
|
|
console.log('writeBLECharacteristicValue success', res.errMsg)
|
|||
|
|
},
|
|||
|
|
fail: function (res) {
|
|||
|
|
console.log('writeBLECharacteristicValue fail', res.errMsg)
|
|||
|
|
},
|
|||
|
|
complete: function (res) {
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
let verificationTimes = 0;
|
|||
|
|
const distributeCommandsWithDataStr = (hex) => {
|
|||
|
|
var cmd = hex.substring(6, 8);
|
|||
|
|
var code = hex.substring(8, 10);
|
|||
|
|
var errCode = code
|
|||
|
|
var desDic = {}
|
|||
|
|
var des = '';
|
|||
|
|
if (code == '00') {
|
|||
|
|
des = '成功'
|
|||
|
|
errCode = 0
|
|||
|
|
} else if (code == 'ff') { //-1
|
|||
|
|
des = '锁已打开'
|
|||
|
|
errCode = -1
|
|||
|
|
} else if (code == 'fe') { //-2
|
|||
|
|
des = '电量不足'
|
|||
|
|
errCode = -2
|
|||
|
|
} else if (code == 'fd') { //-3
|
|||
|
|
des = '加密验证失败'
|
|||
|
|
errCode = -3
|
|||
|
|
} else if (code == 'fc') { //-4
|
|||
|
|
des = '内存空间不足'
|
|||
|
|
errCode = -4
|
|||
|
|
} else if (code == 'fb') { //-5
|
|||
|
|
des = '格式错误'
|
|||
|
|
errCode = -5
|
|||
|
|
} else if (code == 'fa') { //-6
|
|||
|
|
des = '没有验证或验证失败'
|
|||
|
|
errCode = -6
|
|||
|
|
desDic['mac'] = hex.substring(10, 22);
|
|||
|
|
desDic['key'] = hex.substring(22, 30);
|
|||
|
|
} else if (code == 'f9') { //-7
|
|||
|
|
des = 'flash写入失败'
|
|||
|
|
errCode = -7
|
|||
|
|
} else if (code == 'f8') { //-8
|
|||
|
|
des = '数据空'
|
|||
|
|
errCode = -8
|
|||
|
|
} else if (code == 'f7') { //-9
|
|||
|
|
des = '操作失败'
|
|||
|
|
errCode = -9
|
|||
|
|
} else if (code == 'f6') { //-10
|
|||
|
|
des = '运输模式下无法执行该指令'
|
|||
|
|
errCode = -10
|
|||
|
|
} else if (code == 'f5') { //-11
|
|||
|
|
des = '锁车失败,车辆未停止'
|
|||
|
|
errCode = -11
|
|||
|
|
} else if (code == 'f4') { //-12
|
|||
|
|
des = '未检测到道钉信息'
|
|||
|
|
errCode = -12
|
|||
|
|
} else if (parseInt(code,16) == 149) { //
|
|||
|
|
des = '摄像头正在工作中'
|
|||
|
|
errCode = parseInt(code,16)
|
|||
|
|
} else if (parseInt(code,16) == 150) { //
|
|||
|
|
des = '摄像头离线'
|
|||
|
|
errCode = parseInt(code,16)
|
|||
|
|
} else if (parseInt(code,16) == 151) { //
|
|||
|
|
des = '车辆不在使用中(临时停车或是还车中)无法使用摄像头还车'
|
|||
|
|
errCode = parseInt(code,16)
|
|||
|
|
} else if (parseInt(code,16) == 152) { //
|
|||
|
|
des = '执行命令超时'
|
|||
|
|
errCode = parseInt(code,16)
|
|||
|
|
} else if (parseInt(code,16) == 153) { //
|
|||
|
|
des = '摄像头执行失败'
|
|||
|
|
errCode = parseInt(code,16)
|
|||
|
|
} else if (parseInt(code,16) == 154) { //
|
|||
|
|
des = '不在站点中或没有垂直停车'
|
|||
|
|
errCode = parseInt(code,16)
|
|||
|
|
} else {
|
|||
|
|
des = '未知错误码' + code
|
|||
|
|
errCode = code
|
|||
|
|
}
|
|||
|
|
console.log('distributeCommandsWithDataStr', hex)
|
|||
|
|
desDic['errCode'] = errCode
|
|||
|
|
desDic['des'] = des
|
|||
|
|
// if (cmd == '41') { //关锁指令
|
|||
|
|
// if (!that.data.fortifiedDing) {
|
|||
|
|
// if (that.BLESetUpDefences) {
|
|||
|
|
// desDic['CMD'] = '81'
|
|||
|
|
// that.BLESetUpDefences(desDic);
|
|||
|
|
// } else {
|
|||
|
|
// console.log('未找到BLESetUpDefences函数')
|
|||
|
|
// }
|
|||
|
|
// } else {
|
|||
|
|
// if (that.BLEFortifiedDing) {
|
|||
|
|
// // 6774108a
|
|||
|
|
// if (hex.length > 22) {
|
|||
|
|
// desDic['macDing'] = hex.substring(10, 22);
|
|||
|
|
// }
|
|||
|
|
// desDic['CMD'] = '81'
|
|||
|
|
// that.BLEFortifiedDing(desDic);
|
|||
|
|
// } else {
|
|||
|
|
// console.log('未找到BLEFortifiedDing函数')
|
|||
|
|
// }
|
|||
|
|
// }
|
|||
|
|
// }
|
|||
|
|
// else if (cmd == '42') { //开锁指令
|
|||
|
|
// if (that.BLEUnlock) {
|
|||
|
|
// desDic['CMD'] = '82'
|
|||
|
|
// that.BLEUnlock(desDic);
|
|||
|
|
// } else {
|
|||
|
|
// console.log('未找到BLEUnlock函数')
|
|||
|
|
// }
|
|||
|
|
// }
|
|||
|
|
// else if (cmd == '44') { //重启设备
|
|||
|
|
// if (that.BLEResetDevice) {
|
|||
|
|
// desDic['CMD'] = '84'
|
|||
|
|
// that.BLEResetDevice(desDic);
|
|||
|
|
// } else {
|
|||
|
|
// console.log('未找到BLEResetDevice函数')
|
|||
|
|
// }
|
|||
|
|
// }
|
|||
|
|
// else if (cmd == '46') { //修改设备工作模式
|
|||
|
|
// if (that.BLEUpdateDeviceMode) {
|
|||
|
|
// desDic['CMD'] = '86'
|
|||
|
|
// that.BLEUpdateDeviceMode(desDic);
|
|||
|
|
// } else {
|
|||
|
|
// console.log('未找到BLEUpdateDeviceMode函数')
|
|||
|
|
// }
|
|||
|
|
// }
|
|||
|
|
// else if (cmd == '47') { //获取版本信息
|
|||
|
|
// if (that.BLEGetVersionInfo) {
|
|||
|
|
// var hardwareVersion = hex.substring(10, 12);
|
|||
|
|
// var softwareVersion = hex.substring(12, 16);
|
|||
|
|
// desDic['CMD'] = '87'
|
|||
|
|
// desDic['hardwareVersion'] = hardwareVersion
|
|||
|
|
// desDic['softwareVersion'] = softwareVersion
|
|||
|
|
// that.BLEGetVersionInfo(desDic);
|
|||
|
|
// } else {
|
|||
|
|
// console.log('未找到BLEGetVersionInfo函数')
|
|||
|
|
// }
|
|||
|
|
// }
|
|||
|
|
// else if (cmd == '49') { //打开电池仓
|
|||
|
|
// if (that.BLEOpenTheBatteryCompartment) {
|
|||
|
|
// desDic['CMD'] = '89'
|
|||
|
|
// that.BLEOpenTheBatteryCompartment(desDic);
|
|||
|
|
// } else {
|
|||
|
|
// console.log('未找到BLEOpenTheBatteryCompartment函数')
|
|||
|
|
// }
|
|||
|
|
// }
|
|||
|
|
// else
|
|||
|
|
if (cmd == '4a') { //验证
|
|||
|
|
if (verificationTimes >= 1) {
|
|||
|
|
verificationTimes = 0
|
|||
|
|
if (errCode == -6) {
|
|||
|
|
verificationTimes = 1;
|
|||
|
|
verification(desDic.mac, desDic.key, '6666660000888888')
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
//验证成功
|
|||
|
|
return;
|
|||
|
|
} else {
|
|||
|
|
verificationTimes += 1;
|
|||
|
|
}
|
|||
|
|
if (errCode == -6) {
|
|||
|
|
verification(desDic.mac, desDic.key, '6666660000888888')
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
// else if (cmd == '4b') { //临时停车
|
|||
|
|
// if (that.BLETemporaryParking) {
|
|||
|
|
// desDic['CMD'] = '8b'
|
|||
|
|
// that.BLETemporaryParking(desDic);
|
|||
|
|
// } else {
|
|||
|
|
// console.log('未找到BLETemporaryParking函数')
|
|||
|
|
// }
|
|||
|
|
// }
|
|||
|
|
// else if (cmd == '4c') { //继续用车
|
|||
|
|
// if (that.BLEContinueUnlocking) {
|
|||
|
|
// desDic['CMD'] = '8c'
|
|||
|
|
// that.BLEContinueUnlocking(desDic);
|
|||
|
|
// } else {
|
|||
|
|
// console.log('未找到BLEContinueUnlocking函数')
|
|||
|
|
// }
|
|||
|
|
// }
|
|||
|
|
// else if (cmd == '4d') { //继续用车
|
|||
|
|
// if (that.BLEOpenHelmetLock) {
|
|||
|
|
// desDic['CMD'] = '8d'
|
|||
|
|
// that.BLEOpenHelmetLock(desDic);
|
|||
|
|
// } else {
|
|||
|
|
// console.log('未找到BLEOpenHelmetLock函数')
|
|||
|
|
// }
|
|||
|
|
// }
|
|||
|
|
// else if (cmd == '4e') { //摄像头还车 67740a 4e 95 00 000000ff 00000000 24
|
|||
|
|
// if (that.BLELockBikeWithCamera) {
|
|||
|
|
// desDic['CMD'] = '8e'
|
|||
|
|
// //摄像头执行的错误码
|
|||
|
|
// desDic['code'] = parseInt(hex.substring(10, 12),16)
|
|||
|
|
// // (目标图像识别到的图像角度,标识报砂识别到的目标图片与车头方向顺时针的角度值,如果未识别到的角度则 255)
|
|||
|
|
// desDic['angle'] = parseInt(hex.substring(12, 20),16)
|
|||
|
|
// // 如示例 0x01 0x01 0x00 0x01 从左到右 第一位 byte:芯片型号。值 01 海思;02 联咏 03 富瀚微 第二位 byte :标志系列 值 01 黄白,02 黄蓝,04 预留 11 多颜色输入适配 第三、四位 byte 低字节递增 :版本号如 0001,0002,0003
|
|||
|
|
// desDic['version'] = hex.substring(20, 28)
|
|||
|
|
// that.BLELockBikeWithCamera(desDic);
|
|||
|
|
// } else {
|
|||
|
|
// console.log('未找到BLELockBikeWithCamera函数')
|
|||
|
|
// }
|
|||
|
|
// }
|
|||
|
|
else {
|
|||
|
|
console.log('未找到对应指令及函数')
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const bufTohex = (buffer) => {
|
|||
|
|
return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join('');
|
|||
|
|
}
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
<style>
|
|||
|
|
.container {
|
|||
|
|
padding: 15px;
|
|||
|
|
background-color: #fff;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.unconn-icon{
|
|||
|
|
display: flex;
|
|||
|
|
/* 启用 Flexbox 布局 */
|
|||
|
|
justify-content: center;
|
|||
|
|
/* 水平居中 */
|
|||
|
|
align-items: center;
|
|||
|
|
/* 垂直居中 */
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.unconn-text{
|
|||
|
|
width: 100%;
|
|||
|
|
height: 80rpx;
|
|||
|
|
display: flex;
|
|||
|
|
/* 启用 Flexbox 布局 */
|
|||
|
|
justify-content: center;
|
|||
|
|
/* 水平居中 */
|
|||
|
|
align-items: center;
|
|||
|
|
/* 垂直居中 */
|
|||
|
|
color: #b4b4b4;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.lt-title {
|
|||
|
|
width: 30%;
|
|||
|
|
padding: 8px 0 0 0;
|
|||
|
|
font-size: 14px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.lt-state {
|
|||
|
|
width: 50%;
|
|||
|
|
display: flex;
|
|||
|
|
flex-direction: column;
|
|||
|
|
justify-content: center;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.lt-but {
|
|||
|
|
width: 20%;
|
|||
|
|
}
|
|||
|
|
</style>
|