@moshenguo/ms-data-sdk 0.1.1

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 (38) hide show
  1. package/README.md +35 -0
  2. package/build/MsDataSdk.types.d.ts +18 -0
  3. package/build/MsDataSdk.types.d.ts.map +1 -0
  4. package/build/MsDataSdk.types.js +2 -0
  5. package/build/MsDataSdk.types.js.map +1 -0
  6. package/build/MsDataSdkModule.d.ts +10 -0
  7. package/build/MsDataSdkModule.d.ts.map +1 -0
  8. package/build/MsDataSdkModule.js +4 -0
  9. package/build/MsDataSdkModule.js.map +1 -0
  10. package/build/MsDataSdkModule.web.d.ts +10 -0
  11. package/build/MsDataSdkModule.web.d.ts.map +1 -0
  12. package/build/MsDataSdkModule.web.js +12 -0
  13. package/build/MsDataSdkModule.web.js.map +1 -0
  14. package/build/index.d.ts +8 -0
  15. package/build/index.d.ts.map +1 -0
  16. package/build/index.js +11 -0
  17. package/build/index.js.map +1 -0
  18. package/build/sdk/bleConst.d.ts +286 -0
  19. package/build/sdk/bleConst.d.ts.map +1 -0
  20. package/build/sdk/bleConst.js +289 -0
  21. package/build/sdk/bleConst.js.map +1 -0
  22. package/build/sdk/bleSDK.d.ts +114 -0
  23. package/build/sdk/bleSDK.d.ts.map +1 -0
  24. package/build/sdk/bleSDK.js +977 -0
  25. package/build/sdk/bleSDK.js.map +1 -0
  26. package/build/sdk/constants.d.ts +10 -0
  27. package/build/sdk/constants.d.ts.map +1 -0
  28. package/build/sdk/constants.js +20 -0
  29. package/build/sdk/constants.js.map +1 -0
  30. package/build/sdk/models.d.ts +58 -0
  31. package/build/sdk/models.d.ts.map +1 -0
  32. package/build/sdk/models.js +2 -0
  33. package/build/sdk/models.js.map +1 -0
  34. package/build/sdk/resolveUtil.d.ts +113 -0
  35. package/build/sdk/resolveUtil.d.ts.map +1 -0
  36. package/build/sdk/resolveUtil.js +1448 -0
  37. package/build/sdk/resolveUtil.js.map +1 -0
  38. package/package.json +61 -0
@@ -0,0 +1,1448 @@
1
+ import { DeviceConst, BleConst, DeviceKey } from './bleConst';
2
+ // 字节操作工具类
3
+ export class ResolveUtil {
4
+ // CRC 校验
5
+ static crcValue(value) {
6
+ let crc = 0;
7
+ for (let i = 0; i < value.length - 1; i++) {
8
+ crc += value[i];
9
+ }
10
+ value[value.length - 1] = crc & 0xff;
11
+ }
12
+ static hexByte2Int(b, count) {
13
+ return (b & 0xff) * Math.pow(256, count);
14
+ }
15
+ // BCD 码时间解析
16
+ static bcd2String(bytes) {
17
+ const a = (bytes & 0xf0) >> 4;
18
+ const b = bytes & 0x0f;
19
+ return `${a}${b}`;
20
+ }
21
+ // 字节数组转十六进制字符串
22
+ static intList2String(bytes) {
23
+ return bytes.map(b => b.toString(16).padStart(2, '0').toUpperCase()).join(' ');
24
+ }
25
+ // 字节数组转十六进制字符串(小写)
26
+ static intList3String(bytes) {
27
+ return bytes.map(b => b.toString(16).padStart(2, '0').toLowerCase()).join(' ');
28
+ }
29
+ static setMacSuccessful() {
30
+ return {
31
+ [DeviceKey.DataType]: BleConst.CMD_Set_Mac,
32
+ [DeviceKey.End]: true,
33
+ [DeviceKey.Data]: {}
34
+ };
35
+ }
36
+ static intBitToDouble(value) {
37
+ const buffer = new ArrayBuffer(8); //4
38
+ const view = new DataView(buffer);
39
+ view.setInt32(0, value, false); // big-endian
40
+ return view.getFloat32(0, false);
41
+ }
42
+ // 设备时间解析
43
+ static getDeviceTime(value) {
44
+ const date = `20${this.bcd2String(value[1])}-${this.bcd2String(value[2])}-${this.bcd2String(value[3])} ${this.bcd2String(value[4])}:${this.bcd2String(value[5])}:${this.bcd2String(value[6])}`;
45
+ const gpsDate = `${this.bcd2String(value[9])}.${this.bcd2String(value[10])}.${this.bcd2String(value[11])}`;
46
+ return {
47
+ [DeviceKey.DataType]: BleConst.GetDeviceTime,
48
+ [DeviceKey.End]: true,
49
+ [DeviceKey.Data]: {
50
+ [DeviceKey.DeviceTime]: date,
51
+ [DeviceKey.GPSTime]: gpsDate
52
+ }
53
+ };
54
+ }
55
+ // int转ASCII
56
+ static int2Ascll(value) {
57
+ if (value < 0 || value > 255) {
58
+ throw new Error("Value must be between 0 and 255");
59
+ }
60
+ return String.fromCharCode(value);
61
+ }
62
+ // GPS 时间解析
63
+ static getGpsTime(value) {
64
+ return `${this.bcd2String(value[9])}.${this.bcd2String(value[10])}.${this.bcd2String(value[11])}`;
65
+ }
66
+ // 用户信息解析
67
+ static getUserInfo(value) {
68
+ const userInfo = new Array(6).fill(0);
69
+ for (let i = 0; i < 5; i++) {
70
+ userInfo[i] = this.hexByte2Int(value[i + 1], 0);
71
+ }
72
+ let userId = '';
73
+ for (let i = 6; i < 12; i++) {
74
+ if (value[i] === 0)
75
+ continue;
76
+ userId += String.fromCharCode(this.hexByte2Int(value[i], 0));
77
+ }
78
+ return {
79
+ [DeviceKey.DataType]: BleConst.GetPersonalInfo,
80
+ [DeviceKey.End]: true,
81
+ [DeviceKey.Data]: {
82
+ [DeviceKey.Gender]: userInfo[0],
83
+ [DeviceKey.Age]: userInfo[1],
84
+ [DeviceKey.Height]: userInfo[2],
85
+ [DeviceKey.Weight]: userInfo[3],
86
+ [DeviceKey.Stride]: userInfo[4],
87
+ [DeviceKey.KUserDeviceId]: userId
88
+ }
89
+ };
90
+ }
91
+ // 设备信息解析
92
+ static getDeviceInfo(value) {
93
+ return {
94
+ [DeviceKey.DataType]: BleConst.GetDeviceInfo,
95
+ [DeviceKey.End]: true,
96
+ [DeviceKey.Data]: {
97
+ [DeviceKey.DistanceUnit]: this.hexByte2Int(value[1], 0).toString(),
98
+ [DeviceKey.TimeUnit]: this.hexByte2Int(value[2], 0).toString(),
99
+ [DeviceKey.StatusOfTheRaisedHandOnscreen]: this.hexByte2Int(value[3], 0).toString(),
100
+ [DeviceKey.TempUnit]: this.hexByte2Int(value[4], 0).toString(),
101
+ [DeviceKey.NightMode]: this.hexByte2Int(value[5], 0).toString(),
102
+ [DeviceKey.KBaseHeart]: this.hexByte2Int(value[9], 0).toString(),
103
+ [DeviceKey.ScreenBrightness]: this.hexByte2Int(value[11], 0).toString(),
104
+ [DeviceKey.Dialinterface]: this.hexByte2Int(value[12], 0).toString(),
105
+ [DeviceKey.SocialDistancedwitch]: this.hexByte2Int(value[13], 0).toString(),
106
+ [DeviceKey.ChineseOrEnglish]: this.hexByte2Int(value[14], 0).toString()
107
+ }
108
+ };
109
+ }
110
+ // 实时计步信息解析
111
+ static getActivityData(value) {
112
+ let step = 0;
113
+ let cal = 0;
114
+ let distance = 0;
115
+ let time = 0;
116
+ let exerciseTime = 0;
117
+ for (let i = 1; i < 5; i++) {
118
+ step += this.hexByte2Int(value[i], i - 1);
119
+ }
120
+ for (let i = 5; i < 9; i++) {
121
+ cal += this.hexByte2Int(value[i], i - 5);
122
+ }
123
+ for (let i = 9; i < 13; i++) {
124
+ distance += this.hexByte2Int(value[i], i - 9);
125
+ }
126
+ for (let i = 13; i < 17; i++) {
127
+ time += this.hexByte2Int(value[i], i - 13);
128
+ }
129
+ for (let i = 17; i < 21; i++) {
130
+ exerciseTime += this.hexByte2Int(value[i], i - 17);
131
+ }
132
+ const heart = this.hexByte2Int(value[21], 0);
133
+ let temp = 0;
134
+ let spo2 = 0;
135
+ if (value.length > 22) {
136
+ temp = this.hexByte2Int(value[22], 0) + this.hexByte2Int(value[23], 1);
137
+ if (value.length > 24) {
138
+ spo2 = this.hexByte2Int(value[24], 0);
139
+ }
140
+ }
141
+ return {
142
+ [DeviceKey.DataType]: BleConst.RealTimeStep,
143
+ [DeviceKey.End]: true,
144
+ [DeviceKey.Data]: {
145
+ [DeviceKey.Step]: step.toString(),
146
+ [DeviceKey.Calories]: (cal / 100).toFixed(1),
147
+ [DeviceKey.Distance]: (distance / 100).toFixed(1),
148
+ [DeviceKey.ExerciseMinutes]: (time / 60).toString(),
149
+ [DeviceKey.HeartRate]: heart.toString(),
150
+ [DeviceKey.ActiveMinutes]: exerciseTime.toString(),
151
+ [DeviceKey.TempData]: temp.toFixed(1),
152
+ [DeviceKey.Blood_oxygen]: spo2.toString()
153
+ }
154
+ };
155
+ }
156
+ // 步数目标解析
157
+ static getGoal(value) {
158
+ let goal = 0;
159
+ let distance = 0;
160
+ let calorie = 0;
161
+ let sleepTime = 0;
162
+ for (let i = 0; i < 4; i++) {
163
+ goal += this.hexByte2Int(value[i + 1], i);
164
+ }
165
+ for (let i = 0; i <= 1; i++) {
166
+ distance += this.hexByte2Int(value[i + 7], i);
167
+ }
168
+ for (let i = 0; i <= 1; i++) {
169
+ calorie += this.hexByte2Int(value[i + 9], i);
170
+ }
171
+ for (let i = 0; i <= 1; i++) {
172
+ sleepTime += this.hexByte2Int(value[i + 11], i);
173
+ }
174
+ return {
175
+ [DeviceKey.DataType]: BleConst.GetStepGoal,
176
+ [DeviceKey.End]: true,
177
+ [DeviceKey.Data]: {
178
+ [DeviceKey.StepGoal]: goal.toString(),
179
+ [DeviceKey.DistanceGoal]: distance.toString(),
180
+ [DeviceKey.CalorieGoal]: calorie.toString(),
181
+ [DeviceKey.SleepTimeGoal]: sleepTime.toString()
182
+ }
183
+ };
184
+ }
185
+ // 设备电量解析
186
+ static getDeviceBattery(value) {
187
+ const battery = this.hexByte2Int(value[1], 0);
188
+ return {
189
+ [DeviceKey.DataType]: BleConst.GetDeviceBatteryLevel,
190
+ [DeviceKey.End]: true,
191
+ [DeviceKey.Data]: {
192
+ [DeviceKey.BatteryLevel]: battery.toString()
193
+ }
194
+ };
195
+ }
196
+ // 设备 MAC 地址解析
197
+ static getDeviceAddress(value) {
198
+ if (value.length === 0)
199
+ return {};
200
+ const addressParts = [];
201
+ for (let i = 1; i < 7; i++) {
202
+ const mac = value[i].toString(16).padStart(2, '0');
203
+ addressParts.push(mac);
204
+ }
205
+ const macAddress = addressParts.join(':');
206
+ return {
207
+ [DeviceKey.DataType]: BleConst.GetDeviceMacAddress,
208
+ [DeviceKey.End]: true,
209
+ [DeviceKey.Data]: {
210
+ [DeviceKey.MacAddress]: macAddress
211
+ }
212
+ };
213
+ }
214
+ // 设备版本号解析
215
+ static getDeviceVersion(value) {
216
+ if (value.length === 0)
217
+ return {};
218
+ const versionParts = [];
219
+ for (let i = 1; i < 5; i++) {
220
+ versionParts.push(value[i].toString(16));
221
+ }
222
+ const version = versionParts.join('.');
223
+ return {
224
+ [DeviceKey.DataType]: BleConst.GetDeviceVersion,
225
+ [DeviceKey.End]: true,
226
+ [DeviceKey.Data]: {
227
+ [DeviceKey.DeviceVersion]: version
228
+ }
229
+ };
230
+ }
231
+ // 恢复出厂设置
232
+ static Reset() {
233
+ return {
234
+ [DeviceKey.DataType]: BleConst.CMD_Reset,
235
+ [DeviceKey.End]: true
236
+ };
237
+ }
238
+ // MCU 软复位指令
239
+ static MCUReset() {
240
+ return {
241
+ [DeviceKey.DataType]: BleConst.CMD_MCUReset,
242
+ [DeviceKey.End]: true
243
+ };
244
+ }
245
+ // 第三方提醒命令
246
+ static Notify() {
247
+ return {
248
+ [DeviceKey.DataType]: BleConst.Notify,
249
+ [DeviceKey.End]: true
250
+ };
251
+ }
252
+ // 设备名称解析
253
+ static getDeviceName(value) {
254
+ let name = "";
255
+ for (let i = 1; i < 15; i++) {
256
+ const charValue = this.hexByte2Int(value[i], 0);
257
+ if (charValue === 0 || charValue > 127)
258
+ continue;
259
+ name += String.fromCharCode(charValue);
260
+ }
261
+ return {
262
+ [DeviceKey.DataType]: BleConst.GetDeviceName,
263
+ [DeviceKey.End]: true,
264
+ [DeviceKey.Data]: {
265
+ [DeviceKey.DeviceName]: name
266
+ }
267
+ };
268
+ }
269
+ // 自动测量心率时间段解析
270
+ static getAutoHeart(value) {
271
+ const time = this.hexByte2Int(value[7], 0) + this.hexByte2Int(value[8], 1);
272
+ return {
273
+ [DeviceKey.DataType]: BleConst.GetAutomaticHRMonitoring,
274
+ [DeviceKey.End]: true,
275
+ [DeviceKey.Data]: {
276
+ [DeviceKey.WorkMode]: this.hexByte2Int(value[1], 0).toString(),
277
+ [DeviceKey.StartTime]: this.bcd2String(value[2]),
278
+ [DeviceKey.KHeartStartMinter]: this.bcd2String(value[3]),
279
+ [DeviceKey.EndTime]: this.bcd2String(value[4]),
280
+ [DeviceKey.KHeartEndMinter]: this.bcd2String(value[5]),
281
+ [DeviceKey.Weeks]: this.getByteString(value[6]),
282
+ [DeviceKey.IntervalTime]: time.toString()
283
+ }
284
+ };
285
+ }
286
+ // 周解析工具
287
+ static getWeekInt(ar) {
288
+ let week = 0;
289
+ for (let i = 0; i < ar.length; i++) {
290
+ if (ar[i] === 1) {
291
+ week += Math.pow(2, i);
292
+ }
293
+ }
294
+ return week;
295
+ }
296
+ // 字节转字符串
297
+ static getByteString(b) {
298
+ const array = new Array(8).fill(0);
299
+ const parts = [];
300
+ for (let i = 0; i <= 6; i++) {
301
+ array[i] = b & 1;
302
+ b = b >> 1;
303
+ parts.push(array[i].toString());
304
+ }
305
+ return parts.join('-');
306
+ }
307
+ // 字节数组解析
308
+ static getByteArray(b) {
309
+ const array = new Array(8).fill(0);
310
+ let result = '';
311
+ for (let i = 0; i <= 7; i++) {
312
+ array[i] = b & 1;
313
+ b = b >> 1;
314
+ result += array[i];
315
+ }
316
+ return result;
317
+ }
318
+ /**
319
+ * 字节转整数(对应原 _hexByte2Int)
320
+ * @param byte 字节值
321
+ * @param shift 位移量(用于多字节拼接)
322
+ */
323
+ static _hexByte2Int(byte, shift) {
324
+ return byte << (8 * shift);
325
+ }
326
+ /**
327
+ * BCD编码转字符串(对应原 _bcd2String)
328
+ * BCD编码:每个字节表示2位十进制数(如0x12 → "12")
329
+ */
330
+ static _bcd2String(byte) {
331
+ const high = (byte >> 4) & 0x0F; // 高4位
332
+ const low = byte & 0x0F; // 低4位
333
+ return `${high}${low}`;
334
+ }
335
+ /**
336
+ * 久坐提醒
337
+ */
338
+ static getActivityAlarm(value) {
339
+ const mapData = {
340
+ [DeviceKey.StartTimeHour]: this._bcd2String(value[1]),
341
+ [DeviceKey.StartTimeMin]: this._bcd2String(value[2]),
342
+ [DeviceKey.EndTimeHour]: this._bcd2String(value[3]),
343
+ [DeviceKey.EndTimeMin]: this._bcd2String(value[4]),
344
+ [DeviceKey.Week]: this.getByteString(value[5]),
345
+ [DeviceKey.IntervalTime]: this._hexByte2Int(value[6], 0).toString(),
346
+ [DeviceKey.LeastSteps]: this._hexByte2Int(value[7], 0).toString(),
347
+ [DeviceKey.OpenOrClose]: this._hexByte2Int(value[8], 0).toString()
348
+ };
349
+ return {
350
+ [DeviceKey.DataType]: BleConst.GetSedentaryReminder,
351
+ [DeviceKey.End]: true,
352
+ [DeviceKey.Data]: mapData
353
+ };
354
+ }
355
+ /**
356
+ * 总运动数据解析
357
+ */
358
+ static getTotalStepData(value) {
359
+ console.log('total:', value);
360
+ const maps = {
361
+ [DeviceKey.DataType]: BleConst.GetTotalActivityData,
362
+ [DeviceKey.End]: false,
363
+ [DeviceKey.Data]: []
364
+ };
365
+ const count = 27;
366
+ const length = value.length;
367
+ const size = Math.floor(length / count);
368
+ if (size === 0) {
369
+ maps[DeviceKey.End] = true;
370
+ return maps;
371
+ }
372
+ for (let i = 0; i < size; i++) {
373
+ // 检查是否结束
374
+ const flag = 1 + (i + 1) * count;
375
+ if (flag < length && value[flag] === 0xff) {
376
+ maps[DeviceKey.End] = true;
377
+ }
378
+ // 解析日期
379
+ const date = `20${this._bcd2String(value[2 + i * count])}.${this._bcd2String(value[3 + i * count])}.${this._bcd2String(value[4 + i * count])}`;
380
+ // 解析步数
381
+ let step = 0;
382
+ for (let j = 0; j < 4; j++) {
383
+ step += this._hexByte2Int(value[5 + j + i * count], j);
384
+ }
385
+ // 解析运动时间
386
+ let time = 0;
387
+ for (let j = 0; j < 4; j++) {
388
+ time += this._hexByte2Int(value[9 + j + i * count], j);
389
+ }
390
+ // 解析距离
391
+ let distance = 0;
392
+ for (let j = 0; j < 4; j++) {
393
+ distance += this._hexByte2Int(value[13 + j + i * count], j);
394
+ }
395
+ // 解析卡路里
396
+ let cal = 0;
397
+ for (let j = 0; j < 4; j++) {
398
+ cal += this._hexByte2Int(value[17 + j + i * count], j);
399
+ }
400
+ // 解析目标值
401
+ let goal = this._hexByte2Int(value[21 + i * count], 0) + this._hexByte2Int(value[22 + i * count], 1);
402
+ // 解析活跃时间
403
+ let exerciseTime = 0;
404
+ for (let j = 0; j < 4; j++) {
405
+ exerciseTime += this._hexByte2Int(value[count - 4 + j + i * count], j);
406
+ }
407
+ // 组装数据
408
+ maps[DeviceKey.Data].push({
409
+ [DeviceKey.Date]: date,
410
+ [DeviceKey.Step]: step.toString(),
411
+ [DeviceKey.ExerciseMinutes]: time.toString(),
412
+ [DeviceKey.Calories]: (cal / 100).toFixed(1),
413
+ [DeviceKey.Distance]: (distance / 100).toFixed(1),
414
+ [DeviceKey.Goal]: goal.toString(),
415
+ [DeviceKey.ActiveMinutes]: exerciseTime
416
+ });
417
+ }
418
+ return maps;
419
+ }
420
+ /**
421
+ * 详细运动数据解析
422
+ */
423
+ static getDetailData(value) {
424
+ const maps = {
425
+ [DeviceKey.DataType]: BleConst.GetDetailActivityData,
426
+ [DeviceKey.End]: false,
427
+ [DeviceKey.Data]: []
428
+ };
429
+ const count = 25;
430
+ const length = value.length;
431
+ const size = Math.floor(length / count);
432
+ if (size === 0) {
433
+ maps[DeviceKey.End] = true;
434
+ return maps;
435
+ }
436
+ for (let i = 0; i < size; i++) {
437
+ // 检查是否结束
438
+ if (value[length - 1] === 0xff) {
439
+ maps[DeviceKey.End] = true;
440
+ }
441
+ // 解析日期时间
442
+ const date = `20${this._bcd2String(value[3 + i * 25])}.${this._bcd2String(value[4 + i * 25])}.${this._bcd2String(value[5 + i * 25])} ${this._bcd2String(value[6 + i * 25])}:${this._bcd2String(value[7 + i * 25])}:${this._bcd2String(value[8 + i * 25])}`;
443
+ // 解析步数
444
+ let step = 0;
445
+ for (let j = 0; j < 2; j++) {
446
+ step += this._hexByte2Int(value[9 + j + i * 25], j);
447
+ }
448
+ // 解析卡路里
449
+ let cal = 0;
450
+ for (let j = 0; j < 2; j++) {
451
+ cal += this._hexByte2Int(value[11 + j + i * 25], j);
452
+ }
453
+ // 解析距离
454
+ let distance = 0;
455
+ for (let j = 0; j < 2; j++) {
456
+ distance += this._hexByte2Int(value[13 + j + i * 25], j);
457
+ }
458
+ // 解析步数数组
459
+ const arraySteps = [];
460
+ for (let j = 0; j < 10; j++) {
461
+ arraySteps.push(this._hexByte2Int(value[15 + j + i * 25], 0).toString());
462
+ }
463
+ // 组装数据
464
+ maps[DeviceKey.Data].push({
465
+ [DeviceKey.Date]: date,
466
+ [DeviceKey.KDetailMinterStep]: step.toString(),
467
+ [DeviceKey.Calories]: (cal / 100).toFixed(2),
468
+ [DeviceKey.Distance]: (distance / 100).toFixed(2),
469
+ [DeviceKey.ArraySteps]: arraySteps.join(' ')
470
+ });
471
+ }
472
+ return maps;
473
+ }
474
+ /**
475
+ * 睡眠数据解析
476
+ */
477
+ static getSleepData(value) {
478
+ const length = value.length;
479
+ const maps = {
480
+ [DeviceKey.DataType]: BleConst.GetDetailSleepData,
481
+ [DeviceKey.End]: false,
482
+ [DeviceKey.Data]: []
483
+ };
484
+ // 检查是否结束
485
+ const end = value[value.length - 1] === 0xff && value[value.length - 2] === DeviceConst.CMD_Get_SleepData;
486
+ if (end) {
487
+ maps[DeviceKey.End] = true;
488
+ }
489
+ // 解析130字节或132字节格式
490
+ if (length === 130 || (end && length === 132)) {
491
+ const date = `20${this._bcd2String(value[3])}-${this._bcd2String(value[4])}-${this._bcd2String(value[5])} ${this._bcd2String(value[6])}:${this._bcd2String(value[7])}:${this._bcd2String(value[8])}`;
492
+ const sleepLength = this._hexByte2Int(value[9], 0);
493
+ const arraySleep = [];
494
+ for (let j = 0; j < sleepLength; j++) {
495
+ arraySleep.push(this._hexByte2Int(value[10 + j], 0).toString());
496
+ }
497
+ maps[DeviceKey.Data].push({
498
+ [DeviceKey.Date]: date,
499
+ [DeviceKey.ArraySleep]: arraySleep.join(' '),
500
+ [DeviceKey.sleepUnitLength]: '1'
501
+ });
502
+ }
503
+ else {
504
+ // 解析34字节格式
505
+ const count = 34;
506
+ const size = Math.floor(length / count);
507
+ if (size === 0) {
508
+ maps[DeviceKey.End] = true;
509
+ return maps;
510
+ }
511
+ for (let i = 0; i < size; i++) {
512
+ const date = `20${this._bcd2String(value[3 + i * 34])}-${this._bcd2String(value[4 + i * 34])}-${this._bcd2String(value[5 + i * 34])} ${this._bcd2String(value[6 + i * 34])}:${this._bcd2String(value[7 + i * 34])}:${this._bcd2String(value[8 + i * 34])}`;
513
+ const sleepLength = this._hexByte2Int(value[9 + i * 34], 0);
514
+ const arraySleep = [];
515
+ for (let j = 0; j < sleepLength; j++) {
516
+ arraySleep.push(this._hexByte2Int(value[10 + j + i * 34], 0).toString());
517
+ }
518
+ maps[DeviceKey.Data].push({
519
+ [DeviceKey.Date]: date,
520
+ [DeviceKey.ArraySleep]: arraySleep.join(' '),
521
+ [DeviceKey.sleepUnitLength]: '5'
522
+ });
523
+ }
524
+ }
525
+ return maps;
526
+ }
527
+ /**
528
+ * 自动血氧数据解析
529
+ */
530
+ static getAutoBloodOxygen(value) {
531
+ const maps = {
532
+ [DeviceKey.DataType]: BleConst.AutoBloodOxygen,
533
+ [DeviceKey.End]: false,
534
+ [DeviceKey.Data]: []
535
+ };
536
+ const count = 10;
537
+ const length = value.length;
538
+ const size = Math.floor(length / count);
539
+ if (size === 0) {
540
+ maps[DeviceKey.End] = true;
541
+ return maps;
542
+ }
543
+ for (let i = 0; i < size; i++) {
544
+ // 检查是否结束
545
+ if (value[length - 1] === 0xff) {
546
+ maps[DeviceKey.End] = true;
547
+ }
548
+ // 解析日期时间
549
+ const date = `20${this._bcd2String(value[3 + i * count])}.${this._bcd2String(value[4 + i * count])}.${this._bcd2String(value[5 + i * count])} ${this._bcd2String(value[6 + i * count])}:${this._bcd2String(value[7 + i * count])}:${this._bcd2String(value[8 + i * count])}`;
550
+ // 解析血氧值
551
+ const bloodOxygen = this._hexByte2Int(value[9 + i * 10], 0).toString();
552
+ maps[DeviceKey.Data].push({
553
+ [DeviceKey.Date]: date,
554
+ [DeviceKey.Blood_oxygen]: bloodOxygen
555
+ });
556
+ }
557
+ return maps;
558
+ }
559
+ /**
560
+ * 历史血氧数据解析(与自动血氧逻辑一致,复用代码)
561
+ */
562
+ static getBloodoxygen(value) {
563
+ const maps = {
564
+ [DeviceKey.DataType]: BleConst.Blood_oxygen,
565
+ [DeviceKey.End]: false,
566
+ [DeviceKey.Data]: []
567
+ };
568
+ const count = 10;
569
+ const length = value.length;
570
+ const size = Math.floor(length / count);
571
+ if (size === 0) {
572
+ maps[DeviceKey.End] = true;
573
+ return maps;
574
+ }
575
+ for (let i = 0; i < size; i++) {
576
+ // 检查是否结束
577
+ if (value[length - 1] === 0xff) {
578
+ maps[DeviceKey.End] = true;
579
+ }
580
+ // 解析日期时间
581
+ const date = `20${this._bcd2String(value[3 + i * count])}.${this._bcd2String(value[4 + i * count])}.${this._bcd2String(value[5 + i * count])} ${this._bcd2String(value[6 + i * count])}:${this._bcd2String(value[7 + i * count])}:${this._bcd2String(value[8 + i * count])}`;
582
+ // 解析血氧值
583
+ const bloodOxygen = this._hexByte2Int(value[9 + i * 10], 0).toString();
584
+ maps[DeviceKey.Data].push({
585
+ [DeviceKey.Date]: date,
586
+ [DeviceKey.Blood_oxygen]: bloodOxygen
587
+ });
588
+ }
589
+ return maps;
590
+ }
591
+ /**
592
+ * 历史心率数据解析
593
+ */
594
+ static getHeartData(value) {
595
+ const maps = {
596
+ [DeviceKey.DataType]: BleConst.GetDynamicHR,
597
+ [DeviceKey.End]: false,
598
+ [DeviceKey.Data]: []
599
+ };
600
+ const count = 24;
601
+ const length = value.length;
602
+ const size = Math.floor(length / count);
603
+ if (size === 0) {
604
+ maps[DeviceKey.End] = true;
605
+ return maps;
606
+ }
607
+ for (let i = 0; i < size; i++) {
608
+ // 检查是否结束
609
+ if (value[length - 1] === 0xff) {
610
+ maps[DeviceKey.End] = true;
611
+ }
612
+ // 解析日期时间
613
+ const date = `20${this._bcd2String(value[3 + i * count])}.${this._bcd2String(value[4 + i * count])}.${this._bcd2String(value[5 + i * count])} ${this._bcd2String(value[6 + i * count])}:${this._bcd2String(value[7 + i * count])}:${this._bcd2String(value[8 + i * count])}`;
614
+ // 解析心率数组
615
+ const arrayHR = [];
616
+ for (let j = 0; j < 15; j++) {
617
+ arrayHR.push(this._hexByte2Int(value[9 + j + i * count], 0).toString());
618
+ }
619
+ maps[DeviceKey.Data].push({
620
+ [DeviceKey.Date]: date,
621
+ [DeviceKey.ArrayDynamicHR]: arrayHR.join(' ')
622
+ });
623
+ }
624
+ return maps;
625
+ }
626
+ /**
627
+ * 单次历史心率数据解析
628
+ */
629
+ static getOnceHeartData(value) {
630
+ const maps = {
631
+ [DeviceKey.DataType]: BleConst.GetStaticHR,
632
+ [DeviceKey.End]: false,
633
+ [DeviceKey.Data]: []
634
+ };
635
+ const count = 10;
636
+ const length = value.length;
637
+ const size = Math.floor(length / count);
638
+ // 检查是否结束
639
+ if (size === 0 || (size === 1 && value[1] === 0x99)) {
640
+ maps[DeviceKey.End] = true;
641
+ return maps;
642
+ }
643
+ for (let i = 0; i < size; i++) {
644
+ if (value[length - 1] === 0xff) {
645
+ maps[DeviceKey.End] = true;
646
+ }
647
+ // 解析日期时间
648
+ const date = `20${this._bcd2String(value[3 + i * 10])}.${this._bcd2String(value[4 + i * 10])}.${this._bcd2String(value[5 + i * 10])} ${this._bcd2String(value[6 + i * 10])}:${this._bcd2String(value[7 + i * 10])}:${this._bcd2String(value[8 + i * 10])}`;
649
+ // 解析心率值
650
+ const heartRate = this._hexByte2Int(value[9 + i * 10], 0).toString();
651
+ maps[DeviceKey.Data].push({
652
+ [DeviceKey.Date]: date,
653
+ [DeviceKey.StaticHR]: heartRate
654
+ });
655
+ }
656
+ return maps;
657
+ }
658
+ // resolveUtil.tsx
659
+ // HRV测试数据解析
660
+ static getHrvTestData(value) {
661
+ const result = {
662
+ [DeviceKey.DataType]: BleConst.GetHRVData,
663
+ [DeviceKey.End]: false,
664
+ [DeviceKey.Data]: []
665
+ };
666
+ const count = 15;
667
+ const length = value.length;
668
+ const size = Math.floor(length / count);
669
+ if (size === 0) {
670
+ result[DeviceKey.End] = true;
671
+ return result;
672
+ }
673
+ if (value[value.length - 1] === 0xff) {
674
+ result[DeviceKey.End] = true;
675
+ }
676
+ for (let i = 0; i < size; i++) {
677
+ const date = `20${this.bcd2String(value[3 + i * count])}.${this.bcd2String(value[4 + i * count])}.${this.bcd2String(value[5 + i * count])} ${this.bcd2String(value[6 + i * count])}:${this.bcd2String(value[7 + i * count])}:${this.bcd2String(value[8 + i * count])}`;
678
+ const hrv = this.hexByte2Int(value[9 + i * count], 0).toString();
679
+ const blood = this.hexByte2Int(value[10 + i * count], 0).toString();
680
+ const heart = this.hexByte2Int(value[11 + i * count], 0).toString();
681
+ const tired = this.hexByte2Int(value[12 + i * count], 0).toString();
682
+ const moodValue = this.hexByte2Int(value[13 + i * count], 0).toString();
683
+ const breathRate = this.hexByte2Int(value[14 + i * count], 0).toString();
684
+ result[DeviceKey.Data].push({
685
+ [DeviceKey.Date]: date,
686
+ [DeviceKey.HRV]: hrv,
687
+ [DeviceKey.VascularAging]: blood,
688
+ [DeviceKey.HeartRate]: heart,
689
+ [DeviceKey.Stress]: tired,
690
+ [DeviceKey.highBP]: moodValue,
691
+ [DeviceKey.lowBP]: breathRate
692
+ });
693
+ }
694
+ return result;
695
+ }
696
+ // 闹钟数据解析
697
+ static getClockData(value) {
698
+ console.log("getClockData:", value);
699
+ const result = {
700
+ [DeviceKey.DataType]: BleConst.GetAlarmClock,
701
+ [DeviceKey.End]: false,
702
+ [DeviceKey.Data]: []
703
+ };
704
+ const count = 41;
705
+ const length = value.length;
706
+ var isDele = false;
707
+ const size = Math.floor(length / count);
708
+ if (size === 0) {
709
+ result[DeviceKey.End] = true;
710
+ return result;
711
+ }
712
+ if (value[1] == 0x99 && length == 16) {
713
+ isDele = true;
714
+ }
715
+ result[DeviceKey.IsDeleteData] = isDele;
716
+ for (let i = 0; i < size; i++) {
717
+ const flag = 1 + (i + 1) * count;
718
+ if (flag < length && value[flag] === 0xff) {
719
+ result[DeviceKey.End] = true;
720
+ }
721
+ const id = this.hexByte2Int(value[4 + i * count], 0).toString();
722
+ const enable = this.hexByte2Int(value[5 + i * count], 0).toString();
723
+ const type = this.hexByte2Int(value[6 + i * count], 0).toString();
724
+ const hour = this.bcd2String(value[7 + i * count]);
725
+ const min = this.bcd2String(value[8 + i * count]);
726
+ const week = this.hexByte2Int(value[9 + i * count], 0);
727
+ const lengthS = this.hexByte2Int(value[10 + i * count], 0);
728
+ let content = "";
729
+ for (let j = 0; j < lengthS; j++) {
730
+ const charValue = value[11 + j + i * count];
731
+ if (charValue === 0)
732
+ continue;
733
+ content += this.int2Ascll(this.hexByte2Int(charValue, 0));
734
+ }
735
+ result[DeviceKey.Data].push({
736
+ [DeviceKey.KAlarmId]: id,
737
+ [DeviceKey.OpenOrClose]: enable,
738
+ [DeviceKey.ClockType]: type,
739
+ [DeviceKey.ClockTime]: hour,
740
+ [DeviceKey.KAlarmMinter]: min,
741
+ [DeviceKey.Week]: week,
742
+ [DeviceKey.KAlarmContent]: content,
743
+ [DeviceKey.KAlarmLength]: lengthS.toString()
744
+ });
745
+ }
746
+ return result;
747
+ }
748
+ // 腋下温度数据解析
749
+ static getTempDataer(value) {
750
+ const result = {
751
+ [DeviceKey.DataType]: BleConst.GetAxillaryTemperatureDataWithMode,
752
+ [DeviceKey.End]: false,
753
+ [DeviceKey.Data]: []
754
+ };
755
+ const count = 11;
756
+ const length = value.length;
757
+ const size = Math.floor(length / count);
758
+ if (size === 0 || value[length - 1] === 0xff) {
759
+ result[DeviceKey.End] = true;
760
+ return result;
761
+ }
762
+ for (let i = 0; i < size; i++) {
763
+ if (value[length - 1] === 0xff) {
764
+ result[DeviceKey.End] = true;
765
+ }
766
+ const date = `20${this.bcd2String(value[3 + i * count])}.${this.bcd2String(value[4 + i * count])}.${this.bcd2String(value[5 + i * count])} ${this.bcd2String(value[6 + i * count])}:${this.bcd2String(value[7 + i * count])}:${this.bcd2String(value[8 + i * count])}`;
767
+ const tempValue = this.hexByte2Int(value[9 + i * count], 0) +
768
+ this.hexByte2Int(value[10 + i * count], 1);
769
+ result[DeviceKey.Data].push({
770
+ [DeviceKey.Date]: date,
771
+ [DeviceKey.axillaryTemperature]: (tempValue * 0.1).toFixed(1)
772
+ });
773
+ }
774
+ return result;
775
+ }
776
+ // 二维码相关功能
777
+ static getQrCode(value, flag) {
778
+ if (flag) {
779
+ return {
780
+ [DeviceKey.DataType]: BleConst.EnterQrCode,
781
+ [DeviceKey.End]: true,
782
+ [DeviceKey.Data]: {}
783
+ };
784
+ }
785
+ else {
786
+ if (value[1] === 0x80 || value[1] === 0x81) {
787
+ return {
788
+ [DeviceKey.DataType]: BleConst.QrCodeBandBack,
789
+ [DeviceKey.End]: true,
790
+ [DeviceKey.Data]: {
791
+ [DeviceKey.Band]: value[1] === 0x81 ? "1" : "0"
792
+ }
793
+ };
794
+ }
795
+ else {
796
+ return {
797
+ [DeviceKey.DataType]: BleConst.ExitQrCode,
798
+ [DeviceKey.End]: true,
799
+ [DeviceKey.Data]: {}
800
+ };
801
+ }
802
+ }
803
+ }
804
+ // 温度历史数据解析
805
+ static getTempData(value) {
806
+ const result = {
807
+ [DeviceKey.DataType]: BleConst.Temperature_history,
808
+ [DeviceKey.End]: false,
809
+ [DeviceKey.Data]: []
810
+ };
811
+ const count = 11;
812
+ const length = value.length;
813
+ const size = Math.floor(length / count);
814
+ if (size === 0 ||
815
+ value[length - 1] === 0xff ||
816
+ (size === 1 && value[1] === 0x99)) {
817
+ result[DeviceKey.End] = true;
818
+ return result;
819
+ }
820
+ for (let i = 0; i < size; i++) {
821
+ if (value[length - 1] === 0xff) {
822
+ result[DeviceKey.End] = true;
823
+ }
824
+ const date = `20${this.bcd2String(value[3 + i * count])}.${this.bcd2String(value[4 + i * count])}.${this.bcd2String(value[5 + i * count])} ${this.bcd2String(value[6 + i * count])}:${this.bcd2String(value[7 + i * count])}:${this.bcd2String(value[8 + i * count])}`;
825
+ const tempValue = this.hexByte2Int(value[9 + i * count], 0) +
826
+ this.hexByte2Int(value[10 + i * count], 1);
827
+ result[DeviceKey.Data].push({
828
+ [DeviceKey.Date]: date,
829
+ [DeviceKey.temperature]: (tempValue * 0.1).toFixed(1)
830
+ });
831
+ }
832
+ return result;
833
+ }
834
+ // 运动模式数据解析
835
+ static getExerciseData(value) {
836
+ const result = {
837
+ [DeviceKey.DataType]: BleConst.GetActivityModeData,
838
+ [DeviceKey.End]: false,
839
+ [DeviceKey.Data]: []
840
+ };
841
+ const count = 25;
842
+ const length = value.length;
843
+ const size = Math.floor(length / count);
844
+ if (size === 0) {
845
+ result[DeviceKey.End] = true;
846
+ return result;
847
+ }
848
+ for (let i = 0; i < size; i++) {
849
+ const flag = 1 + (i + 1) * count;
850
+ if (flag < length && i === size - 1 && value[flag] === 0xff) {
851
+ result[DeviceKey.End] = true;
852
+ }
853
+ const date = `20${this.bcd2String(value[3 + i * count])}.${this.bcd2String(value[4 + i * count])}.${this.bcd2String(value[5 + i * count])} ${this.bcd2String(value[6 + i * count])}:${this.bcd2String(value[7 + i * count])}:${this.bcd2String(value[8 + i * count])}`;
854
+ const mode = this.hexByte2Int(value[9 + i * count], 0).toString();
855
+ const heartRate = this.hexByte2Int(value[10 + i * count], 0).toString();
856
+ const periodTime = this.getData(2, 11 + i * count, value);
857
+ const steps = this.getData(2, 13 + i * count, value);
858
+ const speedMin = this.hexByte2Int(value[15 + i * count], 0);
859
+ const speedS = this.hexByte2Int(value[16 + i * count], 0);
860
+ const valueCal = new Array(4).fill(0);
861
+ for (let j = 0; j < 4; j++) {
862
+ valueCal[3 - j] = value[17 + j + i * count];
863
+ }
864
+ const valueDistance = new Array(4).fill(0);
865
+ for (let j = 0; j < 4; j++) {
866
+ valueDistance[3 - j] = value[21 + j + i * count];
867
+ }
868
+ const cal = this.getFloat(valueCal, 0);
869
+ const distance = this.getFloat(valueDistance, 0);
870
+ result[DeviceKey.Data].push({
871
+ [DeviceKey.Date]: date,
872
+ [DeviceKey.ActivityMode]: mode,
873
+ [DeviceKey.HeartRate]: heartRate,
874
+ [DeviceKey.ActiveMinutes]: periodTime.toString(),
875
+ [DeviceKey.Step]: steps.toString(),
876
+ [DeviceKey.Pace]: `${speedMin.toString(16)}'${speedS.toString(16)}`,
877
+ [DeviceKey.Distance]: distance.toFixed(2),
878
+ [DeviceKey.Calories]: cal.toFixed(1)
879
+ });
880
+ }
881
+ return result;
882
+ }
883
+ // 活动运动数据解析
884
+ static getActivityExerciseData(value) {
885
+ let steps = 0;
886
+ let time = 0;
887
+ const valueCal = new Array(4).fill(0);
888
+ for (let i = 0; i < 4; i++) {
889
+ steps += this.hexByte2Int(value[i + 2], i);
890
+ valueCal[3 - i] = value[i + 6];
891
+ time += this.hexByte2Int(value[i + 10], i);
892
+ }
893
+ const heartRate = this.hexByte2Int(value[1], 0);
894
+ const kcal = this.getFloat(valueCal, 0);
895
+ return {
896
+ [DeviceKey.DataType]: BleConst.EnterActivityMode,
897
+ [DeviceKey.End]: true,
898
+ [DeviceKey.Data]: {
899
+ [DeviceKey.HeartRate]: heartRate.toString(),
900
+ [DeviceKey.Step]: steps.toString(),
901
+ [DeviceKey.Calories]: kcal.toFixed(1),
902
+ [DeviceKey.ActiveMinutes]: time.toString()
903
+ }
904
+ };
905
+ }
906
+ // 设置时间成功响应
907
+ static setTimeSuccessful(value) {
908
+ return {
909
+ [DeviceKey.DataType]: BleConst.SetDeviceTime,
910
+ [DeviceKey.End]: true,
911
+ [DeviceKey.Data]: {
912
+ [DeviceKey.KPhoneDataLength]: this.hexByte2Int(value[1], 0).toString()
913
+ }
914
+ };
915
+ }
916
+ // 辅助方法:获取数据块
917
+ static getData(length, start, value) {
918
+ let data = 0;
919
+ for (let j = 0; j < length; j++) {
920
+ data += this.hexByte2Int(value[j + start], j);
921
+ }
922
+ return data;
923
+ }
924
+ // 字节转浮点
925
+ static getFloat(arr, index) {
926
+ return this.intBitToDouble(this.getInt(arr, index));
927
+ }
928
+ static getInt(arr, index) {
929
+ return (((arr[index] & 0xff) << 24) |
930
+ ((arr[index + 1] & 0xff) << 16) |
931
+ ((arr[index + 2] & 0xff) << 8) |
932
+ (arr[index + 3] & 0xff));
933
+ }
934
+ // 设置成功响应
935
+ static setMethodSuccessful(dataType) {
936
+ return {
937
+ [DeviceKey.DataType]: dataType,
938
+ [DeviceKey.End]: true,
939
+ [DeviceKey.Data]: {}
940
+ };
941
+ }
942
+ // ECG数据解析
943
+ static getEcgHistoryData(value) {
944
+ const result = {
945
+ [DeviceKey.DataType]: BleConst.ECGdata,
946
+ [DeviceKey.End]: false,
947
+ [DeviceKey.Data]: {}
948
+ };
949
+ const length = value.length;
950
+ if (length === 3 ||
951
+ (value[length - 3] === 0x71 &&
952
+ value[length - 2] === 0xff &&
953
+ value[length - 1] === 0xff)) {
954
+ result[DeviceKey.End] = true;
955
+ return result;
956
+ }
957
+ const id = this.hexByte2Int(value[1], 0) + this.hexByte2Int(value[2], 1);
958
+ let offset = 3;
959
+ if (id === 0) {
960
+ const date = `20${this.bcd2String(value[3])}-${this.bcd2String(value[4])}-${this.bcd2String(value[5])} ${this.bcd2String(value[6])}:${this.bcd2String(value[7])}:${this.bcd2String(value[8])}`;
961
+ const hrv = this.hexByte2Int(value[11], 0).toString();
962
+ const heart = this.hexByte2Int(value[12], 0).toString();
963
+ const moodValue = this.hexByte2Int(value[13], 0).toString();
964
+ result[DeviceKey.Data][DeviceKey.Date] = date;
965
+ result[DeviceKey.Data][DeviceKey.HRV] = hrv;
966
+ result[DeviceKey.Data][DeviceKey.HeartRate] = heart;
967
+ result[DeviceKey.Data][DeviceKey.ECGMoodValue] = moodValue;
968
+ offset = 27;
969
+ }
970
+ const tempValue = value.slice(offset, length);
971
+ const ecgData = this.getEcgDataString(tempValue);
972
+ result[DeviceKey.Data][DeviceKey.ECGValue] = ecgData;
973
+ return result;
974
+ }
975
+ static getEcgDataString(value) {
976
+ const points = [];
977
+ const length = Math.floor(value.length / 2) - 1;
978
+ for (let i = 0; i < length; i++) {
979
+ let ecgValue = this.hexByte2Int(value[i * 2 + 1], 1) +
980
+ this.hexByte2Int(value[i * 2 + 2], 0);
981
+ if (ecgValue >= 32768)
982
+ ecgValue -= 65536;
983
+ points.push(ecgValue.toString());
984
+ }
985
+ return points.join(',');
986
+ }
987
+ // resolveUtil.tsx
988
+ // ECG数据解析
989
+ static ecgData(value) {
990
+ const index = this.hexByte2Int(value[1], 0);
991
+ return {
992
+ [DeviceKey.DataType]: BleConst.EcgppGstatus,
993
+ [DeviceKey.End]: true,
994
+ [DeviceKey.Data]: {
995
+ [DeviceKey.EcgStatus]: index.toString()
996
+ }
997
+ };
998
+ }
999
+ // PPG数据解析
1000
+ static PPGData(value) {
1001
+ return {
1002
+ [DeviceKey.DataType]: BleConst.EcgppGstatus,
1003
+ [DeviceKey.End]: true,
1004
+ [DeviceKey.Data]: {
1005
+ [DeviceKey.PPGValue]: value
1006
+ }
1007
+ };
1008
+ }
1009
+ // ECG结果解析
1010
+ static ECGResult(value) {
1011
+ const result = {
1012
+ [DeviceKey.DataType]: BleConst.GetEcgPpgStatus,
1013
+ [DeviceKey.End]: true,
1014
+ [DeviceKey.Data]: {}
1015
+ };
1016
+ const resultValue = this.hexByte2Int(value[1], 0);
1017
+ if (resultValue === 3) {
1018
+ const date = `20${this.bcd2String(value[10])}.${this.bcd2String(value[11])}.${this.bcd2String(value[12])} ${this.bcd2String(value[13])}:${this.bcd2String(value[14])}:${this.bcd2String(value[15])}`;
1019
+ result[DeviceKey.Data] = {
1020
+ [DeviceKey.Date]: date,
1021
+ [DeviceKey.ECGHrvValue]: this.hexByte2Int(value[2], 0).toString(),
1022
+ [DeviceKey.ECGAvBlockValue]: this.hexByte2Int(value[3], 0).toString(),
1023
+ [DeviceKey.ECGHrValue]: this.hexByte2Int(value[4], 0).toString(),
1024
+ [DeviceKey.ECGStreesValue]: this.hexByte2Int(value[5], 0).toString(),
1025
+ [DeviceKey.ECGhighBpValue]: this.hexByte2Int(value[6], 0).toString(),
1026
+ [DeviceKey.ECGLowBpValue]: this.hexByte2Int(value[7], 0).toString(),
1027
+ [DeviceKey.ECGMoodValue]: this.hexByte2Int(value[8], 0).toString(),
1028
+ [DeviceKey.ECGBreathValue]: this.hexByte2Int(value[9], 0).toString()
1029
+ };
1030
+ }
1031
+ return result;
1032
+ }
1033
+ // 进入ECG模式
1034
+ static enterEcg(value) {
1035
+ return {
1036
+ [DeviceKey.DataType]: BleConst.ENTERECG,
1037
+ [DeviceKey.End]: true,
1038
+ [DeviceKey.Data]: {}
1039
+ };
1040
+ }
1041
+ // 测量类型处理
1042
+ static measurementWithType(flag, value) {
1043
+ if (flag) {
1044
+ switch (value[1]) {
1045
+ case 1: // HRV
1046
+ return {
1047
+ [DeviceKey.DataType]: BleConst.MeasurementHrvCallback,
1048
+ [DeviceKey.End]: true,
1049
+ [DeviceKey.Data]: {
1050
+ [DeviceKey.HRV]: this.hexByte2Int(value[4], 0)
1051
+ }
1052
+ };
1053
+ case 2: // 心率
1054
+ return {
1055
+ [DeviceKey.DataType]: BleConst.MeasurementHeartCallback,
1056
+ [DeviceKey.End]: true,
1057
+ [DeviceKey.Data]: {
1058
+ [DeviceKey.HeartRate]: this.hexByte2Int(value[2], 0)
1059
+ }
1060
+ };
1061
+ case 3: // 血氧
1062
+ return {
1063
+ [DeviceKey.DataType]: BleConst.MeasurementOxygenCallback,
1064
+ [DeviceKey.End]: true,
1065
+ [DeviceKey.Data]: {
1066
+ [DeviceKey.Blood_oxygen]: this.hexByte2Int(value[3], 0)
1067
+ }
1068
+ };
1069
+ case 4: // 体温
1070
+ const tempValue = this.hexByte2Int(value[8], 0) +
1071
+ this.hexByte2Int(value[9], 1);
1072
+ return {
1073
+ [DeviceKey.DataType]: BleConst.MeasurementTempCallback,
1074
+ [DeviceKey.End]: true,
1075
+ [DeviceKey.Data]: {
1076
+ [DeviceKey.temperature]: (tempValue * 0.1).toFixed(1)
1077
+ }
1078
+ };
1079
+ }
1080
+ }
1081
+ else {
1082
+ const callbacks = {
1083
+ 1: BleConst.StopMeasurementHrvCallback,
1084
+ 2: BleConst.StopMeasurementHeartCallback,
1085
+ 3: BleConst.StopMeasurementOxygenCallback,
1086
+ 4: BleConst.StopMeasurementTempCallback
1087
+ };
1088
+ if (callbacks[value[1]]) {
1089
+ return this.setMethodSuccessful(callbacks[value[1]]);
1090
+ }
1091
+ }
1092
+ return {};
1093
+ }
1094
+ // 手环表盘设置
1095
+ static braceletdial(isruning, value) {
1096
+ if (isruning) {
1097
+ return {
1098
+ [DeviceKey.DataType]: BleConst.Braceletdial,
1099
+ [DeviceKey.End]: true
1100
+ };
1101
+ }
1102
+ else {
1103
+ return {
1104
+ [DeviceKey.DataType]: BleConst.Braceletdialok,
1105
+ [DeviceKey.End]: true,
1106
+ [DeviceKey.Data]: {
1107
+ index: value[1].toString()
1108
+ }
1109
+ };
1110
+ }
1111
+ }
1112
+ // 获取运动模式
1113
+ static getSportMode(value) {
1114
+ const length = this.hexByte2Int(value[1], 0);
1115
+ const types = [];
1116
+ for (let i = 0; i < length; i++) {
1117
+ types.push(this.hexByte2Int(value[i + 2], 0).toString());
1118
+ }
1119
+ return {
1120
+ [DeviceKey.DataType]: BleConst.GetSportMode,
1121
+ [DeviceKey.End]: true,
1122
+ [DeviceKey.Data]: types.join(",")
1123
+ };
1124
+ }
1125
+ // GPS控制命令解析
1126
+ static gPSControlCommand(value) {
1127
+ const date = `20${this.bcd2String(value[1])}-${this.bcd2String(value[2])}-${this.bcd2String(value[3])} ${this.bcd2String(value[4])}:${this.bcd2String(value[5])}:${this.bcd2String(value[6])}`;
1128
+ const valueLatitude = new Array(4).fill(0);
1129
+ const valueLongitude = new Array(4).fill(0);
1130
+ for (let j = 0; j < 4; j++) {
1131
+ valueLatitude[3 - j] = value[9 + j];
1132
+ valueLongitude[3 - j] = value[14 + j];
1133
+ }
1134
+ const latitude = this.getFloat(valueLatitude, 0).toString();
1135
+ const longitude = this.getFloat(valueLongitude, 0).toString();
1136
+ const count = this.hexByte2Int(value[18], 0);
1137
+ return {
1138
+ [DeviceKey.DataType]: BleConst.GPSControlCommand,
1139
+ [DeviceKey.End]: true,
1140
+ [DeviceKey.Data]: {
1141
+ [DeviceKey.KActivityLocationTime]: date,
1142
+ [DeviceKey.KActivityLocationLatitude]: latitude,
1143
+ [DeviceKey.KActivityLocationLongitude]: longitude,
1144
+ [DeviceKey.KActivityLocationCount]: count.toString()
1145
+ }
1146
+ };
1147
+ }
1148
+ // 设置社交距离
1149
+ static setSocial(value) {
1150
+ return {
1151
+ [DeviceKey.DataType]: BleConst.SocialdistanceGetting,
1152
+ [DeviceKey.End]: true,
1153
+ [DeviceKey.Data]: {
1154
+ scanInterval: this.hexByte2Int(value[2], 0).toString(),
1155
+ scanTime: this.hexByte2Int(value[3], 0).toString(),
1156
+ signalStrength: value[4].toString()
1157
+ }
1158
+ };
1159
+ }
1160
+ // ECG质量数据
1161
+ static eCGQuality(value) {
1162
+ return {
1163
+ [DeviceKey.DataType]: BleConst.EcgppG,
1164
+ [DeviceKey.End]: true,
1165
+ [DeviceKey.Data]: {
1166
+ heartValue: this.hexByte2Int(value[1], 0).toString(),
1167
+ hrvValue: this.hexByte2Int(value[2], 0).toString(),
1168
+ Quality: this.hexByte2Int(value[3], 0).toString()
1169
+ }
1170
+ };
1171
+ }
1172
+ // 进入照片模式返回
1173
+ static enterPhotoModeback(value) {
1174
+ let type = "";
1175
+ switch (value[1]) {
1176
+ case 1:
1177
+ type = value[2] === 0 ? "0" : "1";
1178
+ break;
1179
+ case 2:
1180
+ type = "2";
1181
+ break;
1182
+ case 3:
1183
+ switch (value[2]) {
1184
+ case 1:
1185
+ type = "3";
1186
+ break;
1187
+ case 2:
1188
+ type = "4";
1189
+ break;
1190
+ case 3:
1191
+ type = "5";
1192
+ break;
1193
+ case 4:
1194
+ type = "6";
1195
+ break;
1196
+ case 5:
1197
+ type = "7";
1198
+ break;
1199
+ }
1200
+ break;
1201
+ case 4:
1202
+ type = "8";
1203
+ break;
1204
+ }
1205
+ return {
1206
+ [DeviceKey.DataType]: BleConst.DeviceSendDataToAPP,
1207
+ [DeviceKey.End]: true,
1208
+ [DeviceKey.Data]: {
1209
+ type
1210
+ }
1211
+ };
1212
+ }
1213
+ // 设置新设备信息
1214
+ static setNewDeviceInfo(value) {
1215
+ return {
1216
+ [DeviceKey.DataType]: BleConst.SetNewDeviceInfo,
1217
+ [DeviceKey.End]: true,
1218
+ [DeviceKey.Data]: {}
1219
+ };
1220
+ }
1221
+ // 获取新设备信息
1222
+ static getNewDeviceInfo(value) {
1223
+ return {
1224
+ [DeviceKey.DataType]: BleConst.GetNewDeviceInfo,
1225
+ [DeviceKey.End]: true,
1226
+ [DeviceKey.Data]: {
1227
+ KEcg: this.hexByte2Int(value[1], 0).toString()
1228
+ }
1229
+ };
1230
+ }
1231
+ // 更新闹钟成功
1232
+ static updateClockSuccessful(value) {
1233
+ console.log('updateClockSuccessful:', value);
1234
+ return {
1235
+ [DeviceKey.DataType]: BleConst.SetAlarmClockWithAllClock,
1236
+ [DeviceKey.End]: true,
1237
+ [DeviceKey.Data]: {
1238
+ [DeviceKey.KClockLast]: this.hexByte2Int(value[value.length - 1], 0).toString()
1239
+ }
1240
+ };
1241
+ }
1242
+ // 设置血糖状态
1243
+ static setBoolSugarStatus(value) {
1244
+ return {
1245
+ [DeviceKey.DataType]: BleConst.BoolsugarStatus,
1246
+ [DeviceKey.End]: true,
1247
+ [DeviceKey.Data]: {
1248
+ [DeviceKey.EcgStatus]: this.hexByte2Int(value[2], 0)
1249
+ }
1250
+ };
1251
+ }
1252
+ // 设置血糖值
1253
+ static setBoolSugarValue(value) {
1254
+ const tempValue = value.slice(3);
1255
+ const datas = [];
1256
+ for (let i = 0; i < Math.floor(tempValue.length / 3); i++) {
1257
+ const val = this.hexByte2Int(tempValue[3 * i], 2) +
1258
+ this.hexByte2Int(tempValue[3 * i + 1], 1) +
1259
+ this.hexByte2Int(tempValue[3 * i + 2], 0);
1260
+ datas.push(val);
1261
+ }
1262
+ return {
1263
+ [DeviceKey.DataType]: BleConst.BoolsugarValue,
1264
+ [DeviceKey.End]: true,
1265
+ [DeviceKey.Data]: {
1266
+ timestamp: Math.floor(Date.now() / 1000),
1267
+ ppg: datas
1268
+ }
1269
+ };
1270
+ }
1271
+ // 设置方法错误
1272
+ static setMethodError(dataType) {
1273
+ return {
1274
+ [DeviceKey.DataType]: dataType,
1275
+ [DeviceKey.End]: false,
1276
+ [DeviceKey.Data]: {}
1277
+ };
1278
+ }
1279
+ // 读取怀孕周期数据
1280
+ static readPregnancyCycle(value) {
1281
+ return {
1282
+ [DeviceKey.DataType]: BleConst.GetPregnancyCycle,
1283
+ [DeviceKey.End]: true,
1284
+ [DeviceKey.Data]: {
1285
+ [DeviceKey.Date]: `20${this.bcd2String(value[3])}-${this.bcd2String(value[4])}-${this.bcd2String(value[5])}`,
1286
+ [DeviceKey.Week]: this.hexByte2Int(value[1], 0),
1287
+ [DeviceKey.DayOfWeek]: this.hexByte2Int(value[2], 0)
1288
+ }
1289
+ };
1290
+ }
1291
+ // 女性健康数据解析
1292
+ static readWomenHealth(value) {
1293
+ return {
1294
+ [DeviceKey.DataType]: BleConst.GetWomenHealth,
1295
+ [DeviceKey.End]: true,
1296
+ [DeviceKey.Data]: {
1297
+ [DeviceKey.Date]: `${this.bcd2String(value[1])}-${this.bcd2String(value[2])}`,
1298
+ [DeviceKey.WomenHealthPeriod]: this.hexByte2Int(value[3], 0),
1299
+ [DeviceKey.WomenHealthLength]: this.hexByte2Int(value[4], 0)
1300
+ }
1301
+ };
1302
+ }
1303
+ // 温度校正值解析
1304
+ static getTemperatureCorrectionValue(value) {
1305
+ const tempValue = [value[3], value[2]];
1306
+ const temperatureCorrectionValue = this.byteArrayToInt(tempValue);
1307
+ return {
1308
+ [DeviceKey.DataType]: BleConst.CMD_Set_TemperatureCorrection,
1309
+ [DeviceKey.End]: true,
1310
+ [DeviceKey.Data]: {
1311
+ [DeviceKey.TemperatureCorrectionValue]: temperatureCorrectionValue.toString()
1312
+ }
1313
+ };
1314
+ }
1315
+ static byteArrayToInt(arr) {
1316
+ return ((arr[0] << 8) & 0xff00) | (arr[1] & 0xff);
1317
+ }
1318
+ // resolveUtil.ts
1319
+ // 获取历史GPS数据
1320
+ static getHistoryGpsData(value) {
1321
+ const list = [];
1322
+ const result = {
1323
+ [DeviceKey.DataType]: BleConst.Gps,
1324
+ [DeviceKey.End]: false
1325
+ };
1326
+ const count = 59;
1327
+ const length = value.length;
1328
+ const size = Math.floor(length / count);
1329
+ if (size === 0) {
1330
+ return result;
1331
+ }
1332
+ // 检查是否结束
1333
+ if (value[value.length - 1] === 0xff && value[value.length - 2] === 0x5a) {
1334
+ result[DeviceKey.End] = true;
1335
+ }
1336
+ for (let i = 0; i < size; i++) {
1337
+ const hashMap = {};
1338
+ const date = `20${this.bcd2String(value[3 + i * count])}.${this.bcd2String(value[4 + i * count])}.${this.bcd2String(value[5 + i * count])} ${this.bcd2String(value[6 + i * count])}:${this.bcd2String(value[7 + i * count])}:${this.bcd2String(value[8 + i * count])}`;
1339
+ const latitudeParts = [];
1340
+ const longitudeParts = [];
1341
+ for (let k = 0; k < 6; k++) {
1342
+ const valueLatitude = new Array(4).fill(0);
1343
+ const valueLongitude = new Array(4).fill(0);
1344
+ for (let j = 0; j < 4; j++) {
1345
+ valueLatitude[3 - j] = value[9 + j + i * count + k * 8];
1346
+ valueLongitude[3 - j] = value[13 + j + i * count + k * 8];
1347
+ }
1348
+ const latitude = this.getFloat(valueLatitude, 0).toString();
1349
+ const longitude = this.getFloat(valueLongitude, 0).toString();
1350
+ latitudeParts.push(latitude);
1351
+ longitudeParts.push(longitude);
1352
+ }
1353
+ hashMap[DeviceKey.Date] = date.length === 17 ? date : "2019.01.01 00:00:00";
1354
+ hashMap[DeviceKey.Latitude] = latitudeParts.join(",");
1355
+ hashMap[DeviceKey.Longitude] = longitudeParts.join(",");
1356
+ list.push(hashMap);
1357
+ }
1358
+ result[DeviceKey.Data] = list;
1359
+ return result;
1360
+ }
1361
+ // PPI测试数据解析
1362
+ static getPPITestData(value) {
1363
+ const result = {
1364
+ [DeviceKey.DataType]: BleConst.GetPPIData,
1365
+ [DeviceKey.End]: false,
1366
+ [DeviceKey.Data]: []
1367
+ };
1368
+ const count = 123;
1369
+ const length = value.length;
1370
+ const size = Math.floor(length / count);
1371
+ if (size === 0) {
1372
+ result[DeviceKey.End] = true;
1373
+ return result;
1374
+ }
1375
+ if (value[value.length - 1] === 0xff) {
1376
+ result[DeviceKey.End] = true;
1377
+ }
1378
+ const arraySize = 56;
1379
+ for (let i = 0; i < size; i++) {
1380
+ const hashMap = {};
1381
+ // 数据编号
1382
+ const numList = new Array(2).fill(0);
1383
+ for (let k = 0; k < 2; k++) {
1384
+ numList[1 - k] = value[1 + k + i * count];
1385
+ }
1386
+ const numCode = this.getInt(numList, 0);
1387
+ const date = `20${this.bcd2String(value[3 + i * count])}.${this.bcd2String(value[4 + i * count])}.${this.bcd2String(value[5 + i * count])} ${this.bcd2String(value[6 + i * count])}:${this.bcd2String(value[7 + i * count])}:${this.bcd2String(value[8 + i * count])}`;
1388
+ // 数据条数
1389
+ const totalId = this.hexByte2Int(value[9 + i * count], 0);
1390
+ const ID = this.hexByte2Int(value[10 + i * count], 0).toString();
1391
+ const startFrame = 11;
1392
+ const ppiList = [];
1393
+ for (let j = 0; j < arraySize; j++) {
1394
+ const tempFrame = startFrame + j * 2;
1395
+ const valueCal = new Array(2).fill(0);
1396
+ for (let n = 0; n < 2; n++) {
1397
+ valueCal[1 - n] = value[tempFrame + n + i * count];
1398
+ }
1399
+ const PII = this.getFloat(valueCal, 0);
1400
+ if (PII === 0.0) {
1401
+ break;
1402
+ }
1403
+ ppiList.push(PII);
1404
+ }
1405
+ hashMap[DeviceKey.TOTAL_ID] = totalId.toString();
1406
+ hashMap[DeviceKey.PPI_ID] = ID;
1407
+ hashMap[DeviceKey.DeviceTime] = date;
1408
+ hashMap[DeviceKey.PPI_LIST] = ppiList;
1409
+ hashMap[DeviceKey.PPI_NUM] = numCode;
1410
+ result[DeviceKey.Data].push(hashMap);
1411
+ }
1412
+ return result;
1413
+ }
1414
+ // 获取HRV测量时间数据
1415
+ static getHrvTimeData(value) {
1416
+ return {
1417
+ [DeviceKey.DataType]: BleConst.GetHrvTimeValue,
1418
+ [DeviceKey.End]: true,
1419
+ [DeviceKey.Data]: {
1420
+ [DeviceKey.HRV_TIME_MODE]: this.hexByte2Int(value[1], 0),
1421
+ [DeviceKey.HRV_TIME_Value]: this.hexByte2Int(value[2], 0)
1422
+ }
1423
+ };
1424
+ }
1425
+ // 断开蓝牙连接
1426
+ static closeDevices(value) {
1427
+ return {
1428
+ [DeviceKey.DataType]: BleConst.CloseDevices,
1429
+ [DeviceKey.End]: true,
1430
+ [DeviceKey.Data]: {
1431
+ [DeviceKey.RESULT]: true
1432
+ }
1433
+ };
1434
+ }
1435
+ // 脱手检测状态上报
1436
+ static getOffCheckStatus(value) {
1437
+ return {
1438
+ [DeviceKey.DataType]: BleConst.GetOffCheckStatus,
1439
+ [DeviceKey.End]: true,
1440
+ [DeviceKey.Data]: {
1441
+ [DeviceKey.GET_OFF_TAG]: this.hexByte2Int(value[1], 0),
1442
+ [DeviceKey.GET_OFF_STATE]: this.hexByte2Int(value[2], 0)
1443
+ }
1444
+ };
1445
+ }
1446
+ }
1447
+ ;
1448
+ //# sourceMappingURL=resolveUtil.js.map