fit-file-parser 2.1.0 → 2.2.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.
- package/debug_output.json +413301 -0
- package/deep_probe.js +69 -0
- package/dist/binary.js +22 -4
- package/dist/cjs/binary.js +22 -4
- package/dist/cjs/fit-parser.js +10 -0
- package/dist/cjs/fit.js +280 -3
- package/dist/cjs/fit_types.d.ts +33 -1
- package/dist/cjs/helper.js +3 -8
- package/dist/cjs/type_generator.js +1 -0
- package/dist/fit-parser.js +10 -0
- package/dist/fit.js +280 -3
- package/dist/fit_types.d.ts +33 -1
- package/dist/helper.js +3 -8
- package/dist/type_generator.js +1 -0
- package/package.json +1 -1
- package/probe_session.js +44 -0
- package/tsconfig.cjs.json +7 -7
package/dist/fit-parser.js
CHANGED
|
@@ -99,6 +99,8 @@ export default class FitParser {
|
|
|
99
99
|
const lengths = [];
|
|
100
100
|
const tank_updates = [];
|
|
101
101
|
const tank_summaries = [];
|
|
102
|
+
const jumps = [];
|
|
103
|
+
const time_in_zone = [];
|
|
102
104
|
let loopIndex = headerLength;
|
|
103
105
|
const messageTypes = [];
|
|
104
106
|
const developerFields = [];
|
|
@@ -194,6 +196,12 @@ export default class FitParser {
|
|
|
194
196
|
case 'tank_summary':
|
|
195
197
|
tank_summaries.push(message);
|
|
196
198
|
break;
|
|
199
|
+
case 'jump':
|
|
200
|
+
jumps.push(message);
|
|
201
|
+
break;
|
|
202
|
+
case 'time_in_zone':
|
|
203
|
+
time_in_zone.push(message);
|
|
204
|
+
break;
|
|
197
205
|
default:
|
|
198
206
|
if (messageType !== '') {
|
|
199
207
|
fitObj[messageType] = message;
|
|
@@ -213,6 +221,8 @@ export default class FitParser {
|
|
|
213
221
|
fitObj.definitions = definitions;
|
|
214
222
|
fitObj.tank_updates = tank_updates;
|
|
215
223
|
fitObj.tank_summaries = tank_summaries;
|
|
224
|
+
fitObj.jumps = jumps;
|
|
225
|
+
fitObj.time_in_zone = time_in_zone;
|
|
216
226
|
if (isCascadeNeeded) {
|
|
217
227
|
laps = mapDataIntoLap(laps, 'records', records);
|
|
218
228
|
laps = mapDataIntoLap(laps, 'lengths', lengths);
|
package/dist/fit.js
CHANGED
|
@@ -1080,6 +1080,20 @@ export const FIT = {
|
|
|
1080
1080
|
offset: 0,
|
|
1081
1081
|
units: '%',
|
|
1082
1082
|
},
|
|
1083
|
+
38: {
|
|
1084
|
+
field: 'end_position_lat',
|
|
1085
|
+
type: 'sint32',
|
|
1086
|
+
scale: null,
|
|
1087
|
+
offset: 0,
|
|
1088
|
+
units: 'semicircles',
|
|
1089
|
+
},
|
|
1090
|
+
39: {
|
|
1091
|
+
field: 'end_position_long',
|
|
1092
|
+
type: 'sint32',
|
|
1093
|
+
scale: null,
|
|
1094
|
+
offset: 0,
|
|
1095
|
+
units: 'semicircles',
|
|
1096
|
+
},
|
|
1083
1097
|
41: {
|
|
1084
1098
|
field: 'avg_stroke_count',
|
|
1085
1099
|
type: 'uint32',
|
|
@@ -1634,7 +1648,7 @@ export const FIT = {
|
|
|
1634
1648
|
units: 'mm',
|
|
1635
1649
|
},
|
|
1636
1650
|
137: {
|
|
1637
|
-
field: '
|
|
1651
|
+
field: 'total_anaerobic_training_effect',
|
|
1638
1652
|
type: 'uint8',
|
|
1639
1653
|
scale: 10,
|
|
1640
1654
|
offset: 0,
|
|
@@ -1643,9 +1657,9 @@ export const FIT = {
|
|
|
1643
1657
|
139: {
|
|
1644
1658
|
field: 'avg_vam',
|
|
1645
1659
|
type: 'uint16',
|
|
1646
|
-
scale:
|
|
1660
|
+
scale: 1, // Raw 100 -> 100 (User specific m/h)
|
|
1647
1661
|
offset: 0,
|
|
1648
|
-
units: 'm/
|
|
1662
|
+
units: 'm/h',
|
|
1649
1663
|
},
|
|
1650
1664
|
192: {
|
|
1651
1665
|
field: 'workout_feel',
|
|
@@ -1661,6 +1675,111 @@ export const FIT = {
|
|
|
1661
1675
|
offset: 0,
|
|
1662
1676
|
units: '',
|
|
1663
1677
|
},
|
|
1678
|
+
110: {
|
|
1679
|
+
field: 'sport_profile_name',
|
|
1680
|
+
type: 'string',
|
|
1681
|
+
scale: null,
|
|
1682
|
+
offset: 0,
|
|
1683
|
+
units: '',
|
|
1684
|
+
},
|
|
1685
|
+
168: {
|
|
1686
|
+
field: 'training_load_peak',
|
|
1687
|
+
type: 'uint32',
|
|
1688
|
+
scale: 1,
|
|
1689
|
+
offset: 0,
|
|
1690
|
+
units: '',
|
|
1691
|
+
},
|
|
1692
|
+
169: {
|
|
1693
|
+
field: 'enhanced_avg_respiration_rate',
|
|
1694
|
+
type: 'uint16',
|
|
1695
|
+
scale: 100,
|
|
1696
|
+
offset: 0,
|
|
1697
|
+
units: 'breaths/min',
|
|
1698
|
+
},
|
|
1699
|
+
150: {
|
|
1700
|
+
field: 'min_temperature',
|
|
1701
|
+
type: 'sint8',
|
|
1702
|
+
scale: null,
|
|
1703
|
+
offset: 0,
|
|
1704
|
+
units: 'C',
|
|
1705
|
+
},
|
|
1706
|
+
170: {
|
|
1707
|
+
field: 'enhanced_max_respiration_rate',
|
|
1708
|
+
type: 'uint16',
|
|
1709
|
+
scale: 100,
|
|
1710
|
+
offset: 0,
|
|
1711
|
+
units: 'breaths/min',
|
|
1712
|
+
},
|
|
1713
|
+
178: {
|
|
1714
|
+
field: 'est_sweat_loss',
|
|
1715
|
+
type: 'uint16',
|
|
1716
|
+
scale: 1, // ml
|
|
1717
|
+
offset: 0,
|
|
1718
|
+
units: 'ml',
|
|
1719
|
+
},
|
|
1720
|
+
180: {
|
|
1721
|
+
field: 'enhanced_min_respiration_rate',
|
|
1722
|
+
type: 'uint16',
|
|
1723
|
+
scale: 100,
|
|
1724
|
+
offset: 0,
|
|
1725
|
+
units: 'breaths/min',
|
|
1726
|
+
},
|
|
1727
|
+
181: {
|
|
1728
|
+
field: 'total_grit',
|
|
1729
|
+
type: 'float32',
|
|
1730
|
+
scale: 1,
|
|
1731
|
+
offset: 0,
|
|
1732
|
+
units: 'kGrit',
|
|
1733
|
+
},
|
|
1734
|
+
183: {
|
|
1735
|
+
field: 'jump_count',
|
|
1736
|
+
type: 'uint16',
|
|
1737
|
+
scale: 1,
|
|
1738
|
+
offset: 0,
|
|
1739
|
+
units: '',
|
|
1740
|
+
},
|
|
1741
|
+
187: {
|
|
1742
|
+
field: 'avg_flow',
|
|
1743
|
+
type: 'float32',
|
|
1744
|
+
scale: 1,
|
|
1745
|
+
offset: 0,
|
|
1746
|
+
units: 'Flow',
|
|
1747
|
+
},
|
|
1748
|
+
188: {
|
|
1749
|
+
field: 'primary_benefit',
|
|
1750
|
+
type: 'uint8',
|
|
1751
|
+
scale: 1,
|
|
1752
|
+
offset: 0,
|
|
1753
|
+
units: '',
|
|
1754
|
+
},
|
|
1755
|
+
196: {
|
|
1756
|
+
field: 'resting_calories',
|
|
1757
|
+
type: 'uint16',
|
|
1758
|
+
scale: 1,
|
|
1759
|
+
offset: 0,
|
|
1760
|
+
units: 'kcal',
|
|
1761
|
+
},
|
|
1762
|
+
214: {
|
|
1763
|
+
field: 'avg_grit',
|
|
1764
|
+
type: 'float32',
|
|
1765
|
+
scale: null,
|
|
1766
|
+
offset: 0,
|
|
1767
|
+
units: '',
|
|
1768
|
+
},
|
|
1769
|
+
215: {
|
|
1770
|
+
field: 'avg_flow',
|
|
1771
|
+
type: 'float32',
|
|
1772
|
+
scale: null,
|
|
1773
|
+
offset: 0,
|
|
1774
|
+
units: '',
|
|
1775
|
+
},
|
|
1776
|
+
140: {
|
|
1777
|
+
field: 'recovery_advisor',
|
|
1778
|
+
type: 'uint16', // Minutes?
|
|
1779
|
+
scale: 1,
|
|
1780
|
+
offset: 0,
|
|
1781
|
+
units: 'min',
|
|
1782
|
+
},
|
|
1664
1783
|
},
|
|
1665
1784
|
19: {
|
|
1666
1785
|
name: 'lap',
|
|
@@ -2404,6 +2523,20 @@ export const FIT = {
|
|
|
2404
2523
|
offset: 0,
|
|
2405
2524
|
units: 's',
|
|
2406
2525
|
},
|
|
2526
|
+
114: {
|
|
2527
|
+
field: 'grit',
|
|
2528
|
+
type: 'float32',
|
|
2529
|
+
scale: null,
|
|
2530
|
+
offset: 0,
|
|
2531
|
+
units: '',
|
|
2532
|
+
},
|
|
2533
|
+
115: {
|
|
2534
|
+
field: 'flow',
|
|
2535
|
+
type: 'float32',
|
|
2536
|
+
scale: null,
|
|
2537
|
+
offset: 0,
|
|
2538
|
+
units: '',
|
|
2539
|
+
},
|
|
2407
2540
|
0: {
|
|
2408
2541
|
field: 'position_lat',
|
|
2409
2542
|
type: 'sint32',
|
|
@@ -2855,6 +2988,14 @@ export const FIT = {
|
|
|
2855
2988
|
units: 'percent',
|
|
2856
2989
|
},
|
|
2857
2990
|
},
|
|
2991
|
+
140: {
|
|
2992
|
+
name: 'jump',
|
|
2993
|
+
253: { field: 'timestamp', type: 'date_time', scale: null, offset: 0, units: 's' },
|
|
2994
|
+
9: { field: 'distance', type: 'uint16', scale: 100, offset: 0, units: 'm' },
|
|
2995
|
+
10: { field: 'height', type: 'uint16', scale: 1000, offset: 0, units: 'm' },
|
|
2996
|
+
37: { field: 'score', type: 'sint32', scale: null, offset: 0, units: '' },
|
|
2997
|
+
7: { field: 'enhanced_mets', type: 'uint32', scale: 65536, offset: 0, units: 'METs' },
|
|
2998
|
+
},
|
|
2858
2999
|
21: {
|
|
2859
3000
|
name: 'event',
|
|
2860
3001
|
253: {
|
|
@@ -2997,6 +3138,13 @@ export const FIT = {
|
|
|
2997
3138
|
offset: 0,
|
|
2998
3139
|
units: 'V',
|
|
2999
3140
|
},
|
|
3141
|
+
32: {
|
|
3142
|
+
field: 'battery_level',
|
|
3143
|
+
type: 'uint8',
|
|
3144
|
+
scale: null,
|
|
3145
|
+
offset: 0,
|
|
3146
|
+
units: 'percent',
|
|
3147
|
+
},
|
|
3000
3148
|
11: {
|
|
3001
3149
|
field: 'battery_status',
|
|
3002
3150
|
type: 'battery_status',
|
|
@@ -3039,6 +3187,13 @@ export const FIT = {
|
|
|
3039
3187
|
offset: 0,
|
|
3040
3188
|
units: '',
|
|
3041
3189
|
},
|
|
3190
|
+
24: {
|
|
3191
|
+
field: 'ant_id',
|
|
3192
|
+
type: 'uint32z',
|
|
3193
|
+
scale: null,
|
|
3194
|
+
offset: 0,
|
|
3195
|
+
units: '',
|
|
3196
|
+
},
|
|
3042
3197
|
25: {
|
|
3043
3198
|
field: 'source_type',
|
|
3044
3199
|
type: 'source_type',
|
|
@@ -4483,6 +4638,128 @@ export const FIT = {
|
|
|
4483
4638
|
units: 'cbar',
|
|
4484
4639
|
},
|
|
4485
4640
|
},
|
|
4641
|
+
216: {
|
|
4642
|
+
name: 'time_in_zone',
|
|
4643
|
+
253: {
|
|
4644
|
+
field: 'timestamp',
|
|
4645
|
+
type: 'date_time',
|
|
4646
|
+
scale: null,
|
|
4647
|
+
offset: 0,
|
|
4648
|
+
units: 's',
|
|
4649
|
+
},
|
|
4650
|
+
0: {
|
|
4651
|
+
field: 'reference_mesg',
|
|
4652
|
+
type: 'uint16',
|
|
4653
|
+
scale: null,
|
|
4654
|
+
offset: 0,
|
|
4655
|
+
units: '',
|
|
4656
|
+
},
|
|
4657
|
+
1: {
|
|
4658
|
+
field: 'reference_index',
|
|
4659
|
+
type: 'uint16',
|
|
4660
|
+
scale: null,
|
|
4661
|
+
offset: 0,
|
|
4662
|
+
units: '',
|
|
4663
|
+
},
|
|
4664
|
+
2: {
|
|
4665
|
+
field: 'time_in_hr_zone',
|
|
4666
|
+
type: 'uint32_array',
|
|
4667
|
+
scale: 1000,
|
|
4668
|
+
offset: 0,
|
|
4669
|
+
units: 's',
|
|
4670
|
+
},
|
|
4671
|
+
3: {
|
|
4672
|
+
field: 'time_in_speed_zone',
|
|
4673
|
+
type: 'uint32_array',
|
|
4674
|
+
scale: 1000,
|
|
4675
|
+
offset: 0,
|
|
4676
|
+
units: 's',
|
|
4677
|
+
},
|
|
4678
|
+
4: {
|
|
4679
|
+
field: 'time_in_power_zone',
|
|
4680
|
+
type: 'uint32_array',
|
|
4681
|
+
scale: 1000,
|
|
4682
|
+
offset: 0,
|
|
4683
|
+
units: 's',
|
|
4684
|
+
},
|
|
4685
|
+
5: {
|
|
4686
|
+
field: 'hr_zone_high_boundary_deprecated',
|
|
4687
|
+
type: 'uint8_array',
|
|
4688
|
+
scale: null,
|
|
4689
|
+
offset: 0,
|
|
4690
|
+
units: '',
|
|
4691
|
+
},
|
|
4692
|
+
6: {
|
|
4693
|
+
field: 'hr_zone_high_boundary',
|
|
4694
|
+
type: 'uint8_array',
|
|
4695
|
+
scale: null,
|
|
4696
|
+
offset: 0,
|
|
4697
|
+
units: 'bpm',
|
|
4698
|
+
},
|
|
4699
|
+
7: {
|
|
4700
|
+
field: 'speed_zone_high_boundary',
|
|
4701
|
+
type: 'uint16_array',
|
|
4702
|
+
scale: 1000,
|
|
4703
|
+
offset: 0,
|
|
4704
|
+
units: 'm/s',
|
|
4705
|
+
},
|
|
4706
|
+
8: {
|
|
4707
|
+
field: 'power_zone_high_boundary',
|
|
4708
|
+
type: 'uint16_array',
|
|
4709
|
+
scale: null,
|
|
4710
|
+
offset: 0,
|
|
4711
|
+
units: 'watts',
|
|
4712
|
+
},
|
|
4713
|
+
9: {
|
|
4714
|
+
field: 'hr_calc_type',
|
|
4715
|
+
type: 'hr_zone_calc',
|
|
4716
|
+
scale: null,
|
|
4717
|
+
offset: 0,
|
|
4718
|
+
units: '',
|
|
4719
|
+
},
|
|
4720
|
+
10: {
|
|
4721
|
+
field: 'max_heart_rate_deprecated',
|
|
4722
|
+
type: 'uint8',
|
|
4723
|
+
scale: null,
|
|
4724
|
+
offset: 0,
|
|
4725
|
+
units: 'bpm',
|
|
4726
|
+
},
|
|
4727
|
+
11: {
|
|
4728
|
+
field: 'max_heart_rate',
|
|
4729
|
+
type: 'uint8',
|
|
4730
|
+
scale: null,
|
|
4731
|
+
offset: 0,
|
|
4732
|
+
units: 'bpm',
|
|
4733
|
+
},
|
|
4734
|
+
12: {
|
|
4735
|
+
field: 'resting_heart_rate',
|
|
4736
|
+
type: 'uint8',
|
|
4737
|
+
scale: null,
|
|
4738
|
+
offset: 0,
|
|
4739
|
+
units: 'bpm',
|
|
4740
|
+
},
|
|
4741
|
+
13: {
|
|
4742
|
+
field: 'threshold_heart_rate',
|
|
4743
|
+
type: 'uint8',
|
|
4744
|
+
scale: null,
|
|
4745
|
+
offset: 0,
|
|
4746
|
+
units: 'bpm',
|
|
4747
|
+
},
|
|
4748
|
+
14: {
|
|
4749
|
+
field: 'pwr_calc_type',
|
|
4750
|
+
type: 'pwr_zone_calc',
|
|
4751
|
+
scale: null,
|
|
4752
|
+
offset: 0,
|
|
4753
|
+
units: '',
|
|
4754
|
+
},
|
|
4755
|
+
15: {
|
|
4756
|
+
field: 'functional_threshold_power',
|
|
4757
|
+
type: 'uint16',
|
|
4758
|
+
scale: null,
|
|
4759
|
+
offset: 0,
|
|
4760
|
+
units: 'watts',
|
|
4761
|
+
},
|
|
4762
|
+
},
|
|
4486
4763
|
},
|
|
4487
4764
|
types: {
|
|
4488
4765
|
file: {
|
package/dist/fit_types.d.ts
CHANGED
|
@@ -16,7 +16,7 @@ export interface MessageIndex {
|
|
|
16
16
|
selected: boolean;
|
|
17
17
|
}
|
|
18
18
|
export type File = 'device' | 'settings' | 'sport' | 'activity' | 'workout' | 'course' | 'schedules' | 'weight' | 'totals' | 'goals' | 'blood_pressure' | 'monitoring_a' | 'activity_summary' | 'monitoring_daily' | 'monitoring_b' | 'segment' | 'segment_list' | 'exd_configuration' | 'mfg_range_min' | 'mfg_range_max';
|
|
19
|
-
export type MesgNum = 'file_id' | 'capabilities' | 'device_settings' | 'user_profile' | 'hrm_profile' | 'sdm_profile' | 'bike_profile' | 'zones_target' | 'hr_zone' | 'power_zone' | 'met_zone' | 'sport' | 'goal' | 'session' | 'lap' | 'record' | 'event' | 'device_info' | 'workout' | 'workout_step' | 'schedule' | 'weight_scale' | 'course' | 'course_point' | 'totals' | 'activity' | 'software' | 'file_capabilities' | 'mesg_capabilities' | 'field_capabilities' | 'file_creator' | 'blood_pressure' | 'speed_zone' | 'monitoring' | 'training_file' | 'hrv' | 'ant_rx' | 'ant_tx' | 'ant_channel_id' | 'length' | 'monitoring_info' | 'pad' | 'slave_device' | 'connectivity' | 'weather_conditions' | 'weather_alert' | 'cadence_zone' | 'hr' | 'segment_lap' | 'memo_glob' | 'segment_id' | 'segment_leaderboard_entry' | 'segment_point' | 'segment_file' | 'workout_session' | 'watchface_settings' | 'gps_metadata' | 'camera_event' | 'timestamp_correlation' | 'gyroscope_data' | 'accelerometer_data' | 'three_d_sensor_calibration' | 'video_frame' | 'obdii_data' | 'nmea_sentence' | 'aviation_attitude' | 'video' | 'video_title' | 'video_description' | 'video_clip' | 'exd_screen_configuration' | 'exd_data_field_configuration' | 'exd_data_concept_configuration' | 'field_description' | 'developer_data_id' | 'magnetometer_data' | 'barometer_data' | 'one_d_sensor_calibration' | 'set' | 'stress_level' | 'dive_settings' | 'dive_gas' | 'dive_alarm' | 'exercise_title' | 'dive_summary' | 'jump' | 'climb_pro' | 'tank_pressure' | 'tank_summary' | 'mfg_range_min' | 'mfg_range_max' | 'o_hr_settings' | 'tank_update' | 'definition';
|
|
19
|
+
export type MesgNum = 'file_id' | 'capabilities' | 'device_settings' | 'user_profile' | 'hrm_profile' | 'sdm_profile' | 'bike_profile' | 'zones_target' | 'hr_zone' | 'power_zone' | 'met_zone' | 'sport' | 'goal' | 'session' | 'lap' | 'record' | 'event' | 'device_info' | 'workout' | 'workout_step' | 'schedule' | 'weight_scale' | 'course' | 'course_point' | 'totals' | 'activity' | 'software' | 'file_capabilities' | 'mesg_capabilities' | 'field_capabilities' | 'file_creator' | 'blood_pressure' | 'speed_zone' | 'monitoring' | 'training_file' | 'hrv' | 'ant_rx' | 'ant_tx' | 'ant_channel_id' | 'length' | 'monitoring_info' | 'pad' | 'slave_device' | 'connectivity' | 'weather_conditions' | 'weather_alert' | 'cadence_zone' | 'hr' | 'segment_lap' | 'memo_glob' | 'segment_id' | 'segment_leaderboard_entry' | 'segment_point' | 'segment_file' | 'workout_session' | 'watchface_settings' | 'gps_metadata' | 'camera_event' | 'timestamp_correlation' | 'gyroscope_data' | 'accelerometer_data' | 'three_d_sensor_calibration' | 'video_frame' | 'obdii_data' | 'nmea_sentence' | 'aviation_attitude' | 'video' | 'video_title' | 'video_description' | 'video_clip' | 'exd_screen_configuration' | 'exd_data_field_configuration' | 'exd_data_concept_configuration' | 'field_description' | 'developer_data_id' | 'magnetometer_data' | 'barometer_data' | 'one_d_sensor_calibration' | 'set' | 'stress_level' | 'dive_settings' | 'dive_gas' | 'dive_alarm' | 'exercise_title' | 'dive_summary' | 'jump' | 'climb_pro' | 'tank_pressure' | 'tank_summary' | 'time_in_zone' | 'mfg_range_min' | 'mfg_range_max' | 'o_hr_settings' | 'tank_update' | 'definition';
|
|
20
20
|
export type Checksum = 'clear' | 'ok';
|
|
21
21
|
export type FileFlags = '0' | 'read' | 'write' | 'erase';
|
|
22
22
|
export type MesgCount = 'num_per_file' | 'max_per_file' | 'max_per_file_type';
|
|
@@ -444,8 +444,12 @@ export interface ParsedSession {
|
|
|
444
444
|
avg_step_length?: number;
|
|
445
445
|
total_anaerobic_effect?: number;
|
|
446
446
|
avg_vam?: number;
|
|
447
|
+
total_grit?: number;
|
|
448
|
+
total_flow?: number;
|
|
447
449
|
workout_feel?: number;
|
|
448
450
|
workout_rpe?: number;
|
|
451
|
+
avg_grit?: number;
|
|
452
|
+
avg_flow?: number;
|
|
449
453
|
timestamp: string;
|
|
450
454
|
message_index?: MessageIndex;
|
|
451
455
|
laps?: ParsedLap[];
|
|
@@ -627,6 +631,8 @@ export interface ParsedRecord {
|
|
|
627
631
|
ndl_time?: number;
|
|
628
632
|
cns_load?: number;
|
|
629
633
|
n2_load?: number;
|
|
634
|
+
grit?: number;
|
|
635
|
+
flow?: number;
|
|
630
636
|
timestamp: string;
|
|
631
637
|
}
|
|
632
638
|
export interface ParsedEvent {
|
|
@@ -662,6 +668,7 @@ export interface ParsedDeviceInfo {
|
|
|
662
668
|
ant_network?: AntNetwork;
|
|
663
669
|
source_type?: SourceType;
|
|
664
670
|
product_name?: string;
|
|
671
|
+
battery_level?: number;
|
|
665
672
|
timestamp: string;
|
|
666
673
|
}
|
|
667
674
|
export interface ParsedWorkout {
|
|
@@ -850,6 +857,12 @@ export interface ParsedOHrSettings {
|
|
|
850
857
|
enabled?: number;
|
|
851
858
|
timestamp: string;
|
|
852
859
|
}
|
|
860
|
+
export interface ParsedJump {
|
|
861
|
+
distance?: number;
|
|
862
|
+
height?: number;
|
|
863
|
+
score?: number;
|
|
864
|
+
timestamp: string;
|
|
865
|
+
}
|
|
853
866
|
export interface ParsedFieldDescription {
|
|
854
867
|
developer_data_index?: number;
|
|
855
868
|
field_definition_number?: number;
|
|
@@ -939,6 +952,23 @@ export interface ParsedTankSummary {
|
|
|
939
952
|
end_pressure?: number;
|
|
940
953
|
volume_used?: number;
|
|
941
954
|
}
|
|
955
|
+
export interface ParsedTimeInZone {
|
|
956
|
+
timestamp: string;
|
|
957
|
+
reference_mesg?: number;
|
|
958
|
+
reference_index?: number;
|
|
959
|
+
time_in_hr_zone?: number[];
|
|
960
|
+
time_in_speed_zone?: number[];
|
|
961
|
+
time_in_power_zone?: number[];
|
|
962
|
+
hr_zone_high_boundary?: number[];
|
|
963
|
+
speed_zone_high_boundary?: number[];
|
|
964
|
+
power_zone_high_boundary?: number[];
|
|
965
|
+
hr_calc_type?: HrZoneCalc;
|
|
966
|
+
max_heart_rate?: number;
|
|
967
|
+
resting_heart_rate?: number;
|
|
968
|
+
threshold_heart_rate?: number;
|
|
969
|
+
pwr_calc_type?: PwrZoneCalc;
|
|
970
|
+
functional_threshold_power?: number;
|
|
971
|
+
}
|
|
942
972
|
export interface ParsedFit {
|
|
943
973
|
protocolVersion?: number;
|
|
944
974
|
profileVersion?: number;
|
|
@@ -971,4 +1001,6 @@ export interface ParsedFit {
|
|
|
971
1001
|
definitions?: unknown[];
|
|
972
1002
|
tank_updates?: ParsedTankUpdate[];
|
|
973
1003
|
tank_summaries?: ParsedTankSummary[];
|
|
1004
|
+
jumps?: ParsedJump[];
|
|
1005
|
+
time_in_zone?: ParsedTimeInZone[];
|
|
974
1006
|
}
|
package/dist/helper.js
CHANGED
|
@@ -2,18 +2,16 @@ export function mapDataIntoLap(inputLaps, lapKey, data) {
|
|
|
2
2
|
const laps = [...inputLaps];
|
|
3
3
|
let index = 0;
|
|
4
4
|
for (let i = 0; i < laps.length; i++) {
|
|
5
|
-
const lap = laps[i];
|
|
6
5
|
const nextLap = laps[i + 1];
|
|
7
6
|
const tempData = [];
|
|
8
|
-
const lapStartTime = new Date(lap.start_time).getTime();
|
|
9
7
|
const nextLapStartTime = nextLap
|
|
10
8
|
? new Date(nextLap.start_time).getTime()
|
|
11
9
|
: null;
|
|
12
10
|
for (let j = index; j < data.length; j++) {
|
|
13
11
|
const row = data[j];
|
|
14
12
|
if (nextLap && nextLapStartTime) {
|
|
15
|
-
const timestamp = new Date(row.timestamp).getTime();
|
|
16
|
-
if (
|
|
13
|
+
const timestamp = new Date(row.timestamp || row.start_time).getTime();
|
|
14
|
+
if (nextLapStartTime > timestamp) {
|
|
17
15
|
tempData.push(row);
|
|
18
16
|
}
|
|
19
17
|
else if (nextLapStartTime <= timestamp) {
|
|
@@ -35,10 +33,8 @@ export function mapDataIntoSession(inputSessions, laps) {
|
|
|
35
33
|
const sessions = [...inputSessions];
|
|
36
34
|
let lapIndex = 0;
|
|
37
35
|
for (let i = 0; i < sessions.length; i++) {
|
|
38
|
-
const session = sessions[i];
|
|
39
36
|
const nextSession = sessions[i + 1];
|
|
40
37
|
const tempLaps = [];
|
|
41
|
-
const sessionStartTime = new Date(session.start_time).getTime();
|
|
42
38
|
const nextSessionStartTime = nextSession
|
|
43
39
|
? new Date(nextSession.start_time).getTime()
|
|
44
40
|
: null;
|
|
@@ -46,8 +42,7 @@ export function mapDataIntoSession(inputSessions, laps) {
|
|
|
46
42
|
const lap = laps[j];
|
|
47
43
|
if (nextSession && nextSessionStartTime) {
|
|
48
44
|
const lapStartTime = new Date(lap.start_time).getTime();
|
|
49
|
-
if (
|
|
50
|
-
&& nextSessionStartTime > lapStartTime) {
|
|
45
|
+
if (nextSessionStartTime > lapStartTime) {
|
|
51
46
|
tempLaps.push(lap);
|
|
52
47
|
}
|
|
53
48
|
else if (nextSessionStartTime <= lapStartTime) {
|
package/dist/type_generator.js
CHANGED
|
@@ -186,6 +186,7 @@ export function generateFitType() {
|
|
|
186
186
|
definitions: 'unknown',
|
|
187
187
|
tank_updates: 'parsed_tank_update',
|
|
188
188
|
tank_summaries: 'parsed_tank_summary',
|
|
189
|
+
jumps: 'parsed_jump',
|
|
189
190
|
};
|
|
190
191
|
const referenceProperties = {
|
|
191
192
|
file_creator: 'parsed_file_creator',
|
package/package.json
CHANGED
package/probe_session.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
// Note: Importing TS directly might not work with node without a loader.
|
|
6
|
+
// Better to use the built file if available, or use ts-node.
|
|
7
|
+
// But earlier I saw `dist/fit-parser.js`. Let's try to import that if key is default.
|
|
8
|
+
// Actually, let's just use `fs.readFileSync` and basic node.
|
|
9
|
+
// If `dist` is CJS, I can use `createRequire`.
|
|
10
|
+
|
|
11
|
+
import { createRequire } from 'module';
|
|
12
|
+
const require = createRequire(import.meta.url);
|
|
13
|
+
|
|
14
|
+
const FitParserDist = require('./dist/fit-parser.js').default;
|
|
15
|
+
|
|
16
|
+
const content = fs.readFileSync('/Users/dimitrios/Projects/sports-lib/samples/fit/jumps-mtb.fit');
|
|
17
|
+
const fitParser = new FitParserDist({
|
|
18
|
+
force: true,
|
|
19
|
+
speedUnit: 'km/h',
|
|
20
|
+
lengthUnit: 'm',
|
|
21
|
+
temperatureUnit: 'celsius',
|
|
22
|
+
elapsedRecordField: true,
|
|
23
|
+
mode: 'both',
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
fitParser.parse(content, (error, data) => {
|
|
27
|
+
if (error) {
|
|
28
|
+
console.error(error);
|
|
29
|
+
} else {
|
|
30
|
+
const session = data.sessions[0];
|
|
31
|
+
if (session) {
|
|
32
|
+
console.log("=== SESSION KEYS & VALUES ===");
|
|
33
|
+
Object.keys(session).forEach(key => {
|
|
34
|
+
const val = session[key];
|
|
35
|
+
console.log(`${key}: ${val}`);
|
|
36
|
+
if (Math.abs(val - 11) < 0.1) console.log(`>>> MATCH 11 (Jump Count?): ${key}`);
|
|
37
|
+
if (Math.abs(val - 159) < 0.1) console.log(`>>> MATCH 159 (Resting Cals?): ${key}`);
|
|
38
|
+
if (Math.abs(val - 6079174) < 1) console.log(`>>> MATCH 6M (Training Load?): ${key}`);
|
|
39
|
+
if (Math.abs(val - 100) < 0.1) console.log(`>>> MATCH 100 (Avg VAM?): ${key}`);
|
|
40
|
+
if (Math.abs(val - 2756) < 1) console.log(`>>> MATCH 2756 (Avg Resp?): ${key}`);
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
});
|
package/tsconfig.cjs.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}
|
|
2
|
+
"extends": "./tsconfig.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"module": "commonjs",
|
|
5
|
+
"outDir": "./dist/cjs",
|
|
6
|
+
"verbatimModuleSyntax": false
|
|
7
|
+
}
|
|
8
|
+
}
|