Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
431 changes: 216 additions & 215 deletions README.md

Large diffs are not rendered by default.

50 changes: 25 additions & 25 deletions garmin_fit_sdk/__init__.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
# __init__garmin_fit_sdk.py
###########################################################################################
# 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.188.0Release
# Tag = production/release/21.188.0-0-g55050f8
############################################################################################
from garmin_fit_sdk.accumulator import Accumulator
from garmin_fit_sdk.bitstream import BitStream
from garmin_fit_sdk.crc_calculator import CrcCalculator
from garmin_fit_sdk.decoder import Decoder
from garmin_fit_sdk.fit import BASE_TYPE, BASE_TYPE_DEFINITIONS
from garmin_fit_sdk.hr_mesg_utils import expand_heart_rates
from garmin_fit_sdk.profile import Profile
from garmin_fit_sdk.stream import Stream
from garmin_fit_sdk.util import FIT_EPOCH_S, convert_timestamp_to_datetime
__version__ = '21.188.0'
# __init__garmin_fit_sdk.py

###########################################################################################
# Copyright 2026 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.194.0Release
# Tag = production/release/21.194.0-0-g65135fc
############################################################################################


from garmin_fit_sdk.accumulator import Accumulator
from garmin_fit_sdk.bitstream import BitStream
from garmin_fit_sdk.crc_calculator import CrcCalculator
from garmin_fit_sdk.decoder import Decoder
from garmin_fit_sdk.fit import BASE_TYPE, BASE_TYPE_DEFINITIONS
from garmin_fit_sdk.hr_mesg_utils import expand_heart_rates
from garmin_fit_sdk.profile import Profile
from garmin_fit_sdk.stream import Stream
from garmin_fit_sdk.util import FIT_EPOCH_S, convert_timestamp_to_datetime

__version__ = '21.194.0'
126 changes: 63 additions & 63 deletions garmin_fit_sdk/accumulator.py
Original file line number Diff line number Diff line change
@@ -1,63 +1,63 @@
'''accumulator.py: Contains the Accumulator class and sub-component class AccumulatedField'''
###########################################################################################
# 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.188.0Release
# Tag = production/release/21.188.0-0-g55050f8
############################################################################################
class AccumulatedField:
'''A class that accumulates a value for a particular field.
Attributes:
_accumulated_value: Resulting accumulated value
_last_value: The previous accumulated value thus far.
'''
def __init__(self, value = 0):
self._accumulated_value = value
self._last_value = value
def accumulate(self, value, bits):
''''Accumulates to the previous value and gives the updated accumulated value.'''
mask = (1 << bits) - 1
self._accumulated_value += (value - self._last_value) & mask
self._last_value = value
return self._accumulated_value
class Accumulator:
'''A class that represents the accumulated values for particular fields.
Attributes:
_messages: A list of messages with a field or fields to accumulate.
'''
def __init__(self):
self._messages = {}
def createAccumulatedField(self, mesg_num, field_num, value):
'''Creates an accumulated field and stores its initial value in the accumulator'''
accumulatedField = AccumulatedField(value)
if mesg_num not in self._messages:
self._messages[mesg_num] = {}
self._messages[mesg_num][field_num] = accumulatedField
return accumulatedField
def accumulate(self, mesg_num, field_num, value, bits):
'''Accumulates the given field value if present in the accumulator. If it is not, the accumulated field is added to the Accumulator.'''
accumulatedField = None
if mesg_num in self._messages and field_num in self._messages[mesg_num]:
accumulatedField = self._messages[mesg_num][field_num]
else:
accumulatedField = self.createAccumulatedField(mesg_num, field_num, value)
return accumulatedField.accumulate(value, bits)
'''accumulator.py: Contains the Accumulator class and sub-component class AccumulatedField'''

###########################################################################################
# Copyright 2026 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.194.0Release
# Tag = production/release/21.194.0-0-g65135fc
############################################################################################


class AccumulatedField:
'''A class that accumulates a value for a particular field.
Attributes:
_accumulated_value: Resulting accumulated value
_last_value: The previous accumulated value thus far.
'''
def __init__(self, value = 0):
self._accumulated_value = value
self._last_value = value

def accumulate(self, value, bits):
''''Accumulates to the previous value and gives the updated accumulated value.'''
mask = (1 << bits) - 1

self._accumulated_value += (value - self._last_value) & mask
self._last_value = value

return self._accumulated_value

class Accumulator:
'''A class that represents the accumulated values for particular fields.
Attributes:
_messages: A list of messages with a field or fields to accumulate.
'''
def __init__(self):
self._messages = {}

def createAccumulatedField(self, mesg_num, field_num, value):
'''Creates an accumulated field and stores its initial value in the accumulator'''
accumulatedField = AccumulatedField(value)

if mesg_num not in self._messages:
self._messages[mesg_num] = {}

self._messages[mesg_num][field_num] = accumulatedField

return accumulatedField

def accumulate(self, mesg_num, field_num, value, bits):
'''Accumulates the given field value if present in the accumulator. If it is not, the accumulated field is added to the Accumulator.'''
accumulatedField = None

if mesg_num in self._messages and field_num in self._messages[mesg_num]:
accumulatedField = self._messages[mesg_num][field_num]
else:
accumulatedField = self.createAccumulatedField(mesg_num, field_num, value)

return accumulatedField.accumulate(value, bits)

180 changes: 90 additions & 90 deletions garmin_fit_sdk/bitstream.py
Original file line number Diff line number Diff line change
@@ -1,90 +1,90 @@
'''bitstream.py: Contains BitStream class which handles reading streams of data bit by bit '''
###########################################################################################
# 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.188.0Release
# Tag = production/release/21.188.0-0-g55050f8
############################################################################################
from . import fit as FIT
class BitStream:
'''
A class that represents a stream of binary data from a chunk of data.
Attributes:
_array: The stream of data in an array structure.
_current_array_position: Current position in data array.
_bits_per_position: Number of bits per step through the data.
_current_byte: Position of the current byte being read in the data.
_current_bit: Position of the current bit being read in the data.
_bits_available: Remaining number of bits left unread in the data.
'''
def __init__(self, data, base_type):
self._array = None
self._current_array_position = 0
self._bits_per_position = 0
self._current_byte = 0
self._current_bit = 0
self._bits_available = 0
self._array = data if isinstance(data, list) else [data]
base_type_size = FIT.BASE_TYPE_DEFINITIONS[base_type]['size']
self._bits_per_position = base_type_size * 8
self.reset()
def bits_available(self):
'''Returns the number of bits left in the data.'''
return self._bits_available
def has_bits_available(self):
'''Returns true if the data has bits available.'''
return self._bits_available > 0
def reset(self):
'''Resets the bitstream to the start of the data and resets the bits available.'''
self._current_array_position = 0
self._bits_available = self._bits_per_position * len(self._array)
self.__next_byte()
def read_bit(self):
'''Reads the next bit if possible.'''
if self.has_bits_available() is False:
self.__raise_error()
if self._current_bit >= self._bits_per_position:
self.__next_byte()
bit = self._current_byte & 0x01
self._current_byte = (self._current_byte >> 1)
self._current_bit += 1
self._bits_available -= 1
return bit
def read_bits(self, number_bits_to_read):
'''Reads the specificed number of bits if possible.'''
value = 0
for i in range(number_bits_to_read):
value |= self.read_bit() << i
return value
def __next_byte(self):
if self._current_array_position >= len(self._array):
self.__raise_error()
self._current_byte = self._array[self._current_array_position]
self._current_array_position += 1
self._current_bit = 0
def __raise_error(self):
raise IndexError('FIT Runtime Error, no bits available.')
'''bitstream.py: Contains BitStream class which handles reading streams of data bit by bit '''

###########################################################################################
# Copyright 2026 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.194.0Release
# Tag = production/release/21.194.0-0-g65135fc
############################################################################################


from . import fit as FIT


class BitStream:
'''
A class that represents a stream of binary data from a chunk of data.

Attributes:
_array: The stream of data in an array structure.
_current_array_position: Current position in data array.
_bits_per_position: Number of bits per step through the data.
_current_byte: Position of the current byte being read in the data.
_current_bit: Position of the current bit being read in the data.
_bits_available: Remaining number of bits left unread in the data.
'''
def __init__(self, data, base_type):
self._array = None
self._current_array_position = 0
self._bits_per_position = 0
self._current_byte = 0
self._current_bit = 0
self._bits_available = 0

self._array = data if isinstance(data, list) else [data]
base_type_size = FIT.BASE_TYPE_DEFINITIONS[base_type]['size']
self._bits_per_position = base_type_size * 8
self.reset()

def bits_available(self):
'''Returns the number of bits left in the data.'''
return self._bits_available

def has_bits_available(self):
'''Returns true if the data has bits available.'''
return self._bits_available > 0

def reset(self):
'''Resets the bitstream to the start of the data and resets the bits available.'''
self._current_array_position = 0
self._bits_available = self._bits_per_position * len(self._array)
self.__next_byte()

def read_bit(self):
'''Reads the next bit if possible.'''
if self.has_bits_available() is False:
self.__raise_error()

if self._current_bit >= self._bits_per_position:
self.__next_byte()

bit = self._current_byte & 0x01
self._current_byte = (self._current_byte >> 1)
self._current_bit += 1
self._bits_available -= 1

return bit

def read_bits(self, number_bits_to_read):
'''Reads the specificed number of bits if possible.'''
value = 0

for i in range(number_bits_to_read):
value |= self.read_bit() << i

return value

def __next_byte(self):
if self._current_array_position >= len(self._array):
self.__raise_error()

self._current_byte = self._array[self._current_array_position]
self._current_array_position += 1
self._current_bit = 0

def __raise_error(self):
raise IndexError('FIT Runtime Error, no bits available.')
Loading