@@ -417,6 +417,13 @@ def __init__(self):
417417 "4" : {"desc" : "Execute GraphQL query" , "key" : "query_garmin_graphql" },
418418 },
419419 },
420+ "b" : {
421+ "name" : "📅 Training Plans" ,
422+ "options" : {
423+ "1" : {"desc" : "Get training plans" , "key" : "get_training_plans" },
424+ "2" : {"desc" : "Get training plan by ID" , "key" : "get_training_plan_by_id" },
425+ },
426+ },
420427}
421428
422429current_category = None
@@ -1769,6 +1776,63 @@ def get_activity_exercise_sets_data(api: Garmin) -> None:
17691776 print ("ℹ️ No activity exercise sets available" )
17701777
17711778
1779+ def get_training_plan_by_id_data (api : Garmin ) -> None :
1780+ """Get training plan details by ID (routes FBT_ADAPTIVE plans to the adaptive endpoint)."""
1781+ resp = api .get_training_plans () or {}
1782+ training_plans = resp .get ("trainingPlanList" ) or []
1783+ if not training_plans :
1784+ print ("ℹ️ No training plans found" )
1785+ return
1786+
1787+ user_input = input ("Enter training plan ID (press Enter for most recent): " ).strip ()
1788+ selected = None
1789+ if user_input :
1790+ try :
1791+ wanted_id = int (user_input )
1792+ selected = next (
1793+ (
1794+ p
1795+ for p in training_plans
1796+ if int (p .get ("trainingPlanId" , 0 )) == wanted_id
1797+ ),
1798+ None ,
1799+ )
1800+ if not selected :
1801+ print (
1802+ f"ℹ️ Plan ID { wanted_id } not found in your plans; attempting fetch anyway"
1803+ )
1804+ plan_id = wanted_id
1805+ plan_name = f"Plan { wanted_id } "
1806+ plan_category = None
1807+ else :
1808+ plan_id = int (selected ["trainingPlanId" ])
1809+ plan_name = selected .get ("name" , str (plan_id ))
1810+ plan_category = selected .get ("trainingPlanCategory" )
1811+ except ValueError :
1812+ print ("❌ Invalid plan ID" )
1813+ return
1814+ else :
1815+ selected = training_plans [- 1 ]
1816+ plan_id = int (selected ["trainingPlanId" ])
1817+ plan_name = selected .get ("name" , str (plan_id ))
1818+ plan_category = selected .get ("trainingPlanCategory" )
1819+
1820+ if plan_category == "FBT_ADAPTIVE" :
1821+ call_and_display (
1822+ api .get_adaptive_training_plan_by_id ,
1823+ plan_id ,
1824+ method_name = "get_adaptive_training_plan_by_id" ,
1825+ api_call_desc = f"api.get_adaptive_training_plan_by_id({ plan_id } ) - { plan_name } " ,
1826+ )
1827+ else :
1828+ call_and_display (
1829+ api .get_training_plan_by_id ,
1830+ plan_id ,
1831+ method_name = "get_training_plan_by_id" ,
1832+ api_call_desc = f"api.get_training_plan_by_id({ plan_id } ) - { plan_name } " ,
1833+ )
1834+
1835+
17721836def get_workout_by_id_data (api : Garmin ) -> None :
17731837 """Get workout by ID for the last workout."""
17741838 try :
@@ -3186,6 +3250,12 @@ def execute_api_call(api: Garmin, key: str) -> None:
31863250 method_name = "get_workouts" ,
31873251 api_call_desc = "api.get_workouts()" ,
31883252 ),
3253+ "get_training_plan_by_id" : lambda : get_training_plan_by_id_data (api ),
3254+ "get_training_plans" : lambda : call_and_display (
3255+ api .get_training_plans ,
3256+ method_name = "get_training_plans" ,
3257+ api_call_desc = "api.get_training_plans()" ,
3258+ ),
31893259 "upload_activity" : lambda : upload_activity_file (api ),
31903260 "download_activities" : lambda : download_activities_by_date (api ),
31913261 "get_activity_splits" : lambda : get_activity_splits_data (api ),
0 commit comments