FitDecoder (fit_decoder v0.1.0)

A wrapper for the C++ FIT file decoder NIF.

This module provides functionality to decode FIT (Flexible and Interoperable Data Transfer) files, which are commonly used by fitness devices and applications to store workout and activity data.

Examples

# Decode an empty binary (returns empty list)
iex> FitDecoder.decode_fit_file(<<>>)
[]

# Decode invalid binary data (returns error atom)
iex> FitDecoder.decode_fit_file(<<1, 2, 3, 4>>)
:error_integrity_check_failed

# Decode a valid FIT file binary would return a list of maps:
# [%{timestamp: 1096265262, distance: 0.0, heart_rate: 95}, ...]

Summary

Functions

Convenience function that combines file reading, decoding, and info extraction.

Decodes a FIT file binary and returns a list of maps, where each map represents a "Record" message containing sensor data.

Decodes a FIT file from a file path and returns the same data as decode_fit_file/1.

Gets the activity date from decoded FIT file records.

Gets the activity duration from decoded FIT file records.

Gets comprehensive activity information from decoded FIT file records.

Functions

decode_and_analyze(file_path)

Convenience function that combines file reading, decoding, and info extraction.

This function implements the complete workflow: read file → decode → extract info.

Parameters

  • file_path - Path to a FIT file on disk

Returns

  • {:ok, {activity_info, records}} - Activity info and full record list
  • {:error, reason} - If file reading, decoding, or parsing fails
  • Error atoms from the decoder (e.g., :error_integrity_check_failed)

Examples

iex> FitDecoder.decode_and_analyze("/nonexistent/file.fit")
{:error, :enoent}

decode_fit_file(binary)

Decodes a FIT file binary and returns a list of maps, where each map represents a "Record" message containing sensor data.

Parameters

  • binary - A binary containing FIT file data

Returns

  • A list of maps containing decoded record data on success
  • An error atom (:error_integrity_check_failed, :error_sdk_exception) on failure
  • An empty list if the file contains no record data

Record Fields

Each record map may contain the following fields (only present if valid data exists):

  • :timestamp - Unix timestamp (always present in valid records)
  • :distance - Distance in meters (float)
  • :heart_rate - Heart rate in beats per minute (integer)
  • :altitude - Altitude in meters (float)

Examples

iex> FitDecoder.decode_fit_file(<<>>)
[]

iex> FitDecoder.decode_fit_file(<<1, 2, 3, 4>>)
:error_integrity_check_failed

decode_fit_file_from_path(file_path)

Decodes a FIT file from a file path and returns the same data as decode_fit_file/1.

Parameters

  • file_path - Path to a FIT file on disk

Returns

  • Same as decode_fit_file/1 but reads from file path
  • {:error, reason} if file cannot be read

Examples

iex> FitDecoder.decode_fit_file_from_path("/nonexistent/file.fit")
{:error, :enoent}

get_activity_date(records)

Gets the activity date from decoded FIT file records.

Returns the date (as a Date struct) when the activity started based on the earliest timestamp in the records.

Parameters

Returns

  • {:ok, %Date{}} - The date when the activity started
  • {:error, :no_records} - If the records list is empty
  • {:error, :invalid_records} - If records don't contain valid timestamps

Examples

iex> records = [%{timestamp: 1745940695}]
iex> FitDecoder.get_activity_date(records)
{:ok, ~D[2025-04-29]}

get_activity_duration(records)

Gets the activity duration from decoded FIT file records.

Returns the duration of the activity in seconds based on the difference between the earliest and latest timestamps.

Parameters

Returns

  • {:ok, duration_seconds} - Duration in seconds (integer)
  • {:error, :no_records} - If the records list is empty
  • {:error, :invalid_records} - If records don't contain valid timestamps
  • {:error, :insufficient_data} - If there's only one record

Examples

iex> records = [%{timestamp: 1096265262}, %{timestamp: 1096265322}]
iex> FitDecoder.get_activity_duration(records)
{:ok, 60}

get_activity_info(records)

Gets comprehensive activity information from decoded FIT file records.

This is a convenience function that extracts the most commonly needed information from an activity in a single call.

Parameters

Returns

  • {:ok, activity_info} - A map containing activity information
  • {:error, reason} - If records are invalid or empty

The activity_info map contains:

  • :date - Date when activity started (Date struct)
  • :duration_seconds - Duration in seconds (integer)
  • :total_distance - Total distance in meters (float, may be nil)
  • :record_count - Number of data records (integer)
  • :has_heart_rate - Whether heart rate data is present (boolean)
  • :has_altitude - Whether altitude data is present (boolean)

Examples

iex> records = [%{timestamp: 1727321178, distance: 12543.2, heart_rate: 95}, %{timestamp: 1727321238, distance: 12543.2, heart_rate: 98}]
iex> FitDecoder.get_activity_info(records)
{:ok, %{
  date: ~D[2024-09-26],
  duration_seconds: 60,
  total_distance: 12543.2,
  record_count: 2,
  has_heart_rate: true,
  has_altitude: false
}}