fit-file-parser 2.3.3 → 3.0.0
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/binary.js +13 -5
- package/dist/cjs/binary.js +13 -5
- package/dist/cjs/fit-parser.js +5 -0
- package/dist/cjs/fit.js +104 -0
- package/dist/cjs/fit_types.d.ts +18 -1
- package/dist/cjs/type_generator.js +1 -0
- package/dist/fit-parser.js +5 -0
- package/dist/fit.js +104 -0
- package/dist/fit_types.d.ts +18 -1
- package/dist/type_generator.js +1 -0
- package/package.json +1 -1
package/dist/binary.js
CHANGED
|
@@ -190,6 +190,13 @@ function isInvalidValue(data, type) {
|
|
|
190
190
|
return false;
|
|
191
191
|
}
|
|
192
192
|
}
|
|
193
|
+
function isInvalidBaseTypeValue(data, baseTypeNo) {
|
|
194
|
+
if (Array.isArray(data)) {
|
|
195
|
+
return false;
|
|
196
|
+
}
|
|
197
|
+
const baseType = FIT.types.fit_base_type[baseTypeNo];
|
|
198
|
+
return typeof baseType === 'string' ? isInvalidValue(data, baseType) : false;
|
|
199
|
+
}
|
|
193
200
|
function convertTo(data, unitsList, unitName) {
|
|
194
201
|
const options = FIT.options[unitsList];
|
|
195
202
|
const unit = options[unitName];
|
|
@@ -266,6 +273,7 @@ function applyOptions(data, field, options, fields) {
|
|
|
266
273
|
}
|
|
267
274
|
}
|
|
268
275
|
export function readRecord(blob, messageTypes, developerFields, startIndex, options, startDate, pausedTime) {
|
|
276
|
+
var _a, _b;
|
|
269
277
|
const recordHeader = blob[startIndex];
|
|
270
278
|
let localMessageType = recordHeader & 15;
|
|
271
279
|
if ((recordHeader & CompressedHeaderMask) === CompressedHeaderMask) {
|
|
@@ -301,7 +309,7 @@ export function readRecord(blob, messageTypes, developerFields, startIndex, opti
|
|
|
301
309
|
size: blob[fDefIndex + 1],
|
|
302
310
|
endianAbility: (baseType & 128) === 128,
|
|
303
311
|
littleEndian: lEnd,
|
|
304
|
-
baseTypeNo: baseType
|
|
312
|
+
baseTypeNo: baseType,
|
|
305
313
|
name: field,
|
|
306
314
|
dataType: getFitMessageBaseType(baseType & 15),
|
|
307
315
|
};
|
|
@@ -323,7 +331,7 @@ export function readRecord(blob, messageTypes, developerFields, startIndex, opti
|
|
|
323
331
|
size,
|
|
324
332
|
endianAbility: (baseType & 128) === 128,
|
|
325
333
|
littleEndian: lEnd,
|
|
326
|
-
baseTypeNo: baseType
|
|
334
|
+
baseTypeNo: baseType,
|
|
327
335
|
name: devDef.field_name,
|
|
328
336
|
dataType: getFitMessageBaseType(baseType & 15),
|
|
329
337
|
scale: devDef.scale || 1,
|
|
@@ -359,7 +367,7 @@ export function readRecord(blob, messageTypes, developerFields, startIndex, opti
|
|
|
359
367
|
for (let i = 0; i < messageType.fieldDefs.length; i++) {
|
|
360
368
|
const fDef = messageType.fieldDefs[i];
|
|
361
369
|
const data = readData(blob, fDef, readDataFromIndex, options);
|
|
362
|
-
if (!isInvalidValue(data, fDef.type)) {
|
|
370
|
+
if (!isInvalidValue(data, fDef.type) && !isInvalidBaseTypeValue(data, fDef.baseTypeNo)) {
|
|
363
371
|
rawFields.push({ fDef, data });
|
|
364
372
|
}
|
|
365
373
|
readDataFromIndex += fDef.size;
|
|
@@ -375,8 +383,8 @@ export function readRecord(blob, messageTypes, developerFields, startIndex, opti
|
|
|
375
383
|
if (fDef.isDeveloperField) {
|
|
376
384
|
const field = fDef.name;
|
|
377
385
|
const { type } = fDef;
|
|
378
|
-
const
|
|
379
|
-
const
|
|
386
|
+
const scale = (_a = fDef.scale) !== null && _a !== void 0 ? _a : null;
|
|
387
|
+
const offset = (_b = fDef.offset) !== null && _b !== void 0 ? _b : 0;
|
|
380
388
|
fields[fDef.name] = applyOptions(formatByType(data, type, scale, offset), field, options, fields);
|
|
381
389
|
}
|
|
382
390
|
else {
|
package/dist/cjs/binary.js
CHANGED
|
@@ -196,6 +196,13 @@ function isInvalidValue(data, type) {
|
|
|
196
196
|
return false;
|
|
197
197
|
}
|
|
198
198
|
}
|
|
199
|
+
function isInvalidBaseTypeValue(data, baseTypeNo) {
|
|
200
|
+
if (Array.isArray(data)) {
|
|
201
|
+
return false;
|
|
202
|
+
}
|
|
203
|
+
const baseType = fit_js_1.FIT.types.fit_base_type[baseTypeNo];
|
|
204
|
+
return typeof baseType === 'string' ? isInvalidValue(data, baseType) : false;
|
|
205
|
+
}
|
|
199
206
|
function convertTo(data, unitsList, unitName) {
|
|
200
207
|
const options = fit_js_1.FIT.options[unitsList];
|
|
201
208
|
const unit = options[unitName];
|
|
@@ -272,6 +279,7 @@ function applyOptions(data, field, options, fields) {
|
|
|
272
279
|
}
|
|
273
280
|
}
|
|
274
281
|
function readRecord(blob, messageTypes, developerFields, startIndex, options, startDate, pausedTime) {
|
|
282
|
+
var _a, _b;
|
|
275
283
|
const recordHeader = blob[startIndex];
|
|
276
284
|
let localMessageType = recordHeader & 15;
|
|
277
285
|
if ((recordHeader & CompressedHeaderMask) === CompressedHeaderMask) {
|
|
@@ -307,7 +315,7 @@ function readRecord(blob, messageTypes, developerFields, startIndex, options, st
|
|
|
307
315
|
size: blob[fDefIndex + 1],
|
|
308
316
|
endianAbility: (baseType & 128) === 128,
|
|
309
317
|
littleEndian: lEnd,
|
|
310
|
-
baseTypeNo: baseType
|
|
318
|
+
baseTypeNo: baseType,
|
|
311
319
|
name: field,
|
|
312
320
|
dataType: (0, messages_js_1.getFitMessageBaseType)(baseType & 15),
|
|
313
321
|
};
|
|
@@ -329,7 +337,7 @@ function readRecord(blob, messageTypes, developerFields, startIndex, options, st
|
|
|
329
337
|
size,
|
|
330
338
|
endianAbility: (baseType & 128) === 128,
|
|
331
339
|
littleEndian: lEnd,
|
|
332
|
-
baseTypeNo: baseType
|
|
340
|
+
baseTypeNo: baseType,
|
|
333
341
|
name: devDef.field_name,
|
|
334
342
|
dataType: (0, messages_js_1.getFitMessageBaseType)(baseType & 15),
|
|
335
343
|
scale: devDef.scale || 1,
|
|
@@ -365,7 +373,7 @@ function readRecord(blob, messageTypes, developerFields, startIndex, options, st
|
|
|
365
373
|
for (let i = 0; i < messageType.fieldDefs.length; i++) {
|
|
366
374
|
const fDef = messageType.fieldDefs[i];
|
|
367
375
|
const data = readData(blob, fDef, readDataFromIndex, options);
|
|
368
|
-
if (!isInvalidValue(data, fDef.type)) {
|
|
376
|
+
if (!isInvalidValue(data, fDef.type) && !isInvalidBaseTypeValue(data, fDef.baseTypeNo)) {
|
|
369
377
|
rawFields.push({ fDef, data });
|
|
370
378
|
}
|
|
371
379
|
readDataFromIndex += fDef.size;
|
|
@@ -381,8 +389,8 @@ function readRecord(blob, messageTypes, developerFields, startIndex, options, st
|
|
|
381
389
|
if (fDef.isDeveloperField) {
|
|
382
390
|
const field = fDef.name;
|
|
383
391
|
const { type } = fDef;
|
|
384
|
-
const
|
|
385
|
-
const
|
|
392
|
+
const scale = (_a = fDef.scale) !== null && _a !== void 0 ? _a : null;
|
|
393
|
+
const offset = (_b = fDef.offset) !== null && _b !== void 0 ? _b : 0;
|
|
386
394
|
fields[fDef.name] = applyOptions(formatByType(data, type, scale, offset), field, options, fields);
|
|
387
395
|
}
|
|
388
396
|
else {
|
package/dist/cjs/fit-parser.js
CHANGED
|
@@ -104,6 +104,7 @@ class FitParser {
|
|
|
104
104
|
const jumps = [];
|
|
105
105
|
const time_in_zone = [];
|
|
106
106
|
const activity_metrics = [];
|
|
107
|
+
const user_metrics = [];
|
|
107
108
|
let loopIndex = headerLength;
|
|
108
109
|
const messageTypes = [];
|
|
109
110
|
const developerFields = [];
|
|
@@ -208,6 +209,9 @@ class FitParser {
|
|
|
208
209
|
case 'activity_metrics':
|
|
209
210
|
activity_metrics.push(message);
|
|
210
211
|
break;
|
|
212
|
+
case 'user_metrics':
|
|
213
|
+
user_metrics.push(message);
|
|
214
|
+
break;
|
|
211
215
|
default:
|
|
212
216
|
if (messageType !== '') {
|
|
213
217
|
fitObj[messageType] = message;
|
|
@@ -230,6 +234,7 @@ class FitParser {
|
|
|
230
234
|
fitObj.jumps = jumps;
|
|
231
235
|
fitObj.time_in_zone = time_in_zone;
|
|
232
236
|
fitObj.activity_metrics = activity_metrics;
|
|
237
|
+
fitObj.user_metrics = user_metrics;
|
|
233
238
|
if (isCascadeNeeded) {
|
|
234
239
|
laps = (0, helper_js_1.mapDataIntoLap)(laps, 'records', records);
|
|
235
240
|
laps = (0, helper_js_1.mapDataIntoLap)(laps, 'lengths', lengths);
|
package/dist/cjs/fit.js
CHANGED
|
@@ -4134,6 +4134,109 @@ exports.FIT = {
|
|
|
4134
4134
|
units: 'counts',
|
|
4135
4135
|
},
|
|
4136
4136
|
},
|
|
4137
|
+
// Undocumented Garmin user metrics message. Observed in activity FIT files exported
|
|
4138
|
+
// from Garmin Connect and displayed by fitfileviewer as "User Metrics".
|
|
4139
|
+
79: {
|
|
4140
|
+
name: 'user_metrics',
|
|
4141
|
+
253: {
|
|
4142
|
+
field: 'timestamp',
|
|
4143
|
+
type: 'date_time',
|
|
4144
|
+
scale: null,
|
|
4145
|
+
offset: 0,
|
|
4146
|
+
units: '',
|
|
4147
|
+
},
|
|
4148
|
+
0: {
|
|
4149
|
+
field: 'vo2_max',
|
|
4150
|
+
type: 'uint16',
|
|
4151
|
+
scale: 1024 / 3.5,
|
|
4152
|
+
offset: 0,
|
|
4153
|
+
units: 'ml/kg/min',
|
|
4154
|
+
},
|
|
4155
|
+
1: {
|
|
4156
|
+
field: 'age',
|
|
4157
|
+
type: 'uint8',
|
|
4158
|
+
scale: null,
|
|
4159
|
+
offset: 0,
|
|
4160
|
+
units: 'years',
|
|
4161
|
+
},
|
|
4162
|
+
2: {
|
|
4163
|
+
field: 'height',
|
|
4164
|
+
type: 'uint8',
|
|
4165
|
+
scale: 100,
|
|
4166
|
+
offset: 0,
|
|
4167
|
+
units: 'm',
|
|
4168
|
+
},
|
|
4169
|
+
3: {
|
|
4170
|
+
field: 'weight',
|
|
4171
|
+
type: 'uint16',
|
|
4172
|
+
scale: 10,
|
|
4173
|
+
offset: 0,
|
|
4174
|
+
units: 'kg',
|
|
4175
|
+
},
|
|
4176
|
+
4: {
|
|
4177
|
+
field: 'gender',
|
|
4178
|
+
type: 'gender',
|
|
4179
|
+
scale: null,
|
|
4180
|
+
offset: 0,
|
|
4181
|
+
units: '',
|
|
4182
|
+
},
|
|
4183
|
+
6: {
|
|
4184
|
+
field: 'max_heart_rate',
|
|
4185
|
+
type: 'uint8',
|
|
4186
|
+
scale: null,
|
|
4187
|
+
offset: 0,
|
|
4188
|
+
units: 'bpm',
|
|
4189
|
+
},
|
|
4190
|
+
8: {
|
|
4191
|
+
field: 'remaining_recovery_time',
|
|
4192
|
+
type: 'uint16',
|
|
4193
|
+
scale: null,
|
|
4194
|
+
offset: 0,
|
|
4195
|
+
units: '',
|
|
4196
|
+
},
|
|
4197
|
+
11: {
|
|
4198
|
+
field: 'lthr',
|
|
4199
|
+
type: 'uint16',
|
|
4200
|
+
scale: null,
|
|
4201
|
+
offset: 0,
|
|
4202
|
+
units: 'bpm',
|
|
4203
|
+
},
|
|
4204
|
+
12: {
|
|
4205
|
+
field: 'ltpower',
|
|
4206
|
+
type: 'uint16',
|
|
4207
|
+
scale: null,
|
|
4208
|
+
offset: 0,
|
|
4209
|
+
units: 'watts',
|
|
4210
|
+
},
|
|
4211
|
+
13: {
|
|
4212
|
+
field: 'ltspeed',
|
|
4213
|
+
type: 'uint16',
|
|
4214
|
+
scale: 1000,
|
|
4215
|
+
offset: 0,
|
|
4216
|
+
units: 'm/s',
|
|
4217
|
+
},
|
|
4218
|
+
16: {
|
|
4219
|
+
field: 'start_of_activity',
|
|
4220
|
+
type: 'date_time',
|
|
4221
|
+
scale: null,
|
|
4222
|
+
offset: 0,
|
|
4223
|
+
units: '',
|
|
4224
|
+
},
|
|
4225
|
+
19: {
|
|
4226
|
+
field: 'first_vo2_max',
|
|
4227
|
+
type: 'uint32',
|
|
4228
|
+
scale: 65536 / 3.5,
|
|
4229
|
+
offset: 0,
|
|
4230
|
+
units: 'ml/kg/min',
|
|
4231
|
+
},
|
|
4232
|
+
35: {
|
|
4233
|
+
field: 'end_of_previous_activity',
|
|
4234
|
+
type: 'date_time',
|
|
4235
|
+
scale: null,
|
|
4236
|
+
offset: 0,
|
|
4237
|
+
units: '',
|
|
4238
|
+
},
|
|
4239
|
+
},
|
|
4137
4240
|
103: {
|
|
4138
4241
|
name: 'monitoring_info',
|
|
4139
4242
|
253: {
|
|
@@ -4930,6 +5033,7 @@ exports.FIT = {
|
|
|
4930
5033
|
55: 'monitoring',
|
|
4931
5034
|
72: 'training_file',
|
|
4932
5035
|
78: 'hrv',
|
|
5036
|
+
79: 'user_metrics',
|
|
4933
5037
|
80: 'ant_rx',
|
|
4934
5038
|
81: 'ant_tx',
|
|
4935
5039
|
82: 'ant_channel_id',
|
package/dist/cjs/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' | 'activity_metrics' | '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' | 'time_in_zone' | 'set' | 'stress_level' | 'dive_settings' | 'dive_gas' | 'dive_alarm' | 'exercise_title' | 'dive_summary' | 'jump' | 'climb_pro' | 'tank_update' | 'tank_summary' | 'o_hr_settings' | 'mfg_range_min' | 'mfg_range_max' | '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' | 'user_metrics' | 'ant_rx' | 'ant_tx' | 'ant_channel_id' | 'length' | 'monitoring_info' | 'pad' | 'slave_device' | 'connectivity' | 'weather_conditions' | 'weather_alert' | 'cadence_zone' | 'hr' | 'activity_metrics' | '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' | 'time_in_zone' | 'set' | 'stress_level' | 'dive_settings' | 'dive_gas' | 'dive_alarm' | 'exercise_title' | 'dive_summary' | 'jump' | 'climb_pro' | 'tank_update' | 'tank_summary' | 'o_hr_settings' | 'mfg_range_min' | 'mfg_range_max' | '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';
|
|
@@ -841,6 +841,22 @@ export interface ParsedMonitoring {
|
|
|
841
841
|
export interface ParsedHrv {
|
|
842
842
|
time?: number[];
|
|
843
843
|
}
|
|
844
|
+
export interface ParsedUserMetrics {
|
|
845
|
+
vo2_max?: number;
|
|
846
|
+
age?: number;
|
|
847
|
+
height?: number;
|
|
848
|
+
weight?: number;
|
|
849
|
+
gender?: Gender;
|
|
850
|
+
max_heart_rate?: number;
|
|
851
|
+
remaining_recovery_time?: number;
|
|
852
|
+
lthr?: number;
|
|
853
|
+
ltpower?: number;
|
|
854
|
+
ltspeed?: number;
|
|
855
|
+
start_of_activity?: string;
|
|
856
|
+
first_vo2_max?: number;
|
|
857
|
+
end_of_previous_activity?: string;
|
|
858
|
+
timestamp: string;
|
|
859
|
+
}
|
|
844
860
|
export interface ParsedLength {
|
|
845
861
|
event?: Event;
|
|
846
862
|
event_type?: EventType;
|
|
@@ -1040,4 +1056,5 @@ export interface ParsedFit {
|
|
|
1040
1056
|
jumps?: ParsedJump[];
|
|
1041
1057
|
time_in_zone?: ParsedTimeInZone[];
|
|
1042
1058
|
activity_metrics?: ParsedActivityMetrics[];
|
|
1059
|
+
user_metrics?: ParsedUserMetrics[];
|
|
1043
1060
|
}
|
|
@@ -211,6 +211,7 @@ function generateFitType() {
|
|
|
211
211
|
jumps: 'parsed_jump',
|
|
212
212
|
time_in_zone: 'parsed_time_in_zone',
|
|
213
213
|
activity_metrics: 'parsed_activity_metrics',
|
|
214
|
+
user_metrics: 'parsed_user_metrics',
|
|
214
215
|
};
|
|
215
216
|
const referenceProperties = {
|
|
216
217
|
file_creator: 'parsed_file_creator',
|
package/dist/fit-parser.js
CHANGED
|
@@ -102,6 +102,7 @@ export default class FitParser {
|
|
|
102
102
|
const jumps = [];
|
|
103
103
|
const time_in_zone = [];
|
|
104
104
|
const activity_metrics = [];
|
|
105
|
+
const user_metrics = [];
|
|
105
106
|
let loopIndex = headerLength;
|
|
106
107
|
const messageTypes = [];
|
|
107
108
|
const developerFields = [];
|
|
@@ -206,6 +207,9 @@ export default class FitParser {
|
|
|
206
207
|
case 'activity_metrics':
|
|
207
208
|
activity_metrics.push(message);
|
|
208
209
|
break;
|
|
210
|
+
case 'user_metrics':
|
|
211
|
+
user_metrics.push(message);
|
|
212
|
+
break;
|
|
209
213
|
default:
|
|
210
214
|
if (messageType !== '') {
|
|
211
215
|
fitObj[messageType] = message;
|
|
@@ -228,6 +232,7 @@ export default class FitParser {
|
|
|
228
232
|
fitObj.jumps = jumps;
|
|
229
233
|
fitObj.time_in_zone = time_in_zone;
|
|
230
234
|
fitObj.activity_metrics = activity_metrics;
|
|
235
|
+
fitObj.user_metrics = user_metrics;
|
|
231
236
|
if (isCascadeNeeded) {
|
|
232
237
|
laps = mapDataIntoLap(laps, 'records', records);
|
|
233
238
|
laps = mapDataIntoLap(laps, 'lengths', lengths);
|
package/dist/fit.js
CHANGED
|
@@ -4131,6 +4131,109 @@ export const FIT = {
|
|
|
4131
4131
|
units: 'counts',
|
|
4132
4132
|
},
|
|
4133
4133
|
},
|
|
4134
|
+
// Undocumented Garmin user metrics message. Observed in activity FIT files exported
|
|
4135
|
+
// from Garmin Connect and displayed by fitfileviewer as "User Metrics".
|
|
4136
|
+
79: {
|
|
4137
|
+
name: 'user_metrics',
|
|
4138
|
+
253: {
|
|
4139
|
+
field: 'timestamp',
|
|
4140
|
+
type: 'date_time',
|
|
4141
|
+
scale: null,
|
|
4142
|
+
offset: 0,
|
|
4143
|
+
units: '',
|
|
4144
|
+
},
|
|
4145
|
+
0: {
|
|
4146
|
+
field: 'vo2_max',
|
|
4147
|
+
type: 'uint16',
|
|
4148
|
+
scale: 1024 / 3.5,
|
|
4149
|
+
offset: 0,
|
|
4150
|
+
units: 'ml/kg/min',
|
|
4151
|
+
},
|
|
4152
|
+
1: {
|
|
4153
|
+
field: 'age',
|
|
4154
|
+
type: 'uint8',
|
|
4155
|
+
scale: null,
|
|
4156
|
+
offset: 0,
|
|
4157
|
+
units: 'years',
|
|
4158
|
+
},
|
|
4159
|
+
2: {
|
|
4160
|
+
field: 'height',
|
|
4161
|
+
type: 'uint8',
|
|
4162
|
+
scale: 100,
|
|
4163
|
+
offset: 0,
|
|
4164
|
+
units: 'm',
|
|
4165
|
+
},
|
|
4166
|
+
3: {
|
|
4167
|
+
field: 'weight',
|
|
4168
|
+
type: 'uint16',
|
|
4169
|
+
scale: 10,
|
|
4170
|
+
offset: 0,
|
|
4171
|
+
units: 'kg',
|
|
4172
|
+
},
|
|
4173
|
+
4: {
|
|
4174
|
+
field: 'gender',
|
|
4175
|
+
type: 'gender',
|
|
4176
|
+
scale: null,
|
|
4177
|
+
offset: 0,
|
|
4178
|
+
units: '',
|
|
4179
|
+
},
|
|
4180
|
+
6: {
|
|
4181
|
+
field: 'max_heart_rate',
|
|
4182
|
+
type: 'uint8',
|
|
4183
|
+
scale: null,
|
|
4184
|
+
offset: 0,
|
|
4185
|
+
units: 'bpm',
|
|
4186
|
+
},
|
|
4187
|
+
8: {
|
|
4188
|
+
field: 'remaining_recovery_time',
|
|
4189
|
+
type: 'uint16',
|
|
4190
|
+
scale: null,
|
|
4191
|
+
offset: 0,
|
|
4192
|
+
units: '',
|
|
4193
|
+
},
|
|
4194
|
+
11: {
|
|
4195
|
+
field: 'lthr',
|
|
4196
|
+
type: 'uint16',
|
|
4197
|
+
scale: null,
|
|
4198
|
+
offset: 0,
|
|
4199
|
+
units: 'bpm',
|
|
4200
|
+
},
|
|
4201
|
+
12: {
|
|
4202
|
+
field: 'ltpower',
|
|
4203
|
+
type: 'uint16',
|
|
4204
|
+
scale: null,
|
|
4205
|
+
offset: 0,
|
|
4206
|
+
units: 'watts',
|
|
4207
|
+
},
|
|
4208
|
+
13: {
|
|
4209
|
+
field: 'ltspeed',
|
|
4210
|
+
type: 'uint16',
|
|
4211
|
+
scale: 1000,
|
|
4212
|
+
offset: 0,
|
|
4213
|
+
units: 'm/s',
|
|
4214
|
+
},
|
|
4215
|
+
16: {
|
|
4216
|
+
field: 'start_of_activity',
|
|
4217
|
+
type: 'date_time',
|
|
4218
|
+
scale: null,
|
|
4219
|
+
offset: 0,
|
|
4220
|
+
units: '',
|
|
4221
|
+
},
|
|
4222
|
+
19: {
|
|
4223
|
+
field: 'first_vo2_max',
|
|
4224
|
+
type: 'uint32',
|
|
4225
|
+
scale: 65536 / 3.5,
|
|
4226
|
+
offset: 0,
|
|
4227
|
+
units: 'ml/kg/min',
|
|
4228
|
+
},
|
|
4229
|
+
35: {
|
|
4230
|
+
field: 'end_of_previous_activity',
|
|
4231
|
+
type: 'date_time',
|
|
4232
|
+
scale: null,
|
|
4233
|
+
offset: 0,
|
|
4234
|
+
units: '',
|
|
4235
|
+
},
|
|
4236
|
+
},
|
|
4134
4237
|
103: {
|
|
4135
4238
|
name: 'monitoring_info',
|
|
4136
4239
|
253: {
|
|
@@ -4927,6 +5030,7 @@ export const FIT = {
|
|
|
4927
5030
|
55: 'monitoring',
|
|
4928
5031
|
72: 'training_file',
|
|
4929
5032
|
78: 'hrv',
|
|
5033
|
+
79: 'user_metrics',
|
|
4930
5034
|
80: 'ant_rx',
|
|
4931
5035
|
81: 'ant_tx',
|
|
4932
5036
|
82: 'ant_channel_id',
|
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' | 'activity_metrics' | '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' | 'time_in_zone' | 'set' | 'stress_level' | 'dive_settings' | 'dive_gas' | 'dive_alarm' | 'exercise_title' | 'dive_summary' | 'jump' | 'climb_pro' | 'tank_update' | 'tank_summary' | 'o_hr_settings' | 'mfg_range_min' | 'mfg_range_max' | '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' | 'user_metrics' | 'ant_rx' | 'ant_tx' | 'ant_channel_id' | 'length' | 'monitoring_info' | 'pad' | 'slave_device' | 'connectivity' | 'weather_conditions' | 'weather_alert' | 'cadence_zone' | 'hr' | 'activity_metrics' | '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' | 'time_in_zone' | 'set' | 'stress_level' | 'dive_settings' | 'dive_gas' | 'dive_alarm' | 'exercise_title' | 'dive_summary' | 'jump' | 'climb_pro' | 'tank_update' | 'tank_summary' | 'o_hr_settings' | 'mfg_range_min' | 'mfg_range_max' | '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';
|
|
@@ -841,6 +841,22 @@ export interface ParsedMonitoring {
|
|
|
841
841
|
export interface ParsedHrv {
|
|
842
842
|
time?: number[];
|
|
843
843
|
}
|
|
844
|
+
export interface ParsedUserMetrics {
|
|
845
|
+
vo2_max?: number;
|
|
846
|
+
age?: number;
|
|
847
|
+
height?: number;
|
|
848
|
+
weight?: number;
|
|
849
|
+
gender?: Gender;
|
|
850
|
+
max_heart_rate?: number;
|
|
851
|
+
remaining_recovery_time?: number;
|
|
852
|
+
lthr?: number;
|
|
853
|
+
ltpower?: number;
|
|
854
|
+
ltspeed?: number;
|
|
855
|
+
start_of_activity?: string;
|
|
856
|
+
first_vo2_max?: number;
|
|
857
|
+
end_of_previous_activity?: string;
|
|
858
|
+
timestamp: string;
|
|
859
|
+
}
|
|
844
860
|
export interface ParsedLength {
|
|
845
861
|
event?: Event;
|
|
846
862
|
event_type?: EventType;
|
|
@@ -1040,4 +1056,5 @@ export interface ParsedFit {
|
|
|
1040
1056
|
jumps?: ParsedJump[];
|
|
1041
1057
|
time_in_zone?: ParsedTimeInZone[];
|
|
1042
1058
|
activity_metrics?: ParsedActivityMetrics[];
|
|
1059
|
+
user_metrics?: ParsedUserMetrics[];
|
|
1043
1060
|
}
|
package/dist/type_generator.js
CHANGED
|
@@ -191,6 +191,7 @@ export function generateFitType() {
|
|
|
191
191
|
jumps: 'parsed_jump',
|
|
192
192
|
time_in_zone: 'parsed_time_in_zone',
|
|
193
193
|
activity_metrics: 'parsed_activity_metrics',
|
|
194
|
+
user_metrics: 'parsed_user_metrics',
|
|
194
195
|
};
|
|
195
196
|
const referenceProperties = {
|
|
196
197
|
file_creator: 'parsed_file_creator',
|