public List <SessionMessages> ParseSessions()
    {
        if (!IsActivityFile)
        {
            throw new Exception($"Expected FIT File Type: Activity, recieved File Type: {_messages?.FileId?.GetType()}");
        }

        // When there are no Sessions but there are Records create a Session message to recover as much data as possible
        if (_messages.Sessions.Count == 0 && _messages.Records.Count > 0)
        {
            Dynastream.Fit.DateTime startTime = _messages.Records[0].GetTimestamp();
            Dynastream.Fit.DateTime timestamp = _messages.Records[_messages.Records.Count - 1].GetTimestamp();

            var session = new SessionMesg();
            session.SetStartTime(startTime);
            session.SetTimestamp(timestamp);
            session.SetTotalElapsedTime(timestamp.GetTimeStamp() - startTime.GetTimeStamp());
            session.SetTotalTimerTime(timestamp.GetTimeStamp() - startTime.GetTimeStamp());

            _messages.Sessions.Add(session);
        }

        int recordsTaken = 0;

        var sessions = new List <SessionMessages>(_messages.Sessions.Count);

        foreach (SessionMesg sessionMesg in _messages.Sessions)
        {
            var session = new SessionMessages(sessionMesg)
            {
                Laps = _messages.Laps.Skip(sessionMesg.GetFirstLapIndex() ?? 0).Take(sessionMesg.GetNumLaps() ?? 0).ToList(),

                ClimbPros   = _messages.ClimbPros.Where(climb => climb.Within(sessionMesg)).ToList(),
                Events      = _messages.Events.Where(evt => evt.Within(sessionMesg)).ToList(),
                DeviceInfos = _messages.DeviceInfos.Where(deviceInfo => deviceInfo.Within(sessionMesg)).ToList(),
                Lengths     = _messages.Lengths.Where(length => length.Overlaps(sessionMesg)).ToList(),
                Records     = _messages.Records.Skip(recordsTaken).Where(record => record.Within(sessionMesg)).ToList(),
                SegmentLaps = _messages.SegmentLaps.Where(segmentLap => segmentLap.Overlaps(sessionMesg)).ToList(),

                TimerEvents               = _messages.Events.Where(evt => evt.GetEvent() == Event.Timer && evt.Within(sessionMesg)).ToList(),
                FrontGearChangeEvents     = _messages.Events.Where(evt => evt.GetEvent() == Event.FrontGearChange && evt.Within(sessionMesg)).ToList(),
                RearGearChangeEvents      = _messages.Events.Where(evt => evt.GetEvent() == Event.RearGearChange && evt.Within(sessionMesg)).ToList(),
                RiderPositionChangeEvents = _messages.Events.Where(evt => evt.GetEvent() == Event.RiderPositionChange && evt.Within(sessionMesg)).ToList(),

                Activity                  = _messages.Activity,
                FileId                    = _messages.FileId,
                RecordFieldNames          = _messages.RecordFieldNames,
                RecordDeveloperFieldNames = _messages.RecordDeveloperFieldNames,
                UserProfile               = _messages.UserProfile,
                Workout                   = _messages.Workout,
                WorkoutSteps              = _messages.WorkoutSteps,
                ZonesTarget               = _messages.ZonesTarget,
            };

            recordsTaken += session.Records.Count;
            sessions.Add(session);
        }

        return(sessions);
    }
Beispiel #2
0
        public static void AddRecord()
        {
            var now = new DateTime(System.DateTime.Now);

            if (lastRecordTimeStamp == now.GetTimeStamp())
            {
                return; // do not record twice with same timestamp
            }

            try
            {
                var newRecord = new RecordMesg();
                var hr        = State.CyclistHeartRate > 0 ? (byte?)State.CyclistHeartRate : null;
                var cad       = State.BikeCadence > 0 ? (byte?)State.BikeCadence : null;

                newRecord.SetTimestamp(now);

                newRecord.SetHeartRate(hr);
                newRecord.SetCadence(cad);
                newRecord.SetPower((ushort)State.CyclistPower);
                newRecord.SetGrade(State.BikeIncline);
                newRecord.SetDistance(State.TripTotalKm * 1000);
                newRecord.SetSpeed(State.BikeSpeedKmh / 3.6f);
                newRecord.SetAltitude(RaceState.Instance.CarPositions[0].Y);

                encoder.Write(newRecord);

                lastRecordTimeStamp = now.GetTimeStamp();
            } catch (Exception e)
            {
                Console.Write("Failed to write record.");
                Console.WriteLine(e.Message);
            }
        }
Beispiel #3
0
        /// <summary>
        /// Terminates the current lap in the FIT recording.
        /// Use cases : ingame lap (if no workout in progress), start/end of workout, end of activity.
        /// </summary>
        public static void TerminateLap()
        {
            var now = new DateTime(System.DateTime.Now);

            currentLapMesg.SetTimestamp(now);
            currentLapMesg.SetSport(Sport.Cycling);
            currentLapMesg.SetTotalElapsedTime(now.GetTimeStamp() - currentLapMesg.GetStartTime().GetTimeStamp());
            currentLapMesg.SetTotalTimerTime(now.GetTimeStamp() - currentLapMesg.GetStartTime().GetTimeStamp());
            currentLapMesg.SetTotalDistance(State.TripTotalKm * 1000 - alreadyLappedDistance);
            currentLapMesg.SetEvent(Event.Lap);
            currentLapMesg.SetEventType(EventType.Stop);
            currentLapMesg.SetEventGroup(0);

            encoder.Write(currentLapMesg);

            numLaps++;
            currentLapMesg        = new LapMesg();
            alreadyLappedDistance = State.TripTotalKm * 1000;

            currentLapMesg.SetStartTime(now);
        }
Beispiel #4
0
 /// <summary>
 /// Set ObservedAtTime field</summary>
 /// <param name="observedAtTime_">Nullable field value to be set</param>
 public void SetObservedAtTime(DateTime observedAtTime_)
 {
     SetFieldValue(9, 0, observedAtTime_.GetTimeStamp(), Fit.SubfieldIndexMainField);
 }
Beispiel #5
0
        public static void EncodeCourse()
        {
            const string filename = "CourseEncodeRecipe.fit";

            // Example Record Data Defining a Course
            var courseData = new List <Dictionary <string, object> >()
            {
                new Dictionary <string, object>()
                {
                    { "timestamp", 961262849U }, { "position_lat", 463583114 }, { "position_long", -1131028903 }, { "altitude", 329f }, { "distance", 0f }, { "speed", 0f }
                },
                new Dictionary <string, object>()
                {
                    { "timestamp", 961262855U }, { "position_lat", 463583127 }, { "position_long", -1131031938 }, { "altitude", 328.6f }, { "distance", 22.03f }, { "speed", 3.0f }
                },
                new Dictionary <string, object>()
                {
                    { "timestamp", 961262869U }, { "position_lat", 463583152 }, { "position_long", -1131038159 }, { "altitude", 327.6f }, { "distance", 67.29f }, { "speed", 3.0f }
                },
                new Dictionary <string, object>()
                {
                    { "timestamp", 961262876U }, { "position_lat", 463583164 }, { "position_long", -1131041346 }, { "altitude", 327f }, { "distance", 90.52f }, { "speed", 3.0f }
                },
                new Dictionary <string, object>()
                {
                    { "timestamp", 961262876U }, { "position_lat", 463583164 }, { "position_long", -1131041319 }, { "altitude", 327f }, { "distance", 90.72f }, { "speed", 3.0f }
                },
                new Dictionary <string, object>()
                {
                    { "timestamp", 961262891U }, { "position_lat", 463588537 }, { "position_long", -1131041383 }, { "altitude", 327f }, { "distance", 140.72f }, { "speed", 3.0f }
                },
                new Dictionary <string, object>()
                {
                    { "timestamp", 961262891U }, { "position_lat", 463588549 }, { "position_long", -1131041383 }, { "altitude", 327f }, { "distance", 140.82f }, { "speed", 3.0f }
                },
                new Dictionary <string, object>()
                {
                    { "timestamp", 961262897U }, { "position_lat", 463588537 }, { "position_long", -1131038293 }, { "altitude", 327.6f }, { "distance", 163.26f }, { "speed", 3.0f }
                },
                new Dictionary <string, object>()
                {
                    { "timestamp", 961262911U }, { "position_lat", 463588512 }, { "position_long", -1131032041 }, { "altitude", 328.4f }, { "distance", 208.75f }, { "speed", 3.0f }
                },
                new Dictionary <string, object>()
                {
                    { "timestamp", 961262918U }, { "position_lat", 463588499 }, { "position_long", -1131028879 }, { "altitude", 329f }, { "distance", 231.8f }, { "speed", 3.0f }
                },
                new Dictionary <string, object>()
                {
                    { "timestamp", 961262918U }, { "position_lat", 463588499 }, { "position_long", -1131028903 }, { "altitude", 329f }, { "distance", 231.97f }, { "speed", 3.0f }
                },
                new Dictionary <string, object>()
                {
                    { "timestamp", 961262933U }, { "position_lat", 463583127 }, { "position_long", -1131028903 }, { "altitude", 329f }, { "distance", 281.96f }, { "speed", 3.0f }
                },
            };

            // Create the output stream, this can be any type of stream, including a file or memory stream. Must have read/write access.
            FileStream fitDest = new FileStream(filename, FileMode.Create, FileAccess.ReadWrite, FileShare.Read);

            // Create a FIT Encode object
            Encode encoder = new Encode(ProtocolVersion.V10);

            // Write the FIT header to the output stream
            encoder.Open(fitDest);

            // Reference points for the course
            var firstRecord    = courseData[0];
            var lastRecord     = courseData[courseData.Count - 1];
            var halfwayRecord  = courseData[courseData.Count / 2];
            var startTimestamp = (uint)firstRecord["timestamp"];
            var endTimestamp   = (uint)lastRecord["timestamp"];
            var startDateTime  = new Dynastream.Fit.DateTime(startTimestamp);
            var endDateTime    = new Dynastream.Fit.DateTime(endTimestamp);

            // Every FIT file MUST contain a File ID message
            var fileIdMesg = new FileIdMesg();

            fileIdMesg.SetType(Dynastream.Fit.File.Course);
            fileIdMesg.SetManufacturer(Manufacturer.Development);
            fileIdMesg.SetProduct(ProductId);
            fileIdMesg.SetTimeCreated(startDateTime);
            fileIdMesg.SetSerialNumber(startDateTime.GetTimeStamp());
            encoder.Write(fileIdMesg);

            // Every FIT file MUST contain a Course message
            var courseMesg = new CourseMesg();

            courseMesg.SetName("Garmin Field Day");
            courseMesg.SetSport(Sport.Cycling);
            encoder.Write(courseMesg);

            // Every FIT COURSE file MUST contain a Lap message
            var lapMesg = new LapMesg();

            lapMesg.SetStartTime(startDateTime);
            lapMesg.SetTimestamp(startDateTime);
            lapMesg.SetTotalElapsedTime(endTimestamp - startTimestamp);
            lapMesg.SetTotalTimerTime(endTimestamp - startTimestamp);
            lapMesg.SetStartPositionLat((int)firstRecord["position_lat"]);
            lapMesg.SetStartPositionLong((int)firstRecord["position_long"]);
            lapMesg.SetEndPositionLat((int)lastRecord["position_lat"]);
            lapMesg.SetEndPositionLong((int)lastRecord["position_long"]);
            lapMesg.SetTotalDistance((float)lastRecord["distance"]);
            encoder.Write(lapMesg);

            // Timer Events are REQUIRED for FIT COURSE files
            var eventMesgStart = new EventMesg();

            eventMesgStart.SetTimestamp(startDateTime);
            eventMesgStart.SetEvent(Event.Timer);
            eventMesgStart.SetEventType(EventType.Start);
            encoder.Write(eventMesgStart);

            // Every FIT COURSE file MUST contain Record messages
            foreach (var record in courseData)
            {
                var timestamp = (uint)record["timestamp"];
                var latitude  = (int)record["position_lat"];
                var longitude = (int)record["position_long"];
                var distance  = (float)record["distance"];
                var speed     = (float)record["speed"];
                var altitude  = (float)record["altitude"];

                var recordMesg = new RecordMesg();
                recordMesg.SetTimestamp(new Dynastream.Fit.DateTime(timestamp));
                recordMesg.SetPositionLat(latitude);
                recordMesg.SetPositionLong(longitude);
                recordMesg.SetDistance(distance);
                recordMesg.SetSpeed(speed);
                recordMesg.SetAltitude(altitude);
                encoder.Write(recordMesg);

                // Add a Course Point at the halfway point of the route
                if (record == halfwayRecord)
                {
                    var coursePointMesg = new CoursePointMesg();
                    coursePointMesg.SetTimestamp(new Dynastream.Fit.DateTime(timestamp));
                    coursePointMesg.SetName("Halfway");
                    coursePointMesg.SetType(CoursePoint.Generic);
                    coursePointMesg.SetPositionLat(latitude);
                    coursePointMesg.SetPositionLong(longitude);
                    coursePointMesg.SetDistance(distance);
                    encoder.Write(coursePointMesg);
                }
            }

            // Timer Events are REQUIRED for FIT COURSE files
            var eventMesgStop = new EventMesg();

            eventMesgStop.SetTimestamp(endDateTime);
            eventMesgStop.SetEvent(Event.Timer);
            eventMesgStop.SetEventType(EventType.StopAll);
            encoder.Write(eventMesgStop);

            // Update the data size in the header and calculate the CRC
            encoder.Close();

            // Close the output stream
            fitDest.Close();

            Console.WriteLine($"Encoded FIT file {fitDest.Name}");
        }
Beispiel #6
0
 /// <summary>        
 /// Set EndDate field</summary>
 /// <param name="endDate_">Nullable field value to be set</param>      
 public void SetEndDate(DateTime endDate_)
 {
     SetFieldValue(3, 0, endDate_.GetTimeStamp(), Fit.SubfieldIndexMainField);
 }
Beispiel #7
0
 /// <summary>        
 /// Set TimeCreated field
 /// Comment: Corresponds to file_id of scheduled workout / course.</summary>
 /// <param name="timeCreated_">Nullable field value to be set</param>      
 public void SetTimeCreated(DateTime timeCreated_)
 {
     SetFieldValue(3, 0, timeCreated_.GetTimeStamp(), Fit.SubfieldIndexMainField);
 }
Beispiel #8
0
        static public void CreateLapSwimActivity()
        {
            // Example Swim Data representing a 500 yard pool swim using different strokes and drills.
            var swimData = new List <Dictionary <string, object> >()
            {
                new Dictionary <string, object>()
                {
                    { "type", "Active" }, { "duration", 20U }, { "stroke", "Freestyle" }, { "strokes", 30U }
                },
                new Dictionary <string, object>()
                {
                    { "type", "Active" }, { "duration", 25U }, { "stroke", "Freestyle" }, { "strokes", 20U }
                },
                new Dictionary <string, object>()
                {
                    { "type", "Active" }, { "duration", 30U }, { "stroke", "Freestyle" }, { "strokes", 10U }
                },
                new Dictionary <string, object>()
                {
                    { "type", "Active" }, { "duration", 35U }, { "stroke", "Freestyle" }, { "strokes", 20U }
                },
                new Dictionary <string, object>()
                {
                    { "type", "Lap" }
                },
                new Dictionary <string, object>()
                {
                    { "type", "Idle" }, { "duration", 60U }
                },
                new Dictionary <string, object>()
                {
                    { "type", "Lap" }
                },
                new Dictionary <string, object>()
                {
                    { "type", "Active" }, { "duration", 20U }, { "stroke", "Backstroke" }, { "strokes", 30U }
                },
                new Dictionary <string, object>()
                {
                    { "type", "Active" }, { "duration", 25U }, { "stroke", "Backstroke" }, { "strokes", 20U }
                },
                new Dictionary <string, object>()
                {
                    { "type", "Active" }, { "duration", 30U }, { "stroke", "Backstroke" }, { "strokes", 10U }
                },
                new Dictionary <string, object>()
                {
                    { "type", "Active" }, { "duration", 35U }, { "stroke", "Backstroke" }, { "strokes", 20U }
                },
                new Dictionary <string, object>()
                {
                    { "type", "Lap" }
                },
                new Dictionary <string, object>()
                {
                    { "type", "Idle" }, { "duration", 60U }
                },
                new Dictionary <string, object>()
                {
                    { "type", "Lap" }
                },
                new Dictionary <string, object>()
                {
                    { "type", "Active" }, { "duration", 20U }, { "stroke", "Breaststroke" }, { "strokes", 30U }
                },
                new Dictionary <string, object>()
                {
                    { "type", "Active" }, { "duration", 25U }, { "stroke", "Breaststroke" }, { "strokes", 20U }
                },
                new Dictionary <string, object>()
                {
                    { "type", "Active" }, { "duration", 30U }, { "stroke", "Breaststroke" }, { "strokes", 10U }
                },
                new Dictionary <string, object>()
                {
                    { "type", "Active" }, { "duration", 35U }, { "stroke", "Breaststroke" }, { "strokes", 20U }
                },
                new Dictionary <string, object>()
                {
                    { "type", "Lap" }
                },
                new Dictionary <string, object>()
                {
                    { "type", "Idle" }, { "duration", 60U }
                },
                new Dictionary <string, object>()
                {
                    { "type", "Lap" }
                },
                new Dictionary <string, object>()
                {
                    { "type", "Active" }, { "duration", 20U }, { "stroke", "Butterfly" }, { "strokes", 30U }
                },
                new Dictionary <string, object>()
                {
                    { "type", "Active" }, { "duration", 25U }, { "stroke", "Butterfly" }, { "strokes", 20U }
                },
                new Dictionary <string, object>()
                {
                    { "type", "Active" }, { "duration", 30U }, { "stroke", "Butterfly" }, { "strokes", 10U }
                },
                new Dictionary <string, object>()
                {
                    { "type", "Active" }, { "duration", 35U }, { "stroke", "Butterfly" }, { "strokes", 20U }
                },
                new Dictionary <string, object>()
                {
                    { "type", "Lap" }
                },
                new Dictionary <string, object>()
                {
                    { "type", "Idle" }, { "duration", 60U }
                },
                new Dictionary <string, object>()
                {
                    { "type", "Lap" }
                },
                new Dictionary <string, object>()
                {
                    { "type", "Active" }, { "duration", 40U }, { "stroke", "Drill" }
                },
                new Dictionary <string, object>()
                {
                    { "type", "Active" }, { "duration", 40U }, { "stroke", "Drill" }
                },
                new Dictionary <string, object>()
                {
                    { "type", "Active" }, { "duration", 40U }, { "stroke", "Drill" }
                },
                new Dictionary <string, object>()
                {
                    { "type", "Active" }, { "duration", 40U }, { "stroke", "Drill" }
                },
                new Dictionary <string, object>()
                {
                    { "type", "Lap" }
                },
            };

            const string FileName = "ActivityEncodeRecipeLapSwim.fit";
            var          messages = new List <Mesg>();

            // The starting timestamp for the activity
            var startTime = new Dynastream.Fit.DateTime(System.DateTime.UtcNow);


            // Timer Events are a BEST PRACTICE for FIT ACTIVITY files
            var eventMesgStart = new EventMesg();

            eventMesgStart.SetTimestamp(startTime);
            eventMesgStart.SetEvent(Event.Timer);
            eventMesgStart.SetEventType(EventType.Start);
            messages.Add(eventMesgStart);

            //
            // Create a Length or Lap message for each item in the sample swim data. Calculate
            // distance, duration, and stroke count for each lap and the overall session.
            //

            // Session Accumulators
            uint   sessionTotalElapsedTime = 0;
            float  sessionDistance         = 0;
            ushort sessionNumLengths       = 0;
            ushort sessionNumActiveLengths = 0;
            ushort sessionTotalStrokes     = 0;
            ushort sessionNumLaps          = 0;

            // Lap accumulators
            uint   lapTotalElapsedTime = 0;
            float  lapDistance         = 0;
            ushort lapNumActiveLengths = 0;
            ushort lapNumLengths       = 0;
            ushort lapFirstLengthIndex = 0;
            ushort lapTotalStrokes     = 0;
            var    lapStartTime        = new Dynastream.Fit.DateTime(startTime);

            var    poolLength     = 22.86f;
            var    poolLengthUnit = DisplayMeasure.Statute;
            var    timestamp      = new Dynastream.Fit.DateTime(startTime);
            ushort messageIndex   = 0;

            foreach (var swimLength in swimData)
            {
                string type = (string)swimLength["type"];

                if (type.Equals("Lap"))
                {
                    // Create a Lap message, set its fields, and write it to the file
                    var lapMesg = new LapMesg();
                    lapMesg.SetMessageIndex(sessionNumLaps);
                    lapMesg.SetTimestamp(timestamp);
                    lapMesg.SetStartTime(lapStartTime);
                    lapMesg.SetTotalElapsedTime(lapTotalElapsedTime);
                    lapMesg.SetTotalTimerTime(lapTotalElapsedTime);
                    lapMesg.SetTotalDistance(lapDistance);
                    lapMesg.SetFirstLengthIndex(lapFirstLengthIndex);
                    lapMesg.SetNumActiveLengths(lapNumActiveLengths);
                    lapMesg.SetNumLengths(lapNumLengths);
                    lapMesg.SetTotalStrokes(lapTotalStrokes);
                    lapMesg.SetAvgStrokeDistance(lapDistance / lapTotalStrokes);
                    lapMesg.SetSport(Sport.Swimming);
                    lapMesg.SetSubSport(SubSport.LapSwimming);
                    messages.Add(lapMesg);

                    sessionNumLaps++;

                    // Reset the Lap accumulators
                    lapFirstLengthIndex = messageIndex;
                    lapNumActiveLengths = 0;
                    lapNumLengths       = 0;
                    lapTotalElapsedTime = 0;
                    lapDistance         = 0;
                    lapTotalStrokes     = 0;
                    lapStartTime        = new Dynastream.Fit.DateTime(timestamp);
                }
                else
                {
                    uint duration   = (uint)swimLength["duration"];
                    var  lengthType = (LengthType)Enum.Parse(typeof(LengthType), type);

                    // Create a Length message and its fields
                    var lengthMesg = new LengthMesg();
                    lengthMesg.SetMessageIndex(messageIndex++);
                    lengthMesg.SetStartTime(timestamp);
                    lengthMesg.SetTotalElapsedTime(duration);
                    lengthMesg.SetTotalTimerTime(duration);
                    lengthMesg.SetLengthType(lengthType);

                    timestamp.Add(duration);
                    lengthMesg.SetTimestamp(timestamp);

                    // Create the Record message that pairs with the Length Message
                    var recordMesg = new RecordMesg();
                    recordMesg.SetTimestamp(timestamp);
                    recordMesg.SetDistance(sessionDistance + poolLength);

                    // Is this an Active Length?
                    if (lengthType == LengthType.Active)
                    {
                        // Get the Active data from the model
                        string     stroke     = swimLength.ContainsKey("stroke") ? (String)swimLength["stroke"] : "Freestyle";
                        uint       strokes    = swimLength.ContainsKey("strokes") ? (uint)swimLength["strokes"] : 0;
                        SwimStroke swimStroke = (SwimStroke)Enum.Parse(typeof(SwimStroke), stroke);

                        // Set the Active data on the Length Message
                        lengthMesg.SetAvgSpeed(poolLength / (float)duration);
                        lengthMesg.SetSwimStroke(swimStroke);

                        if (strokes > 0)
                        {
                            lengthMesg.SetTotalStrokes((ushort)strokes);
                            lengthMesg.SetAvgSwimmingCadence((byte)(strokes * 60U / duration));
                        }

                        // Set the Active data on the Record Message
                        recordMesg.SetSpeed(poolLength / (float)duration);
                        if (strokes > 0)
                        {
                            recordMesg.SetCadence((byte)((strokes * 60U) / duration));
                        }

                        // Increment the "Active" accumulators
                        sessionNumActiveLengths++;
                        lapNumActiveLengths++;
                        sessionDistance     += poolLength;
                        lapDistance         += poolLength;
                        sessionTotalStrokes += (ushort)strokes;
                        lapTotalStrokes     += (ushort)strokes;
                    }

                    // Write the messages to the file
                    messages.Add(recordMesg);
                    messages.Add(lengthMesg);

                    // Increment the "Total" accumulators
                    sessionTotalElapsedTime += duration;
                    lapTotalElapsedTime     += duration;
                    sessionNumLengths++;
                    lapNumLengths++;
                }
            }

            // Timer Events are a BEST PRACTICE for FIT ACTIVITY files
            var eventMesgStop = new EventMesg();

            eventMesgStop.SetTimestamp(timestamp);
            eventMesgStop.SetEvent(Event.Timer);
            eventMesgStop.SetEventType(EventType.StopAll);
            messages.Add(eventMesgStop);

            // Every FIT ACTIVITY file MUST contain at least one Session message
            var sessionMesg = new SessionMesg();

            sessionMesg.SetMessageIndex(0);
            sessionMesg.SetTimestamp(timestamp);
            sessionMesg.SetStartTime(startTime);
            sessionMesg.SetTotalElapsedTime(sessionTotalElapsedTime);
            sessionMesg.SetTotalTimerTime(sessionTotalElapsedTime);
            sessionMesg.SetTotalDistance(sessionDistance);
            sessionMesg.SetSport(Sport.Swimming);
            sessionMesg.SetSubSport(SubSport.LapSwimming);
            sessionMesg.SetFirstLapIndex(0);
            sessionMesg.SetNumLaps(sessionNumLaps);
            sessionMesg.SetPoolLength(poolLength);
            sessionMesg.SetPoolLengthUnit(poolLengthUnit);
            sessionMesg.SetNumLengths(sessionNumLengths);
            sessionMesg.SetNumActiveLengths(sessionNumActiveLengths);
            sessionMesg.SetTotalStrokes(sessionTotalStrokes);
            sessionMesg.SetAvgStrokeDistance(sessionDistance / sessionTotalStrokes);
            messages.Add(sessionMesg);

            // Every FIT ACTIVITY file MUST contain EXACTLY one Activity message
            var activityMesg = new ActivityMesg();

            activityMesg.SetTimestamp(timestamp);
            activityMesg.SetNumSessions(1);
            var timezoneOffset = (int)TimeZoneInfo.Local.BaseUtcOffset.TotalSeconds;

            activityMesg.SetLocalTimestamp((uint)((int)timestamp.GetTimeStamp() + timezoneOffset));
            activityMesg.SetTotalTimerTime(sessionTotalElapsedTime);
            messages.Add(activityMesg);

            CreateActivityFile(messages, FileName, startTime);
        }
Beispiel #9
0
 /// <summary>
 /// Set StartDate field</summary>
 /// <param name="startDate_">Nullable field value to be set</param>
 public void SetStartDate(DateTime startDate_)
 {
     SetFieldValue(2, 0, startDate_.GetTimeStamp(), Fit.SubfieldIndexMainField);
 }
Beispiel #10
0
 public bool Equals(DateTime dateTime)
 {
     return(this.GetTimeStamp().Equals(dateTime.GetTimeStamp()) && (this.GetFractionalTimeStamp().Equals(dateTime.GetFractionalTimeStamp())));
 }
Beispiel #11
0
 /// <summary>
 /// Set TimeCreated field
 /// Comment: Only set for files that are can be created/erased.</summary>
 /// <param name="timeCreated_">Nullable field value to be set</param>
 public void SetTimeCreated(DateTime timeCreated_)
 {
     SetFieldValue(4, 0, timeCreated_.GetTimeStamp(), Fit.SubfieldIndexMainField);
 }
Beispiel #12
0
 /// <summary>
 /// Set SystemTimestamp field
 /// Units: s
 /// Comment: Whole second part of the system timestamp</summary>
 /// <param name="systemTimestamp_">Nullable field value to be set</param>
 public void SetSystemTimestamp(DateTime systemTimestamp_)
 {
     SetFieldValue(1, 0, systemTimestamp_.GetTimeStamp(), Fit.SubfieldIndexMainField);
 }
Beispiel #13
0
 public bool Equals(DateTime dateTime)
 {
     return (this.timeStamp == dateTime.GetTimeStamp());
 }
 /// <summary>
 /// Set StressLevelTime field
 /// Units: s
 /// Comment: Time stress score was calculated</summary>
 /// <param name="stressLevelTime_">Nullable field value to be set</param>
 public void SetStressLevelTime(DateTime stressLevelTime_)
 {
     SetFieldValue(1, 0, stressLevelTime_.GetTimeStamp(), Fit.SubfieldIndexMainField);
 }
Beispiel #15
0
 /// <summary>
 /// Set ClockTime field
 /// Comment: UTC timestamp used to set the devices clock and date</summary>
 /// <param name="clockTime_">Nullable field value to be set</param>
 public void SetClockTime(DateTime clockTime_)
 {
     SetFieldValue(39, 0, clockTime_.GetTimeStamp(), Fit.SubfieldIndexMainField);
 }
Beispiel #16
0
 /// <summary>
 /// Set Timestamp field
 /// Units: s</summary>
 /// <param name="timestamp_">Nullable field value to be set</param>
 public void SetTimestamp(DateTime timestamp_)
 {
     SetFieldValue(253, 0, timestamp_.GetTimeStamp(), Fit.SubfieldIndexMainField);
 }
Beispiel #17
0
 /// <summary>
 /// Set EndDate field</summary>
 /// <param name="endDate_">Nullable field value to be set</param>
 public void SetEndDate(DateTime endDate_)
 {
     SetFieldValue(3, 0, endDate_.GetTimeStamp(), Fit.SubfieldIndexMainField);
 }
Beispiel #18
0
        static public void CreateTimeBasedActivity()
        {
            const double TwoPI = Math.PI * 2.0;
            const double SemicirclesPerMeter = 107.173;
            const string FileName            = "ActivityEncodeRecipe.fit";

            var messages = new List <Mesg>();

            // The starting timestamp for the activity
            var startTime = new Dynastream.Fit.DateTime(System.DateTime.UtcNow);

            // Timer Events are a BEST PRACTICE for FIT ACTIVITY files
            var eventMesgStart = new EventMesg();

            eventMesgStart.SetTimestamp(startTime);
            eventMesgStart.SetEvent(Event.Timer);
            eventMesgStart.SetEventType(EventType.Start);
            messages.Add(eventMesgStart);

            // Create the Developer Id message for the developer data fields.
            var developerIdMesg = new DeveloperDataIdMesg();

            // It is a BEST PRACTICE to reuse the same Guid for all FIT files created by your platform
            byte[] appId = new Guid("00010203-0405-0607-0809-0A0B0C0D0E0F").ToByteArray();
            for (int i = 0; i < appId.Length; i++)
            {
                developerIdMesg.SetApplicationId(i, appId[i]);
            }
            developerIdMesg.SetDeveloperDataIndex(0);
            developerIdMesg.SetApplicationVersion(110);
            messages.Add(developerIdMesg);

            // Create the Developer Data Field Descriptions
            var doughnutsFieldDescMesg = new FieldDescriptionMesg();

            doughnutsFieldDescMesg.SetDeveloperDataIndex(0);
            doughnutsFieldDescMesg.SetFieldDefinitionNumber(0);
            doughnutsFieldDescMesg.SetFitBaseTypeId(FitBaseType.Float32);
            doughnutsFieldDescMesg.SetFieldName(0, "Doughnuts Earned");
            doughnutsFieldDescMesg.SetUnits(0, "doughnuts");
            doughnutsFieldDescMesg.SetNativeMesgNum(MesgNum.Session);
            messages.Add(doughnutsFieldDescMesg);

            FieldDescriptionMesg hrFieldDescMesg = new FieldDescriptionMesg();

            hrFieldDescMesg.SetDeveloperDataIndex(0);
            hrFieldDescMesg.SetFieldDefinitionNumber(1);
            hrFieldDescMesg.SetFitBaseTypeId(FitBaseType.Uint8);
            hrFieldDescMesg.SetFieldName(0, "Heart Rate");
            hrFieldDescMesg.SetUnits(0, "bpm");
            hrFieldDescMesg.SetNativeFieldNum(RecordMesg.FieldDefNum.HeartRate);
            hrFieldDescMesg.SetNativeMesgNum(MesgNum.Record);
            messages.Add(hrFieldDescMesg);

            // Every FIT ACTIVITY file MUST contain Record messages
            var timestamp = new Dynastream.Fit.DateTime(startTime);

            // Create one hour (3600 seconds) of Record data
            for (uint i = 0; i <= 3600; i++)
            {
                // Create a new Record message and set the timestamp
                var recordMesg = new RecordMesg();
                recordMesg.SetTimestamp(timestamp);

                // Fake Record Data of Various Signal Patterns
                recordMesg.SetDistance(i);                                                          // Ramp
                recordMesg.SetSpeed(1);                                                             // Flatline
                recordMesg.SetHeartRate((byte)((Math.Sin(TwoPI * (0.01 * i + 10)) + 1.0) * 127.0)); // Sine
                recordMesg.SetCadence((byte)(i % 255));                                             // Sawtooth
                recordMesg.SetPower((ushort)((i % 255) < 127 ? 150 : 250));                         // Square
                recordMesg.SetAltitude((float)Math.Abs(((double)i % 255.0) - 127.0));               // Triangle
                recordMesg.SetPositionLat(0);
                recordMesg.SetPositionLong((int)Math.Round(i * SemicirclesPerMeter));

                // Add a Developer Field to the Record Message
                var hrDevField = new DeveloperField(hrFieldDescMesg, developerIdMesg);
                recordMesg.SetDeveloperField(hrDevField);
                hrDevField.SetValue((byte)((Math.Sin(TwoPI * (0.01 * i + 10)) + 1.0) * 127.0)); // Sine

                // Write the Rercord message to the output stream
                messages.Add(recordMesg);

                // Increment the timestamp by one second
                timestamp.Add(1);
            }

            // Timer Events are a BEST PRACTICE for FIT ACTIVITY files
            var eventMesgStop = new EventMesg();

            eventMesgStop.SetTimestamp(timestamp);
            eventMesgStop.SetEvent(Event.Timer);
            eventMesgStop.SetEventType(EventType.StopAll);
            messages.Add(eventMesgStop);

            // Every FIT ACTIVITY file MUST contain at least one Lap message
            var lapMesg = new LapMesg();

            lapMesg.SetMessageIndex(0);
            lapMesg.SetTimestamp(timestamp);
            lapMesg.SetStartTime(startTime);
            lapMesg.SetTotalElapsedTime(timestamp.GetTimeStamp() - startTime.GetTimeStamp());
            lapMesg.SetTotalTimerTime(timestamp.GetTimeStamp() - startTime.GetTimeStamp());
            messages.Add(lapMesg);

            // Every FIT ACTIVITY file MUST contain at least one Session message
            var sessionMesg = new SessionMesg();

            sessionMesg.SetMessageIndex(0);
            sessionMesg.SetTimestamp(timestamp);
            sessionMesg.SetStartTime(startTime);
            sessionMesg.SetTotalElapsedTime(timestamp.GetTimeStamp() - startTime.GetTimeStamp());
            sessionMesg.SetTotalTimerTime(timestamp.GetTimeStamp() - startTime.GetTimeStamp());
            sessionMesg.SetSport(Sport.StandUpPaddleboarding);
            sessionMesg.SetSubSport(SubSport.Generic);
            sessionMesg.SetFirstLapIndex(0);
            sessionMesg.SetNumLaps(1);

            // Add a Developer Field to the Session message
            var doughnutsEarnedDevField = new DeveloperField(doughnutsFieldDescMesg, developerIdMesg);

            doughnutsEarnedDevField.SetValue(sessionMesg.GetTotalElapsedTime() / 1200.0f);
            sessionMesg.SetDeveloperField(doughnutsEarnedDevField);
            messages.Add(sessionMesg);

            // Every FIT ACTIVITY file MUST contain EXACTLY one Activity message
            var activityMesg = new ActivityMesg();

            activityMesg.SetTimestamp(timestamp);
            activityMesg.SetNumSessions(1);
            var timezoneOffset = (int)TimeZoneInfo.Local.BaseUtcOffset.TotalSeconds;

            activityMesg.SetLocalTimestamp((uint)((int)timestamp.GetTimeStamp() + timezoneOffset));
            activityMesg.SetTotalTimerTime(timestamp.GetTimeStamp() - startTime.GetTimeStamp());
            messages.Add(activityMesg);

            CreateActivityFile(messages, FileName, startTime);
        }
Beispiel #19
0
 /// <summary>
 /// Set UtcTimestamp field
 /// Units: s
 /// Comment: Used to correlate UTC to system time if the timestamp of the message is in system time.  This UTC time is derived from the GPS data.</summary>
 /// <param name="utcTimestamp_">Nullable field value to be set</param>
 public void SetUtcTimestamp(DateTime utcTimestamp_)
 {
     SetFieldValue(6, 0, utcTimestamp_.GetTimeStamp(), Fit.SubfieldIndexMainField);
 }
Beispiel #20
0
 /// <summary>
 /// Set IssueTime field
 /// Comment: Time alert was issued</summary>
 /// <param name="issueTime_">Nullable field value to be set</param>
 public void SetIssueTime(DateTime issueTime_)
 {
     SetFieldValue(1, 0, issueTime_.GetTimeStamp(), Fit.SubfieldIndexMainField);
 }
Beispiel #21
0
 /// <summary>
 /// Set ExpireTime field
 /// Comment: Time alert expires</summary>
 /// <param name="expireTime_">Nullable field value to be set</param>
 public void SetExpireTime(DateTime expireTime_)
 {
     SetFieldValue(2, 0, expireTime_.GetTimeStamp(), Fit.SubfieldIndexMainField);
 }
Beispiel #22
0
 /// <summary>        
 /// Set Timestamp field
 /// Units: s
 /// Comment: Must align to logging interval, for example, time must be 00:00:00 for daily log.</summary>
 /// <param name="timestamp_">Nullable field value to be set</param>      
 public void SetTimestamp(DateTime timestamp_)
 {
     SetFieldValue(253, 0, timestamp_.GetTimeStamp(), Fit.SubfieldIndexMainField);
 }
Beispiel #23
0
 public bool Equals(DateTime dateTime)
 {
     return(this.timeStamp == dateTime.GetTimeStamp());
 }
Beispiel #24
0
 /// <summary>        
 /// Set StartDate field</summary>
 /// <param name="startDate_">Nullable field value to be set</param>      
 public void SetStartDate(DateTime startDate_)
 {
     SetFieldValue(2, 0, startDate_.GetTimeStamp(), Fit.SubfieldIndexMainField);
 }
Beispiel #25
0
 public bool Equals(DateTime dateTime)
 {
     return (this.GetTimeStamp().Equals(dateTime.GetTimeStamp()) && (this.GetFractionalTimeStamp().Equals(dateTime.GetFractionalTimeStamp())));
 }