100J蓝牙设备上报问题解决

This commit is contained in:
微微一笑
2026-03-31 13:57:21 +08:00
parent fe49ff631d
commit c64b140754
3 changed files with 27 additions and 28 deletions

View File

@ -163,7 +163,12 @@ class HBY100JProtocol {
this.onNotifyCallback = callback; this.onNotifyCallback = callback;
} }
parseBleData(buffer) { /**
* @param {Uint8Array|ArrayBuffer} buffer
* @param {{ skipSideEffects?: boolean }} [options] skipSideEffects=true仅解析字段不打日志、不触发 onNotify/文件回调(供 BleReceive 与设备页 bleValueNotify 双订阅时避免重复)
*/
parseBleData(buffer, options = {}) {
const skipSideEffects = !!options.skipSideEffects;
const view = buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer); const view = buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer);
if (view.length < 3) return null; if (view.length < 3) return null;
@ -175,8 +180,10 @@ class HBY100JProtocol {
const macBytes = view.slice(1, 7); const macBytes = view.slice(1, 7);
const macAddress = Array.from(macBytes).map(b => b.toString(16).padStart(2, '0').toUpperCase()).join(':'); const macAddress = Array.from(macBytes).map(b => b.toString(16).padStart(2, '0').toUpperCase()).join(':');
const result = { type: 'mac', macAddress }; const result = { type: 'mac', macAddress };
console.log('[100J-蓝牙] 设备上报MAC:', macAddress, '原始:', Array.from(view).map(b => b.toString(16).padStart(2, '0').toUpperCase()).join(' ')); if (!skipSideEffects) {
if (this.onNotifyCallback) this.onNotifyCallback(result); console.log('[100J-蓝牙] 设备上报MAC:', macAddress, '原始:', Array.from(view).map(b => b.toString(16).padStart(2, '0').toUpperCase()).join(' '));
if (this.onNotifyCallback) this.onNotifyCallback(result);
}
return result; return result;
} }
@ -206,7 +213,7 @@ class HBY100JProtocol {
// 05: 文件更新响应 FB 05 [fileType] [status] FFstatus: 1=成功 2=失败 // 05: 文件更新响应 FB 05 [fileType] [status] FFstatus: 1=成功 2=失败
if (data.length >= 1) result.fileType = data[0]; if (data.length >= 1) result.fileType = data[0];
if (data.length >= 2) result.fileStatus = data[1]; // 1=Success, 2=Failure if (data.length >= 2) result.fileStatus = data[1]; // 1=Success, 2=Failure
if (this._fileResponseResolve) this._fileResponseResolve(result); if (!skipSideEffects && this._fileResponseResolve) this._fileResponseResolve(result);
break; break;
case 0x04: case 0x04:
// 5.5 获取设备电源状态: 容量8B + 电压8B + 百分比1B + 车载1B + 续航2B(分钟) + [充电状态1B] + FF // 5.5 获取设备电源状态: 容量8B + 电压8B + 百分比1B + 车载1B + 续航2B(分钟) + [充电状态1B] + FF
@ -265,10 +272,11 @@ class HBY100JProtocol {
const funcNames = { 0x01: '复位', 0x02: '基础信息', 0x03: '位置', 0x04: '电源状态', 0x05: '文件更新', 0x06: '语音播报', 0x09: '音量', 0x0A: '爆闪模式', 0x0B: '爆闪频率', 0x0C: '强制报警', 0x0D: 'LED亮度', 0x0E: '工作方式' }; const funcNames = { 0x01: '复位', 0x02: '基础信息', 0x03: '位置', 0x04: '电源状态', 0x05: '文件更新', 0x06: '语音播报', 0x09: '音量', 0x0A: '爆闪模式', 0x0B: '爆闪频率', 0x0C: '强制报警', 0x0D: 'LED亮度', 0x0E: '工作方式' };
const name = funcNames[funcCode] || ('0x' + funcCode.toString(16)); const name = funcNames[funcCode] || ('0x' + funcCode.toString(16));
console.log('[100J-蓝牙] 设备响应 FB:', name, '解析:', JSON.stringify(result), '原始:', hexStr); if (!skipSideEffects) {
console.log('[100J-蓝牙] 设备响应 FB:', name, '解析:', JSON.stringify(result), '原始:', hexStr);
if (this.onNotifyCallback) { if (this.onNotifyCallback) {
this.onNotifyCallback(result); this.onNotifyCallback(result);
}
} }
return result; return result;
} }
@ -883,9 +891,9 @@ export function cache100JVoiceFileForBle(deviceId, voiceListId, filePath) {
}); });
} }
// 暴露给页面:解析蓝牙接收到的数据 // 暴露给页面:解析蓝牙接收到的数据options 见类上 parseBleData 注释)
export function parseBleData(buffer) { export function parseBleData(buffer, options) {
return protocolInstance.parseBleData(buffer); return protocolInstance.parseBleData(buffer, options);
} }
// 暴露给页面:蓝牙连接后主动拉取电源状态(电量、续航) // 暴露给页面:蓝牙连接后主动拉取电源状态(电量、续航)

View File

@ -1728,28 +1728,18 @@ class BleHelper {
return linkDevice(deviceId); return linkDevice(deviceId);
}).then((res) => { }).then((res) => {
if (res) { //新连接 if (res) { //新连接(含 createBLEConnection 刚成功)
// console.log("11111111"); // console.log("11111111");
if (fIndex == -1) { if (fIndex == -1) {
// console.log("开始获取服务", targetServiceId) // console.log("开始获取服务", targetServiceId)
return this.getService(deviceId, targetServiceId, writeCharId, return this.getService(deviceId, targetServiceId, writeCharId,
notifyCharId); //获取服务 notifyCharId); //获取服务
} else { } else {
if (f.wirteCharactId && f.notifyCharactId) { // 设备已在 LinkedList例如缓存/重连):不能仅用缓存的 write/notify UUID 直接订阅。
if (!f.notifyState) { // 重连后须先 getBLEDeviceServices否则部分机型 notifyBLECharacteristicValueChange 报 no service(10004)notify 收不到任何数据。
// console.log("开始订阅特征"); console.log("已缓存设备重新连接,重新发现服务并订阅", deviceId);
this.subScribe(deviceId, true); return this.getService(deviceId, targetServiceId, writeCharId,
} else { notifyCharId);
console.log("不订阅消息");
}
return Promise.resolve(true);
} else {
console.log("开始获取服务", targetServiceId)
return this.getService(deviceId, targetServiceId, writeCharId,
notifyCharId);
}
} }
} else { //已连接过,直接订阅消息 } else { //已连接过,直接订阅消息
// console.log("11111111"); // console.log("11111111");

View File

@ -693,7 +693,8 @@ class BleReceive {
let receiveData = {}; let receiveData = {};
try { try {
if (!receive.bytes || receive.bytes.length < 3) return receiveData; if (!receive.bytes || receive.bytes.length < 3) return receiveData;
const parsed = parseBleData(receive.bytes); // 与 HBY100-J 页 bleValueNotify 共用 notify避免 parseBleData 执行两次重复日志、FB05 双次 resolve、onNotify 双次
const parsed = parseBleData(receive.bytes, { skipSideEffects: true });
if (!parsed) return receiveData; if (!parsed) return receiveData;
if (parsed.longitude !== undefined) receiveData.longitude = parsed.longitude; if (parsed.longitude !== undefined) receiveData.longitude = parsed.longitude;
if (parsed.latitude !== undefined) receiveData.latitude = parsed.latitude; if (parsed.latitude !== undefined) receiveData.latitude = parsed.latitude;