From 610929aae221c2a846ba0f9ad1b611d0d4bfd759 Mon Sep 17 00:00:00 2001 From: siliconsolder Date: Fri, 21 Aug 2026 09:03:12 +0200 Subject: [PATCH] Fetch Garmin fitness age --- sync/vyta-sync/collector.py | 101 ++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/sync/vyta-sync/collector.py b/sync/vyta-sync/collector.py index ca1b34f..bb6e4d4 100644 --- a/sync/vyta-sync/collector.py +++ b/sync/vyta-sync/collector.py @@ -83,6 +83,76 @@ def seconds_to_minutes(value): ): return None +def find_nested_value(data, wanted_keys): + if isinstance( + data, + dict, + ): + for key, value in data.items(): + if key in wanted_keys and value is not None: + return value + + nested = find_nested_value( + value, + wanted_keys, + ) + + if nested is not None: + return nested + + if isinstance( + data, + list, + ): + for item in data: + nested = find_nested_value( + item, + wanted_keys, + ) + + if nested is not None: + return nested + + return None + + +def extract_fitness_age(*sources): + value = find_nested_value( + sources, + { + "fitnessAge", + "fitness_age", + "fitnessAgeValue", + "fitnessage", + }, + ) + + if value is None: + return None + + try: + return float(value) + except ( + TypeError, + ValueError, + ): + return None + + +def extract_fitness_age_description(*sources): + value = find_nested_value( + sources, + { + "fitnessAgeDescription", + "fitness_age_description", + "fitnessAgeDesc", + }, + ) + + if value is None: + return None + + return str(value) # --------------------------------------------------------- # LOGIN @@ -474,6 +544,31 @@ def collect_day( {}, ) + fitness_age_data = safe_call( + lambda: + garmin.get_fitnessage_data( + day_str + ) + if hasattr( + garmin, + "get_fitnessage_data", + ) + else garmin.connectapi( + f"/fitnessage-service/fitnessage/{day_str}" + ), + {}, + ) + + fitness_age_value = extract_fitness_age( + fitness_age_data, + training_status, + ) + + fitness_age_description = extract_fitness_age_description( + fitness_age_data, + training_status, + ) + sleep_dto = ( sleep.get( "dailySleepDTO", @@ -846,6 +941,12 @@ def collect_day( training_status.get( "mostRecentTrainingLoadBalance" ), + + "fitnessAge": + fitness_age_value, + + "fitnessAgeDescription": + fitness_age_description, }, }