public static void ExportSchedulesFITFile(Stream exportStream, MemoryStream dataStream) { MemoryStream tempDataStream = new MemoryStream(); // Reserve size for header tempDataStream.Write(new Byte[12], 0, 12); // File id message FITMessage fileIdMessage = new FITMessage(FITGlobalMessageIds.FileId); FITMessageField fileType = new FITMessageField((Byte)FITFileIdFieldsIds.FileType); FITMessageField manufacturerId = new FITMessageField((Byte)FITFileIdFieldsIds.ManufacturerId); FITMessageField productId = new FITMessageField((Byte)FITFileIdFieldsIds.ProductId); FITMessageField serialNumber = new FITMessageField((Byte)FITFileIdFieldsIds.SerialNumber); FITMessageField exportDate = new FITMessageField((Byte)FITFileIdFieldsIds.ExportDate); FITMessageField number = new FITMessageField((Byte)FITFileIdFieldsIds.Number); manufacturerId.SetUInt16(1); fileType.SetEnum((Byte)FITFileTypes.Schedules); // Invalid fields productId.SetUInt16(0xFFFF); serialNumber.SetUInt32z(0); exportDate.SetUInt32(0xFFFFFFFF); number.SetUInt16(0xFFFF); fileIdMessage.AddField(serialNumber); fileIdMessage.AddField(exportDate); fileIdMessage.AddField(manufacturerId); fileIdMessage.AddField(productId); fileIdMessage.AddField(number); fileIdMessage.AddField(fileType); fileIdMessage.Serialize(tempDataStream); // Write all passed in data to output stream tempDataStream.Write(dataStream.GetBuffer(), 0, (int)dataStream.Length); // Write FIT header at the start of the stream GarminFitnessByteRange headerSize = new GarminFitnessByteRange(12); GarminFitnessByteRange protocolVersion = new GarminFitnessByteRange((Byte)((FITConstants.FITProtocolMajorVersion << 4) | FITConstants.FITProtocolMinorVersion)); GarminFitnessUInt16Range profileVersion = new GarminFitnessUInt16Range((UInt16)((FITConstants.FITProfileMajorVersion * FITConstants.FITProfileMajorVersionMultiplier) + FITConstants.FITProfileMinorVersion)); GarminFitnessInt32Range dataSize = new GarminFitnessInt32Range(0); tempDataStream.Seek(0, SeekOrigin.Begin); dataSize.Value = (int)tempDataStream.Length - 12; headerSize.Serialize(tempDataStream); protocolVersion.Serialize(tempDataStream); profileVersion.Serialize(tempDataStream); dataSize.Serialize(tempDataStream); tempDataStream.Write(Encoding.UTF8.GetBytes(FITConstants.FITFileDescriptor), 0, 4); // Write CRC GarminFitnessUInt16Range crc = new GarminFitnessUInt16Range(FITUtils.ComputeStreamCRC(tempDataStream)); tempDataStream.Seek(0, SeekOrigin.End); crc.Serialize(tempDataStream); // Write all data to output stream exportStream.Write(tempDataStream.GetBuffer(), 0, (int)tempDataStream.Length); }
public virtual void FillFITMessageForScheduledDate(FITMessage scheduleMessage, DateTime scheduledDate) { FITMessageField workoutManufacturer = new FITMessageField((Byte)FITScheduleFieldIds.WorkoutManufacturer); FITMessageField workoutProduct = new FITMessageField((Byte)FITScheduleFieldIds.WorkoutProduct); FITMessageField workoutSN = new FITMessageField((Byte)FITScheduleFieldIds.WorkoutSN); FITMessageField scheduleType = new FITMessageField((Byte)FITScheduleFieldIds.ScheduleType); FITMessageField workoutCompleted = new FITMessageField((Byte)FITScheduleFieldIds.WorkoutCompleted); FITMessageField workoutId = new FITMessageField((Byte)FITScheduleFieldIds.WorkoutId); FITMessageField scheduledField = new FITMessageField((Byte)FITScheduleFieldIds.ScheduledDate); DateTime midDaySchedule = new DateTime(scheduledDate.Date.Year, scheduledDate.Date.Month, scheduledDate.Day, 12, 0, 0); TimeSpan timeSinceReference = midDaySchedule - new DateTime(1989, 12, 31); // Hardcoded fields from the schedule file workoutManufacturer.SetUInt16(1); // Always 1 workoutProduct.SetUInt16(20119); // Always 20119 workoutSN.SetUInt32z(0); // Invalid workoutCompleted.SetEnum((Byte)0xFF); // Invalid/Not completed // Real data scheduleType.SetEnum((Byte)FITScheduleType.Workout); workoutId.SetUInt32(CreationTimestamp); scheduleMessage.AddField(workoutSN); scheduleMessage.AddField(workoutId); scheduleMessage.AddField(scheduledField); scheduleMessage.AddField(workoutManufacturer); scheduleMessage.AddField(workoutProduct); scheduleMessage.AddField(workoutCompleted); scheduleMessage.AddField(scheduleType); scheduledField.SetUInt32((UInt32)timeSinceReference.TotalSeconds); }
public void TestFITScheduleDeserialization() { FITMessage serializedMessage = new FITMessage(FITGlobalMessageIds.WorkoutSchedules); FITMessageField dateField = new FITMessageField((Byte)FITScheduleFieldIds.ScheduledDate); DateTime referenceDate = new DateTime(1989, 12, 31); DateTime resultDate; serializedMessage.AddField(dateField); DateTime currentDate = DateTime.Today; dateField.SetUInt32((UInt32)(currentDate - referenceDate).TotalSeconds); resultDate = WorkoutImporter.ImportWorkoutScheduleMessage(serializedMessage); Assert.AreEqual(currentDate, resultDate, "Deserialized date invalid for FIT format"); currentDate = currentDate.AddDays(1); dateField.SetUInt32((UInt32)(currentDate - referenceDate).TotalSeconds); resultDate = WorkoutImporter.ImportWorkoutScheduleMessage(serializedMessage); Assert.AreEqual(currentDate, resultDate, "Deserialized date invalid for FIT format"); dateField.SetUInt32(315576000); resultDate = WorkoutImporter.ImportWorkoutScheduleMessage(serializedMessage); Assert.AreEqual(new DateTime(1999, 12, 31, 12, 0, 0), resultDate, "Deserialized date invalid for FIT format"); // New Zealand time (UST+12H) is a case where we had problems because the offset changes the day String currentZoneName = Time.CurrentTimeZone.standardName; bool res = Time.SetTimeZone("New Zealand Standard Time"); dateField.SetUInt32(315576000); resultDate = WorkoutImporter.ImportWorkoutScheduleMessage(serializedMessage); res = Time.SetTimeZone(currentZoneName); Assert.AreEqual(new DateTime(1999, 12, 31, 12, 0, 0), resultDate, "Deserialized date invalid for FIT format"); }
public static void ExportWorkoutToFIT(IWorkout workout, Stream exportStream, bool updateExportDate) { MemoryStream dataStream = new MemoryStream(); // Reserve size for header dataStream.Write(new Byte[12], 0, 12); // File id message FITMessage fileIdMessage = new FITMessage(FITGlobalMessageIds.FileId); FITMessageField fileType = new FITMessageField((Byte)FITFileIdFieldsIds.FileType); FITMessageField manufacturerId = new FITMessageField((Byte)FITFileIdFieldsIds.ManufacturerId); FITMessageField productId = new FITMessageField((Byte)FITFileIdFieldsIds.ProductId); FITMessageField serialNumber = new FITMessageField((Byte)FITFileIdFieldsIds.SerialNumber); FITMessageField exportDate = new FITMessageField((Byte)FITFileIdFieldsIds.ExportDate); FITMessageField number = new FITMessageField((Byte)FITFileIdFieldsIds.Number); fileType.SetEnum((Byte)FITFileTypes.Workout); manufacturerId.SetUInt16(1); productId.SetUInt16(20119); serialNumber.SetUInt32z(0); exportDate.SetUInt32(workout.CreationTimestamp); number.SetUInt16(0xFFFF); fileIdMessage.AddField(serialNumber); fileIdMessage.AddField(exportDate); fileIdMessage.AddField(manufacturerId); fileIdMessage.AddField(productId); fileIdMessage.AddField(number); fileIdMessage.AddField(fileType); fileIdMessage.Serialize(dataStream); // File creator message FITMessage fileCreatorMessage = new FITMessage(FITGlobalMessageIds.FileCreator); FITMessageField software = new FITMessageField((Byte)FITFileCreatorFieldsIds.SoftwareVersion); FITMessageField hardware = new FITMessageField((Byte)FITFileCreatorFieldsIds.HardwareVersion); software.SetUInt16(3605); hardware.SetUInt8(0); fileCreatorMessage.AddField(software); fileCreatorMessage.AddField(hardware); fileCreatorMessage.Serialize(dataStream); // Write workout workout.SerializeToFIT(dataStream); // Write FIT header at the start of the stream GarminFitnessByteRange headerSize = new GarminFitnessByteRange(12); GarminFitnessByteRange protocolVersion = new GarminFitnessByteRange((Byte)((FITConstants.FITProtocolMajorVersion << 4) | FITConstants.FITProtocolMinorVersion)); GarminFitnessUInt16Range profileVersion = new GarminFitnessUInt16Range((UInt16)((FITConstants.FITProfileMajorVersion * FITConstants.FITProfileMajorVersionMultiplier) + FITConstants.FITProfileMinorVersion)); GarminFitnessInt32Range dataSize = new GarminFitnessInt32Range(0); dataStream.Seek(0, SeekOrigin.Begin); dataSize.Value = (int)dataStream.Length - 12; headerSize.Serialize(dataStream); protocolVersion.Serialize(dataStream); profileVersion.Serialize(dataStream); dataSize.Serialize(dataStream); dataStream.Write(Encoding.UTF8.GetBytes(FITConstants.FITFileDescriptor), 0, 4); // Write CRC GarminFitnessUInt16Range crc = new GarminFitnessUInt16Range(FITUtils.ComputeStreamCRC(dataStream)); dataStream.Seek(0, SeekOrigin.End); crc.Serialize(dataStream); // Write all data to output stream exportStream.Write(dataStream.GetBuffer(), 0, (int)dataStream.Length); if (updateExportDate) { workout.LastExportDate = DateTime.Now; } }
public void TestFITDeserialization() { Workout placeholderWorkout = new Workout("Test", PluginMain.GetApplication().Logbook.ActivityCategories[0]); RepeatStep placeholderStep = new RepeatStep(placeholderWorkout); FITMessage serializedMessage = new FITMessage(FITGlobalMessageIds.WorkoutStep); FITMessageField typeField = new FITMessageField((Byte)FITWorkoutStepFieldIds.DurationType); FITMessageField valueField = new FITMessageField((Byte)FITWorkoutStepFieldIds.TargetValue); IRepeatDuration deserializedDuration; serializedMessage.AddField(typeField); serializedMessage.AddField(valueField); // Repeat count typeField.SetEnum((Byte)FITWorkoutStepDurationTypes.RepeatCount); valueField.SetUInt32(6); deserializedDuration = DurationFactory.Create(serializedMessage, placeholderStep); Assert.IsTrue(deserializedDuration is RepeatCountDuration, "Repeat count duration not properly FIT deserialized"); RepeatCountDuration repeatDuration = deserializedDuration as RepeatCountDuration; Assert.AreEqual(6, repeatDuration.RepetitionCount, "Invalid value deserialized for FIT repeat count duration"); valueField.SetUInt32(2); deserializedDuration = DurationFactory.Create(serializedMessage, placeholderStep); Assert.IsTrue(deserializedDuration is RepeatCountDuration, "Repeat count duration not properly FIT deserialized"); repeatDuration = deserializedDuration as RepeatCountDuration; Assert.AreEqual(2, repeatDuration.RepetitionCount, "Invalid value deserialized for FIT repeat count duration"); // Repeat until calories typeField.SetEnum((Byte)FITWorkoutStepDurationTypes.RepeatUntilCalories); valueField.SetUInt32(666); deserializedDuration = DurationFactory.Create(serializedMessage, placeholderStep); Assert.IsTrue(deserializedDuration is RepeatUntilCaloriesDuration, "Repeat until calories duration not properly FIT deserialized"); RepeatUntilCaloriesDuration caloriesDuration = deserializedDuration as RepeatUntilCaloriesDuration; Assert.AreEqual(666, caloriesDuration.CaloriesToSpend, "Invalid value deserialized for FIT repeat until calories duration"); valueField.SetUInt32(150); deserializedDuration = DurationFactory.Create(serializedMessage, placeholderStep); Assert.IsTrue(deserializedDuration is RepeatUntilCaloriesDuration, "Repeat until calories duration not properly FIT deserialized"); caloriesDuration = deserializedDuration as RepeatUntilCaloriesDuration; Assert.AreEqual(150, caloriesDuration.CaloriesToSpend, "Invalid value deserialized for FIT repeat until calories duration"); // Repeat until distance typeField.SetEnum((Byte)FITWorkoutStepDurationTypes.RepeatUntilDistance); valueField.SetUInt32(100000); deserializedDuration = DurationFactory.Create(serializedMessage, placeholderStep); Assert.IsTrue(deserializedDuration is RepeatUntilDistanceDuration, "Repeat until distance duration not properly FIT deserialized"); RepeatUntilDistanceDuration distanceDuration = deserializedDuration as RepeatUntilDistanceDuration; Assert.AreEqual(1, Length.Convert(distanceDuration.GetDistanceInBaseUnit(), distanceDuration.BaseUnit, Length.Units.Kilometer), STCommon.Data.Constants.Delta, "Invalid value deserialized for FIT repeat until distance duration"); valueField.SetUInt32(160934); deserializedDuration = DurationFactory.Create(serializedMessage, placeholderStep); Assert.IsTrue(deserializedDuration is RepeatUntilDistanceDuration, "Repeat until distance duration not properly FIT deserialized"); distanceDuration = deserializedDuration as RepeatUntilDistanceDuration; Assert.AreEqual(1, Length.Convert(distanceDuration.GetDistanceInBaseUnit(), distanceDuration.BaseUnit, Length.Units.Mile), STCommon.Data.Constants.Delta, "Invalid value deserialized for FIT repeat until distance duration"); // Repeat until HR Above typeField.SetEnum((Byte)FITWorkoutStepDurationTypes.RepeatUntilHeartRateGreaterThan); valueField.SetUInt32(220); deserializedDuration = DurationFactory.Create(serializedMessage, placeholderStep); Assert.IsTrue(deserializedDuration is RepeatUntilHeartRateAboveDuration, "Repeat until HRAbove duration not properly FIT deserialized"); RepeatUntilHeartRateAboveDuration hrAboveDuration = deserializedDuration as RepeatUntilHeartRateAboveDuration; Assert.IsFalse(hrAboveDuration.IsPercentageMaxHeartRate, "Invalid value deserialized for FIT repeat until HRAbove duration"); Assert.AreEqual(120, hrAboveDuration.MaxHeartRate, "Invalid value deserialized for FIT repeat until HRAbove duration"); valueField.SetUInt32(80); deserializedDuration = DurationFactory.Create(serializedMessage, placeholderStep); Assert.IsTrue(deserializedDuration is RepeatUntilHeartRateAboveDuration, "Repeat until HRAbove duration not properly FIT deserialized"); hrAboveDuration = deserializedDuration as RepeatUntilHeartRateAboveDuration; Assert.IsTrue(hrAboveDuration.IsPercentageMaxHeartRate, "Invalid value deserialized for FIT repeat until HRAbove duration"); Assert.AreEqual(80, hrAboveDuration.MaxHeartRate, "Invalid value deserialized for FIT repeat until HRAbove duration"); // Repeat until HR Below typeField.SetEnum((Byte)FITWorkoutStepDurationTypes.RepeatUntilHeartRateLessThan); valueField.SetUInt32(230); deserializedDuration = DurationFactory.Create(serializedMessage, placeholderStep); Assert.IsTrue(deserializedDuration is RepeatUntilHeartRateBelowDuration, "Repeat until HRBelow duration not properly FIT deserialized"); RepeatUntilHeartRateBelowDuration hrBelowDuration = deserializedDuration as RepeatUntilHeartRateBelowDuration; Assert.IsFalse(hrBelowDuration.IsPercentageMaxHeartRate, "Invalid value deserialized for FIT repeat until HRBelow duration"); Assert.AreEqual(130, hrBelowDuration.MinHeartRate, "Invalid value deserialized for FIT repeat until HRBelow duration"); valueField.SetUInt32(65); deserializedDuration = DurationFactory.Create(serializedMessage, placeholderStep); Assert.IsTrue(deserializedDuration is RepeatUntilHeartRateBelowDuration, "Repeat until HRBelow duration not properly FIT deserialized"); hrBelowDuration = deserializedDuration as RepeatUntilHeartRateBelowDuration; Assert.IsTrue(hrBelowDuration.IsPercentageMaxHeartRate, "Invalid value deserialized for FIT repeat until HRBelow duration"); Assert.AreEqual(65, hrBelowDuration.MinHeartRate, "Invalid value deserialized for FIT repeat until HRBelow duration"); // Repeat until Power Above typeField.SetEnum((Byte)FITWorkoutStepDurationTypes.RepeatUntilPowerGreaterThan); valueField.SetUInt32(1220); deserializedDuration = DurationFactory.Create(serializedMessage, placeholderStep); Assert.IsTrue(deserializedDuration is RepeatUntilPowerAboveDuration, "Repeat until PowerAbove duration not properly FIT deserialized"); RepeatUntilPowerAboveDuration powerAboveDuration = deserializedDuration as RepeatUntilPowerAboveDuration; Assert.IsFalse(powerAboveDuration.IsPercentFTP, "Invalid value deserialized for FIT repeat until PowerAbove duration"); Assert.AreEqual(220, powerAboveDuration.MaxPower, "Invalid value deserialized for FIT repeat until PowerAbove duration"); valueField.SetUInt32(80); deserializedDuration = DurationFactory.Create(serializedMessage, placeholderStep); Assert.IsTrue(deserializedDuration is RepeatUntilPowerAboveDuration, "Repeat until PowerAbove duration not properly FIT deserialized"); powerAboveDuration = deserializedDuration as RepeatUntilPowerAboveDuration; Assert.IsTrue(powerAboveDuration.IsPercentFTP, "Invalid value deserialized for FIT repeat until PowerAbove duration"); Assert.AreEqual(80, powerAboveDuration.MaxPower, "Invalid value deserialized for FIT repeat until PowerAbove duration"); // Repeat until Power Below typeField.SetEnum((Byte)FITWorkoutStepDurationTypes.RepeatUntilPowerLessThan); valueField.SetUInt32(1400); deserializedDuration = DurationFactory.Create(serializedMessage, placeholderStep); Assert.IsTrue(deserializedDuration is RepeatUntilPowerBelowDuration, "Repeat until PowerBelow duration not properly FIT deserialized"); RepeatUntilPowerBelowDuration powerBelowDuration = deserializedDuration as RepeatUntilPowerBelowDuration; Assert.IsFalse(powerBelowDuration.IsPercentFTP, "Invalid value deserialized for FIT repeat until PowerBelow duration"); Assert.AreEqual(400, powerBelowDuration.MinPower, "Invalid value deserialized for FIT repeat until PowerBelow duration"); valueField.SetUInt32(125); deserializedDuration = DurationFactory.Create(serializedMessage, placeholderStep); Assert.IsTrue(deserializedDuration is RepeatUntilPowerBelowDuration, "Repeat until PowerBelow duration not properly FIT deserialized"); powerBelowDuration = deserializedDuration as RepeatUntilPowerBelowDuration; Assert.IsTrue(powerBelowDuration.IsPercentFTP, "Invalid value deserialized for FIT repeat until PowerBelow duration"); Assert.AreEqual(125, powerBelowDuration.MinPower, "Invalid value deserialized for FIT repeat until PowerBelow duration"); // Repeat until time typeField.SetEnum((Byte)FITWorkoutStepDurationTypes.RepeatUntilTime); valueField.SetUInt32(60000); deserializedDuration = DurationFactory.Create(serializedMessage, placeholderStep); Assert.IsTrue(deserializedDuration is RepeatUntilTimeDuration, "Repeat until time duration not properly FIT deserialized"); RepeatUntilTimeDuration timeDuration = deserializedDuration as RepeatUntilTimeDuration; Assert.AreEqual(60, timeDuration.TimeInSeconds, "Invalid value deserialized for FIT repeat until time duration"); valueField.SetUInt32(600000); deserializedDuration = DurationFactory.Create(serializedMessage, placeholderStep); Assert.IsTrue(deserializedDuration is RepeatUntilTimeDuration, "Repeat until time duration not properly FIT deserialized"); timeDuration = deserializedDuration as RepeatUntilTimeDuration; Assert.AreEqual(600, timeDuration.TimeInSeconds, "Invalid value deserialized for FIT repeat until time duration"); }
public void TestFITDeserialization() { Workout placeholderWorkout = new Workout("Test", PluginMain.GetApplication().Logbook.ActivityCategories[0]); RegularStep placeholderStep = new RegularStep(placeholderWorkout); FITMessage serializedMessage = new FITMessage(FITGlobalMessageIds.WorkoutStep); FITMessageField typeField = new FITMessageField((Byte)FITWorkoutStepFieldIds.TargetType); FITMessageField valueField = new FITMessageField((Byte)FITWorkoutStepFieldIds.TargetValue); FITMessageField lowRangeField = new FITMessageField((Byte)FITWorkoutStepFieldIds.TargetCustomValueLow); FITMessageField highRangeField = new FITMessageField((Byte)FITWorkoutStepFieldIds.TargetCustomValueHigh); ITarget loadedTarget = null; serializedMessage.AddField(typeField); // No target typeField.SetEnum((Byte)FITWorkoutStepTargetTypes.NoTarget); loadedTarget = TargetFactory.Create(serializedMessage, placeholderStep); Assert.IsTrue(loadedTarget is NullTarget, "No target not properly FIT deserialized without value fields"); serializedMessage.AddField(valueField); serializedMessage.AddField(lowRangeField); serializedMessage.AddField(highRangeField); loadedTarget = TargetFactory.Create(serializedMessage, placeholderStep); Assert.IsTrue(loadedTarget is NullTarget, "No target not properly FIT deserialized with unset value fields"); valueField.SetUInt32(1); lowRangeField.SetUInt32(1); highRangeField.SetUInt32(1); loadedTarget = TargetFactory.Create(serializedMessage, placeholderStep); Assert.IsTrue(loadedTarget is NullTarget, "No target not properly FIT deserialized with value fields"); // Cadence targets BaseCadenceTarget cadenceTarget; // Cadence range CadenceRangeTarget cadenceRangeTarget; typeField.SetEnum((Byte)FITWorkoutStepTargetTypes.Cadence); valueField.SetUInt32(0); lowRangeField.SetUInt32(80); highRangeField.SetUInt32(90); loadedTarget = TargetFactory.Create(serializedMessage, placeholderStep); Assert.IsNotNull(loadedTarget, "CadenceRange target wasn't properly deserialized"); Assert.IsTrue(loadedTarget is BaseCadenceTarget, "CadenceRange target wasn't deserialized as proper type"); cadenceTarget = loadedTarget as BaseCadenceTarget; Assert.IsTrue(cadenceTarget.ConcreteTarget is CadenceRangeTarget, "CadenceRange target wasn't deserialized as proper concrete type"); cadenceRangeTarget = cadenceTarget.ConcreteTarget as CadenceRangeTarget; Assert.AreEqual(80, cadenceRangeTarget.MinCadence, "CadenceRange min value wasn't properly deserialized"); Assert.AreEqual(90, cadenceRangeTarget.MaxCadence, "CadenceRange max value wasn't properly deserialized"); lowRangeField.SetUInt32(60); highRangeField.SetUInt32(120); loadedTarget = TargetFactory.Create(serializedMessage, placeholderStep); Assert.IsNotNull(loadedTarget, "CadenceRange target wasn't properly deserialized"); Assert.IsTrue(loadedTarget is BaseCadenceTarget, "CadenceRange target wasn't deserialized as proper type"); cadenceTarget = loadedTarget as BaseCadenceTarget; Assert.IsTrue(cadenceTarget.ConcreteTarget is CadenceRangeTarget, "CadenceRange target wasn't deserialized as proper concrete type"); cadenceRangeTarget = cadenceTarget.ConcreteTarget as CadenceRangeTarget; Assert.AreEqual(60, cadenceRangeTarget.MinCadence, "CadenceRange min value wasn't properly deserialized"); Assert.AreEqual(120, cadenceRangeTarget.MaxCadence, "CadenceRange max value wasn't properly deserialized"); // Speed targets BaseSpeedTarget speedTarget; // Speed range SpeedRangeTarget speedRangeTarget; double speed; typeField.SetEnum((Byte)FITWorkoutStepTargetTypes.Speed); valueField.SetUInt32(0); lowRangeField.SetUInt32(5555); highRangeField.SetUInt32(8333); loadedTarget = TargetFactory.Create(serializedMessage, placeholderStep); Assert.IsNotNull(loadedTarget, "SpeedRange target wasn't properly deserialized"); Assert.IsTrue(loadedTarget is BaseSpeedTarget, "SpeedRange target wasn't deserialized as proper type"); speedTarget = loadedTarget as BaseSpeedTarget; Assert.IsTrue(speedTarget.ConcreteTarget is SpeedRangeTarget, "SpeedRange target wasn't deserialized as proper concrete type"); speedRangeTarget = speedTarget.ConcreteTarget as SpeedRangeTarget; speed = Length.Convert(speedRangeTarget.GetMinSpeedInBaseUnitsPerHour(), speedRangeTarget.BaseUnit, Length.Units.Kilometer); Assert.AreEqual(20, speed, 0.01, "SpeedRange min value wasn't properly deserialized"); speed = Length.Convert(speedRangeTarget.GetMaxSpeedInBaseUnitsPerHour(), speedRangeTarget.BaseUnit, Length.Units.Kilometer); Assert.AreEqual(30, speed, 0.01, "SpeedRange max value wasn't properly deserialized"); lowRangeField.SetUInt32(1788); highRangeField.SetUInt32(3576); loadedTarget = TargetFactory.Create(serializedMessage, placeholderStep); Assert.IsNotNull(loadedTarget, "SpeedRange target wasn't properly deserialized"); Assert.IsTrue(loadedTarget is BaseSpeedTarget, "SpeedRange target wasn't deserialized as proper type"); speedTarget = loadedTarget as BaseSpeedTarget; Assert.IsTrue(speedTarget.ConcreteTarget is SpeedRangeTarget, "SpeedRange target wasn't deserialized as proper concrete type"); speedRangeTarget = speedTarget.ConcreteTarget as SpeedRangeTarget; speed = Length.Convert(speedRangeTarget.GetMinSpeedInBaseUnitsPerHour(), speedRangeTarget.BaseUnit, Length.Units.Mile); Assert.AreEqual(4, speed, 0.01, "SpeedRange min value wasn't properly deserialized"); speed = Length.Convert(speedRangeTarget.GetMaxSpeedInBaseUnitsPerHour(), speedRangeTarget.BaseUnit, Length.Units.Mile); Assert.AreEqual(8, speed, 0.01, "SpeedRange max value wasn't properly deserialized"); // Speed Garmin zone SpeedZoneGTCTarget speedGTCTarget; valueField.SetUInt32(1); loadedTarget = TargetFactory.Create(serializedMessage, placeholderStep); Assert.IsNotNull(loadedTarget, "SpeedGTC target wasn't properly deserialized"); Assert.IsTrue(loadedTarget is BaseSpeedTarget, "SpeedGTC target wasn't deserialized as proper type"); speedTarget = loadedTarget as BaseSpeedTarget; Assert.IsTrue(speedTarget.ConcreteTarget is SpeedZoneGTCTarget, "SpeedGTC target wasn't deserialized as proper concrete type"); speedGTCTarget = speedTarget.ConcreteTarget as SpeedZoneGTCTarget; Assert.AreEqual(1, speedGTCTarget.Zone, "SpeedGTC zone value wasn't properly deserialized"); valueField.SetUInt32(3); loadedTarget = TargetFactory.Create(serializedMessage, placeholderStep); Assert.IsNotNull(loadedTarget, "SpeedGTC target wasn't properly deserialized"); Assert.IsTrue(loadedTarget is BaseSpeedTarget, "SpeedGTC target wasn't deserialized as proper type"); speedTarget = loadedTarget as BaseSpeedTarget; Assert.IsTrue(speedTarget.ConcreteTarget is SpeedZoneGTCTarget, "SpeedGTC target wasn't deserialized as proper concrete type"); speedGTCTarget = speedTarget.ConcreteTarget as SpeedZoneGTCTarget; Assert.AreEqual(3, speedGTCTarget.Zone, "SpeedGTC zone value wasn't properly deserialized"); // Heart rate targets BaseHeartRateTarget hrTarget; // Heart rate range HeartRateRangeTarget hrRangeTarget; typeField.SetEnum((Byte)FITWorkoutStepTargetTypes.HeartRate); valueField.SetUInt32(0); lowRangeField.SetUInt32(230); highRangeField.SetUInt32(270); loadedTarget = TargetFactory.Create(serializedMessage, placeholderStep); Assert.IsNotNull(loadedTarget, "HRRange target wasn't properly deserialized"); Assert.IsTrue(loadedTarget is BaseHeartRateTarget, "HRRange target wasn't deserialized as proper type"); hrTarget = loadedTarget as BaseHeartRateTarget; Assert.IsTrue(hrTarget.ConcreteTarget is HeartRateRangeTarget, "HRRange target wasn't deserialized as proper concrete type"); hrRangeTarget = hrTarget.ConcreteTarget as HeartRateRangeTarget; Assert.AreEqual(false, hrRangeTarget.IsPercentMaxHeartRate, "HRRange %Max wasn't properly deserialized"); Assert.AreEqual(130, hrRangeTarget.MinHeartRate, "HRRange min value wasn't properly deserialized"); Assert.AreEqual(170, hrRangeTarget.MaxHeartRate, "HRRange max value wasn't properly deserialized"); lowRangeField.SetUInt32(50); highRangeField.SetUInt32(70); loadedTarget = TargetFactory.Create(serializedMessage, placeholderStep); Assert.IsNotNull(loadedTarget, "HRRange target wasn't properly deserialized"); Assert.IsTrue(loadedTarget is BaseHeartRateTarget, "HRRange target wasn't deserialized as proper type"); hrTarget = loadedTarget as BaseHeartRateTarget; Assert.IsTrue(hrTarget.ConcreteTarget is HeartRateRangeTarget, "HRRange target wasn't deserialized as proper concrete type"); hrRangeTarget = hrTarget.ConcreteTarget as HeartRateRangeTarget; Assert.AreEqual(true, hrRangeTarget.IsPercentMaxHeartRate, "HRRange %Max wasn't properly deserialized"); Assert.AreEqual(50, hrRangeTarget.MinHeartRate, "HRRange min value wasn't properly deserialized"); Assert.AreEqual(70, hrRangeTarget.MaxHeartRate, "HRRange max value wasn't properly deserialized"); // Heart rate Garmin zone HeartRateZoneGTCTarget hrGTCTarget; valueField.SetUInt32(2); loadedTarget = TargetFactory.Create(serializedMessage, placeholderStep); Assert.IsNotNull(loadedTarget, "HRGTC target wasn't properly deserialized"); Assert.IsTrue(loadedTarget is BaseHeartRateTarget, "HRGTC target wasn't deserialized as proper type"); hrTarget = loadedTarget as BaseHeartRateTarget; Assert.IsTrue(hrTarget.ConcreteTarget is HeartRateZoneGTCTarget, "HRGTC target wasn't deserialized as proper concrete type"); hrGTCTarget = hrTarget.ConcreteTarget as HeartRateZoneGTCTarget; Assert.AreEqual(2, hrGTCTarget.Zone, "HRGTC zone value wasn't properly deserialized"); valueField.SetUInt32(4); loadedTarget = TargetFactory.Create(serializedMessage, placeholderStep); Assert.IsNotNull(loadedTarget, "HRGTC target wasn't properly deserialized"); Assert.IsTrue(loadedTarget is BaseHeartRateTarget, "HRGTC target wasn't deserialized as proper type"); hrTarget = loadedTarget as BaseHeartRateTarget; Assert.IsTrue(hrTarget.ConcreteTarget is HeartRateZoneGTCTarget, "HRGTC target wasn't deserialized as proper concrete type"); hrGTCTarget = hrTarget.ConcreteTarget as HeartRateZoneGTCTarget; Assert.AreEqual(4, hrGTCTarget.Zone, "HRGTC zone value wasn't properly deserialized"); // Power targets BasePowerTarget powerTarget; // Power range PowerRangeTarget powerRangeTarget; typeField.SetEnum((Byte)FITWorkoutStepTargetTypes.Power); valueField.SetUInt32(0); lowRangeField.SetUInt32(1150); highRangeField.SetUInt32(1200); loadedTarget = TargetFactory.Create(serializedMessage, placeholderStep); Assert.IsNotNull(loadedTarget, "PowerRange target wasn't properly deserialized"); Assert.IsTrue(loadedTarget is BasePowerTarget, "PowerRange target wasn't deserialized as proper type"); powerTarget = loadedTarget as BasePowerTarget; Assert.IsTrue(powerTarget.ConcreteTarget is PowerRangeTarget, "PowerRange target wasn't deserialized as proper concrete type"); powerRangeTarget = powerTarget.ConcreteTarget as PowerRangeTarget; Assert.AreEqual(false, powerRangeTarget.IsPercentFTP, "PowerRange %FTP wasn't properly deserialized"); Assert.AreEqual(150, powerRangeTarget.MinPower, "PowerRange min value wasn't properly deserialized"); Assert.AreEqual(200, powerRangeTarget.MaxPower, "PowerRange max value wasn't properly deserialized"); lowRangeField.SetUInt32(67); highRangeField.SetUInt32(200); loadedTarget = TargetFactory.Create(serializedMessage, placeholderStep); Assert.IsNotNull(loadedTarget, "PowerRange target wasn't properly deserialized"); Assert.IsTrue(loadedTarget is BasePowerTarget, "PowerRange target wasn't deserialized as proper type"); powerTarget = loadedTarget as BasePowerTarget; Assert.IsTrue(powerTarget.ConcreteTarget is PowerRangeTarget, "PowerRange target wasn't deserialized as proper concrete type"); powerRangeTarget = powerTarget.ConcreteTarget as PowerRangeTarget; Assert.AreEqual(true, powerRangeTarget.IsPercentFTP, "PowerRange %FTP wasn't properly deserialized"); Assert.AreEqual(67, powerRangeTarget.MinPower, "PowerRange min value wasn't properly deserialized"); Assert.AreEqual(200, powerRangeTarget.MaxPower, "PowerRange max value wasn't properly deserialized"); // Power Garmin zone PowerZoneGTCTarget powerGTCTarget; valueField.SetUInt32(1); loadedTarget = TargetFactory.Create(serializedMessage, placeholderStep); Assert.IsNotNull(loadedTarget, "PowerGTC target wasn't properly deserialized"); Assert.IsTrue(loadedTarget is BasePowerTarget, "PowerGTC target wasn't deserialized as proper type"); powerTarget = loadedTarget as BasePowerTarget; Assert.IsTrue(powerTarget.ConcreteTarget is PowerZoneGTCTarget, "PowerGTC target wasn't deserialized as proper concrete type"); powerGTCTarget = powerTarget.ConcreteTarget as PowerZoneGTCTarget; Assert.AreEqual(1, powerGTCTarget.Zone, "PowerGTC zone value wasn't properly deserialized"); valueField.SetUInt32(7); loadedTarget = TargetFactory.Create(serializedMessage, placeholderStep); Assert.IsNotNull(loadedTarget, "PowerGTC target wasn't properly deserialized"); Assert.IsTrue(loadedTarget is BasePowerTarget, "PowerGTC target wasn't deserialized as proper type"); powerTarget = loadedTarget as BasePowerTarget; Assert.IsTrue(powerTarget.ConcreteTarget is PowerZoneGTCTarget, "PowerGTC target wasn't deserialized as proper concrete type"); powerGTCTarget = powerTarget.ConcreteTarget as PowerZoneGTCTarget; Assert.AreEqual(7, powerGTCTarget.Zone, "PowerGTC zone value wasn't properly deserialized"); }
public void TestRepeatStepFITDeserialization() { Workout placeholderWorkout = new Workout("Test", PluginMain.GetApplication().Logbook.ActivityCategories[0]); RegularStep regularStep; RepeatStep repeatStep = new RepeatStep(placeholderWorkout); FITMessage serializedMessage = new FITMessage(FITGlobalMessageIds.WorkoutStep); FITMessageField durationValueField = new FITMessageField((Byte)FITWorkoutStepFieldIds.DurationValue); FITMessageField durationTypeField = new FITMessageField((Byte)FITWorkoutStepFieldIds.DurationType); FITMessageField targetValueField = new FITMessageField((Byte)FITWorkoutStepFieldIds.TargetValue); regularStep = placeholderWorkout.Steps[0] as RegularStep; // Setup message serializedMessage.AddField(durationValueField); serializedMessage.AddField(durationTypeField); serializedMessage.AddField(targetValueField); durationValueField.SetUInt32(0); // Step id to start repeat at durationTypeField.SetEnum((Byte)FITWorkoutStepDurationTypes.RepeatCount); targetValueField.SetUInt32(2); // This test is a little hard to follow because repeat steps in FIT format regroup previously deserialized steps. // We will illustrate the expected output throughout the test to ease validation. // At this point we have the following // - Root // - Regular step (id = 0) // By deserializing the message we should get the following // - Root // - Repeat step (id = 1) // - Regular step (id = 0) repeatStep.DeserializeFromFIT(serializedMessage); placeholderWorkout.Steps.AddStepToRoot(repeatStep); Assert.AreEqual(1, placeholderWorkout.Steps.Count, "Incorrect number of steps in workout after FIT deserialization of repeat step with single child"); Assert.AreEqual(2, placeholderWorkout.StepCount, "Incorrect number of steps in workout after FIT deserialization of repeat step with single child"); Assert.IsTrue(placeholderWorkout.Steps[0] is RepeatStep, "Invalid workout structure after FIT deserialization of repeat step with single child"); Assert.AreEqual(repeatStep, placeholderWorkout.Steps[0], "Invalid workout structure after FIT deserialization of repeat step with single child"); Assert.AreEqual(1, repeatStep.StepsToRepeat.Count, "Invalid number of children in repeat after FIT deserialization of repeat step with single child"); Assert.AreEqual(regularStep, repeatStep.StepsToRepeat[0], "Invalid child in repeat after FIT deserialization of repeat step with single child"); placeholderWorkout.Steps.AddStepToRoot(new RegularStep(placeholderWorkout)); placeholderWorkout.Steps.AddStepToRoot(new RegularStep(placeholderWorkout)); repeatStep = new RepeatStep(placeholderWorkout); durationValueField.SetUInt32(2); // Step id to start repeat at // At this point we have the following // - Root // - Repeat step (id = 1) // - Regular step (id = 0) // - Regular step (id = 2) // - Regular step (id = 3) // By deserializing the message we should get the following // - Root // - Repeat step (id = 1) // - Regular step (id = 0) // - Repeat step (id = 4) // - Regular step (id = 2) // - Regular step (id = 3) repeatStep.DeserializeFromFIT(serializedMessage); placeholderWorkout.Steps.AddStepToRoot(repeatStep); Assert.AreEqual(2, placeholderWorkout.Steps.Count, "Incorrect number of steps in workout after FIT deserialization of repeat step with multiple children"); Assert.AreEqual(5, placeholderWorkout.StepCount, "Incorrect number of steps in workout after FIT deserialization of repeat step with multiple children"); Assert.IsTrue(placeholderWorkout.Steps[1] is RepeatStep, "Invalid workout structure after FIT deserialization of repeat step with multiple children"); Assert.AreEqual(repeatStep, placeholderWorkout.Steps[1], "Invalid workout structure after FIT deserialization of repeat step with multiple children"); Assert.AreEqual(2, repeatStep.StepsToRepeat.Count, "Invalid number of children in repeat after FIT deserialization of repeat step with multiple children"); Assert.IsTrue(placeholderWorkout.Steps[0] is RepeatStep, "Invalid repeat step structure after FIT deserialization of repeat step with multiple children"); Assert.IsTrue(placeholderWorkout.Steps[1] is RepeatStep, "Invalid repeat step structure after FIT deserialization of repeat step with multiple children"); regularStep = new RegularStep(placeholderWorkout); placeholderWorkout.Steps.InsertStepBeforeStep(regularStep, placeholderWorkout.Steps[0]); repeatStep = new RepeatStep(placeholderWorkout); durationValueField.SetUInt32(1); // Step id to start repeat at // At this point we have the following // - Root // - Regular step (id = 0) // - Repeat step (id = 2) // - Regular step (id = 1) // - Repeat step (id = 5) // - Regular step (id = 4) // - Regular step (id = 5) // - Repeat step (not deserialized yet) // By deserializing the message we should get the following // - Root // - Regular step (id = 0) // - Repeat step (id = 6) // - Repeat step (id = 2) // - Regular step (id = 1) // - Repeat step (id = 5) // - Regular step (id = 3) // - Regular step (id = 4) repeatStep.DeserializeFromFIT(serializedMessage); placeholderWorkout.Steps.AddStepToRoot(repeatStep); Assert.AreEqual(2, placeholderWorkout.Steps.Count, "Incorrect number of steps in workout after FIT deserialization of repeat step with multiple nested children"); Assert.AreEqual(7, placeholderWorkout.StepCount, "Incorrect number of steps in workout after FIT deserialization of repeat step with multiple nested children"); Assert.IsTrue(placeholderWorkout.Steps[0] is RegularStep, "Invalid workout structure after FIT deserialization of repeat step with multiple nested children"); Assert.IsTrue(placeholderWorkout.Steps[1] is RepeatStep, "Invalid workout structure after FIT deserialization of repeat step with multiple nested children"); Assert.AreEqual(regularStep, placeholderWorkout.Steps[0], "Invalid workout structure after FIT deserialization of repeat step with multiple nested children"); Assert.AreEqual(repeatStep, placeholderWorkout.Steps[1], "Invalid workout structure after FIT deserialization of repeat step with multiple nested children"); Assert.AreEqual(2, repeatStep.StepsToRepeat.Count, "Invalid number of children in repeat after FIT deserialization of repeat step with multiple nested children"); Assert.IsTrue(repeatStep.StepsToRepeat[0] is RepeatStep, "Invalid repeat step structure after FIT deserialization of repeat step with multiple nested children"); Assert.IsTrue(repeatStep.StepsToRepeat[1] is RepeatStep, "Invalid repeat step structure after FIT deserialization of repeat step with multiple nested children"); }
public void TestRegularStepFITDeserialization() { Workout placeholderWorkout = new Workout("Test", PluginMain.GetApplication().Logbook.ActivityCategories[0]); RegularStep placeholderStep = new RegularStep(placeholderWorkout); FITMessage serializedMessage = new FITMessage(FITGlobalMessageIds.WorkoutStep); FITMessageField nameField = new FITMessageField((Byte)FITWorkoutStepFieldIds.StepName); FITMessageField intensityField = new FITMessageField((Byte)FITWorkoutStepFieldIds.Intensity); FITMessageField durationTypeField = new FITMessageField((Byte)FITWorkoutStepFieldIds.DurationType); FITMessageField durationValueField = new FITMessageField((Byte)FITWorkoutStepFieldIds.DurationValue); FITMessageField targetTypeField = new FITMessageField((Byte)FITWorkoutStepFieldIds.TargetType); FITMessageField targetValueField = new FITMessageField((Byte)FITWorkoutStepFieldIds.TargetValue); FITMessageField targetLowRangeField = new FITMessageField((Byte)FITWorkoutStepFieldIds.TargetCustomValueLow); FITMessageField targetHighRangeField = new FITMessageField((Byte)FITWorkoutStepFieldIds.TargetCustomValueHigh); // Setup message serializedMessage.AddField(nameField); serializedMessage.AddField(intensityField); serializedMessage.AddField(durationTypeField); serializedMessage.AddField(durationValueField); serializedMessage.AddField(targetTypeField); serializedMessage.AddField(targetValueField); serializedMessage.AddField(targetLowRangeField); serializedMessage.AddField(targetHighRangeField); durationTypeField.SetEnum((Byte)FITWorkoutStepDurationTypes.Calories); durationValueField.SetUInt32(456); targetTypeField.SetEnum((Byte)FITWorkoutStepTargetTypes.Cadence); targetValueField.SetUInt32(0); targetLowRangeField.SetUInt32(80); targetHighRangeField.SetUInt32(90); // Active step nameField.SetString("TestStep1"); intensityField.SetEnum((Byte)FITWorkoutStepIntensity.Active); placeholderStep.DeserializeFromFIT(serializedMessage); Assert.AreEqual("TestStep1", placeholderStep.Name, "Name not properly FIT deserialized for active step"); Assert.AreEqual(RegularStep.StepIntensity.Active, placeholderStep.Intensity, "Intensity not properly FIT deserialized for active step"); // Rest step nameField.SetString("TestStep2"); intensityField.SetEnum((Byte)FITWorkoutStepIntensity.Rest); placeholderStep.DeserializeFromFIT(serializedMessage); Assert.AreEqual("TestStep2", placeholderStep.Name, "Name not properly FIT deserialized for rest step"); Assert.AreEqual(RegularStep.StepIntensity.Rest, placeholderStep.Intensity, "Intensity not properly FIT deserialized for rest step"); // Warmup step nameField.SetString("TestStep3"); intensityField.SetEnum((Byte)FITWorkoutStepIntensity.Warmup); placeholderStep.DeserializeFromFIT(serializedMessage); Assert.AreEqual("TestStep3", placeholderStep.Name, "Name not properly FIT deserialized for warmup step"); Assert.AreEqual(RegularStep.StepIntensity.Warmup, placeholderStep.Intensity, "Intensity not properly FIT deserialized for warmup step"); // Cooldown step nameField.SetString("TestStep4"); intensityField.SetEnum((Byte)FITWorkoutStepIntensity.Cooldown); placeholderStep.DeserializeFromFIT(serializedMessage); Assert.AreEqual("TestStep4", placeholderStep.Name, "Name not properly FIT deserialized for cooldown step"); Assert.AreEqual(RegularStep.StepIntensity.Cooldown, placeholderStep.Intensity, "Intensity not properly FIT deserialized for cooldown step"); // Duration & target test Assert.IsTrue(placeholderStep.Duration is CaloriesDuration, "Duration not properly FIT deserialized in regular step"); Assert.IsTrue(placeholderStep.Target is BaseCadenceTarget, "Target not properly FIT deserialized in regular step"); }
public virtual void SerializeToFIT(Stream stream, bool serializeDefiniton) { FITMessage message = new FITMessage(FITGlobalMessageIds.WorkoutStep); FITMessageField stepId = new FITMessageField((Byte)FITWorkoutStepFieldIds.MessageIndex); FITMessageField durationType = new FITMessageField((Byte)FITWorkoutStepFieldIds.DurationType); FITMessageField durationValue = new FITMessageField((Byte)FITWorkoutStepFieldIds.DurationValue); FITMessageField intensity = new FITMessageField((Byte)FITWorkoutStepFieldIds.Intensity); FITMessageField stepName = new FITMessageField((Byte)FITWorkoutStepFieldIds.StepName); FITMessageField targetHigh = new FITMessageField((Byte)FITWorkoutStepFieldIds.TargetCustomValueHigh); FITMessageField targetLow = new FITMessageField((Byte)FITWorkoutStepFieldIds.TargetCustomValueLow); FITMessageField targetType = new FITMessageField((Byte)FITWorkoutStepFieldIds.TargetType); FITMessageField targetValue = new FITMessageField((Byte)FITWorkoutStepFieldIds.TargetValue); // Fill in invalid data durationType.SetEnum((Byte)0xFF); durationValue.SetUInt32(0xFFFFFFFF); intensity.SetEnum((Byte)0xFF); stepName.SetString("", (Byte)(Constants.MaxNameLength + 1)); targetHigh.SetUInt32(0xFFFFFFFF); targetLow.SetUInt32(0xFFFFFFFF); targetType.SetEnum((Byte)0xFF); targetValue.SetUInt32(0xFFFFFFFF); message.AddField(stepName); message.AddField(durationValue); message.AddField(targetValue); message.AddField(targetLow); message.AddField(targetHigh); message.AddField(stepId); message.AddField(durationType); message.AddField(targetType); message.AddField(intensity); FillFITStepMessage(message); message.Serialize(stream, serializeDefiniton); }
public void TestFITDeserialization() { Workout placeholderWorkout = new Workout("Test", PluginMain.GetApplication().Logbook.ActivityCategories[0]); RegularStep placeholderStep = new RegularStep(placeholderWorkout); FITMessage serializedMessage = new FITMessage(FITGlobalMessageIds.WorkoutStep); FITMessageField typeField = new FITMessageField((Byte)FITWorkoutStepFieldIds.DurationType); FITMessageField valueField = new FITMessageField((Byte)FITWorkoutStepFieldIds.DurationValue); IDuration deserializedDuration; serializedMessage.AddField(typeField); // Lap button typeField.SetEnum((Byte)FITWorkoutStepDurationTypes.Open); deserializedDuration = DurationFactory.Create(serializedMessage, placeholderStep); Assert.IsTrue(deserializedDuration is LapButtonDuration, "Lap button duration not properly FIT deserialized without value field"); serializedMessage.AddField(valueField); deserializedDuration = DurationFactory.Create(serializedMessage, placeholderStep); Assert.IsTrue(deserializedDuration is LapButtonDuration, "Lap button duration not properly FIT deserialized with unset value field"); valueField.SetUInt32(1); deserializedDuration = DurationFactory.Create(serializedMessage, placeholderStep); Assert.IsTrue(deserializedDuration is LapButtonDuration, "Lap button duration not properly FIT deserialized with value field"); // Time duration TimeDuration timeDuration; typeField.SetEnum((Byte)FITWorkoutStepDurationTypes.Time); valueField.SetUInt32(60000); deserializedDuration = DurationFactory.Create(serializedMessage, placeholderStep); Assert.IsTrue(deserializedDuration is TimeDuration, "Time duration not properly FIT deserialized"); timeDuration = deserializedDuration as TimeDuration; Assert.AreEqual(60, timeDuration.TimeInSeconds, "Invalid value deserialized for FIT time duration"); valueField.SetUInt32(3600000); deserializedDuration = DurationFactory.Create(serializedMessage, placeholderStep); Assert.IsTrue(deserializedDuration is TimeDuration, "Time duration not properly FIT deserialized"); timeDuration = deserializedDuration as TimeDuration; Assert.AreEqual(1, timeDuration.Hours, "Invalid value deserialized for FIT time duration"); Assert.AreEqual(0, timeDuration.Minutes, "Invalid value deserialized for FIT time duration"); Assert.AreEqual(0, timeDuration.Seconds, "Invalid value deserialized for FIT time duration"); // Distance duration DistanceDuration distanceDuration; typeField.SetEnum((Byte)FITWorkoutStepDurationTypes.Distance); valueField.SetUInt32(60000); deserializedDuration = DurationFactory.Create(serializedMessage, placeholderStep); Assert.IsTrue(deserializedDuration is DistanceDuration, "Distance duration not properly FIT deserialized"); distanceDuration = deserializedDuration as DistanceDuration; Assert.AreEqual(0.6, Length.Convert(distanceDuration.GetDistanceInBaseUnit(), distanceDuration.BaseUnit, Length.Units.Kilometer), "Invalid value deserialized for FIT distance duration"); valueField.SetUInt32(160934); deserializedDuration = DurationFactory.Create(serializedMessage, placeholderStep); Assert.IsTrue(deserializedDuration is DistanceDuration, "Distance duration not properly FIT deserialized"); distanceDuration = deserializedDuration as DistanceDuration; Assert.AreEqual(1.0, Length.Convert(distanceDuration.GetDistanceInBaseUnit(), distanceDuration.BaseUnit, Length.Units.Mile), STCommon.Data.Constants.Delta, "Invalid value deserialized for FIT distance duration"); // Calories duration CaloriesDuration caloriesDuration; typeField.SetEnum((Byte)FITWorkoutStepDurationTypes.Calories); valueField.SetUInt32(456); deserializedDuration = DurationFactory.Create(serializedMessage, placeholderStep); Assert.IsTrue(deserializedDuration is CaloriesDuration, "Calories duration not properly FIT deserialized"); caloriesDuration = deserializedDuration as CaloriesDuration; Assert.AreEqual(456, caloriesDuration.CaloriesToSpend, "Invalid value deserialized for FIT calories duration"); valueField.SetUInt32(100); deserializedDuration = DurationFactory.Create(serializedMessage, placeholderStep); Assert.IsTrue(deserializedDuration is CaloriesDuration, "Calories duration not properly FIT deserialized"); caloriesDuration = deserializedDuration as CaloriesDuration; Assert.AreEqual(100, caloriesDuration.CaloriesToSpend, "Invalid value deserialized for FIT calories duration"); // HR Above HeartRateAboveDuration hrAboveDuration; typeField.SetEnum((Byte)FITWorkoutStepDurationTypes.HeartRateGreaterThan); valueField.SetUInt32(256); deserializedDuration = DurationFactory.Create(serializedMessage, placeholderStep); Assert.IsTrue(deserializedDuration is HeartRateAboveDuration, "HRAbove duration not properly FIT deserialized"); hrAboveDuration = deserializedDuration as HeartRateAboveDuration; Assert.AreEqual(false, hrAboveDuration.IsPercentageMaxHeartRate, "Invalid value deserialized for FIT HRAbove duration"); Assert.AreEqual(156, hrAboveDuration.MaxHeartRate, "Invalid value deserialized for FIT HRAbove duration"); valueField.SetUInt32(88); deserializedDuration = DurationFactory.Create(serializedMessage, placeholderStep); Assert.IsTrue(deserializedDuration is HeartRateAboveDuration, "HRAbove duration not properly FIT deserialized"); hrAboveDuration = deserializedDuration as HeartRateAboveDuration; Assert.AreEqual(true, hrAboveDuration.IsPercentageMaxHeartRate, "Invalid value deserialized for FIT HRAbove duration"); Assert.AreEqual(88, hrAboveDuration.MaxHeartRate, "Invalid value deserialized for FIT HRAbove duration"); // HR Below HeartRateBelowDuration hrBelowDuration; typeField.SetEnum((Byte)FITWorkoutStepDurationTypes.HeartRateLessThan); valueField.SetUInt32(270); deserializedDuration = DurationFactory.Create(serializedMessage, placeholderStep); Assert.IsTrue(deserializedDuration is HeartRateBelowDuration, "HRBelow duration not properly FIT deserialized"); hrBelowDuration = deserializedDuration as HeartRateBelowDuration; Assert.AreEqual(false, hrBelowDuration.IsPercentageMaxHeartRate, "Invalid value deserialized for FIT HRBelow duration"); Assert.AreEqual(170, hrBelowDuration.MinHeartRate, "Invalid value deserialized for FIT HRBelow duration"); valueField.SetUInt32(70); deserializedDuration = DurationFactory.Create(serializedMessage, placeholderStep); Assert.IsTrue(deserializedDuration is HeartRateBelowDuration, "HRBelow duration not properly FIT deserialized"); hrBelowDuration = deserializedDuration as HeartRateBelowDuration; Assert.AreEqual(true, hrBelowDuration.IsPercentageMaxHeartRate, "Invalid value deserialized for FIT HRBelow duration"); Assert.AreEqual(70, hrBelowDuration.MinHeartRate, "Invalid value deserialized for FIT HRBelow duration"); // Power Above PowerAboveDuration powerAboveDuration; typeField.SetEnum((Byte)FITWorkoutStepDurationTypes.PowerGreaterThan); valueField.SetUInt32(1256); deserializedDuration = DurationFactory.Create(serializedMessage, placeholderStep); Assert.IsTrue(deserializedDuration is PowerAboveDuration, "PowerAbove duration not properly FIT deserialized"); powerAboveDuration = deserializedDuration as PowerAboveDuration; Assert.AreEqual(false, powerAboveDuration.IsPercentFTP, "Invalid value deserialized for FIT PowerAbove duration"); Assert.AreEqual(256, powerAboveDuration.MaxPower, "Invalid value deserialized for FIT PowerAbove duration"); valueField.SetUInt32(185); deserializedDuration = DurationFactory.Create(serializedMessage, placeholderStep); Assert.IsTrue(deserializedDuration is PowerAboveDuration, "PowerAbove duration not properly FIT deserialized"); powerAboveDuration = deserializedDuration as PowerAboveDuration; Assert.AreEqual(true, powerAboveDuration.IsPercentFTP, "Invalid value deserialized for FIT PowerAbove duration"); Assert.AreEqual(185, powerAboveDuration.MaxPower, "Invalid value deserialized for FIT PowerAbove duration"); // Power Below PowerBelowDuration powerBelowDuration; typeField.SetEnum((Byte)FITWorkoutStepDurationTypes.PowerLessThan); valueField.SetUInt32(1300); deserializedDuration = DurationFactory.Create(serializedMessage, placeholderStep); Assert.IsTrue(deserializedDuration is PowerBelowDuration, "PowerBelow duration not properly FIT deserialized"); powerBelowDuration = deserializedDuration as PowerBelowDuration; Assert.AreEqual(false, powerBelowDuration.IsPercentFTP, "Invalid value deserialized for FIT PowerBelow duration"); Assert.AreEqual(300, powerBelowDuration.MinPower, "Invalid value deserialized for FIT PowerBelow duration"); valueField.SetUInt32(55); deserializedDuration = DurationFactory.Create(serializedMessage, placeholderStep); Assert.IsTrue(deserializedDuration is PowerBelowDuration, "PowerBelow duration not properly FIT deserialized"); powerBelowDuration = deserializedDuration as PowerBelowDuration; Assert.AreEqual(true, powerBelowDuration.IsPercentFTP, "Invalid value deserialized for FIT PowerBelow duration"); Assert.AreEqual(55, powerBelowDuration.MinPower, "Invalid value deserialized for FIT PowerBelow duration"); }
public void SerializeBikeProfiles(Stream outputStream) { UInt16 i = 0; foreach (GarminBikeProfile bike in m_Bikes) { FITMessage bikeProfileMessage = new FITMessage(FITGlobalMessageIds.BikeProfile); FITMessageField index = new FITMessageField((Byte)FITBikeProfileFieldIds.MessageIndex); FITMessageField name = new FITMessageField((Byte)FITBikeProfileFieldIds.Name); FITMessageField odometer = new FITMessageField((Byte)FITBikeProfileFieldIds.Odometer); FITMessageField customWheelSize = new FITMessageField((Byte)FITBikeProfileFieldIds.CustomWheelSize); FITMessageField autoWheelSize = new FITMessageField((Byte)FITBikeProfileFieldIds.AutoWheelSize); FITMessageField weight = new FITMessageField((Byte)FITBikeProfileFieldIds.Weight); FITMessageField useAutoWheelSize = new FITMessageField((Byte)FITBikeProfileFieldIds.AutoWheelSetting); FITMessageField cadenceSensor = new FITMessageField((Byte)FITBikeProfileFieldIds.SpeedCadenceSensorEnabled); FITMessageField powerSensor = new FITMessageField((Byte)FITBikeProfileFieldIds.PowerSensorEnabled); index.SetUInt16(i); name.SetString(bike.Name, (Byte)(Constants.MaxNameLength + 1)); odometer.SetUInt32((UInt32)(bike.OdometerInMeters * 100)); customWheelSize.SetUInt16(bike.WheelSize); autoWheelSize.SetUInt16(bike.WheelSize); weight.SetUInt16((UInt16)Math.Round(Weight.Convert(bike.WeightInPounds, Weight.Units.Pound, Weight.Units.Kilogram) * 10, 0)); useAutoWheelSize.SetEnum(bike.AutoWheelSize ? (Byte)FITBoolean.True : (Byte)FITBoolean.False); cadenceSensor.SetEnum(bike.HasCadenceSensor ? (Byte)FITBoolean.True : (Byte)FITBoolean.False); powerSensor.SetEnum(bike.HasPowerSensor ? (Byte)FITBoolean.True : (Byte)FITBoolean.False); bikeProfileMessage.AddField(index); bikeProfileMessage.AddField(name); bikeProfileMessage.AddField(odometer); bikeProfileMessage.AddField(customWheelSize); bikeProfileMessage.AddField(autoWheelSize); bikeProfileMessage.AddField(weight); bikeProfileMessage.AddField(useAutoWheelSize); bikeProfileMessage.AddField(cadenceSensor); bikeProfileMessage.AddField(powerSensor); bikeProfileMessage.Serialize(outputStream, i == 0); ++i; } }