Compare commits

..

2 Commits

Author SHA1 Message Date
David D'ALMEIDA 6752077f43 Merge remote-tracking branch 'origin/final' into final
continuous-integration/drone/push Build is passing Details
1 year ago
David D'ALMEIDA 578be65f84 try to optimize
1 year ago

@ -9,6 +9,11 @@ public static class UserMappeur
{ {
private static GenericMapper<User, AthleteEntity> _mapper = new (); private static GenericMapper<User, AthleteEntity> _mapper = new ();
public static void Reset()
{
_mapper.Reset();
}
public static User ToModel(this AthleteEntity entity) public static User ToModel(this AthleteEntity entity)
{ {
Func<AthleteEntity, User> create = athleteEntity => new User Func<AthleteEntity, User> create = athleteEntity => new User

@ -20,12 +20,14 @@ public class ActivityController : Controller
private readonly IActivityRepository _activityService; private readonly IActivityRepository _activityService;
private readonly ILogger<ActivityController> _logger; private readonly ILogger<ActivityController> _logger;
private readonly IUserRepository _userRepository; private readonly IUserRepository _userRepository;
private readonly IDataSourceRepository<DataSourceTinyDto> _dataSourceRepository;
public ActivityController(IDataManager dataManager, ILogger<ActivityController> logger) public ActivityController(IDataManager dataManager, ILogger<ActivityController> logger)
{ {
_activityService = dataManager.ActivityRepo; _activityService = dataManager.ActivityRepo;
_userRepository = dataManager.UserRepo; _userRepository = dataManager.UserRepo;
_dataSourceRepository = dataManager.DataSourceRepo;
_logger = logger; _logger = logger;
} }
@ -64,18 +66,23 @@ public class ActivityController : Controller
[HttpPost] [HttpPost]
public async Task<IActionResult> PostActivity(NewActivityDto activityDto) public async Task<IActionResult> PostActivity(NewActivityDto activityDto)
{ {
_logger.LogInformation("Executing {Action} with parameters: {Parameters}, {add}", nameof(PostActivity), activityDto.Activity.Average, activityDto.HeartRates[0].HeartRate); _logger.LogInformation("Executing {Action} with parameters: {Parameters}, {add}", nameof(PostActivity), activityDto.Activity.Average, activityDto.HeartRates[0].Timestamp);
var user = await _userRepository.GetUserById(activityDto.AthleteId); var user = await _userRepository.GetUserTinyById(activityDto.AthleteId);
if (user == null) if (user == null)
{ {
_logger.LogError("Athlete with id {id} not found", activityDto.AthleteId); _logger.LogError("Athlete with id {id} not found", activityDto.AthleteId);
return NotFound($"Athlete with id {activityDto.AthleteId} not found"); return NotFound($"Athlete with id {activityDto.AthleteId} not found");
} }
if (activityDto.DataSourceId != null && user.DataSource?.Id != activityDto.DataSourceId) if (activityDto.DataSourceId != null)
{ {
_logger.LogError("DataSource with id {id} not found for this user", activityDto.DataSourceId); var dataSource = await _dataSourceRepository.GetItemById(activityDto.DataSourceId.Value);
if (dataSource == null)
{
_logger.LogError("DataSource with id {id} not found", activityDto.DataSourceId);
return NotFound($"DataSource with id {activityDto.DataSourceId} not found"); return NotFound($"DataSource with id {activityDto.DataSourceId} not found");
} }
}
var result = await _activityService.AddActivity(activityDto); var result = await _activityService.AddActivity(activityDto);

@ -1,6 +1,10 @@
using Dto;
using Dto.Tiny; using Dto.Tiny;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Model.Manager;
using Model.Repository;
using Model.utils;
namespace HeartTrackAPI.Controllers; namespace HeartTrackAPI.Controllers;
@ -10,6 +14,53 @@ namespace HeartTrackAPI.Controllers;
[Authorize] [Authorize]
public class AnalysisController : Controller public class AnalysisController : Controller
{ {
private readonly IActivityRepository _activityService;
private readonly ILogger<AnalysisController> _logger;
public AnalysisController(IDataManager dataManager, ILogger<AnalysisController> logger)
{
_activityService = dataManager.ActivityRepo;
_logger = logger;
}
[HttpGet("activity/{activityId}")]
public async Task<IActionResult> AnalyseByActivityId(int activityId)
{
var activity = await _activityService.GetActivityById(activityId);
if (activity == null)
{
_logger.LogInformation($"Activity with ID {activityId} not found.");
return NotFound($"Activity with ID {activityId} not found.");
}
// for the moment no need to get the user Entity [Dave]
var user = activity.Athlete;
if (user == null)
{
_logger.LogInformation($"User not found for activity ID {activityId}.");
return NotFound($"User not found for activity ID {activityId}.");
}
var analysis = ActivityAnalysis.FromActivityData(activity);
return Ok(analysis);
}
}
/*
/*
public class HeartRateZoneResult
{
public string Zone { get; set; }
public TimeSpan TimeSpent { get; set; }
}
private readonly List<HeartRateZone> _heartRateZones = new() private readonly List<HeartRateZone> _heartRateZones = new()
{ {
new() { Name = "Repos", MinHeartRate = 0, MaxHeartRate = 60 }, new() { Name = "Repos", MinHeartRate = 0, MaxHeartRate = 60 },
@ -18,26 +69,32 @@ public class AnalysisController : Controller
new() { Name = "Anaérobie", MinHeartRate = 141, MaxHeartRate = 180 }, new() { Name = "Anaérobie", MinHeartRate = 141, MaxHeartRate = 180 },
new() { Name = "VO2 Max", MinHeartRate = 181, MaxHeartRate = 220 } new() { Name = "VO2 Max", MinHeartRate = 181, MaxHeartRate = 220 }
}; };
[HttpGet("heart-rate/zones/{activityId}")]
[HttpGet("heart-rate/zones")] public IActionResult GetActivityHeartRateZones(int activityId)
public IActionResult GetHeartRateZones() {
var heartRateTinyDtos = _activityService.GetActivityById(activityId).Result?.HeartRates;
if (heartRateTinyDtos != null)
{ {
var heartRates = GetMockHeartRateData(); var heartRates = heartRateTinyDtos.ToList();
var results = _heartRateZones.Select(zone => new HeartRateZoneResult var results = _heartRateZones.Select(zone => new HeartRateZoneResult
{ {
Zone = zone.Name, Zone = zone.Name,
TimeSpent = CalculateTimeInZone(zone, heartRates) TimeSpent = CalculateTimeInZone(zone, heartRates)
}).ToList(); }).ToList();
return Ok(results); return Ok(results);
} }
return NotFound("Not heart rates");
}
private TimeSpan CalculateTimeInZone(HeartRateZone zone, List<HeartRateTinyDto> heartRates) private TimeSpan CalculateTimeInZone(HeartRateZone zone, List<HeartRateTinyDto> heartRates)
{ {
var secondsInZone = var secondsInZone =
heartRates.Count(hr => hr.HeartRate >= zone.MinHeartRate && hr.HeartRate <= zone.MaxHeartRate); heartRates.Count(hr => hr.HeartRate >= zone.MinHeartRate && hr.HeartRate <= zone.MaxHeartRate);
return TimeSpan.FromSeconds(secondsInZone); return TimeSpan.FromSeconds(secondsInZone);
} }* /
/*
[HttpGet("getOptimizedPath")] [HttpGet("getOptimizedPath")]
public IActionResult GetOptimizedPath(int activityId) public IActionResult GetOptimizedPath(int activityId)
{ {
@ -57,35 +114,3 @@ public class AnalysisController : Controller
return Ok(path.ToGeoJson()); return Ok(path.ToGeoJson());
} }
*/ */
private 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();
}
}
public class HeartRateZoneResult
{
public string Zone { get; set; }
public TimeSpan TimeSpent { get; set; }
}
internal class HeartRateZone
{
public string Name { get; set; }
public int MinHeartRate { get; set; }
public int MaxHeartRate { get; set; }
}

@ -143,7 +143,7 @@ public class UsersController : Controller
try try
{ {
_logger.LogInformation("Executing {Action} with parameters: {Parameters} for {Id}", nameof(Update), user,id); _logger.LogInformation("Executing {Action} with parameters: {Parameters} for {Id}", nameof(Update), user,id);
var athlete = await _userService.GetUserById(id); var athlete = await _userService.GetUserTinyById(id);
if (athlete == null) if (athlete == null)
{ {
_logger.LogError("Athlete with id {id} not found", id); _logger.LogError("Athlete with id {id} not found", id);
@ -183,7 +183,7 @@ public class UsersController : Controller
{ {
_logger.LogInformation("Executing {Action} with parameters: {Parameters} for {Id}", nameof(Delete), null,id); _logger.LogInformation("Executing {Action} with parameters: {Parameters} for {Id}", nameof(Delete), null,id);
var athlete = await _userService.GetUserById(id); var athlete = await _userService.GetUserTinyById(id);
if (athlete == null) if (athlete == null)
{ {
_logger.LogError("Athlete with id {id} not found", id); _logger.LogError("Athlete with id {id} not found", id);

@ -1,3 +1,4 @@
using Dto.Tiny;
using Model.Repository; using Model.Repository;
namespace Model.Manager; namespace Model.Manager;
@ -6,4 +7,6 @@ public interface IDataManager
{ {
IUserRepository UserRepo { get; } IUserRepository UserRepo { get; }
IActivityRepository ActivityRepo { get; } IActivityRepository ActivityRepo { get; }
IDataSourceRepository<DataSourceTinyDto> DataSourceRepo { get; }
} }

@ -0,0 +1,6 @@
namespace Model.Repository;
public interface IDataSourceRepository<T>
{
Task<T?> GetItemById(int id);
}

@ -17,6 +17,7 @@ public interface IUserRepository : IGenericRepository<User> // Make it generic
public Task<int> GetNbFriends(int user); public Task<int> GetNbFriends(int user);
public Task<UserTinyDto?> UpdateUser(int old,UserTinyDto user); public Task<UserTinyDto?> UpdateUser(int old,UserTinyDto user);
public Task<ResponseUserDto> GetUserById(int id); public Task<ResponseUserDto> GetUserById(int id);
public Task<UserTinyDto?> GetUserTinyById(int id);
public Task<IEnumerable<User>?> GetAllAthletes(int index, int count, AthleteOrderCriteria? criteria, bool descending = false); public Task<IEnumerable<User>?> GetAllAthletes(int index, int count, AthleteOrderCriteria? criteria, bool descending = false);
public Task<IEnumerable<User>?> GetAllCoaches(int index, int count, AthleteOrderCriteria? criteria, bool descending = false); public Task<IEnumerable<User>?> GetAllCoaches(int index, int count, AthleteOrderCriteria? criteria, bool descending = false);

@ -0,0 +1,63 @@
using Model.utils;
namespace Dto.Tiny;
public class ActivityAnalysis
{
public double AverageHeartRate { get; private set; }
public string AverageHeartRateAdvice { get; private set; }
public double Vo2Max { get; private set; }
public string Vo2MaxAdvice { get; private set; }
public double NormalBpm { get; private set; }
public string NormalBpmAdvice { get; private set; }
public double HeartRateVariability { get; private set; }
public string HeartRateVariabilityAdvice { get; private set; }
public string HeartRateZone { get; private set; }
public string HeartRateZoneAdvice { get; private set; }
public double Duration { get; private set; }
public string DurationAdvice { get; private set; }
public double Effort { get; private set; }
public string EffortAdvice { get; private set; }
public static ActivityAnalysis FromActivityData(ResponseActivityDto activity)
{
double dureeActivity = (activity.EndTime - activity.StartTime).TotalMinutes;
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 = HeartRateAdvise.CalculateHeartRateZones(age);
var effortScore = HeartRateAdvise.EvaluateEffort(activity);
var (seuilBPM, vo2Max) = HeartRateAdvise.SeuilBPMavance(gender, age, poids, dureeActivity);
string averageHeartRateAdvice = HeartRateAdvise.GenerateAverageHeartRateAdvice(averageHeartRate, seuilBPM);
string vo2MaxAdvice = HeartRateAdvise.GenerateVo2MaxAdvice(vo2Max);
string normalBpmAdvice = HeartRateAdvise.GenerateNormalBpmAdvice(seuilBPM, averageHeartRate);
string hrvAdvice = HeartRateAdvise.GenerateHrvAdvice(heartRateVariability);
HeartRateAdvise.HeartRateZone currentZone = heartRateZones.Find(zone => averageHeartRate >= zone.MinHeartRate && averageHeartRate <= zone.MaxHeartRate);
string heartRateZoneAdvice = HeartRateAdvise.GenerateHeartRateZoneAdvice(currentZone?.Name);
var effortAccuracy = HeartRateAdvise.CompareEffort(effortFelt, (int)effortScore);
var analysis = new ActivityAnalysis
{
AverageHeartRate = averageHeartRate,
AverageHeartRateAdvice = averageHeartRateAdvice,
Vo2Max = vo2Max,
Vo2MaxAdvice = vo2MaxAdvice,
NormalBpm = seuilBPM,
NormalBpmAdvice = normalBpmAdvice,
HeartRateVariability = heartRateVariability,
HeartRateVariabilityAdvice = hrvAdvice,
HeartRateZone = currentZone != null ? currentZone.Name : "N/A",
HeartRateZoneAdvice = heartRateZoneAdvice,
Duration = dureeActivity,
DurationAdvice =HeartRateAdvise.GenerateDurationAdvice(dureeActivity),
Effort = effortScore,
EffortAdvice = HeartRateAdvise.GenerateEffortAdvice(effortAccuracy)
};
return analysis;
}
}

@ -0,0 +1,278 @@
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, 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.";
// 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();
}
*/

@ -0,0 +1,34 @@
using Dto.Tiny;
using Entities2Dto;
using Microsoft.Extensions.Logging;
using Model.Repository;
namespace Model2Entities;
public partial class DbDataManager
{
public class DataSourceRepository : IDataSourceRepository<DataSourceTinyDto>
{
private readonly DbDataManager _dataManager;
private readonly ILogger<DbDataManager> _logger;
public DataSourceRepository(DbDataManager dbDataManager, ILogger<DbDataManager> logger)
{
_dataManager = dbDataManager;
_logger = logger;
}
public async Task<DataSourceTinyDto?> GetItemById(int id)
{
var dataSource = await _dataManager.DbContext.DataSourcesSet.FindAsync(id);
if (dataSource == null)
{
_logger.LogInformation($"DataSource with ID {id} not found.");
return null;
}
return dataSource.ToTinyDto();
}
}
}

@ -1,4 +1,5 @@
using DbContextLib; using DbContextLib;
using Dto.Tiny;
using EFMappers; using EFMappers;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
@ -11,6 +12,8 @@ public partial class DbDataManager: IDataManager
{ {
public IActivityRepository ActivityRepo { get; } public IActivityRepository ActivityRepo { get; }
public IUserRepository UserRepo { get; } public IUserRepository UserRepo { get; }
public IDataSourceRepository<DataSourceTinyDto> DataSourceRepo { get; }
protected HeartTrackContext DbContext { get; } protected HeartTrackContext DbContext { get; }
protected readonly ILogger<DbDataManager> _logger = new Logger<DbDataManager>(new LoggerFactory()); protected readonly ILogger<DbDataManager> _logger = new Logger<DbDataManager>(new LoggerFactory());
@ -21,7 +24,9 @@ public partial class DbDataManager: IDataManager
DbContext = dbContext; DbContext = dbContext;
ActivityRepo = new ActivityRepository(this, _logger); ActivityRepo = new ActivityRepository(this, _logger);
UserRepo = new UserRepository(this, _logger); UserRepo = new UserRepository(this, _logger);
DataSourceRepo = new DataSourceRepository(this, _logger);
ActivityMapper.Reset(); ActivityMapper.Reset();
UserMappeur.Reset();
// Faire pour les autres reset() des autres mappers // Faire pour les autres reset() des autres mappers
} }
@ -34,5 +39,6 @@ public partial class DbDataManager: IDataManager
DbContext = new HeartTrackContext(); DbContext = new HeartTrackContext();
ActivityRepo = new ActivityRepository(this, _logger); ActivityRepo = new ActivityRepository(this, _logger);
UserRepo= new UserRepository(this, _logger); UserRepo= new UserRepository(this, _logger);
DataSourceRepo = new DataSourceRepository(this, _logger);
} }
} }

@ -104,6 +104,18 @@ public partial class DbDataManager
return user; return user;
} }
public Task<UserTinyDto?> GetUserTinyById(int id)
{
_logger.LogInformation($"GetTinyItemById with id {id}", id);
var userEntity = _dataManager.DbContext.AthletesSet.FindAsync(id).Result;
var user = userEntity != null ? userEntity.ToTinyDto() : null;
if (user != null)
_logger.LogInformation($"Retrieved user with ID {id}");
else
_logger.LogWarning($"No user found with ID {id}");
return Task.FromResult(user);
}
public async Task<User?> UpdateItem(int oldItem, User newItem) public async Task<User?> UpdateItem(int oldItem, User newItem)
{ {
_logger.LogInformation($"UpdateItem with id {oldItem}", oldItem); _logger.LogInformation($"UpdateItem with id {oldItem}", oldItem);

@ -108,6 +108,11 @@ public class UserService : IUserRepository
throw new NotImplementedException(); throw new NotImplementedException();
} }
public Task<UserTinyDto?> GetUserTinyById(int id)
{
throw new NotImplementedException();
}
public async Task<IEnumerable<User>> GetItems(int index, int count, string? orderingProperty = null, public async Task<IEnumerable<User>> GetItems(int index, int count, string? orderingProperty = null,
bool descending = false) bool descending = false)
=>await GetUsers(index, count, this.ToEnum(orderingProperty), descending); =>await GetUsers(index, count, this.ToEnum(orderingProperty), descending);

@ -1,3 +1,4 @@
using Dto.Tiny;
using Model.Manager; using Model.Manager;
using Model.Repository; using Model.Repository;
@ -7,6 +8,7 @@ public class StubData : IDataManager
{ {
public IUserRepository UserRepo { get; } public IUserRepository UserRepo { get; }
public IActivityRepository ActivityRepo { get; } public IActivityRepository ActivityRepo { get; }
public IDataSourceRepository<DataSourceTinyDto> DataSourceRepo { get; }
public StubData() public StubData()
{ {

Loading…
Cancel
Save