@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.
- package/dist/cjs/core/BleApiManager.js +1 -1
- package/dist/cjs/core/BleCmdAnalysis/BaseParamProtocol.js +1 -1
- package/dist/cjs/core/BleCmdAnalysis/BleCmdAnalysis.js +1 -1
- package/dist/cjs/core/BleCmdAnalysis/BleCmdDD.js +1 -1
- package/dist/cjs/core/BleCmdAnalysis/BleCmdDDA4.js +1 -1
- package/dist/cjs/core/BleCmdAnalysis/BleCmdFFAA.js +1 -1
- package/dist/cjs/core/BleCmdAnalysis/readAndSetParam.js +1 -1
- package/dist/cjs/core/BleDataProcess.js +1 -1
- package/dist/cjs/core/OtaUpgrade.js +1 -1
- package/dist/cjs/core/Queue.js +1 -0
- package/dist/cjs/core/mqttServer.js +1 -1
- package/dist/cjs/core/tcpServer.js +1 -0
- package/dist/cjs/index.js +1 -1
- package/dist/esm/core/BleApiManager.js +1 -1
- package/dist/esm/core/BleCmdAnalysis/BaseParamProtocol.js +1 -1
- package/dist/esm/core/BleCmdAnalysis/BleCmdAnalysis.js +1 -1
- package/dist/esm/core/BleCmdAnalysis/BleCmdDD.js +1 -1
- package/dist/esm/core/BleCmdAnalysis/BleCmdDDA4.js +1 -1
- package/dist/esm/core/BleCmdAnalysis/BleCmdFFAA.js +1 -1
- package/dist/esm/core/BleCmdAnalysis/BleCmdHVES.js +1 -1
- package/dist/esm/core/BleCmdAnalysis/readAndSetParam.js +1 -1
- package/dist/esm/core/BleDataProcess.js +1 -1
- package/dist/esm/core/OtaUpgrade.js +1 -1
- package/dist/esm/core/Queue.js +1 -0
- package/dist/esm/core/mqttServer.js +1 -1
- package/dist/esm/core/tcpServer.js +1 -0
- package/dist/esm/index.js +1 -1
- package/package.json +1 -1
- package/src/core/BleApiManager.js +33 -15
- package/src/core/BleCmdAnalysis/BaseParamProtocol.js +116 -32
- package/src/core/BleCmdAnalysis/BleCmdAnalysis.js +58 -2
- package/src/core/BleCmdAnalysis/BleCmdDD.js +88 -19
- package/src/core/BleCmdAnalysis/BleCmdDDA4.js +154 -227
- package/src/core/BleCmdAnalysis/BleCmdFFAA.js +1 -0
- package/src/core/BleCmdAnalysis/readAndSetParam.js +133 -16
- package/src/core/BleDataProcess.js +15 -11
- package/src/core/OtaUpgrade.js +356 -350
- package/src/core/Queue.js +34 -0
- package/src/core/mqttServer.js +75 -5
- package/src/core/tcpServer.js +341 -0
- package/src/index.js +1 -0
|
@@ -20,7 +20,8 @@ export const getDDA420Async = async (deviceId) => {
|
|
|
20
20
|
return { verified: c1 == _c1 && c2 == _c2 };
|
|
21
21
|
},
|
|
22
22
|
},
|
|
23
|
-
'DDA420'
|
|
23
|
+
'DDA420',
|
|
24
|
+
1500
|
|
24
25
|
);
|
|
25
26
|
}
|
|
26
27
|
|
|
@@ -85,10 +86,11 @@ export const getDDA420Async = async (deviceId) => {
|
|
|
85
86
|
);
|
|
86
87
|
|
|
87
88
|
// 6. 充电器温度(2字节)
|
|
88
|
-
const
|
|
89
|
+
const tempChargeTemperature = hexToDecimal(
|
|
89
90
|
decimalToHex(data[n++]) +
|
|
90
91
|
decimalToHex(data[n++])
|
|
91
|
-
)
|
|
92
|
+
);
|
|
93
|
+
const chargeTemperature = tempChargeTemperature > 32768 ? (tempChargeTemperature - 65536) / 10 : tempChargeTemperature / 10;
|
|
92
94
|
|
|
93
95
|
// 7. 已充电量(4字节)
|
|
94
96
|
const chargeCapacity = hexToDecimal(
|
|
@@ -231,7 +233,7 @@ export const getDDA420Async = async (deviceId) => {
|
|
|
231
233
|
const checks = generateCrcCheckSum(_command);
|
|
232
234
|
const command = ['0xdd', '0xa4', ..._command, ...checks, '0x77'];
|
|
233
235
|
|
|
234
|
-
return
|
|
236
|
+
return getData(
|
|
235
237
|
deviceId,
|
|
236
238
|
{
|
|
237
239
|
command,
|
|
@@ -243,7 +245,8 @@ export const getDDA420Async = async (deviceId) => {
|
|
|
243
245
|
return { verified: c1 == _c1 && c2 == _c2 };
|
|
244
246
|
},
|
|
245
247
|
},
|
|
246
|
-
'DDA421'
|
|
248
|
+
'DDA421',
|
|
249
|
+
1500
|
|
247
250
|
);
|
|
248
251
|
}
|
|
249
252
|
/** 解析充电电池信息21指令
|
|
@@ -271,7 +274,8 @@ export const getDDA420Async = async (deviceId) => {
|
|
|
271
274
|
const batterySOC = data[18]; // %
|
|
272
275
|
// 电池温度 2BYTE [19,20]
|
|
273
276
|
const batteryTempHex = decimalToHex(data[19]) + decimalToHex(data[20]);
|
|
274
|
-
const
|
|
277
|
+
const tempBatteryTemperature = hexToDecimal(batteryTempHex);
|
|
278
|
+
const batteryTemperature = tempBatteryTemperature > 32768 ? (tempBatteryTemperature - 65536) / 10 : tempBatteryTemperature / 10; // 0.1摄氏度
|
|
275
279
|
// const batteryTemperature = [data[19] ?? 0, [data[20] ?? 0]] // 摄氏度,保留一位小数
|
|
276
280
|
// 加热状态 1BYTE [21]
|
|
277
281
|
const heatingStatus = data[21]; // 0未加热 1加热中
|
|
@@ -332,7 +336,8 @@ export const getDDA420Async = async (deviceId) => {
|
|
|
332
336
|
return { verified: true };
|
|
333
337
|
},
|
|
334
338
|
},
|
|
335
|
-
'DDA425'
|
|
339
|
+
'DDA425',
|
|
340
|
+
1500
|
|
336
341
|
);
|
|
337
342
|
}
|
|
338
343
|
export const resolveDDA425 = (data) => {
|
|
@@ -377,7 +382,8 @@ export const getDDA420Async = async (deviceId) => {
|
|
|
377
382
|
return { verified: c1 == _c1 && c2 == _c2 };
|
|
378
383
|
},
|
|
379
384
|
},
|
|
380
|
-
'DDA422'
|
|
385
|
+
'DDA422',
|
|
386
|
+
3000
|
|
381
387
|
);
|
|
382
388
|
}
|
|
383
389
|
/** 解析充电器参数22指令响应
|
|
@@ -406,46 +412,66 @@ export const getDDA420Async = async (deviceId) => {
|
|
|
406
412
|
* 设置充电器参数23指令
|
|
407
413
|
*/
|
|
408
414
|
export const getDDA423Async = async (deviceId, startReg, endReg, values, valuesLength) => {
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
415
|
+
try {
|
|
416
|
+
// 起始/结束地址 2 字节大端
|
|
417
|
+
const startRegHex = decimalToHex(startReg, 4);
|
|
418
|
+
const startRegArr = [
|
|
419
|
+
parseInt(startRegHex.slice(0, 2), 16),
|
|
420
|
+
parseInt(startRegHex.slice(2, 4), 16)
|
|
421
|
+
];
|
|
422
|
+
const endRegHex = decimalToHex(endReg, 4);
|
|
423
|
+
const endRegArr = [
|
|
424
|
+
parseInt(endRegHex.slice(0, 2), 16),
|
|
425
|
+
parseInt(endRegHex.slice(2, 4), 16)
|
|
426
|
+
];
|
|
427
|
+
|
|
428
|
+
let valueArr = [];
|
|
429
|
+
// 批量模式:传入数组
|
|
430
|
+
if (Array.isArray(values)) {
|
|
431
|
+
valueArr = values.map(v => (Number(v) || 0) & 0xFF);
|
|
432
|
+
const expectLen = endReg - startReg + 1;
|
|
433
|
+
if (valueArr.length !== expectLen) {
|
|
434
|
+
if (valueArr.length > expectLen) {
|
|
435
|
+
valueArr = valueArr.slice(0, expectLen);
|
|
436
|
+
} else {
|
|
437
|
+
while (valueArr.length < expectLen) valueArr.push(0);
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
valuesLength = valueArr.length;
|
|
441
|
+
} else {
|
|
442
|
+
// 单值模式:保持兼容旧逻辑
|
|
443
|
+
const len = valuesLength || (endReg - startReg + 1);
|
|
444
|
+
const valueRegHex = decimalToHex(values, len * 2);
|
|
445
|
+
for (let i = 0; i < len; i++) {
|
|
446
|
+
const hex = valueRegHex.slice(i * 2, i * 2 + 2);
|
|
447
|
+
valueArr.push(parseInt(hex, 16));
|
|
448
|
+
}
|
|
449
|
+
valuesLength = len;
|
|
450
|
+
}
|
|
431
451
|
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
452
|
+
const lengthHex = 4 + valuesLength;
|
|
453
|
+
const _command = ['0x23', lengthHex, ...startRegArr, ...endRegArr, ...valueArr];
|
|
454
|
+
const checks = generateCrcCheckSum(_command);
|
|
455
|
+
const command = ['0xDD', '0xA4', ..._command, ...checks, '0x77'];
|
|
456
|
+
return getData(
|
|
457
|
+
deviceId,
|
|
458
|
+
{
|
|
459
|
+
command,
|
|
460
|
+
commandVerifyHandler: (hexArr) => ({ verified: hexArr[0] == 0xdd && hexArr[1] == 0x23, pkgLen: hexArr[3] + 7 }),
|
|
461
|
+
pkgVerifyHandler: (pkg) => {
|
|
462
|
+
const len = pkg.length;
|
|
463
|
+
const [c1, c2] = generateCrcCheckSum(pkg.slice(2, len - 3));
|
|
464
|
+
const [_c1, _c2] = [pkg[len - 3], pkg[len - 2]];
|
|
465
|
+
return { verified: c1 == _c1 && c2 == _c2 };
|
|
466
|
+
},
|
|
445
467
|
},
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
468
|
+
'DDA423',
|
|
469
|
+
3000
|
|
470
|
+
);
|
|
471
|
+
} catch (e) {
|
|
472
|
+
console.warn('getDDA423Async build frame error', e);
|
|
473
|
+
return Promise.reject(e);
|
|
474
|
+
}
|
|
449
475
|
}
|
|
450
476
|
export const resolveDDA423 = (data) => {
|
|
451
477
|
if (!data) return null;
|
|
@@ -475,14 +501,14 @@ export const getDDA420Async = async (deviceId) => {
|
|
|
475
501
|
|
|
476
502
|
// 转 4 字节 (大端) 十六进制 -> 数组
|
|
477
503
|
const to4Bytes = (val) => {
|
|
478
|
-
const hex =
|
|
504
|
+
const hex = decimalToHex(val, 8); // 8位十六进制字符串
|
|
479
505
|
return [0, 2, 4, 6].map(i => parseInt(hex.slice(i, i + 2), 16));
|
|
480
506
|
};
|
|
481
507
|
const voltageArr = to4Bytes(outputVoltage);
|
|
482
508
|
const currentArr = to4Bytes(outputCurrent);
|
|
483
509
|
|
|
484
510
|
// 长度 = 1(模式) +4(电压)+4(电流) = 9
|
|
485
|
-
const lengthHex =
|
|
511
|
+
const lengthHex = decimalToHex(9, 2); // '09'
|
|
486
512
|
const _command = ['0x26', `0x${lengthHex}`, testMode & 0xFF, ...voltageArr, ...currentArr].map(o => typeof o === 'number' ? `0x${('00' + o.toString(16)).slice(-2)}` : o);
|
|
487
513
|
// 去掉 0x 前缀转成数值数组生成 CRC
|
|
488
514
|
const _commandNums = _command.map(h => parseInt(h, 16));
|
|
@@ -615,49 +641,31 @@ export const getDDA420Async = async (deviceId) => {
|
|
|
615
641
|
* @param {*} deviceId
|
|
616
642
|
* @returns
|
|
617
643
|
*/
|
|
618
|
-
export const getDDA429Async = async (deviceId, id) => {
|
|
619
|
-
//
|
|
644
|
+
export const getDDA429Async = async (deviceId, id = 1, seq = 0) => {
|
|
645
|
+
// ID 与 SEQ 均为 4 字节大端
|
|
620
646
|
const idHex = decimalToHex(id, 8);
|
|
621
|
-
|
|
647
|
+
const seqHex = decimalToHex(seq, 8);
|
|
622
648
|
const idArr = [
|
|
623
649
|
parseInt(idHex.slice(0, 2), 16),
|
|
624
650
|
parseInt(idHex.slice(2, 4), 16),
|
|
625
651
|
parseInt(idHex.slice(4, 6), 16),
|
|
626
|
-
parseInt(idHex.slice(4, 6), 16),
|
|
627
652
|
parseInt(idHex.slice(6, 8), 16)
|
|
628
653
|
];
|
|
629
|
-
const
|
|
654
|
+
const seqArr = [
|
|
655
|
+
parseInt(seqHex.slice(0, 2), 16),
|
|
656
|
+
parseInt(seqHex.slice(2, 4), 16),
|
|
657
|
+
parseInt(seqHex.slice(4, 6), 16),
|
|
658
|
+
parseInt(seqHex.slice(6, 8), 16)
|
|
659
|
+
];
|
|
660
|
+
// 长度 = 8 (ID+SEQ)
|
|
661
|
+
const _command = ['0x29', '0x08', ...idArr, ...seqArr];
|
|
630
662
|
const checks = generateCrcCheckSum(_command);
|
|
631
|
-
const command = ['
|
|
632
|
-
|
|
633
|
-
|
|
663
|
+
const command = ['0xDD', '0xA4', ..._command, ...checks, '0x77'];
|
|
634
664
|
return getData(
|
|
635
665
|
deviceId,
|
|
636
666
|
{
|
|
637
667
|
command,
|
|
638
|
-
commandVerifyHandler: (hexArr) => {
|
|
639
|
-
// 基本头部验证
|
|
640
|
-
if (hexArr[0] != 0xdd || hexArr[1] != 0x29) return { verified: false, pkgLen: null };
|
|
641
|
-
|
|
642
|
-
// 验证数据包长度是否合理
|
|
643
|
-
if (hexArr.length < 8) return { verified: false, pkgLen: null };
|
|
644
|
-
|
|
645
|
-
// 根据resolveDDA429的解析结构,ID在响应偏移32位置
|
|
646
|
-
// 实际协议中可能有所不同,需要根据协议规范调整
|
|
647
|
-
if (hexArr.length >= 36) {
|
|
648
|
-
// 从resolveDDA429可知,ID位于n=32处的4个字节
|
|
649
|
-
const respIdHex = decimalToHex(hexArr[32]) +
|
|
650
|
-
decimalToHex(hexArr[33]) +
|
|
651
|
-
decimalToHex(hexArr[34]) +
|
|
652
|
-
decimalToHex(hexArr[35]);
|
|
653
|
-
const respId = hexToDecimal(respIdHex);
|
|
654
|
-
|
|
655
|
-
// 如果ID不匹配,则拒绝该数据包
|
|
656
|
-
if (respId !== id) return { verified: false, pkgLen: null };
|
|
657
|
-
}
|
|
658
|
-
|
|
659
|
-
return { verified: true, pkgLen: hexArr[3] + 7 };
|
|
660
|
-
},
|
|
668
|
+
commandVerifyHandler: (hexArr) => ({ verified: hexArr[0] == 0xdd && hexArr[1] == 0x29, pkgLen: hexArr[3] + 7 }),
|
|
661
669
|
pkgVerifyHandler: (pkg) => {
|
|
662
670
|
const len = pkg.length;
|
|
663
671
|
const [c1, c2] = generateCrcCheckSum(pkg.slice(2, len - 3));
|
|
@@ -665,161 +673,80 @@ export const getDDA420Async = async (deviceId) => {
|
|
|
665
673
|
return { verified: c1 == _c1 && c2 == _c2 };
|
|
666
674
|
},
|
|
667
675
|
},
|
|
668
|
-
'DDA429'
|
|
676
|
+
'DDA429',
|
|
677
|
+
3000
|
|
669
678
|
);
|
|
670
679
|
}
|
|
671
680
|
export const resolveDDA429 = (data) => {
|
|
672
681
|
if (!data) return null;
|
|
682
|
+
const status = data[2];
|
|
683
|
+
const content = data.slice(4, data.length - 3);
|
|
673
684
|
const dataStr = hexArr2string(data);
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
const
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
const chargeTime = hexToDecimal(
|
|
720
|
-
decimalToHex(data[n++]) +
|
|
721
|
-
decimalToHex(data[n++])
|
|
722
|
-
);
|
|
723
|
-
|
|
724
|
-
// 9. 充电剩余时间(2字节)
|
|
725
|
-
const chargeRemainTime = hexToDecimal(
|
|
726
|
-
decimalToHex(data[n++]) +
|
|
727
|
-
decimalToHex(data[n++])
|
|
728
|
-
);
|
|
729
|
-
|
|
730
|
-
// 10. 充电完成时长(2字节)
|
|
731
|
-
const chargeCompleteTime = hexToDecimal(
|
|
732
|
-
decimalToHex(data[n++]) +
|
|
733
|
-
decimalToHex(data[n++])
|
|
734
|
-
);
|
|
735
|
-
|
|
736
|
-
// 输出电压占空比
|
|
737
|
-
const outputVoltagePercent = data[n++];
|
|
738
|
-
|
|
739
|
-
// 输出电流占空比
|
|
740
|
-
const outputElectricityPercent = data[n++];
|
|
741
|
-
|
|
742
|
-
// id(4字节)
|
|
743
|
-
const id1 = hexToDecimal(
|
|
744
|
-
decimalToHex(data[n++]) +
|
|
745
|
-
decimalToHex(data[n++]) +
|
|
746
|
-
decimalToHex(data[n++]) +
|
|
747
|
-
decimalToHex(data[n++])
|
|
748
|
-
);
|
|
749
|
-
|
|
750
|
-
// 检测输出电流(4字节)
|
|
751
|
-
const outputElectricity = hexToDecimal(
|
|
752
|
-
decimalToHex(data[n++]) +
|
|
753
|
-
decimalToHex(data[n++]) +
|
|
754
|
-
decimalToHex(data[n++]) +
|
|
755
|
-
decimalToHex(data[n++])
|
|
756
|
-
);
|
|
757
|
-
|
|
758
|
-
// 检测电池电压(4字节)
|
|
759
|
-
const id = hexToDecimal(
|
|
760
|
-
decimalToHex(data[n++]) +
|
|
761
|
-
decimalToHex(data[n++]) +
|
|
762
|
-
decimalToHex(data[n++]) +
|
|
763
|
-
decimalToHex(data[n++])
|
|
764
|
-
);
|
|
765
|
-
|
|
766
|
-
// 开关状态(2字节)
|
|
767
|
-
const switchStatus = hexToDecimal(
|
|
768
|
-
decimalToHex(data[n++]) +
|
|
769
|
-
decimalToHex(data[n++])
|
|
770
|
-
);
|
|
771
|
-
const swtichStatusArr = switchStatus.toString(2).padStart(16, '0').split('').reverse();
|
|
772
|
-
const chargeSwitch = swtichStatusArr[0] == '1';
|
|
773
|
-
const preChargeSwitch = swtichStatusArr[1] == '1';
|
|
774
|
-
const fanSwitch = swtichStatusArr[2] == '1';
|
|
775
|
-
|
|
776
|
-
// 保护状态(4字节)
|
|
777
|
-
const protectStatus = hexToDecimal(
|
|
778
|
-
decimalToHex(data[n++]) +
|
|
779
|
-
decimalToHex(data[n++]) +
|
|
780
|
-
decimalToHex(data[n++]) +
|
|
781
|
-
decimalToHex(data[n++])
|
|
782
|
-
);
|
|
783
|
-
const protectStatusArr = protectStatus.toString(2).padStart(32, '0').split('').reverse();
|
|
784
|
-
let protectStatusIndexs = [];
|
|
785
|
-
for (let i = 0; i < protectStatusArr.length; i++) {
|
|
786
|
-
if (protectStatusArr[i] == '1') protectStatusIndexs.push(i);
|
|
685
|
+
if (content.length < 8) return { dataStr, status, error: 'content too short' };
|
|
686
|
+
|
|
687
|
+
const id = hexToDecimal(decimalToHex(content[0]) + decimalToHex(content[1]) + decimalToHex(content[2]) + decimalToHex(content[3]));
|
|
688
|
+
const seq = hexToDecimal(decimalToHex(content[4]) + decimalToHex(content[5]) + decimalToHex(content[6]) + decimalToHex(content[7]));
|
|
689
|
+
const body = content.slice(8);
|
|
690
|
+
|
|
691
|
+
// ID=1 解析:末尾 57 字节固定含义,其余视作工作信息原始区
|
|
692
|
+
if (id === 1) {
|
|
693
|
+
const peerTailLen = 57;
|
|
694
|
+
let workInfo = [];
|
|
695
|
+
let peerSection = [];
|
|
696
|
+
if (body.length >= peerTailLen) {
|
|
697
|
+
workInfo = body.slice(0, body.length - peerTailLen);
|
|
698
|
+
peerSection = body.slice(body.length - peerTailLen);
|
|
699
|
+
} else {
|
|
700
|
+
peerSection = body.slice();
|
|
701
|
+
}
|
|
702
|
+
const workinfoField = {
|
|
703
|
+
state: workInfo[0] || 0,
|
|
704
|
+
ipwm: hexToDecimal(decimalToHex(workInfo[24]) + decimalToHex(workInfo[25]) + decimalToHex(workInfo[26]) + decimalToHex(workInfo[27])),
|
|
705
|
+
vpwm: hexToDecimal(decimalToHex(workInfo[28]) + decimalToHex(workInfo[29]) + decimalToHex(workInfo[30]) + decimalToHex(workInfo[31])),
|
|
706
|
+
vout: hexToDecimal(decimalToHex(workInfo[32]) + decimalToHex(workInfo[33]) + decimalToHex(workInfo[34]) + decimalToHex(workInfo[35])),
|
|
707
|
+
iout: hexToDecimal(decimalToHex(workInfo[36]) + decimalToHex(workInfo[37]) + decimalToHex(workInfo[38]) + decimalToHex(workInfo[39])),
|
|
708
|
+
vbat: hexToDecimal(decimalToHex(workInfo[40]) + decimalToHex(workInfo[41]) + decimalToHex(workInfo[42]) + decimalToHex(workInfo[43])),
|
|
709
|
+
port: String(workInfo[54]) || 0
|
|
710
|
+
};
|
|
711
|
+
const fieldNames = ['peer_curr', 'peer_num', 'ble_state', 'ble_init', 'ble_release', 'release_cnt', 'scan_start', 'scan_end', 'scan_res', 'scan_resp', 'conn_start', 'conn_resp', 'conn_end', 'conn_idx', 'conn_res', 'cmp_resp', 'handshake_resp', 'qr_chg', 'blacklist', 'ext_resp', 'ext_num'];
|
|
712
|
+
const peerMap = {};
|
|
713
|
+
peerSection.slice(0, 21).forEach((b, i) => { peerMap[fieldNames[i] || (`extra_${i}`)] = b; });
|
|
714
|
+
|
|
715
|
+
const extraBytes = peerSection.slice(21);
|
|
716
|
+
let i = 0;
|
|
717
|
+
let j = 0;
|
|
718
|
+
const fieldNamesExtra = ['run_ts', 'scan_ts', 'scan_end_ts', 'get_ts', 'get_end_ts', 'conn_ts', 'conn_end_ts', 'cmp_ts', 'cmp_end_ts'];
|
|
719
|
+
while (i < extraBytes.length) {
|
|
720
|
+
peerMap[fieldNamesExtra[j] || (`extra_${j}`)] = hexToDecimal(
|
|
721
|
+
decimalToHex(extraBytes[i] || 0) +
|
|
722
|
+
decimalToHex(extraBytes[i + 1] || 0) +
|
|
723
|
+
decimalToHex(extraBytes[i + 2] || 0) +
|
|
724
|
+
decimalToHex(extraBytes[i + 3] || 0)
|
|
725
|
+
);
|
|
726
|
+
i += 4;
|
|
727
|
+
j += 1;
|
|
728
|
+
}
|
|
729
|
+
return { dataStr, status, id, seq, type: 'ID1', ...workinfoField, ...peerMap };
|
|
787
730
|
}
|
|
788
731
|
|
|
789
|
-
//
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
732
|
+
// ID=2/3 解析:按 16 字节一组 peer_info
|
|
733
|
+
if (id === 2 || id === 3) {
|
|
734
|
+
const peerInfos = [];
|
|
735
|
+
for (let i = 0; i + 16 <= body.length; i += 16) {
|
|
736
|
+
const seg = body.slice(i, i + 16);
|
|
737
|
+
const macBytes = seg.slice(0, 6).map(b => decimalToHex(b));
|
|
738
|
+
const mac = macBytes.map(m => m.toUpperCase()).join(':');
|
|
739
|
+
const state = seg[6] === 255 ? -1 : seg[6];
|
|
740
|
+
const cmp = seg[7] === 255 ? -1 : seg[7];
|
|
741
|
+
const voltage = hexToDecimal(decimalToHex(seg[8]) + decimalToHex(seg[9]));
|
|
742
|
+
const b_voltage = hexToDecimal(decimalToHex(seg[10]) + decimalToHex(seg[11]));
|
|
743
|
+
const current = hexToDecimal(decimalToHex(seg[12]) + decimalToHex(seg[13]));
|
|
744
|
+
const b_current = hexToDecimal(decimalToHex(seg[14]) + decimalToHex(seg[15]));
|
|
745
|
+
peerInfos.push({ mac, state, cmp, voltage, b_voltage, current, b_current });
|
|
746
|
+
}
|
|
747
|
+
return { dataStr, status, id, seq, type: `ID${id}`, peerInfos: peerInfos.map((item, i) => ({ id: i, ...item })) };
|
|
800
748
|
}
|
|
801
749
|
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
workStatus,
|
|
805
|
-
chargeStatus,
|
|
806
|
-
chargeVoltage,
|
|
807
|
-
chargeElectricity,
|
|
808
|
-
chargePower,
|
|
809
|
-
chargeTemperature,
|
|
810
|
-
chargeCapacity,
|
|
811
|
-
chargeTime,
|
|
812
|
-
chargeRemainTime,
|
|
813
|
-
chargeCompleteTime,
|
|
814
|
-
outputVoltagePercent,
|
|
815
|
-
outputElectricityPercent,
|
|
816
|
-
id,
|
|
817
|
-
outputElectricity,
|
|
818
|
-
id1,
|
|
819
|
-
chargeSwitch,
|
|
820
|
-
preChargeSwitch,
|
|
821
|
-
fanSwitch,
|
|
822
|
-
protectStatusIndexs,
|
|
823
|
-
alarmStatusIndexs,
|
|
824
|
-
};
|
|
750
|
+
// 未知 ID
|
|
751
|
+
return { dataStr, status, id, seq, raw: body };
|
|
825
752
|
}
|