Fix VO2 max extraction — use fitnessage API not daily stats
get_stats() does not include VO2 max. Switch to get_fitnessage_data() which hits /fitnessage-service/fitnessage and returns the current VO2 max estimate and fitness age. Called once per sync (today only) since VO2 max is a slow-changing metric; the frontend carry-forward shows it on older days. Remove the incorrect stats.get() attempt from _parse_day. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -325,6 +325,31 @@ def sync_wellness(garmin, user_id: int, since: Optional[datetime], db,
|
|||||||
logger.warning("Failed to upsert health_metrics for %s: %s", day_str, exc)
|
logger.warning("Failed to upsert health_metrics for %s: %s", day_str, exc)
|
||||||
db.rollback()
|
db.rollback()
|
||||||
|
|
||||||
|
# Fetch current VO2 max and fitness age once (slow-changing — only update today's row)
|
||||||
|
today_str = date.today().isoformat()
|
||||||
|
fa_data = _safe(garmin.get_fitnessage_data, today_str)
|
||||||
|
if fa_data:
|
||||||
|
vo2 = (fa_data.get("vo2Max")
|
||||||
|
or fa_data.get("vo2MaxPreciseValue")
|
||||||
|
or fa_data.get("biometricProfile", {}).get("vo2Max"))
|
||||||
|
fa = fa_data.get("chronologicalAge") or fa_data.get("fitnessAge")
|
||||||
|
if vo2 and float(vo2) > 0:
|
||||||
|
try:
|
||||||
|
fa_row = {"vo2max": float(vo2)}
|
||||||
|
if fa:
|
||||||
|
fa_row["fitness_age"] = int(fa)
|
||||||
|
fa_cols = list(fa_row.keys())
|
||||||
|
db.execute(text(f"""
|
||||||
|
INSERT INTO health_metrics (user_id, date, {", ".join(fa_cols)})
|
||||||
|
VALUES (:user_id, :day, {", ".join(f":{c}" for c in fa_cols)})
|
||||||
|
ON CONFLICT (user_id, date) DO UPDATE SET
|
||||||
|
{", ".join(f"{c} = EXCLUDED.{c}" for c in fa_cols)}
|
||||||
|
"""), {"user_id": user_id, "day": today_str, **fa_row})
|
||||||
|
db.commit()
|
||||||
|
except Exception as exc:
|
||||||
|
logger.warning("Failed to upsert VO2 max: %s", exc)
|
||||||
|
db.rollback()
|
||||||
|
|
||||||
return processed
|
return processed
|
||||||
|
|
||||||
|
|
||||||
@@ -469,9 +494,6 @@ def _parse_day(stats, sleep_data, hrv_data) -> dict:
|
|||||||
_set(row, "active_calories", active)
|
_set(row, "active_calories", active)
|
||||||
if active and bmr:
|
if active and bmr:
|
||||||
_set(row, "total_calories", float(active) + float(bmr))
|
_set(row, "total_calories", float(active) + float(bmr))
|
||||||
vo2 = stats.get("vo2MaxPreciseValue") or stats.get("vo2Max")
|
|
||||||
if vo2 and float(vo2) > 0:
|
|
||||||
_set(row, "vo2max", float(vo2))
|
|
||||||
|
|
||||||
if sleep_data:
|
if sleep_data:
|
||||||
dto = sleep_data.get("dailySleepDTO") or sleep_data
|
dto = sleep_data.get("dailySleepDTO") or sleep_data
|
||||||
|
|||||||
Reference in New Issue
Block a user