From c64b1407547d638021f6e5063d17df6968e42519 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=AE=E5=BE=AE=E4=B8=80=E7=AC=91?= <709648985@qq.com> Date: Tue, 31 Mar 2026 13:57:21 +0800 Subject: [PATCH] =?UTF-8?q?100J=E8=93=9D=E7=89=99=E8=AE=BE=E5=A4=87?= =?UTF-8?q?=E4=B8=8A=E6=8A=A5=E9=97=AE=E9=A2=98=E8=A7=A3=E5=86=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/100J/HBY100-J.js | 30 +++++++++++++++++++----------- utils/BleHelper.js | 22 ++++++---------------- utils/BleReceive.js | 3 ++- 3 files changed, 27 insertions(+), 28 deletions(-) diff --git a/api/100J/HBY100-J.js b/api/100J/HBY100-J.js index 3369ebb..76f4448 100644 --- a/api/100J/HBY100-J.js +++ b/api/100J/HBY100-J.js @@ -163,7 +163,12 @@ class HBY100JProtocol { 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); if (view.length < 3) return null; @@ -175,8 +180,10 @@ class HBY100JProtocol { const macBytes = view.slice(1, 7); const macAddress = Array.from(macBytes).map(b => b.toString(16).padStart(2, '0').toUpperCase()).join(':'); const result = { type: 'mac', macAddress }; - console.log('[100J-蓝牙] 设备上报MAC:', macAddress, '原始:', Array.from(view).map(b => b.toString(16).padStart(2, '0').toUpperCase()).join(' ')); - if (this.onNotifyCallback) this.onNotifyCallback(result); + if (!skipSideEffects) { + 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; } @@ -206,7 +213,7 @@ class HBY100JProtocol { // 05: 文件更新响应 FB 05 [fileType] [status] FF,status: 1=成功 2=失败 if (data.length >= 1) result.fileType = data[0]; 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; case 0x04: // 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 name = funcNames[funcCode] || ('0x' + funcCode.toString(16)); - console.log('[100J-蓝牙] 设备响应 FB:', name, '解析:', JSON.stringify(result), '原始:', hexStr); - - if (this.onNotifyCallback) { - this.onNotifyCallback(result); + if (!skipSideEffects) { + console.log('[100J-蓝牙] 设备响应 FB:', name, '解析:', JSON.stringify(result), '原始:', hexStr); + if (this.onNotifyCallback) { + this.onNotifyCallback(result); + } } return result; } @@ -883,9 +891,9 @@ export function cache100JVoiceFileForBle(deviceId, voiceListId, filePath) { }); } -// 暴露给页面:解析蓝牙接收到的数据 -export function parseBleData(buffer) { - return protocolInstance.parseBleData(buffer); +// 暴露给页面:解析蓝牙接收到的数据(options 见类上 parseBleData 注释) +export function parseBleData(buffer, options) { + return protocolInstance.parseBleData(buffer, options); } // 暴露给页面:蓝牙连接后主动拉取电源状态(电量、续航) diff --git a/utils/BleHelper.js b/utils/BleHelper.js index f8ed745..6795947 100644 --- a/utils/BleHelper.js +++ b/utils/BleHelper.js @@ -1728,28 +1728,18 @@ class BleHelper { return linkDevice(deviceId); }).then((res) => { - if (res) { //新连接 + if (res) { //新连接(含 createBLEConnection 刚成功) // console.log("11111111"); if (fIndex == -1) { // console.log("开始获取服务", targetServiceId) return this.getService(deviceId, targetServiceId, writeCharId, notifyCharId); //获取服务 } else { - if (f.wirteCharactId && f.notifyCharactId) { - if (!f.notifyState) { - // console.log("开始订阅特征"); - this.subScribe(deviceId, true); - } else { - console.log("不订阅消息"); - } - return Promise.resolve(true); - } else { - console.log("开始获取服务", targetServiceId) - return this.getService(deviceId, targetServiceId, writeCharId, - notifyCharId); - } - - + // 设备已在 LinkedList(例如缓存/重连):不能仅用缓存的 write/notify UUID 直接订阅。 + // 重连后须先 getBLEDeviceServices,否则部分机型 notifyBLECharacteristicValueChange 报 no service(10004),notify 收不到任何数据。 + console.log("已缓存设备重新连接,重新发现服务并订阅", deviceId); + return this.getService(deviceId, targetServiceId, writeCharId, + notifyCharId); } } else { //已连接过,直接订阅消息 // console.log("11111111"); diff --git a/utils/BleReceive.js b/utils/BleReceive.js index 4a62373..6667509 100644 --- a/utils/BleReceive.js +++ b/utils/BleReceive.js @@ -693,7 +693,8 @@ class BleReceive { let receiveData = {}; try { 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.longitude !== undefined) receiveData.longitude = parsed.longitude; if (parsed.latitude !== undefined) receiveData.latitude = parsed.latitude;