Files
Home_assistant/backend/app/fitness/activity_budget.py
T
2026-06-16 04:38:23 +00:00

69 lines
1.7 KiB
Python

from __future__ import annotations
from typing import Any
DEFAULT_MET = 5.0
MET_BY_KEYWORD: list[tuple[str, float]] = [
("триатлон", 10.0),
("марафон", 9.8),
("бег", 9.8),
("running", 9.8),
("run", 9.0),
("плаван", 8.0),
("swim", 8.0),
("велосипед", 7.5),
("cycling", 7.5),
("вел", 7.5),
("hiit", 8.0),
("кроссфит", 8.0),
("силов", 6.0),
("strength", 6.0),
("зал", 5.5),
("gym", 5.5),
("йога", 3.0),
("yoga", 3.0),
("ходьб", 3.5),
("walk", 3.5),
("прогул", 3.5),
]
def infer_met(workout: dict[str, Any]) -> float | None:
explicit = workout.get("met")
if explicit is not None:
return float(explicit)
activity_type = str(workout.get("activity_type") or "").lower()
title = str(workout.get("title") or "").lower()
notes = str(workout.get("notes") or "").lower()
haystack = f"{activity_type} {title} {notes}"
for keyword, met in MET_BY_KEYWORD:
if keyword in haystack:
return met
return None
def estimate_workout_active_kcal(workout: dict[str, Any], *, weight_kg: float) -> float:
active = workout.get("active_calories")
if active is not None:
return round(float(active), 1)
duration = workout.get("duration_min")
if not duration:
return 0.0
met = infer_met(workout)
if met is None:
return 0.0
hours = float(duration) / 60.0
return round(met * weight_kg * hours, 1)
def workouts_kcal_total(workouts: list[dict[str, Any]], *, weight_kg: float) -> float:
if not workouts:
return 0.0
return round(sum(estimate_workout_active_kcal(w, weight_kg=weight_kg) for w in workouts), 1)