You are here: Forum Home → ANT Developers Forums → ANT+ FIT Forum Has Moved → Thread
——————————————————
Free Indoor Cycling Software - https://maximumtrainer.com
——————————————————
Free Indoor Cycling Software - https://maximumtrainer.com
http://www.thisisant.com/resources/fit/).The FIT documentation is included in the FIT SDK archive (
The FIT Protocol document describes the binary file format. The FIT File Types document describes the content of standard FIT file types such as 'activity'. To get started creating FIT files using the FIT SDK I suggest studying the included Encode example app in your preferred language (C/C++/C#/Java).
HTH
ShaneP
——————————————————
Free Indoor Cycling Software - https://maximumtrainer.com
void FitActivityCreator::build_FIT_file() {
fit::Encode encode;
std::fstream file;
file.open("C:/test2.fit", std::ios::in | std::ios::out | std::ios::binary | std::ios::trunc);
if (!file.is_open()) {
qDebug() << "Error opening file test.fit\n";
}
encode.Open(file);
// TimeCreated - seconds since UTC 00:00 Dec 31 1989
QDateTime now = QDateTime::currentDateTime().toUTC();
QDateTime ref = QDateTime(QDate(1989,12,31), QTime(0,0), Qt::UTC);
qint64 diffSecs = ref.secsTo(now);
// --------------- FileIdMesg ------------------
fit::FileIdMesg fileIdMesg;
fileIdMesg.SetType(FIT_FILE_ACTIVITY);
fileIdMesg.SetManufacturer(FIT_MANUFACTURER_DYNASTREAM);
fileIdMesg.SetProduct(1);
fileIdMesg.SetSerialNumber(123456);
fileIdMesg.SetTimeCreated(diffSecs);
encode.Write(fileIdMesg);
fit::FileCreatorMesg fileCreatorMesg;
fileCreatorMesg.SetSoftwareVersion(29);
encode.Write(fileCreatorMesg);
fit::EventMesg eventMesg3;
eventMesg3.SetTimestamp(diffSecs);
eventMesg3.SetTimerTrigger(FIT_TIMER_TRIGGER_MANUAL);
encode.Write(eventMesg3);
// --------------- RecordMesg ------------------
//add some filler data for 0-5min
for (int i=0; i<300; i++) {
fit::RecordMesg recordMesg;
recordMesg.SetTimestamp(diffSecs+i);
recordMesg.SetHeartRate(140);
recordMesg.SetCadence(80);
recordMesg.SetPower(290);
recordMesg.SetSpeed(30*1000.0/3600.0);
encode.Write(recordMesg);
}
// --------------- LapMesg ------------------
fit::LapMesg lapMesg2;
lapMesg2.SetIntensity(FIT_INTENSITY_WARMUP);
lapMesg2.SetStartTime(diffSecs);
lapMesg2.SetTimestamp(diffSecs+299);
lapMesg2.SetTotalElapsedTime(300);
lapMesg2.SetTotalTimerTime(300);
lapMesg2.SetEvent(FIT_EVENT_WORKOUT);
lapMesg2.SetEventType(FIT_EVENT_TYPE_START);
lapMesg2.SetLapTrigger(FIT_LAP_TRIGGER_TIME);
lapMesg2.SetSport(FIT_SPORT_CYCLING);
lapMesg2.SetEvent(FIT_EVENT_LAP);
lapMesg2.SetEventType(FIT_EVENT_TYPE_STOP);
encode.Write(lapMesg2);
// --------------- RecordMesg ------------------
//add some filler data for 5-10min
for (int i=300; i<600; i++) {
fit::RecordMesg recordMesg;
recordMesg.SetTimestamp(diffSecs+i);
recordMesg.SetHeartRate(150);
recordMesg.SetCadence(90);
recordMesg.SetPower(300);
recordMesg.SetSpeed(40*1000.0/3600.0);
encode.Write(recordMesg);
}
// --------------- LapMesg ------------------
lapMesg2.SetIntensity(FIT_INTENSITY_REST);
lapMesg2.SetStartTime(diffSecs+300);
lapMesg2.SetTimestamp(diffSecs+599);
lapMesg2.SetTotalElapsedTime(300);
lapMesg2.SetTotalTimerTime(300);
lapMesg2.SetEvent(FIT_EVENT_WORKOUT);
lapMesg2.SetEventType(FIT_EVENT_TYPE_START);
lapMesg2.SetLapTrigger(FIT_LAP_TRIGGER_SESSION_END);
lapMesg2.SetSport(FIT_SPORT_CYCLING);
lapMesg2.SetEvent(FIT_EVENT_LAP);
lapMesg2.SetEventType(FIT_EVENT_TYPE_STOP);
encode.Write(lapMesg2);
fit::EventMesg eventMesg;
eventMesg.SetTimestamp(diffSecs+599);
eventMesg.SetEvent(FIT_EVENT_SESSION);
eventMesg.SetEventType(FIT_EVENT_TYPE_STOP_DISABLE_ALL);
encode.Write(eventMesg);
// --------------- SessionMesg ------------------
fit::SessionMesg sessionMesg;
sessionMesg.SetTimestamp(diffSecs+599);
sessionMesg.SetStartTime(diffSecs);
sessionMesg.SetTotalTimerTime(600); //Timer Time (excludes pauses)
sessionMesg.SetTotalElapsedTime(600); //Total number of msec since timer started (includes pauses) - Todo: calculate paused time
sessionMesg.SetSport(FIT_SPORT_CYCLING);
sessionMesg.SetEvent(FIT_EVENT_SESSION);
sessionMesg.SetEventType(FIT_EVENT_TYPE_STOP);
sessionMesg.SetTotalCalories(150); //kcal
sessionMesg.SetFirstLapIndex(0);
sessionMesg.SetNumLaps(2);
sessionMesg.SetTrigger(FIT_SESSION_TRIGGER_ACTIVITY_END);
sessionMesg.SetMessageIndex(FIT_MESSAGE_INDEX_RESERVED);
encode.Write(sessionMesg);
// --------------- ActivityMesg ------------------
fit::ActivityMesg activityMesg;
activityMesg.SetTimestamp(diffSecs+599);
activityMesg.SetTotalTimerTime(600); //10min
activityMesg.SetNumSessions(1); // Always 1 session (1 workout per file)
activityMesg.SetType(FIT_ACTIVITY_MANUAL);
activityMesg.SetEvent(FIT_EVENT_WORKOUT);
activityMesg.SetEventType(FIT_EVENT_TYPE_START);
activityMesg.SetLocalTimestamp(diffSecs); //seconds since 00:00 Dec d31 1989 in local time zone
activityMesg.SetEvent(FIT_EVENT_ACTIVITY);
activityMesg.SetEventType(FIT_EVENT_TYPE_STOP);
encode.Write(activityMesg);
if (!encode.Close()) {
qDebug() << "Error closing encode.\n";
}
file.close();
qDebug() << "Encoded FIT file test.fit.\n";
}
——————————————————
Free Indoor Cycling Software - https://maximumtrainer.com
——————————————————
Free Indoor Cycling Software - https://maximumtrainer.com
-Your Activity file seems to meet all the requirements in the File Types Document. I might add lap.message_index and store something else in session.message_index. As for Garmin Connect, I don't think it accepts arbitrary uploads.
ShaneP
——————————————————
Free Indoor Cycling Software - https://maximumtrainer.com
——————————————————
Free Indoor Cycling Software - https://maximumtrainer.com
// --------------- ActivityMesg ------------------
...
activityMesg.SetEvent(FIT_EVENT_WORKOUT);
activityMesg.SetEventType(FIT_EVENT_TYPE_START);
..
activityMesg.SetEvent(FIT_EVENT_ACTIVITY);
activityMesg.SetEventType(FIT_EVENT_TYPE_STOP);
encode.Write(activityMesg);
...
Thanks for your help
——————————————————
Free Indoor Cycling Software - https://maximumtrainer.com