346
fitparser/profile.go
Normal file
346
fitparser/profile.go
Normal file
@@ -0,0 +1,346 @@
|
||||
package fitparser
|
||||
|
||||
// Common message numbers
|
||||
const (
|
||||
MesgNumFileId = 0
|
||||
MesgNumCapabilities = 1
|
||||
MesgNumDeviceSettings = 2
|
||||
MesgNumUserProfile = 3
|
||||
MesgNumHrmProfile = 4
|
||||
MesgNumSdmProfile = 5
|
||||
MesgNumBikeProfile = 6
|
||||
MesgNumZonesTarget = 7
|
||||
MesgNumHrZone = 8
|
||||
MesgNumPowerZone = 9
|
||||
MesgNumMetZone = 10
|
||||
MesgNumSport = 12
|
||||
MesgNumGoal = 15
|
||||
MesgNumSession = 18
|
||||
MesgNumLap = 19
|
||||
MesgNumRecord = 20
|
||||
MesgNumEvent = 21
|
||||
MesgNumDeviceInfo = 23
|
||||
MesgNumWorkout = 26
|
||||
MesgNumWorkoutStep = 27
|
||||
MesgNumSchedule = 28
|
||||
MesgNumActivity = 34
|
||||
MesgNumSoftware = 35
|
||||
MesgNumFileCapabilities = 37
|
||||
MesgNumMesgCapabilities = 38
|
||||
MesgNumFieldCapabilities = 39
|
||||
MesgNumFileCreator = 49
|
||||
MesgNumBloodPressure = 51
|
||||
MesgNumSpeedZone = 53
|
||||
MesgNumMonitoring = 55
|
||||
MesgNumHrv = 78
|
||||
MesgNumLength = 101
|
||||
MesgNumMonitoringInfo = 103
|
||||
MesgNumPad = 105
|
||||
MesgNumSegmentLap = 142
|
||||
)
|
||||
|
||||
// Common field numbers for FileId message
|
||||
const (
|
||||
FieldFileIdType = 0
|
||||
FieldFileIdManufacturer = 1
|
||||
FieldFileIdProduct = 2
|
||||
FieldFileIdSerialNumber = 3
|
||||
FieldFileIdTimeCreated = 4
|
||||
FieldFileIdNumber = 5
|
||||
)
|
||||
|
||||
// Common field numbers for Record message
|
||||
const (
|
||||
FieldRecordTimestamp = 253
|
||||
FieldRecordPositionLat = 0
|
||||
FieldRecordPositionLong = 1
|
||||
FieldRecordAltitude = 2
|
||||
FieldRecordHeartRate = 3
|
||||
FieldRecordCadence = 4
|
||||
FieldRecordDistance = 5
|
||||
FieldRecordSpeed = 6
|
||||
FieldRecordPower = 7
|
||||
FieldRecordCompressedSpeedDistance = 8
|
||||
FieldRecordGrade = 9
|
||||
FieldRecordResistance = 10
|
||||
FieldRecordTimeFromCourse = 11
|
||||
FieldRecordCycleLength = 12
|
||||
FieldRecordTemperature = 13
|
||||
)
|
||||
|
||||
// Common field numbers for Lap message
|
||||
const (
|
||||
FieldLapTimestamp = 253
|
||||
FieldLapEvent = 0
|
||||
FieldLapEventType = 1
|
||||
FieldLapStartTime = 2
|
||||
FieldLapStartPositionLat = 3
|
||||
FieldLapStartPositionLong = 4
|
||||
FieldLapEndPositionLat = 5
|
||||
FieldLapEndPositionLong = 6
|
||||
FieldLapTotalElapsedTime = 7
|
||||
FieldLapTotalTimerTime = 8
|
||||
FieldLapTotalDistance = 9
|
||||
FieldLapTotalCycles = 10
|
||||
FieldLapTotalCalories = 11
|
||||
FieldLapTotalFatCalories = 12
|
||||
FieldLapAvgSpeed = 13
|
||||
FieldLapMaxSpeed = 14
|
||||
FieldLapAvgHeartRate = 15
|
||||
FieldLapMaxHeartRate = 16
|
||||
FieldLapAvgCadence = 17
|
||||
FieldLapMaxCadence = 18
|
||||
FieldLapAvgPower = 19
|
||||
FieldLapMaxPower = 20
|
||||
)
|
||||
|
||||
// Common field numbers for Session message
|
||||
const (
|
||||
FieldSessionTimestamp = 253
|
||||
FieldSessionEvent = 0
|
||||
FieldSessionEventType = 1
|
||||
FieldSessionStartTime = 2
|
||||
FieldSessionStartPositionLat = 3
|
||||
FieldSessionStartPositionLong = 4
|
||||
FieldSessionSport = 5
|
||||
FieldSessionSubSport = 6
|
||||
FieldSessionTotalElapsedTime = 7
|
||||
FieldSessionTotalTimerTime = 8
|
||||
FieldSessionTotalDistance = 9
|
||||
FieldSessionTotalCycles = 10
|
||||
FieldSessionTotalCalories = 11
|
||||
FieldSessionTotalFatCalories = 13
|
||||
FieldSessionAvgSpeed = 14
|
||||
FieldSessionMaxSpeed = 15
|
||||
FieldSessionAvgHeartRate = 16
|
||||
FieldSessionMaxHeartRate = 17
|
||||
FieldSessionAvgCadence = 18
|
||||
FieldSessionMaxCadence = 19
|
||||
FieldSessionAvgPower = 20
|
||||
FieldSessionMaxPower = 21
|
||||
)
|
||||
|
||||
// Common field numbers for Activity message
|
||||
const (
|
||||
FieldActivityTimestamp = 253
|
||||
FieldActivityTotalTimerTime = 0
|
||||
FieldActivityNumSessions = 1
|
||||
FieldActivityType = 2
|
||||
FieldActivityEvent = 3
|
||||
FieldActivityEventType = 4
|
||||
FieldActivityLocalTimestamp = 5
|
||||
FieldActivityEventGroup = 6
|
||||
)
|
||||
|
||||
// File types
|
||||
const (
|
||||
FileTypeDevice = 1
|
||||
FileTypeSettings = 2
|
||||
FileTypeSport = 3
|
||||
FileTypeActivity = 4
|
||||
FileTypeWorkout = 5
|
||||
FileTypeCourse = 6
|
||||
FileTypeSchedules = 7
|
||||
FileTypeWeight = 9
|
||||
FileTypeTotals = 10
|
||||
FileTypeGoals = 11
|
||||
FileTypeBloodPressure = 14
|
||||
FileTypeMonitoringA = 15
|
||||
FileTypeActivitySummary = 20
|
||||
FileTypeMonitoringDaily = 28
|
||||
FileTypeMonitoringB = 32
|
||||
FileTypeSegment = 34
|
||||
FileTypeSegmentList = 35
|
||||
)
|
||||
|
||||
// Sport types
|
||||
const (
|
||||
SportGeneric = 0
|
||||
SportRunning = 1
|
||||
SportCycling = 2
|
||||
SportTransition = 3
|
||||
SportFitnessEquipment = 4
|
||||
SportSwimming = 5
|
||||
SportBasketball = 6
|
||||
SportSoccer = 7
|
||||
SportTennis = 8
|
||||
SportAmericanFootball = 9
|
||||
SportTraining = 10
|
||||
SportWalking = 11
|
||||
SportCrossCountrySkiing = 12
|
||||
SportAlpineSkiing = 13
|
||||
SportSnowboarding = 14
|
||||
SportRowing = 15
|
||||
SportMountaineering = 16
|
||||
SportHiking = 17
|
||||
SportMultisport = 18
|
||||
SportPaddling = 19
|
||||
)
|
||||
|
||||
// GetMessageName returns a human-readable name for a message number
|
||||
func GetMessageName(mesgNum uint16) string {
|
||||
switch mesgNum {
|
||||
case MesgNumFileId:
|
||||
return "FileId"
|
||||
case MesgNumCapabilities:
|
||||
return "Capabilities"
|
||||
case MesgNumDeviceSettings:
|
||||
return "DeviceSettings"
|
||||
case MesgNumUserProfile:
|
||||
return "UserProfile"
|
||||
case MesgNumHrmProfile:
|
||||
return "HrmProfile"
|
||||
case MesgNumSdmProfile:
|
||||
return "SdmProfile"
|
||||
case MesgNumBikeProfile:
|
||||
return "BikeProfile"
|
||||
case MesgNumZonesTarget:
|
||||
return "ZonesTarget"
|
||||
case MesgNumHrZone:
|
||||
return "HrZone"
|
||||
case MesgNumPowerZone:
|
||||
return "PowerZone"
|
||||
case MesgNumMetZone:
|
||||
return "MetZone"
|
||||
case MesgNumSport:
|
||||
return "Sport"
|
||||
case MesgNumGoal:
|
||||
return "Goal"
|
||||
case MesgNumSession:
|
||||
return "Session"
|
||||
case MesgNumLap:
|
||||
return "Lap"
|
||||
case MesgNumRecord:
|
||||
return "Record"
|
||||
case MesgNumEvent:
|
||||
return "Event"
|
||||
case MesgNumDeviceInfo:
|
||||
return "DeviceInfo"
|
||||
case MesgNumActivity:
|
||||
return "Activity"
|
||||
case MesgNumSoftware:
|
||||
return "Software"
|
||||
case MesgNumFileCapabilities:
|
||||
return "FileCapabilities"
|
||||
case MesgNumMesgCapabilities:
|
||||
return "MesgCapabilities"
|
||||
case MesgNumFieldCapabilities:
|
||||
return "FieldCapabilities"
|
||||
case MesgNumFileCreator:
|
||||
return "FileCreator"
|
||||
case MesgNumBloodPressure:
|
||||
return "BloodPressure"
|
||||
case MesgNumSpeedZone:
|
||||
return "SpeedZone"
|
||||
case MesgNumMonitoring:
|
||||
return "Monitoring"
|
||||
case MesgNumHrv:
|
||||
return "Hrv"
|
||||
case MesgNumLength:
|
||||
return "Length"
|
||||
case MesgNumMonitoringInfo:
|
||||
return "MonitoringInfo"
|
||||
case MesgNumPad:
|
||||
return "Pad"
|
||||
case MesgNumSegmentLap:
|
||||
return "SegmentLap"
|
||||
default:
|
||||
return "Unknown"
|
||||
}
|
||||
}
|
||||
|
||||
// GetFileTypeName returns a human-readable name for a file type
|
||||
func GetFileTypeName(fileType uint8) string {
|
||||
switch fileType {
|
||||
case FileTypeDevice:
|
||||
return "Device"
|
||||
case FileTypeSettings:
|
||||
return "Settings"
|
||||
case FileTypeSport:
|
||||
return "Sport"
|
||||
case FileTypeActivity:
|
||||
return "Activity"
|
||||
case FileTypeWorkout:
|
||||
return "Workout"
|
||||
case FileTypeCourse:
|
||||
return "Course"
|
||||
case FileTypeSchedules:
|
||||
return "Schedules"
|
||||
case FileTypeWeight:
|
||||
return "Weight"
|
||||
case FileTypeTotals:
|
||||
return "Totals"
|
||||
case FileTypeGoals:
|
||||
return "Goals"
|
||||
case FileTypeBloodPressure:
|
||||
return "BloodPressure"
|
||||
case FileTypeMonitoringA:
|
||||
return "MonitoringA"
|
||||
case FileTypeActivitySummary:
|
||||
return "ActivitySummary"
|
||||
case FileTypeMonitoringDaily:
|
||||
return "MonitoringDaily"
|
||||
case FileTypeMonitoringB:
|
||||
return "MonitoringB"
|
||||
case FileTypeSegment:
|
||||
return "Segment"
|
||||
case FileTypeSegmentList:
|
||||
return "SegmentList"
|
||||
default:
|
||||
return "Unknown"
|
||||
}
|
||||
}
|
||||
|
||||
// GetSportName returns a human-readable name for a sport type
|
||||
func GetSportName(sport uint8) string {
|
||||
switch sport {
|
||||
case SportGeneric:
|
||||
return "Generic"
|
||||
case SportRunning:
|
||||
return "Running"
|
||||
case SportCycling:
|
||||
return "Cycling"
|
||||
case SportTransition:
|
||||
return "Transition"
|
||||
case SportFitnessEquipment:
|
||||
return "FitnessEquipment"
|
||||
case SportSwimming:
|
||||
return "Swimming"
|
||||
case SportBasketball:
|
||||
return "Basketball"
|
||||
case SportSoccer:
|
||||
return "Soccer"
|
||||
case SportTennis:
|
||||
return "Tennis"
|
||||
case SportAmericanFootball:
|
||||
return "AmericanFootball"
|
||||
case SportTraining:
|
||||
return "Training"
|
||||
case SportWalking:
|
||||
return "Walking"
|
||||
case SportCrossCountrySkiing:
|
||||
return "CrossCountrySkiing"
|
||||
case SportAlpineSkiing:
|
||||
return "AlpineSkiing"
|
||||
case SportSnowboarding:
|
||||
return "Snowboarding"
|
||||
case SportRowing:
|
||||
return "Rowing"
|
||||
case SportMountaineering:
|
||||
return "Mountaineering"
|
||||
case SportHiking:
|
||||
return "Hiking"
|
||||
case SportMultisport:
|
||||
return "Multisport"
|
||||
case SportPaddling:
|
||||
return "Paddling"
|
||||
default:
|
||||
return "Unknown"
|
||||
}
|
||||
}
|
||||
|
||||
// ConvertSemicirclesToDegrees converts a position in semicircles to degrees
|
||||
// FIT files store lat/long as semicircles (2^31 semicircles = 180 degrees)
|
||||
func ConvertSemicirclesToDegrees(semicircles int32) float64 {
|
||||
return float64(semicircles) * (180.0 / 2147483648.0)
|
||||
}
|
||||
Reference in New Issue
Block a user