From 9b67561d563f4d0ce0893f7cfc50c4bde1ea4dcc Mon Sep 17 00:00:00 2001 From: Ben Pryhoda Date: Tue, 14 Jan 2025 12:50:28 -0700 Subject: [PATCH] Garmin FIT SDK 21.161.0 * Garmin FIT SDK 21.161.0 * Adds Encoder feature * Update versions of Node tested --- .github/workflows/run-tests.yml | 2 +- README.md | 6 + package.json | 11 +- src/accumulator.js | 6 +- src/bit-stream.js | 6 +- src/crc-calculator.js | 6 +- src/decoder.js | 39 +- src/encoder.js | 323 +++++ src/fit.js | 83 +- src/index.js | 10 +- src/mesg-definition.js | 269 +++++ src/output-stream.js | 220 ++++ src/profile.js | 1495 +++++++++++++++++++++++- src/stream.js | 6 +- src/utils-hr-mesg.js | 6 +- src/utils-internal.js | 6 +- src/utils.js | 41 +- test/accumulator.test.js | 3 +- test/bit-stream.test.js | 3 +- test/crc.test.js | 3 +- test/data/test-data-expand-hr-mesgs.js | 2 +- test/data/test-data.js | 2 +- test/decoder.test.js | 10 +- test/encode-activity-recipe.test.js | 196 ++++ test/encoder.test.js | 174 +++ test/output-stream.test.js | 318 +++++ test/stream.test.js | 3 +- test/utils-hr-mesg.test.js | 3 +- test/utils.test.js | 48 +- 29 files changed, 3228 insertions(+), 72 deletions(-) create mode 100644 src/encoder.js create mode 100644 src/mesg-definition.js create mode 100644 src/output-stream.js create mode 100644 test/encode-activity-recipe.test.js create mode 100644 test/encoder.test.js create mode 100644 test/output-stream.test.js diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index c8a61cf..2a18ced 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -13,7 +13,7 @@ jobs: strategy: matrix: - node-version: [16.x, 18.x] + node-version: [16.x, 18.x, 20.x] # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ steps: diff --git a/README.md b/README.md index f5f741c..9aaf847 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,8 @@ The Read method accepts an optional options object that can be used to customize ````js const { messages, errors } = decoder.read({ mesgListener: (messageNumber, message) => {}, + mesgDefinitionListener: (mesgDefinition) => {}, + fieldDescriptionListener: (key, developerDataIdMesg, fieldDescriptionMesg) => {}, applyScaleAndOffset: true, expandSubFields: true, expandComponents: true, @@ -97,6 +99,10 @@ const { messages, errors } = decoder.read({ console.log(recordFields); ```` +#### mesgDefinitionListener: (mesgDefinition) => {} +Optional callback function that can be used to inspect message defintions as they are decoded from the file. +#### fieldDescriptionListener: (key, developerDataIdMesg, fieldDescriptionMesg) => {} +Optional callback function that can be used to inspect developer field descriptions as they are decoded from the file. #### applyScaleAndOffset: true | false When true the scale and offset values as defined in the FIT Profile are applied to the raw field values. ````js diff --git a/package.json b/package.json index f4c84e4..dda2061 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,12 @@ { "name": "@garmin/fitsdk", - "version": "21.158.0", + "version": "21.161.0", "description": "FIT JavaScript SDK", "main": "src/index.js", "type": "module", "scripts": { "build": "node .", - "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js" + "test": "vitest run" }, "author": "Garmin International, Inc.", "license": "SEE LICENSE IN LICENSE.txt", @@ -18,9 +18,6 @@ "src/" ], "devDependencies": { - "jest": "^28.1.2" - }, - "jest": { - "transform": {} + "vitest": "^2.1.8" } -} \ No newline at end of file +} diff --git a/src/accumulator.js b/src/accumulator.js index d88bd34..036f8fb 100644 --- a/src/accumulator.js +++ b/src/accumulator.js @@ -1,12 +1,12 @@ ///////////////////////////////////////////////////////////////////////////////////////////// -// Copyright 2024 Garmin International, Inc. +// Copyright 2025 Garmin International, Inc. // Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you // may not use this file except in compliance with the Flexible and Interoperable Data // Transfer (FIT) Protocol License. ///////////////////////////////////////////////////////////////////////////////////////////// // ****WARNING**** This file is auto-generated! Do NOT edit this file. -// Profile Version = 21.158.0Release -// Tag = production/release/21.158.0-0-gc9428aa +// Profile Version = 21.161.0Release +// Tag = production/release/21.161.0-0-g58854c0 ///////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/bit-stream.js b/src/bit-stream.js index 90c99a9..f6e7ef3 100644 --- a/src/bit-stream.js +++ b/src/bit-stream.js @@ -1,12 +1,12 @@ ///////////////////////////////////////////////////////////////////////////////////////////// -// Copyright 2024 Garmin International, Inc. +// Copyright 2025 Garmin International, Inc. // Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you // may not use this file except in compliance with the Flexible and Interoperable Data // Transfer (FIT) Protocol License. ///////////////////////////////////////////////////////////////////////////////////////////// // ****WARNING**** This file is auto-generated! Do NOT edit this file. -// Profile Version = 21.158.0Release -// Tag = production/release/21.158.0-0-gc9428aa +// Profile Version = 21.161.0Release +// Tag = production/release/21.161.0-0-g58854c0 ///////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/crc-calculator.js b/src/crc-calculator.js index 1e0d1c7..16aedf7 100644 --- a/src/crc-calculator.js +++ b/src/crc-calculator.js @@ -1,12 +1,12 @@ ///////////////////////////////////////////////////////////////////////////////////////////// -// Copyright 2024 Garmin International, Inc. +// Copyright 2025 Garmin International, Inc. // Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you // may not use this file except in compliance with the Flexible and Interoperable Data // Transfer (FIT) Protocol License. ///////////////////////////////////////////////////////////////////////////////////////////// // ****WARNING**** This file is auto-generated! Do NOT edit this file. -// Profile Version = 21.158.0Release -// Tag = production/release/21.158.0-0-gc9428aa +// Profile Version = 21.161.0Release +// Tag = production/release/21.161.0-0-g58854c0 ///////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/decoder.js b/src/decoder.js index 2cc461a..39035bd 100644 --- a/src/decoder.js +++ b/src/decoder.js @@ -1,12 +1,12 @@ ///////////////////////////////////////////////////////////////////////////////////////////// -// Copyright 2024 Garmin International, Inc. +// Copyright 2025 Garmin International, Inc. // Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you // may not use this file except in compliance with the Flexible and Interoperable Data // Transfer (FIT) Protocol License. ///////////////////////////////////////////////////////////////////////////////////////////// // ****WARNING**** This file is auto-generated! Do NOT edit this file. -// Profile Version = 21.158.0Release -// Tag = production/release/21.158.0-0-gc9428aa +// Profile Version = 21.161.0Release +// Tag = production/release/21.161.0-0-g58854c0 ///////////////////////////////////////////////////////////////////////////////////////////// @@ -48,6 +48,8 @@ class Decoder { #decodeMode = DecodeMode.NORMAL; #mesgListener = null; + #mesgDefinitionListener = null; + #fieldDescriptionListener = null; #optExpandSubFields = true; #optExpandComponents = true; #optApplyScaleAndOffset = true; @@ -149,11 +151,28 @@ class Decoder { * @param {Object} message - The message */ + /** + * Message Definition Listener Callback + * + * @callback Decoder~mesgDefinitionListener + * @param {Object} messageDefinition - The message Definition + */ + + /** + * Developer Field Description Listener Callback + * + * @callback Decoder~fieldDescriptionListener + * @param {Number} key - The key associated with this pairing of of Developer Data Id and Field Description Mesgs + * @param {Object} developerDataIdMesg - The Developer Data Id Mesg associated with this pairing + * @param {Object} fieldDescriptionMesg - The Field Description Mesg associated with this pairing + */ /** * Read the messages from the stream. * @param {Object=} [options] - Read options (optional) * @param {Decoder~mesgListener} [options.mesgListener=null] - (optional, default null) mesgListener(mesgNum, message) + * @param {Decoder~mesgDefinitionListener} [options.mesgDefinitionListener=null] - (optional, default null) mesgDefinitionListener(mesgDefinition) + * @param {Decoder~fieldDescriptionListener} [options.fieldDescriptionListener=null] - (optional, default null) fieldDescriptionListener(key, developerDataIdMesg, fieldDescriptionMesg) * @param {Boolean} [options.expandSubFields=true] - (optional, default true) * @param {Boolean} [options.expandComponents=true] - (optional, default true) * @param {Boolean} [options.applyScaleAndOffset=true] - (optional, default true) @@ -167,6 +186,8 @@ class Decoder { */ read({ mesgListener = null, + mesgDefinitionListener = null, + fieldDescriptionListener = null, expandSubFields = true, expandComponents = true, applyScaleAndOffset = true, @@ -178,6 +199,8 @@ class Decoder { dataOnly = false,} = {}) { this.#mesgListener = mesgListener; + this.#mesgDefinitionListener = mesgDefinitionListener; + this.#fieldDescriptionListener = fieldDescriptionListener; this.#optExpandSubFields = expandSubFields this.#optExpandComponents = expandComponents; this.#optApplyScaleAndOffset = applyScaleAndOffset; @@ -310,6 +333,8 @@ class Decoder { } } + this.#mesgDefinitionListener?.({...messageDefinition}); + let messageProfile = Profile.messages[messageDefinition.globalMessageNumber]; if (messageProfile == null && this.#optIncludeUnknownData) { @@ -414,6 +439,14 @@ class Decoder { this.#messages[messageDefinition.messagesKey].push(message); this.#mesgListener?.(messageDefinition.globalMessageNumber, message); + + if (mesgNum === Profile.MesgNum.FIELD_DESCRIPTION && this.#fieldDescriptionListener != null) { + const developerDataIdMesg = this.#messages.developerDataIdMesgs?.find((developerDataIdMesg) => { + return developerDataIdMesg.developerDataIndex === message.developerDataIndex; + }) ?? {}; + + this.#fieldDescriptionListener(message.key, {...developerDataIdMesg}, {...message}); + } } } diff --git a/src/encoder.js b/src/encoder.js new file mode 100644 index 0000000..53ca7b1 --- /dev/null +++ b/src/encoder.js @@ -0,0 +1,323 @@ +///////////////////////////////////////////////////////////////////////////////////////////// +// Copyright 2025 Garmin International, Inc. +// Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you +// may not use this file except in compliance with the Flexible and Interoperable Data +// Transfer (FIT) Protocol License. +///////////////////////////////////////////////////////////////////////////////////////////// +// ****WARNING**** This file is auto-generated! Do NOT edit this file. +// Profile Version = 21.161.0Release +// Tag = production/release/21.161.0-0-g58854c0 +///////////////////////////////////////////////////////////////////////////////////////////// + + +import CrcCalculator from "./crc-calculator.js"; +import FIT from "./fit.js"; +import MesgDefinition from "./mesg-definition.js"; +import OutputStream from "./output-stream.js"; +import Profile from "./profile.js"; +import Utils from "./utils.js"; + +const HEADER_WITH_CRC_SIZE = 14; +const HEADER_WITHOUT_CRC_SIZE = 12; + +/** + * A class for encoding FIT files. + * @class + */ +class Encoder { + /** + Creates a FIT File Encoder + * @param {Object} [options] - Encoder options (optional) + * @param {Object. { + const values = this.#transformValues(mesg[fieldDefinition.name], fieldDefinition); + const baseTypeDef = FIT.BaseTypeDefinitions[fieldDefinition.baseType]; + + this.#outputStream.write(values, baseTypeDef.type); + }); + + // Write Developer Field Values + mesgDefinition.developerFieldDefinitions.forEach((developerFieldDefinition) => { + const values = this.#transformValues( + mesg.developerFields[developerFieldDefinition.key], + developerFieldDefinition); + + const baseTypeDef = FIT.BaseTypeDefinitions[developerFieldDefinition.baseType]; + + this.#outputStream.write(values, baseTypeDef.type); + }); + } + catch (error) { + throw new Error( + "Could not write Message", { + cause: { + mesg, + cause: { + message: error.message, + cause: error.cause, + }, + }, + } + ); + } + + return this; + }; + + /** + * Adds a Developer Data Field Description and associated Developer Data Id Message to the Endoder + * This provides the Encoder with the context required to write Developer Fields to the output-stream. + * *** This method does not write the messages to the output-stream *** + * This method can be used as a Decoder~fieldDescriptionListener callback. + * @param {Number} key - The message number for this message + * @param {Object} developerDataIdMesg - The Developer Data Id mesg + * @param {Object} fieldDescriptionMesg - The Field Description mesg + * @return {this} + */ + addDeveloperField(key, developerDataIdMesg, fieldDescriptionMesg) { + if(developerDataIdMesg.developerDataIndex == null || fieldDescriptionMesg.developerDataIndex == null) { + throw new Error("addDeveloperField() - one or more developerDataIndex values are null.", { + cause: { + key, + developerDataIdMesg, + fieldDescriptionMesg + } + }); + } + + if(developerDataIdMesg.developerDataIndex !== fieldDescriptionMesg.developerDataIndex) { + throw new Error("addDeveloperField() - developerDataIndex values do not match.", { + cause: { + key, + developerDataIdMesg, + fieldDescriptionMesg + } + }); + } + + this.#fieldDescriptions[key] = { + developerDataIdMesg, + fieldDescriptionMesg + } + + return this; + } + + #writeEmptyFileHeader() { + Array(HEADER_WITH_CRC_SIZE).fill(0).forEach((zero) => { + this.#outputStream.writeUInt8(zero); + }); + } + + #updateFileHeader() { + const arrayBuffer = new ArrayBuffer(HEADER_WITH_CRC_SIZE); + const dataView = new DataView(arrayBuffer); + + // Header Size + dataView.setUint8(0, HEADER_WITH_CRC_SIZE); + + // Protocol Version + dataView.setUint8(1, 2); + + // Profile Version + dataView.setUint16(2, Profile.version.major * 1000 + Profile.version.minor, true); + + // Data Size + dataView.setUint32(4, this.#outputStream.length - HEADER_WITH_CRC_SIZE, true); + + // Data Type ".FIT" + dataView.setUint8(8, 0x2E); + dataView.setUint8(9, 0x46); + dataView.setUint8(10, 0x49); + dataView.setUint8(11, 0x54); + + // Header CRC + const crc = CrcCalculator.calculateCRC(new Uint8Array(arrayBuffer), 0, HEADER_WITHOUT_CRC_SIZE); + dataView.setUint16(12, crc, true); + + this.#outputStream.set(new Uint8Array(arrayBuffer)); + } + + #writeFileCrc() { + const crc = CrcCalculator.calculateCRC(this.#outputStream.uint8Array, 0, this.#outputStream.length); + this.#outputStream.writeUInt16(crc); + } + + #transformValues(value, fieldDefinition) { + const values = Array.isArray(value) ? value : [value,]; + + return values.map((value) => { + return this.#transformValue(value, fieldDefinition); + }); + } + + #transformValue(value, fieldDefinition) { + try { + if (FIT.isNotNumberStringDateOrBoolean(value)) { + return FIT.BaseTypeDefinitions[fieldDefinition.baseType].invalid; + } + + // Is this a numeric field? + if (FIT.NumericFieldTypes.includes(fieldDefinition.type)) { + if (!FIT.isNumeric(value)) { + throw new Error(); + } + + const scale = Array.isArray(fieldDefinition.scale) ? fieldDefinition.scale[0] : fieldDefinition.scale; + const offset = Array.isArray(fieldDefinition.offset) ? fieldDefinition.offset[0] : fieldDefinition.offset; + + return (value + offset) * scale; + } + + // Is this a date_time field? + if (fieldDefinition.type === "dateTime") { + if (FIT.isDate(value)) { + return Utils.convertDateToDateTime(value); + } + + if (!FIT.isNumeric(value)) { + throw new Error(); + } + + return value; + } + + // Is this a string field + if (fieldDefinition.type === "string") { + if (!FIT.isString(value)) { + throw new Error(); + } + + return value; + } + + // Must be a FIT type field + if (FIT.isNumeric(value)) { + return value; + } + + const profileType = Profile.types[fieldDefinition.type]; + + const [typeValue,] = Object.entries(profileType).find(([, typeValue,]) => { + return typeValue === value; + }); + + return typeValue; + } + catch { + throw new Error( + `Could not convert "${value}" to "${fieldDefinition.type}"`, + { cause: { value, fieldDefinition, }, }); + } + } + + /** + * Creates a MesgDefinition from the mesgNum and mesg. + * @param {Number} mesgNum - The mesg number for this message + * @param {Object} [mesg] - The message data + * @return {MesgDefinition} + */ + #createMesgDefinition = (mesgNum, mesg) => { + const mesgDefinition = new MesgDefinition(mesgNum, mesg, { fieldDescriptions: this.#fieldDescriptions, }); + mesgDefinition.localMesgNum = this.#lookupLocalMesgNum(mesgDefinition); + + return mesgDefinition; + }; + + /** + * Searches the #localMesgDefinitions for a matching mesgDefinition + * @param {Object} mesgDefinition - the mesg definition to match + * @return The localMesgNum to be used with mesgDefinition + */ + #lookupLocalMesgNum = (mesgDefinition) => { + const localMesgNum = this.#localMesgDefinitions.findIndex((localMesgDefinition) => { + return localMesgDefinition?.equals(mesgDefinition) ?? false; + }); + + return (localMesgNum !== -1 ? localMesgNum : this.#nextLocalMesgNum++) & FIT.LOCAL_MESG_NUM_MASK; + }; + + /** + * Writes the mesgDefinition to the output stream, if it is not one of the currently active 16 + * @param {Object} mesgDefinition - the mesg definition to match + * @return The localMesgNum to be used with mesgDefinition + */ + #writeMesgDefinitionIfNotActive = (mesgDefinition) => { + const localMesgNum = mesgDefinition.localMesgNum; + + if (this.#localMesgDefinitions[localMesgNum] == null + || !this.#localMesgDefinitions[localMesgNum].equals(mesgDefinition)) { + this.#writeMesgDefinition(mesgDefinition); + } + + return localMesgNum; + }; + + /** + * Writes the mesgDefinition to the output stream + * @param {Object} mesgDefinition - the mesg definition to write + * @return {this} + */ + #writeMesgDefinition(mesgDefinition) { + mesgDefinition.write(this.#outputStream); + this.#localMesgDefinitions[mesgDefinition.localMesgNum] = mesgDefinition; + + return this; + } + + #localMesgDefinitions = Array(16).fill(null); + #nextLocalMesgNum = 0; + #outputStream = new OutputStream(); + #fieldDescriptions = null; +} + +export default Encoder; diff --git a/src/fit.js b/src/fit.js index cc9af92..637efef 100644 --- a/src/fit.js +++ b/src/fit.js @@ -1,12 +1,12 @@ ///////////////////////////////////////////////////////////////////////////////////////////// -// Copyright 2024 Garmin International, Inc. +// Copyright 2025 Garmin International, Inc. // Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you // may not use this file except in compliance with the Flexible and Interoperable Data // Transfer (FIT) Protocol License. ///////////////////////////////////////////////////////////////////////////////////////////// // ****WARNING**** This file is auto-generated! Do NOT edit this file. -// Profile Version = 21.158.0Release -// Tag = production/release/21.158.0-0-gc9428aa +// Profile Version = 21.161.0Release +// Tag = production/release/21.161.0-0-g58854c0 ///////////////////////////////////////////////////////////////////////////////////////////// @@ -69,6 +69,7 @@ const NumericFieldTypes = [ ]; const FieldTypeToBaseType = { + "enum": BaseType.UINT8, "sint8": BaseType.SINT8, "uint8": BaseType.UINT8, "sint16": BaseType.SINT16, @@ -87,9 +88,83 @@ const FieldTypeToBaseType = { "uint64z": BaseType.UINT64Z }; +const BaseTypeToFieldType = { + [BaseType.ENUM]: "enum", + [BaseType.SINT8]: "sint8", + [BaseType.UINT8]: "uint8", + [BaseType.SINT16]: "sint16", + [BaseType.UINT16]: "uint16", + [BaseType.SINT32]: "sint32", + [BaseType.UINT32]: "uint32", + [BaseType.STRING]: "string", + [BaseType.FLOAT32]: "float32", + [BaseType.FLOAT64]: "float64", + [BaseType.UINT8Z]: "uint8z", + [BaseType.UINT16Z]: "uint16z", + [BaseType.UINT32Z]: "uint32z", + [BaseType.BYTE]: "byte", + [BaseType.SINT64]: "sint64", + [BaseType.UINT64]: "uint64", + [BaseType.UINT64Z]: "uint64z", +}; + +const isNullOrUndefined = (obj) => { + return obj == null; +}; + +const isObject = (obj) => { + return typeof obj === "object"; +}; + +const isBoolean = (obj) => { + return "boolean" === typeof obj; +}; + +const isDate = (obj) => { + return typeof obj === "object" && obj instanceof Date; +}; + +const isString = (obj) => { + return typeof obj === "string"; +}; + +const isNumeric = (obj) => { + return !isNaN(parseFloat(obj)) && isFinite(obj); +}; + +const isNotNumberStringDateOrBoolean = (obj) => { + return !isNumberStringDateOrBoolean(obj); +}; + +const isNumberStringDateOrBoolean = (obj) => { + if (isNullOrUndefined(obj)) { + return false; + } + + if (!isDate(obj) && !isString(obj) && !isNumeric(obj) && !isBoolean(obj)) { + return false; + } + + return true; +}; + export default { BaseType, BaseTypeDefinitions, NumericFieldTypes, - FieldTypeToBaseType + FieldTypeToBaseType, + BaseTypeToFieldType, + isNullOrUndefined, + isObject, + isBoolean, + isDate, + isString, + isNumeric, + isNumberStringDateOrBoolean, + isNotNumberStringDateOrBoolean, + MAX_FIELD_SIZE: 255, + MESG_DEFINITION_MASK: 0x40, + LOCAL_MESG_NUM_MASK: 0x0F, + ARCH_LITTLE_ENDIAN: 0x00, + DEV_DATA_MASK: 0x20, }; diff --git a/src/index.js b/src/index.js index 1850c0d..1b8e94b 100644 --- a/src/index.js +++ b/src/index.js @@ -1,18 +1,20 @@ ///////////////////////////////////////////////////////////////////////////////////////////// -// Copyright 2024 Garmin International, Inc. +// Copyright 2025 Garmin International, Inc. // Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you // may not use this file except in compliance with the Flexible and Interoperable Data // Transfer (FIT) Protocol License. ///////////////////////////////////////////////////////////////////////////////////////////// // ****WARNING**** This file is auto-generated! Do NOT edit this file. -// Profile Version = 21.158.0Release -// Tag = production/release/21.158.0-0-gc9428aa +// Profile Version = 21.161.0Release +// Tag = production/release/21.161.0-0-g58854c0 ///////////////////////////////////////////////////////////////////////////////////////////// +import CrcCalculator from "./crc-calculator.js"; import Decoder from "./decoder.js"; +import Encoder from "./encoder.js"; import Profile from "./profile.js"; import Stream from "./stream.js"; import Utils from "./utils.js"; -export { Decoder, Stream, Profile, Utils }; +export { CrcCalculator, Decoder, Encoder, Stream, Profile, Utils }; diff --git a/src/mesg-definition.js b/src/mesg-definition.js new file mode 100644 index 0000000..2c78186 --- /dev/null +++ b/src/mesg-definition.js @@ -0,0 +1,269 @@ +///////////////////////////////////////////////////////////////////////////////////////////// +// Copyright 2025 Garmin International, Inc. +// Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you +// may not use this file except in compliance with the Flexible and Interoperable Data +// Transfer (FIT) Protocol License. +///////////////////////////////////////////////////////////////////////////////////////////// +// ****WARNING**** This file is auto-generated! Do NOT edit this file. +// Profile Version = 21.161.0Release +// Tag = production/release/21.161.0-0-g58854c0 +///////////////////////////////////////////////////////////////////////////////////////////// + + +import FIT from "./fit.js"; +import Profile from "./profile.js"; + +const textEncoder = new TextEncoder(); + +class MesgDefinition { + globalMesgNumber; + localMesgNum; + fieldDefinitions = []; + developerFieldDefinitions = []; + + constructor(mesgNum, mesg, { fieldDescriptions = null, } = {}) { + try { + if (mesg == null) { + throw new Error("mesg is missing or null"); + } + + if (mesgNum == null) { + throw new Error("mesgNum is missing or null"); + } + + const mesgProfile = Profile.messages[mesgNum]; + + if (mesgProfile == null) { + throw new Error(`mesgNum: ${mesgNum} could not be found in the Profile`); + } + + this.globalMesgNumber = mesgNum; + this.localMesgNum = 0; + + Object.keys(mesg).forEach((fieldName) => { + if (mesg[fieldName] == null) { + return; + } + + const fieldProfile = Object.entries(mesgProfile.fields).find(([, fieldProfile,]) => { + return fieldProfile.name === fieldName; + }); + + if (fieldProfile == null) { + return; + } + + const baseType = FIT.FieldTypeToBaseType[fieldProfile[1].baseType]; + const baseTypeDef = FIT.BaseTypeDefinitions[baseType]; + + this.fieldDefinitions.push({ + name: fieldName, + num: fieldProfile[1].num, + size: this.#fieldSize(mesg[fieldName], baseTypeDef), + baseType: baseType, + type: fieldProfile[1].type, + scale: fieldProfile[1].scale, + offset: fieldProfile[1].offset, + }); + }); + + Object.keys(mesg.developerFields ?? {})?.sort()?.forEach((key) => { + const { developerDataIdMesg, fieldDescriptionMesg, } = this.#fieldDescriptionForKey(fieldDescriptions, key); + + const baseTypeDef = FIT.BaseTypeDefinitions[fieldDescriptionMesg.fitBaseTypeId]; + + this.developerFieldDefinitions.push({ + key, + baseType: fieldDescriptionMesg.fitBaseTypeId, + fieldDefinitionNumber: fieldDescriptionMesg.fieldDefinitionNumber, + size: this.#fieldSize(mesg.developerFields[key], baseTypeDef), + developerDataIndex: developerDataIdMesg.developerDataIndex, + }); + }); + + if (this.fieldDefinitions.length === 0) { + throw new Error("No valid fields were found in the message"); + } + + if (this.fieldDefinitions.some((fieldDefinition) => { + return fieldDefinition.size > FIT.MAX_FIELD_SIZE; + })) { + throw new Error(`Some field sizes are greater than ${FIT.MAX_FIELD_SIZE}`, { cause: this.fieldDefinitions, }); + } + } + catch (error) { + throw new Error( + "Could not construct MesgDefinition from Message", { + cause: { + cause: { + message: error.message, + cause: error.cause, + }, + }, + } + ); + } + } + + write(outputStream) { + // Header + let headerByte = FIT.MESG_DEFINITION_MASK | (this.localMesgNum & FIT.LOCAL_MESG_NUM_MASK); + if (this.developerFieldDefinitions.length > 0) { + headerByte |= FIT.DEV_DATA_MASK; + } + + outputStream.writeUInt8(headerByte); + + // Reserved Byte + outputStream.writeUInt8(0x00); + + // Architecture + outputStream.writeUInt8(FIT.ARCH_LITTLE_ENDIAN); + + // Global Message Number + outputStream.writeUInt16(this.globalMesgNumber); + + // Field Count + outputStream.writeUInt8(this.fieldDefinitions.length); + + // Field Definitions + this.fieldDefinitions.forEach((fieldDefinition) => { + outputStream.writeUInt8(fieldDefinition.num); + outputStream.writeUInt8(fieldDefinition.size); + outputStream.writeUInt8(fieldDefinition.baseType); + }); + + // Developer Field Definitions + if (this.developerFieldDefinitions.length > 0) { + outputStream.writeUInt8(this.developerFieldDefinitions.length); + + this.developerFieldDefinitions.forEach((developerFieldDefinition) => { + outputStream.writeUInt8(developerFieldDefinition.fieldDefinitionNumber); + outputStream.writeUInt8(developerFieldDefinition.size); + outputStream.writeUInt8(developerFieldDefinition.developerDataIndex); + }); + } + } + + equals(other) { + if (this.globalMessageNumber !== other.globalMessageNumber + || this.fieldDefinitions.length !== other.fieldDefinitions.length + || this.developerFieldDefinitions.length !== other.developerFieldDefinitions.length) { + return false; + } + + // Field Definitions + for (let i = 0; i < this.fieldDefinitions.length; i++) { + const lhs = this.fieldDefinitions[i]; + + if (null == other.fieldDefinitions.find((rhs) => { + return lhs.num === rhs.num + && lhs.size === rhs.size + && lhs.baseType === rhs.baseType; + })) { + return false; + } + } + + // Developer Field Definitions + for (let i = 0; i < this.developerFieldDefinitions.length; i++) { + const lhs = this.developerFieldDefinitions[i]; + + if (null == other.developerFieldDefinitions.find((rhs) => { + return lhs.fieldDefinitionNumber === rhs.fieldDefinitionNumber + && lhs.size === rhs.size + && lhs.developerDataIndex === rhs.developerDataIndex; + })) { + return false; + } + } + + return true; + } + + #fieldSize(value, baseTypeDef) { + const values = Array.isArray(value) ? value : [value,]; + + if (baseTypeDef.type === FIT.BaseType.STRING) { + const size = values.reduce( + (accumulator, currentValue) => { + return accumulator + textEncoder.encode(currentValue).length + 1; + }, + 0 + ); + + return size; + } + + return baseTypeDef.size * values.length; + }; + + /** + * Look up the field description for the key, and validate the required fields. + */ + #fieldDescriptionForKey(fieldDescriptions, key) { + try { + if (fieldDescriptions == null) { + throw new Error("no developer data field descriptions provided", { + cause: { + fieldDescriptions, + }, + }); + } + + const { developerDataIdMesg, fieldDescriptionMesg, } = fieldDescriptions?.[key] ?? {}; + + if (developerDataIdMesg == null || fieldDescriptionMesg == null) { + throw new Error(`could not find a developer field description for key ${key}`); + } + + const errors = []; + + if (fieldDescriptionMesg.fitBaseTypeId == null) { + errors.push(`fieldDescriptionMesg fitBaseTypeId is ${fieldDescriptionMesg.fitBaseTypeId}`); + } + if (fieldDescriptionMesg.fieldDefinitionNumber == null) { + errors.push(`fieldDescriptionMesg fieldDefinitionNumber is ${fieldDescriptionMesg.fieldDefinitionNumber}`); + } + if (fieldDescriptionMesg.developerDataIndex == null) { + errors.push(`fieldDescriptionMesg developerDataIndex is ${fieldDescriptionMesg.developerDataIndex}`); + } + if (developerDataIdMesg.developerDataIndex == null) { + errors.push(`developerDataIdMesg developerDataIndex is ${developerDataIdMesg.developerDataIndex}`); + } + + if (developerDataIdMesg.developerDataIndex !== fieldDescriptionMesg.developerDataIndex) { + errors.push("developerDataIndex values do not match in fieldDescription" + + ` ${developerDataIdMesg.developerDataIndex} != ${fieldDescriptionMesg.developerDataIndex}` + ); + } + + if (errors.length > 0) { + throw new Error("missing or invalid values in the fieldDescription,", { + cause: { + developerDataIdMesg, + fieldDescriptionMesg, + cause: errors, + }, + }); + } + + return { key, developerDataIdMesg, fieldDescriptionMesg, }; + } + catch (error) { + throw new Error( + `invalid field description for key ${key}`, { + cause: { + key, + cause: { + message: error.message, + cause: error.cause, + }, + }, + } + ); + } + } +} + +export default MesgDefinition; diff --git a/src/output-stream.js b/src/output-stream.js new file mode 100644 index 0000000..9c8767f --- /dev/null +++ b/src/output-stream.js @@ -0,0 +1,220 @@ +///////////////////////////////////////////////////////////////////////////////////////////// +// Copyright 2025 Garmin International, Inc. +// Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you +// may not use this file except in compliance with the Flexible and Interoperable Data +// Transfer (FIT) Protocol License. +///////////////////////////////////////////////////////////////////////////////////////////// +// ****WARNING**** This file is auto-generated! Do NOT edit this file. +// Profile Version = 21.161.0Release +// Tag = production/release/21.161.0-0-g58854c0 +///////////////////////////////////////////////////////////////////////////////////////////// + + +import FIT from "./fit.js"; + +const ONE_MEGABYTE = 1048576; +const TEN_MEGABYTES = ONE_MEGABYTE * 10; +const HALF_MEGABYTE = ONE_MEGABYTE / 2; + +class OutputStream { + #arrayBuffer = null; + #dataView = null; + #byteOffset = 0; + #resizeByBytes = 0; + #baseTypeDefinitions = null; + #textEncoder = new TextEncoder(); + + /** + * Creates an OutputStream + * @constructor + * @param {Object=} [options] - Read options (optional) + * @param {Number} [options.initialByteLength=0.5MB] - (optional, default 0.5 MB) + * @param {Number} [options.maxByteLength=2MB] - (optional, default 2 MB) + * @param {Number} [options.resizeByBytes=0.5MB] - (optional, default 0.5 MB) + */ + constructor({ + initialByteLength = HALF_MEGABYTE, + maxByteLength = TEN_MEGABYTES, + resizeByBytes = HALF_MEGABYTE, + } = {}) { + this.#arrayBuffer = new ArrayBuffer(initialByteLength, { maxByteLength, }); + this.#dataView = new DataView(this.#arrayBuffer); + + this.#resizeByBytes = resizeByBytes; + + this.#baseTypeDefinitions = { + [FIT.BaseType.ENUM]: { setValue: this.#dataView.setUint8.bind(this.#dataView), size: 1, mask: 0xFF, }, + [FIT.BaseType.UINT8]: { setValue: this.#dataView.setUint8.bind(this.#dataView), size: 1, mask: 0xFF, }, + [FIT.BaseType.UINT16]: { setValue: this.#dataView.setUint16.bind(this.#dataView), size: 2, mask: 0xFFFF, }, + [FIT.BaseType.UINT32]: { setValue: this.#dataView.setUint32.bind(this.#dataView), size: 4, mask: 0xFFFFFFFF, }, + [FIT.BaseType.UINT64]: { setValue: this.#dataView.setBigUint64.bind(this.#dataView), size: 8, mask: 0xFFFFFFFFFFFFFFFFn, }, + [FIT.BaseType.SINT8]: { setValue: this.#dataView.setInt8.bind(this.#dataView), size: 1, mask: 0xFF, }, + [FIT.BaseType.SINT16]: { setValue: this.#dataView.setInt16.bind(this.#dataView), size: 2, mask: 0xFFFF, }, + [FIT.BaseType.SINT32]: { setValue: this.#dataView.setInt32.bind(this.#dataView), size: 4, mask: 0xFFFFFFFF, }, + [FIT.BaseType.SINT64]: { setValue: this.#dataView.setBigInt64.bind(this.#dataView), size: 8, mask: 0xFFFFFFFFFFFFFFFFn, }, + [FIT.BaseType.FLOAT32]: { setValue: this.#dataView.setFloat32.bind(this.#dataView), size: 4, }, + [FIT.BaseType.FLOAT64]: { setValue: this.#dataView.setFloat64.bind(this.#dataView), size: 8, }, + [FIT.BaseType.UINT8Z]: { setValue: this.#dataView.setUint8.bind(this.#dataView), size: 1, mask: 0xFF, }, + [FIT.BaseType.UINT16Z]: { setValue: this.#dataView.setUint16.bind(this.#dataView), size: 2, mask: 0xFFFF, }, + [FIT.BaseType.UINT32Z]: { setValue: this.#dataView.setUint32.bind(this.#dataView), size: 4, mask: 0xFFFFFFFF, }, + [FIT.BaseType.UINT64Z]: { setValue: this.#dataView.setBigUint64.bind(this.#dataView), size: 8, mask: 0xFFFFFFFFFFFFFFFFn, }, + [FIT.BaseType.BYTE]: { setValue: this.#dataView.setUint8.bind(this.#dataView), size: 1, mask: 0xFF, }, + }; + } + + get length() { + return this.#byteOffset; + } + get uint8Array() { + return new Uint8Array(this.#arrayBuffer.slice(0, this.#byteOffset)); + } + + writeUInt8(value) { + return this.write(value, FIT.BaseType.UINT8); + } + + writeUInt16(value) { + return this.write(value, FIT.BaseType.UINT16); + } + + writeUInt32(value) { + return this.write(value, FIT.BaseType.UINT32); + } + + writeUInt64(value) { + return this.write(value, FIT.BaseType.UINT64); + } + + writeSInt8(value) { + return this.write(value, FIT.BaseType.SINT8); + } + + writeSInt16(value) { + return this.write(value, FIT.BaseType.SINT16); + } + + writeSInt32(value) { + return this.write(value, FIT.BaseType.SINT32); + } + + writeSInt64(value) { + return this.write(value, FIT.BaseType.SINT64); + } + + writeFloat32(value) { + return this.write(value, FIT.BaseType.FLOAT32); + } + + writeFloat64(value) { + return this.write(value, FIT.BaseType.FLOAT64); + } + + writeUInt8z(value) { + return this.write(value, FIT.BaseType.UINT8Z); + } + + writeUInt16z(value) { + return this.write(value, FIT.BaseType.UINT16Z); + } + + writeUInt32z(value) { + return this.write(value, FIT.BaseType.UINT32Z); + } + + writeUInt64z(value) { + return this.write(value, FIT.BaseType.UINT64Z); + } + + writeByte(value) { + return this.write(value, FIT.BaseType.BYTE); + } + + writeString(text) { + const bytes = this.#textEncoder.encode(text); + + this.#resizeIfNeeded(bytes.byteLength); + + const uint8Array = new Uint8Array(this.#arrayBuffer, this.#byteOffset, bytes.byteLength); + uint8Array.set(bytes); + + this.#byteOffset += bytes.byteLength; + + // Add a null terminator + this.writeUInt8(0); + + return this; + } + + write(value, baseType) { + if (baseType === FIT.BaseType.STRING) { + return this.writeString(value); + } + + this.#setValues(baseType, value); + + return; + } + + set(typedarray, targetOffset = 0) { + this.#resizeIfNeeded(typedarray.byteLength + targetOffset); + + const uint8Array = new Uint8Array(this.#arrayBuffer); + uint8Array.set(typedarray, targetOffset); + + this.#byteOffset = Math.max(this.#byteOffset, typedarray.byteLength + targetOffset); + + return this; + } + + [Symbol.iterator]() { + let start = 0; + const end = this.#byteOffset; + const dataView = this.#dataView; + + return { + next() { + if (start < end) { + return { value: dataView.getUint8(start++), done: false, }; + } + else { + return { done: true, }; + } + }, + }; + } + + #setValues(baseType, value) { + const values = Array.isArray(value) ? value : [value,]; + + values.forEach((value) => { + return this.#setValue(baseType, value); + }); + } + + #setValue(baseType, value) { + const def = this.#baseTypeDefinitions[baseType]; + + this.#resizeIfNeeded(def.size); + + const val = def.mask == null ? value : value & def.mask; + + def.setValue(this.#byteOffset, val, true); + this.#byteOffset += def.size; + + return this; + } + + #resizeIfNeeded(byteCount = 1) { + if (this.#arrayBuffer.byteLength - this.#byteOffset >= byteCount) { + return; + } + + if (!this.#arrayBuffer.resizable) { + throw new Error("Can not resize OutputStream. Set a larger initial size."); + } + + this.#arrayBuffer.resize(this.#arrayBuffer.byteLength + Math.max(this.#resizeByBytes, byteCount)); + } +} + +export default OutputStream; diff --git a/src/profile.js b/src/profile.js index f3f714b..275b82b 100644 --- a/src/profile.js +++ b/src/profile.js @@ -1,19 +1,19 @@ ///////////////////////////////////////////////////////////////////////////////////////////// -// Copyright 2024 Garmin International, Inc. +// Copyright 2025 Garmin International, Inc. // Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you // may not use this file except in compliance with the Flexible and Interoperable Data // Transfer (FIT) Protocol License. ///////////////////////////////////////////////////////////////////////////////////////////// // ****WARNING**** This file is auto-generated! Do NOT edit this file. -// Profile Version = 21.158.0Release -// Tag = production/release/21.158.0-0-gc9428aa +// Profile Version = 21.161.0Release +// Tag = production/release/21.161.0-0-g58854c0 ///////////////////////////////////////////////////////////////////////////////////////////// const Profile = { version: { major: 21, - minor: 158, + minor: 161, patch: 0, type: "Release" }, @@ -32,6 +32,7 @@ const Profile = { num: 0, name: "type", type: "file", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -46,6 +47,7 @@ const Profile = { num: 1, name: "manufacturer", type: "manufacturer", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -60,6 +62,7 @@ const Profile = { num: 2, name: "product", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -71,6 +74,7 @@ const Profile = { subFields: [{ name: "faveroProduct", type: "faveroProduct", + baseType: "uint16", array: "", scale: 1, offset: 0, @@ -85,6 +89,7 @@ const Profile = { { name: "garminProduct", type: "garminProduct", + baseType: "uint16", array: "", scale: 1, offset: 0, @@ -105,6 +110,7 @@ const Profile = { num: 3, name: "serialNumber", type: "uint32z", + baseType: "uint32z", array: "false", scale: 1, offset: 0, @@ -119,6 +125,7 @@ const Profile = { num: 4, // Only set for files that are can be created/erased. name: "timeCreated", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -133,6 +140,7 @@ const Profile = { num: 5, // Only set for files that are not created/erased. name: "number", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -147,6 +155,7 @@ const Profile = { num: 8, // Optional free form string to indicate the devices name or model name: "productName", type: "string", + baseType: "string", array: "true", scale: 1, offset: 0, @@ -168,6 +177,7 @@ const Profile = { num: 0, name: "softwareVersion", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -182,6 +192,7 @@ const Profile = { num: 1, name: "hardwareVersion", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -203,6 +214,7 @@ const Profile = { num: 253, // Whole second part of UTC timestamp at the time the system timestamp was recorded. name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -217,6 +229,7 @@ const Profile = { num: 0, // Fractional part of the UTC timestamp at the time the system timestamp was recorded. name: "fractionalTimestamp", type: "uint16", + baseType: "uint16", array: "false", scale: 32768, offset: 0, @@ -231,6 +244,7 @@ const Profile = { num: 1, // Whole second part of the system timestamp name: "systemTimestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -245,6 +259,7 @@ const Profile = { num: 2, // Fractional part of the system timestamp name: "fractionalSystemTimestamp", type: "uint16", + baseType: "uint16", array: "false", scale: 32768, offset: 0, @@ -259,6 +274,7 @@ const Profile = { num: 3, // timestamp epoch expressed in local time used to convert timestamps to local time name: "localTimestamp", type: "localDateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -273,6 +289,7 @@ const Profile = { num: 4, // Millisecond part of the UTC timestamp at the time the system timestamp was recorded. name: "timestampMs", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -287,6 +304,7 @@ const Profile = { num: 5, // Millisecond part of the system timestamp name: "systemTimestampMs", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -308,6 +326,7 @@ const Profile = { num: 254, name: "messageIndex", type: "messageIndex", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -322,6 +341,7 @@ const Profile = { num: 3, name: "version", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -336,6 +356,7 @@ const Profile = { num: 5, name: "partNumber", type: "string", + baseType: "string", array: "true", scale: 1, offset: 0, @@ -357,6 +378,7 @@ const Profile = { num: 0, name: "manufacturer", type: "manufacturer", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -371,6 +393,7 @@ const Profile = { num: 1, name: "product", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -382,6 +405,7 @@ const Profile = { subFields: [{ name: "faveroProduct", type: "faveroProduct", + baseType: "uint16", array: "", scale: 1, offset: 0, @@ -396,6 +420,7 @@ const Profile = { { name: "garminProduct", type: "garminProduct", + baseType: "uint16", array: "", scale: 1, offset: 0, @@ -423,6 +448,7 @@ const Profile = { num: 0, // Use language_bits_x types where x is index of array. name: "languages", type: "uint8z", + baseType: "uint8z", array: "true", scale: 1, offset: 0, @@ -437,6 +463,7 @@ const Profile = { num: 1, // Use sport_bits_x types where x is index of array. name: "sports", type: "sportBits0", + baseType: "uint8z", array: "true", scale: 1, offset: 0, @@ -451,6 +478,7 @@ const Profile = { num: 21, name: "workoutsSupported", type: "workoutCapabilities", + baseType: "uint32z", array: "false", scale: 1, offset: 0, @@ -465,6 +493,7 @@ const Profile = { num: 23, name: "connectivitySupported", type: "connectivityCapabilities", + baseType: "uint32z", array: "false", scale: 1, offset: 0, @@ -486,6 +515,7 @@ const Profile = { num: 254, name: "messageIndex", type: "messageIndex", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -500,6 +530,7 @@ const Profile = { num: 0, name: "type", type: "file", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -514,6 +545,7 @@ const Profile = { num: 1, name: "flags", type: "fileFlags", + baseType: "uint8z", array: "false", scale: 1, offset: 0, @@ -528,6 +560,7 @@ const Profile = { num: 2, name: "directory", type: "string", + baseType: "string", array: "true", scale: 1, offset: 0, @@ -542,6 +575,7 @@ const Profile = { num: 3, name: "maxCount", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -556,6 +590,7 @@ const Profile = { num: 4, name: "maxSize", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -577,6 +612,7 @@ const Profile = { num: 254, name: "messageIndex", type: "messageIndex", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -591,6 +627,7 @@ const Profile = { num: 0, name: "file", type: "file", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -605,6 +642,7 @@ const Profile = { num: 1, name: "mesgNum", type: "mesgNum", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -619,6 +657,7 @@ const Profile = { num: 2, name: "countType", type: "mesgCount", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -633,6 +672,7 @@ const Profile = { num: 3, name: "count", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -644,6 +684,7 @@ const Profile = { subFields: [{ name: "numPerFile", type: "uint16", + baseType: "uint16", array: "", scale: 1, offset: 0, @@ -658,6 +699,7 @@ const Profile = { { name: "maxPerFile", type: "uint16", + baseType: "uint16", array: "", scale: 1, offset: 0, @@ -672,6 +714,7 @@ const Profile = { { name: "maxPerFileType", type: "uint16", + baseType: "uint16", array: "", scale: 1, offset: 0, @@ -696,6 +739,7 @@ const Profile = { num: 254, name: "messageIndex", type: "messageIndex", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -710,6 +754,7 @@ const Profile = { num: 0, name: "file", type: "file", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -724,6 +769,7 @@ const Profile = { num: 1, name: "mesgNum", type: "mesgNum", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -738,6 +784,7 @@ const Profile = { num: 2, name: "fieldNum", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -752,6 +799,7 @@ const Profile = { num: 3, name: "count", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -773,6 +821,7 @@ const Profile = { num: 0, // Index into time zone arrays. name: "activeTimeZone", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -787,6 +836,7 @@ const Profile = { num: 1, // Offset from system time. Required to convert timestamp from system time to UTC. name: "utcOffset", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -801,6 +851,7 @@ const Profile = { num: 2, // Offset from system time. name: "timeOffset", type: "uint32", + baseType: "uint32", array: "true", scale: 1, offset: 0, @@ -815,6 +866,7 @@ const Profile = { num: 4, // Display mode for the time name: "timeMode", type: "timeMode", + baseType: "enum", array: "true", scale: 1, offset: 0, @@ -829,6 +881,7 @@ const Profile = { num: 5, // timezone offset in 1/4 hour increments name: "timeZoneOffset", type: "sint8", + baseType: "sint8", array: "true", scale: 4, offset: 0, @@ -843,6 +896,7 @@ const Profile = { num: 12, // Mode for backlight name: "backlightMode", type: "backlightMode", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -857,6 +911,7 @@ const Profile = { num: 36, // Enabled state of the activity tracker functionality name: "activityTrackerEnabled", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -871,6 +926,7 @@ const Profile = { num: 39, // UTC timestamp used to set the devices clock and date name: "clockTime", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -885,6 +941,7 @@ const Profile = { num: 40, // Bitfield to configure enabled screens for each supported loop name: "pagesEnabled", type: "uint16", + baseType: "uint16", array: "true", scale: 1, offset: 0, @@ -899,6 +956,7 @@ const Profile = { num: 46, // Enabled state of the move alert name: "moveAlertEnabled", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -913,6 +971,7 @@ const Profile = { num: 47, // Display mode for the date name: "dateMode", type: "dateMode", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -927,6 +986,7 @@ const Profile = { num: 55, name: "displayOrientation", type: "displayOrientation", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -941,6 +1001,7 @@ const Profile = { num: 56, name: "mountingSide", type: "side", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -955,6 +1016,7 @@ const Profile = { num: 57, // Bitfield to indicate one page as default for each supported loop name: "defaultPage", type: "uint16", + baseType: "uint16", array: "true", scale: 1, offset: 0, @@ -969,6 +1031,7 @@ const Profile = { num: 58, // Minimum steps before an autosync can occur name: "autosyncMinSteps", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -983,6 +1046,7 @@ const Profile = { num: 59, // Minimum minutes before an autosync can occur name: "autosyncMinTime", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -997,6 +1061,7 @@ const Profile = { num: 80, // Enable auto-detect setting for the lactate threshold feature. name: "lactateThresholdAutodetectEnabled", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -1011,6 +1076,7 @@ const Profile = { num: 86, // Automatically upload using BLE name: "bleAutoUploadEnabled", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -1025,6 +1091,7 @@ const Profile = { num: 89, // Helps to conserve battery by changing modes name: "autoSyncFrequency", type: "autoSyncFrequency", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -1039,6 +1106,7 @@ const Profile = { num: 90, // Allows setting specific activities auto-activity detect enabled/disabled settings name: "autoActivityDetect", type: "autoActivityDetect", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -1053,6 +1121,7 @@ const Profile = { num: 94, // Number of screens configured to display name: "numberOfScreens", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -1067,6 +1136,7 @@ const Profile = { num: 95, // Smart Notification display orientation name: "smartNotificationDisplayOrientation", type: "displayOrientation", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -1081,6 +1151,7 @@ const Profile = { num: 134, name: "tapInterface", type: "switch", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -1095,6 +1166,7 @@ const Profile = { num: 174, // Used to hold the tap threshold setting name: "tapSensitivity", type: "tapSensitivity", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -1116,6 +1188,7 @@ const Profile = { num: 254, name: "messageIndex", type: "messageIndex", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -1130,6 +1203,7 @@ const Profile = { num: 0, // Used for Morning Report greeting name: "friendlyName", type: "string", + baseType: "string", array: "true", scale: 1, offset: 0, @@ -1144,6 +1218,7 @@ const Profile = { num: 1, name: "gender", type: "gender", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -1158,6 +1233,7 @@ const Profile = { num: 2, name: "age", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -1172,6 +1248,7 @@ const Profile = { num: 3, name: "height", type: "uint8", + baseType: "uint8", array: "false", scale: 100, offset: 0, @@ -1186,6 +1263,7 @@ const Profile = { num: 4, name: "weight", type: "uint16", + baseType: "uint16", array: "false", scale: 10, offset: 0, @@ -1200,6 +1278,7 @@ const Profile = { num: 5, name: "language", type: "language", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -1214,6 +1293,7 @@ const Profile = { num: 6, name: "elevSetting", type: "displayMeasure", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -1228,6 +1308,7 @@ const Profile = { num: 7, name: "weightSetting", type: "displayMeasure", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -1242,6 +1323,7 @@ const Profile = { num: 8, name: "restingHeartRate", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -1256,6 +1338,7 @@ const Profile = { num: 9, name: "defaultMaxRunningHeartRate", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -1270,6 +1353,7 @@ const Profile = { num: 10, name: "defaultMaxBikingHeartRate", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -1284,6 +1368,7 @@ const Profile = { num: 11, name: "defaultMaxHeartRate", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -1298,6 +1383,7 @@ const Profile = { num: 12, name: "hrSetting", type: "displayHeart", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -1312,6 +1398,7 @@ const Profile = { num: 13, name: "speedSetting", type: "displayMeasure", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -1326,6 +1413,7 @@ const Profile = { num: 14, name: "distSetting", type: "displayMeasure", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -1340,6 +1428,7 @@ const Profile = { num: 16, name: "powerSetting", type: "displayPower", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -1354,6 +1443,7 @@ const Profile = { num: 17, name: "activityClass", type: "activityClass", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -1368,6 +1458,7 @@ const Profile = { num: 18, name: "positionSetting", type: "displayPosition", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -1382,6 +1473,7 @@ const Profile = { num: 21, name: "temperatureSetting", type: "displayMeasure", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -1396,6 +1488,7 @@ const Profile = { num: 22, name: "localId", type: "userLocalId", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -1410,6 +1503,7 @@ const Profile = { num: 23, name: "globalId", type: "byte", + baseType: "byte", array: "true", scale: 1, offset: 0, @@ -1424,6 +1518,7 @@ const Profile = { num: 28, // Typical wake time name: "wakeTime", type: "localtimeIntoDay", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -1438,6 +1533,7 @@ const Profile = { num: 29, // Typical bed time name: "sleepTime", type: "localtimeIntoDay", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -1452,6 +1548,7 @@ const Profile = { num: 30, name: "heightSetting", type: "displayMeasure", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -1466,6 +1563,7 @@ const Profile = { num: 31, // User defined running step length set to 0 for auto length name: "userRunningStepLength", type: "uint16", + baseType: "uint16", array: "false", scale: 1000, offset: 0, @@ -1480,6 +1578,7 @@ const Profile = { num: 32, // User defined walking step length set to 0 for auto length name: "userWalkingStepLength", type: "uint16", + baseType: "uint16", array: "false", scale: 1000, offset: 0, @@ -1494,6 +1593,7 @@ const Profile = { num: 47, name: "depthSetting", type: "displayMeasure", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -1508,6 +1608,7 @@ const Profile = { num: 49, name: "diveCount", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -1529,6 +1630,7 @@ const Profile = { num: 254, name: "messageIndex", type: "messageIndex", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -1543,6 +1645,7 @@ const Profile = { num: 0, name: "enabled", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -1557,6 +1660,7 @@ const Profile = { num: 1, name: "hrmAntId", type: "uint16z", + baseType: "uint16z", array: "false", scale: 1, offset: 0, @@ -1571,6 +1675,7 @@ const Profile = { num: 2, name: "logHrv", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -1585,6 +1690,7 @@ const Profile = { num: 3, name: "hrmAntIdTransType", type: "uint8z", + baseType: "uint8z", array: "false", scale: 1, offset: 0, @@ -1606,6 +1712,7 @@ const Profile = { num: 254, name: "messageIndex", type: "messageIndex", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -1620,6 +1727,7 @@ const Profile = { num: 0, name: "enabled", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -1634,6 +1742,7 @@ const Profile = { num: 1, name: "sdmAntId", type: "uint16z", + baseType: "uint16z", array: "false", scale: 1, offset: 0, @@ -1648,6 +1757,7 @@ const Profile = { num: 2, name: "sdmCalFactor", type: "uint16", + baseType: "uint16", array: "false", scale: 10, offset: 0, @@ -1662,6 +1772,7 @@ const Profile = { num: 3, name: "odometer", type: "uint32", + baseType: "uint32", array: "false", scale: 100, offset: 0, @@ -1676,6 +1787,7 @@ const Profile = { num: 4, // Use footpod for speed source instead of GPS name: "speedSource", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -1690,6 +1802,7 @@ const Profile = { num: 5, name: "sdmAntIdTransType", type: "uint8z", + baseType: "uint8z", array: "false", scale: 1, offset: 0, @@ -1704,6 +1817,7 @@ const Profile = { num: 7, // Rollover counter that can be used to extend the odometer name: "odometerRollover", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -1725,6 +1839,7 @@ const Profile = { num: 254, name: "messageIndex", type: "messageIndex", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -1739,6 +1854,7 @@ const Profile = { num: 0, name: "name", type: "string", + baseType: "string", array: "true", scale: 1, offset: 0, @@ -1753,6 +1869,7 @@ const Profile = { num: 1, name: "sport", type: "sport", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -1767,6 +1884,7 @@ const Profile = { num: 2, name: "subSport", type: "subSport", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -1781,6 +1899,7 @@ const Profile = { num: 3, name: "odometer", type: "uint32", + baseType: "uint32", array: "false", scale: 100, offset: 0, @@ -1795,6 +1914,7 @@ const Profile = { num: 4, name: "bikeSpdAntId", type: "uint16z", + baseType: "uint16z", array: "false", scale: 1, offset: 0, @@ -1809,6 +1929,7 @@ const Profile = { num: 5, name: "bikeCadAntId", type: "uint16z", + baseType: "uint16z", array: "false", scale: 1, offset: 0, @@ -1823,6 +1944,7 @@ const Profile = { num: 6, name: "bikeSpdcadAntId", type: "uint16z", + baseType: "uint16z", array: "false", scale: 1, offset: 0, @@ -1837,6 +1959,7 @@ const Profile = { num: 7, name: "bikePowerAntId", type: "uint16z", + baseType: "uint16z", array: "false", scale: 1, offset: 0, @@ -1851,6 +1974,7 @@ const Profile = { num: 8, name: "customWheelsize", type: "uint16", + baseType: "uint16", array: "false", scale: 1000, offset: 0, @@ -1865,6 +1989,7 @@ const Profile = { num: 9, name: "autoWheelsize", type: "uint16", + baseType: "uint16", array: "false", scale: 1000, offset: 0, @@ -1879,6 +2004,7 @@ const Profile = { num: 10, name: "bikeWeight", type: "uint16", + baseType: "uint16", array: "false", scale: 10, offset: 0, @@ -1893,6 +2019,7 @@ const Profile = { num: 11, name: "powerCalFactor", type: "uint16", + baseType: "uint16", array: "false", scale: 10, offset: 0, @@ -1907,6 +2034,7 @@ const Profile = { num: 12, name: "autoWheelCal", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -1921,6 +2049,7 @@ const Profile = { num: 13, name: "autoPowerZero", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -1935,6 +2064,7 @@ const Profile = { num: 14, name: "id", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -1949,6 +2079,7 @@ const Profile = { num: 15, name: "spdEnabled", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -1963,6 +2094,7 @@ const Profile = { num: 16, name: "cadEnabled", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -1977,6 +2109,7 @@ const Profile = { num: 17, name: "spdcadEnabled", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -1991,6 +2124,7 @@ const Profile = { num: 18, name: "powerEnabled", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -2005,6 +2139,7 @@ const Profile = { num: 19, name: "crankLength", type: "uint8", + baseType: "uint8", array: "false", scale: 2, offset: -110, @@ -2019,6 +2154,7 @@ const Profile = { num: 20, name: "enabled", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -2033,6 +2169,7 @@ const Profile = { num: 21, name: "bikeSpdAntIdTransType", type: "uint8z", + baseType: "uint8z", array: "false", scale: 1, offset: 0, @@ -2047,6 +2184,7 @@ const Profile = { num: 22, name: "bikeCadAntIdTransType", type: "uint8z", + baseType: "uint8z", array: "false", scale: 1, offset: 0, @@ -2061,6 +2199,7 @@ const Profile = { num: 23, name: "bikeSpdcadAntIdTransType", type: "uint8z", + baseType: "uint8z", array: "false", scale: 1, offset: 0, @@ -2075,6 +2214,7 @@ const Profile = { num: 24, name: "bikePowerAntIdTransType", type: "uint8z", + baseType: "uint8z", array: "false", scale: 1, offset: 0, @@ -2089,6 +2229,7 @@ const Profile = { num: 37, // Rollover counter that can be used to extend the odometer name: "odometerRollover", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -2103,6 +2244,7 @@ const Profile = { num: 38, // Number of front gears name: "frontGearNum", type: "uint8z", + baseType: "uint8z", array: "false", scale: 1, offset: 0, @@ -2117,6 +2259,7 @@ const Profile = { num: 39, // Number of teeth on each gear 0 is innermost name: "frontGear", type: "uint8z", + baseType: "uint8z", array: "true", scale: 1, offset: 0, @@ -2131,6 +2274,7 @@ const Profile = { num: 40, // Number of rear gears name: "rearGearNum", type: "uint8z", + baseType: "uint8z", array: "false", scale: 1, offset: 0, @@ -2145,6 +2289,7 @@ const Profile = { num: 41, // Number of teeth on each gear 0 is innermost name: "rearGear", type: "uint8z", + baseType: "uint8z", array: "true", scale: 1, offset: 0, @@ -2159,6 +2304,7 @@ const Profile = { num: 44, name: "shimanoDi2Enabled", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -2180,6 +2326,7 @@ const Profile = { num: 0, // Use Bluetooth for connectivity features name: "bluetoothEnabled", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -2194,6 +2341,7 @@ const Profile = { num: 1, // Use Bluetooth Low Energy for connectivity features name: "bluetoothLeEnabled", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -2208,6 +2356,7 @@ const Profile = { num: 2, // Use ANT for connectivity features name: "antEnabled", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -2222,6 +2371,7 @@ const Profile = { num: 3, name: "name", type: "string", + baseType: "string", array: "true", scale: 1, offset: 0, @@ -2236,6 +2386,7 @@ const Profile = { num: 4, name: "liveTrackingEnabled", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -2250,6 +2401,7 @@ const Profile = { num: 5, name: "weatherConditionsEnabled", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -2264,6 +2416,7 @@ const Profile = { num: 6, name: "weatherAlertsEnabled", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -2278,6 +2431,7 @@ const Profile = { num: 7, name: "autoActivityUploadEnabled", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -2292,6 +2446,7 @@ const Profile = { num: 8, name: "courseDownloadEnabled", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -2306,6 +2461,7 @@ const Profile = { num: 9, name: "workoutDownloadEnabled", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -2320,6 +2476,7 @@ const Profile = { num: 10, name: "gpsEphemerisDownloadEnabled", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -2334,6 +2491,7 @@ const Profile = { num: 11, name: "incidentDetectionEnabled", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -2348,6 +2506,7 @@ const Profile = { num: 12, name: "grouptrackEnabled", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -2369,6 +2528,7 @@ const Profile = { num: 254, name: "messageIndex", type: "messageIndex", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -2383,6 +2543,7 @@ const Profile = { num: 0, name: "mode", type: "watchfaceMode", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -2397,6 +2558,7 @@ const Profile = { num: 1, name: "layout", type: "byte", + baseType: "byte", array: "false", scale: 1, offset: 0, @@ -2408,6 +2570,7 @@ const Profile = { subFields: [{ name: "digitalLayout", type: "digitalWatchfaceLayout", + baseType: "enum", array: "", scale: 1, offset: 0, @@ -2422,6 +2585,7 @@ const Profile = { { name: "analogLayout", type: "analogWatchfaceLayout", + baseType: "enum", array: "", scale: 1, offset: 0, @@ -2446,6 +2610,7 @@ const Profile = { num: 253, name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -2460,6 +2625,7 @@ const Profile = { num: 0, name: "enabled", type: "switch", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -2481,6 +2647,7 @@ const Profile = { num: 253, name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -2495,6 +2662,7 @@ const Profile = { num: 0, name: "referenceMesg", type: "mesgNum", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -2509,6 +2677,7 @@ const Profile = { num: 1, name: "referenceIndex", type: "messageIndex", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -2523,6 +2692,7 @@ const Profile = { num: 2, name: "timeInHrZone", type: "uint32", + baseType: "uint32", array: "true", scale: 1000, offset: 0, @@ -2537,6 +2707,7 @@ const Profile = { num: 3, name: "timeInSpeedZone", type: "uint32", + baseType: "uint32", array: "true", scale: 1000, offset: 0, @@ -2551,6 +2722,7 @@ const Profile = { num: 4, name: "timeInCadenceZone", type: "uint32", + baseType: "uint32", array: "true", scale: 1000, offset: 0, @@ -2565,6 +2737,7 @@ const Profile = { num: 5, name: "timeInPowerZone", type: "uint32", + baseType: "uint32", array: "true", scale: 1000, offset: 0, @@ -2579,6 +2752,7 @@ const Profile = { num: 6, name: "hrZoneHighBoundary", type: "uint8", + baseType: "uint8", array: "true", scale: 1, offset: 0, @@ -2593,6 +2767,7 @@ const Profile = { num: 7, name: "speedZoneHighBoundary", type: "uint16", + baseType: "uint16", array: "true", scale: 1000, offset: 0, @@ -2607,6 +2782,7 @@ const Profile = { num: 8, name: "cadenceZoneHighBondary", type: "uint8", + baseType: "uint8", array: "true", scale: 1, offset: 0, @@ -2621,6 +2797,7 @@ const Profile = { num: 9, name: "powerZoneHighBoundary", type: "uint16", + baseType: "uint16", array: "true", scale: 1, offset: 0, @@ -2635,6 +2812,7 @@ const Profile = { num: 10, name: "hrCalcType", type: "hrZoneCalc", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -2649,6 +2827,7 @@ const Profile = { num: 11, name: "maxHeartRate", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -2663,6 +2842,7 @@ const Profile = { num: 12, name: "restingHeartRate", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -2677,6 +2857,7 @@ const Profile = { num: 13, name: "thresholdHeartRate", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -2691,6 +2872,7 @@ const Profile = { num: 14, name: "pwrCalcType", type: "pwrZoneCalc", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -2705,6 +2887,7 @@ const Profile = { num: 15, name: "functionalThresholdPower", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -2726,6 +2909,7 @@ const Profile = { num: 1, name: "maxHeartRate", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -2740,6 +2924,7 @@ const Profile = { num: 2, name: "thresholdHeartRate", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -2754,6 +2939,7 @@ const Profile = { num: 3, name: "functionalThresholdPower", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -2768,6 +2954,7 @@ const Profile = { num: 5, name: "hrCalcType", type: "hrZoneCalc", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -2782,6 +2969,7 @@ const Profile = { num: 7, name: "pwrCalcType", type: "pwrZoneCalc", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -2803,6 +2991,7 @@ const Profile = { num: 0, name: "sport", type: "sport", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -2817,6 +3006,7 @@ const Profile = { num: 1, name: "subSport", type: "subSport", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -2831,6 +3021,7 @@ const Profile = { num: 3, name: "name", type: "string", + baseType: "string", array: "true", scale: 1, offset: 0, @@ -2852,6 +3043,7 @@ const Profile = { num: 254, name: "messageIndex", type: "messageIndex", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -2866,6 +3058,7 @@ const Profile = { num: 1, name: "highBpm", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -2880,6 +3073,7 @@ const Profile = { num: 2, name: "name", type: "string", + baseType: "string", array: "true", scale: 1, offset: 0, @@ -2901,6 +3095,7 @@ const Profile = { num: 254, name: "messageIndex", type: "messageIndex", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -2915,6 +3110,7 @@ const Profile = { num: 0, name: "highValue", type: "uint16", + baseType: "uint16", array: "false", scale: 1000, offset: 0, @@ -2929,6 +3125,7 @@ const Profile = { num: 1, name: "name", type: "string", + baseType: "string", array: "true", scale: 1, offset: 0, @@ -2950,6 +3147,7 @@ const Profile = { num: 254, name: "messageIndex", type: "messageIndex", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -2964,6 +3162,7 @@ const Profile = { num: 0, name: "highValue", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -2978,6 +3177,7 @@ const Profile = { num: 1, name: "name", type: "string", + baseType: "string", array: "true", scale: 1, offset: 0, @@ -2999,6 +3199,7 @@ const Profile = { num: 254, name: "messageIndex", type: "messageIndex", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -3013,6 +3214,7 @@ const Profile = { num: 1, name: "highValue", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -3027,6 +3229,7 @@ const Profile = { num: 2, name: "name", type: "string", + baseType: "string", array: "true", scale: 1, offset: 0, @@ -3048,6 +3251,7 @@ const Profile = { num: 254, name: "messageIndex", type: "messageIndex", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -3062,6 +3266,7 @@ const Profile = { num: 1, name: "highBpm", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -3076,6 +3281,7 @@ const Profile = { num: 2, name: "calories", type: "uint16", + baseType: "uint16", array: "false", scale: 10, offset: 0, @@ -3090,6 +3296,7 @@ const Profile = { num: 3, name: "fatCalories", type: "uint8", + baseType: "uint8", array: "false", scale: 10, offset: 0, @@ -3111,6 +3318,7 @@ const Profile = { num: 253, name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -3125,6 +3333,7 @@ const Profile = { num: 254, name: "messageIndex", type: "messageIndex", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -3139,6 +3348,7 @@ const Profile = { num: 0, name: "name", type: "string", + baseType: "string", array: "true", scale: 1, offset: 0, @@ -3153,6 +3363,7 @@ const Profile = { num: 1, name: "model", type: "tissueModelType", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -3167,6 +3378,7 @@ const Profile = { num: 2, name: "gfLow", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -3181,6 +3393,7 @@ const Profile = { num: 3, name: "gfHigh", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -3195,6 +3408,7 @@ const Profile = { num: 4, name: "waterType", type: "waterType", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -3209,6 +3423,7 @@ const Profile = { num: 5, // Fresh water is usually 1000; salt water is usually 1025 name: "waterDensity", type: "float32", + baseType: "float32", array: "false", scale: 1, offset: 0, @@ -3223,6 +3438,7 @@ const Profile = { num: 6, // Typically 1.40 name: "po2Warn", type: "uint8", + baseType: "uint8", array: "false", scale: 100, offset: 0, @@ -3237,6 +3453,7 @@ const Profile = { num: 7, // Typically 1.60 name: "po2Critical", type: "uint8", + baseType: "uint8", array: "false", scale: 100, offset: 0, @@ -3251,6 +3468,7 @@ const Profile = { num: 8, name: "po2Deco", type: "uint8", + baseType: "uint8", array: "false", scale: 100, offset: 0, @@ -3265,6 +3483,7 @@ const Profile = { num: 9, name: "safetyStopEnabled", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -3279,6 +3498,7 @@ const Profile = { num: 10, name: "bottomDepth", type: "float32", + baseType: "float32", array: "false", scale: 1, offset: 0, @@ -3293,6 +3513,7 @@ const Profile = { num: 11, name: "bottomTime", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -3307,6 +3528,7 @@ const Profile = { num: 12, name: "apneaCountdownEnabled", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -3321,6 +3543,7 @@ const Profile = { num: 13, name: "apneaCountdownTime", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -3335,6 +3558,7 @@ const Profile = { num: 14, name: "backlightMode", type: "diveBacklightMode", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -3349,6 +3573,7 @@ const Profile = { num: 15, name: "backlightBrightness", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -3363,6 +3588,7 @@ const Profile = { num: 16, name: "backlightTimeout", type: "backlightTimeout", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -3377,6 +3603,7 @@ const Profile = { num: 17, // Time between surfacing and ending the activity name: "repeatDiveInterval", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -3391,6 +3618,7 @@ const Profile = { num: 18, // Time at safety stop (if enabled) name: "safetyStopTime", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -3405,6 +3633,7 @@ const Profile = { num: 19, name: "heartRateSourceType", type: "sourceType", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -3419,6 +3648,7 @@ const Profile = { num: 20, name: "heartRateSource", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -3430,6 +3660,7 @@ const Profile = { subFields: [{ name: "heartRateAntplusDeviceType", type: "antplusDeviceType", + baseType: "uint8", array: "", scale: 1, offset: 0, @@ -3444,6 +3675,7 @@ const Profile = { { name: "heartRateLocalDeviceType", type: "localDeviceType", + baseType: "uint8", array: "", scale: 1, offset: 0, @@ -3461,6 +3693,7 @@ const Profile = { num: 21, // Index of travel dive_gas message name: "travelGas", type: "messageIndex", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -3475,6 +3708,7 @@ const Profile = { num: 22, // If low PO2 should be switched to automatically name: "ccrLowSetpointSwitchMode", type: "ccrSetpointSwitchMode", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -3489,6 +3723,7 @@ const Profile = { num: 23, // Target PO2 when using low setpoint name: "ccrLowSetpoint", type: "uint8", + baseType: "uint8", array: "false", scale: 100, offset: 0, @@ -3503,6 +3738,7 @@ const Profile = { num: 24, // Depth to switch to low setpoint in automatic mode name: "ccrLowSetpointDepth", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -3517,6 +3753,7 @@ const Profile = { num: 25, // If high PO2 should be switched to automatically name: "ccrHighSetpointSwitchMode", type: "ccrSetpointSwitchMode", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -3531,6 +3768,7 @@ const Profile = { num: 26, // Target PO2 when using high setpoint name: "ccrHighSetpoint", type: "uint8", + baseType: "uint8", array: "false", scale: 100, offset: 0, @@ -3545,6 +3783,7 @@ const Profile = { num: 27, // Depth to switch to high setpoint in automatic mode name: "ccrHighSetpointDepth", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -3559,6 +3798,7 @@ const Profile = { num: 29, // Type of gas consumption rate to display. Some values are only valid if tank volume is known. name: "gasConsumptionDisplay", type: "gasConsumptionRateType", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -3573,6 +3813,7 @@ const Profile = { num: 30, // Indicates whether the up key is enabled during dives name: "upKeyEnabled", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -3587,6 +3828,7 @@ const Profile = { num: 35, // Sounds and vibration enabled or disabled in-dive name: "diveSounds", type: "tone", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -3601,6 +3843,7 @@ const Profile = { num: 36, // Usually 1.0/1.5/2.0 representing 3/4.5/6m or 10/15/20ft name: "lastStopMultiple", type: "uint8", + baseType: "uint8", array: "false", scale: 10, offset: 0, @@ -3615,6 +3858,7 @@ const Profile = { num: 37, // Indicates which guidelines to use for no-fly surface interval. name: "noFlyTimeMode", type: "noFlyTimeMode", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -3636,6 +3880,7 @@ const Profile = { num: 254, // Index of the alarm name: "messageIndex", type: "messageIndex", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -3650,6 +3895,7 @@ const Profile = { num: 0, // Depth setting (m) for depth type alarms name: "depth", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -3664,6 +3910,7 @@ const Profile = { num: 1, // Time setting (s) for time type alarms name: "time", type: "sint32", + baseType: "sint32", array: "false", scale: 1, offset: 0, @@ -3678,6 +3925,7 @@ const Profile = { num: 2, // Enablement flag name: "enabled", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -3692,6 +3940,7 @@ const Profile = { num: 3, // Alarm type setting name: "alarmType", type: "diveAlarmType", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -3706,6 +3955,7 @@ const Profile = { num: 4, // Tone and Vibe setting for the alarm name: "sound", type: "tone", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -3720,6 +3970,7 @@ const Profile = { num: 5, // Dive types the alarm will trigger on name: "diveTypes", type: "subSport", + baseType: "enum", array: "true", scale: 1, offset: 0, @@ -3734,6 +3985,7 @@ const Profile = { num: 6, // Alarm ID name: "id", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -3748,6 +4000,7 @@ const Profile = { num: 7, // Show a visible pop-up for this alarm name: "popupEnabled", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -3762,6 +4015,7 @@ const Profile = { num: 8, // Trigger the alarm on descent name: "triggerOnDescent", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -3776,6 +4030,7 @@ const Profile = { num: 9, // Trigger the alarm on ascent name: "triggerOnAscent", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -3790,6 +4045,7 @@ const Profile = { num: 10, // Repeat alarm each time threshold is crossed? name: "repeating", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -3804,6 +4060,7 @@ const Profile = { num: 11, // Ascent/descent rate (mps) setting for speed type alarms name: "speed", type: "sint32", + baseType: "sint32", array: "false", scale: 1000, offset: 0, @@ -3825,6 +4082,7 @@ const Profile = { num: 254, // Index of the alarm name: "messageIndex", type: "messageIndex", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -3839,6 +4097,7 @@ const Profile = { num: 0, // Depth setting (m) for depth type alarms name: "depth", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -3853,6 +4112,7 @@ const Profile = { num: 1, // Time setting (s) for time type alarms name: "time", type: "sint32", + baseType: "sint32", array: "false", scale: 1, offset: 0, @@ -3867,6 +4127,7 @@ const Profile = { num: 2, // Enablement flag name: "enabled", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -3881,6 +4142,7 @@ const Profile = { num: 3, // Alarm type setting name: "alarmType", type: "diveAlarmType", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -3895,6 +4157,7 @@ const Profile = { num: 4, // Tone and Vibe setting for the alarm. name: "sound", type: "tone", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -3909,6 +4172,7 @@ const Profile = { num: 5, // Dive types the alarm will trigger on name: "diveTypes", type: "subSport", + baseType: "enum", array: "true", scale: 1, offset: 0, @@ -3923,6 +4187,7 @@ const Profile = { num: 6, // Alarm ID name: "id", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -3937,6 +4202,7 @@ const Profile = { num: 7, // Show a visible pop-up for this alarm name: "popupEnabled", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -3951,6 +4217,7 @@ const Profile = { num: 8, // Trigger the alarm on descent name: "triggerOnDescent", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -3965,6 +4232,7 @@ const Profile = { num: 9, // Trigger the alarm on ascent name: "triggerOnAscent", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -3979,6 +4247,7 @@ const Profile = { num: 10, // Repeat alarm each time threshold is crossed? name: "repeating", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -3993,6 +4262,7 @@ const Profile = { num: 11, // Ascent/descent rate (mps) setting for speed type alarms name: "speed", type: "sint32", + baseType: "sint32", array: "false", scale: 1000, offset: 0, @@ -4014,6 +4284,7 @@ const Profile = { num: 254, name: "messageIndex", type: "messageIndex", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -4028,6 +4299,7 @@ const Profile = { num: 0, name: "heliumContent", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -4042,6 +4314,7 @@ const Profile = { num: 1, name: "oxygenContent", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -4056,6 +4329,7 @@ const Profile = { num: 2, name: "status", type: "diveGasStatus", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -4070,6 +4344,7 @@ const Profile = { num: 3, name: "mode", type: "diveGasMode", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -4091,6 +4366,7 @@ const Profile = { num: 254, name: "messageIndex", type: "messageIndex", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -4105,6 +4381,7 @@ const Profile = { num: 0, name: "sport", type: "sport", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -4119,6 +4396,7 @@ const Profile = { num: 1, name: "subSport", type: "subSport", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -4133,6 +4411,7 @@ const Profile = { num: 2, name: "startDate", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -4147,6 +4426,7 @@ const Profile = { num: 3, name: "endDate", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -4161,6 +4441,7 @@ const Profile = { num: 4, name: "type", type: "goal", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -4175,6 +4456,7 @@ const Profile = { num: 5, name: "value", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -4189,6 +4471,7 @@ const Profile = { num: 6, name: "repeat", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -4203,6 +4486,7 @@ const Profile = { num: 7, name: "targetValue", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -4217,6 +4501,7 @@ const Profile = { num: 8, name: "recurrence", type: "goalRecurrence", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -4231,6 +4516,7 @@ const Profile = { num: 9, name: "recurrenceValue", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -4245,6 +4531,7 @@ const Profile = { num: 10, name: "enabled", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -4259,6 +4546,7 @@ const Profile = { num: 11, name: "source", type: "goalSource", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -4280,6 +4568,7 @@ const Profile = { num: 253, name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -4294,6 +4583,7 @@ const Profile = { num: 0, // Exclude pauses name: "totalTimerTime", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -4308,6 +4598,7 @@ const Profile = { num: 1, name: "numSessions", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -4322,6 +4613,7 @@ const Profile = { num: 2, name: "type", type: "activity", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -4336,6 +4628,7 @@ const Profile = { num: 3, name: "event", type: "event", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -4350,6 +4643,7 @@ const Profile = { num: 4, name: "eventType", type: "eventType", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -4364,6 +4658,7 @@ const Profile = { num: 5, // timestamp epoch expressed in local time, used to convert activity timestamps to local time name: "localTimestamp", type: "localDateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -4378,6 +4673,7 @@ const Profile = { num: 6, name: "eventGroup", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -4399,6 +4695,7 @@ const Profile = { num: 254, // Selected bit is set for the current session. name: "messageIndex", type: "messageIndex", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -4413,6 +4710,7 @@ const Profile = { num: 253, // Sesson end time. name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -4427,6 +4725,7 @@ const Profile = { num: 0, // session name: "event", type: "event", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -4441,6 +4740,7 @@ const Profile = { num: 1, // stop name: "eventType", type: "eventType", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -4455,6 +4755,7 @@ const Profile = { num: 2, name: "startTime", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -4469,6 +4770,7 @@ const Profile = { num: 3, name: "startPositionLat", type: "sint32", + baseType: "sint32", array: "false", scale: 1, offset: 0, @@ -4483,6 +4785,7 @@ const Profile = { num: 4, name: "startPositionLong", type: "sint32", + baseType: "sint32", array: "false", scale: 1, offset: 0, @@ -4497,6 +4800,7 @@ const Profile = { num: 5, name: "sport", type: "sport", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -4511,6 +4815,7 @@ const Profile = { num: 6, name: "subSport", type: "subSport", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -4525,6 +4830,7 @@ const Profile = { num: 7, // Time (includes pauses) name: "totalElapsedTime", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -4539,6 +4845,7 @@ const Profile = { num: 8, // Timer Time (excludes pauses) name: "totalTimerTime", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -4553,6 +4860,7 @@ const Profile = { num: 9, name: "totalDistance", type: "uint32", + baseType: "uint32", array: "false", scale: 100, offset: 0, @@ -4567,6 +4875,7 @@ const Profile = { num: 10, name: "totalCycles", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -4578,6 +4887,7 @@ const Profile = { subFields: [{ name: "totalStrides", type: "uint32", + baseType: "uint32", array: "", scale: 1, offset: 0, @@ -4593,6 +4903,7 @@ const Profile = { { name: "totalStrokes", type: "uint32", + baseType: "uint32", array: "", scale: 1, offset: 0, @@ -4613,6 +4924,7 @@ const Profile = { num: 11, name: "totalCalories", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -4627,6 +4939,7 @@ const Profile = { num: 13, name: "totalFatCalories", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -4641,6 +4954,7 @@ const Profile = { num: 14, // total_distance / total_timer_time name: "avgSpeed", type: "uint16", + baseType: "uint16", array: "false", scale: [1000, ], offset: [0, ], @@ -4655,6 +4969,7 @@ const Profile = { num: 15, name: "maxSpeed", type: "uint16", + baseType: "uint16", array: "false", scale: [1000, ], offset: [0, ], @@ -4669,6 +4984,7 @@ const Profile = { num: 16, // average heart rate (excludes pause time) name: "avgHeartRate", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -4683,6 +4999,7 @@ const Profile = { num: 17, name: "maxHeartRate", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -4697,6 +5014,7 @@ const Profile = { num: 18, // total_cycles / total_timer_time if non_zero_avg_cadence otherwise total_cycles / total_elapsed_time name: "avgCadence", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -4708,6 +5026,7 @@ const Profile = { subFields: [{ name: "avgRunningCadence", type: "uint8", + baseType: "uint8", array: "", scale: 1, offset: 0, @@ -4725,6 +5044,7 @@ const Profile = { num: 19, name: "maxCadence", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -4736,6 +5056,7 @@ const Profile = { subFields: [{ name: "maxRunningCadence", type: "uint8", + baseType: "uint8", array: "", scale: 1, offset: 0, @@ -4753,6 +5074,7 @@ const Profile = { num: 20, // total_power / total_timer_time if non_zero_avg_power otherwise total_power / total_elapsed_time name: "avgPower", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -4767,6 +5089,7 @@ const Profile = { num: 21, name: "maxPower", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -4781,6 +5104,7 @@ const Profile = { num: 22, name: "totalAscent", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -4795,6 +5119,7 @@ const Profile = { num: 23, name: "totalDescent", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -4809,6 +5134,7 @@ const Profile = { num: 24, name: "totalTrainingEffect", type: "uint8", + baseType: "uint8", array: "false", scale: 10, offset: 0, @@ -4823,6 +5149,7 @@ const Profile = { num: 25, name: "firstLapIndex", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -4837,6 +5164,7 @@ const Profile = { num: 26, name: "numLaps", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -4851,6 +5179,7 @@ const Profile = { num: 27, name: "eventGroup", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -4865,6 +5194,7 @@ const Profile = { num: 28, name: "trigger", type: "sessionTrigger", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -4879,6 +5209,7 @@ const Profile = { num: 29, // North east corner latitude name: "necLat", type: "sint32", + baseType: "sint32", array: "false", scale: 1, offset: 0, @@ -4893,6 +5224,7 @@ const Profile = { num: 30, // North east corner longitude name: "necLong", type: "sint32", + baseType: "sint32", array: "false", scale: 1, offset: 0, @@ -4907,6 +5239,7 @@ const Profile = { num: 31, // South west corner latitude name: "swcLat", type: "sint32", + baseType: "sint32", array: "false", scale: 1, offset: 0, @@ -4921,6 +5254,7 @@ const Profile = { num: 32, // South west corner longitude name: "swcLong", type: "sint32", + baseType: "sint32", array: "false", scale: 1, offset: 0, @@ -4935,6 +5269,7 @@ const Profile = { num: 33, // # of lengths of swim pool name: "numLengths", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -4949,6 +5284,7 @@ const Profile = { num: 34, name: "normalizedPower", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -4963,6 +5299,7 @@ const Profile = { num: 35, name: "trainingStressScore", type: "uint16", + baseType: "uint16", array: "false", scale: 10, offset: 0, @@ -4977,6 +5314,7 @@ const Profile = { num: 36, name: "intensityFactor", type: "uint16", + baseType: "uint16", array: "false", scale: 1000, offset: 0, @@ -4991,6 +5329,7 @@ const Profile = { num: 37, name: "leftRightBalance", type: "leftRightBalance100", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -5005,6 +5344,7 @@ const Profile = { num: 38, name: "endPositionLat", type: "sint32", + baseType: "sint32", array: "false", scale: 1, offset: 0, @@ -5019,6 +5359,7 @@ const Profile = { num: 39, name: "endPositionLong", type: "sint32", + baseType: "sint32", array: "false", scale: 1, offset: 0, @@ -5033,6 +5374,7 @@ const Profile = { num: 41, name: "avgStrokeCount", type: "uint32", + baseType: "uint32", array: "false", scale: 10, offset: 0, @@ -5047,6 +5389,7 @@ const Profile = { num: 42, name: "avgStrokeDistance", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -5061,6 +5404,7 @@ const Profile = { num: 43, name: "swimStroke", type: "swimStroke", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -5075,6 +5419,7 @@ const Profile = { num: 44, name: "poolLength", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -5089,6 +5434,7 @@ const Profile = { num: 45, name: "thresholdPower", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -5103,6 +5449,7 @@ const Profile = { num: 46, name: "poolLengthUnit", type: "displayMeasure", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -5117,6 +5464,7 @@ const Profile = { num: 47, // # of active lengths of swim pool name: "numActiveLengths", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -5131,6 +5479,7 @@ const Profile = { num: 48, name: "totalWork", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -5145,6 +5494,7 @@ const Profile = { num: 49, name: "avgAltitude", type: "uint16", + baseType: "uint16", array: "false", scale: [5, ], offset: [500, ], @@ -5159,6 +5509,7 @@ const Profile = { num: 50, name: "maxAltitude", type: "uint16", + baseType: "uint16", array: "false", scale: [5, ], offset: [500, ], @@ -5173,6 +5524,7 @@ const Profile = { num: 51, name: "gpsAccuracy", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -5187,6 +5539,7 @@ const Profile = { num: 52, name: "avgGrade", type: "sint16", + baseType: "sint16", array: "false", scale: 100, offset: 0, @@ -5201,6 +5554,7 @@ const Profile = { num: 53, name: "avgPosGrade", type: "sint16", + baseType: "sint16", array: "false", scale: 100, offset: 0, @@ -5215,6 +5569,7 @@ const Profile = { num: 54, name: "avgNegGrade", type: "sint16", + baseType: "sint16", array: "false", scale: 100, offset: 0, @@ -5229,6 +5584,7 @@ const Profile = { num: 55, name: "maxPosGrade", type: "sint16", + baseType: "sint16", array: "false", scale: 100, offset: 0, @@ -5243,6 +5599,7 @@ const Profile = { num: 56, name: "maxNegGrade", type: "sint16", + baseType: "sint16", array: "false", scale: 100, offset: 0, @@ -5257,6 +5614,7 @@ const Profile = { num: 57, name: "avgTemperature", type: "sint8", + baseType: "sint8", array: "false", scale: 1, offset: 0, @@ -5271,6 +5629,7 @@ const Profile = { num: 58, name: "maxTemperature", type: "sint8", + baseType: "sint8", array: "false", scale: 1, offset: 0, @@ -5285,6 +5644,7 @@ const Profile = { num: 59, name: "totalMovingTime", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -5299,6 +5659,7 @@ const Profile = { num: 60, name: "avgPosVerticalSpeed", type: "sint16", + baseType: "sint16", array: "false", scale: 1000, offset: 0, @@ -5313,6 +5674,7 @@ const Profile = { num: 61, name: "avgNegVerticalSpeed", type: "sint16", + baseType: "sint16", array: "false", scale: 1000, offset: 0, @@ -5327,6 +5689,7 @@ const Profile = { num: 62, name: "maxPosVerticalSpeed", type: "sint16", + baseType: "sint16", array: "false", scale: 1000, offset: 0, @@ -5341,6 +5704,7 @@ const Profile = { num: 63, name: "maxNegVerticalSpeed", type: "sint16", + baseType: "sint16", array: "false", scale: 1000, offset: 0, @@ -5355,6 +5719,7 @@ const Profile = { num: 64, name: "minHeartRate", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -5369,6 +5734,7 @@ const Profile = { num: 65, name: "timeInHrZone", type: "uint32", + baseType: "uint32", array: "true", scale: 1000, offset: 0, @@ -5383,6 +5749,7 @@ const Profile = { num: 66, name: "timeInSpeedZone", type: "uint32", + baseType: "uint32", array: "true", scale: 1000, offset: 0, @@ -5397,6 +5764,7 @@ const Profile = { num: 67, name: "timeInCadenceZone", type: "uint32", + baseType: "uint32", array: "true", scale: 1000, offset: 0, @@ -5411,6 +5779,7 @@ const Profile = { num: 68, name: "timeInPowerZone", type: "uint32", + baseType: "uint32", array: "true", scale: 1000, offset: 0, @@ -5425,6 +5794,7 @@ const Profile = { num: 69, name: "avgLapTime", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -5439,6 +5809,7 @@ const Profile = { num: 70, name: "bestLapIndex", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -5453,6 +5824,7 @@ const Profile = { num: 71, name: "minAltitude", type: "uint16", + baseType: "uint16", array: "false", scale: [5, ], offset: [500, ], @@ -5467,6 +5839,7 @@ const Profile = { num: 82, name: "playerScore", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -5481,6 +5854,7 @@ const Profile = { num: 83, name: "opponentScore", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -5495,6 +5869,7 @@ const Profile = { num: 84, name: "opponentName", type: "string", + baseType: "string", array: "true", scale: 1, offset: 0, @@ -5509,6 +5884,7 @@ const Profile = { num: 85, // stroke_type enum used as the index name: "strokeCount", type: "uint16", + baseType: "uint16", array: "true", scale: 1, offset: 0, @@ -5523,6 +5899,7 @@ const Profile = { num: 86, // zone number used as the index name: "zoneCount", type: "uint16", + baseType: "uint16", array: "true", scale: 1, offset: 0, @@ -5537,6 +5914,7 @@ const Profile = { num: 87, name: "maxBallSpeed", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -5551,6 +5929,7 @@ const Profile = { num: 88, name: "avgBallSpeed", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -5565,6 +5944,7 @@ const Profile = { num: 89, name: "avgVerticalOscillation", type: "uint16", + baseType: "uint16", array: "false", scale: 10, offset: 0, @@ -5579,6 +5959,7 @@ const Profile = { num: 90, name: "avgStanceTimePercent", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -5593,6 +5974,7 @@ const Profile = { num: 91, name: "avgStanceTime", type: "uint16", + baseType: "uint16", array: "false", scale: 10, offset: 0, @@ -5607,6 +5989,7 @@ const Profile = { num: 92, // fractional part of the avg_cadence name: "avgFractionalCadence", type: "uint8", + baseType: "uint8", array: "false", scale: 128, offset: 0, @@ -5621,6 +6004,7 @@ const Profile = { num: 93, // fractional part of the max_cadence name: "maxFractionalCadence", type: "uint8", + baseType: "uint8", array: "false", scale: 128, offset: 0, @@ -5635,6 +6019,7 @@ const Profile = { num: 94, // fractional part of the total_cycles name: "totalFractionalCycles", type: "uint8", + baseType: "uint8", array: "false", scale: 128, offset: 0, @@ -5649,6 +6034,7 @@ const Profile = { num: 95, // Avg saturated and unsaturated hemoglobin name: "avgTotalHemoglobinConc", type: "uint16", + baseType: "uint16", array: "true", scale: 100, offset: 0, @@ -5663,6 +6049,7 @@ const Profile = { num: 96, // Min saturated and unsaturated hemoglobin name: "minTotalHemoglobinConc", type: "uint16", + baseType: "uint16", array: "true", scale: 100, offset: 0, @@ -5677,6 +6064,7 @@ const Profile = { num: 97, // Max saturated and unsaturated hemoglobin name: "maxTotalHemoglobinConc", type: "uint16", + baseType: "uint16", array: "true", scale: 100, offset: 0, @@ -5691,6 +6079,7 @@ const Profile = { num: 98, // Avg percentage of hemoglobin saturated with oxygen name: "avgSaturatedHemoglobinPercent", type: "uint16", + baseType: "uint16", array: "true", scale: 10, offset: 0, @@ -5705,6 +6094,7 @@ const Profile = { num: 99, // Min percentage of hemoglobin saturated with oxygen name: "minSaturatedHemoglobinPercent", type: "uint16", + baseType: "uint16", array: "true", scale: 10, offset: 0, @@ -5719,6 +6109,7 @@ const Profile = { num: 100, // Max percentage of hemoglobin saturated with oxygen name: "maxSaturatedHemoglobinPercent", type: "uint16", + baseType: "uint16", array: "true", scale: 10, offset: 0, @@ -5733,6 +6124,7 @@ const Profile = { num: 101, name: "avgLeftTorqueEffectiveness", type: "uint8", + baseType: "uint8", array: "false", scale: 2, offset: 0, @@ -5747,6 +6139,7 @@ const Profile = { num: 102, name: "avgRightTorqueEffectiveness", type: "uint8", + baseType: "uint8", array: "false", scale: 2, offset: 0, @@ -5761,6 +6154,7 @@ const Profile = { num: 103, name: "avgLeftPedalSmoothness", type: "uint8", + baseType: "uint8", array: "false", scale: 2, offset: 0, @@ -5775,6 +6169,7 @@ const Profile = { num: 104, name: "avgRightPedalSmoothness", type: "uint8", + baseType: "uint8", array: "false", scale: 2, offset: 0, @@ -5789,6 +6184,7 @@ const Profile = { num: 105, name: "avgCombinedPedalSmoothness", type: "uint8", + baseType: "uint8", array: "false", scale: 2, offset: 0, @@ -5803,6 +6199,7 @@ const Profile = { num: 110, // Sport name from associated sport mesg name: "sportProfileName", type: "string", + baseType: "string", array: "true", scale: 1, offset: 0, @@ -5817,6 +6214,7 @@ const Profile = { num: 111, name: "sportIndex", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -5831,6 +6229,7 @@ const Profile = { num: 112, // Total time spend in the standing position name: "timeStanding", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -5845,6 +6244,7 @@ const Profile = { num: 113, // Number of transitions to the standing state name: "standCount", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -5859,6 +6259,7 @@ const Profile = { num: 114, // Average platform center offset Left name: "avgLeftPco", type: "sint8", + baseType: "sint8", array: "false", scale: 1, offset: 0, @@ -5873,6 +6274,7 @@ const Profile = { num: 115, // Average platform center offset Right name: "avgRightPco", type: "sint8", + baseType: "sint8", array: "false", scale: 1, offset: 0, @@ -5887,6 +6289,7 @@ const Profile = { num: 116, // Average left power phase angles. Indexes defined by power_phase_type. name: "avgLeftPowerPhase", type: "uint8", + baseType: "uint8", array: "true", scale: 0.7111111, offset: 0, @@ -5901,6 +6304,7 @@ const Profile = { num: 117, // Average left power phase peak angles. Data value indexes defined by power_phase_type. name: "avgLeftPowerPhasePeak", type: "uint8", + baseType: "uint8", array: "true", scale: 0.7111111, offset: 0, @@ -5915,6 +6319,7 @@ const Profile = { num: 118, // Average right power phase angles. Data value indexes defined by power_phase_type. name: "avgRightPowerPhase", type: "uint8", + baseType: "uint8", array: "true", scale: 0.7111111, offset: 0, @@ -5929,6 +6334,7 @@ const Profile = { num: 119, // Average right power phase peak angles data value indexes defined by power_phase_type. name: "avgRightPowerPhasePeak", type: "uint8", + baseType: "uint8", array: "true", scale: 0.7111111, offset: 0, @@ -5943,6 +6349,7 @@ const Profile = { num: 120, // Average power by position. Data value indexes defined by rider_position_type. name: "avgPowerPosition", type: "uint16", + baseType: "uint16", array: "true", scale: 1, offset: 0, @@ -5957,6 +6364,7 @@ const Profile = { num: 121, // Maximum power by position. Data value indexes defined by rider_position_type. name: "maxPowerPosition", type: "uint16", + baseType: "uint16", array: "true", scale: 1, offset: 0, @@ -5971,6 +6379,7 @@ const Profile = { num: 122, // Average cadence by position. Data value indexes defined by rider_position_type. name: "avgCadencePosition", type: "uint8", + baseType: "uint8", array: "true", scale: 1, offset: 0, @@ -5985,6 +6394,7 @@ const Profile = { num: 123, // Maximum cadence by position. Data value indexes defined by rider_position_type. name: "maxCadencePosition", type: "uint8", + baseType: "uint8", array: "true", scale: 1, offset: 0, @@ -5999,6 +6409,7 @@ const Profile = { num: 124, // total_distance / total_timer_time name: "enhancedAvgSpeed", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -6013,6 +6424,7 @@ const Profile = { num: 125, name: "enhancedMaxSpeed", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -6027,6 +6439,7 @@ const Profile = { num: 126, name: "enhancedAvgAltitude", type: "uint32", + baseType: "uint32", array: "false", scale: 5, offset: 500, @@ -6041,6 +6454,7 @@ const Profile = { num: 127, name: "enhancedMinAltitude", type: "uint32", + baseType: "uint32", array: "false", scale: 5, offset: 500, @@ -6055,6 +6469,7 @@ const Profile = { num: 128, name: "enhancedMaxAltitude", type: "uint32", + baseType: "uint32", array: "false", scale: 5, offset: 500, @@ -6069,6 +6484,7 @@ const Profile = { num: 129, // lev average motor power during session name: "avgLevMotorPower", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -6083,6 +6499,7 @@ const Profile = { num: 130, // lev maximum motor power during session name: "maxLevMotorPower", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -6097,6 +6514,7 @@ const Profile = { num: 131, // lev battery consumption during session name: "levBatteryConsumption", type: "uint8", + baseType: "uint8", array: "false", scale: 2, offset: 0, @@ -6111,6 +6529,7 @@ const Profile = { num: 132, name: "avgVerticalRatio", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -6125,6 +6544,7 @@ const Profile = { num: 133, name: "avgStanceTimeBalance", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -6139,6 +6559,7 @@ const Profile = { num: 134, name: "avgStepLength", type: "uint16", + baseType: "uint16", array: "false", scale: 10, offset: 0, @@ -6153,6 +6574,7 @@ const Profile = { num: 137, name: "totalAnaerobicTrainingEffect", type: "uint8", + baseType: "uint8", array: "false", scale: 10, offset: 0, @@ -6167,6 +6589,7 @@ const Profile = { num: 139, name: "avgVam", type: "uint16", + baseType: "uint16", array: "false", scale: 1000, offset: 0, @@ -6181,6 +6604,7 @@ const Profile = { num: 140, // 0 if above water name: "avgDepth", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -6195,6 +6619,7 @@ const Profile = { num: 141, // 0 if above water name: "maxDepth", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -6209,6 +6634,7 @@ const Profile = { num: 142, // Time since end of last dive name: "surfaceInterval", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -6223,6 +6649,7 @@ const Profile = { num: 143, name: "startCns", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -6237,6 +6664,7 @@ const Profile = { num: 144, name: "endCns", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -6251,6 +6679,7 @@ const Profile = { num: 145, name: "startN2", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -6265,6 +6694,7 @@ const Profile = { num: 146, name: "endN2", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -6279,6 +6709,7 @@ const Profile = { num: 147, name: "avgRespirationRate", type: "uint8", + baseType: "uint8", array: "false", scale: [1, ], offset: [0, ], @@ -6293,6 +6724,7 @@ const Profile = { num: 148, name: "maxRespirationRate", type: "uint8", + baseType: "uint8", array: "false", scale: [1, ], offset: [0, ], @@ -6307,6 +6739,7 @@ const Profile = { num: 149, name: "minRespirationRate", type: "uint8", + baseType: "uint8", array: "false", scale: [1, ], offset: [0, ], @@ -6321,6 +6754,7 @@ const Profile = { num: 150, name: "minTemperature", type: "sint8", + baseType: "sint8", array: "false", scale: 1, offset: 0, @@ -6335,6 +6769,7 @@ const Profile = { num: 155, name: "o2Toxicity", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -6349,6 +6784,7 @@ const Profile = { num: 156, name: "diveNumber", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -6363,6 +6799,7 @@ const Profile = { num: 168, name: "trainingLoadPeak", type: "sint32", + baseType: "sint32", array: "false", scale: 65536, offset: 0, @@ -6377,6 +6814,7 @@ const Profile = { num: 169, name: "enhancedAvgRespirationRate", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -6391,6 +6829,7 @@ const Profile = { num: 170, name: "enhancedMaxRespirationRate", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -6405,6 +6844,7 @@ const Profile = { num: 180, name: "enhancedMinRespirationRate", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -6419,6 +6859,7 @@ const Profile = { num: 181, // The grit score estimates how challenging a route could be for a cyclist in terms of time spent going over sharp turns or large grade slopes. name: "totalGrit", type: "float32", + baseType: "float32", array: "false", scale: 1, offset: 0, @@ -6433,6 +6874,7 @@ const Profile = { num: 182, // The flow score estimates how long distance wise a cyclist deaccelerates over intervals where deacceleration is unnecessary such as smooth turns or small grade angle intervals. name: "totalFlow", type: "float32", + baseType: "float32", array: "false", scale: 1, offset: 0, @@ -6447,6 +6889,7 @@ const Profile = { num: 183, name: "jumpCount", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -6461,6 +6904,7 @@ const Profile = { num: 186, // The grit score estimates how challenging a route could be for a cyclist in terms of time spent going over sharp turns or large grade slopes. name: "avgGrit", type: "float32", + baseType: "float32", array: "false", scale: 1, offset: 0, @@ -6475,6 +6919,7 @@ const Profile = { num: 187, // The flow score estimates how long distance wise a cyclist deaccelerates over intervals where deacceleration is unnecessary such as smooth turns or small grade angle intervals. name: "avgFlow", type: "float32", + baseType: "float32", array: "false", scale: 1, offset: 0, @@ -6489,6 +6934,7 @@ const Profile = { num: 192, // A 0-100 scale representing how a user felt while performing a workout. Low values are considered feeling bad, while high values are good. name: "workoutFeel", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -6503,6 +6949,7 @@ const Profile = { num: 193, // Common Borg CR10 / 0-10 RPE scale, multiplied 10x.. Aggregate score for all workouts in a single session. name: "workoutRpe", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -6517,6 +6964,7 @@ const Profile = { num: 194, // Average SPO2 for the monitoring session name: "avgSpo2", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -6531,6 +6979,7 @@ const Profile = { num: 195, // Average stress for the monitoring session name: "avgStress", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -6545,6 +6994,7 @@ const Profile = { num: 197, // Standard deviation of R-R interval (SDRR) - Heart rate variability measure most useful for wellness users. name: "sdrrHrv", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -6559,6 +7009,7 @@ const Profile = { num: 198, // Root mean square successive difference (RMSSD) - Heart rate variability measure most useful for athletes name: "rmssdHrv", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -6573,6 +7024,7 @@ const Profile = { num: 199, // fractional part of total_ascent name: "totalFractionalAscent", type: "uint8", + baseType: "uint8", array: "false", scale: 100, offset: 0, @@ -6587,6 +7039,7 @@ const Profile = { num: 200, // fractional part of total_descent name: "totalFractionalDescent", type: "uint8", + baseType: "uint8", array: "false", scale: 100, offset: 0, @@ -6601,6 +7054,7 @@ const Profile = { num: 208, name: "avgCoreTemperature", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -6615,6 +7069,7 @@ const Profile = { num: 209, name: "minCoreTemperature", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -6629,6 +7084,7 @@ const Profile = { num: 210, name: "maxCoreTemperature", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -6650,6 +7106,7 @@ const Profile = { num: 254, name: "messageIndex", type: "messageIndex", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -6664,6 +7121,7 @@ const Profile = { num: 253, // Lap end time. name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -6678,6 +7136,7 @@ const Profile = { num: 0, name: "event", type: "event", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -6692,6 +7151,7 @@ const Profile = { num: 1, name: "eventType", type: "eventType", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -6706,6 +7166,7 @@ const Profile = { num: 2, name: "startTime", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -6720,6 +7181,7 @@ const Profile = { num: 3, name: "startPositionLat", type: "sint32", + baseType: "sint32", array: "false", scale: 1, offset: 0, @@ -6734,6 +7196,7 @@ const Profile = { num: 4, name: "startPositionLong", type: "sint32", + baseType: "sint32", array: "false", scale: 1, offset: 0, @@ -6748,6 +7211,7 @@ const Profile = { num: 5, name: "endPositionLat", type: "sint32", + baseType: "sint32", array: "false", scale: 1, offset: 0, @@ -6762,6 +7226,7 @@ const Profile = { num: 6, name: "endPositionLong", type: "sint32", + baseType: "sint32", array: "false", scale: 1, offset: 0, @@ -6776,6 +7241,7 @@ const Profile = { num: 7, // Time (includes pauses) name: "totalElapsedTime", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -6790,6 +7256,7 @@ const Profile = { num: 8, // Timer Time (excludes pauses) name: "totalTimerTime", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -6804,6 +7271,7 @@ const Profile = { num: 9, name: "totalDistance", type: "uint32", + baseType: "uint32", array: "false", scale: 100, offset: 0, @@ -6818,6 +7286,7 @@ const Profile = { num: 10, name: "totalCycles", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -6829,6 +7298,7 @@ const Profile = { subFields: [{ name: "totalStrides", type: "uint32", + baseType: "uint32", array: "", scale: 1, offset: 0, @@ -6844,6 +7314,7 @@ const Profile = { { name: "totalStrokes", type: "uint32", + baseType: "uint32", array: "", scale: 1, offset: 0, @@ -6864,6 +7335,7 @@ const Profile = { num: 11, name: "totalCalories", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -6878,6 +7350,7 @@ const Profile = { num: 12, // If New Leaf name: "totalFatCalories", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -6892,6 +7365,7 @@ const Profile = { num: 13, name: "avgSpeed", type: "uint16", + baseType: "uint16", array: "false", scale: [1000, ], offset: [0, ], @@ -6906,6 +7380,7 @@ const Profile = { num: 14, name: "maxSpeed", type: "uint16", + baseType: "uint16", array: "false", scale: [1000, ], offset: [0, ], @@ -6920,6 +7395,7 @@ const Profile = { num: 15, name: "avgHeartRate", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -6934,6 +7410,7 @@ const Profile = { num: 16, name: "maxHeartRate", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -6948,6 +7425,7 @@ const Profile = { num: 17, // total_cycles / total_timer_time if non_zero_avg_cadence otherwise total_cycles / total_elapsed_time name: "avgCadence", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -6959,6 +7437,7 @@ const Profile = { subFields: [{ name: "avgRunningCadence", type: "uint8", + baseType: "uint8", array: "", scale: 1, offset: 0, @@ -6976,6 +7455,7 @@ const Profile = { num: 18, name: "maxCadence", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -6987,6 +7467,7 @@ const Profile = { subFields: [{ name: "maxRunningCadence", type: "uint8", + baseType: "uint8", array: "", scale: 1, offset: 0, @@ -7004,6 +7485,7 @@ const Profile = { num: 19, // total_power / total_timer_time if non_zero_avg_power otherwise total_power / total_elapsed_time name: "avgPower", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -7018,6 +7500,7 @@ const Profile = { num: 20, name: "maxPower", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -7032,6 +7515,7 @@ const Profile = { num: 21, name: "totalAscent", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -7046,6 +7530,7 @@ const Profile = { num: 22, name: "totalDescent", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -7060,6 +7545,7 @@ const Profile = { num: 23, name: "intensity", type: "intensity", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -7074,6 +7560,7 @@ const Profile = { num: 24, name: "lapTrigger", type: "lapTrigger", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -7088,6 +7575,7 @@ const Profile = { num: 25, name: "sport", type: "sport", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -7102,6 +7590,7 @@ const Profile = { num: 26, name: "eventGroup", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -7116,6 +7605,7 @@ const Profile = { num: 32, // # of lengths of swim pool name: "numLengths", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -7130,6 +7620,7 @@ const Profile = { num: 33, name: "normalizedPower", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -7144,6 +7635,7 @@ const Profile = { num: 34, name: "leftRightBalance", type: "leftRightBalance100", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -7158,6 +7650,7 @@ const Profile = { num: 35, name: "firstLengthIndex", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -7172,6 +7665,7 @@ const Profile = { num: 37, name: "avgStrokeDistance", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -7186,6 +7680,7 @@ const Profile = { num: 38, name: "swimStroke", type: "swimStroke", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -7200,6 +7695,7 @@ const Profile = { num: 39, name: "subSport", type: "subSport", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -7214,6 +7710,7 @@ const Profile = { num: 40, // # of active lengths of swim pool name: "numActiveLengths", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -7228,6 +7725,7 @@ const Profile = { num: 41, name: "totalWork", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -7242,6 +7740,7 @@ const Profile = { num: 42, name: "avgAltitude", type: "uint16", + baseType: "uint16", array: "false", scale: [5, ], offset: [500, ], @@ -7256,6 +7755,7 @@ const Profile = { num: 43, name: "maxAltitude", type: "uint16", + baseType: "uint16", array: "false", scale: [5, ], offset: [500, ], @@ -7270,6 +7770,7 @@ const Profile = { num: 44, name: "gpsAccuracy", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -7284,6 +7785,7 @@ const Profile = { num: 45, name: "avgGrade", type: "sint16", + baseType: "sint16", array: "false", scale: 100, offset: 0, @@ -7298,6 +7800,7 @@ const Profile = { num: 46, name: "avgPosGrade", type: "sint16", + baseType: "sint16", array: "false", scale: 100, offset: 0, @@ -7312,6 +7815,7 @@ const Profile = { num: 47, name: "avgNegGrade", type: "sint16", + baseType: "sint16", array: "false", scale: 100, offset: 0, @@ -7326,6 +7830,7 @@ const Profile = { num: 48, name: "maxPosGrade", type: "sint16", + baseType: "sint16", array: "false", scale: 100, offset: 0, @@ -7340,6 +7845,7 @@ const Profile = { num: 49, name: "maxNegGrade", type: "sint16", + baseType: "sint16", array: "false", scale: 100, offset: 0, @@ -7354,6 +7860,7 @@ const Profile = { num: 50, name: "avgTemperature", type: "sint8", + baseType: "sint8", array: "false", scale: 1, offset: 0, @@ -7368,6 +7875,7 @@ const Profile = { num: 51, name: "maxTemperature", type: "sint8", + baseType: "sint8", array: "false", scale: 1, offset: 0, @@ -7382,6 +7890,7 @@ const Profile = { num: 52, name: "totalMovingTime", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -7396,6 +7905,7 @@ const Profile = { num: 53, name: "avgPosVerticalSpeed", type: "sint16", + baseType: "sint16", array: "false", scale: 1000, offset: 0, @@ -7410,6 +7920,7 @@ const Profile = { num: 54, name: "avgNegVerticalSpeed", type: "sint16", + baseType: "sint16", array: "false", scale: 1000, offset: 0, @@ -7424,6 +7935,7 @@ const Profile = { num: 55, name: "maxPosVerticalSpeed", type: "sint16", + baseType: "sint16", array: "false", scale: 1000, offset: 0, @@ -7438,6 +7950,7 @@ const Profile = { num: 56, name: "maxNegVerticalSpeed", type: "sint16", + baseType: "sint16", array: "false", scale: 1000, offset: 0, @@ -7452,6 +7965,7 @@ const Profile = { num: 57, name: "timeInHrZone", type: "uint32", + baseType: "uint32", array: "true", scale: 1000, offset: 0, @@ -7466,6 +7980,7 @@ const Profile = { num: 58, name: "timeInSpeedZone", type: "uint32", + baseType: "uint32", array: "true", scale: 1000, offset: 0, @@ -7480,6 +7995,7 @@ const Profile = { num: 59, name: "timeInCadenceZone", type: "uint32", + baseType: "uint32", array: "true", scale: 1000, offset: 0, @@ -7494,6 +8010,7 @@ const Profile = { num: 60, name: "timeInPowerZone", type: "uint32", + baseType: "uint32", array: "true", scale: 1000, offset: 0, @@ -7508,6 +8025,7 @@ const Profile = { num: 61, name: "repetitionNum", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -7522,6 +8040,7 @@ const Profile = { num: 62, name: "minAltitude", type: "uint16", + baseType: "uint16", array: "false", scale: [5, ], offset: [500, ], @@ -7536,6 +8055,7 @@ const Profile = { num: 63, name: "minHeartRate", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -7550,6 +8070,7 @@ const Profile = { num: 71, name: "wktStepIndex", type: "messageIndex", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -7564,6 +8085,7 @@ const Profile = { num: 74, name: "opponentScore", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -7578,6 +8100,7 @@ const Profile = { num: 75, // stroke_type enum used as the index name: "strokeCount", type: "uint16", + baseType: "uint16", array: "true", scale: 1, offset: 0, @@ -7592,6 +8115,7 @@ const Profile = { num: 76, // zone number used as the index name: "zoneCount", type: "uint16", + baseType: "uint16", array: "true", scale: 1, offset: 0, @@ -7606,6 +8130,7 @@ const Profile = { num: 77, name: "avgVerticalOscillation", type: "uint16", + baseType: "uint16", array: "false", scale: 10, offset: 0, @@ -7620,6 +8145,7 @@ const Profile = { num: 78, name: "avgStanceTimePercent", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -7634,6 +8160,7 @@ const Profile = { num: 79, name: "avgStanceTime", type: "uint16", + baseType: "uint16", array: "false", scale: 10, offset: 0, @@ -7648,6 +8175,7 @@ const Profile = { num: 80, // fractional part of the avg_cadence name: "avgFractionalCadence", type: "uint8", + baseType: "uint8", array: "false", scale: 128, offset: 0, @@ -7662,6 +8190,7 @@ const Profile = { num: 81, // fractional part of the max_cadence name: "maxFractionalCadence", type: "uint8", + baseType: "uint8", array: "false", scale: 128, offset: 0, @@ -7676,6 +8205,7 @@ const Profile = { num: 82, // fractional part of the total_cycles name: "totalFractionalCycles", type: "uint8", + baseType: "uint8", array: "false", scale: 128, offset: 0, @@ -7690,6 +8220,7 @@ const Profile = { num: 83, name: "playerScore", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -7704,6 +8235,7 @@ const Profile = { num: 84, // Avg saturated and unsaturated hemoglobin name: "avgTotalHemoglobinConc", type: "uint16", + baseType: "uint16", array: "true", scale: 100, offset: 0, @@ -7718,6 +8250,7 @@ const Profile = { num: 85, // Min saturated and unsaturated hemoglobin name: "minTotalHemoglobinConc", type: "uint16", + baseType: "uint16", array: "true", scale: 100, offset: 0, @@ -7732,6 +8265,7 @@ const Profile = { num: 86, // Max saturated and unsaturated hemoglobin name: "maxTotalHemoglobinConc", type: "uint16", + baseType: "uint16", array: "true", scale: 100, offset: 0, @@ -7746,6 +8280,7 @@ const Profile = { num: 87, // Avg percentage of hemoglobin saturated with oxygen name: "avgSaturatedHemoglobinPercent", type: "uint16", + baseType: "uint16", array: "true", scale: 10, offset: 0, @@ -7760,6 +8295,7 @@ const Profile = { num: 88, // Min percentage of hemoglobin saturated with oxygen name: "minSaturatedHemoglobinPercent", type: "uint16", + baseType: "uint16", array: "true", scale: 10, offset: 0, @@ -7774,6 +8310,7 @@ const Profile = { num: 89, // Max percentage of hemoglobin saturated with oxygen name: "maxSaturatedHemoglobinPercent", type: "uint16", + baseType: "uint16", array: "true", scale: 10, offset: 0, @@ -7788,6 +8325,7 @@ const Profile = { num: 91, name: "avgLeftTorqueEffectiveness", type: "uint8", + baseType: "uint8", array: "false", scale: 2, offset: 0, @@ -7802,6 +8340,7 @@ const Profile = { num: 92, name: "avgRightTorqueEffectiveness", type: "uint8", + baseType: "uint8", array: "false", scale: 2, offset: 0, @@ -7816,6 +8355,7 @@ const Profile = { num: 93, name: "avgLeftPedalSmoothness", type: "uint8", + baseType: "uint8", array: "false", scale: 2, offset: 0, @@ -7830,6 +8370,7 @@ const Profile = { num: 94, name: "avgRightPedalSmoothness", type: "uint8", + baseType: "uint8", array: "false", scale: 2, offset: 0, @@ -7844,6 +8385,7 @@ const Profile = { num: 95, name: "avgCombinedPedalSmoothness", type: "uint8", + baseType: "uint8", array: "false", scale: 2, offset: 0, @@ -7858,6 +8400,7 @@ const Profile = { num: 98, // Total time spent in the standing position name: "timeStanding", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -7872,6 +8415,7 @@ const Profile = { num: 99, // Number of transitions to the standing state name: "standCount", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -7886,6 +8430,7 @@ const Profile = { num: 100, // Average left platform center offset name: "avgLeftPco", type: "sint8", + baseType: "sint8", array: "false", scale: 1, offset: 0, @@ -7900,6 +8445,7 @@ const Profile = { num: 101, // Average right platform center offset name: "avgRightPco", type: "sint8", + baseType: "sint8", array: "false", scale: 1, offset: 0, @@ -7914,6 +8460,7 @@ const Profile = { num: 102, // Average left power phase angles. Data value indexes defined by power_phase_type. name: "avgLeftPowerPhase", type: "uint8", + baseType: "uint8", array: "true", scale: 0.7111111, offset: 0, @@ -7928,6 +8475,7 @@ const Profile = { num: 103, // Average left power phase peak angles. Data value indexes defined by power_phase_type. name: "avgLeftPowerPhasePeak", type: "uint8", + baseType: "uint8", array: "true", scale: 0.7111111, offset: 0, @@ -7942,6 +8490,7 @@ const Profile = { num: 104, // Average right power phase angles. Data value indexes defined by power_phase_type. name: "avgRightPowerPhase", type: "uint8", + baseType: "uint8", array: "true", scale: 0.7111111, offset: 0, @@ -7956,6 +8505,7 @@ const Profile = { num: 105, // Average right power phase peak angles. Data value indexes defined by power_phase_type. name: "avgRightPowerPhasePeak", type: "uint8", + baseType: "uint8", array: "true", scale: 0.7111111, offset: 0, @@ -7970,6 +8520,7 @@ const Profile = { num: 106, // Average power by position. Data value indexes defined by rider_position_type. name: "avgPowerPosition", type: "uint16", + baseType: "uint16", array: "true", scale: 1, offset: 0, @@ -7984,6 +8535,7 @@ const Profile = { num: 107, // Maximum power by position. Data value indexes defined by rider_position_type. name: "maxPowerPosition", type: "uint16", + baseType: "uint16", array: "true", scale: 1, offset: 0, @@ -7998,6 +8550,7 @@ const Profile = { num: 108, // Average cadence by position. Data value indexes defined by rider_position_type. name: "avgCadencePosition", type: "uint8", + baseType: "uint8", array: "true", scale: 1, offset: 0, @@ -8012,6 +8565,7 @@ const Profile = { num: 109, // Maximum cadence by position. Data value indexes defined by rider_position_type. name: "maxCadencePosition", type: "uint8", + baseType: "uint8", array: "true", scale: 1, offset: 0, @@ -8026,6 +8580,7 @@ const Profile = { num: 110, name: "enhancedAvgSpeed", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -8040,6 +8595,7 @@ const Profile = { num: 111, name: "enhancedMaxSpeed", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -8054,6 +8610,7 @@ const Profile = { num: 112, name: "enhancedAvgAltitude", type: "uint32", + baseType: "uint32", array: "false", scale: 5, offset: 500, @@ -8068,6 +8625,7 @@ const Profile = { num: 113, name: "enhancedMinAltitude", type: "uint32", + baseType: "uint32", array: "false", scale: 5, offset: 500, @@ -8082,6 +8640,7 @@ const Profile = { num: 114, name: "enhancedMaxAltitude", type: "uint32", + baseType: "uint32", array: "false", scale: 5, offset: 500, @@ -8096,6 +8655,7 @@ const Profile = { num: 115, // lev average motor power during lap name: "avgLevMotorPower", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -8110,6 +8670,7 @@ const Profile = { num: 116, // lev maximum motor power during lap name: "maxLevMotorPower", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -8124,6 +8685,7 @@ const Profile = { num: 117, // lev battery consumption during lap name: "levBatteryConsumption", type: "uint8", + baseType: "uint8", array: "false", scale: 2, offset: 0, @@ -8138,6 +8700,7 @@ const Profile = { num: 118, name: "avgVerticalRatio", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -8152,6 +8715,7 @@ const Profile = { num: 119, name: "avgStanceTimeBalance", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -8166,6 +8730,7 @@ const Profile = { num: 120, name: "avgStepLength", type: "uint16", + baseType: "uint16", array: "false", scale: 10, offset: 0, @@ -8180,6 +8745,7 @@ const Profile = { num: 121, name: "avgVam", type: "uint16", + baseType: "uint16", array: "false", scale: 1000, offset: 0, @@ -8194,6 +8760,7 @@ const Profile = { num: 122, // 0 if above water name: "avgDepth", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -8208,6 +8775,7 @@ const Profile = { num: 123, // 0 if above water name: "maxDepth", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -8222,6 +8790,7 @@ const Profile = { num: 124, name: "minTemperature", type: "sint8", + baseType: "sint8", array: "false", scale: 1, offset: 0, @@ -8236,6 +8805,7 @@ const Profile = { num: 136, name: "enhancedAvgRespirationRate", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -8250,6 +8820,7 @@ const Profile = { num: 137, name: "enhancedMaxRespirationRate", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -8264,6 +8835,7 @@ const Profile = { num: 147, name: "avgRespirationRate", type: "uint8", + baseType: "uint8", array: "false", scale: [1, ], offset: [0, ], @@ -8278,6 +8850,7 @@ const Profile = { num: 148, name: "maxRespirationRate", type: "uint8", + baseType: "uint8", array: "false", scale: [1, ], offset: [0, ], @@ -8292,6 +8865,7 @@ const Profile = { num: 149, // The grit score estimates how challenging a route could be for a cyclist in terms of time spent going over sharp turns or large grade slopes. name: "totalGrit", type: "float32", + baseType: "float32", array: "false", scale: 1, offset: 0, @@ -8306,6 +8880,7 @@ const Profile = { num: 150, // The flow score estimates how long distance wise a cyclist deaccelerates over intervals where deacceleration is unnecessary such as smooth turns or small grade angle intervals. name: "totalFlow", type: "float32", + baseType: "float32", array: "false", scale: 1, offset: 0, @@ -8320,6 +8895,7 @@ const Profile = { num: 151, name: "jumpCount", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -8334,6 +8910,7 @@ const Profile = { num: 153, // The grit score estimates how challenging a route could be for a cyclist in terms of time spent going over sharp turns or large grade slopes. name: "avgGrit", type: "float32", + baseType: "float32", array: "false", scale: 1, offset: 0, @@ -8348,6 +8925,7 @@ const Profile = { num: 154, // The flow score estimates how long distance wise a cyclist deaccelerates over intervals where deacceleration is unnecessary such as smooth turns or small grade angle intervals. name: "avgFlow", type: "float32", + baseType: "float32", array: "false", scale: 1, offset: 0, @@ -8362,6 +8940,7 @@ const Profile = { num: 156, // fractional part of total_ascent name: "totalFractionalAscent", type: "uint8", + baseType: "uint8", array: "false", scale: 100, offset: 0, @@ -8376,6 +8955,7 @@ const Profile = { num: 157, // fractional part of total_descent name: "totalFractionalDescent", type: "uint8", + baseType: "uint8", array: "false", scale: 100, offset: 0, @@ -8390,6 +8970,7 @@ const Profile = { num: 158, name: "avgCoreTemperature", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -8404,6 +8985,7 @@ const Profile = { num: 159, name: "minCoreTemperature", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -8418,6 +9000,7 @@ const Profile = { num: 160, name: "maxCoreTemperature", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -8439,6 +9022,7 @@ const Profile = { num: 254, name: "messageIndex", type: "messageIndex", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -8453,6 +9037,7 @@ const Profile = { num: 253, name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -8467,6 +9052,7 @@ const Profile = { num: 0, name: "event", type: "event", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -8481,6 +9067,7 @@ const Profile = { num: 1, name: "eventType", type: "eventType", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -8495,6 +9082,7 @@ const Profile = { num: 2, name: "startTime", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -8509,6 +9097,7 @@ const Profile = { num: 3, name: "totalElapsedTime", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -8523,6 +9112,7 @@ const Profile = { num: 4, name: "totalTimerTime", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -8537,6 +9127,7 @@ const Profile = { num: 5, name: "totalStrokes", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -8551,6 +9142,7 @@ const Profile = { num: 6, name: "avgSpeed", type: "uint16", + baseType: "uint16", array: "false", scale: 1000, offset: 0, @@ -8565,6 +9157,7 @@ const Profile = { num: 7, name: "swimStroke", type: "swimStroke", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -8579,6 +9172,7 @@ const Profile = { num: 9, name: "avgSwimmingCadence", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -8593,6 +9187,7 @@ const Profile = { num: 10, name: "eventGroup", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -8607,6 +9202,7 @@ const Profile = { num: 11, name: "totalCalories", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -8621,6 +9217,7 @@ const Profile = { num: 12, name: "lengthType", type: "lengthType", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -8635,6 +9232,7 @@ const Profile = { num: 18, name: "playerScore", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -8649,6 +9247,7 @@ const Profile = { num: 19, name: "opponentScore", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -8663,6 +9262,7 @@ const Profile = { num: 20, // stroke_type enum used as the index name: "strokeCount", type: "uint16", + baseType: "uint16", array: "true", scale: 1, offset: 0, @@ -8677,6 +9277,7 @@ const Profile = { num: 21, // zone number used as the index name: "zoneCount", type: "uint16", + baseType: "uint16", array: "true", scale: 1, offset: 0, @@ -8691,6 +9292,7 @@ const Profile = { num: 22, name: "enhancedAvgRespirationRate", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -8705,6 +9307,7 @@ const Profile = { num: 23, name: "enhancedMaxRespirationRate", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -8719,6 +9322,7 @@ const Profile = { num: 24, name: "avgRespirationRate", type: "uint8", + baseType: "uint8", array: "false", scale: [1, ], offset: [0, ], @@ -8733,6 +9337,7 @@ const Profile = { num: 25, name: "maxRespirationRate", type: "uint8", + baseType: "uint8", array: "false", scale: [1, ], offset: [0, ], @@ -8754,6 +9359,7 @@ const Profile = { num: 253, name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -8768,6 +9374,7 @@ const Profile = { num: 0, name: "positionLat", type: "sint32", + baseType: "sint32", array: "false", scale: 1, offset: 0, @@ -8782,6 +9389,7 @@ const Profile = { num: 1, name: "positionLong", type: "sint32", + baseType: "sint32", array: "false", scale: 1, offset: 0, @@ -8796,6 +9404,7 @@ const Profile = { num: 2, name: "altitude", type: "uint16", + baseType: "uint16", array: "false", scale: [5, ], offset: [500, ], @@ -8810,6 +9419,7 @@ const Profile = { num: 3, name: "heartRate", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -8824,6 +9434,7 @@ const Profile = { num: 4, name: "cadence", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -8838,6 +9449,7 @@ const Profile = { num: 5, name: "distance", type: "uint32", + baseType: "uint32", array: "false", scale: 100, offset: 0, @@ -8852,6 +9464,7 @@ const Profile = { num: 6, name: "speed", type: "uint16", + baseType: "uint16", array: "false", scale: [1000, ], offset: [0, ], @@ -8866,6 +9479,7 @@ const Profile = { num: 7, name: "power", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -8880,6 +9494,7 @@ const Profile = { num: 8, name: "compressedSpeedDistance", type: "byte", + baseType: "byte", array: "true", scale: [100, 16, ], offset: [0, 0, ], @@ -8894,6 +9509,7 @@ const Profile = { num: 9, name: "grade", type: "sint16", + baseType: "sint16", array: "false", scale: 100, offset: 0, @@ -8908,6 +9524,7 @@ const Profile = { num: 10, // Relative. 0 is none 254 is Max. name: "resistance", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -8922,6 +9539,7 @@ const Profile = { num: 11, name: "timeFromCourse", type: "sint32", + baseType: "sint32", array: "false", scale: 1000, offset: 0, @@ -8936,6 +9554,7 @@ const Profile = { num: 12, name: "cycleLength", type: "uint8", + baseType: "uint8", array: "false", scale: 100, offset: 0, @@ -8950,6 +9569,7 @@ const Profile = { num: 13, name: "temperature", type: "sint8", + baseType: "sint8", array: "false", scale: 1, offset: 0, @@ -8964,6 +9584,7 @@ const Profile = { num: 17, // Speed at 1s intervals. Timestamp field indicates time of last array element. name: "speed1s", type: "uint8", + baseType: "uint8", array: "true", scale: 16, offset: 0, @@ -8978,6 +9599,7 @@ const Profile = { num: 18, name: "cycles", type: "uint8", + baseType: "uint8", array: "false", scale: [1, ], offset: [0, ], @@ -8992,6 +9614,7 @@ const Profile = { num: 19, name: "totalCycles", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -9006,6 +9629,7 @@ const Profile = { num: 28, name: "compressedAccumulatedPower", type: "uint16", + baseType: "uint16", array: "false", scale: [1, ], offset: [0, ], @@ -9020,6 +9644,7 @@ const Profile = { num: 29, name: "accumulatedPower", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -9034,6 +9659,7 @@ const Profile = { num: 30, name: "leftRightBalance", type: "leftRightBalance", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -9048,6 +9674,7 @@ const Profile = { num: 31, name: "gpsAccuracy", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -9062,6 +9689,7 @@ const Profile = { num: 32, name: "verticalSpeed", type: "sint16", + baseType: "sint16", array: "false", scale: 1000, offset: 0, @@ -9076,6 +9704,7 @@ const Profile = { num: 33, name: "calories", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -9090,6 +9719,7 @@ const Profile = { num: 39, name: "verticalOscillation", type: "uint16", + baseType: "uint16", array: "false", scale: 10, offset: 0, @@ -9104,6 +9734,7 @@ const Profile = { num: 40, name: "stanceTimePercent", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -9118,6 +9749,7 @@ const Profile = { num: 41, name: "stanceTime", type: "uint16", + baseType: "uint16", array: "false", scale: 10, offset: 0, @@ -9132,6 +9764,7 @@ const Profile = { num: 42, name: "activityType", type: "activityType", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -9146,6 +9779,7 @@ const Profile = { num: 43, name: "leftTorqueEffectiveness", type: "uint8", + baseType: "uint8", array: "false", scale: 2, offset: 0, @@ -9160,6 +9794,7 @@ const Profile = { num: 44, name: "rightTorqueEffectiveness", type: "uint8", + baseType: "uint8", array: "false", scale: 2, offset: 0, @@ -9174,6 +9809,7 @@ const Profile = { num: 45, name: "leftPedalSmoothness", type: "uint8", + baseType: "uint8", array: "false", scale: 2, offset: 0, @@ -9188,6 +9824,7 @@ const Profile = { num: 46, name: "rightPedalSmoothness", type: "uint8", + baseType: "uint8", array: "false", scale: 2, offset: 0, @@ -9202,6 +9839,7 @@ const Profile = { num: 47, name: "combinedPedalSmoothness", type: "uint8", + baseType: "uint8", array: "false", scale: 2, offset: 0, @@ -9216,6 +9854,7 @@ const Profile = { num: 48, name: "time128", type: "uint8", + baseType: "uint8", array: "false", scale: 128, offset: 0, @@ -9230,6 +9869,7 @@ const Profile = { num: 49, name: "strokeType", type: "strokeType", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -9244,6 +9884,7 @@ const Profile = { num: 50, name: "zone", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -9258,6 +9899,7 @@ const Profile = { num: 51, name: "ballSpeed", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -9272,6 +9914,7 @@ const Profile = { num: 52, // Log cadence and fractional cadence for backwards compatability name: "cadence256", type: "uint16", + baseType: "uint16", array: "false", scale: 256, offset: 0, @@ -9286,6 +9929,7 @@ const Profile = { num: 53, name: "fractionalCadence", type: "uint8", + baseType: "uint8", array: "false", scale: 128, offset: 0, @@ -9300,6 +9944,7 @@ const Profile = { num: 54, // Total saturated and unsaturated hemoglobin name: "totalHemoglobinConc", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -9314,6 +9959,7 @@ const Profile = { num: 55, // Min saturated and unsaturated hemoglobin name: "totalHemoglobinConcMin", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -9328,6 +9974,7 @@ const Profile = { num: 56, // Max saturated and unsaturated hemoglobin name: "totalHemoglobinConcMax", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -9342,6 +9989,7 @@ const Profile = { num: 57, // Percentage of hemoglobin saturated with oxygen name: "saturatedHemoglobinPercent", type: "uint16", + baseType: "uint16", array: "false", scale: 10, offset: 0, @@ -9356,6 +10004,7 @@ const Profile = { num: 58, // Min percentage of hemoglobin saturated with oxygen name: "saturatedHemoglobinPercentMin", type: "uint16", + baseType: "uint16", array: "false", scale: 10, offset: 0, @@ -9370,6 +10019,7 @@ const Profile = { num: 59, // Max percentage of hemoglobin saturated with oxygen name: "saturatedHemoglobinPercentMax", type: "uint16", + baseType: "uint16", array: "false", scale: 10, offset: 0, @@ -9384,6 +10034,7 @@ const Profile = { num: 62, name: "deviceIndex", type: "deviceIndex", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -9398,6 +10049,7 @@ const Profile = { num: 67, // Left platform center offset name: "leftPco", type: "sint8", + baseType: "sint8", array: "false", scale: 1, offset: 0, @@ -9412,6 +10064,7 @@ const Profile = { num: 68, // Right platform center offset name: "rightPco", type: "sint8", + baseType: "sint8", array: "false", scale: 1, offset: 0, @@ -9426,6 +10079,7 @@ const Profile = { num: 69, // Left power phase angles. Data value indexes defined by power_phase_type. name: "leftPowerPhase", type: "uint8", + baseType: "uint8", array: "true", scale: 0.7111111, offset: 0, @@ -9440,6 +10094,7 @@ const Profile = { num: 70, // Left power phase peak angles. Data value indexes defined by power_phase_type. name: "leftPowerPhasePeak", type: "uint8", + baseType: "uint8", array: "true", scale: 0.7111111, offset: 0, @@ -9454,6 +10109,7 @@ const Profile = { num: 71, // Right power phase angles. Data value indexes defined by power_phase_type. name: "rightPowerPhase", type: "uint8", + baseType: "uint8", array: "true", scale: 0.7111111, offset: 0, @@ -9468,6 +10124,7 @@ const Profile = { num: 72, // Right power phase peak angles. Data value indexes defined by power_phase_type. name: "rightPowerPhasePeak", type: "uint8", + baseType: "uint8", array: "true", scale: 0.7111111, offset: 0, @@ -9482,6 +10139,7 @@ const Profile = { num: 73, name: "enhancedSpeed", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -9496,6 +10154,7 @@ const Profile = { num: 78, name: "enhancedAltitude", type: "uint32", + baseType: "uint32", array: "false", scale: 5, offset: 500, @@ -9510,6 +10169,7 @@ const Profile = { num: 81, // lev battery state of charge name: "batterySoc", type: "uint8", + baseType: "uint8", array: "false", scale: 2, offset: 0, @@ -9524,6 +10184,7 @@ const Profile = { num: 82, // lev motor power name: "motorPower", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -9538,6 +10199,7 @@ const Profile = { num: 83, name: "verticalRatio", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -9552,6 +10214,7 @@ const Profile = { num: 84, name: "stanceTimeBalance", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -9566,6 +10229,7 @@ const Profile = { num: 85, name: "stepLength", type: "uint16", + baseType: "uint16", array: "false", scale: 10, offset: 0, @@ -9580,6 +10244,7 @@ const Profile = { num: 87, // Supports larger cycle sizes needed for paddlesports. Max cycle size: 655.35 name: "cycleLength16", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -9594,6 +10259,7 @@ const Profile = { num: 91, // Includes atmospheric pressure name: "absolutePressure", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -9608,6 +10274,7 @@ const Profile = { num: 92, // 0 if above water name: "depth", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -9622,6 +10289,7 @@ const Profile = { num: 93, // 0 if above water name: "nextStopDepth", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -9636,6 +10304,7 @@ const Profile = { num: 94, name: "nextStopTime", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -9650,6 +10319,7 @@ const Profile = { num: 95, name: "timeToSurface", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -9664,6 +10334,7 @@ const Profile = { num: 96, name: "ndlTime", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -9678,6 +10349,7 @@ const Profile = { num: 97, name: "cnsLoad", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -9692,6 +10364,7 @@ const Profile = { num: 98, name: "n2Load", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -9706,6 +10379,7 @@ const Profile = { num: 99, name: "respirationRate", type: "uint8", + baseType: "uint8", array: "false", scale: [1, ], offset: [0, ], @@ -9720,6 +10394,7 @@ const Profile = { num: 108, name: "enhancedRespirationRate", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -9734,6 +10409,7 @@ const Profile = { num: 114, // The grit score estimates how challenging a route could be for a cyclist in terms of time spent going over sharp turns or large grade slopes. name: "grit", type: "float32", + baseType: "float32", array: "false", scale: 1, offset: 0, @@ -9748,6 +10424,7 @@ const Profile = { num: 115, // The flow score estimates how long distance wise a cyclist deaccelerates over intervals where deacceleration is unnecessary such as smooth turns or small grade angle intervals. name: "flow", type: "float32", + baseType: "float32", array: "false", scale: 1, offset: 0, @@ -9762,6 +10439,7 @@ const Profile = { num: 116, // Current Stress value name: "currentStress", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -9776,6 +10454,7 @@ const Profile = { num: 117, name: "ebikeTravelRange", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -9790,6 +10469,7 @@ const Profile = { num: 118, name: "ebikeBatteryLevel", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -9804,6 +10484,7 @@ const Profile = { num: 119, name: "ebikeAssistMode", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -9818,6 +10499,7 @@ const Profile = { num: 120, name: "ebikeAssistLevelPercent", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -9832,6 +10514,7 @@ const Profile = { num: 123, name: "airTimeRemaining", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -9846,6 +10529,7 @@ const Profile = { num: 124, // Pressure-based surface air consumption name: "pressureSac", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -9860,6 +10544,7 @@ const Profile = { num: 125, // Volumetric surface air consumption name: "volumeSac", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -9874,6 +10559,7 @@ const Profile = { num: 126, // Respiratory minute volume name: "rmv", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -9888,6 +10574,7 @@ const Profile = { num: 127, name: "ascentRate", type: "sint32", + baseType: "sint32", array: "false", scale: 1000, offset: 0, @@ -9902,6 +10589,7 @@ const Profile = { num: 129, // Current partial pressure of oxygen name: "po2", type: "uint8", + baseType: "uint8", array: "false", scale: 100, offset: 0, @@ -9916,6 +10604,7 @@ const Profile = { num: 139, name: "coreTemperature", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -9937,6 +10626,7 @@ const Profile = { num: 253, name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -9951,6 +10641,7 @@ const Profile = { num: 0, name: "event", type: "event", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -9965,6 +10656,7 @@ const Profile = { num: 1, name: "eventType", type: "eventType", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -9979,6 +10671,7 @@ const Profile = { num: 2, name: "data16", type: "uint16", + baseType: "uint16", array: "false", scale: [1, ], offset: [0, ], @@ -9993,6 +10686,7 @@ const Profile = { num: 3, name: "data", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -10004,6 +10698,7 @@ const Profile = { subFields: [{ name: "timerTrigger", type: "timerTrigger", + baseType: "enum", array: "", scale: 1, offset: 0, @@ -10018,6 +10713,7 @@ const Profile = { { name: "coursePointIndex", type: "messageIndex", + baseType: "uint16", array: "", scale: 1, offset: 0, @@ -10032,6 +10728,7 @@ const Profile = { { name: "batteryLevel", type: "uint16", + baseType: "uint16", array: "", scale: 1000, offset: 0, @@ -10046,6 +10743,7 @@ const Profile = { { name: "virtualPartnerSpeed", type: "uint16", + baseType: "uint16", array: "", scale: 1000, offset: 0, @@ -10060,6 +10758,7 @@ const Profile = { { name: "hrHighAlert", type: "uint8", + baseType: "uint8", array: "", scale: 1, offset: 0, @@ -10074,6 +10773,7 @@ const Profile = { { name: "hrLowAlert", type: "uint8", + baseType: "uint8", array: "", scale: 1, offset: 0, @@ -10088,6 +10788,7 @@ const Profile = { { name: "speedHighAlert", type: "uint32", + baseType: "uint32", array: "", scale: 1000, offset: 0, @@ -10102,6 +10803,7 @@ const Profile = { { name: "speedLowAlert", type: "uint32", + baseType: "uint32", array: "", scale: 1000, offset: 0, @@ -10116,6 +10818,7 @@ const Profile = { { name: "cadHighAlert", type: "uint16", + baseType: "uint16", array: "", scale: 1, offset: 0, @@ -10130,6 +10833,7 @@ const Profile = { { name: "cadLowAlert", type: "uint16", + baseType: "uint16", array: "", scale: 1, offset: 0, @@ -10144,6 +10848,7 @@ const Profile = { { name: "powerHighAlert", type: "uint16", + baseType: "uint16", array: "", scale: 1, offset: 0, @@ -10158,6 +10863,7 @@ const Profile = { { name: "powerLowAlert", type: "uint16", + baseType: "uint16", array: "", scale: 1, offset: 0, @@ -10172,6 +10878,7 @@ const Profile = { { name: "timeDurationAlert", type: "uint32", + baseType: "uint32", array: "", scale: 1000, offset: 0, @@ -10186,6 +10893,7 @@ const Profile = { { name: "distanceDurationAlert", type: "uint32", + baseType: "uint32", array: "", scale: 100, offset: 0, @@ -10200,6 +10908,7 @@ const Profile = { { name: "calorieDurationAlert", type: "uint32", + baseType: "uint32", array: "", scale: 1, offset: 0, @@ -10214,6 +10923,7 @@ const Profile = { { name: "fitnessEquipmentState", type: "fitnessEquipmentState", + baseType: "enum", array: "", scale: 1, offset: 0, @@ -10228,6 +10938,7 @@ const Profile = { { name: "sportPoint", type: "uint32", + baseType: "uint32", array: "", scale: [1, 1, ], offset: [0, 0, ], @@ -10242,6 +10953,7 @@ const Profile = { { name: "gearChangeData", type: "uint32", + baseType: "uint32", array: "", scale: [1, 1, 1, 1, ], offset: [0, 0, 0, 0, ], @@ -10257,6 +10969,7 @@ const Profile = { { name: "riderPosition", // Indicates the rider position value. type: "riderPositionType", + baseType: "enum", array: "", scale: 1, offset: 0, @@ -10271,6 +10984,7 @@ const Profile = { { name: "commTimeout", type: "commTimeoutType", + baseType: "uint16", array: "", scale: 1, offset: 0, @@ -10285,6 +10999,7 @@ const Profile = { { name: "diveAlert", type: "diveAlert", + baseType: "enum", array: "", scale: 1, offset: 0, @@ -10299,6 +11014,7 @@ const Profile = { { name: "autoActivityDetectDuration", type: "uint16", + baseType: "uint16", array: "", scale: 1, offset: 0, @@ -10313,6 +11029,7 @@ const Profile = { { name: "radarThreatAlert", // The first byte is the radar_threat_level_max, the second byte is the radar_threat_count, third bytes is the average approach speed, and the 4th byte is the max approach speed type: "uint32", + baseType: "uint32", array: "", scale: [1, 1, 10, 10, ], offset: [0, 0, 0, 0, ], @@ -10330,6 +11047,7 @@ const Profile = { num: 4, name: "eventGroup", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -10344,6 +11062,7 @@ const Profile = { num: 7, // Do not populate directly. Autogenerated by decoder for sport_point subfield components name: "score", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -10358,6 +11077,7 @@ const Profile = { num: 8, // Do not populate directly. Autogenerated by decoder for sport_point subfield components name: "opponentScore", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -10372,6 +11092,7 @@ const Profile = { num: 9, // Do not populate directly. Autogenerated by decoder for gear_change subfield components. Front gear number. 1 is innermost. name: "frontGearNum", type: "uint8z", + baseType: "uint8z", array: "false", scale: 1, offset: 0, @@ -10386,6 +11107,7 @@ const Profile = { num: 10, // Do not populate directly. Autogenerated by decoder for gear_change subfield components. Number of front teeth. name: "frontGear", type: "uint8z", + baseType: "uint8z", array: "false", scale: 1, offset: 0, @@ -10400,6 +11122,7 @@ const Profile = { num: 11, // Do not populate directly. Autogenerated by decoder for gear_change subfield components. Rear gear number. 1 is innermost. name: "rearGearNum", type: "uint8z", + baseType: "uint8z", array: "false", scale: 1, offset: 0, @@ -10414,6 +11137,7 @@ const Profile = { num: 12, // Do not populate directly. Autogenerated by decoder for gear_change subfield components. Number of rear teeth. name: "rearGear", type: "uint8z", + baseType: "uint8z", array: "false", scale: 1, offset: 0, @@ -10428,6 +11152,7 @@ const Profile = { num: 13, name: "deviceIndex", type: "deviceIndex", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -10442,6 +11167,7 @@ const Profile = { num: 14, // Activity Type associated with an auto_activity_detect event name: "activityType", type: "activityType", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -10456,6 +11182,7 @@ const Profile = { num: 15, // Timestamp of when the event started name: "startTimestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -10467,6 +11194,7 @@ const Profile = { subFields: [{ name: "autoActivityDetectStartTimestamp", // Auto Activity Detect Start Timestamp. type: "dateTime", + baseType: "uint32", array: "", scale: 1, offset: 0, @@ -10484,6 +11212,7 @@ const Profile = { num: 21, // Do not populate directly. Autogenerated by decoder for threat_alert subfield components. name: "radarThreatLevelMax", type: "radarThreatLevelType", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -10498,6 +11227,7 @@ const Profile = { num: 22, // Do not populate directly. Autogenerated by decoder for threat_alert subfield components. name: "radarThreatCount", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -10512,6 +11242,7 @@ const Profile = { num: 23, // Do not populate directly. Autogenerated by decoder for radar_threat_alert subfield components name: "radarThreatAvgApproachSpeed", type: "uint8", + baseType: "uint8", array: "false", scale: 10, offset: 0, @@ -10526,6 +11257,7 @@ const Profile = { num: 24, // Do not populate directly. Autogenerated by decoder for radar_threat_alert subfield components name: "radarThreatMaxApproachSpeed", type: "uint8", + baseType: "uint8", array: "false", scale: 10, offset: 0, @@ -10547,6 +11279,7 @@ const Profile = { num: 253, name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -10561,6 +11294,7 @@ const Profile = { num: 0, name: "deviceIndex", type: "deviceIndex", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -10575,6 +11309,7 @@ const Profile = { num: 1, name: "deviceType", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -10586,6 +11321,7 @@ const Profile = { subFields: [{ name: "bleDeviceType", type: "bleDeviceType", + baseType: "uint8", array: "", scale: 1, offset: 0, @@ -10600,6 +11336,7 @@ const Profile = { { name: "antplusDeviceType", type: "antplusDeviceType", + baseType: "uint8", array: "", scale: 1, offset: 0, @@ -10614,6 +11351,7 @@ const Profile = { { name: "antDeviceType", type: "uint8", + baseType: "uint8", array: "", scale: 1, offset: 0, @@ -10628,6 +11366,7 @@ const Profile = { { name: "localDeviceType", type: "localDeviceType", + baseType: "uint8", array: "", scale: 1, offset: 0, @@ -10645,6 +11384,7 @@ const Profile = { num: 2, name: "manufacturer", type: "manufacturer", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -10659,6 +11399,7 @@ const Profile = { num: 3, name: "serialNumber", type: "uint32z", + baseType: "uint32z", array: "false", scale: 1, offset: 0, @@ -10673,6 +11414,7 @@ const Profile = { num: 4, name: "product", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -10684,6 +11426,7 @@ const Profile = { subFields: [{ name: "faveroProduct", type: "faveroProduct", + baseType: "uint16", array: "", scale: 1, offset: 0, @@ -10698,6 +11441,7 @@ const Profile = { { name: "garminProduct", type: "garminProduct", + baseType: "uint16", array: "", scale: 1, offset: 0, @@ -10718,6 +11462,7 @@ const Profile = { num: 5, name: "softwareVersion", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -10732,6 +11477,7 @@ const Profile = { num: 6, name: "hardwareVersion", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -10746,6 +11492,7 @@ const Profile = { num: 7, // Reset by new battery or charge. name: "cumOperatingTime", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -10760,6 +11507,7 @@ const Profile = { num: 10, name: "batteryVoltage", type: "uint16", + baseType: "uint16", array: "false", scale: 256, offset: 0, @@ -10774,6 +11522,7 @@ const Profile = { num: 11, name: "batteryStatus", type: "batteryStatus", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -10788,6 +11537,7 @@ const Profile = { num: 18, // Indicates the location of the sensor name: "sensorPosition", type: "bodyLocation", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -10802,6 +11552,7 @@ const Profile = { num: 19, // Used to describe the sensor or location name: "descriptor", type: "string", + baseType: "string", array: "true", scale: 1, offset: 0, @@ -10816,6 +11567,7 @@ const Profile = { num: 20, name: "antTransmissionType", type: "uint8z", + baseType: "uint8z", array: "false", scale: 1, offset: 0, @@ -10830,6 +11582,7 @@ const Profile = { num: 21, name: "antDeviceNumber", type: "uint16z", + baseType: "uint16z", array: "false", scale: 1, offset: 0, @@ -10844,6 +11597,7 @@ const Profile = { num: 22, name: "antNetwork", type: "antNetwork", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -10858,6 +11612,7 @@ const Profile = { num: 25, name: "sourceType", type: "sourceType", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -10872,6 +11627,7 @@ const Profile = { num: 27, // Optional free form string to indicate the devices name or model name: "productName", type: "string", + baseType: "string", array: "true", scale: 1, offset: 0, @@ -10886,6 +11642,7 @@ const Profile = { num: 32, name: "batteryLevel", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -10907,6 +11664,7 @@ const Profile = { num: 253, name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -10921,6 +11679,7 @@ const Profile = { num: 0, name: "deviceIndex", type: "deviceIndex", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -10935,6 +11694,7 @@ const Profile = { num: 1, name: "batteryVoltage", type: "uint16", + baseType: "uint16", array: "false", scale: 256, offset: 0, @@ -10949,6 +11709,7 @@ const Profile = { num: 2, name: "batteryStatus", type: "batteryStatus", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -10963,6 +11724,7 @@ const Profile = { num: 3, name: "batteryIdentifier", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -10984,6 +11746,7 @@ const Profile = { num: 253, name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -10998,6 +11761,7 @@ const Profile = { num: 0, name: "type", type: "file", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -11012,6 +11776,7 @@ const Profile = { num: 1, name: "manufacturer", type: "manufacturer", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -11026,6 +11791,7 @@ const Profile = { num: 2, name: "product", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -11037,6 +11803,7 @@ const Profile = { subFields: [{ name: "faveroProduct", type: "faveroProduct", + baseType: "uint16", array: "", scale: 1, offset: 0, @@ -11051,6 +11818,7 @@ const Profile = { { name: "garminProduct", type: "garminProduct", + baseType: "uint16", array: "", scale: 1, offset: 0, @@ -11071,6 +11839,7 @@ const Profile = { num: 3, name: "serialNumber", type: "uint32z", + baseType: "uint32z", array: "false", scale: 1, offset: 0, @@ -11085,6 +11854,7 @@ const Profile = { num: 4, name: "timeCreated", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -11106,6 +11876,7 @@ const Profile = { num: 253, // time of update for current conditions, else forecast time name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -11120,6 +11891,7 @@ const Profile = { num: 0, // Current or forecast name: "weatherReport", type: "weatherReport", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -11134,6 +11906,7 @@ const Profile = { num: 1, name: "temperature", type: "sint8", + baseType: "sint8", array: "false", scale: 1, offset: 0, @@ -11148,6 +11921,7 @@ const Profile = { num: 2, // Corresponds to GSC Response weatherIcon field name: "condition", type: "weatherStatus", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -11162,6 +11936,7 @@ const Profile = { num: 3, name: "windDirection", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -11176,6 +11951,7 @@ const Profile = { num: 4, name: "windSpeed", type: "uint16", + baseType: "uint16", array: "false", scale: 1000, offset: 0, @@ -11190,6 +11966,7 @@ const Profile = { num: 5, // range 0-100 name: "precipitationProbability", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -11204,6 +11981,7 @@ const Profile = { num: 6, // Heat Index if GCS heatIdx above or equal to 90F or wind chill if GCS windChill below or equal to 32F name: "temperatureFeelsLike", type: "sint8", + baseType: "sint8", array: "false", scale: 1, offset: 0, @@ -11218,6 +11996,7 @@ const Profile = { num: 7, name: "relativeHumidity", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -11232,6 +12011,7 @@ const Profile = { num: 8, // string corresponding to GCS response location string name: "location", type: "string", + baseType: "string", array: "true", scale: 1, offset: 0, @@ -11246,6 +12026,7 @@ const Profile = { num: 9, name: "observedAtTime", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -11260,6 +12041,7 @@ const Profile = { num: 10, name: "observedLocationLat", type: "sint32", + baseType: "sint32", array: "false", scale: 1, offset: 0, @@ -11274,6 +12056,7 @@ const Profile = { num: 11, name: "observedLocationLong", type: "sint32", + baseType: "sint32", array: "false", scale: 1, offset: 0, @@ -11288,6 +12071,7 @@ const Profile = { num: 12, name: "dayOfWeek", type: "dayOfWeek", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -11302,6 +12086,7 @@ const Profile = { num: 13, name: "highTemperature", type: "sint8", + baseType: "sint8", array: "false", scale: 1, offset: 0, @@ -11316,6 +12101,7 @@ const Profile = { num: 14, name: "lowTemperature", type: "sint8", + baseType: "sint8", array: "false", scale: 1, offset: 0, @@ -11337,6 +12123,7 @@ const Profile = { num: 253, name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -11351,6 +12138,7 @@ const Profile = { num: 0, // Unique identifier from GCS report ID string, length is 12 name: "reportId", type: "string", + baseType: "string", array: "true", scale: 1, offset: 0, @@ -11365,6 +12153,7 @@ const Profile = { num: 1, // Time alert was issued name: "issueTime", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -11379,6 +12168,7 @@ const Profile = { num: 2, // Time alert expires name: "expireTime", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -11393,6 +12183,7 @@ const Profile = { num: 3, // Warning, Watch, Advisory, Statement name: "severity", type: "weatherSeverity", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -11407,6 +12198,7 @@ const Profile = { num: 4, // Tornado, Severe Thunderstorm, etc. name: "type", type: "weatherSevereType", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -11428,6 +12220,7 @@ const Profile = { num: 253, // Whole second part of the timestamp. name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -11442,6 +12235,7 @@ const Profile = { num: 0, // Millisecond part of the timestamp. name: "timestampMs", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -11456,6 +12250,7 @@ const Profile = { num: 1, name: "positionLat", type: "sint32", + baseType: "sint32", array: "false", scale: 1, offset: 0, @@ -11470,6 +12265,7 @@ const Profile = { num: 2, name: "positionLong", type: "sint32", + baseType: "sint32", array: "false", scale: 1, offset: 0, @@ -11484,6 +12280,7 @@ const Profile = { num: 3, name: "enhancedAltitude", type: "uint32", + baseType: "uint32", array: "false", scale: 5, offset: 500, @@ -11498,6 +12295,7 @@ const Profile = { num: 4, name: "enhancedSpeed", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -11512,6 +12310,7 @@ const Profile = { num: 5, name: "heading", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -11526,6 +12325,7 @@ const Profile = { num: 6, // Used to correlate UTC to system time if the timestamp of the message is in system time. This UTC time is derived from the GPS data. name: "utcTimestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -11540,6 +12340,7 @@ const Profile = { num: 7, // velocity[0] is lon velocity. Velocity[1] is lat velocity. Velocity[2] is altitude velocity. name: "velocity", type: "sint16", + baseType: "sint16", array: "true", scale: 100, offset: 0, @@ -11561,6 +12362,7 @@ const Profile = { num: 253, // Whole second part of the timestamp. name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -11575,6 +12377,7 @@ const Profile = { num: 0, // Millisecond part of the timestamp. name: "timestampMs", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -11589,6 +12392,7 @@ const Profile = { num: 1, name: "cameraEventType", type: "cameraEventType", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -11603,6 +12407,7 @@ const Profile = { num: 2, name: "cameraFileUuid", type: "string", + baseType: "string", array: "true", scale: 1, offset: 0, @@ -11617,6 +12422,7 @@ const Profile = { num: 3, name: "cameraOrientation", type: "cameraOrientationType", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -11638,6 +12444,7 @@ const Profile = { num: 253, // Whole second part of the timestamp name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -11652,6 +12459,7 @@ const Profile = { num: 0, // Millisecond part of the timestamp. name: "timestampMs", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -11666,6 +12474,7 @@ const Profile = { num: 1, // Each time in the array describes the time at which the gyro sample with the corrosponding index was taken. Limited to 30 samples in each message. The samples may span across seconds. Array size must match the number of samples in gyro_x and gyro_y and gyro_z name: "sampleTimeOffset", type: "uint16", + baseType: "uint16", array: "true", scale: 1, offset: 0, @@ -11680,6 +12489,7 @@ const Profile = { num: 2, // These are the raw ADC reading. Maximum number of samples is 30 in each message. The samples may span across seconds. A conversion will need to be done on this data once read. name: "gyroX", type: "uint16", + baseType: "uint16", array: "true", scale: 1, offset: 0, @@ -11694,6 +12504,7 @@ const Profile = { num: 3, // These are the raw ADC reading. Maximum number of samples is 30 in each message. The samples may span across seconds. A conversion will need to be done on this data once read. name: "gyroY", type: "uint16", + baseType: "uint16", array: "true", scale: 1, offset: 0, @@ -11708,6 +12519,7 @@ const Profile = { num: 4, // These are the raw ADC reading. Maximum number of samples is 30 in each message. The samples may span across seconds. A conversion will need to be done on this data once read. name: "gyroZ", type: "uint16", + baseType: "uint16", array: "true", scale: 1, offset: 0, @@ -11722,6 +12534,7 @@ const Profile = { num: 5, // Calibrated gyro reading name: "calibratedGyroX", type: "float32", + baseType: "float32", array: "true", scale: 1, offset: 0, @@ -11736,6 +12549,7 @@ const Profile = { num: 6, // Calibrated gyro reading name: "calibratedGyroY", type: "float32", + baseType: "float32", array: "true", scale: 1, offset: 0, @@ -11750,6 +12564,7 @@ const Profile = { num: 7, // Calibrated gyro reading name: "calibratedGyroZ", type: "float32", + baseType: "float32", array: "true", scale: 1, offset: 0, @@ -11771,6 +12586,7 @@ const Profile = { num: 253, // Whole second part of the timestamp name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -11785,6 +12601,7 @@ const Profile = { num: 0, // Millisecond part of the timestamp. name: "timestampMs", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -11799,6 +12616,7 @@ const Profile = { num: 1, // Each time in the array describes the time at which the accelerometer sample with the corrosponding index was taken. Limited to 30 samples in each message. The samples may span across seconds. Array size must match the number of samples in accel_x and accel_y and accel_z name: "sampleTimeOffset", type: "uint16", + baseType: "uint16", array: "true", scale: 1, offset: 0, @@ -11813,6 +12631,7 @@ const Profile = { num: 2, // These are the raw ADC reading. Maximum number of samples is 30 in each message. The samples may span across seconds. A conversion will need to be done on this data once read. name: "accelX", type: "uint16", + baseType: "uint16", array: "true", scale: 1, offset: 0, @@ -11827,6 +12646,7 @@ const Profile = { num: 3, // These are the raw ADC reading. Maximum number of samples is 30 in each message. The samples may span across seconds. A conversion will need to be done on this data once read. name: "accelY", type: "uint16", + baseType: "uint16", array: "true", scale: 1, offset: 0, @@ -11841,6 +12661,7 @@ const Profile = { num: 4, // These are the raw ADC reading. Maximum number of samples is 30 in each message. The samples may span across seconds. A conversion will need to be done on this data once read. name: "accelZ", type: "uint16", + baseType: "uint16", array: "true", scale: 1, offset: 0, @@ -11855,6 +12676,7 @@ const Profile = { num: 5, // Calibrated accel reading name: "calibratedAccelX", type: "float32", + baseType: "float32", array: "true", scale: 1, offset: 0, @@ -11869,6 +12691,7 @@ const Profile = { num: 6, // Calibrated accel reading name: "calibratedAccelY", type: "float32", + baseType: "float32", array: "true", scale: 1, offset: 0, @@ -11883,6 +12706,7 @@ const Profile = { num: 7, // Calibrated accel reading name: "calibratedAccelZ", type: "float32", + baseType: "float32", array: "true", scale: 1, offset: 0, @@ -11897,6 +12721,7 @@ const Profile = { num: 8, // Calibrated accel reading name: "compressedCalibratedAccelX", type: "sint16", + baseType: "sint16", array: "true", scale: 1, offset: 0, @@ -11911,6 +12736,7 @@ const Profile = { num: 9, // Calibrated accel reading name: "compressedCalibratedAccelY", type: "sint16", + baseType: "sint16", array: "true", scale: 1, offset: 0, @@ -11925,6 +12751,7 @@ const Profile = { num: 10, // Calibrated accel reading name: "compressedCalibratedAccelZ", type: "sint16", + baseType: "sint16", array: "true", scale: 1, offset: 0, @@ -11946,6 +12773,7 @@ const Profile = { num: 253, // Whole second part of the timestamp name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -11960,6 +12788,7 @@ const Profile = { num: 0, // Millisecond part of the timestamp. name: "timestampMs", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -11974,6 +12803,7 @@ const Profile = { num: 1, // Each time in the array describes the time at which the compass sample with the corrosponding index was taken. Limited to 30 samples in each message. The samples may span across seconds. Array size must match the number of samples in cmps_x and cmps_y and cmps_z name: "sampleTimeOffset", type: "uint16", + baseType: "uint16", array: "true", scale: 1, offset: 0, @@ -11988,6 +12818,7 @@ const Profile = { num: 2, // These are the raw ADC reading. Maximum number of samples is 30 in each message. The samples may span across seconds. A conversion will need to be done on this data once read. name: "magX", type: "uint16", + baseType: "uint16", array: "true", scale: 1, offset: 0, @@ -12002,6 +12833,7 @@ const Profile = { num: 3, // These are the raw ADC reading. Maximum number of samples is 30 in each message. The samples may span across seconds. A conversion will need to be done on this data once read. name: "magY", type: "uint16", + baseType: "uint16", array: "true", scale: 1, offset: 0, @@ -12016,6 +12848,7 @@ const Profile = { num: 4, // These are the raw ADC reading. Maximum number of samples is 30 in each message. The samples may span across seconds. A conversion will need to be done on this data once read. name: "magZ", type: "uint16", + baseType: "uint16", array: "true", scale: 1, offset: 0, @@ -12030,6 +12863,7 @@ const Profile = { num: 5, // Calibrated Magnetometer reading name: "calibratedMagX", type: "float32", + baseType: "float32", array: "true", scale: 1, offset: 0, @@ -12044,6 +12878,7 @@ const Profile = { num: 6, // Calibrated Magnetometer reading name: "calibratedMagY", type: "float32", + baseType: "float32", array: "true", scale: 1, offset: 0, @@ -12058,6 +12893,7 @@ const Profile = { num: 7, // Calibrated Magnetometer reading name: "calibratedMagZ", type: "float32", + baseType: "float32", array: "true", scale: 1, offset: 0, @@ -12079,6 +12915,7 @@ const Profile = { num: 253, // Whole second part of the timestamp name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -12093,6 +12930,7 @@ const Profile = { num: 0, // Millisecond part of the timestamp. name: "timestampMs", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -12107,6 +12945,7 @@ const Profile = { num: 1, // Each time in the array describes the time at which the barometer sample with the corrosponding index was taken. The samples may span across seconds. Array size must match the number of samples in baro_cal name: "sampleTimeOffset", type: "uint16", + baseType: "uint16", array: "true", scale: 1, offset: 0, @@ -12121,6 +12960,7 @@ const Profile = { num: 2, // These are the raw ADC reading. The samples may span across seconds. A conversion will need to be done on this data once read. name: "baroPres", type: "uint32", + baseType: "uint32", array: "true", scale: 1, offset: 0, @@ -12142,6 +12982,7 @@ const Profile = { num: 253, // Whole second part of the timestamp name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -12156,6 +12997,7 @@ const Profile = { num: 0, // Indicates which sensor the calibration is for name: "sensorType", type: "sensorType", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -12170,6 +13012,7 @@ const Profile = { num: 1, // Calibration factor used to convert from raw ADC value to degrees, g, etc. name: "calibrationFactor", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -12181,6 +13024,7 @@ const Profile = { subFields: [{ name: "accelCalFactor", // Accelerometer calibration factor type: "uint32", + baseType: "uint32", array: "", scale: 1, offset: 0, @@ -12195,6 +13039,7 @@ const Profile = { { name: "gyroCalFactor", // Gyro calibration factor type: "uint32", + baseType: "uint32", array: "", scale: 1, offset: 0, @@ -12212,6 +13057,7 @@ const Profile = { num: 2, // Calibration factor divisor name: "calibrationDivisor", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -12226,6 +13072,7 @@ const Profile = { num: 3, // Level shift value used to shift the ADC value back into range name: "levelShift", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -12240,6 +13087,7 @@ const Profile = { num: 4, // Internal calibration factors, one for each: xy, yx, zx name: "offsetCal", type: "sint32", + baseType: "sint32", array: "true", scale: 1, offset: 0, @@ -12254,6 +13102,7 @@ const Profile = { num: 5, // 3 x 3 rotation matrix (row major) name: "orientationMatrix", type: "sint32", + baseType: "sint32", array: "true", scale: 65535, offset: 0, @@ -12275,6 +13124,7 @@ const Profile = { num: 253, // Whole second part of the timestamp name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -12289,6 +13139,7 @@ const Profile = { num: 0, // Indicates which sensor the calibration is for name: "sensorType", type: "sensorType", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -12303,6 +13154,7 @@ const Profile = { num: 1, // Calibration factor used to convert from raw ADC value to degrees, g, etc. name: "calibrationFactor", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -12314,6 +13166,7 @@ const Profile = { subFields: [{ name: "baroCalFactor", // Barometer calibration factor type: "uint32", + baseType: "uint32", array: "", scale: 1, offset: 0, @@ -12331,6 +13184,7 @@ const Profile = { num: 2, // Calibration factor divisor name: "calibrationDivisor", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -12345,6 +13199,7 @@ const Profile = { num: 3, // Level shift value used to shift the ADC value back into range name: "levelShift", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -12359,6 +13214,7 @@ const Profile = { num: 4, // Internal Calibration factor name: "offsetCal", type: "sint32", + baseType: "sint32", array: "false", scale: 1, offset: 0, @@ -12380,6 +13236,7 @@ const Profile = { num: 253, // Whole second part of the timestamp name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -12394,6 +13251,7 @@ const Profile = { num: 0, // Millisecond part of the timestamp. name: "timestampMs", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -12408,6 +13266,7 @@ const Profile = { num: 1, // Number of the frame that the timestamp and timestamp_ms correlate to name: "frameNumber", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -12429,6 +13288,7 @@ const Profile = { num: 253, // Timestamp message was output name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -12443,6 +13303,7 @@ const Profile = { num: 0, // Fractional part of timestamp, added to timestamp name: "timestampMs", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -12457,6 +13318,7 @@ const Profile = { num: 1, // Offset of PID reading [i] from start_timestamp+start_timestamp_ms. Readings may span accross seconds. name: "timeOffset", type: "uint16", + baseType: "uint16", array: "true", scale: 1, offset: 0, @@ -12471,6 +13333,7 @@ const Profile = { num: 2, // Parameter ID name: "pid", type: "byte", + baseType: "byte", array: "false", scale: 1, offset: 0, @@ -12485,6 +13348,7 @@ const Profile = { num: 3, // Raw parameter data name: "rawData", type: "byte", + baseType: "byte", array: "true", scale: 1, offset: 0, @@ -12499,6 +13363,7 @@ const Profile = { num: 4, // Optional, data size of PID[i]. If not specified refer to SAE J1979. name: "pidDataSize", type: "uint8", + baseType: "uint8", array: "true", scale: 1, offset: 0, @@ -12513,6 +13378,7 @@ const Profile = { num: 5, // System time associated with sample expressed in ms, can be used instead of time_offset. There will be a system_time value for each raw_data element. For multibyte pids the system_time is repeated. name: "systemTime", type: "uint32", + baseType: "uint32", array: "true", scale: 1, offset: 0, @@ -12527,6 +13393,7 @@ const Profile = { num: 6, // Timestamp of first sample recorded in the message. Used with time_offset to generate time of each sample name: "startTimestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -12541,6 +13408,7 @@ const Profile = { num: 7, // Fractional part of start_timestamp name: "startTimestampMs", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -12562,6 +13430,7 @@ const Profile = { num: 253, // Timestamp message was output name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -12576,6 +13445,7 @@ const Profile = { num: 0, // Fractional part of timestamp, added to timestamp name: "timestampMs", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -12590,6 +13460,7 @@ const Profile = { num: 1, // NMEA sentence name: "sentence", type: "string", + baseType: "string", array: "true", scale: 1, offset: 0, @@ -12611,6 +13482,7 @@ const Profile = { num: 253, // Timestamp message was output name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -12625,6 +13497,7 @@ const Profile = { num: 0, // Fractional part of timestamp, added to timestamp name: "timestampMs", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -12639,6 +13512,7 @@ const Profile = { num: 1, // System time associated with sample expressed in ms. name: "systemTime", type: "uint32", + baseType: "uint32", array: "true", scale: 1, offset: 0, @@ -12653,6 +13527,7 @@ const Profile = { num: 2, // Range -PI/2 to +PI/2 name: "pitch", type: "sint16", + baseType: "sint16", array: "true", scale: 10430.38, offset: 0, @@ -12667,6 +13542,7 @@ const Profile = { num: 3, // Range -PI to +PI name: "roll", type: "sint16", + baseType: "sint16", array: "true", scale: 10430.38, offset: 0, @@ -12681,6 +13557,7 @@ const Profile = { num: 4, // Range -78.4 to +78.4 (-8 Gs to 8 Gs) name: "accelLateral", type: "sint16", + baseType: "sint16", array: "true", scale: 100, offset: 0, @@ -12695,6 +13572,7 @@ const Profile = { num: 5, // Range -78.4 to +78.4 (-8 Gs to 8 Gs) name: "accelNormal", type: "sint16", + baseType: "sint16", array: "true", scale: 100, offset: 0, @@ -12709,6 +13587,7 @@ const Profile = { num: 6, // Range -8.727 to +8.727 (-500 degs/sec to +500 degs/sec) name: "turnRate", type: "sint16", + baseType: "sint16", array: "true", scale: 1024, offset: 0, @@ -12723,6 +13602,7 @@ const Profile = { num: 7, name: "stage", type: "attitudeStage", + baseType: "enum", array: "true", scale: 1, offset: 0, @@ -12737,6 +13617,7 @@ const Profile = { num: 8, // The percent complete of the current attitude stage. Set to 0 for attitude stages 0, 1 and 2 and to 100 for attitude stage 3 by AHRS modules that do not support it. Range - 100 name: "attitudeStageComplete", type: "uint8", + baseType: "uint8", array: "true", scale: 1, offset: 0, @@ -12751,6 +13632,7 @@ const Profile = { num: 9, // Track Angle/Heading Range 0 - 2pi name: "track", type: "uint16", + baseType: "uint16", array: "true", scale: 10430.38, offset: 0, @@ -12765,6 +13647,7 @@ const Profile = { num: 10, name: "validity", type: "attitudeValidity", + baseType: "uint16", array: "true", scale: 1, offset: 0, @@ -12786,6 +13669,7 @@ const Profile = { num: 0, name: "url", type: "string", + baseType: "string", array: "true", scale: 1, offset: 0, @@ -12800,6 +13684,7 @@ const Profile = { num: 1, name: "hostingProvider", type: "string", + baseType: "string", array: "true", scale: 1, offset: 0, @@ -12814,6 +13699,7 @@ const Profile = { num: 2, // Playback time of video name: "duration", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -12835,6 +13721,7 @@ const Profile = { num: 254, // Long titles will be split into multiple parts name: "messageIndex", type: "messageIndex", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -12849,6 +13736,7 @@ const Profile = { num: 0, // Total number of title parts name: "messageCount", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -12863,6 +13751,7 @@ const Profile = { num: 1, name: "text", type: "string", + baseType: "string", array: "true", scale: 1, offset: 0, @@ -12884,6 +13773,7 @@ const Profile = { num: 254, // Long descriptions will be split into multiple parts name: "messageIndex", type: "messageIndex", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -12898,6 +13788,7 @@ const Profile = { num: 0, // Total number of description parts name: "messageCount", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -12912,6 +13803,7 @@ const Profile = { num: 1, name: "text", type: "string", + baseType: "string", array: "true", scale: 1, offset: 0, @@ -12933,6 +13825,7 @@ const Profile = { num: 0, name: "clipNumber", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -12947,6 +13840,7 @@ const Profile = { num: 1, name: "startTimestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -12961,6 +13855,7 @@ const Profile = { num: 2, name: "startTimestampMs", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -12975,6 +13870,7 @@ const Profile = { num: 3, name: "endTimestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -12989,6 +13885,7 @@ const Profile = { num: 4, name: "endTimestampMs", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -13003,6 +13900,7 @@ const Profile = { num: 6, // Start of clip in video time name: "clipStart", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -13017,6 +13915,7 @@ const Profile = { num: 7, // End of clip in video time name: "clipEnd", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -13038,6 +13937,7 @@ const Profile = { num: 254, // Timestamp of the set name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -13052,6 +13952,7 @@ const Profile = { num: 0, name: "duration", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -13066,6 +13967,7 @@ const Profile = { num: 3, // # of repitions of the movement name: "repetitions", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -13080,6 +13982,7 @@ const Profile = { num: 4, // Amount of weight applied for the set name: "weight", type: "uint16", + baseType: "uint16", array: "false", scale: 16, offset: 0, @@ -13094,6 +13997,7 @@ const Profile = { num: 5, name: "setType", type: "setType", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -13108,6 +14012,7 @@ const Profile = { num: 6, // Start time of the set name: "startTime", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -13122,6 +14027,7 @@ const Profile = { num: 7, name: "category", type: "exerciseCategory", + baseType: "uint16", array: "true", scale: 1, offset: 0, @@ -13136,6 +14042,7 @@ const Profile = { num: 8, // Based on the associated category, see [category]_exercise_names name: "categorySubtype", type: "uint16", + baseType: "uint16", array: "true", scale: 1, offset: 0, @@ -13150,6 +14057,7 @@ const Profile = { num: 9, name: "weightDisplayUnit", type: "fitBaseUnit", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -13164,6 +14072,7 @@ const Profile = { num: 10, name: "messageIndex", type: "messageIndex", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -13178,6 +14087,7 @@ const Profile = { num: 11, name: "wktStepIndex", type: "messageIndex", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -13199,6 +14109,7 @@ const Profile = { num: 253, name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -13213,6 +14124,7 @@ const Profile = { num: 0, name: "distance", type: "float32", + baseType: "float32", array: "false", scale: 1, offset: 0, @@ -13227,6 +14139,7 @@ const Profile = { num: 1, name: "height", type: "float32", + baseType: "float32", array: "false", scale: 1, offset: 0, @@ -13241,6 +14154,7 @@ const Profile = { num: 2, name: "rotations", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -13255,6 +14169,7 @@ const Profile = { num: 3, name: "hangTime", type: "float32", + baseType: "float32", array: "false", scale: 1, offset: 0, @@ -13269,6 +14184,7 @@ const Profile = { num: 4, // A score for a jump calculated based on hang time, rotations, and distance. name: "score", type: "float32", + baseType: "float32", array: "false", scale: 1, offset: 0, @@ -13283,6 +14199,7 @@ const Profile = { num: 5, name: "positionLat", type: "sint32", + baseType: "sint32", array: "false", scale: 1, offset: 0, @@ -13297,6 +14214,7 @@ const Profile = { num: 6, name: "positionLong", type: "sint32", + baseType: "sint32", array: "false", scale: 1, offset: 0, @@ -13311,6 +14229,7 @@ const Profile = { num: 7, name: "speed", type: "uint16", + baseType: "uint16", array: "false", scale: [1000, ], offset: [0, ], @@ -13325,6 +14244,7 @@ const Profile = { num: 8, name: "enhancedSpeed", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -13346,6 +14266,7 @@ const Profile = { num: 254, name: "messageIndex", type: "messageIndex", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -13360,6 +14281,7 @@ const Profile = { num: 0, name: "splitType", type: "splitType", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -13374,6 +14296,7 @@ const Profile = { num: 1, name: "totalElapsedTime", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -13388,6 +14311,7 @@ const Profile = { num: 2, name: "totalTimerTime", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -13402,6 +14326,7 @@ const Profile = { num: 3, name: "totalDistance", type: "uint32", + baseType: "uint32", array: "false", scale: 100, offset: 0, @@ -13416,6 +14341,7 @@ const Profile = { num: 4, name: "avgSpeed", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -13430,6 +14356,7 @@ const Profile = { num: 9, name: "startTime", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -13444,6 +14371,7 @@ const Profile = { num: 13, name: "totalAscent", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -13458,6 +14386,7 @@ const Profile = { num: 14, name: "totalDescent", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -13472,6 +14401,7 @@ const Profile = { num: 21, name: "startPositionLat", type: "sint32", + baseType: "sint32", array: "false", scale: 1, offset: 0, @@ -13486,6 +14416,7 @@ const Profile = { num: 22, name: "startPositionLong", type: "sint32", + baseType: "sint32", array: "false", scale: 1, offset: 0, @@ -13500,6 +14431,7 @@ const Profile = { num: 23, name: "endPositionLat", type: "sint32", + baseType: "sint32", array: "false", scale: 1, offset: 0, @@ -13514,6 +14446,7 @@ const Profile = { num: 24, name: "endPositionLong", type: "sint32", + baseType: "sint32", array: "false", scale: 1, offset: 0, @@ -13528,6 +14461,7 @@ const Profile = { num: 25, name: "maxSpeed", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -13542,6 +14476,7 @@ const Profile = { num: 26, name: "avgVertSpeed", type: "sint32", + baseType: "sint32", array: "false", scale: 1000, offset: 0, @@ -13556,6 +14491,7 @@ const Profile = { num: 27, name: "endTime", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -13570,6 +14506,7 @@ const Profile = { num: 28, name: "totalCalories", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -13584,6 +14521,7 @@ const Profile = { num: 74, name: "startElevation", type: "uint32", + baseType: "uint32", array: "false", scale: 5, offset: 500, @@ -13598,6 +14536,7 @@ const Profile = { num: 110, name: "totalMovingTime", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -13619,6 +14558,7 @@ const Profile = { num: 254, name: "messageIndex", type: "messageIndex", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -13633,6 +14573,7 @@ const Profile = { num: 0, name: "splitType", type: "splitType", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -13647,6 +14588,7 @@ const Profile = { num: 3, name: "numSplits", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -13661,6 +14603,7 @@ const Profile = { num: 4, name: "totalTimerTime", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -13675,6 +14618,7 @@ const Profile = { num: 5, name: "totalDistance", type: "uint32", + baseType: "uint32", array: "false", scale: 100, offset: 0, @@ -13689,6 +14633,7 @@ const Profile = { num: 6, name: "avgSpeed", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -13703,6 +14648,7 @@ const Profile = { num: 7, name: "maxSpeed", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -13717,6 +14663,7 @@ const Profile = { num: 8, name: "totalAscent", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -13731,6 +14678,7 @@ const Profile = { num: 9, name: "totalDescent", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -13745,6 +14693,7 @@ const Profile = { num: 10, name: "avgHeartRate", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -13759,6 +14708,7 @@ const Profile = { num: 11, name: "maxHeartRate", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -13773,6 +14723,7 @@ const Profile = { num: 12, name: "avgVertSpeed", type: "sint32", + baseType: "sint32", array: "false", scale: 1000, offset: 0, @@ -13787,6 +14738,7 @@ const Profile = { num: 13, name: "totalCalories", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -13801,6 +14753,7 @@ const Profile = { num: 77, name: "totalMovingTime", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -13822,6 +14775,7 @@ const Profile = { num: 253, name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -13836,6 +14790,7 @@ const Profile = { num: 0, name: "positionLat", type: "sint32", + baseType: "sint32", array: "false", scale: 1, offset: 0, @@ -13850,6 +14805,7 @@ const Profile = { num: 1, name: "positionLong", type: "sint32", + baseType: "sint32", array: "false", scale: 1, offset: 0, @@ -13864,6 +14820,7 @@ const Profile = { num: 2, name: "climbProEvent", type: "climbProEvent", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -13878,6 +14835,7 @@ const Profile = { num: 3, name: "climbNumber", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -13892,6 +14850,7 @@ const Profile = { num: 4, name: "climbCategory", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -13906,6 +14865,7 @@ const Profile = { num: 5, name: "currentDist", type: "float32", + baseType: "float32", array: "false", scale: 1, offset: 0, @@ -13927,6 +14887,7 @@ const Profile = { num: 0, name: "developerDataIndex", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -13941,6 +14902,7 @@ const Profile = { num: 1, name: "fieldDefinitionNumber", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -13955,6 +14917,7 @@ const Profile = { num: 2, name: "fitBaseTypeId", type: "fitBaseType", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -13969,6 +14932,7 @@ const Profile = { num: 3, name: "fieldName", type: "string", + baseType: "string", array: "true", scale: 1, offset: 0, @@ -13983,6 +14947,7 @@ const Profile = { num: 4, name: "array", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -13997,6 +14962,7 @@ const Profile = { num: 5, name: "components", type: "string", + baseType: "string", array: "true", scale: 1, offset: 0, @@ -14011,6 +14977,7 @@ const Profile = { num: 6, name: "scale", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -14025,6 +14992,7 @@ const Profile = { num: 7, name: "offset", type: "sint8", + baseType: "sint8", array: "false", scale: 1, offset: 0, @@ -14039,6 +15007,7 @@ const Profile = { num: 8, name: "units", type: "string", + baseType: "string", array: "true", scale: 1, offset: 0, @@ -14053,6 +15022,7 @@ const Profile = { num: 9, name: "bits", type: "string", + baseType: "string", array: "true", scale: 1, offset: 0, @@ -14067,6 +15037,7 @@ const Profile = { num: 10, name: "accumulate", type: "string", + baseType: "string", array: "true", scale: 1, offset: 0, @@ -14081,6 +15052,7 @@ const Profile = { num: 13, name: "fitBaseUnitId", type: "fitBaseUnit", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -14095,6 +15067,7 @@ const Profile = { num: 14, name: "nativeMesgNum", type: "mesgNum", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -14109,6 +15082,7 @@ const Profile = { num: 15, name: "nativeFieldNum", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -14130,6 +15104,7 @@ const Profile = { num: 0, name: "developerId", type: "byte", + baseType: "byte", array: "true", scale: 1, offset: 0, @@ -14144,6 +15119,7 @@ const Profile = { num: 1, name: "applicationId", type: "byte", + baseType: "byte", array: "true", scale: 1, offset: 0, @@ -14158,6 +15134,7 @@ const Profile = { num: 2, name: "manufacturerId", type: "manufacturer", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -14172,6 +15149,7 @@ const Profile = { num: 3, name: "developerDataIndex", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -14186,6 +15164,7 @@ const Profile = { num: 4, name: "applicationVersion", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -14207,6 +15186,7 @@ const Profile = { num: 4, name: "sport", type: "sport", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -14221,6 +15201,7 @@ const Profile = { num: 5, name: "name", type: "string", + baseType: "string", array: "true", scale: 1, offset: 0, @@ -14235,6 +15216,7 @@ const Profile = { num: 6, name: "capabilities", type: "courseCapabilities", + baseType: "uint32z", array: "false", scale: 1, offset: 0, @@ -14249,6 +15231,7 @@ const Profile = { num: 7, name: "subSport", type: "subSport", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -14270,6 +15253,7 @@ const Profile = { num: 254, name: "messageIndex", type: "messageIndex", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -14284,6 +15268,7 @@ const Profile = { num: 1, name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -14298,6 +15283,7 @@ const Profile = { num: 2, name: "positionLat", type: "sint32", + baseType: "sint32", array: "false", scale: 1, offset: 0, @@ -14312,6 +15298,7 @@ const Profile = { num: 3, name: "positionLong", type: "sint32", + baseType: "sint32", array: "false", scale: 1, offset: 0, @@ -14326,6 +15313,7 @@ const Profile = { num: 4, name: "distance", type: "uint32", + baseType: "uint32", array: "false", scale: 100, offset: 0, @@ -14340,6 +15328,7 @@ const Profile = { num: 5, name: "type", type: "coursePoint", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -14354,6 +15343,7 @@ const Profile = { num: 6, name: "name", type: "string", + baseType: "string", array: "true", scale: 1, offset: 0, @@ -14368,6 +15358,7 @@ const Profile = { num: 8, name: "favorite", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -14389,6 +15380,7 @@ const Profile = { num: 0, // Friendly name assigned to segment name: "name", type: "string", + baseType: "string", array: "true", scale: 1, offset: 0, @@ -14403,6 +15395,7 @@ const Profile = { num: 1, // UUID of the segment name: "uuid", type: "string", + baseType: "string", array: "true", scale: 1, offset: 0, @@ -14417,6 +15410,7 @@ const Profile = { num: 2, // Sport associated with the segment name: "sport", type: "sport", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -14431,6 +15425,7 @@ const Profile = { num: 3, // Segment enabled for evaluation name: "enabled", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -14445,6 +15440,7 @@ const Profile = { num: 4, // Primary key of the user that created the segment name: "userProfilePrimaryKey", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -14459,6 +15455,7 @@ const Profile = { num: 5, // ID of the device that created the segment name: "deviceId", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -14473,6 +15470,7 @@ const Profile = { num: 6, // Index for the Leader Board entry selected as the default race participant name: "defaultRaceLeader", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -14487,6 +15485,7 @@ const Profile = { num: 7, // Indicates if any segments should be deleted name: "deleteStatus", type: "segmentDeleteStatus", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -14501,6 +15500,7 @@ const Profile = { num: 8, // Indicates how the segment was selected to be sent to the device name: "selectionType", type: "segmentSelectionType", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -14522,6 +15522,7 @@ const Profile = { num: 254, name: "messageIndex", type: "messageIndex", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -14536,6 +15537,7 @@ const Profile = { num: 0, // Friendly name assigned to leader name: "name", type: "string", + baseType: "string", array: "true", scale: 1, offset: 0, @@ -14550,6 +15552,7 @@ const Profile = { num: 1, // Leader classification name: "type", type: "segmentLeaderboardType", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -14564,6 +15567,7 @@ const Profile = { num: 2, // Primary user ID of this leader name: "groupPrimaryKey", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -14578,6 +15582,7 @@ const Profile = { num: 3, // ID of the activity associated with this leader time name: "activityId", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -14592,6 +15597,7 @@ const Profile = { num: 4, // Segment Time (includes pauses) name: "segmentTime", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -14606,6 +15612,7 @@ const Profile = { num: 5, // String version of the activity_id. 21 characters long, express in decimal name: "activityIdString", type: "string", + baseType: "string", array: "true", scale: 1, offset: 0, @@ -14627,6 +15634,7 @@ const Profile = { num: 254, name: "messageIndex", type: "messageIndex", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -14641,6 +15649,7 @@ const Profile = { num: 1, name: "positionLat", type: "sint32", + baseType: "sint32", array: "false", scale: 1, offset: 0, @@ -14655,6 +15664,7 @@ const Profile = { num: 2, name: "positionLong", type: "sint32", + baseType: "sint32", array: "false", scale: 1, offset: 0, @@ -14669,6 +15679,7 @@ const Profile = { num: 3, // Accumulated distance along the segment at the described point name: "distance", type: "uint32", + baseType: "uint32", array: "false", scale: 100, offset: 0, @@ -14683,6 +15694,7 @@ const Profile = { num: 4, // Accumulated altitude along the segment at the described point name: "altitude", type: "uint16", + baseType: "uint16", array: "false", scale: [5, ], offset: [500, ], @@ -14697,6 +15709,7 @@ const Profile = { num: 5, // Accumualted time each leader board member required to reach the described point. This value is zero for all leader board members at the starting point of the segment. name: "leaderTime", type: "uint32", + baseType: "uint32", array: "true", scale: 1000, offset: 0, @@ -14711,6 +15724,7 @@ const Profile = { num: 6, // Accumulated altitude along the segment at the described point name: "enhancedAltitude", type: "uint32", + baseType: "uint32", array: "false", scale: 5, offset: 500, @@ -14732,6 +15746,7 @@ const Profile = { num: 254, name: "messageIndex", type: "messageIndex", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -14746,6 +15761,7 @@ const Profile = { num: 253, // Lap end time. name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -14760,6 +15776,7 @@ const Profile = { num: 0, name: "event", type: "event", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -14774,6 +15791,7 @@ const Profile = { num: 1, name: "eventType", type: "eventType", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -14788,6 +15806,7 @@ const Profile = { num: 2, name: "startTime", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -14802,6 +15821,7 @@ const Profile = { num: 3, name: "startPositionLat", type: "sint32", + baseType: "sint32", array: "false", scale: 1, offset: 0, @@ -14816,6 +15836,7 @@ const Profile = { num: 4, name: "startPositionLong", type: "sint32", + baseType: "sint32", array: "false", scale: 1, offset: 0, @@ -14830,6 +15851,7 @@ const Profile = { num: 5, name: "endPositionLat", type: "sint32", + baseType: "sint32", array: "false", scale: 1, offset: 0, @@ -14844,6 +15866,7 @@ const Profile = { num: 6, name: "endPositionLong", type: "sint32", + baseType: "sint32", array: "false", scale: 1, offset: 0, @@ -14858,6 +15881,7 @@ const Profile = { num: 7, // Time (includes pauses) name: "totalElapsedTime", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -14872,6 +15896,7 @@ const Profile = { num: 8, // Timer Time (excludes pauses) name: "totalTimerTime", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -14886,6 +15911,7 @@ const Profile = { num: 9, name: "totalDistance", type: "uint32", + baseType: "uint32", array: "false", scale: 100, offset: 0, @@ -14900,6 +15926,7 @@ const Profile = { num: 10, name: "totalCycles", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -14911,6 +15938,7 @@ const Profile = { subFields: [{ name: "totalStrokes", type: "uint32", + baseType: "uint32", array: "", scale: 1, offset: 0, @@ -14928,6 +15956,7 @@ const Profile = { num: 11, name: "totalCalories", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -14942,6 +15971,7 @@ const Profile = { num: 12, // If New Leaf name: "totalFatCalories", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -14956,6 +15986,7 @@ const Profile = { num: 13, name: "avgSpeed", type: "uint16", + baseType: "uint16", array: "false", scale: 1000, offset: 0, @@ -14970,6 +16001,7 @@ const Profile = { num: 14, name: "maxSpeed", type: "uint16", + baseType: "uint16", array: "false", scale: 1000, offset: 0, @@ -14984,6 +16016,7 @@ const Profile = { num: 15, name: "avgHeartRate", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -14998,6 +16031,7 @@ const Profile = { num: 16, name: "maxHeartRate", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -15012,6 +16046,7 @@ const Profile = { num: 17, // total_cycles / total_timer_time if non_zero_avg_cadence otherwise total_cycles / total_elapsed_time name: "avgCadence", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -15026,6 +16061,7 @@ const Profile = { num: 18, name: "maxCadence", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -15040,6 +16076,7 @@ const Profile = { num: 19, // total_power / total_timer_time if non_zero_avg_power otherwise total_power / total_elapsed_time name: "avgPower", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -15054,6 +16091,7 @@ const Profile = { num: 20, name: "maxPower", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -15068,6 +16106,7 @@ const Profile = { num: 21, name: "totalAscent", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -15082,6 +16121,7 @@ const Profile = { num: 22, name: "totalDescent", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -15096,6 +16136,7 @@ const Profile = { num: 23, name: "sport", type: "sport", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -15110,6 +16151,7 @@ const Profile = { num: 24, name: "eventGroup", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -15124,6 +16166,7 @@ const Profile = { num: 25, // North east corner latitude. name: "necLat", type: "sint32", + baseType: "sint32", array: "false", scale: 1, offset: 0, @@ -15138,6 +16181,7 @@ const Profile = { num: 26, // North east corner longitude. name: "necLong", type: "sint32", + baseType: "sint32", array: "false", scale: 1, offset: 0, @@ -15152,6 +16196,7 @@ const Profile = { num: 27, // South west corner latitude. name: "swcLat", type: "sint32", + baseType: "sint32", array: "false", scale: 1, offset: 0, @@ -15166,6 +16211,7 @@ const Profile = { num: 28, // South west corner latitude. name: "swcLong", type: "sint32", + baseType: "sint32", array: "false", scale: 1, offset: 0, @@ -15180,6 +16226,7 @@ const Profile = { num: 29, name: "name", type: "string", + baseType: "string", array: "true", scale: 1, offset: 0, @@ -15194,6 +16241,7 @@ const Profile = { num: 30, name: "normalizedPower", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -15208,6 +16256,7 @@ const Profile = { num: 31, name: "leftRightBalance", type: "leftRightBalance100", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -15222,6 +16271,7 @@ const Profile = { num: 32, name: "subSport", type: "subSport", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -15236,6 +16286,7 @@ const Profile = { num: 33, name: "totalWork", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -15250,6 +16301,7 @@ const Profile = { num: 34, name: "avgAltitude", type: "uint16", + baseType: "uint16", array: "false", scale: [5, ], offset: [500, ], @@ -15264,6 +16316,7 @@ const Profile = { num: 35, name: "maxAltitude", type: "uint16", + baseType: "uint16", array: "false", scale: [5, ], offset: [500, ], @@ -15278,6 +16331,7 @@ const Profile = { num: 36, name: "gpsAccuracy", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -15292,6 +16346,7 @@ const Profile = { num: 37, name: "avgGrade", type: "sint16", + baseType: "sint16", array: "false", scale: 100, offset: 0, @@ -15306,6 +16361,7 @@ const Profile = { num: 38, name: "avgPosGrade", type: "sint16", + baseType: "sint16", array: "false", scale: 100, offset: 0, @@ -15320,6 +16376,7 @@ const Profile = { num: 39, name: "avgNegGrade", type: "sint16", + baseType: "sint16", array: "false", scale: 100, offset: 0, @@ -15334,6 +16391,7 @@ const Profile = { num: 40, name: "maxPosGrade", type: "sint16", + baseType: "sint16", array: "false", scale: 100, offset: 0, @@ -15348,6 +16406,7 @@ const Profile = { num: 41, name: "maxNegGrade", type: "sint16", + baseType: "sint16", array: "false", scale: 100, offset: 0, @@ -15362,6 +16421,7 @@ const Profile = { num: 42, name: "avgTemperature", type: "sint8", + baseType: "sint8", array: "false", scale: 1, offset: 0, @@ -15376,6 +16436,7 @@ const Profile = { num: 43, name: "maxTemperature", type: "sint8", + baseType: "sint8", array: "false", scale: 1, offset: 0, @@ -15390,6 +16451,7 @@ const Profile = { num: 44, name: "totalMovingTime", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -15404,6 +16466,7 @@ const Profile = { num: 45, name: "avgPosVerticalSpeed", type: "sint16", + baseType: "sint16", array: "false", scale: 1000, offset: 0, @@ -15418,6 +16481,7 @@ const Profile = { num: 46, name: "avgNegVerticalSpeed", type: "sint16", + baseType: "sint16", array: "false", scale: 1000, offset: 0, @@ -15432,6 +16496,7 @@ const Profile = { num: 47, name: "maxPosVerticalSpeed", type: "sint16", + baseType: "sint16", array: "false", scale: 1000, offset: 0, @@ -15446,6 +16511,7 @@ const Profile = { num: 48, name: "maxNegVerticalSpeed", type: "sint16", + baseType: "sint16", array: "false", scale: 1000, offset: 0, @@ -15460,6 +16526,7 @@ const Profile = { num: 49, name: "timeInHrZone", type: "uint32", + baseType: "uint32", array: "true", scale: 1000, offset: 0, @@ -15474,6 +16541,7 @@ const Profile = { num: 50, name: "timeInSpeedZone", type: "uint32", + baseType: "uint32", array: "true", scale: 1000, offset: 0, @@ -15488,6 +16556,7 @@ const Profile = { num: 51, name: "timeInCadenceZone", type: "uint32", + baseType: "uint32", array: "true", scale: 1000, offset: 0, @@ -15502,6 +16571,7 @@ const Profile = { num: 52, name: "timeInPowerZone", type: "uint32", + baseType: "uint32", array: "true", scale: 1000, offset: 0, @@ -15516,6 +16586,7 @@ const Profile = { num: 53, name: "repetitionNum", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -15530,6 +16601,7 @@ const Profile = { num: 54, name: "minAltitude", type: "uint16", + baseType: "uint16", array: "false", scale: [5, ], offset: [500, ], @@ -15544,6 +16616,7 @@ const Profile = { num: 55, name: "minHeartRate", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -15558,6 +16631,7 @@ const Profile = { num: 56, name: "activeTime", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -15572,6 +16646,7 @@ const Profile = { num: 57, name: "wktStepIndex", type: "messageIndex", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -15586,6 +16661,7 @@ const Profile = { num: 58, name: "sportEvent", type: "sportEvent", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -15600,6 +16676,7 @@ const Profile = { num: 59, name: "avgLeftTorqueEffectiveness", type: "uint8", + baseType: "uint8", array: "false", scale: 2, offset: 0, @@ -15614,6 +16691,7 @@ const Profile = { num: 60, name: "avgRightTorqueEffectiveness", type: "uint8", + baseType: "uint8", array: "false", scale: 2, offset: 0, @@ -15628,6 +16706,7 @@ const Profile = { num: 61, name: "avgLeftPedalSmoothness", type: "uint8", + baseType: "uint8", array: "false", scale: 2, offset: 0, @@ -15642,6 +16721,7 @@ const Profile = { num: 62, name: "avgRightPedalSmoothness", type: "uint8", + baseType: "uint8", array: "false", scale: 2, offset: 0, @@ -15656,6 +16736,7 @@ const Profile = { num: 63, name: "avgCombinedPedalSmoothness", type: "uint8", + baseType: "uint8", array: "false", scale: 2, offset: 0, @@ -15670,6 +16751,7 @@ const Profile = { num: 64, name: "status", type: "segmentLapStatus", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -15684,6 +16766,7 @@ const Profile = { num: 65, name: "uuid", type: "string", + baseType: "string", array: "true", scale: 1, offset: 0, @@ -15698,6 +16781,7 @@ const Profile = { num: 66, // fractional part of the avg_cadence name: "avgFractionalCadence", type: "uint8", + baseType: "uint8", array: "false", scale: 128, offset: 0, @@ -15712,6 +16796,7 @@ const Profile = { num: 67, // fractional part of the max_cadence name: "maxFractionalCadence", type: "uint8", + baseType: "uint8", array: "false", scale: 128, offset: 0, @@ -15726,6 +16811,7 @@ const Profile = { num: 68, // fractional part of the total_cycles name: "totalFractionalCycles", type: "uint8", + baseType: "uint8", array: "false", scale: 128, offset: 0, @@ -15740,6 +16826,7 @@ const Profile = { num: 69, name: "frontGearShiftCount", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -15754,6 +16841,7 @@ const Profile = { num: 70, name: "rearGearShiftCount", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -15768,6 +16856,7 @@ const Profile = { num: 71, // Total time spent in the standing position name: "timeStanding", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -15782,6 +16871,7 @@ const Profile = { num: 72, // Number of transitions to the standing state name: "standCount", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -15796,6 +16886,7 @@ const Profile = { num: 73, // Average left platform center offset name: "avgLeftPco", type: "sint8", + baseType: "sint8", array: "false", scale: 1, offset: 0, @@ -15810,6 +16901,7 @@ const Profile = { num: 74, // Average right platform center offset name: "avgRightPco", type: "sint8", + baseType: "sint8", array: "false", scale: 1, offset: 0, @@ -15824,6 +16916,7 @@ const Profile = { num: 75, // Average left power phase angles. Data value indexes defined by power_phase_type. name: "avgLeftPowerPhase", type: "uint8", + baseType: "uint8", array: "true", scale: 0.7111111, offset: 0, @@ -15838,6 +16931,7 @@ const Profile = { num: 76, // Average left power phase peak angles. Data value indexes defined by power_phase_type. name: "avgLeftPowerPhasePeak", type: "uint8", + baseType: "uint8", array: "true", scale: 0.7111111, offset: 0, @@ -15852,6 +16946,7 @@ const Profile = { num: 77, // Average right power phase angles. Data value indexes defined by power_phase_type. name: "avgRightPowerPhase", type: "uint8", + baseType: "uint8", array: "true", scale: 0.7111111, offset: 0, @@ -15866,6 +16961,7 @@ const Profile = { num: 78, // Average right power phase peak angles. Data value indexes defined by power_phase_type. name: "avgRightPowerPhasePeak", type: "uint8", + baseType: "uint8", array: "true", scale: 0.7111111, offset: 0, @@ -15880,6 +16976,7 @@ const Profile = { num: 79, // Average power by position. Data value indexes defined by rider_position_type. name: "avgPowerPosition", type: "uint16", + baseType: "uint16", array: "true", scale: 1, offset: 0, @@ -15894,6 +16991,7 @@ const Profile = { num: 80, // Maximum power by position. Data value indexes defined by rider_position_type. name: "maxPowerPosition", type: "uint16", + baseType: "uint16", array: "true", scale: 1, offset: 0, @@ -15908,6 +17006,7 @@ const Profile = { num: 81, // Average cadence by position. Data value indexes defined by rider_position_type. name: "avgCadencePosition", type: "uint8", + baseType: "uint8", array: "true", scale: 1, offset: 0, @@ -15922,6 +17021,7 @@ const Profile = { num: 82, // Maximum cadence by position. Data value indexes defined by rider_position_type. name: "maxCadencePosition", type: "uint8", + baseType: "uint8", array: "true", scale: 1, offset: 0, @@ -15936,6 +17036,7 @@ const Profile = { num: 83, // Manufacturer that produced the segment name: "manufacturer", type: "manufacturer", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -15950,6 +17051,7 @@ const Profile = { num: 84, // The grit score estimates how challenging a route could be for a cyclist in terms of time spent going over sharp turns or large grade slopes. name: "totalGrit", type: "float32", + baseType: "float32", array: "false", scale: 1, offset: 0, @@ -15964,6 +17066,7 @@ const Profile = { num: 85, // The flow score estimates how long distance wise a cyclist deaccelerates over intervals where deacceleration is unnecessary such as smooth turns or small grade angle intervals. name: "totalFlow", type: "float32", + baseType: "float32", array: "false", scale: 1, offset: 0, @@ -15978,6 +17081,7 @@ const Profile = { num: 86, // The grit score estimates how challenging a route could be for a cyclist in terms of time spent going over sharp turns or large grade slopes. name: "avgGrit", type: "float32", + baseType: "float32", array: "false", scale: 1, offset: 0, @@ -15992,6 +17096,7 @@ const Profile = { num: 87, // The flow score estimates how long distance wise a cyclist deaccelerates over intervals where deacceleration is unnecessary such as smooth turns or small grade angle intervals. name: "avgFlow", type: "float32", + baseType: "float32", array: "false", scale: 1, offset: 0, @@ -16006,6 +17111,7 @@ const Profile = { num: 89, // fractional part of total_ascent name: "totalFractionalAscent", type: "uint8", + baseType: "uint8", array: "false", scale: 100, offset: 0, @@ -16020,6 +17126,7 @@ const Profile = { num: 90, // fractional part of total_descent name: "totalFractionalDescent", type: "uint8", + baseType: "uint8", array: "false", scale: 100, offset: 0, @@ -16034,6 +17141,7 @@ const Profile = { num: 91, name: "enhancedAvgAltitude", type: "uint32", + baseType: "uint32", array: "false", scale: 5, offset: 500, @@ -16048,6 +17156,7 @@ const Profile = { num: 92, name: "enhancedMaxAltitude", type: "uint32", + baseType: "uint32", array: "false", scale: 5, offset: 500, @@ -16062,6 +17171,7 @@ const Profile = { num: 93, name: "enhancedMinAltitude", type: "uint32", + baseType: "uint32", array: "false", scale: 5, offset: 500, @@ -16083,6 +17193,7 @@ const Profile = { num: 254, name: "messageIndex", type: "messageIndex", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -16097,6 +17208,7 @@ const Profile = { num: 1, // UUID of the segment file name: "fileUuid", type: "string", + baseType: "string", array: "true", scale: 1, offset: 0, @@ -16111,6 +17223,7 @@ const Profile = { num: 3, // Enabled state of the segment file name: "enabled", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -16125,6 +17238,7 @@ const Profile = { num: 4, // Primary key of the user that created the segment file name: "userProfilePrimaryKey", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -16139,6 +17253,7 @@ const Profile = { num: 7, // Leader type of each leader in the segment file name: "leaderType", type: "segmentLeaderboardType", + baseType: "enum", array: "true", scale: 1, offset: 0, @@ -16153,6 +17268,7 @@ const Profile = { num: 8, // Group primary key of each leader in the segment file name: "leaderGroupPrimaryKey", type: "uint32", + baseType: "uint32", array: "true", scale: 1, offset: 0, @@ -16167,6 +17283,7 @@ const Profile = { num: 9, // Activity ID of each leader in the segment file name: "leaderActivityId", type: "uint32", + baseType: "uint32", array: "true", scale: 1, offset: 0, @@ -16181,6 +17298,7 @@ const Profile = { num: 10, // String version of the activity ID of each leader in the segment file. 21 characters long for each ID, express in decimal name: "leaderActivityIdString", type: "string", + baseType: "string", array: "true", scale: 1, offset: 0, @@ -16195,6 +17313,7 @@ const Profile = { num: 11, // Index for the Leader Board entry selected as the default race participant name: "defaultRaceLeader", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -16216,6 +17335,7 @@ const Profile = { num: 254, name: "messageIndex", type: "messageIndex", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -16230,6 +17350,7 @@ const Profile = { num: 4, name: "sport", type: "sport", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -16244,6 +17365,7 @@ const Profile = { num: 5, name: "capabilities", type: "workoutCapabilities", + baseType: "uint32z", array: "false", scale: 1, offset: 0, @@ -16258,6 +17380,7 @@ const Profile = { num: 6, // number of valid steps name: "numValidSteps", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -16272,6 +17395,7 @@ const Profile = { num: 8, name: "wktName", type: "string", + baseType: "string", array: "true", scale: 1, offset: 0, @@ -16286,6 +17410,7 @@ const Profile = { num: 11, name: "subSport", type: "subSport", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -16300,6 +17425,7 @@ const Profile = { num: 14, name: "poolLength", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -16314,6 +17440,7 @@ const Profile = { num: 15, name: "poolLengthUnit", type: "displayMeasure", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -16328,6 +17455,7 @@ const Profile = { num: 17, // Description of the workout name: "wktDescription", type: "string", + baseType: "string", array: "true", scale: 1, offset: 0, @@ -16349,6 +17477,7 @@ const Profile = { num: 254, name: "messageIndex", type: "messageIndex", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -16363,6 +17492,7 @@ const Profile = { num: 0, name: "sport", type: "sport", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -16377,6 +17507,7 @@ const Profile = { num: 1, name: "subSport", type: "subSport", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -16391,6 +17522,7 @@ const Profile = { num: 2, name: "numValidSteps", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -16405,6 +17537,7 @@ const Profile = { num: 3, name: "firstStepIndex", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -16419,6 +17552,7 @@ const Profile = { num: 4, name: "poolLength", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -16433,6 +17567,7 @@ const Profile = { num: 5, name: "poolLengthUnit", type: "displayMeasure", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -16454,6 +17589,7 @@ const Profile = { num: 254, name: "messageIndex", type: "messageIndex", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -16468,6 +17604,7 @@ const Profile = { num: 0, name: "wktStepName", type: "string", + baseType: "string", array: "true", scale: 1, offset: 0, @@ -16482,6 +17619,7 @@ const Profile = { num: 1, name: "durationType", type: "wktStepDuration", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -16496,6 +17634,7 @@ const Profile = { num: 2, name: "durationValue", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -16507,6 +17646,7 @@ const Profile = { subFields: [{ name: "durationTime", type: "uint32", + baseType: "uint32", array: "", scale: 1000, offset: 0, @@ -16522,6 +17662,7 @@ const Profile = { { name: "durationDistance", type: "uint32", + baseType: "uint32", array: "", scale: 100, offset: 0, @@ -16536,6 +17677,7 @@ const Profile = { { name: "durationHr", type: "workoutHr", + baseType: "uint32", array: "", scale: 1, offset: 0, @@ -16551,6 +17693,7 @@ const Profile = { { name: "durationCalories", type: "uint32", + baseType: "uint32", array: "", scale: 1, offset: 0, @@ -16565,6 +17708,7 @@ const Profile = { { name: "durationStep", // message_index of step to loop back to. Steps are assumed to be in the order by message_index. custom_name and intensity members are undefined for this duration type. type: "uint32", + baseType: "uint32", array: "", scale: 1, offset: 0, @@ -16586,6 +17730,7 @@ const Profile = { { name: "durationPower", type: "workoutPower", + baseType: "uint32", array: "", scale: 1, offset: 0, @@ -16601,6 +17746,7 @@ const Profile = { { name: "durationReps", type: "uint32", + baseType: "uint32", array: "", scale: 1, offset: 0, @@ -16618,6 +17764,7 @@ const Profile = { num: 3, name: "targetType", type: "wktStepTarget", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -16632,6 +17779,7 @@ const Profile = { num: 4, name: "targetValue", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -16643,6 +17791,7 @@ const Profile = { subFields: [{ name: "targetSpeedZone", // speed zone (1-10);Custom =0; type: "uint32", + baseType: "uint32", array: "", scale: 1, offset: 0, @@ -16657,6 +17806,7 @@ const Profile = { { name: "targetHrZone", // hr zone (1-5);Custom =0; type: "uint32", + baseType: "uint32", array: "", scale: 1, offset: 0, @@ -16671,6 +17821,7 @@ const Profile = { { name: "targetCadenceZone", // Zone (1-?); Custom = 0; type: "uint32", + baseType: "uint32", array: "", scale: 1, offset: 0, @@ -16685,6 +17836,7 @@ const Profile = { { name: "targetPowerZone", // Power Zone ( 1-7); Custom = 0; type: "uint32", + baseType: "uint32", array: "", scale: 1, offset: 0, @@ -16699,6 +17851,7 @@ const Profile = { { name: "repeatSteps", // # of repetitions type: "uint32", + baseType: "uint32", array: "", scale: 1, offset: 0, @@ -16713,6 +17866,7 @@ const Profile = { { name: "repeatTime", type: "uint32", + baseType: "uint32", array: "", scale: 1000, offset: 0, @@ -16727,6 +17881,7 @@ const Profile = { { name: "repeatDistance", type: "uint32", + baseType: "uint32", array: "", scale: 100, offset: 0, @@ -16741,6 +17896,7 @@ const Profile = { { name: "repeatCalories", type: "uint32", + baseType: "uint32", array: "", scale: 1, offset: 0, @@ -16755,6 +17911,7 @@ const Profile = { { name: "repeatHr", type: "workoutHr", + baseType: "uint32", array: "", scale: 1, offset: 0, @@ -16770,6 +17927,7 @@ const Profile = { { name: "repeatPower", type: "workoutPower", + baseType: "uint32", array: "", scale: 1, offset: 0, @@ -16785,6 +17943,7 @@ const Profile = { { name: "targetStrokeType", type: "swimStroke", + baseType: "enum", array: "", scale: 1, offset: 0, @@ -16802,6 +17961,7 @@ const Profile = { num: 5, name: "customTargetValueLow", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -16813,6 +17973,7 @@ const Profile = { subFields: [{ name: "customTargetSpeedLow", type: "uint32", + baseType: "uint32", array: "", scale: 1000, offset: 0, @@ -16827,6 +17988,7 @@ const Profile = { { name: "customTargetHeartRateLow", type: "workoutHr", + baseType: "uint32", array: "", scale: 1, offset: 0, @@ -16841,6 +18003,7 @@ const Profile = { { name: "customTargetCadenceLow", type: "uint32", + baseType: "uint32", array: "", scale: 1, offset: 0, @@ -16855,6 +18018,7 @@ const Profile = { { name: "customTargetPowerLow", type: "workoutPower", + baseType: "uint32", array: "", scale: 1, offset: 0, @@ -16872,6 +18036,7 @@ const Profile = { num: 6, name: "customTargetValueHigh", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -16883,6 +18048,7 @@ const Profile = { subFields: [{ name: "customTargetSpeedHigh", type: "uint32", + baseType: "uint32", array: "", scale: 1000, offset: 0, @@ -16897,6 +18063,7 @@ const Profile = { { name: "customTargetHeartRateHigh", type: "workoutHr", + baseType: "uint32", array: "", scale: 1, offset: 0, @@ -16911,6 +18078,7 @@ const Profile = { { name: "customTargetCadenceHigh", type: "uint32", + baseType: "uint32", array: "", scale: 1, offset: 0, @@ -16925,6 +18093,7 @@ const Profile = { { name: "customTargetPowerHigh", type: "workoutPower", + baseType: "uint32", array: "", scale: 1, offset: 0, @@ -16942,6 +18111,7 @@ const Profile = { num: 7, name: "intensity", type: "intensity", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -16956,6 +18126,7 @@ const Profile = { num: 8, name: "notes", type: "string", + baseType: "string", array: "true", scale: 1, offset: 0, @@ -16970,6 +18141,7 @@ const Profile = { num: 9, name: "equipment", type: "workoutEquipment", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -16984,6 +18156,7 @@ const Profile = { num: 10, name: "exerciseCategory", type: "exerciseCategory", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -16998,6 +18171,7 @@ const Profile = { num: 11, name: "exerciseName", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -17012,6 +18186,7 @@ const Profile = { num: 12, name: "exerciseWeight", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -17026,6 +18201,7 @@ const Profile = { num: 13, name: "weightDisplayUnit", type: "fitBaseUnit", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -17040,6 +18216,7 @@ const Profile = { num: 19, name: "secondaryTargetType", type: "wktStepTarget", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -17054,6 +18231,7 @@ const Profile = { num: 20, name: "secondaryTargetValue", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -17065,6 +18243,7 @@ const Profile = { subFields: [{ name: "secondaryTargetSpeedZone", // speed zone (1-10);Custom =0; type: "uint32", + baseType: "uint32", array: "", scale: 1, offset: 0, @@ -17079,6 +18258,7 @@ const Profile = { { name: "secondaryTargetHrZone", // hr zone (1-5);Custom =0; type: "uint32", + baseType: "uint32", array: "", scale: 1, offset: 0, @@ -17093,6 +18273,7 @@ const Profile = { { name: "secondaryTargetCadenceZone", // Zone (1-?); Custom = 0; type: "uint32", + baseType: "uint32", array: "", scale: 1, offset: 0, @@ -17107,6 +18288,7 @@ const Profile = { { name: "secondaryTargetPowerZone", // Power Zone ( 1-7); Custom = 0; type: "uint32", + baseType: "uint32", array: "", scale: 1, offset: 0, @@ -17121,6 +18303,7 @@ const Profile = { { name: "secondaryTargetStrokeType", type: "swimStroke", + baseType: "enum", array: "", scale: 1, offset: 0, @@ -17138,6 +18321,7 @@ const Profile = { num: 21, name: "secondaryCustomTargetValueLow", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -17149,6 +18333,7 @@ const Profile = { subFields: [{ name: "secondaryCustomTargetSpeedLow", type: "uint32", + baseType: "uint32", array: "", scale: 1000, offset: 0, @@ -17163,6 +18348,7 @@ const Profile = { { name: "secondaryCustomTargetHeartRateLow", type: "workoutHr", + baseType: "uint32", array: "", scale: 1, offset: 0, @@ -17177,6 +18363,7 @@ const Profile = { { name: "secondaryCustomTargetCadenceLow", type: "uint32", + baseType: "uint32", array: "", scale: 1, offset: 0, @@ -17191,6 +18378,7 @@ const Profile = { { name: "secondaryCustomTargetPowerLow", type: "workoutPower", + baseType: "uint32", array: "", scale: 1, offset: 0, @@ -17208,6 +18396,7 @@ const Profile = { num: 22, name: "secondaryCustomTargetValueHigh", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -17219,6 +18408,7 @@ const Profile = { subFields: [{ name: "secondaryCustomTargetSpeedHigh", type: "uint32", + baseType: "uint32", array: "", scale: 1000, offset: 0, @@ -17233,6 +18423,7 @@ const Profile = { { name: "secondaryCustomTargetHeartRateHigh", type: "workoutHr", + baseType: "uint32", array: "", scale: 1, offset: 0, @@ -17247,6 +18438,7 @@ const Profile = { { name: "secondaryCustomTargetCadenceHigh", type: "uint32", + baseType: "uint32", array: "", scale: 1, offset: 0, @@ -17261,6 +18453,7 @@ const Profile = { { name: "secondaryCustomTargetPowerHigh", type: "workoutPower", + baseType: "uint32", array: "", scale: 1, offset: 0, @@ -17285,6 +18478,7 @@ const Profile = { num: 254, name: "messageIndex", type: "messageIndex", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -17299,6 +18493,7 @@ const Profile = { num: 0, name: "exerciseCategory", type: "exerciseCategory", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -17313,6 +18508,7 @@ const Profile = { num: 1, name: "exerciseName", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -17327,6 +18523,7 @@ const Profile = { num: 2, name: "wktStepName", type: "string", + baseType: "string", array: "true", scale: 1, offset: 0, @@ -17348,6 +18545,7 @@ const Profile = { num: 0, // Corresponds to file_id of scheduled workout / course. name: "manufacturer", type: "manufacturer", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -17362,6 +18560,7 @@ const Profile = { num: 1, // Corresponds to file_id of scheduled workout / course. name: "product", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -17373,6 +18572,7 @@ const Profile = { subFields: [{ name: "faveroProduct", type: "faveroProduct", + baseType: "uint16", array: "", scale: 1, offset: 0, @@ -17387,6 +18587,7 @@ const Profile = { { name: "garminProduct", type: "garminProduct", + baseType: "uint16", array: "", scale: 1, offset: 0, @@ -17407,6 +18608,7 @@ const Profile = { num: 2, // Corresponds to file_id of scheduled workout / course. name: "serialNumber", type: "uint32z", + baseType: "uint32z", array: "false", scale: 1, offset: 0, @@ -17421,6 +18623,7 @@ const Profile = { num: 3, // Corresponds to file_id of scheduled workout / course. name: "timeCreated", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -17435,6 +18638,7 @@ const Profile = { num: 4, // TRUE if this activity has been started name: "completed", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -17449,6 +18653,7 @@ const Profile = { num: 5, name: "type", type: "schedule", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -17463,6 +18668,7 @@ const Profile = { num: 6, name: "scheduledTime", type: "localDateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -17484,6 +18690,7 @@ const Profile = { num: 254, name: "messageIndex", type: "messageIndex", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -17498,6 +18705,7 @@ const Profile = { num: 253, name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -17512,6 +18720,7 @@ const Profile = { num: 0, // Excludes pauses name: "timerTime", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -17526,6 +18735,7 @@ const Profile = { num: 1, name: "distance", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -17540,6 +18750,7 @@ const Profile = { num: 2, name: "calories", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -17554,6 +18765,7 @@ const Profile = { num: 3, name: "sport", type: "sport", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -17568,6 +18780,7 @@ const Profile = { num: 4, // Includes pauses name: "elapsedTime", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -17582,6 +18795,7 @@ const Profile = { num: 5, name: "sessions", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -17596,6 +18810,7 @@ const Profile = { num: 6, name: "activeTime", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -17610,6 +18825,7 @@ const Profile = { num: 9, name: "sportIndex", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -17631,6 +18847,7 @@ const Profile = { num: 253, name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -17645,6 +18862,7 @@ const Profile = { num: 0, name: "weight", type: "weight", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -17659,6 +18877,7 @@ const Profile = { num: 1, name: "percentFat", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -17673,6 +18892,7 @@ const Profile = { num: 2, name: "percentHydration", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -17687,6 +18907,7 @@ const Profile = { num: 3, name: "visceralFatMass", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -17701,6 +18922,7 @@ const Profile = { num: 4, name: "boneMass", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -17715,6 +18937,7 @@ const Profile = { num: 5, name: "muscleMass", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -17729,6 +18952,7 @@ const Profile = { num: 7, name: "basalMet", type: "uint16", + baseType: "uint16", array: "false", scale: 4, offset: 0, @@ -17743,6 +18967,7 @@ const Profile = { num: 8, name: "physiqueRating", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -17757,6 +18982,7 @@ const Profile = { num: 9, // ~4kJ per kcal, 0.25 allows max 16384 kcal name: "activeMet", type: "uint16", + baseType: "uint16", array: "false", scale: 4, offset: 0, @@ -17771,6 +18997,7 @@ const Profile = { num: 10, name: "metabolicAge", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -17785,6 +19012,7 @@ const Profile = { num: 11, name: "visceralFatRating", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -17799,6 +19027,7 @@ const Profile = { num: 12, // Associates this weight scale message to a user. This corresponds to the index of the user profile message in the weight scale file. name: "userProfileIndex", type: "messageIndex", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -17813,6 +19042,7 @@ const Profile = { num: 13, name: "bmi", type: "uint16", + baseType: "uint16", array: "false", scale: 10, offset: 0, @@ -17834,6 +19064,7 @@ const Profile = { num: 253, name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -17848,6 +19079,7 @@ const Profile = { num: 0, name: "systolicPressure", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -17862,6 +19094,7 @@ const Profile = { num: 1, name: "diastolicPressure", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -17876,6 +19109,7 @@ const Profile = { num: 2, name: "meanArterialPressure", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -17890,6 +19124,7 @@ const Profile = { num: 3, name: "map3SampleMean", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -17904,6 +19139,7 @@ const Profile = { num: 4, name: "mapMorningValues", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -17918,6 +19154,7 @@ const Profile = { num: 5, name: "mapEveningValues", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -17932,6 +19169,7 @@ const Profile = { num: 6, name: "heartRate", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -17946,6 +19184,7 @@ const Profile = { num: 7, name: "heartRateType", type: "hrType", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -17960,6 +19199,7 @@ const Profile = { num: 8, name: "status", type: "bpStatus", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -17974,6 +19214,7 @@ const Profile = { num: 9, // Associates this blood pressure message to a user. This corresponds to the index of the user profile message in the blood pressure file. name: "userProfileIndex", type: "messageIndex", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -17995,6 +19236,7 @@ const Profile = { num: 253, name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -18009,6 +19251,7 @@ const Profile = { num: 0, // Use to convert activity timestamps to local time if device does not support time zone and daylight savings time correction. name: "localTimestamp", type: "localDateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -18023,6 +19266,7 @@ const Profile = { num: 1, name: "activityType", type: "activityType", + baseType: "enum", array: "true", scale: 1, offset: 0, @@ -18037,6 +19281,7 @@ const Profile = { num: 3, // Indexed by activity_type name: "cyclesToDistance", type: "uint16", + baseType: "uint16", array: "true", scale: 5000, offset: 0, @@ -18051,6 +19296,7 @@ const Profile = { num: 4, // Indexed by activity_type name: "cyclesToCalories", type: "uint16", + baseType: "uint16", array: "true", scale: 5000, offset: 0, @@ -18065,6 +19311,7 @@ const Profile = { num: 5, name: "restingMetabolicRate", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -18086,6 +19333,7 @@ const Profile = { num: 253, // Must align to logging interval, for example, time must be 00:00:00 for daily log. name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -18100,6 +19348,7 @@ const Profile = { num: 0, // Associates this data to device_info message. Not required for file with single device (sensor). name: "deviceIndex", type: "deviceIndex", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -18114,6 +19363,7 @@ const Profile = { num: 1, // Accumulated total calories. Maintained by MonitoringReader for each activity_type. See SDK documentation name: "calories", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -18128,6 +19378,7 @@ const Profile = { num: 2, // Accumulated distance. Maintained by MonitoringReader for each activity_type. See SDK documentation. name: "distance", type: "uint32", + baseType: "uint32", array: "false", scale: 100, offset: 0, @@ -18142,6 +19393,7 @@ const Profile = { num: 3, // Accumulated cycles. Maintained by MonitoringReader for each activity_type. See SDK documentation. name: "cycles", type: "uint32", + baseType: "uint32", array: "false", scale: 2, offset: 0, @@ -18153,6 +19405,7 @@ const Profile = { subFields: [{ name: "steps", type: "uint32", + baseType: "uint32", array: "", scale: 1, offset: 0, @@ -18168,6 +19421,7 @@ const Profile = { { name: "strokes", type: "uint32", + baseType: "uint32", array: "", scale: 2, offset: 0, @@ -18186,6 +19440,7 @@ const Profile = { num: 4, name: "activeTime", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -18200,6 +19455,7 @@ const Profile = { num: 5, name: "activityType", type: "activityType", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -18214,6 +19470,7 @@ const Profile = { num: 6, name: "activitySubtype", type: "activitySubtype", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -18228,6 +19485,7 @@ const Profile = { num: 7, name: "activityLevel", type: "activityLevel", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -18242,6 +19500,7 @@ const Profile = { num: 8, name: "distance16", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -18256,6 +19515,7 @@ const Profile = { num: 9, name: "cycles16", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -18270,6 +19530,7 @@ const Profile = { num: 10, name: "activeTime16", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -18284,6 +19545,7 @@ const Profile = { num: 11, // Must align to logging interval, for example, time must be 00:00:00 for daily log. name: "localTimestamp", type: "localDateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -18298,6 +19560,7 @@ const Profile = { num: 12, // Avg temperature during the logging interval ended at timestamp name: "temperature", type: "sint16", + baseType: "sint16", array: "false", scale: 100, offset: 0, @@ -18312,6 +19575,7 @@ const Profile = { num: 14, // Min temperature during the logging interval ended at timestamp name: "temperatureMin", type: "sint16", + baseType: "sint16", array: "false", scale: 100, offset: 0, @@ -18326,6 +19590,7 @@ const Profile = { num: 15, // Max temperature during the logging interval ended at timestamp name: "temperatureMax", type: "sint16", + baseType: "sint16", array: "false", scale: 100, offset: 0, @@ -18340,6 +19605,7 @@ const Profile = { num: 16, // Indexed using minute_activity_level enum name: "activityTime", type: "uint16", + baseType: "uint16", array: "true", scale: 1, offset: 0, @@ -18354,6 +19620,7 @@ const Profile = { num: 19, name: "activeCalories", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -18368,6 +19635,7 @@ const Profile = { num: 24, // Indicates single type / intensity for duration since last monitoring message. name: "currentActivityTypeIntensity", type: "byte", + baseType: "byte", array: "false", scale: [1, 1, ], offset: [0, 0, ], @@ -18382,6 +19650,7 @@ const Profile = { num: 25, name: "timestampMin8", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -18396,6 +19665,7 @@ const Profile = { num: 26, name: "timestamp16", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -18410,6 +19680,7 @@ const Profile = { num: 27, name: "heartRate", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -18424,6 +19695,7 @@ const Profile = { num: 28, name: "intensity", type: "uint8", + baseType: "uint8", array: "false", scale: 10, offset: 0, @@ -18438,6 +19710,7 @@ const Profile = { num: 29, name: "durationMin", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -18452,6 +19725,7 @@ const Profile = { num: 30, name: "duration", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -18466,6 +19740,7 @@ const Profile = { num: 31, name: "ascent", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -18480,6 +19755,7 @@ const Profile = { num: 32, name: "descent", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -18494,6 +19770,7 @@ const Profile = { num: 33, name: "moderateActivityMinutes", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -18508,6 +19785,7 @@ const Profile = { num: 34, name: "vigorousActivityMinutes", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -18529,6 +19807,7 @@ const Profile = { num: 253, // Must align to logging interval, for example, time must be 00:00:00 for daily log. name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -18543,6 +19822,7 @@ const Profile = { num: 0, // 7-day rolling average name: "restingHeartRate", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -18557,6 +19837,7 @@ const Profile = { num: 1, // RHR for today only. (Feeds into 7-day average) name: "currentDayRestingHeartRate", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -18578,6 +19859,7 @@ const Profile = { num: 253, name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -18592,6 +19874,7 @@ const Profile = { num: 0, name: "readingSpo2", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -18606,6 +19889,7 @@ const Profile = { num: 1, name: "readingConfidence", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -18620,6 +19904,7 @@ const Profile = { num: 2, // Mode when data was captured name: "mode", type: "spo2MeasurementType", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -18641,6 +19926,7 @@ const Profile = { num: 253, name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -18655,6 +19941,7 @@ const Profile = { num: 0, name: "fractionalTimestamp", type: "uint16", + baseType: "uint16", array: "false", scale: 32768, offset: 0, @@ -18669,6 +19956,7 @@ const Profile = { num: 1, name: "time256", type: "uint8", + baseType: "uint8", array: "false", scale: [256, ], offset: [0, ], @@ -18683,6 +19971,7 @@ const Profile = { num: 6, name: "filteredBpm", type: "uint8", + baseType: "uint8", array: "true", scale: 1, offset: 0, @@ -18697,6 +19986,7 @@ const Profile = { num: 9, name: "eventTimestamp", type: "uint32", + baseType: "uint32", array: "true", scale: 1024, offset: 0, @@ -18711,6 +20001,7 @@ const Profile = { num: 10, name: "eventTimestamp12", type: "byte", + baseType: "byte", array: "true", scale: [1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, ], offset: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ], @@ -18732,6 +20023,7 @@ const Profile = { num: 0, name: "stressLevelValue", type: "sint16", + baseType: "sint16", array: "false", scale: 1, offset: 0, @@ -18746,6 +20038,7 @@ const Profile = { num: 1, // Time stress score was calculated name: "stressLevelTime", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -18767,6 +20060,7 @@ const Profile = { num: 0, // Time maxMET and vo2 were calculated name: "updateTime", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -18781,6 +20075,7 @@ const Profile = { num: 2, name: "vo2Max", type: "uint16", + baseType: "uint16", array: "false", scale: 10, offset: 0, @@ -18795,6 +20090,7 @@ const Profile = { num: 5, name: "sport", type: "sport", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -18809,6 +20105,7 @@ const Profile = { num: 6, name: "subSport", type: "subSport", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -18823,6 +20120,7 @@ const Profile = { num: 8, name: "maxMetCategory", type: "maxMetCategory", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -18837,6 +20135,7 @@ const Profile = { num: 9, // Indicates if calibrated data was used in the calculation name: "calibratedData", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -18851,6 +20150,7 @@ const Profile = { num: 12, // Indicates if the estimate was obtained using a chest strap or wrist heart rate name: "hrSource", type: "maxMetHeartRateSource", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -18865,6 +20165,7 @@ const Profile = { num: 13, // Indidcates if the estimate was obtained using onboard GPS or connected GPS name: "speedSource", type: "maxMetSpeedSource", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -18886,6 +20187,7 @@ const Profile = { num: 253, name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -18900,6 +20202,7 @@ const Profile = { num: 0, // Processing interval length in seconds name: "processingInterval", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -18914,6 +20217,7 @@ const Profile = { num: 1, // Body battery level: [0,100] Blank: -16 name: "level", type: "sint8", + baseType: "sint8", array: "true", scale: 1, offset: 0, @@ -18928,6 +20232,7 @@ const Profile = { num: 2, // Body battery charged value name: "charged", type: "sint16", + baseType: "sint16", array: "true", scale: 1, offset: 0, @@ -18942,6 +20247,7 @@ const Profile = { num: 3, // Body battery uncharged value name: "uncharged", type: "sint16", + baseType: "sint16", array: "true", scale: 1, offset: 0, @@ -18963,6 +20269,7 @@ const Profile = { num: 253, name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -18977,6 +20284,7 @@ const Profile = { num: 0, // Event ID. Health SDK use only name: "eventId", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -18998,6 +20306,7 @@ const Profile = { num: 253, name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -19012,6 +20321,7 @@ const Profile = { num: 0, // Millisecond resolution of the timestamp name: "timestampMs", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -19026,6 +20336,7 @@ const Profile = { num: 1, // Sampling Interval in Milliseconds name: "samplingInterval", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -19040,6 +20351,7 @@ const Profile = { num: 2, // X-Axis Measurement name: "accelX", type: "sint16", + baseType: "sint16", array: "true", scale: 1.024, offset: 0, @@ -19054,6 +20366,7 @@ const Profile = { num: 3, // Y-Axis Measurement name: "accelY", type: "sint16", + baseType: "sint16", array: "true", scale: 1.024, offset: 0, @@ -19068,6 +20381,7 @@ const Profile = { num: 4, // Z-Axis Measurement name: "accelZ", type: "sint16", + baseType: "sint16", array: "true", scale: 1.024, offset: 0, @@ -19082,6 +20396,7 @@ const Profile = { num: 5, // 32 kHz timestamp name: "timestamp32k", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -19103,6 +20418,7 @@ const Profile = { num: 253, name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -19117,6 +20433,7 @@ const Profile = { num: 0, // Millisecond resolution of the timestamp name: "timestampMs", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -19131,6 +20448,7 @@ const Profile = { num: 1, // Sampling Interval in 32 kHz timescale name: "samplingInterval", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -19145,6 +20463,7 @@ const Profile = { num: 2, // X-Axis Measurement name: "gyroX", type: "sint16", + baseType: "sint16", array: "true", scale: 28.57143, offset: 0, @@ -19159,6 +20478,7 @@ const Profile = { num: 3, // Y-Axis Measurement name: "gyroY", type: "sint16", + baseType: "sint16", array: "true", scale: 28.57143, offset: 0, @@ -19173,6 +20493,7 @@ const Profile = { num: 4, // Z-Axis Measurement name: "gyroZ", type: "sint16", + baseType: "sint16", array: "true", scale: 28.57143, offset: 0, @@ -19187,6 +20508,7 @@ const Profile = { num: 5, // 32 kHz timestamp name: "timestamp32k", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -19208,6 +20530,7 @@ const Profile = { num: 253, name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -19222,6 +20545,7 @@ const Profile = { num: 0, // Processing interval length in seconds. File start: 0xFFFFFFEF File stop: 0xFFFFFFEE name: "processingInterval", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -19236,6 +20560,7 @@ const Profile = { num: 1, // Total step sum name: "steps", type: "uint32", + baseType: "uint32", array: "true", scale: 1, offset: 0, @@ -19257,6 +20582,7 @@ const Profile = { num: 253, name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -19271,6 +20597,7 @@ const Profile = { num: 0, // Processing interval length in seconds name: "processingInterval", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -19285,6 +20612,7 @@ const Profile = { num: 1, // SpO2 Reading: [70,100] Blank: 240 name: "readingSpo2", type: "uint8", + baseType: "uint8", array: "true", scale: 1, offset: 0, @@ -19299,6 +20627,7 @@ const Profile = { num: 2, // SpO2 Confidence: [0,254] name: "confidence", type: "uint8", + baseType: "uint8", array: "true", scale: 1, offset: 0, @@ -19320,6 +20649,7 @@ const Profile = { num: 253, name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -19334,6 +20664,7 @@ const Profile = { num: 0, // Processing interval length in seconds name: "processingInterval", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -19348,6 +20679,7 @@ const Profile = { num: 1, // Stress Level: [0,100] Off wrist: -1 Excess motion: -2 Not enough data: -3 Recovering from exercise: -4 Unidentified: -5 Blank: -16 name: "stressLevel", type: "sint8", + baseType: "sint8", array: "true", scale: 1, offset: 0, @@ -19369,6 +20701,7 @@ const Profile = { num: 253, name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -19383,6 +20716,7 @@ const Profile = { num: 0, // Processing interval length in seconds name: "processingInterval", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -19397,6 +20731,7 @@ const Profile = { num: 1, // Breaths / min: [1,100] Invalid: 255 Excess motion: 254 Off wrist: 253 Not available: 252 Blank: 2.4 name: "respirationRate", type: "sint16", + baseType: "sint16", array: "true", scale: 100, offset: 0, @@ -19418,6 +20753,7 @@ const Profile = { num: 253, name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -19432,6 +20768,7 @@ const Profile = { num: 0, // Processing interval length in seconds name: "processingInterval", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -19446,6 +20783,7 @@ const Profile = { num: 1, // Status of measurements in buffer - 0 indicates SEARCHING 1 indicates LOCKED name: "status", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -19460,6 +20798,7 @@ const Profile = { num: 2, // Beats / min. Blank: 0 name: "heartRate", type: "uint8", + baseType: "uint8", array: "true", scale: 1, offset: 0, @@ -19481,6 +20820,7 @@ const Profile = { num: 253, // Encoded configuration data name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -19495,6 +20835,7 @@ const Profile = { num: 0, // Encoded configuration data. Health SDK use only name: "data", type: "byte", + baseType: "byte", array: "true", scale: 1, offset: 0, @@ -19509,6 +20850,7 @@ const Profile = { num: 1, // Size in bytes of data field name: "dataSize", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -19530,6 +20872,7 @@ const Profile = { num: 253, name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -19544,6 +20887,7 @@ const Profile = { num: 0, // Processing interval length in seconds name: "processingInterval", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -19558,6 +20902,7 @@ const Profile = { num: 1, // Wrist temperature reading name: "value", type: "uint16", + baseType: "uint16", array: "true", scale: 1000, offset: 0, @@ -19579,6 +20924,7 @@ const Profile = { num: 250, // Sequence number of memo blocks name: "partIndex", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -19593,6 +20939,7 @@ const Profile = { num: 0, // Deprecated. Use data field. name: "memo", type: "byte", + baseType: "byte", array: "true", scale: 1, offset: 0, @@ -19607,6 +20954,7 @@ const Profile = { num: 1, // Message Number of the parent message name: "mesgNum", type: "mesgNum", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -19621,6 +20969,7 @@ const Profile = { num: 2, // Index of mesg that this glob is associated with. name: "parentIndex", type: "messageIndex", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -19635,6 +20984,7 @@ const Profile = { num: 3, // Field within the parent that this glob is associated with name: "fieldNum", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -19649,6 +20999,7 @@ const Profile = { num: 4, // Block of utf8 bytes. Note, mutltibyte characters may be split across adjoining memo_glob messages. name: "data", type: "uint8z", + baseType: "uint8z", array: "true", scale: 1, offset: 0, @@ -19670,6 +21021,7 @@ const Profile = { num: 253, name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -19684,6 +21036,7 @@ const Profile = { num: 0, name: "sleepLevel", type: "sleepLevel", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -19705,6 +21058,7 @@ const Profile = { num: 0, name: "channelNumber", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -19719,6 +21073,7 @@ const Profile = { num: 1, name: "deviceType", type: "uint8z", + baseType: "uint8z", array: "false", scale: 1, offset: 0, @@ -19733,6 +21088,7 @@ const Profile = { num: 2, name: "deviceNumber", type: "uint16z", + baseType: "uint16z", array: "false", scale: 1, offset: 0, @@ -19747,6 +21103,7 @@ const Profile = { num: 3, name: "transmissionType", type: "uint8z", + baseType: "uint8z", array: "false", scale: 1, offset: 0, @@ -19761,6 +21118,7 @@ const Profile = { num: 4, name: "deviceIndex", type: "deviceIndex", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -19782,6 +21140,7 @@ const Profile = { num: 253, name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -19796,6 +21155,7 @@ const Profile = { num: 0, name: "fractionalTimestamp", type: "uint16", + baseType: "uint16", array: "false", scale: 32768, offset: 0, @@ -19810,6 +21170,7 @@ const Profile = { num: 1, name: "mesgId", type: "byte", + baseType: "byte", array: "false", scale: 1, offset: 0, @@ -19824,6 +21185,7 @@ const Profile = { num: 2, name: "mesgData", type: "byte", + baseType: "byte", array: "true", scale: [1, 1, 1, 1, 1, 1, 1, 1, 1, ], offset: [0, 0, 0, 0, 0, 0, 0, 0, 0, ], @@ -19838,6 +21200,7 @@ const Profile = { num: 3, name: "channelNumber", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -19852,6 +21215,7 @@ const Profile = { num: 4, name: "data", type: "byte", + baseType: "byte", array: "true", scale: 1, offset: 0, @@ -19873,6 +21237,7 @@ const Profile = { num: 253, name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -19887,6 +21252,7 @@ const Profile = { num: 0, name: "fractionalTimestamp", type: "uint16", + baseType: "uint16", array: "false", scale: 32768, offset: 0, @@ -19901,6 +21267,7 @@ const Profile = { num: 1, name: "mesgId", type: "byte", + baseType: "byte", array: "false", scale: 1, offset: 0, @@ -19915,6 +21282,7 @@ const Profile = { num: 2, name: "mesgData", type: "byte", + baseType: "byte", array: "true", scale: [1, 1, 1, 1, 1, 1, 1, 1, 1, ], offset: [0, 0, 0, 0, 0, 0, 0, 0, 0, ], @@ -19929,6 +21297,7 @@ const Profile = { num: 3, name: "channelNumber", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -19943,6 +21312,7 @@ const Profile = { num: 4, name: "data", type: "byte", + baseType: "byte", array: "true", scale: 1, offset: 0, @@ -19964,6 +21334,7 @@ const Profile = { num: 0, name: "screenIndex", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -19978,6 +21349,7 @@ const Profile = { num: 1, // number of fields in screen name: "fieldCount", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -19992,6 +21364,7 @@ const Profile = { num: 2, name: "layout", type: "exdLayout", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -20006,6 +21379,7 @@ const Profile = { num: 3, name: "screenEnabled", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -20027,6 +21401,7 @@ const Profile = { num: 0, name: "screenIndex", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -20041,6 +21416,7 @@ const Profile = { num: 1, name: "conceptField", type: "byte", + baseType: "byte", array: "false", scale: [1, 1, ], offset: [0, 0, ], @@ -20055,6 +21431,7 @@ const Profile = { num: 2, name: "fieldId", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -20069,6 +21446,7 @@ const Profile = { num: 3, name: "conceptCount", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -20083,6 +21461,7 @@ const Profile = { num: 4, name: "displayType", type: "exdDisplayType", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -20097,6 +21476,7 @@ const Profile = { num: 5, name: "title", type: "string", + baseType: "string", array: "true", scale: 1, offset: 0, @@ -20118,6 +21498,7 @@ const Profile = { num: 0, name: "screenIndex", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -20132,6 +21513,7 @@ const Profile = { num: 1, name: "conceptField", type: "byte", + baseType: "byte", array: "false", scale: [1, 1, ], offset: [0, 0, ], @@ -20146,6 +21528,7 @@ const Profile = { num: 2, name: "fieldId", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -20160,6 +21543,7 @@ const Profile = { num: 3, name: "conceptIndex", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -20174,6 +21558,7 @@ const Profile = { num: 4, name: "dataPage", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -20188,6 +21573,7 @@ const Profile = { num: 5, name: "conceptKey", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -20202,6 +21588,7 @@ const Profile = { num: 6, name: "scaling", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -20216,6 +21603,7 @@ const Profile = { num: 8, name: "dataUnits", type: "exdDataUnits", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -20230,6 +21618,7 @@ const Profile = { num: 9, name: "qualifier", type: "exdQualifiers", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -20244,6 +21633,7 @@ const Profile = { num: 10, name: "descriptor", type: "exdDescriptors", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -20258,6 +21648,7 @@ const Profile = { num: 11, name: "isSigned", type: "bool", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -20279,6 +21670,7 @@ const Profile = { num: 253, name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -20293,6 +21685,7 @@ const Profile = { num: 0, name: "referenceMesg", type: "mesgNum", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -20307,6 +21700,7 @@ const Profile = { num: 1, name: "referenceIndex", type: "messageIndex", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -20321,6 +21715,7 @@ const Profile = { num: 2, // 0 if above water name: "avgDepth", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -20335,6 +21730,7 @@ const Profile = { num: 3, // 0 if above water name: "maxDepth", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -20349,6 +21745,7 @@ const Profile = { num: 4, // Time since end of last dive name: "surfaceInterval", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -20363,6 +21760,7 @@ const Profile = { num: 5, name: "startCns", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -20377,6 +21775,7 @@ const Profile = { num: 6, name: "endCns", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -20391,6 +21790,7 @@ const Profile = { num: 7, name: "startN2", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -20405,6 +21805,7 @@ const Profile = { num: 8, name: "endN2", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -20419,6 +21820,7 @@ const Profile = { num: 9, name: "o2Toxicity", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -20433,6 +21835,7 @@ const Profile = { num: 10, name: "diveNumber", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -20447,6 +21850,7 @@ const Profile = { num: 11, name: "bottomTime", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -20461,6 +21865,7 @@ const Profile = { num: 12, // Average pressure-based surface air consumption name: "avgPressureSac", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -20475,6 +21880,7 @@ const Profile = { num: 13, // Average volumetric surface air consumption name: "avgVolumeSac", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -20489,6 +21895,7 @@ const Profile = { num: 14, // Average respiratory minute volume name: "avgRmv", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -20503,6 +21910,7 @@ const Profile = { num: 15, // Time to reach deepest level stop name: "descentTime", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -20517,6 +21925,7 @@ const Profile = { num: 16, // Time after leaving bottom until reaching surface name: "ascentTime", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -20531,6 +21940,7 @@ const Profile = { num: 17, // Average ascent rate, not including descents or stops name: "avgAscentRate", type: "sint32", + baseType: "sint32", array: "false", scale: 1000, offset: 0, @@ -20545,6 +21955,7 @@ const Profile = { num: 22, // Average descent rate, not including ascents or stops name: "avgDescentRate", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -20559,6 +21970,7 @@ const Profile = { num: 23, // Maximum ascent rate name: "maxAscentRate", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -20573,6 +21985,7 @@ const Profile = { num: 24, // Maximum descent rate name: "maxDescentRate", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -20587,6 +22000,7 @@ const Profile = { num: 25, // Time spent neither ascending nor descending name: "hangTime", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -20608,6 +22022,7 @@ const Profile = { num: 253, name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -20622,6 +22037,7 @@ const Profile = { num: 0, // Time interval length in seconds name: "time", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -20636,6 +22052,7 @@ const Profile = { num: 1, // Total accelerometer energy in the interval name: "energyTotal", type: "uint32", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -20650,6 +22067,7 @@ const Profile = { num: 2, // Count of zero crossings name: "zeroCrossCnt", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -20664,6 +22082,7 @@ const Profile = { num: 3, // Instance ID of zero crossing algorithm name: "instance", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -20678,6 +22097,7 @@ const Profile = { num: 4, // Total accelerometer time above threshold in the interval name: "timeAboveThreshold", type: "uint16", + baseType: "uint16", array: "false", scale: 25, offset: 0, @@ -20699,6 +22119,7 @@ const Profile = { num: 0, // Time between beats name: "time", type: "uint16", + baseType: "uint16", array: "true", scale: 1000, offset: 0, @@ -20720,6 +22141,7 @@ const Profile = { num: 253, name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -20734,6 +22156,7 @@ const Profile = { num: 0, // Milliseconds past date_time name: "timestampMs", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -20748,6 +22171,7 @@ const Profile = { num: 1, // Array of millisecond times between beats name: "time", type: "uint16", + baseType: "uint16", array: "true", scale: 1, offset: 0, @@ -20769,6 +22193,7 @@ const Profile = { num: 253, name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -20783,6 +22208,7 @@ const Profile = { num: 0, // 7 day RMSSD average over sleep name: "weeklyAverage", type: "uint16", + baseType: "uint16", array: "false", scale: 128, offset: 0, @@ -20797,6 +22223,7 @@ const Profile = { num: 1, // Last night RMSSD average over sleep name: "lastNightAverage", type: "uint16", + baseType: "uint16", array: "false", scale: 128, offset: 0, @@ -20811,6 +22238,7 @@ const Profile = { num: 2, // 5 minute high RMSSD value over sleep name: "lastNight5MinHigh", type: "uint16", + baseType: "uint16", array: "false", scale: 128, offset: 0, @@ -20825,6 +22253,7 @@ const Profile = { num: 3, // 3 week baseline, upper boundary of low HRV status name: "baselineLowUpper", type: "uint16", + baseType: "uint16", array: "false", scale: 128, offset: 0, @@ -20839,6 +22268,7 @@ const Profile = { num: 4, // 3 week baseline, lower boundary of balanced HRV status name: "baselineBalancedLower", type: "uint16", + baseType: "uint16", array: "false", scale: 128, offset: 0, @@ -20853,6 +22283,7 @@ const Profile = { num: 5, // 3 week baseline, upper boundary of balanced HRV status name: "baselineBalancedUpper", type: "uint16", + baseType: "uint16", array: "false", scale: 128, offset: 0, @@ -20867,6 +22298,7 @@ const Profile = { num: 6, name: "status", type: "hrvStatus", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -20888,6 +22320,7 @@ const Profile = { num: 253, name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -20902,6 +22335,7 @@ const Profile = { num: 0, // 5 minute RMSSD name: "value", type: "uint16", + baseType: "uint16", array: "false", scale: 128, offset: 0, @@ -20923,6 +22357,7 @@ const Profile = { num: 253, name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -20937,6 +22372,7 @@ const Profile = { num: 0, // Millisecond resolution of the timestamp name: "timestampMs", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -20951,6 +22387,7 @@ const Profile = { num: 1, // 1 bit for gap indicator, 1 bit for quality indicator, and 14 bits for Beat-to-Beat interval values in whole-integer millisecond resolution name: "data", type: "uint16", + baseType: "uint16", array: "true", scale: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ], offset: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ], @@ -20965,6 +22402,7 @@ const Profile = { num: 2, // Array of millisecond times between beats name: "time", type: "uint16", + baseType: "uint16", array: "true", scale: 1, offset: 0, @@ -20979,6 +22417,7 @@ const Profile = { num: 3, // 1 = high confidence. 0 = low confidence. N/A when gap = 1 name: "quality", type: "uint8", + baseType: "uint8", array: "true", scale: 1, offset: 0, @@ -20993,6 +22432,7 @@ const Profile = { num: 4, // 1 = gap (time represents ms gap length). 0 = BBI data name: "gap", type: "uint8", + baseType: "uint8", array: "true", scale: 1, offset: 0, @@ -21014,6 +22454,7 @@ const Profile = { num: 253, name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -21028,6 +22469,7 @@ const Profile = { num: 0, // Breaths * 100 /min, -300 indicates invalid, -200 indicates large motion, -100 indicates off wrist name: "respirationRate", type: "sint16", + baseType: "sint16", array: "false", scale: 100, offset: 0, @@ -21049,6 +22491,7 @@ const Profile = { num: 253, name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -21063,6 +22506,7 @@ const Profile = { num: 0, name: "minSpeed", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -21077,6 +22521,7 @@ const Profile = { num: 1, name: "maxSpeed", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -21091,6 +22536,7 @@ const Profile = { num: 2, name: "avgSpeed", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -21105,6 +22551,7 @@ const Profile = { num: 3, name: "shotCount", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -21119,6 +22566,7 @@ const Profile = { num: 4, name: "projectileType", type: "projectileType", + baseType: "enum", array: "false", scale: 1, offset: 0, @@ -21133,6 +22581,7 @@ const Profile = { num: 5, name: "grainWeight", type: "uint32", + baseType: "uint32", array: "false", scale: 10, offset: 0, @@ -21147,6 +22596,7 @@ const Profile = { num: 6, name: "standardDeviation", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -21168,6 +22618,7 @@ const Profile = { num: 253, name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -21182,6 +22633,7 @@ const Profile = { num: 0, name: "shotSpeed", type: "uint32", + baseType: "uint32", array: "false", scale: 1000, offset: 0, @@ -21196,6 +22648,7 @@ const Profile = { num: 1, name: "shotNum", type: "uint16", + baseType: "uint16", array: "false", scale: 1, offset: 0, @@ -21217,6 +22670,7 @@ const Profile = { num: 253, name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -21231,6 +22685,7 @@ const Profile = { num: 0, name: "sensor", type: "antChannelId", + baseType: "uint32z", array: "false", scale: 1, offset: 0, @@ -21245,6 +22700,7 @@ const Profile = { num: 1, name: "pressure", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -21266,6 +22722,7 @@ const Profile = { num: 253, name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -21280,6 +22737,7 @@ const Profile = { num: 0, name: "sensor", type: "antChannelId", + baseType: "uint32z", array: "false", scale: 1, offset: 0, @@ -21294,6 +22752,7 @@ const Profile = { num: 1, name: "startPressure", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -21308,6 +22767,7 @@ const Profile = { num: 2, name: "endPressure", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -21322,6 +22782,7 @@ const Profile = { num: 3, name: "volumeUsed", type: "uint32", + baseType: "uint32", array: "false", scale: 100, offset: 0, @@ -21343,6 +22804,7 @@ const Profile = { num: 0, // Average of awake_time_score and awakenings_count_score. If valid: 0 (worst) to 100 (best). If unknown: FIT_UINT8_INVALID. name: "combinedAwakeScore", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -21357,6 +22819,7 @@ const Profile = { num: 1, // Score that evaluates the total time spent awake between sleep. If valid: 0 (worst) to 100 (best). If unknown: FIT_UINT8_INVALID. name: "awakeTimeScore", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -21371,6 +22834,7 @@ const Profile = { num: 2, // Score that evaluates the number of awakenings that interrupt sleep. If valid: 0 (worst) to 100 (best). If unknown: FIT_UINT8_INVALID. name: "awakeningsCountScore", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -21385,6 +22849,7 @@ const Profile = { num: 3, // Score that evaluates the amount of deep sleep. If valid: 0 (worst) to 100 (best). If unknown: FIT_UINT8_INVALID. name: "deepSleepScore", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -21399,6 +22864,7 @@ const Profile = { num: 4, // Score that evaluates the quality of sleep based on sleep stages, heart-rate variability and possible awakenings during the night. If valid: 0 (worst) to 100 (best). If unknown: FIT_UINT8_INVALID. name: "sleepDurationScore", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -21413,6 +22879,7 @@ const Profile = { num: 5, // Score that evaluates the amount of light sleep. If valid: 0 (worst) to 100 (best). If unknown: FIT_UINT8_INVALID. name: "lightSleepScore", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -21427,6 +22894,7 @@ const Profile = { num: 6, // Total score that summarizes the overall quality of sleep, combining sleep duration and quality. If valid: 0 (worst) to 100 (best). If unknown: FIT_UINT8_INVALID. name: "overallSleepScore", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -21441,6 +22909,7 @@ const Profile = { num: 7, // Score that evaluates the quality of sleep based on sleep stages, heart-rate variability and possible awakenings during the night. If valid: 0 (worst) to 100 (best). If unknown: FIT_UINT8_INVALID. name: "sleepQualityScore", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -21455,6 +22924,7 @@ const Profile = { num: 8, // Score that evaluates stress and recovery during sleep. If valid: 0 (worst) to 100 (best). If unknown: FIT_UINT8_INVALID. name: "sleepRecoveryScore", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -21469,6 +22939,7 @@ const Profile = { num: 9, // Score that evaluates the amount of REM sleep. If valid: 0 (worst) to 100 (best). If unknown: FIT_UINT8_INVALID. name: "remSleepScore", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -21483,6 +22954,7 @@ const Profile = { num: 10, // Score that evaluates the amount of restlessness during sleep. If valid: 0 (worst) to 100 (best). If unknown: FIT_UINT8_INVALID. name: "sleepRestlessnessScore", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -21497,6 +22969,7 @@ const Profile = { num: 11, // The number of awakenings during sleep. name: "awakeningsCount", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -21511,6 +22984,7 @@ const Profile = { num: 14, // Score that evaluates the sleep interruptions. If valid: 0 (worst) to 100 (best). If unknown: FIT_UINT8_INVALID. name: "interruptionsScore", type: "uint8", + baseType: "uint8", array: "false", scale: 1, offset: 0, @@ -21525,6 +22999,7 @@ const Profile = { num: 15, // Excludes stress during awake periods in the sleep window name: "averageStressDuringSleep", type: "uint16", + baseType: "uint16", array: "false", scale: 100, offset: 0, @@ -21546,6 +23021,7 @@ const Profile = { num: 253, name: "timestamp", type: "dateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -21560,6 +23036,7 @@ const Profile = { num: 0, name: "localTimestamp", type: "localDateTime", + baseType: "uint32", array: "false", scale: 1, offset: 0, @@ -21574,6 +23051,7 @@ const Profile = { num: 1, // The average overnight deviation from baseline temperature in degrees C name: "averageDeviation", type: "float32", + baseType: "float32", array: "false", scale: 1, offset: 0, @@ -21588,6 +23066,7 @@ const Profile = { num: 2, // The average 7 day overnight deviation from baseline temperature in degrees C name: "average7DayDeviation", type: "float32", + baseType: "float32", array: "false", scale: 1, offset: 0, @@ -21602,6 +23081,7 @@ const Profile = { num: 4, // Final overnight temperature value name: "nightlyValue", type: "float32", + baseType: "float32", array: "false", scale: 1, offset: 0, @@ -22817,6 +24297,7 @@ types: { 330: "eoSwimbetter", 331: "mywhoosh", 332: "ravemen", + 333: "tektroRacingProducts", 5759: "actigraphcorp", }, garminProduct: { @@ -23250,7 +24731,13 @@ types: { 4536: "fenix8", 4556: "d2Mach1Pro", 4575: "enduro3", + 4583: "instinctE40mm", + 4584: "instinctE45mm", + 4585: "instinct3Solar45mm", + 4586: "instinct3Amoled45mm", + 4587: "instinct3Amoled50mm", 4666: "fenixE", + 4759: "instinct3Solar50mm", 10007: "sdm4", // SDM4 footpod 10014: "edgeRemote", 20533: "tacxTrainingAppWin", diff --git a/src/stream.js b/src/stream.js index 6e04634..4ca324b 100644 --- a/src/stream.js +++ b/src/stream.js @@ -1,12 +1,12 @@ ///////////////////////////////////////////////////////////////////////////////////////////// -// Copyright 2024 Garmin International, Inc. +// Copyright 2025 Garmin International, Inc. // Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you // may not use this file except in compliance with the Flexible and Interoperable Data // Transfer (FIT) Protocol License. ///////////////////////////////////////////////////////////////////////////////////////////// // ****WARNING**** This file is auto-generated! Do NOT edit this file. -// Profile Version = 21.158.0Release -// Tag = production/release/21.158.0-0-gc9428aa +// Profile Version = 21.161.0Release +// Tag = production/release/21.161.0-0-g58854c0 ///////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/utils-hr-mesg.js b/src/utils-hr-mesg.js index 6bde5d8..8fa8694 100644 --- a/src/utils-hr-mesg.js +++ b/src/utils-hr-mesg.js @@ -1,12 +1,12 @@ ///////////////////////////////////////////////////////////////////////////////////////////// -// Copyright 2024 Garmin International, Inc. +// Copyright 2025 Garmin International, Inc. // Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you // may not use this file except in compliance with the Flexible and Interoperable Data // Transfer (FIT) Protocol License. ///////////////////////////////////////////////////////////////////////////////////////////// // ****WARNING**** This file is auto-generated! Do NOT edit this file. -// Profile Version = 21.158.0Release -// Tag = production/release/21.158.0-0-gc9428aa +// Profile Version = 21.161.0Release +// Tag = production/release/21.161.0-0-g58854c0 ///////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/utils-internal.js b/src/utils-internal.js index 19becd0..be47b41 100644 --- a/src/utils-internal.js +++ b/src/utils-internal.js @@ -1,12 +1,12 @@ ///////////////////////////////////////////////////////////////////////////////////////////// -// Copyright 2024 Garmin International, Inc. +// Copyright 2025 Garmin International, Inc. // Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you // may not use this file except in compliance with the Flexible and Interoperable Data // Transfer (FIT) Protocol License. ///////////////////////////////////////////////////////////////////////////////////////////// // ****WARNING**** This file is auto-generated! Do NOT edit this file. -// Profile Version = 21.158.0Release -// Tag = production/release/21.158.0-0-gc9428aa +// Profile Version = 21.161.0Release +// Tag = production/release/21.161.0-0-g58854c0 ///////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/utils.js b/src/utils.js index 17ef3d7..0f616cc 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,12 +1,12 @@ ///////////////////////////////////////////////////////////////////////////////////////////// -// Copyright 2024 Garmin International, Inc. +// Copyright 2025 Garmin International, Inc. // Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you // may not use this file except in compliance with the Flexible and Interoperable Data // Transfer (FIT) Protocol License. ///////////////////////////////////////////////////////////////////////////////////////////// // ****WARNING**** This file is auto-generated! Do NOT edit this file. -// Profile Version = 21.158.0Release -// Tag = production/release/21.158.0-0-gc9428aa +// Profile Version = 21.161.0Release +// Tag = production/release/21.161.0-0-g58854c0 ///////////////////////////////////////////////////////////////////////////////////////////// @@ -25,7 +25,42 @@ const convertDateTimeToDate = (datetime) => { return new Date((datetime ?? 0) * 1000 + FIT_EPOCH_MS); }; +/** + * Convert a JavaScript Date to a FIT DateTime + * @param {Date} A JavaScript Date object + * @return {number} datetime - Seconds since FIT EPOCH + */ +const convertDateToDateTime = (date) => { + return (date.getTime() - FIT_EPOCH_MS) / 1000; +}; + + +/** + * FIT Base Type enum, for use with Developer Data Field Descriptions + */ +const FitBaseType = Object.freeze({ + enum: 0, + sint8: 1, + uint8: 2, + sint16: 131, + uint16: 132, + sint32: 133, + uint32: 134, + string: 7, + float32: 136, + float64: 137, + uint8z: 10, + uint16z: 139, + uint32z: 140, + byte: 13, + sint64: 142, + uint64: 143, + uint64z: 144, +}); + export default { FIT_EPOCH_MS, convertDateTimeToDate, + convertDateToDateTime, + FitBaseType, }; diff --git a/test/accumulator.test.js b/test/accumulator.test.js index 820d5ed..bf47636 100644 --- a/test/accumulator.test.js +++ b/test/accumulator.test.js @@ -1,10 +1,11 @@ ///////////////////////////////////////////////////////////////////////////////////////////// -// Copyright 2024 Garmin International, Inc. +// Copyright 2025 Garmin International, Inc. // Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you // may not use this file except in compliance with the Flexible and Interoperable Data // Transfer (FIT) Protocol License. ///////////////////////////////////////////////////////////////////////////////////////////// +import { describe, expect, test } from "vitest"; import Accumulator from "../src/accumulator.js"; diff --git a/test/bit-stream.test.js b/test/bit-stream.test.js index 1ff813c..bd53260 100644 --- a/test/bit-stream.test.js +++ b/test/bit-stream.test.js @@ -1,10 +1,11 @@ ///////////////////////////////////////////////////////////////////////////////////////////// -// Copyright 2024 Garmin International, Inc. +// Copyright 2025 Garmin International, Inc. // Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you // may not use this file except in compliance with the Flexible and Interoperable Data // Transfer (FIT) Protocol License. ///////////////////////////////////////////////////////////////////////////////////////////// +import { describe, expect, test } from "vitest"; import BitStream from "../src/bit-stream.js"; import FIT from "../src/fit.js"; diff --git a/test/crc.test.js b/test/crc.test.js index 2432e3f..437f618 100644 --- a/test/crc.test.js +++ b/test/crc.test.js @@ -1,10 +1,11 @@ ///////////////////////////////////////////////////////////////////////////////////////////// -// Copyright 2024 Garmin International, Inc. +// Copyright 2025 Garmin International, Inc. // Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you // may not use this file except in compliance with the Flexible and Interoperable Data // Transfer (FIT) Protocol License. ///////////////////////////////////////////////////////////////////////////////////////////// +import { describe, expect, test } from "vitest"; import CrcCalculator from "../src/crc-calculator.js" import Data from "./data/test-data.js" diff --git a/test/data/test-data-expand-hr-mesgs.js b/test/data/test-data-expand-hr-mesgs.js index 669946f..ca2f27f 100644 --- a/test/data/test-data-expand-hr-mesgs.js +++ b/test/data/test-data-expand-hr-mesgs.js @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////////////////////// -// Copyright 2024 Garmin International, Inc. +// Copyright 2025 Garmin International, Inc. // Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you // may not use this file except in compliance with the Flexible and Interoperable Data // Transfer (FIT) Protocol License. diff --git a/test/data/test-data.js b/test/data/test-data.js index 2f3f806..f620cd0 100644 --- a/test/data/test-data.js +++ b/test/data/test-data.js @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////////////////////// -// Copyright 2024 Garmin International, Inc. +// Copyright 2025 Garmin International, Inc. // Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you // may not use this file except in compliance with the Flexible and Interoperable Data // Transfer (FIT) Protocol License. diff --git a/test/decoder.test.js b/test/decoder.test.js index 797a27a..864cf33 100644 --- a/test/decoder.test.js +++ b/test/decoder.test.js @@ -1,13 +1,13 @@ ///////////////////////////////////////////////////////////////////////////////////////////// -// Copyright 2024 Garmin International, Inc. +// Copyright 2025 Garmin International, Inc. // Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you // may not use this file except in compliance with the Flexible and Interoperable Data // Transfer (FIT) Protocol License. ///////////////////////////////////////////////////////////////////////////////////////////// +import { describe, expect, test, vi } from "vitest"; import * as fs from "fs"; -import { jest } from "@jest/globals"; import CRC from "../src/crc-calculator.js"; import Decoder from "../src/decoder.js"; @@ -61,7 +61,7 @@ describe("Decoder Tests", () => { }); test("When file is not a FIT checkIntegrity() returns false", () => { - const isFITMock = jest + const isFITMock = vi .spyOn(Decoder.prototype, "isFIT") .mockImplementationOnce(() => { return false; @@ -79,7 +79,7 @@ describe("Decoder Tests", () => { }); test("When Header CRC is incorrect checkIntegrity() returns false", () => { - const calculateCRCMock = jest + const calculateCRCMock = vi .spyOn(CRC, "calculateCRC") .mockImplementationOnce(() => { return false; @@ -100,7 +100,7 @@ describe("Decoder Tests", () => { describe("Decoder FIT File Tests", () => { test("When file is not a FIT read() returns an error", () => { - const isFITMock = jest + const isFITMock = vi .spyOn(Decoder.prototype, "isFIT") .mockImplementationOnce(() => { return false; diff --git a/test/encode-activity-recipe.test.js b/test/encode-activity-recipe.test.js new file mode 100644 index 0000000..5a177be --- /dev/null +++ b/test/encode-activity-recipe.test.js @@ -0,0 +1,196 @@ +///////////////////////////////////////////////////////////////////////////////////////////// +// Copyright 2025 Garmin International, Inc. +// Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you +// may not use this file except in compliance with the Flexible and Interoperable Data +// Transfer (FIT) Protocol License. +///////////////////////////////////////////////////////////////////////////////////////////// + +import { expect, test } from "vitest"; + +import * as fs from "fs"; + +import { Encoder, Profile, Utils } from "../src/index.js"; + +test("Can encode a FIT Activity file", () => { + const twoPI = Math.PI * 2.0; + const semicirclesPerMeter = 107.173; + const DOUGHNUTS_EARNED_KEY = 0; + const HEART_RATE_KEY = 1; + + const mesgs = []; + + // Create the Developer Id message for the developer data fields. + const developerDataIdMesg = { + mesgNum: Profile.MesgNum.DEVELOPER_DATA_ID, + applicationId: Array(16).fill(0), // In practice, this should be a UUID converted to a byte array + applicationVersion: 1, + developerDataIndex: 0, + }; + mesgs.push(developerDataIdMesg); + + // Create the developer data Field Descriptions + const doughnutsFieldDescMesg = { + mesgNum: Profile.MesgNum.FIELD_DESCRIPTION, + developerDataIndex: 0, + fieldDefinitionNumber: 0, + fitBaseTypeId: Utils.FitBaseType.float32, + fieldName: "Doughnuts Earned", + units: "doughnuts", + nativeMesgNum: Profile.MesgNum.SESSION, + }; + mesgs.push(doughnutsFieldDescMesg); + + const hrFieldDescMesg = { + mesgNum: Profile.MesgNum.FIELD_DESCRIPTION, + developerDataIndex: 0, + fieldDefinitionNumber: 1, + fitBaseTypeId: Utils.FitBaseType.uint8, + fieldName: "Heart Rate", + units: "bpm", + nativeMesgNum: Profile.MesgNum.RECORD, + nativeFieldNum: 3, // See the FIT Profile for the native field numbers + + }; + mesgs.push(hrFieldDescMesg); + + // Link the Developer Data Id and Field Description messages with a unique key + const fieldDescriptions = { + [DOUGHNUTS_EARNED_KEY]: { + developerDataIdMesg: developerDataIdMesg, + fieldDescriptionMesg: doughnutsFieldDescMesg, + }, + [HEART_RATE_KEY]: { + developerDataIdMesg: developerDataIdMesg, + fieldDescriptionMesg: hrFieldDescMesg, + }, + }; + + // The starting timestamp for the activity + const now = new Date(); + const localTimestampOffset = now.getTimezoneOffset() * -60; + const startTime = Utils.convertDateToDateTime(now); + + // Every FIT file MUST contain a File ID message + mesgs.push({ + mesgNum: Profile.MesgNum.FILE_ID, + type: "activity", + manufacturer: "development", + product: 0, + timeCreated: startTime, + serialNumber: 1234, + }); + + // A Device Info message is a BEST PRACTICE for FIT ACTIVITY files + mesgs.push({ + mesgNum: Profile.MesgNum.DEVICE_INFO, + deviceIndex: "creator", + manufacturer: "development", + product: 0, + productName: "FIT Cookbook", + serialNumber: 1234, + softwareVersion: 12.34, + timestamp: startTime, + }); + + // Timer Events are a BEST PRACTICE for FIT ACTIVITY files + mesgs.push({ + mesgNum: Profile.MesgNum.EVENT, + timestamp: startTime, + event: "timer", + eventType: "start", + }); + + // Every FIT ACTIVITY file MUST contain Record messages + let timestamp = startTime; + + for (let i = 0; i <= 3600; i++) { + mesgs.push({ + mesgNum: Profile.MesgNum.RECORD, + timestamp: timestamp, + distance: i, // Ramp + enhancedSpeed: 1, // Flat Line + heartRate: (Math.sin(twoPI * (0.01 * i + 10)) + 1.0) * 127.0, // Sine + cadence: i % 255, // Sawtooth + power: (i % 255) < 127 ? 150 : 250, // Square + enhancedAltitude: Math.abs((i % 255) - 127), // Triangle + positionLat: 0, // Flat Line + positionLong: i * semicirclesPerMeter, // Ramp + + // Add a Developer Field to the Record Message + developerFields: { + [HEART_RATE_KEY]: (Math.cos(twoPI * (0.01 * i + 10)) + 1.0) * 127.0, // Cosine + }, + }); + + timestamp++; + } + + // Timer Events are a BEST PRACTICE for FIT ACTIVITY files + mesgs.push({ + mesgNum: Profile.MesgNum.EVENT, + timestamp: timestamp, + event: "timer", + eventType: "stop", + }); + + // Every FIT ACTIVITY file MUST contain at least one Lap message + mesgs.push({ + mesgNum: Profile.MesgNum.LAP, + messageIndex: 0, + timestamp: timestamp, + startTime: startTime, + totalElapsedTime: timestamp - startTime, + totalTimerTime: timestamp - startTime, + }); + + // Every FIT ACTIVITY file MUST contain at least one Session message + mesgs.push({ + mesgNum: Profile.MesgNum.SESSION, + messageIndex: 0, + timestamp: timestamp, + startTime: startTime, + totalElapsedTime: timestamp - startTime, + totalTimerTime: timestamp - startTime, + sport: "standUpPaddleboarding", + subSport: "generic", + firstLapIndex: 0, + numLaps: 1, + + // Add a Developer Field to the Session Message + developerFields: { + [DOUGHNUTS_EARNED_KEY]: (timestamp - startTime) / 1200.0, // Three per hour + }, + }); + + // Every FIT ACTIVITY file MUST contain EXACTLY one Activity message + mesgs.push({ + mesgNum: Profile.MesgNum.ACTIVITY, + timestamp: timestamp, + numSessions: 1, + localTimestamp: timestamp + localTimestampOffset, + totalTimerTime: timestamp = startTime, + }); + + try { + // Create an Encoder and provide the developer data field descriptions + const encoder = new Encoder({ fieldDescriptions, }); + + // Write each message to the encoder + mesgs.forEach((mesg) => { + encoder.writeMesg(mesg); + }); + + // Close the encoder + const uint8Array = encoder.close(); + + // Write the bytes to a file + fs.writeFileSync("test/data/encode-activity-recipe.fit", uint8Array); + + expect(uint8Array.length).toBe(108485); + } + catch (error) { + console.error(error.name, error.message, JSON.stringify(error?.cause, null, 2)); + + throw error; + } +}); diff --git a/test/encoder.test.js b/test/encoder.test.js new file mode 100644 index 0000000..6fcdec8 --- /dev/null +++ b/test/encoder.test.js @@ -0,0 +1,174 @@ +///////////////////////////////////////////////////////////////////////////////////////////// +// Copyright 2025 Garmin International, Inc. +// Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you +// may not use this file except in compliance with the Flexible and Interoperable Data +// Transfer (FIT) Protocol License. +///////////////////////////////////////////////////////////////////////////////////////////// + +import { describe, expect, test } from "vitest"; + +import { Encoder, Profile } from "../src/index.js"; + +describe("Encoder Tests", () => { + test("A file encoded with no messages should be 16 bytes long.", () => { + const encoder = new Encoder(); + const uint8Array = encoder.close(); + + expect(uint8Array.length).toBe(16); + }); + + test("Can encode a FIT file.", () => { + const fileIdMesg = { + type: "activity", + manufacturer: "development", + product: 0, + timeCreated: 1000000000, // Wed, 08 Sep 2021 01:46:40 GMT + serialNumber: 1234, + }; + + try { + const encoder = new Encoder(); + encoder.onMesg(Profile.MesgNum.FILE_ID, fileIdMesg); + const uint8Array = encoder.close(); + + expect(uint8Array.length).toBe(51); + } + catch (error) { + console.error(`${error.name}: ${error.message} \n${JSON.stringify(error.cause, null, 3)}`); + throw error; + } + }); + + describe("Can Encode Strings Tests", () => { + test("Can encode a short string of single byte charactors", () => { + const fileIdMesg = { + productName: "Short String Of Single Byte Characters", + }; + + try { + const encoder = new Encoder(); + encoder.onMesg(Profile.MesgNum.FILE_ID, fileIdMesg); + const uint8Array = encoder.close(); + + expect(uint8Array.length).toBe(65); + } + catch (error) { + console.error(`${error.name}: ${error.message} \n${JSON.stringify(error.cause, null, 3)}`); + throw error; + } + }); + + test("Encoding a single byte string greater than 255 bytes in length throws an exception", () => { + const fileIdMesg = { + productName: "AS4EgyRNHimg4Pw3bUiFQwGyOttIQti8kHzPcfoUQ1kxi4PGVpwuE7MVlfnA0PjvIdWYnwemn" + + "L5yDX4LmULwXFTt8jGqfafPSoL3CXmYVGaTHuB1ILbjdVtPGPm0FQPyS6NVeJ97cBYI6PoVI7wmRnc7MLS903ckhJephdklsjdf" + + "Y1OdBKJ4YRWTmhrR712BSl59SEwDs6uLHLUvWnA6JE6aVPkN2LJbI11QAtKzXNORWcK2ggsWqtsAzxSsdGyXCs6qs6CDxskdjfh", + }; + + try { + const encoder = new Encoder(); + + expect(() => { + encoder.onMesg(Profile.MesgNum.FILE_ID, fileIdMesg); + }).toThrowError(); + + const uint8Array = encoder.close(); + + expect(uint8Array.length).toBe(16); + } + catch (error) { + console.error(`${error.name}: ${error.message} \n${JSON.stringify(error.cause, null, 3)}`); + throw error; + } + }); + + test("Can encode a short string of multibyte charactors", () => { + const fileIdMesg = { + productName: "中文占位符文本", + }; + + try { + const encoder = new Encoder(); + encoder.onMesg(Profile.MesgNum.FILE_ID, fileIdMesg); + const uint8Array = encoder.close(); + + expect(uint8Array.length).toBe(48); + } + catch (error) { + console.error(`${error.name}: ${error.message} \n${JSON.stringify(error.cause, null, 3)}`); + throw error; + } + }); + test("Encoding a multibyte string greater than 255 bytes in length throws an exception", () => { + const fileIdMesg = { + productName: "这是一个占位符文本,用于展示设计效果。" + + "这是一个占位符文本,用于展示设计效果。" + + "这是一个占位符文本,用于展示设计效果。" + + "这是一个占位符文本,用于展示设计效果。" + + "这是一个占位符文本,用于展示设计效果。" + }; + + try { + const encoder = new Encoder(); + + expect(() => { + encoder.onMesg(Profile.MesgNum.FILE_ID, fileIdMesg); + }).toThrowError(); + + const uint8Array = encoder.close(); + + expect(uint8Array.length).toBe(16); + } + catch (error) { + console.error(`${error.name}: ${error.message} \n${JSON.stringify(error.cause, null, 3)}`); + throw error; + } + }); + }); + + describe("Can Encode Developer Data Fields", () => { + test.for([ + [null, null], + [null, 1], + [1, null], + [0, 1], + ])("Constructing an Encoder with invalid Field Descriptions throws and exception %i and %i", ([id1, id2]) => { + const fieldDescriptions = { + 0: { + developerDataIdMesg: { + developerDataIndex: id1, + }, + fieldDescriptionMesg: { + developerDataIndex: id2, + }, + }, + }; + expect(() => { + const encoder = new Encoder({ fieldDescriptions }); + }).toThrowError(); + }); + + test.for([ + [null, null], + [null, 1], + [1, null], + [0, 1], + ])("Adding Developer Fields with invalid developerDataIndex values throws and exception %i and %i", ([id1, id2]) => { + const developerDataIdMesg = { + developerDataIndex: id1, + } + + const fieldDescriptionMesg = { + developerDataIndex: id2, + } + + const encoder = new Encoder(); + + expect(() => { + encoder.addDeveloperField(0, developerDataIdMesg, fieldDescriptionMesg); + }).toThrowError(); + + encoder.close(); + }); + }); +}); diff --git a/test/output-stream.test.js b/test/output-stream.test.js new file mode 100644 index 0000000..942c20e --- /dev/null +++ b/test/output-stream.test.js @@ -0,0 +1,318 @@ +///////////////////////////////////////////////////////////////////////////////////////////// +// Copyright 2025 Garmin International, Inc. +// Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you +// may not use this file except in compliance with the Flexible and Interoperable Data +// Transfer (FIT) Protocol License. +///////////////////////////////////////////////////////////////////////////////////////////// + +import { describe, expect, test } from "vitest"; +import FIT from "../src/fit.js"; +import OutputStream from "./src/output-stream.js"; + +test("New OutputStream has a length of zero", () => { + const outputStream = new OutputStream(); + + expect(outputStream.length).toBe(0); +}); + +test("Outputstream supports iterable protocol", () => { + const outputStream = new OutputStream(); + + outputStream.writeUInt32(0x03020100); + + expect([...outputStream,]).toEqual([0, 1, 2, 3,]); +}); + +test("Outputstream can set Typed Array", () => { + const outputStream = new OutputStream(); + + outputStream.set(new Uint8Array([0, 1, 2, 3,]), 1); + + expect([...outputStream,]).toEqual([0, 0, 1, 2, 3,]); +}); + +describe("Can write single values to an OutputStream", () => { + test("Outputstream has a length of 1 when writing a Byte", () => { + const outputStream = new OutputStream(); + + outputStream.writeByte(1); + + expect(outputStream.length).toBe(1); + }); + + + test("Outputstream has a length of 1 when writing a UInt8", () => { + const outputStream = new OutputStream(); + + outputStream.writeUInt8(1); + + expect(outputStream.length).toBe(1); + }); + + test("Outputstream has a length of 2 when writing a UInt16", () => { + const outputStream = new OutputStream(); + + outputStream.writeUInt16(1); + + expect(outputStream.length).toBe(2); + }); + + test("Outputstream has a length of 4 when writing a UInt32", () => { + const outputStream = new OutputStream(); + + outputStream.writeUInt32(1); + + expect(outputStream.length).toBe(4); + }); + + test("Outputstream has a length of 8 when writing a UInt64", () => { + const outputStream = new OutputStream(); + + outputStream.writeUInt64(0x0807060504030201n); + + expect(outputStream.length).toBe(8); + }); + + + test("Outputstream has a length of 1 when writing a UInt8z", () => { + const outputStream = new OutputStream(); + + outputStream.writeUInt8z(1); + + expect(outputStream.length).toBe(1); + }); + + test("Outputstream has a length of 2 when writing a UInt16z", () => { + const outputStream = new OutputStream(); + + outputStream.writeUInt16z(1); + + expect(outputStream.length).toBe(2); + }); + + test("Outputstream has a length of 4 when writing a UInt32z", () => { + const outputStream = new OutputStream(); + + outputStream.writeUInt32z(1); + + expect(outputStream.length).toBe(4); + }); + + test("Outputstream has a length of 8 when writing a UInt64z", () => { + const outputStream = new OutputStream(); + + outputStream.writeUInt64z(0x0807060504030201n); + + expect(outputStream.length).toBe(8); + }); + + test("Outputstream has a length of 1 when writing a SInt8", () => { + const outputStream = new OutputStream(); + + outputStream.writeSInt8(1); + + expect(outputStream.length).toBe(1); + }); + + test("Outputstream has a length of 2 when writing a SInt16", () => { + const outputStream = new OutputStream(); + + outputStream.writeSInt16(1); + + expect(outputStream.length).toBe(2); + }); + + test("Outputstream has a length of 4 when writing a SInt32", () => { + const outputStream = new OutputStream(); + + outputStream.writeSInt32(1); + + expect(outputStream.length).toBe(4); + }); + + test("Outputstream has a length of 8 when writing a SInt64", () => { + const outputStream = new OutputStream(); + + outputStream.writeSInt64(0x0807060504030201n); + + expect(outputStream.length).toBe(8); + }); + + test("Outputstream has a length of 4 when writing a Float32", () => { + const outputStream = new OutputStream(); + + outputStream.writeFloat32(1234.5678); + + expect(outputStream.length).toBe(4); + }); + + test("Outputstream has a length of 8 when writing a Float32", () => { + const outputStream = new OutputStream(); + + outputStream.writeFloat64(1234.5678); + + expect(outputStream.length).toBe(8); + }); +}); + +describe("Can write an array of values to an OutputStream", () => { + test("Outputstream has a length of 4 when writing an array of 4 byte values", () => { + const outputStream = new OutputStream(); + + outputStream.writeByte([0, 1, 2, 3,]); + + expect(outputStream.length).toBe(4); + }); + + test("Outputstream has a length of 4 when writing an array of 4 UInt8 values", () => { + const outputStream = new OutputStream(); + + outputStream.writeUInt8([0, 1, 2, 3,]); + + expect(outputStream.length).toBe(4); + }); + + test("Outputstream has a length of 8 when writing an array of 4 UInt16 values", () => { + const outputStream = new OutputStream(); + + outputStream.writeUInt16([0, 1, 2, 3,]); + + expect(outputStream.length).toBe(8); + }); + + test("Outputstream has a length of 16 when writing an array of 4 UInt32 values", () => { + const outputStream = new OutputStream(); + + outputStream.writeUInt32([0, 1, 2, 3,]); + + expect(outputStream.length).toBe(16); + }); + + test("Outputstream has a length of 32 when writing an array of 4 UInt64 values", () => { + const outputStream = new OutputStream(); + + outputStream.writeUInt64([0n, 1n, 2n, 3n,]); + + expect(outputStream.length).toBe(32); + }); + + test("Outputstream has a length of 4 when writing an array of 4 UInt8z values", () => { + const outputStream = new OutputStream(); + + outputStream.writeUInt8z([0, 1, 2, 3,]); + + expect(outputStream.length).toBe(4); + }); + + test("Outputstream has a length of 8 when writing an array of 4 UInt16z values", () => { + const outputStream = new OutputStream(); + + outputStream.writeUInt16z([0, 1, 2, 3,]); + + expect(outputStream.length).toBe(8); + }); + + test("Outputstream has a length of 16 when writing an array of 4 UInt32z values", () => { + const outputStream = new OutputStream(); + + outputStream.writeUInt32z([0, 1, 2, 3,]); + + expect(outputStream.length).toBe(16); + }); + + test("Outputstream has a length of 32 when writing an array of 4 UInt64z values", () => { + const outputStream = new OutputStream(); + + outputStream.writeUInt64z([0n, 1n, 2n, 3n,]); + + expect(outputStream.length).toBe(32); + }); + + test("Outputstream has a length of 4 when writing an array of 4 SInt8 values", () => { + const outputStream = new OutputStream(); + + outputStream.writeSInt8([0, 1, 2, 3,]); + + expect(outputStream.length).toBe(4); + }); + + test("Outputstream has a length of 8 when writing an array of 4 SInt16 values", () => { + const outputStream = new OutputStream(); + + outputStream.writeSInt16([0, 1, 2, 3,]); + + expect(outputStream.length).toBe(8); + }); + + test("Outputstream has a length of 16 when writing an array of 4 SInt32 values", () => { + const outputStream = new OutputStream(); + + outputStream.writeSInt32([0, 1, 2, 3,]); + + expect(outputStream.length).toBe(16); + }); + + test("Outputstream has a length of 32 when writing an array of 4 SInt64 values", () => { + const outputStream = new OutputStream(); + + outputStream.writeSInt64([0n, 1n, 2n, 3n,]); + + expect(outputStream.length).toBe(32); + }); + + test("Outputstream has a length of 16 when writing an array of 4 Float32 values", () => { + const outputStream = new OutputStream(); + + outputStream.writeFloat32([0, 1, 2, 3,]); + + expect(outputStream.length).toBe(16); + }); + + test("Outputstream has a length of 32 when writing an array of 4 Float64 values", () => { + const outputStream = new OutputStream(); + + outputStream.writeFloat64([0, 1, 2, 3,]); + + expect(outputStream.length).toBe(32); + }); +}); + +describe("When writing type X Outputstream has a length of Y", () => { + test.each([ + [FIT.BaseType.UINT8, 1, 1,], + [FIT.BaseType.SINT8, 1, 1,], + [FIT.BaseType.UINT16, 1, 2,], + [FIT.BaseType.SINT16, 1, 2,], + [FIT.BaseType.UINT32, 1, 4,], + [FIT.BaseType.SINT32, 1, 4,], + [FIT.BaseType.UINT64, 1n, 8,], + [FIT.BaseType.SINT64, 1n, 8,], + [FIT.BaseType.FLOAT32, 1, 4,], + [FIT.BaseType.FLOAT64, 1, 8,], + ])("When writing a %s of value %i Outputstream has a length of %i", (type, value, expectedLength) => { + const outputStream = new OutputStream(); + + outputStream.write(value, type); + + expect(outputStream.length).toBe(expectedLength); + }); +}); + +describe("Can write strings to an OutputStream", () => { + + test("OutputStream should append null terminator when writing a string", () => { + const outputStream = new OutputStream(); + + outputStream.writeString(".FIT"); + + expect(outputStream.length).toBe(5); + }); + + test("Can write an array of strings to an OutputStream", () => { + const outputStream = new OutputStream(); + + outputStream.writeString([".FIT", ".FIT"]); + + expect(outputStream.length).toBe(10); + }); +}); diff --git a/test/stream.test.js b/test/stream.test.js index df22a58..d48b646 100644 --- a/test/stream.test.js +++ b/test/stream.test.js @@ -1,10 +1,11 @@ ///////////////////////////////////////////////////////////////////////////////////////////// -// Copyright 2024 Garmin International, Inc. +// Copyright 2025 Garmin International, Inc. // Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you // may not use this file except in compliance with the Flexible and Interoperable Data // Transfer (FIT) Protocol License. ///////////////////////////////////////////////////////////////////////////////////////////// +import { describe, expect, test } from "vitest"; import Stream from "../src/stream.js"; import FIT from "../src/fit.js"; diff --git a/test/utils-hr-mesg.test.js b/test/utils-hr-mesg.test.js index 9ff4dbc..d071f93 100644 --- a/test/utils-hr-mesg.test.js +++ b/test/utils-hr-mesg.test.js @@ -1,10 +1,11 @@ ///////////////////////////////////////////////////////////////////////////////////////////// -// Copyright 2024 Garmin International, Inc. +// Copyright 2025 Garmin International, Inc. // Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you // may not use this file except in compliance with the Flexible and Interoperable Data // Transfer (FIT) Protocol License. ///////////////////////////////////////////////////////////////////////////////////////////// +import { describe, expect, test } from "vitest"; import * as fs from "fs"; diff --git a/test/utils.test.js b/test/utils.test.js index 390337a..74b1f4d 100644 --- a/test/utils.test.js +++ b/test/utils.test.js @@ -1,31 +1,47 @@ ///////////////////////////////////////////////////////////////////////////////////////////// -// Copyright 2024 Garmin International, Inc. +// Copyright 2025 Garmin International, Inc. // Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you // may not use this file except in compliance with the Flexible and Interoperable Data // Transfer (FIT) Protocol License. ///////////////////////////////////////////////////////////////////////////////////////////// +import { describe, expect, test } from "vitest"; import Utils from "../src/utils.js"; describe("Utils Tests", () => { - test("0 should be Sun, 31 Dec 1989 00:00:00 GMT", () => { - const date = Utils.convertDateTimeToDate(0); - expect(date.toString()).toBe(new Date(Date.UTC(1989, 11, 31, 0, 0, 0)).toString()); - }); + describe("convertDateTimeToDate Tests", () => { + test("0 should be Sun, 31 Dec 1989 00:00:00 GMT", () => { + const date = Utils.convertDateTimeToDate(0); + expect(date.toString()).toBe(new Date(Date.UTC(1989, 11, 31, 0, 0, 0)).toString()); + }); - test("1000000000 should be Wed, 08 Sep 2021 01:46:40 GMT", () => { - const date = Utils.convertDateTimeToDate(1000000000); - expect(date.toString()).toBe(new Date(Date.UTC(2021, 8, 8, 1, 46, 40)).toString()); - }); + test("1000000000 should be Wed, 08 Sep 2021 01:46:40 GMT", () => { + const date = Utils.convertDateTimeToDate(1000000000); + expect(date.toString()).toBe(new Date(Date.UTC(2021, 8, 8, 1, 46, 40)).toString()); + }); + + test("No convertDateTimeToDate arguements should be Sun, 31 Dec 1989 00:00:00 GMT", () => { + const date = Utils.convertDateTimeToDate(); + expect(date.toString()).toBe(new Date(Date.UTC(1989, 11, 31, 0, 0, 0)).toString()); + }); - test("No convertDateTimeToDate arguements should be Sun, 31 Dec 1989 00:00:00 GMT", () => { - const date = Utils.convertDateTimeToDate(); - expect(date.toString()).toBe(new Date(Date.UTC(1989, 11, 31, 0, 0, 0)).toString()); + test("Null should be Sun, 31 Dec 1989 00:00:00 GMT", () => { + const date = Utils.convertDateTimeToDate(null); + expect(date.toString()).toBe(new Date(Date.UTC(1989, 11, 31, 0, 0, 0)).toString()); + }); }); - test("Null should be Sun, 31 Dec 1989 00:00:00 GMT", () => { - const date = Utils.convertDateTimeToDate(null); - expect(date.toString()).toBe(new Date(Date.UTC(1989, 11, 31, 0, 0, 0)).toString()); + describe("convertDateToDateTime Tests", () => { + test("Sun, 31 Dec 1989 00:00:00 GMT should be 0", () => { + const datetime = Utils.convertDateToDateTime(new Date(Date.UTC(1989, 11, 31, 0, 0, 0))); + expect(datetime).toBe(0); + }); + + test("Wed, 08 Sep 2021 01:46:40 GMT should be 1000000000", () => { + const datetime = Utils.convertDateToDateTime(new Date(Date.UTC(2021, 8, 8, 1, 46, 40))); + expect(datetime).toBe(1000000000); + }); + }); -}); \ No newline at end of file +});