private void MergeFiles(Stream outStream)
        {
            lock (_zwiftFile)
            {
                ResetStreams();
                FindDelay();

                _encode = new Encode(outStream, ProtocolVersion.V20);
                try
                {
                    ResetStreams();

                    // Read the header from both files to ensure we can step through the messages
                    MergeMessages();
                }
                finally
                {
                    _encode.Close();
                    _encode = null;
                    ResetStreams();
                }
            }

            outStream.Seek(0, SeekOrigin.Begin);
        }
Exemple #2
0
        public static void Stop()
        {
            var now = new DateTime(System.DateTime.Now);

            TerminateLap();

            sessionMesg.SetTimestamp(now);
            sessionMesg.SetSport(Sport.Cycling);
            sessionMesg.SetSubSport(SubSport.VirtualActivity);
            sessionMesg.SetTotalDistance(State.TripTotalKm * 1000);
            sessionMesg.SetTotalElapsedTime(State.TripTotalTime);
            sessionMesg.SetFirstLapIndex(0);
            sessionMesg.SetNumLaps(numLaps);
            sessionMesg.SetEvent(Event.Session);
            sessionMesg.SetEventType(EventType.Stop);
            sessionMesg.SetEventGroup(0);

            activityMesg = new ActivityMesg();
            activityMesg.SetTimestamp(now);
            activityMesg.SetTotalTimerTime(State.TripTotalTime);
            activityMesg.SetNumSessions(1);
            activityMesg.SetType(Activity.Manual);
            activityMesg.SetEvent(Event.Activity);
            activityMesg.SetEventType(EventType.Stop);
            activityMesg.SetEventGroup(0);

            encoder.Write(sessionMesg);
            encoder.Write(activityMesg);

            encoder.Close();
            fitDest.Close();
        }
Exemple #3
0
 public void Close()
 {
     if (_encoder != null)
     {
         _encoder.Close();
         _encoder = null;
     }
 }
Exemple #4
0
        static void CreateActivityFile(List <Mesg> messages, String filename, Dynastream.Fit.DateTime startTime)
        {
            // The combination of file type, manufacturer id, product id, and serial number should be unique.
            // When available, a non-random serial number should be used.
            Dynastream.Fit.File fileType = Dynastream.Fit.File.Activity;
            ushort manufacturerId        = Manufacturer.Development;
            ushort productId             = 0;
            float  softwareVersion       = 1.0f;

            Random random       = new Random();
            uint   serialNumber = (uint)random.Next();

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

            fileIdMesg.SetType(fileType);
            fileIdMesg.SetManufacturer(manufacturerId);
            fileIdMesg.SetProduct(productId);
            fileIdMesg.SetTimeCreated(startTime);
            fileIdMesg.SetSerialNumber(serialNumber);

            // A Device Info message is a BEST PRACTICE for FIT ACTIVITY files
            var deviceInfoMesg = new DeviceInfoMesg();

            deviceInfoMesg.SetDeviceIndex(DeviceIndex.Creator);
            deviceInfoMesg.SetManufacturer(Manufacturer.Development);
            deviceInfoMesg.SetProduct(productId);
            deviceInfoMesg.SetProductName("FIT Cookbook"); // Max 20 Chars
            deviceInfoMesg.SetSerialNumber(serialNumber);
            deviceInfoMesg.SetSoftwareVersion(softwareVersion);
            deviceInfoMesg.SetTimestamp(startTime);

            // 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.V20);

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

            // Write the messages to the file, in the proper sequence
            encoder.Write(fileIdMesg);
            encoder.Write(deviceInfoMesg);

            foreach (Mesg message in messages)
            {
                encoder.Write(message);
            }

            // 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}");
        }
Exemple #5
0
        private void convertFilesGarmin()
        {
            int        result;
            string     gcUploadFileName = "GCupload.fit";
            HttpGarmin garminUpload     = new HttpGarmin(txtGarminUsername.Text, txtGarminPassword.Text, gcUploadFileName);

            result = garminUpload.GarminLogin();

            foreach (string sourceFile in Directory.GetFiles(txtSource.Text, "*.fit"))
            {
                string sourceFileName  = Path.GetFileName(sourceFile);
                string destinationFile = txtDestination.Text + "\\" + sourceFileName;
                string archiveFile     = txtArchive.Text + "\\" + sourceFileName;
                string gcUploadFile    = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + "\\" + gcUploadFileName;

                fitSource = new FileStream(sourceFile, FileMode.Open);

                Decode          GD3decoder      = new Decode();
                MesgBroadcaster mesgBroadcaster = new MesgBroadcaster();

                GD3encoder = new Encode(ProtocolVersion.V20);
                fitDest    = new FileStream(destinationFile, FileMode.Create, FileAccess.ReadWrite, FileShare.Read);
                GD3encoder.Open(fitDest);

                GD3decoder.MesgEvent += mesgBroadcaster.OnMesg;

                mesgBroadcaster.MesgEvent += OnMesg;

                bool status = GD3decoder.IsFIT(fitSource);
                status &= GD3decoder.CheckIntegrity(fitSource);

                if (status)
                {
                    GD3decoder.Read(fitSource);
                }

                fitSource.Close();
                GD3encoder.Close();
                fitDest.Close();

                System.IO.File.Move(sourceFile, archiveFile);

                System.IO.File.Copy(destinationFile, gcUploadFile, true);
                result = garminUpload.GarminUpload();
                System.IO.File.Delete(gcUploadFile);
            }

            result = garminUpload.GarminLogout();
        }
Exemple #6
0
        protected override void Save(Tuple <string, ICollection <Mesg> > data, string path)
        {
            using (FileStream fitDest = new FileStream(path, FileMode.Create, FileAccess.ReadWrite, FileShare.Read))
            {
                Encode encoder = new Encode(ProtocolVersion.V20);
                encoder.Open(fitDest);
                foreach (Mesg message in data.Item2)
                {
                    encoder.Write(message);
                }
                encoder.Close();

                Log.Information("Encoded FIT file {@Path}", fitDest.Name);
            }
        }
Exemple #7
0
        //[Test]
        //public void DecodeFitFile()
        //{
        //	var syncMyWorkoutFitFile = Path.Join(DataDirectory, "fenix_outdoor_run_vo2.fit");
        //	FitDecoder.Decode(syncMyWorkoutFitFile);
        //}

        //[Test]
        //public async Task DownloadWorkout()
        //{
        //	var email = "";
        //	var password = "";

        //var workoutId = "aaa6527fd5a74b7e8e2f8975c6025e60";

        //	var client = new ApiClient(email, password, false);
        //	await client.InitAuthAsync();

        //	var workout = await client.GetWorkoutByIdAsync(workoutId);
        //	var workoutSamples = await client.GetWorkoutSamplesByIdAsync(workoutId);
        //	var workoutSummary = await client.GetWorkoutSummaryByIdAsync(workoutId);

        //	dynamic data = new JObject();
        //	data.Workout = workout;
        //	data.WorkoutSamples = workoutSamples;
        //	data.WorkoutSummary = workoutSummary;

        //	Log.Debug(data.ToString());
        //	SaveRawData(data, workoutId, DataDirectory);
        //}

        //[Test]
        //public async Task DeSerialize()
        //{
        //	var file = Path.Join(DataDirectory, "test.json");
        //	var _fileHandler = new IOWrapper();
        //	var workout = _fileHandler.DeserializeJson<P2GWorkout>(file);
        //}

        //[Test]
        //public async Task Convert()
        //{
        //	var file = Path.Join(DataDirectory, "lanebreaker.json");

        //	var autoMocker = new AutoMocker();
        //	var settings = new Settings();

        //	var fitConverter = new ConverterInstance(settings);
        //	var messages = fitConverter.Convert(file);

        //	var output = Path.Join(DataDirectory, "output.fit");

        //	SaveFit(messages, output);
        //}

        private void SaveFit(Tuple <string, ICollection <Mesg> > messages, string outputPath)
        {
            using (FileStream fitDest = new FileStream(outputPath, FileMode.Create, FileAccess.ReadWrite, FileShare.Read))
            {
                Encode encoder = new Encode(ProtocolVersion.V20);
                try
                {
                    encoder.Open(fitDest);
                    encoder.Write(messages.Item2);
                }
                finally
                {
                    encoder.Close();
                }
            }
        }
Exemple #8
0
        static void CreateWorkout(WorkoutMesg workoutMesg, List <WorkoutStepMesg> workoutSteps)
        {
            // The combination of file type, manufacturer id, product id, and serial number should be unique.
            // When available, a non-random serial number should be used.
            Dynastream.Fit.File fileType = Dynastream.Fit.File.Workout;
            ushort manufacturerId        = Manufacturer.Development;
            ushort productId             = 0;
            Random random       = new Random();
            uint   serialNumber = (uint)random.Next();

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

            fileIdMesg.SetType(fileType);
            fileIdMesg.SetManufacturer(manufacturerId);
            fileIdMesg.SetProduct(productId);
            fileIdMesg.SetTimeCreated(new Dynastream.Fit.DateTime(System.DateTime.UtcNow));
            fileIdMesg.SetSerialNumber(serialNumber);

            // 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($"{workoutMesg.GetWktNameAsString().Replace(' ', '_')}.fit", 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);

            // Write the messages to the file, in the proper sequence
            encoder.Write(fileIdMesg);
            encoder.Write(workoutMesg);

            foreach (WorkoutStepMesg workoutStep in workoutSteps)
            {
                encoder.Write(workoutStep);
            }

            // 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}");
        }
Exemple #9
0
        public static void Stop(DateTime?time = null)
        {
            Trace.TraceInformation("Stop()");
            var now = time ?? DateTime.UtcNow;

            TerminateLap(time);

            if (!isPaused)
            {
                Pause(time);
            }

            sessionMesg.SetTimestamp(new Dynastream.Fit.DateTime(now));
            sessionMesg.SetSport(Sport.Cycling);
            sessionMesg.SetSubSport(SubSport.VirtualActivity);
            sessionMesg.SetTotalDistance(totalDistance);
            sessionMesg.SetTotalElapsedTime((float)(now - startTime).TotalSeconds);
            sessionMesg.SetTotalTimerTime((float)totalTimerTime.TotalSeconds);
            sessionMesg.SetFirstLapIndex(0);
            sessionMesg.SetNumLaps(numLaps);
            sessionMesg.SetEvent(Event.Session);
            sessionMesg.SetEventType(EventType.Stop);
            sessionMesg.SetEventGroup(0);
            sessionMesg.SetStartTime(new Dynastream.Fit.DateTime(startTime));

            activityMesg = new ActivityMesg();
            activityMesg.SetTimestamp(new Dynastream.Fit.DateTime(now));
            activityMesg.SetTotalTimerTime((float)totalTimerTime.TotalSeconds);
            activityMesg.SetNumSessions(1);
            activityMesg.SetType(Activity.Manual);
            activityMesg.SetEvent(Event.Activity);
            activityMesg.SetEventType(EventType.Stop);
            activityMesg.SetEventGroup(0);

            encoder.Write(sessionMesg);
            encoder.Write(activityMesg);

            encoder.Close();
            fitDest.Close();

            csvFile.Close();
        }
        protected override void Save(Tuple <string, ICollection <Mesg> > data, string path)
        {
            using var tracing = Tracing.Trace($"{nameof(FitConverter)}.{nameof(Save)}")
                                .WithTag(TagKey.Format, FileFormat.Fit.ToString());

            using (FileStream fitDest = new FileStream(path, FileMode.Create, FileAccess.ReadWrite, FileShare.Read))
            {
                Encode encoder = new Encode(ProtocolVersion.V20);

                try
                {
                    encoder.Open(fitDest);
                    encoder.Write(data.Item2);
                }
                finally
                {
                    encoder.Close();
                }

                _logger.Information("[{@Format}] Encoded file {@Path}", FileFormat.Fit, fitDest.Name);
            }
        }
        /// <summary>
        /// Demonstrate the encoding of a 'Settings File' by writing a 'Settings File' containing a 'User Profile' Message.
        /// This example is simpler than the 'Monitoring File' example.
        /// </summary>
        static void EncodeSettingsFile()
        {
            // Generate some FIT messages
            FileIdMesg fileIdMesg = new FileIdMesg(); // Every FIT file MUST contain a 'File ID' message as the first message

            fileIdMesg.SetType(Dynastream.Fit.File.Settings);
            fileIdMesg.SetManufacturer(Manufacturer.Development);  // Types defined in the profile are available
            fileIdMesg.SetProduct(1);
            fileIdMesg.SetSerialNumber(12345);

            UserProfileMesg myUserProfile = new UserProfileMesg();

            myUserProfile.SetGender(Gender.Female);
            float myWeight = 63.1F;

            myUserProfile.SetWeight(myWeight);
            myUserProfile.SetAge(99);
            myUserProfile.SetFriendlyName(Encoding.UTF8.GetBytes("TestUser"));

            FileStream fitDest = new FileStream("ExampleSettings.fit", FileMode.Create, FileAccess.ReadWrite, FileShare.Read);

            // Create file encode object
            Encode encodeDemo = new Encode(ProtocolVersion.V10);

            // Write our header
            encodeDemo.Open(fitDest);

            // Encode each message, a definition message is automatically generated and output if necessary
            encodeDemo.Write(fileIdMesg);
            encodeDemo.Write(myUserProfile);

            // Update header datasize and file CRC
            encodeDemo.Close();
            fitDest.Close();

            Console.WriteLine("Encoded FIT file ExampleSettings.fit");
            return;
        }
Exemple #12
0
        public void Fit_Converter_Creates_Valid_Fit(string filename, PreferredLapType lapType)
        {
            var workoutPath = Path.Join(DataDirectory, $"{filename}.json");
            var settings    = new Settings()
            {
                Format = new Format()
                {
                    Running = new Running()
                    {
                        PreferredLapType = lapType
                    },
                    Cycling = new Cycling()
                    {
                        PreferredLapType = lapType
                    }
                }
            };
            var converter      = new ConverterInstance(settings);
            var convertedMesgs = converter.ConvertForTest(workoutPath);

            convertedMesgs.Should().NotBeNullOrEmpty();

            var dest = Path.Join(DataDirectory, $"test_output_{filename}.fit");

            try
            {
                using (FileStream fitDest = new FileStream(dest, FileMode.Create, FileAccess.ReadWrite, FileShare.Read))
                {
                    var validator = new Encode(ProtocolVersion.V20);
                    validator.Open(fitDest);
                    validator.Write(convertedMesgs);                     // validates while writing
                    validator.Close();
                }
            } finally
            {
                System.IO.File.Delete(dest);
            }
        }
Exemple #13
0
        static void Main(string[] args)
        {
            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();

            // Generate some FIT messages
            FileIdMesg fileIdMesg = new FileIdMesg();

            fileIdMesg.SetManufacturer(Manufacturer.Dynastream);  // Types defined in the profile are available
            fileIdMesg.SetProduct(1000);
            fileIdMesg.SetSerialNumber(12345);

            //UserProfileMesg myUserProfile = new UserProfileMesg();
            //myUserProfile.SetGender(Gender.Female);
            //float myWeight = 63.1F;
            //myUserProfile.SetWeight(myWeight);
            //myUserProfile.SetAge(99);
            //myUserProfile.SetFriendlyName(Encoding.UTF8.GetBytes("TestUser"));

            var route = GpxClass.FromFile("route.gpx");

            CourseMesg course = new CourseMesg();

            course.SetName(Encoding.UTF8.GetBytes("route from gpx"));
            course.SetSport(Sport.Cycling);

            var baseDate = route.metadata.timeSpecified ? route.metadata.time : System.DateTime.Now.AddDays(-1);

            FileStream fitDest = new FileStream("Test.fit", FileMode.Create, FileAccess.ReadWrite, FileShare.Read);

            // Create file encode object
            Encode encodeDemo = new Encode();

            // Write our header
            encodeDemo.Open(fitDest);
            // Encode each message, a definition message is automatically generated and output if necessary
            encodeDemo.Write(fileIdMesg);
            //encodeDemo.Write(myUserProfile);

            encodeDemo.Write(course);

            var lap = new LapMesg();

            encodeDemo.Write(lap);


            var firstTrk = route.trk.First();

            var firstTrkSeg = firstTrk.trkseg.First();

            var firstPoint = firstTrkSeg.trkpt.First();

            lap.SetTimestamp(new fit.DateTime(firstPoint.time));
            lap.SetStartPositionLat(firstPoint.lat.RawInt());
            lap.SetStartPositionLong(firstPoint.lon.RawInt());

            var lastPoint = firstTrkSeg.trkpt.Last();

            lap.SetEndPositionLat(lastPoint.lat.RawInt());
            lap.SetEndPositionLong(lastPoint.lon.RawInt());

            var e = new EventMesg();

            e.SetTimestamp(new fit.DateTime(firstPoint.time));
            e.SetEventType(EventType.Start);
            e.SetEventGroup(0);
            e.SetEvent(Event.Timer);
            e.SetData(null);
            encodeDemo.Write(e);

            foreach (var point in firstTrkSeg.trkpt)
            {
                var p = new RecordMesg();
                p.SetPositionLat(point.lat.RawInt());
                p.SetPositionLong(point.lon.RawInt());
                //p.SetDistance(point. 10665.65f);
                p.SetAltitude(Convert.ToSingle(point.ele));
                p.SetTimestamp(new fit.DateTime(baseDate));

                encodeDemo.Write(p);
            }

            var eventStop = new EventMesg();

            eventStop.SetData(null);
            eventStop.SetTimestamp(new fit.DateTime(lastPoint.time));
            eventStop.SetEvent(Event.Timer);
            eventStop.SetEventType(EventType.StopDisableAll);
            encodeDemo.Write(eventStop);

            // Update header datasize and file CRC
            encodeDemo.Close();

            fitDest.Close();

            Console.WriteLine("Encoded FIT file test.fit");
            stopwatch.Stop();
            Console.WriteLine("Time elapsed: {0:0.#}s", stopwatch.Elapsed.TotalSeconds);

            Console.ReadKey();
        }
Exemple #14
0
        public void Strip(Stream input, Stream output, StripOptions options)
        {
            int time = Environment.TickCount;

            _options = options;

            // Create file encode object
            _encoder = new Encode(output);

            Decode decoder = new Decode();

            //MesgBroadcaster mesgBroadcaster = new MesgBroadcaster();

            // Connect the Broadcaster to our event (message) source (in this case the Decoder)
            decoder.MesgEvent           += OnMesg;
            decoder.MesgDefinitionEvent += OnMesgDefn;

            // Subscribe to message events of interest by connecting to the Broadcaster
            //mesgBroadcaster.MesgEvent += OnMesg;
            //mesgBroadcaster.MesgDefinitionEvent += OnMesgDefn;

            _mesgCounts.Clear();

            bool status = decoder.IsFIT(input);

            status &= decoder.CheckIntegrity(input);
            // Process the file
            if (status)
            {
                Log("Decoding...");
                decoder.Read(input);
                Log("Decoded FIT file");
            }
            else
            {
                try
                {
                    Log("Integrity Check Failed.");
                    Log("Attempting to decode...");
                    decoder.Read(input);
                }
                catch (FitException ex)
                {
                    Log("DecodeDemo caught FitException: " + ex.Message);
                }
            }

            _encoder.Close();

            Log("Summary:");
            int totalMesgs = 0;

            foreach (KeyValuePair <ushort, int> pair in _mesgCounts)
            {
                Log("MesgID {0,3} Count {1}", pair.Key, pair.Value);
                totalMesgs += pair.Value;
            }

            Log("{0} Message Types {1} Total Messages", _mesgCounts.Count, totalMesgs);

            time = Environment.TickCount - time;
            Log("Time elapsed: {0:0.#}s", time / 1000.0f);// stopwatch.Elapsed.TotalSeconds);
        }
Exemple #15
0
        /// <summary>
        /// Encode to a fit file
        /// </summary>
        /// <param name="db"></param>
        /// <param name="outputFileName"></param>
        public static void EncodeActivityFile(TrainingCenterDatabase_t db, string outputFileName)
        {
            /*
             *          string assemblyFilePath = Assembly.GetExecutingAssembly().GetName().CodeBase;
             *          string assemblyPath = assemblyFilePath.Replace(SysPath.GetFileName(assemblyFilePath), "");
             */

            if (string.IsNullOrEmpty(outputFileName))
            {
                outputFileName = "out";
            }

            //outputFileName = assemblyPath + outputFileName;

            //  write FIT file
            Encode        encoder = new Encode(ProtocolVersion.V20);
            SysFileStream fitDest = new SysFileStream(outputFileName + ".fit",
                                                      SysFileMode.Create,
                                                      SysFileAccess.ReadWrite,
                                                      SysFileShare.Read);

            // Write our header
            encoder.Open(fitDest);

            // FIT file_id message
            FileIdMesg fileIdMesg = new FileIdMesg();

            fileIdMesg.SetType(File.Activity);  // Activity File = 4
            fileIdMesg.SetManufacturer(Manufacturer.Garmin);
            fileIdMesg.SetProduct(GarminProduct.Fr935);
            fileIdMesg.SetSerialNumber(3949668594);
            fileIdMesg.SetTimeCreated(new DateTime(db.Activities.Activity[0].Id));    // set from input file

            // Encode each message, a definition message is automatically generated and output if necessary
            encoder.OnMesgDefinition(new MesgDefinition(fileIdMesg));
            encoder.OnMesg(fileIdMesg);
            Utils.LogMessage(LogType.Information, "Wrote FileID");

            // FIT FileCreator
            FileCreatorMesg fileCreatorMesg = new FileCreatorMesg();

            fileCreatorMesg.SetSoftwareVersion(600);    // Garmin Connect
            encoder.OnMesgDefinition(new MesgDefinition(fileCreatorMesg));
            encoder.OnMesg(fileCreatorMesg);
            Utils.LogMessage(LogType.Information, "Wrote FileCreatorMesg");

            // FIT event message : not found in TCX
            EventMesg eventMesg = new EventMesg();

            eventMesg.SetTimestamp(new DateTime(db.Activities.Activity[0].Id));
            eventMesg.SetData(0);
            eventMesg.SetEvent(Event.Timer);
            eventMesg.SetEventType(EventType.Start);
            eventMesg.SetEventGroup(0);
            encoder.OnMesgDefinition(new MesgDefinition(eventMesg));
            encoder.OnMesg(eventMesg);
            Utils.LogMessage(LogType.Information, "Wrote EventMesg");

            // FIT deviceInfo message: not found in TCX
            DeviceInfoMesg devInfoMesg = new DeviceInfoMesg();

            devInfoMesg.SetTimestamp(new DateTime(db.Activities.Activity[0].Id));
            devInfoMesg.SetSerialNumber(3949668594);
            devInfoMesg.SetManufacturer(Manufacturer.Garmin);
            devInfoMesg.SetProduct(GarminProduct.Fr935);
            devInfoMesg.SetSoftwareVersion(6);
            devInfoMesg.SetDeviceIndex(0);
            devInfoMesg.SetSourceType(SourceType.Local);
            for (int i = 0; i < 4; i++)
            {
                encoder.OnMesgDefinition(new MesgDefinition(devInfoMesg));
                encoder.OnMesg(devInfoMesg);
                Utils.LogMessage(LogType.Information, "Wrote DeviceInfoMesg");
            }

            // FIT deviceSettings message: not found in TCX
            DeviceSettingsMesg devSettingsMesg = new DeviceSettingsMesg();

            devSettingsMesg.SetUtcOffset(0);
            devSettingsMesg.SetTimeOffset(7, 0);
            devSettingsMesg.SetAutoActivityDetect(0);
            devSettingsMesg.SetAutosyncMinSteps(2000);
            devSettingsMesg.SetAutosyncMinTime(240);
            devSettingsMesg.SetActiveTimeZone(0);
            devSettingsMesg.SetActivityTrackerEnabled(Bool.True);
            devSettingsMesg.SetMountingSide(Side.Left);
            devSettingsMesg.SetTimeMode(1, TimeMode.Utc);
            encoder.OnMesgDefinition(new MesgDefinition(devSettingsMesg));
            encoder.OnMesg(devSettingsMesg);
            Utils.LogMessage(LogType.Information, "Wrote DeviceSettingsMesg");

            // FIT UserProfile message: : not found in TCX
            UserProfileMesg userProfileMesg = new UserProfileMesg();

            userProfileMesg.SetActivityClass(ActivityClass.Level);
            encoder.OnMesgDefinition(new MesgDefinition(userProfileMesg));
            encoder.OnMesg(userProfileMesg);
            Utils.LogMessage(LogType.Information, "Wrote UserProfileMesg");

            // FIT Sport:
            SportMesg sportMesg = new SportMesg();

            sportMesg.SetSport(Sport.Running);
            sportMesg.SetSubSport(SubSport.Road);

            // Encode each message, a definition message is automatically generated and output if necessary
            encoder.OnMesgDefinition(new MesgDefinition(sportMesg));
            encoder.OnMesg(sportMesg);
            Utils.LogMessage(LogType.Information, "Wrote SportMesg");

            // create FIT record and lap message
            double totalTime = 0;

            foreach (Activity_t act in db.Activities.Activity)
            {
                foreach (ActivityLap_t lap in act.Lap)
                {
                    List <RecordMesg> records = new List <RecordMesg>();

                    // FIT Record message:
                    foreach (Trackpoint_t trackPoint in lap.Track)
                    {
                        RecordMesg recMesg = new RecordMesg();

                        recMesg.SetTimestamp(new DateTime(trackPoint.Time));
                        recMesg.SetPositionLat(Utils.ConvertTcxLatLongToFit(trackPoint.Position.LatitudeDegrees));
                        recMesg.SetPositionLong(Utils.ConvertTcxLatLongToFit(trackPoint.Position.LongitudeDegrees));
                        recMesg.SetDistance((float)trackPoint.DistanceMeters);
                        recMesg.SetAltitude((float)trackPoint.AltitudeMeters);
                        //recMesg.SetSpeed((float)trackPoint.Extensions.Any["Speed"]);
                        if (trackPoint.HeartRateBpm != null)
                        {
                            recMesg.SetHeartRate((byte)trackPoint.HeartRateBpm.Value);
                        }

                        // Extension
                        if (trackPoint.Extensions.Any[0].GetElementsByTagName("ns3:RunCadence") != null)
                        {
                            if (trackPoint.Extensions.Any[0].GetElementsByTagName("ns3:RunCadence").Count == 1)
                            {
                                int cadence = 0;
                                int.TryParse((trackPoint.Extensions.Any[0].GetElementsByTagName("ns3:RunCadence")[0].InnerText), out cadence);
                                recMesg.SetCadence((byte)cadence);
                            }
                        }

                        if (trackPoint.Extensions.Any[0].GetElementsByTagName("ns3:Speed") != null)
                        {
                            if (trackPoint.Extensions.Any[0].GetElementsByTagName("ns3:Speed").Count == 1)
                            {
                                double speed = 0;
                                double.TryParse((trackPoint.Extensions.Any[0].GetElementsByTagName("ns3:Speed")[0].InnerText), out speed);
                                recMesg.SetSpeed((float)speed);
                            }
                        }

                        encoder.OnMesgDefinition(new MesgDefinition(recMesg));
                        encoder.OnMesg(recMesg);
                        Utils.LogMessage(LogType.Information, string.Format("Wrote RecMesg: {0}", recMesg.GetTimestamp().ToString()));
                    }

                    LapMesg lapMesg = new LapMesg();
                    lapMesg.SetTimestamp(new DateTime(lap.StartTime));
                    lapMesg.SetStartTime(new DateTime(lap.StartTime));
                    lapMesg.SetTotalMovingTime((float)lap.TotalTimeSeconds);
                    lapMesg.SetStartPositionLat(Utils.ConvertTcxLatLongToFit(lap.Track[0].Position.LatitudeDegrees));
                    lapMesg.SetStartPositionLong(Utils.ConvertTcxLatLongToFit(lap.Track[0].Position.LongitudeDegrees));
                    lapMesg.SetSport(Sport.Running);
                    lapMesg.SetSubSport(SubSport.Road);
                    // TODO: EndPosition
                    lapMesg.SetTotalElapsedTime((float)lap.TotalTimeSeconds);
                    totalTime += lap.TotalTimeSeconds;
                    // TODO: The rest

                    encoder.OnMesgDefinition(new MesgDefinition(lapMesg));
                    encoder.OnMesg(lapMesg);
                    Utils.LogMessage(LogType.Information, "Wrote LapMesg");
                }
            }

            // FIT Session: not found in tcx
            // FIT Activity
            ActivityMesg activityMesg = new ActivityMesg();

            activityMesg.SetTimestamp(new DateTime(db.Activities.Activity[0].Id));
            activityMesg.SetTotalTimerTime((float)totalTime);
            activityMesg.SetLocalTimestamp(new DateTime(db.Activities.Activity[0].Id).GetTimeStamp() + (uint)totalTime);
            activityMesg.SetNumSessions(1);
            activityMesg.SetType(Activity.Manual);
            activityMesg.SetEvent(Event.Activity);
            activityMesg.SetEventType(EventType.Stop);
            //activityMesg.SetTotalTimerTime(db.Activities.Activity[0].Training.);

            encoder.OnMesgDefinition(new MesgDefinition(activityMesg));
            encoder.OnMesg(activityMesg);
            Utils.LogMessage(LogType.Information, "Wrote ActivityMesg");

            // Update header datasize and file CRC
            encoder.Close();
            fitDest.Close();

            Console.WriteLine("Encoded FIT file " + outputFileName + ".fit");
        }
Exemple #16
0
        /// <summary>
        /// Writes the data to a FIT file.
        /// </summary>
        /// <param name="fileName">Name of the FIT file to write to.</param>
        /// <param name="start">Start date/time of the activity.</param>
        /// <param name="laps">Lap and record data to be written.</param>
        /// <param name="calories">Calories used for the activity.</param>
        /// <param name="work">Work done for the activity.</param>
        static void WriteFitFile(string fileName, System.DateTime start, LapsList laps, int calories, uint work)
        {
            // open the encoder and stream
            Encode     encoder   = new Encode(ProtocolVersion.V20);
            FileStream fitStream = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite, FileShare.Read);

            encoder.Open(fitStream);

            // write the file ID message
            FileIdMesg fileIdMsg = new FileIdMesg();

            fileIdMsg.SetType(Dynastream.Fit.File.Activity);
            fileIdMsg.SetManufacturer(Manufacturer.StagesCycling);
            fileIdMsg.SetProduct(3);
            fileIdMsg.SetSerialNumber(1);
            fileIdMsg.SetTimeCreated(new Dynastream.Fit.DateTime(start));
            encoder.Write(fileIdMsg);

            // write the record and lap messages
            foreach (Lap lap in laps)
            {
                // write the record messages
                foreach (Record record in lap.Records)
                {
                    RecordMesg recordMsg = new RecordMesg();
                    recordMsg.SetTimestamp(new Dynastream.Fit.DateTime(record.Time.ToUniversalTime()));
                    recordMsg.SetHeartRate((byte)record.HeartRate);
                    recordMsg.SetCadence((byte)record.Cadence);
                    recordMsg.SetDistance((float)record.Distance * 1000);
                    recordMsg.SetSpeed((float)(record.Speed / 3.6));
                    recordMsg.SetPower((ushort)record.Power);
                    encoder.Write(recordMsg);
                }

                // write the lap message
                Record   first  = lap.Records[0];
                Record   last   = lap.Records[lap.Records.Count - 1];
                TimeSpan time   = last.Time - first.Time;
                LapMesg  lapMsg = new LapMesg();
                lapMsg.SetTimestamp(new Dynastream.Fit.DateTime(last.Time.ToUniversalTime()));
                lapMsg.SetStartTime(new Dynastream.Fit.DateTime(first.Time.ToUniversalTime()));
                lapMsg.SetTotalElapsedTime((int)time.TotalSeconds);
                lapMsg.SetTotalTimerTime((int)time.TotalSeconds);
                lapMsg.SetTotalDistance((float)(last.Distance - first.Distance) * 1000);
                lapMsg.SetTotalCalories((ushort)lap.Calories);
                lapMsg.SetTotalWork(lap.Work * 1000);
                lapMsg.SetEvent(Event.Lap);
                lapMsg.SetEventType(EventType.Stop);
                lapMsg.SetIntensity(Intensity.Active);
                lapMsg.SetLapTrigger(LapTrigger.Manual);
                lapMsg.SetSport(Sport.Cycling);
                Summary lapSummary = GetLapSummary(lap);
                lapMsg.SetAvgCadence((byte)lapSummary.AveCadence);
                lapMsg.SetMaxCadence((byte)lapSummary.MaxCadence);
                lapMsg.SetAvgHeartRate((byte)lapSummary.AveHeartRate);
                lapMsg.SetMaxHeartRate((byte)lapSummary.MaxHeartRate);
                lapMsg.SetAvgPower((ushort)lapSummary.AvePower);
                lapMsg.SetMaxPower((ushort)lapSummary.MaxPower);
                lapMsg.SetAvgSpeed((float)lapSummary.AveSpeed / 3.6f);
                lapMsg.SetMaxSpeed((float)lapSummary.MaxSpeed / 3.6f);
                encoder.Write(lapMsg);
            }

            // get the first and last records
            Record   firstRecord = laps[0].Records[0];
            Lap      lastLap     = laps[laps.Count - 1];
            Record   lastRecord  = lastLap.Records[lastLap.Records.Count - 1];
            TimeSpan totalTime   = lastRecord.Time - firstRecord.Time;

            // write the session message
            SessionMesg sessionMsg = new SessionMesg();

            sessionMsg.SetTimestamp(new Dynastream.Fit.DateTime(lastRecord.Time.ToUniversalTime()));
            sessionMsg.SetStartTime(new Dynastream.Fit.DateTime(firstRecord.Time.ToUniversalTime()));
            sessionMsg.SetTotalElapsedTime((int)totalTime.TotalSeconds);
            sessionMsg.SetTotalTimerTime((int)totalTime.TotalSeconds);
            sessionMsg.SetTotalDistance((float)(lastRecord.Distance - firstRecord.Distance) * 1000);
            sessionMsg.SetTotalCalories((ushort)calories);
            sessionMsg.SetTotalWork(work * 1000);
            sessionMsg.SetFirstLapIndex(0);
            sessionMsg.SetNumLaps((ushort)laps.Count);
            sessionMsg.SetEvent(Event.Session);
            sessionMsg.SetEventType(EventType.Stop);
            sessionMsg.SetSport(Sport.Cycling);
            sessionMsg.SetSubSport(SubSport.Spin);
            Summary sessionSummary = GetSessionSummary(laps);

            sessionMsg.SetAvgCadence((byte)sessionSummary.AveCadence);
            sessionMsg.SetMaxCadence((byte)sessionSummary.MaxCadence);
            sessionMsg.SetAvgHeartRate((byte)sessionSummary.AveHeartRate);
            sessionMsg.SetMaxHeartRate((byte)sessionSummary.MaxHeartRate);
            sessionMsg.SetAvgPower((ushort)sessionSummary.AvePower);
            sessionMsg.SetMaxPower((ushort)sessionSummary.MaxPower);
            sessionMsg.SetAvgSpeed((float)sessionSummary.AveSpeed / 3.6f);
            sessionMsg.SetMaxSpeed((float)sessionSummary.MaxSpeed / 3.6f);
            encoder.Write(sessionMsg);

            // write the activity message
            ActivityMesg activityMsg = new ActivityMesg();

            activityMsg.SetTimestamp(new Dynastream.Fit.DateTime(lastRecord.Time.ToUniversalTime()));
            activityMsg.SetTotalTimerTime((int)totalTime.TotalSeconds);
            activityMsg.SetNumSessions(1);
            activityMsg.SetType(Activity.Manual);
            activityMsg.SetEvent(Event.Activity);
            activityMsg.SetEventType(EventType.Stop);
            encoder.Write(activityMsg);

            // close the encoder and stream
            encoder.Close();
            fitStream.Close();
        }
        /// <summary>
        /// Demonstrates encoding a 'MonitoringB File' of a made up device which counts steps and reports the battery status of the device.
        /// </summary>
        static void EncodeMonitoringFile()
        {
            System.DateTime systemStartTime = System.DateTime.Now;
            System.DateTime systemTimeNow   = systemStartTime;

            FileStream fitDest = new FileStream("ExampleMonitoringFile.fit", FileMode.Create, FileAccess.ReadWrite, FileShare.Read);

            // Create file encode object
            Encode encodeDemo = new Encode(ProtocolVersion.V10);

            // Write our header
            encodeDemo.Open(fitDest);

            // Generate some FIT messages
            FileIdMesg fileIdMesg = new FileIdMesg(); // Every FIT file MUST contain a 'File ID' message as the first message

            fileIdMesg.SetTimeCreated(new Dynastream.Fit.DateTime(systemTimeNow));
            fileIdMesg.SetManufacturer(Manufacturer.Development);
            fileIdMesg.SetProduct(1);
            fileIdMesg.SetSerialNumber(12345);
            fileIdMesg.SetNumber(0);
            fileIdMesg.SetType(Dynastream.Fit.File.MonitoringB); // See the 'FIT FIle Types Description' document for more information about this file type.
            encodeDemo.Write(fileIdMesg);                        // Write the 'File ID Message'

            DeviceInfoMesg deviceInfoMesg = new DeviceInfoMesg();

            deviceInfoMesg.SetTimestamp(new Dynastream.Fit.DateTime(systemTimeNow));
            deviceInfoMesg.SetSerialNumber(12345);
            deviceInfoMesg.SetManufacturer(Manufacturer.Development);
            deviceInfoMesg.SetBatteryStatus(Dynastream.Fit.BatteryStatus.Good);
            encodeDemo.Write(deviceInfoMesg);

            MonitoringMesg monitoringMesg = new MonitoringMesg();

            // By default, each time a new message is written the Local Message Type 0 will be redefined to match the new message.
            // In this case,to avoid having a definition message each time there is a DeviceInfoMesg, we can manually set the Local Message Type of the MonitoringMessage to '1'.
            // By doing this we avoid an additional 7 definition messages in our FIT file.
            monitoringMesg.LocalNum = 1;

            // Simulate some data
            Random numberOfCycles = new Random(); // Fake a number of cycles

            for (int i = 0; i < 4; i++)           // Each of these loops represent a quarter of a day
            {
                for (int j = 0; j < 6; j++)       // Each of these loops represent 1 hour
                {
                    monitoringMesg.SetTimestamp(new Dynastream.Fit.DateTime(systemTimeNow));
                    monitoringMesg.SetActivityType(Dynastream.Fit.ActivityType.Walking);                 // Setting this to walking will cause Cycles to be interpretted as steps.
                    monitoringMesg.SetCycles(monitoringMesg.GetCycles() + numberOfCycles.Next(0, 1000)); // Cycles are accumulated (i.e. must be increasing)
                    encodeDemo.Write(monitoringMesg);
                    systemTimeNow = systemTimeNow.AddHours(1);                                           // Add an hour to our contrieved timestamp
                }

                deviceInfoMesg.SetTimestamp(new Dynastream.Fit.DateTime(systemTimeNow));
                deviceInfoMesg.SetBatteryStatus(Dynastream.Fit.BatteryStatus.Good); // Report the battery status every quarter day
                encodeDemo.Write(deviceInfoMesg);
            }

            // Update header datasize and file CRC
            encodeDemo.Close();
            fitDest.Close();

            Console.WriteLine("Encoded FIT file ExampleMonitoringFile.fit");
        }
Exemple #18
0
        public void Foo()
        {
            using (var fitDest = new FileStream("Test.fit", FileMode.Create, FileAccess.ReadWrite, FileShare.Read))
            {
                Encoder = new Encode();
                // Write our header
                Encoder.Open(fitDest);

                Stopwatch stopwatch = new Stopwatch();
                stopwatch.Start();

                logger.Trace("FIT Decode Example Application");

                //if (args.Length != 1)
                //{
                //   logger.Trace("Usage: decode.exe <filename>");
                //   return;
                //}

                // Attempt to open .FIT file
                var fileName = "B1.fit";
                fitSource = new FileStream(fileName, FileMode.Open);
                logger.Trace("Opening {0}", fileName);

                Decode          decodeDemo      = new Decode();
                MesgBroadcaster mesgBroadcaster = new MesgBroadcaster();

                // Connect the Broadcaster to our event (message) source (in this case the Decoder)
                decodeDemo.MesgEvent           += mesgBroadcaster.OnMesg;
                decodeDemo.MesgDefinitionEvent += mesgBroadcaster.OnMesgDefinition;

                // Subscribe to message events of interest by connecting to the Broadcaster
                mesgBroadcaster.MesgEvent           += new MesgEventHandler(OnMesg);
                mesgBroadcaster.MesgDefinitionEvent += new MesgDefinitionEventHandler(OnMesgDefn);

                mesgBroadcaster.FileIdMesgEvent      += new MesgEventHandler(OnFileIDMesg);
                mesgBroadcaster.UserProfileMesgEvent += new MesgEventHandler(OnUserProfileMesg);

                bool status = decodeDemo.IsFIT(fitSource);
                status &= decodeDemo.CheckIntegrity(fitSource);
                // Process the file
                if (status == true)
                {
                    logger.Trace("Decoding...");
                    decodeDemo.Read(fitSource);
                    logger.Trace("Decoded FIT file {0}", fileName);
                }
                else
                {
                    try
                    {
                        logger.Trace("Integrity Check Failed {0}", fileName);
                        logger.Trace("Attempting to decode...");
                        decodeDemo.Read(fitSource);
                    }
                    catch (FitException ex)
                    {
                        logger.Trace("DecodeDemo caught FitException: " + ex.Message);
                    }
                }
                fitSource.Close();

                Encoder.Close();

                logger.Trace("");
                logger.Trace("Summary:");
                int totalMesgs = 0;
                foreach (KeyValuePair <ushort, int> pair in mesgCounts)
                {
                    logger.Trace("MesgID {0,3} Count {1}", pair.Key, pair.Value);
                    totalMesgs += pair.Value;
                }

                logger.Trace("{0} Message Types {1} Total Messages", mesgCounts.Count, totalMesgs);

                stopwatch.Stop();
                logger.Trace("");
                logger.Trace("Time elapsed: {0:0.#}s", stopwatch.Elapsed.TotalSeconds);
            }

            Console.ReadKey();
        }
Exemple #19
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}");
        }
Exemple #20
0
        static void RunOptionsAndReturnExitCode(Options opts)
        {
            options = opts;

            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();

            Console.WriteLine("FIT Decode Example Application");

            try
            {
                fitDest = new FileStream(options.OutFile, FileMode.Create, FileAccess.ReadWrite, FileShare.Read);
                Console.WriteLine("Opening Destintion {0}", options.OutFile);
                // Write our header
                encodeDemo.Open(fitDest);

                // Attempt to open .FIT file
                fitSource = new FileStream(options.InFile, FileMode.Open);
                Console.WriteLine("Opening Source {0}", options.InFile);

                Decode          decodeDemo      = new Decode();
                MesgBroadcaster mesgBroadcaster = new MesgBroadcaster();

                // Connect the Broadcaster to our event (message) source (in this case the Decoder)
                decodeDemo.MesgEvent           += mesgBroadcaster.OnMesg;
                decodeDemo.MesgDefinitionEvent += mesgBroadcaster.OnMesgDefinition;
                //decodeDemo.DeveloperFieldDescriptionEvent += OnDeveloperFieldDescriptionEvent;

                // Subscribe to message events of interest by connecting to the Broadcaster
                mesgBroadcaster.MesgEvent           += OnMesg;
                mesgBroadcaster.MesgDefinitionEvent += OnMesgDefn;

                mesgBroadcaster.FileIdMesgEvent      += OnFileIDMesg;
                mesgBroadcaster.UserProfileMesgEvent += OnUserProfileMesg;
                mesgBroadcaster.MonitoringMesgEvent  += OnMonitoringMessage;
                mesgBroadcaster.DeviceInfoMesgEvent  += OnDeviceInfoMessage;
                mesgBroadcaster.RecordMesgEvent      += OnRecordMessage;

                bool status = decodeDemo.IsFIT(fitSource);
                status &= decodeDemo.CheckIntegrity(fitSource);

                // Process the file
                if (status)
                {
                    Console.WriteLine("Translating...");
                    decodeDemo.Read(fitSource);
                    Console.WriteLine("Translated FIT file {0}", options.InFile);
                }
                else
                {
                    try
                    {
                        Console.WriteLine("Integrity Check Failed {0}", options.InFile);
                        if (decodeDemo.InvalidDataSize)
                        {
                            Console.WriteLine("Invalid Size Detected, Attempting to decode...");
                            decodeDemo.Read(fitSource);
                        }
                        else
                        {
                            Console.WriteLine("Attempting to decode by skipping the header...");
                            decodeDemo.Read(fitSource, DecodeMode.InvalidHeader);
                        }
                    }
                    catch (FitException ex)
                    {
                        Console.WriteLine("Translate caught FitException: " + ex.Message);
                    }
                }
                fitSource.Close();

                // Update header datasize and file CRC
                encodeDemo.Close();
                fitDest.Close();

                Console.WriteLine("");
                Console.WriteLine("Summary:");
                int totalMesgs = 0;
                foreach (KeyValuePair <ushort, int> pair in mesgCounts)
                {
                    Console.WriteLine("MesgID {0,3} Count {1}", pair.Key, pair.Value);
                    totalMesgs += pair.Value;
                }

                Console.WriteLine("{0} Message Types {1} Total Messages", mesgCounts.Count, totalMesgs);

                stopwatch.Stop();
                Console.WriteLine("");
                Console.WriteLine("Time elapsed: {0:0.#}s", stopwatch.Elapsed.TotalSeconds);
                Console.ReadKey();
            }
            catch (FitException ex)
            {
                Console.WriteLine("A FitException occurred when trying to decode the FIT file. Message: " + ex.Message);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception occurred when trying to decode the FIT file. Message: " + ex.Message);
            }
        }
        static void EncodeActivityFile()
        {
            // Generate some FIT messages
            var fileIdMesg      = new FileIdMesg(); // Every FIT file MUST contain a 'File ID' message as the first message
            var developerIdMesg = new DeveloperDataIdMesg();
            var fieldDescMesg   = new FieldDescriptionMesg();

            var records = new List <RecordMesg>();

            byte[] appId =
            {
                1,   2,  3,  4,
                5,   6,  7,  8,
                9,  10, 11, 12,
                13, 14, 15, 16
            };

            fileIdMesg.SetType(Dynastream.Fit.File.Activity);
            fileIdMesg.SetManufacturer(Manufacturer.Development);
            fileIdMesg.SetProduct(1);
            fileIdMesg.SetSerialNumber(12345);
            fileIdMesg.SetTimeCreated(new DateTime(621463080));

            for (int i = 0; i < appId.Length; i++)
            {
                developerIdMesg.SetApplicationId(i, appId[i]);
            }
            developerIdMesg.SetDeveloperDataIndex(0);

            fieldDescMesg.SetDeveloperDataIndex(0);
            fieldDescMesg.SetFieldDefinitionNumber(0);
            fieldDescMesg.SetFitBaseTypeId(FitBaseType.Sint8);
            fieldDescMesg.SetFieldName(0, "doughnuts_earned");
            fieldDescMesg.SetUnits(0, "doughnuts");

            for (int i = 0; i < 3; i++)
            {
                var newRecord            = new RecordMesg();
                var doughnutsEarnedField = new DeveloperField(fieldDescMesg, developerIdMesg);
                newRecord.SetDeveloperField(doughnutsEarnedField);

                newRecord.SetHeartRate((byte)(140 + (i * 2)));
                newRecord.SetCadence((byte)(88 + (i * 2)));
                newRecord.SetDistance(510 + (i * 100));
                newRecord.SetSpeed(2.8f + (i * 0.4f));
                doughnutsEarnedField.SetValue(i + 1);

                records.Add(newRecord);
            }

            // Create file encode object
            Encode encodeDemo = new Encode(ProtocolVersion.V20);

            FileStream fitDest = new FileStream("ExampleActivity.fit", FileMode.Create, FileAccess.ReadWrite, FileShare.Read);

            // Write our header
            encodeDemo.Open(fitDest);

            // Encode each message, a definition message is automatically generated and output if necessary
            encodeDemo.Write(fileIdMesg);
            encodeDemo.Write(developerIdMesg);
            encodeDemo.Write(fieldDescMesg);
            encodeDemo.Write(records);

            // Update header datasize and file CRC
            encodeDemo.Close();
            fitDest.Close();

            Console.WriteLine("Encoded FIT file ExampleActivity.fit");
        }
Exemple #22
0
        void BtnSaveFitClick(object sender, EventArgs e)
        {
            if (saveFileDlg.ShowDialog() == DialogResult.OK)
            {
                FileIdMesg fileIdMesg = new FileIdMesg();
                fileIdMesg.SetManufacturer(Manufacturer.Dynastream);
                fileIdMesg.SetProduct(1000);
                fileIdMesg.SetSerialNumber(12345);

                FileStream fitDest = new FileStream(saveFileDlg.FileName, FileMode.Create, FileAccess.ReadWrite, FileShare.Read);

                // create file encode object
                Encode encode = new Encode();
                // write out header
                encode.Open(fitDest);
                // encode each message, a definition message is automatically generated and output if necessary
                encode.Write(fileIdMesg);

                SQLiteCommand cmd = new SQLiteCommand(_db);
                string        sql;
                // TODO: write FIT File Summary Information here, suspect that's why GarminConnect
                // is rejecting it because the summary data isn't there.
                sql             = string.Format("select fs.*, f.fileActivityDateTime from FileSummary fs join File f on f.idFile = fs.idFile where fs.idFile = {0}", _file);
                cmd.CommandText = sql;
                SQLiteDataReader rdr_summary = cmd.ExecuteReader();
                if (rdr_summary.HasRows)
                {
                    rdr_summary.Read();
                    SessionMesg sess = new SessionMesg();
                    //"fsMaxHeartRate" INTEGER,"fsMaxCadence" INTEGER,"fsMaxSpeed" FLOAT, "fsAvgPower" FLOAT, "fsMaxPower" FLOAT)
                    sess.SetTotalElapsedTime((float)Convert.ToDouble(rdr_summary["fsDuration"]));
                    sess.SetTotalMovingTime((float)Convert.ToDouble(rdr_summary["fsMovingTime"]));
                    sess.SetTotalTimerTime((float)Convert.ToDouble(rdr_summary["fsMovingTime"]));
                    sess.SetTotalDistance((float)(Convert.ToDouble(rdr_summary["fsDistance"]) * 1609.344));                     // convert miles back to metres
                    sess.SetTotalCalories(Convert.ToUInt16(rdr_summary["fsCalories"]));
                    sess.SetAvgHeartRate(Convert.ToByte(Convert.ToInt32(rdr_summary["fsAvgHeart"])));
                    sess.SetAvgCadence(Convert.ToByte(Convert.ToInt32(rdr_summary["fsAvgCadence"])));
                    sess.SetAvgSpeed((float)(Convert.ToDouble(rdr_summary["fsAvgSpeed"]) / 2.23693629));
                    sess.SetTotalAscent(Convert.ToUInt16(Convert.ToDouble(rdr_summary["fsTotalAscent"]) / 3.2808399));
                    sess.SetTotalDescent(Convert.ToUInt16(Convert.ToDouble(rdr_summary["fsTotalDescent"]) / 3.2808399));
                    sess.SetMaxHeartRate(Convert.ToByte(Convert.ToInt32(rdr_summary["fsMaxHeartRate"])));
                    sess.SetMaxCadence(Convert.ToByte(Convert.ToInt32(rdr_summary["fsMaxCadence"])));
                    sess.SetMaxSpeed(Convert.ToByte(Convert.ToInt32(rdr_summary["fsMaxSpeed"]) / 2.23693629));

                    Dynastream.Fit.DateTime dt_start = new Dynastream.Fit.DateTime(Convert.ToDateTime(rdr_summary["fileActivityDateTime"]));
                    sess.SetStartTime(dt_start);
                    encode.Write(sess);
                }
                rdr_summary.Close();

                // load and process the archived trackpoints for file

                sql             = string.Format("select * from FileTrackpoints where idFile = {0}", _file);
                cmd.CommandText = sql;
                SQLiteDataReader rdr = cmd.ExecuteReader();
                if (rdr.HasRows)
                {
                    while (rdr.Read())
                    {
                        // TODO: need to handle `0` lng/lat coordinates so that we're not mapped
                        // as being in the middle of the atlantic ! :-)
                        RecordMesg rec             = new RecordMesg();
                        Dynastream.Fit.DateTime dt = new Dynastream.Fit.DateTime(System.DateTime.Parse((string)rdr["tpTime"]));
                        rec.SetTimestamp(dt);
                        rec.SetDistance((float)Convert.ToDouble(rdr["tpDistance"]));
                        rec.SetHeartRate(Convert.ToByte(Convert.ToInt32(rdr["tpHeart"])));
                        rec.SetCadence(Convert.ToByte(Convert.ToInt32(rdr["tpCadence"])));
                        rec.SetTemperature(Convert.ToSByte(Convert.ToInt32(rdr["tpTemperature"])));
                        rec.SetAltitude((float)(Convert.ToDouble(rdr["tpAltitude"]) / 3.2808399));                         // converted back to metres from ft in db
                        rec.SetPositionLong((int)GeoMath.degrees_to_semicircle(Convert.ToDouble(rdr["tpLongitude"])));
                        rec.SetPositionLat((int)GeoMath.degrees_to_semicircle(Convert.ToDouble(rdr["tpLatitude"])));
                        rec.SetSpeed((float)Convert.ToDouble(rdr["tpSpeed"]));
                        encode.Write(rec);
                    }
                }

                encode.Close();
                fitDest.Close();

                MessageBox.Show("File Saved Successfully");

                System.Diagnostics.Process.Start(saveFileDlg.FileName);
            }
            else
            {
            }
        }