cyberjunky / python-garminconnect

Python 3 API wrapper for Garmin Connect to get activity statistics
MIT License
852 stars 139 forks source link

Individual route data for "Bouldering" and "Indoor Climbing" activities #214

Closed mwcoleman closed 1 month ago

mwcoleman commented 1 month ago

I'm trying to get individual route data for the bouldering and indoor climbing activities. I've tried using api.get_activity_details() and api.get_splits(<activity_id>) and it does not appear to contain the per-route data I'm after. It only has two splits: CLIMB and REST api.get_exercise_sets returns None.

The Garmin connect andriod app has a page that displays this info (see attached screenshot) so it is being recorded/stored, but weirdly (to me?) it doesn't appear as part of the activity data.

garmin_screenshot

Is it possible to access it with the python wrapper?

psdupvi commented 1 month ago

It looks like it might be an endpoint of the format https://connect.garmin.com/activity-service/activity/{activity_id}/typedsplits.

The JSON return for the dummy bouldering I just did looked like:

{
    "activityId": {activity_id},
    "activityUUID": {
        "uuid": "{activity_uuid}"
    },
    "splits": [
        {
            "startTimeLocal": "2024-07-08T09:33:19.0",
            "startTimeGMT": "2024-07-08T13:33:19.0",
            "duration": 2.214,
            "movingDuration": 0.0,
            "elapsedDuration": 2.214,
            "calories": 0.0,
            "bmrCalories": 0.0,
            "averageHR": 59.0,
            "maxHR": 59.0,
            "totalExerciseReps": 0,
            "type": "CLIMB_ACTIVE",
            "messageIndex": 0,
            "endTimeGMT": "2024-07-08T13:33:20.0",
            "status": "CLIMB_COMPLETED",
            "gradeValue": {
                "sortOrder": 1,
                "valueKey": "_2",
                "scale": "FONT"
            }
        },
        {
            "startTimeLocal": "2024-07-08T09:33:21.0",
            "startTimeGMT": "2024-07-08T13:33:21.0",
            "duration": 5.44,
            "movingDuration": 0.0,
            "elapsedDuration": 5.44,
            "calories": 0.0,
            "bmrCalories": 0.0,
            "averageHR": 59.0,
            "maxHR": 60.0,
            "totalExerciseReps": 0,
            "type": "CLIMB_REST",
            "messageIndex": 1,
            "endTimeGMT": "2024-07-08T13:33:26.0"
        },
        {
            "startTimeLocal": "2024-07-08T09:33:27.0",
            "startTimeGMT": "2024-07-08T13:33:27.0",
            "duration": 4.985,
            "movingDuration": 0.0,
            "elapsedDuration": 4.985,
            "calories": 0.0,
            "bmrCalories": 0.0,
            "averageHR": 59.0,
            "maxHR": 60.0,
            "totalExerciseReps": 0,
            "type": "CLIMB_ACTIVE",
            "messageIndex": 2,
            "endTimeGMT": "2024-07-08T13:33:31.0",
            "status": "CLIMB_ATTEMPTED",
            "gradeValue": {
                "sortOrder": 1,
                "valueKey": "_2",
                "scale": "FONT"
            }
        },
        {
            "startTimeLocal": "2024-07-08T09:33:32.0",
            "startTimeGMT": "2024-07-08T13:33:32.0",
            "duration": 6.797,
            "movingDuration": 0.0,
            "elapsedDuration": 6.797,
            "calories": 0.0,
            "bmrCalories": 0.0,
            "averageHR": 58.0,
            "maxHR": 59.0,
            "totalExerciseReps": 0,
            "type": "CLIMB_REST",
            "messageIndex": 3,
            "endTimeGMT": "2024-07-08T13:33:38.0"
        },
        {
            "startTimeLocal": "2024-07-08T09:33:39.0",
            "startTimeGMT": "2024-07-08T13:33:39.0",
            "duration": 4.006,
            "movingDuration": 0.0,
            "elapsedDuration": 4.006,
            "calories": 0.0,
            "bmrCalories": 0.0,
            "averageHR": 57.0,
            "maxHR": 58.0,
            "totalExerciseReps": 0,
            "type": "CLIMB_ACTIVE",
            "messageIndex": 4,
            "endTimeGMT": "2024-07-08T13:33:42.0",
            "status": "CLIMB_COMPLETED",
            "gradeValue": {
                "sortOrder": 3,
                "valueKey": "_4",
                "scale": "FONT"
            }
        },
        {
            "startTimeLocal": "2024-07-08T09:33:43.0",
            "startTimeGMT": "2024-07-08T13:33:43.0",
            "duration": 1.618,
            "movingDuration": 0.0,
            "elapsedDuration": 3.61,
            "calories": 0.0,
            "bmrCalories": 0.0,
            "averageHR": 58.0,
            "maxHR": 58.0,
            "totalExerciseReps": 0,
            "type": "CLIMB_REST",
            "messageIndex": 5,
            "endTimeGMT": "2024-07-08T13:33:44.0"
        }
    ]
}

I'll look at creating a PR for this. I think Typed Splits works for other activity types as well (I see that the endpoint returns data for one of my runs). I wonder how different the data is between them

psdupvi commented 1 month ago

Created #215

mwcoleman commented 1 month ago

That's exactly the info I was after, thanks for adding the functionality.

Yeah, I was expecting it to be the same endpoint as activity_splits, but that only returns summary information for the whole activity (treating it as one split).