@jiabaida/tools 1.0.7 → 1.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dist/cjs/core/BleApiManager.js +1 -1
  2. package/dist/cjs/core/BleCmdAnalysis/BaseParamProtocol.js +1 -1
  3. package/dist/cjs/core/BleCmdAnalysis/BleCmdAnalysis.js +1 -1
  4. package/dist/cjs/core/BleCmdAnalysis/BleCmdDD.js +1 -1
  5. package/dist/cjs/core/BleCmdAnalysis/BleCmdDDA4.js +1 -1
  6. package/dist/cjs/core/BleCmdAnalysis/BleCmdFFAA.js +1 -1
  7. package/dist/cjs/core/BleCmdAnalysis/readAndSetParam.js +1 -1
  8. package/dist/cjs/core/BleDataProcess.js +1 -1
  9. package/dist/cjs/core/OtaUpgrade.js +1 -1
  10. package/dist/cjs/core/Queue.js +1 -0
  11. package/dist/cjs/core/mqttServer.js +1 -1
  12. package/dist/cjs/core/tcpServer.js +1 -0
  13. package/dist/cjs/index.js +1 -1
  14. package/dist/esm/core/BleApiManager.js +1 -1
  15. package/dist/esm/core/BleCmdAnalysis/BaseParamProtocol.js +1 -1
  16. package/dist/esm/core/BleCmdAnalysis/BleCmdAnalysis.js +1 -1
  17. package/dist/esm/core/BleCmdAnalysis/BleCmdDD.js +1 -1
  18. package/dist/esm/core/BleCmdAnalysis/BleCmdDDA4.js +1 -1
  19. package/dist/esm/core/BleCmdAnalysis/BleCmdFFAA.js +1 -1
  20. package/dist/esm/core/BleCmdAnalysis/BleCmdHVES.js +1 -1
  21. package/dist/esm/core/BleCmdAnalysis/readAndSetParam.js +1 -1
  22. package/dist/esm/core/BleDataProcess.js +1 -1
  23. package/dist/esm/core/OtaUpgrade.js +1 -1
  24. package/dist/esm/core/Queue.js +1 -0
  25. package/dist/esm/core/mqttServer.js +1 -1
  26. package/dist/esm/core/tcpServer.js +1 -0
  27. package/dist/esm/index.js +1 -1
  28. package/package.json +1 -1
  29. package/src/core/BleApiManager.js +33 -15
  30. package/src/core/BleCmdAnalysis/BaseParamProtocol.js +116 -32
  31. package/src/core/BleCmdAnalysis/BleCmdAnalysis.js +58 -2
  32. package/src/core/BleCmdAnalysis/BleCmdDD.js +88 -19
  33. package/src/core/BleCmdAnalysis/BleCmdDDA4.js +154 -227
  34. package/src/core/BleCmdAnalysis/BleCmdFFAA.js +1 -0
  35. package/src/core/BleCmdAnalysis/readAndSetParam.js +133 -16
  36. package/src/core/BleDataProcess.js +15 -11
  37. package/src/core/OtaUpgrade.js +356 -350
  38. package/src/core/Queue.js +34 -0
  39. package/src/core/mqttServer.js +75 -5
  40. package/src/core/tcpServer.js +341 -0
  41. package/src/index.js +1 -0
@@ -1,6 +1,12 @@
1
1
  import { ref } from 'vue';
2
2
  import { ab2decimalArr, hexToDecimal } from './BleDataProcess';
3
3
  import { eventBus, getOS } from './commonfun'; // 导入eventBus
4
+ // #ifdef MP-WEIXIN
5
+ import { tcpServer } from './tcpServer.js';
6
+ // #endif
7
+ // #ifdef APP-PLUS
8
+ import { mqttServer } from './mqttServer.js';
9
+ // #endif
4
10
  const serviceId = '0000FF00-0000-1000-8000-00805F9B34FB';
5
11
  const UUID_READ = '0000FF01-0000-1000-8000-00805F9B34FB';
6
12
  const UUID_WRITE = '0000FF02-0000-1000-8000-00805F9B34FB';
@@ -40,11 +46,11 @@ export const enhanceDevice = (device) => {
40
46
  const productType = advHex.slice(18, 20);
41
47
  let protocolVersion = advHex.slice(20, 22);
42
48
  if (protocolVersion) {
43
- const v = hexToDecimal(protocolVersion)
44
- if (macAddr.startsWith("A5:C2") && v <= 0x23) {
45
- protocolVersion = '01';
46
- }
49
+ const v = hexToDecimal(protocolVersion)
50
+ if (macAddr.startsWith("A5:C2") && v <= 0x23) {
51
+ protocolVersion = '01';
47
52
  }
53
+ }
48
54
  const appkeyStatus = advHex.slice(22, 24);
49
55
  const tempVoltage = advHex.slice(24, 26);
50
56
  const voltage = tempVoltage || tempVoltage == 0 ? hexToDecimal(tempVoltage) : '';
@@ -66,7 +72,7 @@ export const enhanceDevice = (device) => {
66
72
  * 105:请授权微信位置信息和蓝牙权限 --- 打开手机内微信权限设置页面 openAppAuthorizeSetting
67
73
  * 106:请授权蓝牙和位置权限,并重启小程序 --- 打开小程序设置页面 openSetting
68
74
  */
69
- export const checkBluetoothStatus = async (successCallback = () => {}) => {
75
+ export const checkBluetoothStatus = async (successCallback = () => { }) => {
70
76
  return new Promise((resolve, reject) => {
71
77
  uni.openBluetoothAdapter({
72
78
  success: async (res) => {
@@ -89,7 +95,7 @@ export const checkBluetoothStatus = async (successCallback = () => {}) => {
89
95
  });
90
96
  }
91
97
 
92
- export const checkLocationStatus = async (successCallback = () => {}) => {
98
+ export const checkLocationStatus = async (successCallback = () => { }) => {
93
99
  // 创建超时Promise
94
100
  const timeoutPromise = new Promise((resolve, reject) => {
95
101
  setTimeout(() => {
@@ -124,7 +130,7 @@ export const checkLocationStatus = async (successCallback = () => {}) => {
124
130
  })
125
131
  }
126
132
 
127
- export const getBluetoothPermission = async (successCallback = () => {}) => {
133
+ export const getBluetoothPermission = async (successCallback = () => { }) => {
128
134
  try {
129
135
  if (isAndroid) {
130
136
  return await checkLocationStatus(successCallback);
@@ -147,13 +153,13 @@ export const initBle = async () => {
147
153
  const initBluetoothSuccessCb = () => {
148
154
  console.log('初始化蓝牙成功initBluetoothSuccessCb1');
149
155
  try {
150
- if(isInit) return;
156
+ if (isInit) return;
151
157
  onBluetoothDeviceFound();
152
158
  onBLECharacteristicValueChange();
153
159
  onBLEConnectionStateChange();
154
160
  onBluetoothAdapterStateChange()
155
161
  isInit = true;
156
- } catch (error) {
162
+ } catch (error) {
157
163
  throw error;
158
164
  }
159
165
  }
@@ -274,6 +280,15 @@ export const onBLEConnectionStateChange = async () => {
274
280
  console.log('onBLEConnectionStateChange', characteristic);
275
281
  // 触发事件总线事件
276
282
  eventBus.emit('setBleChangedConnectionState', characteristic);
283
+ if (!characteristic.connected) {
284
+ // #ifdef APP-PLUS
285
+ mqttServer.closeMqttByDeviceId(characteristic.deviceId)
286
+ // #endif
287
+ // #ifdef MP-WEIXIN
288
+ // 连接失败
289
+ tcpServer.closeTcpSocket(characteristic.deviceId);
290
+ // #endif
291
+ }
277
292
  });
278
293
  };
279
294
 
@@ -351,10 +366,10 @@ export const getBLEDeviceServices = (deviceId) => {
351
366
  await getBLEDeviceCharacteristics(deviceId);
352
367
  return res.services;
353
368
  },
354
- 20, // 最大重试次数
355
- 100,
369
+ 10, // 最大重试次数(减少到10次)
370
+ 300, // 重试间隔增加到300ms
356
371
  '获取蓝牙服务'
357
- ); // 重试间隔
372
+ );
358
373
  };
359
374
  // #region 获取蓝牙特征值
360
375
  /** 获取蓝牙特征值 */
@@ -374,10 +389,10 @@ export const getBLEDeviceCharacteristics = async (deviceId) => {
374
389
  console.log('获取特征值成功:', res);
375
390
  return res.characteristics;
376
391
  },
377
- 20, // 最大重试次数
378
- 100,
392
+ 10, // 最大重试次数(减少到10次)
393
+ 300, // 重试间隔增加到300ms
379
394
  '获取蓝牙特征值'
380
- ); // 重试间隔
395
+ );
381
396
  };
382
397
  // #region 订阅特征值
383
398
  /** 订阅特征值 */
@@ -423,6 +438,8 @@ export const connectAsync = async (deviceId, timeout = 10000) => {
423
438
  return new Promise(async (resolve, reject) => {
424
439
  try {
425
440
  await createBLEConnection(deviceId, timeout);
441
+ // 连接成功后等待设备准备服务(关键修复)
442
+ await new Promise(resolve => setTimeout(resolve, 800));
426
443
  await getBLEDeviceServices(deviceId);
427
444
  await notify(deviceId);
428
445
  resolve(true);
@@ -441,6 +458,7 @@ export const scanHandle = (historyConnectedList = [], connectFn = (device) => {
441
458
  // 调起条码扫描
442
459
  uni.scanCode({
443
460
  scanType: ['barCode', 'qrCode'],
461
+ autoZoom: false,
444
462
  success: async ({ result }) => {
445
463
  console.log('扫描内容: ' + result);
446
464
  let searchKey = result;
@@ -1,7 +1,7 @@
1
- import { getSysParamCmd } from './readAndSetParam'
2
1
  import { decimalToHex, hexToDecimal } from '../BleDataProcess';
3
- import { batteryInfoJson, capInfoJson, voltageInfoJson,currentInfoJson, tempInfoJson, equalizerFunJson, capVolInfoJson, funcJson, tempFuncJson, systemJson, funcAndTempFuncJson } from '../dataJson/baseParamsJson.js';
4
- import { readExistFactory, getProtectCountCmd, enterFactory } from './BleCmdDD.js'
2
+ import { batteryInfoJson, capInfoJson, capVolInfoJson, currentInfoJson, equalizerFunJson, funcAndTempFuncJson, funcJson, systemJson, tempFuncJson, tempInfoJson, voltageInfoJson } from '../dataJson/baseParamsJson.js';
3
+ import { enterFactory, getProtectCountCmd, readExistFactory } from './BleCmdDD.js';
4
+ import { getSysParamCmd } from './readAndSetParam';
5
5
 
6
6
  /**
7
7
  *
@@ -55,31 +55,43 @@ function formatBinary(arr) {
55
55
  return resultArray
56
56
  }
57
57
  /**
58
- * 发送命令序列
59
- * @param {Object} datasInfo 存储数据的对象
60
- * @param {string} chipType 芯片类型
61
- * @param {string} deviceId 设备ID
62
- * @param {Array<any>} params 参数数组
58
+ * 批量串行读取设备参数
59
+ * @param {Object} datasInfo - 结果存储对象
60
+ * @param {string|null} chipType - 芯片类型
61
+ * @param {string} deviceId - 设备 ID
62
+ * @param {Array} params - 参数列表
63
63
  */
64
64
  const sendCmdSeq = async (datasInfo, chipType, deviceId, params) => {
65
- let index = 0;
66
- // 读多个参数时统一进出工厂
67
- if(!chipType) await enterFactory(deviceId);
68
- while (index < params.length) {
69
- const item = params[index];
65
+ // 基础参数校验
66
+ if (!datasInfo || !deviceId || !Array.isArray(params)) {
67
+ console.error('sendCmdSeq 参数异常');
68
+ return;
69
+ }
70
+
71
+ // 无芯片类型 → 进入工厂模式
72
+ if (!chipType) {
73
+ await enterFactory(deviceId);
74
+ }
75
+
76
+ // 串行读取所有参数(失败不中断)
77
+ for (const item of params) {
78
+ if (!item?.key) continue; // 跳过无效项
79
+
70
80
  try {
71
- const basedata = await getSysParamCmd(chipType, deviceId, item, false);
72
- datasInfo[item.key] = basedata;
73
- index++; // 只有当前操作成功完成后才增加索引
74
- } catch (error) {
75
- console.error(`获取参数 ${item.key} 失败:`, error);
76
- // 可以选择继续执行下一个,或者中断执行
77
- // break; // 如果要在失败时中断
78
- index++; // 如果希望失败时也继续下一个
81
+ const baseData = await getSysParamCmd(chipType, deviceId, item, false);
82
+ datasInfo[item.key] = baseData;
83
+ } catch (err) {
84
+ console.error(`获取参数失败 [${item.key}]:`, err);
85
+ // 失败不重试、不中断,继续下一个
79
86
  }
80
87
  }
81
- if(!chipType) await readExistFactory(deviceId);
82
- }
88
+
89
+ // 无芯片类型 → 退出工厂模式
90
+ if (!chipType) {
91
+ await readExistFactory(deviceId);
92
+ }
93
+ };
94
+
83
95
  let crsDivisor = 0.1;
84
96
  /**
85
97
  * 解析FA基础参数
@@ -116,14 +128,36 @@ export const getBaseParams = async (chipType, deviceData, index, paramObj) => {
116
128
  return dataInfo
117
129
  case 2:
118
130
  let datasInfo2 = {}
131
+ // 11 为主动均衡 需取高位
132
+ const productType = deviceData.productType;
133
+ const isBalanceDevice = productType === "12"
134
+ console.log('productType', productType, isBalanceDevice)
119
135
  if (chipType) {
120
- /**连续读两个参数 */
121
- const capData = await getSysParamCmd(chipType, deviceId, { ...capInfoJson[0], paramLength: 4 })
122
- console.warn('capData: ', capData);
123
- datasInfo2['normCap'] = capData?.slice(0, 2)
124
- datasInfo2['cycleCap'] = capData?.slice(2, 4)
125
- const capData2 = await getSysParamCmd(chipType, deviceId, capInfoJson[2])
126
- datasInfo2['fullCap'] = capData2?.slice(0, 2)
136
+ if (!isBalanceDevice) {
137
+ /**连续读两个参数 */
138
+ const capData = await getSysParamCmd(chipType, deviceId, { ...capInfoJson[0], paramLength: 4 })
139
+ console.warn('capData: ', capData);
140
+ datasInfo2['normCap'] = capData?.slice(0, 2)
141
+ datasInfo2['cycleCap'] = capData?.slice(2, 4)
142
+ const capData2 = await getSysParamCmd(chipType, deviceId, capInfoJson[2])
143
+ datasInfo2['fullCap'] = capData2?.slice(0, 2)
144
+ } else {
145
+ /**读取标称容量:需要读取paramNo 0(低16位)和155(高16位) */
146
+ const normCapLow = await getSysParamCmd(chipType, deviceId, { paramNo: 0, paramLength: 2 })
147
+ const normCapHigh = await getSysParamCmd(chipType, deviceId, { paramNo: 155, paramLength: 2 })
148
+ console.log('normCapLow: ', normCapLow, 'normCapHigh: ', normCapHigh);
149
+ // 合并高低位,每个都只取前2个字节
150
+ datasInfo2['normCap'] = [...(normCapLow?.slice(0, 2) || []), ...(normCapHigh?.slice(0, 2) || [])]
151
+
152
+ const cycleCapData = await getSysParamCmd(chipType, deviceId, capInfoJson[1])
153
+ datasInfo2['cycleCap'] = cycleCapData?.slice(0, 2)
154
+
155
+ /**读取满充容量:需要读取paramNo 112(低16位)和156(高16位) */
156
+ const fullCapLow = await getSysParamCmd(chipType, deviceId, { paramNo: 112, paramLength: 2 })
157
+ const fullCapHigh = await getSysParamCmd(chipType, deviceId, { paramNo: 156, paramLength: 2 })
158
+ console.log('fullCapLow: ', fullCapLow, 'fullCapHigh: ', fullCapHigh);
159
+ datasInfo2['fullCap'] = [...(fullCapLow?.slice(0, 2) || []), ...(fullCapHigh?.slice(0, 2) || [])]
160
+ }
127
161
  } else {
128
162
  await sendCmdSeq(datasInfo2, chipType, deviceId, capInfoJson)
129
163
  }
@@ -378,9 +412,59 @@ function toHexString(arr) {
378
412
  }
379
413
  const getCapInfo = async (datas) => {
380
414
  console.log('datas: ', datas);
381
- const normCap = format(datas.normCap, 0.01, 0, 2)
415
+ // 标称容量:低16位(前2字节)+ 高16位(后2字节),单位是0.01AH
416
+ let normCap = null;
417
+ if (datas.normCap && datas.normCap.length >= 4) {
418
+ console.log('normCap原始数据: ', datas.normCap);
419
+ // 读取低16位(前两个字节)- 大端序
420
+ const lowBytes = datas.normCap.slice(0, 2);
421
+ const lowValue = (lowBytes[0] << 8) | lowBytes[1];
422
+ console.log('normCap lowValue: ', lowValue);
423
+
424
+ // 读取高16位(后两个字节)- 大端序
425
+ const highBytes = datas.normCap.slice(2, 4);
426
+ const highValue = (highBytes[0] << 8) | highBytes[1];
427
+ console.log('normCap highValue: ', highValue);
428
+
429
+ // 合并高低位:(高位 << 16) | 低位
430
+ const totalValue = (highValue << 16) | lowValue;
431
+ console.log('normCap totalValue: ', totalValue);
432
+ normCap = Number((totalValue * 0.01).toFixed(2));
433
+ console.log('normCap最终值: ', normCap);
434
+ } else if (datas.normCap && datas.normCap.length >= 2) {
435
+ // 兼容旧协议,只有低16位 - 大端序
436
+ const lowBytes = datas.normCap.slice(0, 2);
437
+ const lowValue = (lowBytes[0] << 8) | lowBytes[1];
438
+ normCap = Number((lowValue * 0.01).toFixed(2));
439
+ }
440
+
382
441
  const cycleCap = format(datas.cycleCap, 0.01, 0, 2)
383
- const fullCap = format(datas.fullCap, 0.01, 0, 2)
442
+
443
+ // 满充容量:低16位(前2字节)+ 高16位(后2字节),单位是0.01AH
444
+ let fullCap = null;
445
+ if (datas.fullCap && datas.fullCap.length >= 4) {
446
+ console.log('fullCap原始数据: ', datas.fullCap);
447
+ // 读取低16位(前两个字节)- 大端序
448
+ const lowBytes = datas.fullCap.slice(0, 2);
449
+ const lowValue = (lowBytes[0] << 8) | lowBytes[1];
450
+ console.log('fullCap lowValue: ', lowValue);
451
+
452
+ // 读取高16位(后两个字节)- 大端序
453
+ const highBytes = datas.fullCap.slice(2, 4);
454
+ const highValue = (highBytes[0] << 8) | highBytes[1];
455
+ console.log('fullCap highValue: ', highValue);
456
+
457
+ // 合并高低位:(高位 << 16) | 低位
458
+ const totalValue = (highValue << 16) | lowValue;
459
+ console.log('fullCap totalValue: ', totalValue);
460
+ fullCap = Number((totalValue * 0.01).toFixed(2));
461
+ console.log('fullCap最终值: ', fullCap);
462
+ } else if (datas.fullCap && datas.fullCap.length >= 2) {
463
+ // 兼容旧协议,只有低16位 - 大端序
464
+ const lowBytes = datas.fullCap.slice(0, 2);
465
+ const lowValue = (lowBytes[0] << 8) | lowBytes[1];
466
+ fullCap = Number((lowValue * 0.01).toFixed(2));
467
+ }
384
468
  return {
385
469
  normCap,
386
470
  cycleCap,
@@ -1,11 +1,57 @@
1
1
  import { ab2decimalArr, hexArr2ab, hexArr2string, sleep } from '../BleDataProcess';
2
2
  import { eventBus, getOS, getPlatform } from '../commonfun';
3
+ // #ifdef APP-PLUS
4
+ import { mqttServer } from '../mqttServer';
5
+ // #endif
3
6
 
4
7
  const BLE_RESPONSE_TIMEOUT = 300; // 蓝牙指令响应超时
5
8
  const STORE_MUTATION_NAME = 'setBleChangedCharacteristicValue';
6
9
  const serviceId = '0000FF00-0000-1000-8000-00805F9B34FB';
7
10
  const UUID_READ = '0000FF01-0000-1000-8000-00805F9B34FB';
8
11
  const characteristicId = '0000FF02-0000-1000-8000-00805F9B34FB';
12
+
13
+ // 按设备维度串行执行蓝牙指令,避免并发写入导致回包串线
14
+ const BLE_COMMAND_QUEUE = new Map();
15
+ const BLE_COMMAND_RUNNING = new Set();
16
+
17
+ const runNextBleCommand = async (queueKey) => {
18
+ if (BLE_COMMAND_RUNNING.has(queueKey)) return;
19
+ const queue = BLE_COMMAND_QUEUE.get(queueKey) || [];
20
+ if (queue.length === 0) {
21
+ BLE_COMMAND_QUEUE.delete(queueKey);
22
+ return;
23
+ }
24
+
25
+ BLE_COMMAND_RUNNING.add(queueKey);
26
+ const currentTask = queue[0];
27
+
28
+ try {
29
+ const result = await currentTask.task();
30
+ currentTask.resolve(result);
31
+ } catch (error) {
32
+ currentTask.reject(error);
33
+ } finally {
34
+ const currentQueue = BLE_COMMAND_QUEUE.get(queueKey) || [];
35
+ currentQueue.shift();
36
+ BLE_COMMAND_RUNNING.delete(queueKey);
37
+
38
+ if (currentQueue.length === 0) {
39
+ BLE_COMMAND_QUEUE.delete(queueKey);
40
+ } else {
41
+ runNextBleCommand(queueKey);
42
+ }
43
+ }
44
+ };
45
+
46
+ const enqueueBleCommand = (deviceId, task) => {
47
+ const queueKey = deviceId || '__default__';
48
+ return new Promise((resolve, reject) => {
49
+ const queue = BLE_COMMAND_QUEUE.get(queueKey) || [];
50
+ queue.push({ task, resolve, reject });
51
+ BLE_COMMAND_QUEUE.set(queueKey, queue);
52
+ runNextBleCommand(queueKey);
53
+ });
54
+ };
9
55
  // #region 发送写入指令
10
56
  /** 向蓝牙设备写入特征值 发送指令
11
57
  * @param {string} deviceId - 设备ID
@@ -88,7 +134,7 @@ export const getData = async (deviceId, {
88
134
  if (!deviceId) throw new Error('deviceId is required');
89
135
  if (!command || command.length <= 0) throw new Error('command is required');
90
136
 
91
- return new Promise((resolve, reject) => {
137
+ return enqueueBleCommand(deviceId, () => new Promise((resolve, reject) => {
92
138
  let isCompleted = false;
93
139
  let timeoutId = null;
94
140
  let responsed = false;
@@ -135,6 +181,16 @@ export const getData = async (deviceId, {
135
181
  if (verified) {
136
182
  responsed = true;
137
183
  cleanup();
184
+ // #ifdef APP-PLUS
185
+ const value = [...pkg].map((o) => `00${o.toString(16)}`.slice(-2)).join('');
186
+ const cmdCode = mqttServer.currentCommand
187
+ if (value && cmdCode) {
188
+ if (mqttServer.setPassthroughType === 0) {
189
+ mqttServer.publishPassthroughHandle({ value, cmdCode }, deviceId)
190
+ }
191
+ mqttServer.setPassthroughType = 0
192
+ }
193
+ // #endif
138
194
  resolve([...pkg]);
139
195
  } else {
140
196
  // 验证失败,重置状态
@@ -197,7 +253,7 @@ export const getData = async (deviceId, {
197
253
  cleanup();
198
254
  reject(error);
199
255
  });
200
- });
256
+ }));
201
257
  }
202
258
  // #region 设置Android MTU 最大传输单元
203
259
  /** 设置Android MTU
@@ -1,7 +1,8 @@
1
- import { decimalToHex, fromBCD, generateCrc16modbusCheck, generateCrcCheckSum, hex2string, hexArr2Assic, hexArr2string, hexToDecimal, isWithin30Minutes, sleep, stringToTwoHexArray, toBCD } from '../BleDataProcess';
1
+ import { decimalToHex, fromBCD, generateCrc16modbusCheck, generateCrcCheckSum, hex2string, hexArr2Assic, hexArr2string, hexToDecimal, isWithin30Minutes, sleep, stringToTwoHexArray, toBCD, decimalToHex0x } from '../BleDataProcess';
2
2
  import { getData } from './BleCmdAnalysis.js';
3
3
  import { getFFAA80Async, resolveFFAA80 } from './BleCmdFFAA.js';
4
-
4
+ import { controlSwitch } from './readAndSetParam.js';
5
+
5
6
  // #region 进出工厂
6
7
  /**进工厂 */
7
8
  export const enterFactory = async (deviceId) => {
@@ -147,7 +148,16 @@ export const resolve3B3C = (data) => {
147
148
  const content = data.slice(12, data.length - 3);
148
149
  const CONTENT = [/*产品类型-TYPE*/ '01', /*产品类型标识长度*/ '04', /*产品类型表示*/ '00', /*前端类型标识*/ '02', /*协议版本标识*/ '01', /*层级关系架构*/ '00', /*硬件版本号-TYPE*/ '02', /*硬件版本号长度*/ '00', /*软件版本号-TYPE*/ '03', /*软件版本号长度*/ '0a', /*软件版本号内容ASCII*/ '44', /*软件版本号内容ASCII*/ '48', /*软件版本号内容ASCII*/ '30', /*软件版本号内容ASCII*/ '34', /*软件版本号内容ASCII*/ '2e', /*软件版本号内容ASCII*/ '31', /*软件版本号内容ASCII*/ '2e', /*软件版本号内容ASCII*/ '34', /*软件版本号内容ASCII*/ '2e', /*软件版本号内容ASCII*/ '37', /*PCB-TYPE*/ '04', /*PCB内容长度*/ '00'];
149
150
  while (content.length > 0) {
150
- const [v1, v2, ...v] = content.splice(0, content[1] + 2);
151
+ if (content.length < 2) {
152
+ console.warn('Content too short to parse, remaining:', content);
153
+ break;
154
+ }
155
+ const len = Math.min(content[1] + 2, content.length);
156
+ const [v1, v2, ...v] = content.splice(0, len);
157
+ if (v.length !== v2) {
158
+ console.warn(`Data length mismatch for type ${v1}: expected ${v2}, got ${v.length}`);
159
+ continue;
160
+ }
151
161
  if (v1 == 0x01) {
152
162
  result['productFlag'] = hex2string(v1);
153
163
  result['productLen'] = v2;
@@ -358,6 +368,9 @@ export const resolveDDA503 = (data) => {
358
368
  name: index + 1,
359
369
  value: item,
360
370
  }));
371
+ const hasProtocol =
372
+ data[3] + 7 >= humidityIndex + 11 + 3 + 1;
373
+ const protocolVersion = data[humidityIndex + 11];
361
374
  return {
362
375
  cmdResp03,
363
376
  status: hex2string(data[2]),
@@ -383,6 +396,7 @@ export const resolveDDA503 = (data) => {
383
396
  heatingState,
384
397
  heatingCurrent,
385
398
  equilibriumCurrent,
399
+ eqCurr: equilibriumCurrent,
386
400
  isFactoryMode,
387
401
  protVal,
388
402
  alarmsState,
@@ -391,6 +405,8 @@ export const resolveDDA503 = (data) => {
391
405
  fahTempList,
392
406
  fet,
393
407
  seriesNum,
408
+ hasProtocol,
409
+ protocolVersion
394
410
  };
395
411
  }
396
412
 
@@ -765,7 +781,7 @@ export const resolveDDA505 = (data) => {
765
781
  export const getDDA5FAAsync = async (deviceId, paramNo, length) => {
766
782
  const header = ['0xDD', '0xA5']
767
783
  const _values = [...paramNo, length];
768
- const lengthHex = decimalToHex(_values.length)
784
+ const lengthHex = decimalToHex0x(_values.length)
769
785
  const _command = ['0xFA', lengthHex, ..._values];
770
786
  const checks = generateCrcCheckSum(_command);
771
787
  const command = [...header, ..._command, ...checks, '0x77'];
@@ -1206,9 +1222,8 @@ export const get3B3CInfo = ({ deviceId, macAddr, moduleType, productType }) => {
1206
1222
  try {
1207
1223
  if (!deviceId) throw new Error('deviceId required');
1208
1224
  // 发送FFAA_80
1209
- const _ffaa_80_hex = await getFFAA80Async(deviceId, 'AT^VERSION?');
1210
- _ffaa_80 = resolveFFAA80(_ffaa_80_hex);
1211
- console.warn('Report-3B3C _ffaa_80 ', { _ffaa_80_hex, _ffaa_80 });
1225
+ const _ffaa_80 = await getFFAA80Async(deviceId, 'AT^VERSION?');
1226
+ console.warn('Report-3B3C _ffaa_80 ', { _ffaa_80 });
1212
1227
  if (_ffaa_80) reportData['moduleVersion'] = _ffaa_80?.moduleVersion;
1213
1228
 
1214
1229
  // 发送3B3C
@@ -1217,6 +1232,7 @@ export const get3B3CInfo = ({ deviceId, macAddr, moduleType, productType }) => {
1217
1232
  console.warn('Report-3B3C _3b3c ', { _3b3c_hex, _3b3c });
1218
1233
  if (_3b3c) {
1219
1234
  reportData['cmdContent'] = _3b3c?.dataStr;
1235
+ reportData['bmsVersion'] = _3b3c?.sofewareV;
1220
1236
  } /*3B3C超时 or 不支持3B3C*/ else {
1221
1237
  // 发送DDA5_03
1222
1238
  const _dda5_03_hex = await getDDA503Async(deviceId);
@@ -1245,18 +1261,71 @@ export const get3B3CInfo = ({ deviceId, macAddr, moduleType, productType }) => {
1245
1261
 
1246
1262
  // #region 发送设备激活指令
1247
1263
  export const activateAsync = async (deviceId) => {
1248
- const startTime = +new Date();
1249
- const disChargMOSHex = await getDD5AFBAsync(deviceId, '0x00', '0x00');
1250
- const disChargMOSRes = resolveBaseDD(disChargMOSHex)?.dataStr;
1251
- const disChargEndTime = +new Date();
1252
- const activeHex = await getDD5AFBAsync(deviceId, '0x05', '0x01');
1253
- const activeRes = resolveBaseDD(disChargMOSHex)?.dataStr;
1254
- let baseInfo = null
1255
- const endTime = +new Date();
1256
- await sleep(300)
1257
- baseInfo = await getDDA503Async(deviceId);
1258
- const voltageInfo = await getDDA504Async(deviceId);
1259
- return { disChargMOSHex, disChargMOSRes, activeHex, activeRes, baseInfo, voltageInfo, startTime, disChargEndTime, endTime };
1264
+ // const startTime = +new Date();
1265
+ // const disChargMOSHex = await getDD5AFBAsync(deviceId, '0x00', '0x00');
1266
+ // const disChargMOSRes = resolveBaseDD(disChargMOSHex)?.dataStr;
1267
+ // const disChargEndTime = +new Date();
1268
+ // const activeHex = await getDD5AFBAsync(deviceId, '0x05', '0x01');
1269
+ // const activeRes = resolveBaseDD(disChargMOSHex)?.dataStr;
1270
+ // let baseInfo = null
1271
+ // const endTime = +new Date();
1272
+ // await sleep(300)
1273
+ // baseInfo = await getDDA503Async(deviceId);
1274
+ // const voltageInfo = await getDDA504Async(deviceId);
1275
+ // return { disChargMOSHex, disChargMOSRes, activeHex, activeRes, baseInfo, voltageInfo, startTime, disChargEndTime, endTime };
1276
+ try {
1277
+ const startTime = +new Date();
1278
+ let acStatus = false // 激活结果
1279
+ // 发送打开放电MOS指令
1280
+ const mosRes = await controlSwitch(
1281
+ deviceId,
1282
+ '0x00',
1283
+ true,
1284
+ true,
1285
+ );
1286
+ const disChargMOSRes = mosRes?.dataStr;
1287
+ const disChargEndTime = +new Date();
1288
+ // 发送激活指令
1289
+ const activeHex = await getDD5AFBAsync(deviceId, '0x05', '0x01');
1290
+ const activeResult = resolveBaseDD(activeHex);
1291
+ console.log('激活指令结果: ', { activeHex, activeResult });
1292
+ const activeRes = activeResult?.dataStr;
1293
+ let endTime = +new Date();
1294
+ let baseInfo = null
1295
+ let voltageInfo = null
1296
+ let steps = []
1297
+ if (activeResult?.status == '00') {
1298
+ steps.push(4)
1299
+ acStatus = true
1300
+ } else if (activeResult?.status == '81' || activeResult?.status == '84') {//不支持激活指令,判断开关执行结果
1301
+ if (mosRes?.status == '00') {
1302
+ acStatus = true
1303
+ steps.push(5)
1304
+ } else {
1305
+ acStatus = false
1306
+ steps.push(10)
1307
+ }
1308
+ } else if (activeResult?.status == '82' || activeResult?.status == '83') { // 激活指令执行失败
1309
+ acStatus = false
1310
+ steps.push(6)
1311
+ } else if (!activeResult || activeResult == null) { //激活无响应
1312
+ await sleep(300)
1313
+ const baseInfo = await getDDA503Async(deviceId);
1314
+ // 读取03指令后判断放电MOS是否打开,若打开则激活成功
1315
+ if (baseInfo?.dischargeSwitch) {
1316
+ acStatus = true
1317
+ steps.push(7)
1318
+ } else {
1319
+ acStatus = false
1320
+ steps.push(8)
1321
+ }
1322
+ endTime = +new Date()
1323
+ }
1324
+ return { disChargMOSRes, activeHex, activeRes, baseInfo, voltageInfo, startTime, disChargEndTime, endTime, acStatus, steps };
1325
+ } catch (error) {
1326
+ console.log("🚀 ~ BleApiManager ~ activateAsync ~ error:", error)
1327
+ return null
1328
+ }
1260
1329
  }
1261
1330
 
1262
1331
  // #region 获取均衡线电阻 DC 指令