You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
API/src/Model/utils/HeartRateAdvise.cs

279 lines
13 KiB

using Dto;
namespace Model.utils;
public class HeartRateAdvise
{
public class HeartRateZone
{
public string Name { get; set; }
public int MinHeartRate { get; set; }
public int MaxHeartRate { get; set; }
}
public string getAdvise(Activity activity)
{
return "You should take a break";
}
public static List<HeartRateZone> CalculateHeartRateZones(int age)
{
int fcm = 220 - age; // Estimation de la FCM
List<HeartRateZone> zones = new List<HeartRateZone>
{
new HeartRateZone { Name = "Très Légère", MinHeartRate = (int)(fcm * 0.50), MaxHeartRate = (int)(fcm * 0.60) },
new HeartRateZone { Name = "Aérobie légère", MinHeartRate = (int)(fcm * 0.60), MaxHeartRate = (int)(fcm * 0.70) },
new HeartRateZone { Name = "Aérobie", MinHeartRate = (int)(fcm * 0.70), MaxHeartRate = (int)(fcm * 0.80) },
new HeartRateZone { Name = "Anaérobie", MinHeartRate = (int)(fcm * 0.80), MaxHeartRate = (int)(fcm * 0.90) },
new HeartRateZone { Name = "Maximum", MinHeartRate = (int)(fcm * 0.90), MaxHeartRate = (int)(fcm * 1.00) }
};
return zones;
}
public static double EvaluateEffort(ResponseActivityDto stats)
{
double score = 0;
score += stats.Average * 0.3; // Exemple de poids
score += stats.HeartRates.Average(speed => speed.Speed ?? 0) * 0.25;
score += stats.HeartRates.Sum(dist => dist.Distance ?? 0) * 0.15;
score += stats.HeartRates.Average(hr => hr.Cadence ?? 0) * 0.1;
score += stats.HeartRates.Average(hr => hr.Power ?? 0) * 0.15;
score += stats.StandardDeviation * 0.05;
return score;
}
public static string CompareEffort(int perceivedEffort, int objectiveEffort)
{
if (perceivedEffort == objectiveEffort) return "Accurate";
if (perceivedEffort > objectiveEffort) return "Overestimated";
if (perceivedEffort < objectiveEffort) return "Underestimated";
return "Unknown";
}
// Faible intensité : 50-60% de la FCM
// Intensité modérée : 60-70% de la FCM
// Haute intensité : 70-85% de la FCM
public static double CalculerVo2Max(char sexe, int age, double poids)
{
if (sexe == 'M')
{
return (poids * 0.198) + (age * -0.193) + 24.489;
}
// sexe == "F"
{
return (poids * 0.201) + (age * -0.217) + 20.453;
}
}
public static (double SeuilBPM, double Vo2Max) SeuilBPMavance(char sexe, int age, double poids, double dureeActivite)
{
double fcm = sexe == 'M' ? 207 - (0.7 * age) : 206 - (0.88 * age);
double vo2Max = CalculerVo2Max(sexe, age, poids);
double zone = dureeActivite <= 30 ? 0.8 : dureeActivite <= 60 ? 0.7 : 0.6;
double seuilBpm = fcm * zone;
return (seuilBpm, vo2Max);
}
public static Dictionary<string, (double Value, string Advice)> GenerateAdvice(ResponseActivityDto activity)
{
int dureeActivity = (activity.EndTime - activity.StartTime).Minutes;
var age = DateTime.Today.Year - activity.Athlete.DateOfBirth.Year;
var gender = activity.Athlete.Sexe;
var poids = activity.Athlete.Weight;
var effortFelt = activity.EffortFelt;
var averageHeartRate = activity.Average;
var heartRateVariability = activity.Variability;
var heartRateZones = CalculateHeartRateZones(age);
var effortScore = EvaluateEffort(activity);
var (seuilBPM, vo2Max) = SeuilBPMavance(gender, age, poids, dureeActivity);
Dictionary<string, (double Value, string Advice)> healthMetrics = new Dictionary<string, (double Value, string Advice)>();
// Conseil pour AverageHeartRate
string averageHeartRateAdvice = averageHeartRate > seuilBPM
? "Votre rythme cardiaque moyen est supérieur au seuil recommandé. Envisagez de réduire l'intensité."
: "Votre rythme cardiaque moyen est dans une bonne plage. Continuez à maintenir votre intensité actuelle.";
// Conseil pour Vo2Max
string vo2MaxAdvice;
if (vo2Max < 30)
vo2MaxAdvice =
"Votre Vo2 max est faible, envisagez d'augmenter progressivement l'intensité de vos entraînements.";
else if (vo2Max < 40)
vo2MaxAdvice = "Votre Vo2 max est dans la moyenne. Continuez de travailler sur votre endurance.";
else vo2MaxAdvice = "Votre Vo2 max est excellente. Vous pourriez bénéficier d'entraînements à haute intensité.";
// Conseil basé sur la comparaison avec NormalBpm
string normalBpmAdvice = seuilBPM > averageHeartRate
? "Votre BPM normal est plus élevé que la moyenne, assurez-vous de surveiller votre intensité d'entraînement."
: "Votre BPM normal est inférieur à la moyenne, ce qui peut indiquer un bon niveau de forme physique.";
// Conseil pour HeartRateVariability
string hrvAdvice = heartRateVariability < 40
? "Votre HRV est basse, ce qui peut indiquer un stress élevé ou une récupération insuffisante. Envisagez d'améliorer votre récupération."
: heartRateVariability < 60
? "Votre HRV est dans une plage moyenne. Continuez de surveiller votre récupération et votre stress."
: "Votre HRV est élevée, indiquant une bonne récupération et une gestion du stress. Continuez vos bonnes pratiques de gestion de la santé.";
HeartRateZone currentZone = heartRateZones.Find(zone =>
averageHeartRate >= zone.MinHeartRate && averageHeartRate <= zone.MaxHeartRate);
string heartRateZoneAdvice;
if (currentZone != null)
{
heartRateZoneAdvice = $"Votre BPM moyen est dans la zone '{currentZone.Name}', qui est idéale pour ";
switch (currentZone.Name)
{
case "Repos":
heartRateZoneAdvice += "favoriser la récupération.";
break;
case "Endurance":
heartRateZoneAdvice += "améliorer l'endurance cardiovasculaire et brûler des graisses.";
break;
case "Aérobie":
heartRateZoneAdvice += "améliorer votre capacité aérobie.";
break;
case "Anaérobie":
heartRateZoneAdvice += "améliorer la performance à haute intensité.";
break;
case "VO2 Max":
heartRateZoneAdvice += "maximiser la performance et la capacité aérobie.";
break;
default:
heartRateZoneAdvice =
"Cette zone est spécifique et peut avoir différents objectifs en fonction de votre plan d'entraînement.";
break;
}
}
else
{
heartRateZoneAdvice =
"Vous n'êtes dans aucune zone spécifique. Assurez-vous que votre BPM moyen est correctement mesuré.";
}
// Comparaison de l'effort objectif avec l'effort perçu
var effortAccuracy = CompareEffort(effortFelt, (int)effortScore);
// Remplissage du dictionnaire
healthMetrics.Add("AverageHeartRate", (averageHeartRate, averageHeartRateAdvice));
healthMetrics.Add("Vo2Max", (vo2Max, vo2MaxAdvice));
healthMetrics.Add("NormalBpm", (seuilBPM, normalBpmAdvice));
healthMetrics.Add("HeartRateVariability", (heartRateVariability, hrvAdvice));
healthMetrics.Add("HeartRateZone", (averageHeartRate, heartRateZoneAdvice));
healthMetrics.Add("Duration",
(dureeActivity,
dureeActivity < 75
? "Vous pourriez augmenter la durée de vos activités pour atteindre les recommandations."
: "Votre durée d'activité est conforme aux recommandations."));
healthMetrics.Add("Effort", (effortScore, GenerateEffortAdvice(effortAccuracy)));
return healthMetrics;
}
public static string GenerateAverageHeartRateAdvice(float averageHeartRate, double seuilBPM)
{
return averageHeartRate > seuilBPM
? "Votre rythme cardiaque moyen est supérieur au seuil recommandé. Envisagez de réduire l'intensité."
: "Votre rythme cardiaque moyen est dans une bonne plage. Continuez à maintenir votre intensité actuelle.";
}
public static string GenerateVo2MaxAdvice(double vo2Max)
{
if (vo2Max < 30)
return "Votre Vo2 max est faible, envisagez d'augmenter progressivement l'intensité de vos entraînements.";
if (vo2Max < 40)
return "Votre Vo2 max est dans la moyenne. Continuez de travailler sur votre endurance.";
return "Votre Vo2 max est excellente. Vous pourriez bénéficier d'entraînements à haute intensité.";
}
public static string GenerateNormalBpmAdvice(double normalBpm,double averageHeartRate)
{
return normalBpm > averageHeartRate
? "Votre BPM normal est plus élevé que la moyenne, ce qui peut indiquer un bon niveau de forme physique."
: "Votre BPM normal est inférieur à la moyenne, assurez-vous de surveiller votre intensité d'entraînement.";
}
public static string GenerateHrvAdvice(double heartRateVariability)
{
return heartRateVariability < 40
? "Votre HRV est basse, ce qui peut indiquer un stress élevé ou une récupération insuffisante. Envisagez d'améliorer votre récupération."
: heartRateVariability < 60
? "Votre HRV est dans une plage moyenne. Continuez de surveiller votre récupération et votre stress."
: "Votre HRV est élevée, indiquant une bonne récupération et une gestion du stress. Continuez vos bonnes pratiques de gestion de la santé.";
}
public static string GenerateHeartRateZoneAdvice(string? heartRateZone)
{
return heartRateZone switch
{
"Repos" => "Favoriser la récupération.",
"Endurance" => "Améliorer l'endurance cardiovasculaire et brûler des graisses.",
"Aérobie" => "Améliorer votre capacité aérobie.",
"Anaérobie" => "Améliorer la performance à haute intensité.",
"VO2 Max" => "Maximiser la performance et la capacité aérobie.",
_ => "Cette zone est spécifique et peut avoir différents objectifs en fonction de votre plan d'entraînement."
};
}
public static string GenerateDurationAdvice(double dureeActivity)
{
return dureeActivity < 75
? "Vous pourriez augmenter la durée de vos activités pour atteindre les recommandations."
: "Votre durée d'activité est conforme aux recommandations.";
}
public static string GenerateEffortAdvice(string effortAccuracy)
{
return effortAccuracy switch
{
"Accurate" => "Votre perception de l'effort est précise. Continuez ainsi!",
"Overestimated" => "Vous surestimez votre effort. Essayez de pousser un peu plus lors de vos prochaines activités.",
"Underestimated" => "Vous sous-estimez votre effort. Vous pourriez être plus proche de vos limites que vous ne le pensez.",
_ => "Continuez à surveiller et ajuster votre effort pour de meilleurs résultats."
};
}
}
/*
public class EffortAnalysisResult
{
public string EffortAccuracy { get; set; }
public string Advice { get; set; }
}
public EffortAnalysisResult AnalyzeActivityEffort(ResponseActivityDto activity)
{
var effortScore = EvaluateEffort(activity);
// Comparaison de l'effort objectif avec l'effort perçu
var effortAccuracy = CompareEffort(activity.EffortFelt, (int)effortScore);
var result = new EffortAnalysisResult
{
EffortAccuracy = effortAccuracy,
Advice = GenerateEffortAdvice(effortAccuracy)
};
return result;
}
public List<HeartRateTinyDto> GetMockHeartRateData()
{
var random = new Random();
return Enumerable.Range(1, 3600)
.Select(_ => new HeartRateTinyDto
{
HeartRate = random.Next(60, 220),
Timestamp = new DateTime(2021, 1, 1).AddSeconds(random.Next(3600)),
Latitude = random.NextDouble() * 180 - 90,
Longitude = random.NextDouble() * 360 - 180,
Altitude = random.NextDouble() * 1000,
Cadence = random.Next(60, 120),
Distance = random.NextDouble() * 100,
Speed = random.NextDouble() * 30,
Power = random.Next(0, 500),
Temperature = random.NextDouble() * 30
}).ToList();
}
*/