fit

module
v0.19.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 28, 2024 License: BSD-3-Clause

README

FIT SDK for Go

GitHub Workflow Status Go Reference CodeCov Go Report Card Profile Version OpenSSF Best Practices OpenSSF Scorecard

This project hosts the Go implementation for The Flexible and Interoperable Data Transfer (FIT) protocol, which is a protocol developed by Garmin for storing and sharing data originating from sports, fitness, and health devices. Activities recorded using devices such as smartwatch and cycling computer are now mostly in a FIT file format (*.fit).

Motivation

The FIT protocol, known for its compact size as a binary file format, is the preferred choice for manufacturers to use in their embedded devices. However, despite its widespread adoption, Garmin has not yet released an official SDK for Go, and existing third-party libraries for decoding and encoding the FIT protocol lack the semantics of the official SDK.

One of the key semantics they are missing is the ability for users to retrieve raw protocol messages; instead, they decode directly into predefined message structs grouped by common file types. Furthermore, existing third-party libraries do not seem to fully support FIT Protocol V2, and their ability to produce variant options of the FIT protocol is limited. For instance, creating FIT files with compressed timestamps or FIT files with multiple local message types, which significantly reduces the resulting FIT files' size, is missing.

Without diminishing respect for the existing libraries created nearly a decade ago, at a time when the capabilities of Go were limited, we believe a new approach is necessary. This is where this SDK comes in, bridging the gap and enabling Go developers to seamlessly interact with the FIT protocol.

Usage

Please see Usage.

Protocol Version 2.0 is supported

Version 2.0 introduced Developer Fields as a way to add custom data fields to existing messages. We strives to support Developer Fields and carefully thought about how to implement it since the inception of the SDK. While this may still need to be battle-tested to ensure correctness, this is generally work and usable.

Here is the sample of what Developer Fields would look like in a .fit that have been converted to .csv by fitconv. The device_info message has some Developer Fields defined in field_description (the ones that are being bold):

Type Local Number Message Field 1 Value 1 Units 1 Field 2 Value 2 Units 2 Field 3 Value 3 Units 3 Field 4 Value 4 Units 4 Field 5 Value 5 Units 5 Field 6 Value 6 Units 6
Definition 0 developer_data_id developer_data_index 1 application_id 16 application_version 1
Data 0 developer_data_id developer_data_index 1 application_id <omitted> application_version 40113
Definition 0 field_description fit_base_type_id 1 developer_data_index 1 field_definition_number 1 field_name 13
Data 0 field_description fit_base_type_id 7 developer_data_index 1 field_definition_number 5 field_name device_model
Definition 0 field_description fit_base_type_id 1 developer_data_index 1 field_definition_number 1 field_name 20
Data 0 field_description fit_base_type_id 7 developer_data_index 1 field_definition_number 4 field_name device_manufacturer
Data 0 field_description fit_base_type_id 7 developer_data_index 1 field_definition_number 6 field_name device_os_version
Data 0 field_description fit_base_type_id 7 developer_data_index 1 field_definition_number 7 field_name mobile_app_version
Definition 0 device_info manufacturer 1 product 1 device_model 11 device_manufacturer 6 device_os_version 5 mobile_app_version 8
Data 0 device_info manufacturer 265 product 101 device_model iPhone14,4 device_manufacturer apple device_os_version 16.6 mobile_app_version 332.0.0

CLIs

We provide some CLI programs to interact with FIT files that can be found in cmd folder.

  1. fitactivity: Combines multiple FIT activity files into one continuous FIT activity (and conceal the start and end GPS positions for privacy). README.md
  2. fitconv: Converts FIT files to CSV format, enabling us to read the FIT data in a human-readable format. Conversely, it also converts CSV files back to FIT format, enabling us to create or edit FIT files in CSV form. The programs is designed to work seamlessly with CSVs produced by the Official FIT SDK's FitCSVTool.jar. README.md
  3. fitprint: Generates comprehensive human-readable *.txt file containing details extracted from FIT files. README.md
  4. fitdump: Dumps the FIT file(s) into segmented bytes in a *.txt file format. README.md

Some programs are automatically built during release; for Linux, Windows, and macOS platforms. They are available for download in Release's Assets.

Custom FIT SDK

A FIT file may contain manufacturer specific messages (Product Profile) that are not defined in Global Profile (Profile.xlsx) since it's specific to a manufacturer (other manufacturers may have different meaning for that messages)

To be able to decode or create the manufacturer specific messages, we provide options to pick based on your need:

  1. Register Manufacturer Specific Messages at Runtime

    For those who prefer using this SDK as it is without need to generate their own custom SDK, we provide factory package as an abstraction to hold the profile messages. See Register at Runtime.

  2. Generate Custom FIT SDK

    Please see Generate Custom FIT SDK

Benchmark

We do not aim to compete with anyone; rather, we have created this FIT SDK with the intention of providing an alternative. However, having a benchmark can show us how relevant we are to the world.

Here is a benchmark for decoding and encoding big_activity.fit using this FIT SDK in comparison to github.com/tormoder/fit, the long-standing Go library for decoding and encoding FIT files. See internal/cmd/benchfit/benchfit_test.go

cd internal/cmd/benchfit
go test -bench=. -benchmem
goos: darwin
goarch: amd64
pkg: benchfit
cpu: Intel(R) Core(TM) i5-5257U CPU @ 2.70GHz
BenchmarkDecode/muktihari/fit_raw-4  12    94329778 ns/op   77092752 B/op    100046 allocs/op
BenchmarkDecode/muktihari/fit-4      12    88640146 ns/op   52205512 B/op    100192 allocs/op
BenchmarkDecode/tormoder/fit-4       10   106416303 ns/op   84108940 B/op    700051 allocs/op
BenchmarkEncode/muktihari/fit_raw-4  19    58971880 ns/op     131514 B/op        14 allocs/op
BenchmarkEncode/muktihari/fit-4       9   122926830 ns/op   44137916 B/op    100017 allocs/op
BenchmarkEncode/tormoder/fit-4        1  1324877437 ns/op  101992744 B/op  12100315 allocs/op
PASS
ok      benchfit        12.575s

NOTE: The 1st on the list, "raw", means we decode the file into the original FIT protocol message structure (similar to the Official FIT SDK implementation in other languages). While the 2nd decodes messages to Activity File struct, which should be equivalent to what the 3rd does.

We decode slightly faster and encode significantly faster. We allocate far fewer objects on the heap and have a smaller memory footprint for both decoding and encoding.

Contributing

Please see CONTRIBUTING.md. Thank you, contributors!

Directories

Path Synopsis
cmd
Package cmd provides CLI programs to work with FIT files.
Package cmd provides CLI programs to work with FIT files.
fitconv/fitcsv
Package fitcsv provides the implementations of FIT listener's interfaces that can listen to the events emitted by the decoder.
Package fitcsv provides the implementations of FIT listener's interfaces that can listen to the events emitted by the decoder.
Package decoder provides a handler to decode FIT files.
Package decoder provides a handler to decode FIT files.
Package encoder provides a handler to encode data into FIT file binary form.
Package encoder provides a handler to encode data into FIT file binary form.
Package factory contains predefined messages based on messages in [Profile.xlsx] provided in the Official FIT SDK.
Package factory contains predefined messages based on messages in [Profile.xlsx] provided in the Official FIT SDK.
internal
cmd/fitgen/pkg/strutil
Package strutil is used only for naming package, variable, etc inside the go template.
Package strutil is used only for naming package, variable, etc inside the go template.
kit
Package kit provides helpers for decoding and encoding as well as type conversion.
Package kit provides helpers for decoding and encoding as well as type conversion.
bufferedwriter
Package bufferedwriter provides functionality to wrap an io.Writer while keep maintaining the underlying capability to write at specific bytes such as when it's implementing io.WriterAt or io.WriteSeeker.
Package bufferedwriter provides functionality to wrap an io.Writer while keep maintaining the underlying capability to write at specific bytes such as when it's implementing io.WriterAt or io.WriteSeeker.
datetime
Package datetime provides functions to convert uint32 timestamp to time.Time and vice-versa.
Package datetime provides functions to convert uint32 timestamp to time.Time and vice-versa.
hash
Package hash provides interface for hash16 functions as an additional interface to the existing Go stdlib's Hash32 and Hash64.
Package hash provides interface for hash16 functions as an additional interface to the existing Go stdlib's Hash32 and Hash64.
hash/crc16
Package crc16 implements the 16-bit cyclic redundancy check, or CRC-16, checksum.
Package crc16 implements the 16-bit cyclic redundancy check, or CRC-16, checksum.
scaleoffset
Package scaleoffset provides functions for applying and discarding scale and offset from a value.
Package scaleoffset provides functions for applying and discarding scale and offset from a value.
semicircles
Package semicircles provides functions for converting GPS units: semicircles to degrees and degrees to semicircles.
Package semicircles provides functions for converting GPS units: semicircles to degrees and degrees to semicircles.
Package profile defines all the types and messages generated from Profile.xlsx using fitgen.
Package profile defines all the types and messages generated from Profile.xlsx using fitgen.
basetype
Package basetype defines the base of all types used in FIT.
Package basetype defines the base of all types used in FIT.
filedef
Package filedef contains general implementation of known common file types retrieved from Garmin or its affiliates website and a listener building block convert decoded FIT file into the desired common file type as soon as the message is decoded.
Package filedef contains general implementation of known common file types retrieved from Garmin or its affiliates website and a listener building block convert decoded FIT file into the desired common file type as soon as the message is decoded.
mesgdef
Package mesgdef contains all the messages defined in the Global Profile (Profile.xlsx), which is generated by internal/cmd/fitgen/main.go.
Package mesgdef contains all the messages defined in the Global Profile (Profile.xlsx), which is generated by internal/cmd/fitgen/main.go.
typedef
Package typedef contains all the types defined in the Global Profile (Profile.xlsx) generated by internal/cmd/fitgen/main.go.
Package typedef contains all the types defined in the Global Profile (Profile.xlsx) generated by internal/cmd/fitgen/main.go.
untyped/fieldnum
Package fieldnum contains untyped constants for greater flexibility, intended to simplify code typing when creating messages and fields using the factory and reduce human error.
Package fieldnum contains untyped constants for greater flexibility, intended to simplify code typing when creating messages and fields using the factory and reduce human error.
untyped/mesgnum
Package mesgnum contains untyped constants for greater flexibility, intended to simplify code typing when creating messages and fields using the factory and reduce human error.
Package mesgnum contains untyped constants for greater flexibility, intended to simplify code typing when creating messages and fields using the factory and reduce human error.
Package proto defines the abstraction for FIT Protocol.
Package proto defines the abstraction for FIT Protocol.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL