A small crate used for reading and decoding FIT files generated by sports devices.
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
benches
examples
fits
src
.gitignore
Cargo.toml
LICENSE
README.md
build.rs
messages.semi.csv
types.semi.csv

README.md

Fit

Fit is a small crate used for reading and decoding FIT files generated by various sports devices. Currently it has only been designed specifically to read files produced by Garmin Edges 1000 and 520, and a Wahoo Elemnt. It will probably mostly work out of the box with other file sources, but will probably not work 100% perfectly unless it's a Garmin cycling computer.

It currently does not support FIT files using custom developer fields.

Installation

[dependencies]
fit = "0.2"

Usage

extern crate env_logger;
extern crate fit;

use std::path::PathBuf;

fn main() {
    env_logger::init();
    let filepath = PathBuf::from("fits/2913547417.fit");
    let f = fit::FitFile::read(filepath);
}

After reading a FIT file, a digest of message types can be inspected by calling

    println!("{:#?}", f.message_counts());

which will return a list similar to the following, showing respectively the name of the record type (as defined in the FIT SDK), and the number of records parsed

{
    "File Id": 1,
    "Record": 5401,
    "Lap": 13,
    "Event": 2,
    "File Creator": 1,
    "Activity": 1,
    "Device Info": 1,
    "Session": 1
}

Armed with this information, we can call

    f.messages().filter("Record").for_each(|r| {
        println!("{:#?}", r.all_values());
    })

which will fetch the "Record" messages, for example

[
    position_lat: 57.71064 /f32,
    position_long: 11.994529 /f32,
    speed: 0 /f64,
    heart_rate: 110 /u8,
    power: 0 /u16,
    temperature: 17 /i8,
    accumulated_power: 965468 /u32,
    distance: 46095.28 /f64,
    altitude: 9 /f64,
    timestamp: 1536170231 /time
]

The messages are trait objects of the form Box<dyn DefinedMessageType>. These respond to a few useful methods: primarily #name(), #value(u16), and #field_name_and_value(u16). To get all values at the same time there is also a #all_values() method. FieldNameAndValue structs contain two fields: a name, and a Value.

A Value enum is a simple wrapper around most rust primitive types, such as u16 or i64 or f32. It implements a few helper methods to make it easier to extract the internal value, #is_u8(), #is_str() etc. It also implements a basic version of nightly rust's TryFrom trait that allows save up-casting, but not down-casting. That is, a Value::U8 can be cast as a u32, but you can't get a u8 from a Value::U32.

Some things to watch out for:

  • speed is recorded as m/s, rather than kph.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/richardbrodie/fit-rs.

License

The gem is available as open source under the terms of the MIT License.