1
0
forked from dyf/APP

650蓝牙协议更新

This commit is contained in:
liub
2025-08-05 13:14:22 +08:00
parent a3865e2f26
commit b3c0b74628
14 changed files with 4394 additions and 206 deletions

View File

@ -22,10 +22,10 @@
</view>
</view>
<view class="eqinfo">
<view class="item">
<!-- <view class="item">
<text class="lbl">蓝牙名称</text>
<text class="value">{{formData.name}}</text>
</view>
</view> -->
<view class="item">
<text class="lbl">照明档位</text>
<text class="value">{{formData.RSSI}}</text>
@ -34,6 +34,10 @@
<text class="lbl">探测档位</text>
<text class="value">{{formData.statu}}</text>
</view>
<view class="item">
<text class="lbl">预警级别</text>
<text class="value">{{formData.warnLevel}}</text>
</view>
</view>
<!-- <view class="lamp">
<view class="title">
@ -167,7 +171,8 @@
<script>
import gbk from '@/utils/gbk.js'
import ble from '@/api/6155/BlueHelper';
import BleTool from '@/utils/BleHelper.js'
var ble = null;
export default {
data() {
return {
@ -252,7 +257,9 @@
name: 'JQZM-EF4651',
RSSI: '-30',
statu: '运行中',
liangDu: '50'
liangDu: '50',
warnLevel: '',
macAddress: ''
},
cEdit: {
mode: ''
@ -267,8 +274,8 @@
deviceId: '',
writeServiceId: '',
wirteCharactId: '',
notifyServiceid:'',
notifyCharactId:''
notifyServiceid: '',
notifyCharactId: ''
},
videoHexArray: []
}
@ -276,6 +283,7 @@
onLoad: function() {
var these = this;
ble = BleTool.getBleTool();
let eventChannel = this.getOpenerEventChannel();
//eventChannel.on('receivdata', function(data) {
@ -296,23 +304,37 @@
these.formData.img = device.devicePic;
these.formData.id = device.id;
//});
ble.featrueValueCallback = these.bleValueNotify;
ble.OpenBlue(true, () => {
ble.StartSearch((res) => {
ble.addReceiveCallback(these.bleValueNotify);
let startLink=()=>{
ble.addDeviceFound((res) => {
console.log("发现新设备,",res);
let f = res.devices.find((v) => {
return v.name == 'JQZM-EF4651';
return v.name == device.deviceName;
});
if (f) {
ble.StopSearch();
console.log("找到了目标设备,正在连接:"+f.deviceId)
these.device.deviceId = f.deviceId;
these.formData.id = f.deviceId;
ble.LinkBlue(f.deviceId);
}
})
})
});
ble.StartSearch();
}
if(ble.data.LinkedList && ble.data.LinkedList.length>0){
let f=ble.data.LinkedList.find((v)=>{
return v.name==device.deviceName;
});
if(!f){
startLink();
}else{
these.device.deviceId = f.deviceId;
these.formData.id = f.deviceId;
}
}else{
startLink();
}
},
onHide: function() {
@ -380,119 +402,107 @@
},
methods: {
bleValueNotify: function(receive) { //订阅消息
console.log("收到订阅消息", receive);
var these = this;
var bytesToHexString =
function(bytes) {
return bytes.map(
byte =>
byte
.toString(
16)
.padStart(
2, '0')
).join(' ');
}
var parseData = (
bytes) => {
if (bytes.length < 6) {
console.warn('数据包长度不足至少需要6个字节');
return;
}
try {
// 跳过帧头(第一个字节),从第二个字节开始解析
const staticLevelByte = bytes[1];
let staticLevelText = '未知';
let modeCurr = '';
switch (staticLevelByte) {
case 0x65:
staticLevelText = '高档';
modeCurr = 'hight';
break;
case 0x66:
staticLevelText = '中档';
modeCurr = 'center';
break;
case 0x67:
staticLevelText = '低档';
modeCurr = 'low';
break;
case 0x68:
staticLevelText = '关闭';
modeCurr = 'close';
break;
if (bytes[0] == 0x55) {
try {
let staticLevelByte = bytes[1];
let staticLevelText = '未知';
let modeCurr = "";
switch (staticLevelByte) {
case 0x65:
staticLevelText = '高档';
modeCurr = "hight";
break;
case 0x66:
staticLevelText = '中档';
modeCurr = "center";
break;
case 0x67:
staticLevelText = '低档';
modeCurr = "low";
break;
case 0x68:
staticLevelText = '关闭';
modeCurr = "close";
break;
}
// 解析照明档位
let lightingLevelByte = bytes[2];
let lightingLevelText = lightingLevelByte === 0x6e ? '开启' : '关闭';
// 解析剩余照明时间(第三和第四字节,大端序)
let lightingTime =(bytes[3] <<8) | bytes[4];
let hours = Math.floor(lightingTime / 60);
let remainingMinutes = lightingTime % 60;
let xuhang = '0分';
// 处理不同情况的显示
if (hours === 0) {
xuhang = `${remainingMinutes}`;
} else if (remainingMinutes === 0) {
xuhang = `${hours}小时`;
} else {
xuhang = `${hours}小时${remainingMinutes}`;
}
// 解析剩余电量
let batteryLevelByte = bytes[5];
// 电量百分比范围检查
let batteryLevel = Math.max(0, Math.min(100, batteryLevelByte));
let warn = bytes[6];
if (warn == 0x00) {
warn = '无预警';
} else if (warn == 0x01) {
warn = '弱预警';
} else if (warn == 0x02) {
warn = '中预警';
} else if (warn == 0x03) {
warn = '强预警';
} else if (warn == 0x04) {
warn = '非常强预警';
}
these.formData.battary = batteryLevel;
these.formData.xuhang = xuhang;
these.Status.cMode = lightingLevelByte === 0x6e;
these.Status.modeCurr = modeCurr;
these.formData.warnLevel = warn;
} catch (error) {
console.error('数据解析错误:', error);
}
// 解析照明档位
const lightingLevelByte = bytes[2];
const lightingLevelText = lightingLevelByte === 0x6e ? '开启' : '关闭';
// 解析剩余照明时间(第三和第四字节,小端序)
const lightingTime = (bytes[4] << 8) | bytes[3];
// 解析剩余电量
const batteryLevelByte = bytes[5];
// 电量百分比范围检查
const batteryLevel = Math.max(0, Math.min(100, batteryLevelByte));
console.log('解析结果:', {
staticLevel: staticLevelText,
lightingLevel: lightingLevelText,
lightingTime: `${lightingTime} 分钟`,
batteryLevel: `${batteryLevel}%`
});
let hours = Math.floor(lightingTime / 60);
let remainingMinutes = lightingTime % 60;
let xuhang = '0分';
// 处理不同情况的显示
if (hours === 0) {
xuhang = `${remainingMinutes}`;
} else if (remainingMinutes === 0) {
xuhang = `${hours}小时`;
} else {
xuhang = `${hours}小时${remainingMinutes}`;
} else {
try {
let uint8Array = new Uint8Array(receive.value);
let str = '';
for (let i = 0; i < uint8Array.length; i++) {
// 将每个字节转换为对应的字符
str += String.fromCharCode(uint8Array[i]);
}
if (str.indexOf('mac address:') == 0) {
these.formData.macAddress = str.split(':')[1];
console.log("收到mac地址:", )
} else {
console.log("收到无法解析的字符串:", str)
}
} catch (ex) {
console.log("将数据转文本失败", ex);
}
these.formData.battary = batteryLevel;
these.formData.xuhang = xuhang;
these.Status.cMode = lightingLevelByte === 0x6e;
these.Status.modeCurr = modeCurr;
console.log("curr=", {
battary: batteryLevel,
xuhang: xuhang,
cMode: these.Status.cMode,
modeCurr: modeCurr
});
} catch (error) {
console.error('数据解析错误:', error);
}
}
const dataView =
new DataView(receive
.value);
// 转换为字节数组
const bytes = [];
for (let i = 0; i <
dataView
.byteLength; i++) {
bytes.push(dataView
.getUint8(i));
}
// 保存原始数据用于调试
this.receivedData = bytes;
console.log('接收到原始数据:',
bytesToHexString(
bytes));
const bytes = receive.bytes;
parseData(bytes);
@ -500,50 +510,19 @@
},
getDevice: function() {
var these = this;
if (this.device.deviceId && this.device.writeServiceId && this.device.wirteCharactId) {
return this.device;
}
let key = "linkedDevices";
var store = uni.getStorageInfoSync();
var f = store.keys.find(function(v) {
return v == key;
let f = ble.data.LinkedList.find((v) => {
return v.deviceId == these.device.deviceId;
});
// console.log("倒计时5");
var linkedDevices = [];
if (f) {
var str = uni.getStorageSync(key);
if (str) {
linkedDevices = JSON.parse(str);
}
}
// console.log("倒计时4");
if (linkedDevices && linkedDevices.length && linkedDevices.length > 0) {
// console.log("倒计时3");
f = linkedDevices.find(function(v) {
if(v.deviceId == these.device.deviceId){
these.device.writeServiceId=v.writeServiceId;
these.device.wirteCharactId=v.wirteCharactId;
these.device.notifyServiceid=v.notifyServiceid;
these.device.notifyCharactId=v.notifyCharactId;
return true;
}
return false;
});
} else {
f = null;
}
return f;
},
MainModeSetting: function(type, byteType) {
if (this.Status.modeCurr == type) {
return;
}
this.Status.modeCurr = type;
let dataValue = 0x00;
let btype = 0x00;
@ -592,22 +571,30 @@
dataView.setUint8(5, dataValue); // 数据
let f = this.getDevice();
if (f) {
// 发送数据
ble.LinkBlue(f.deviceId, (id, flag) => {
setTimeout(() => {
ble.sendDataNew(f.deviceId, f.writeServiceId, f.wirteCharactId, buffer);
}, flag ? 0 : 1000);
ble.sendData(f.deviceId, buffer, f.writeServiceId, f.wirteCharactId, 50).then(()=>{
console.log("发送成功了");
}).catch((ex)=>{
uni.showModal({
title:'提示',
content:ex.msg
})
});
} else {
console.log("333333");
}
},
LampToggle: function() {
this.Status.cMode = !this.Status.cMode;
this.MainModeSetting(this.Status.cMode, "lamp");
},
@ -711,7 +698,7 @@
let currentPacket = 1;
let f = these.getDevice();
if (f) {
// 发送单个数据包
const sendNextPacket = () => {
@ -744,12 +731,12 @@
}
const packetData = imageData.slice(startIndex,
endIndex); // imageData.subarray(startIndex, endIndex);
console.log("imageData.length=" + imageData.length +
",startIndex=" +
startIndex +
",endIndex=" + endIndex + ",数据包长度" + (endIndex -
startIndex) +
',packetData.length=' + packetData.length);
// console.log("imageData.length=" + imageData.length +
// ",startIndex=" +
// startIndex +
// ",endIndex=" + endIndex + ",数据包长度" + (endIndex -
// startIndex) +
// ',packetData.length=' + packetData.length);
// 构建数据包
const bufferSize = 5 + packetData.length * 2; // 头部5字节 + 数据部分
const buffer = new ArrayBuffer(bufferSize);
@ -786,30 +773,36 @@
//发送数据包
ble.sendDataNew(f.deviceId, f.writeServiceId, f.wirteCharactId,
buffer).then(() => {
ble.sendData(f.deviceId, buffer, f.writeServiceId, f.wirteCharactId, 50)
.then(() => {
these.Status.Progress.curr = currentPacket;
currentPacket++;
these.Status.Progress.curr = currentPacket;
currentPacket++;
setTimeout(sendNextPacket, 40);
}).catch(err => {
console.log("发送数据包失败了" + JSON.stringify(err));
if(err.code=='10007'){
setTimeout(sendNextPacket, 40);
return;
}
these.Status.BottomMenu.show = false;
these.Status.Progress.show = false;
these.alert("发送数据包失败了");
uni.hideLoading();
reject(err);
});
setTimeout(sendNextPacket, 0);
}).catch(err => {
console.log("发送数据包失败了" + JSON.stringify(err));
if (err.code == '10007') {
setTimeout(sendNextPacket, 0);
return;
}
these.Status.BottomMenu.show = false;
these.Status.Progress.show = false;
uni.showModal({
title:'提示',
content:err.msg
})
uni.hideLoading();
reject(err);
});
}
// 开始牵手
these.HoldYouHand("picture transmit start", 120, f.deviceId, f.writeServiceId,f.wirteCharactId).then(() => {
these.HoldYouHand("picture transmit start", 120, f.deviceId, f.writeServiceId,
f.wirteCharactId).then(() => {
sendNextPacket();
}).catch((err) => {
console.log("握手没有成功");
@ -871,7 +864,8 @@
uni.showLoading({
title: "上传中"
});
let p1 = these.HoldYouHand("video transmit start", 2200, f.deviceId, f.writeServiceId,f.wirteCharactId);
let p1 = these.HoldYouHand("video transmit start", 2200, f.deviceId, f.writeServiceId,
f.wirteCharactId);
let p2 = new Promise((succ, err) => {
uni.uploadFile({
url: 'http://114.55.111.217/video/upload',
@ -944,7 +938,7 @@
console.log("发送数据准备中,总共" + totalPackets);
// 发送单个数据包
const sendNextVideoPacket = () => {
////console.log("currentPacket="+currentPacket+",imageData.length="+imageData.length);
console.log("准备发送一段数据");
if (currentPacket > totalPackets) {
these.Status.BottomMenu.show = false;
these.Status.Progress.show = false;
@ -995,19 +989,34 @@
}
let inteval = 50;
ble.sendDataNew(f.deviceId, f.writeServiceId, f.wirteCharactId,
buffer).then(() => {
console.log("开始发送一段视频"); //
ble.sendData(f.deviceId, buffer, f.writeServiceId, f
.wirteCharactId, inteval).then(() => {
these.Status.Progress.curr = currentPacket;
currentPacket++;
console.log("发送一段成功,发送下一段");
setTimeout(sendNextVideoPacket, inteval);
}).catch(err => {
console.log(err.errMsg + ",发送失败了,正在补偿:" +
currentPacket);
setTimeout(sendNextVideoPacket, inteval);
if(err.code=='10007'){//遇到这个错误自动重新发送
console.log(err.errMsg + ",发送失败了,正在补偿:" +
currentPacket);
setTimeout(sendNextVideoPacket, inteval);
}
else{
these.Status.BottomMenu.show = false;
these.Status.Progress.show = false;
these.Status.Pop.showPop = true;
these.Status.Pop.message = err.msg+",发送失败了";
these.Status.Pop.borderColor="#e034344d";
these.Status.Pop.buttonBgColor="#E03434";
these.Status.Pop.buttonText="确定";
these.Status.Pop.iconUrl =
"/static/images/6155/DeviceDetail/uploadErr.png";
reject(err);
return;
}
});
};
@ -1203,7 +1212,7 @@
// 发送数据包
ble.sendDataNew(f.deviceId, f.writeServiceId, f.wirteCharactId, buffer).then(() => {
ble.sendData(f.deviceId, buffer, f.writeServiceId, f.wirteCharactId, 50).then(() => {
// 更新进度
console.log(
`发送文字数据包 ${currentPacket}/${totalPackets}: ${text}`
@ -1211,7 +1220,7 @@
// 发送下一个包
currentPacket++;
setTimeout(sendNextPacket, 100);
setTimeout(sendNextPacket, 0);
}).catch(err => {
// this.isSendingText = false;
uni.showToast({
@ -1234,7 +1243,7 @@
these.HoldYouHand("word transmit start", 120, f.deviceId, f.writeServiceId, f.wirteCharactId).then(
() => {
() => {
setTimeout(sendText, 200);
}).catch((ex) => {
@ -1265,18 +1274,19 @@
dataView.setUint8(i, str.charCodeAt(i));
}
console.log("开始握手");
ble.LinkBlue(deviceid, () => {
ble.sendDataNew(deviceid, serviceid, characid, buffer).then(
() => {
setTimeout(() => {
console.log("握手成功并完成了等待");
resolve(true);
}, pauseTime);
}).catch(err => {
reject(err);
});
ble.sendData(deviceid, buffer, serviceid, characid, 50).then(
() => {
setTimeout(() => {
console.log("握手成功并完成了等待");
resolve(true);
}, pauseTime);
}).catch(err => {
console.log("握手没有成功",)
reject(err);
});
});