diff --git a/rowers/fitness.py b/rowers/fitness.py index bcced876..2d2986cc 100644 --- a/rowers/fitness.py +++ b/rowers/fitness.py @@ -17,9 +17,9 @@ def weightfromrecord(row,metricchoice): return 0 # pragma: no cover -def getfatigues(df, fatigues, fitnesses, dates, impulses, startdate, kfatigue, kfitness): - fatigue = 0 - fitness = 0 +def getfatigues(df, fatigues, fitnesses, dates, impulses, startdate, kfatigue, kfitness,actualfitness=0, actualfatigue=0): + fatigue = actualfatigue + fitness = actualfitness impulses = [] for f in fatigues: @@ -57,13 +57,28 @@ def getfatigues(df, fatigues, fitnesses, dates, impulses, startdate, kfatigue, k return fatigues, fitnesses, dates, impulses -def calculate_fitness(rower): - workouts = Workout.objects.filter(user=rower, date__gte=datetime.date.today() - datetime.timedelta(days=90), - duplicate=False).order_by('date') +def calculate_fitness(rower, reset=False): + try: + w_last = Workout.objects.get(id=rower.last_workout) + datetime_last = w_last.startdatetime + except Workout.DoesNotExist: + w_last = None + datetime_last = datetime.datetime.now() - datetime.timedelta(days=90) + + if reset: + rower.last_workout = 0 + rower.actualfit = 0 + rower.actualfatigue = 0 + rower.save() + datetime_last = datetime.datetime.now() - datetime.timedelta(days=90) + + workouts = Workout.objects.filter(user=rower, startdatetime__gt=datetime_last, + duplicate=False).order_by('date').exclude(id=rower.last_workout) kfitness = rower.kfit kfatigue = rower.kfatigue - + actualfitness = rower.actualfit + actualfatigue = rower.actualfatigue records = [] @@ -81,13 +96,15 @@ def calculate_fitness(rower): df = pl.from_records(records) if df.is_empty(): - return 0, 0 + return actualfitness, actualfatigue dates = [arrow.get(w.date).datetime for w in workouts] impulses = [np.nan for w in workouts] fitnesses = [np.nan for w in workouts] fatigues = [np.nan for w in workouts] + + fatigues, fitnesses, dates, impulses = getfatigues( df, fatigues, @@ -95,7 +112,9 @@ def calculate_fitness(rower): dates, impulses, datetime.date.today()-datetime.timedelta(days=90), - kfatigue, kfitness + kfatigue, kfitness, + actualfitness=actualfitness, + actualfatigue=actualfatigue, ) df = pl.DataFrame({ @@ -105,8 +124,15 @@ def calculate_fitness(rower): 'impulse': impulses, }) - endfitness = fitnesses[-2] - endfatigue = fatigues[-2] + endfitness = fitnesses[-1] + endfatigue = fatigues[-1] + + if workouts: + enddate = workouts.last().date + rower.last_workout = workouts.last().id + rower.actualfit = int(endfitness) + rower.actualfatigue = int(endfatigue) + rower.save() return endfitness, endfatigue diff --git a/rowers/forms.py b/rowers/forms.py index 45a545bb..0ce79b0c 100644 --- a/rowers/forms.py +++ b/rowers/forms.py @@ -316,17 +316,6 @@ class MetricsForm(forms.Form): class CNsummaryForm(forms.Form): file = forms.FileField(required=True, validators=[must_be_csv]) -class CurrentWeekJsonForm(forms.Form): - plan = forms.CharField(required=True, label="Plan Code", initial="zwolsche") - secret = forms.CharField(required=True, label="Plan Secret", initial="noot") - delete_existing = forms.BooleanField(required=False, initial=False, label="Remove any existing sessions") - -class NextWeekJsonForm(forms.Form): - plan = forms.CharField(required=True, label="Plan Code", initial="zwolsche") - secret = forms.CharField(required=True, label="Plan Secret", initial="noot") - fitness = forms.IntegerField(required=False, label='Fitness', initial=0) - fatigue = forms.IntegerField(required=False, label='Fatigue', initial=0) - delete_existing = forms.BooleanField(required=False, initial=False, label="Remove any existing sessions") # The little window to type '4x2000m/500m' to update the workout summary diff --git a/rowers/models.py b/rowers/models.py index 43665c5b..611574d4 100644 --- a/rowers/models.py +++ b/rowers/models.py @@ -1129,6 +1129,10 @@ class Rower(models.Model): showfit = models.BooleanField(default=False) showfresh = models.BooleanField(default=False) + actualfit = models.IntegerField(default=0, verbose_name='Actual Fitness') + actualfatigue = models.IntegerField(default=0, verbose_name='Actual Fatigue') + last_workout = models.BigIntegerField(default=0, verbose_name='Last Workout ID') + pw_ut2 = models.IntegerField(default=124, verbose_name="UT2 Power") pw_ut1 = models.IntegerField(default=171, verbose_name="UT1 Power") pw_at = models.IntegerField(default=203, verbose_name="AT Power") @@ -1175,6 +1179,8 @@ class Rower(models.Model): workoutnametemplate = WorkoutNameTemplateField(default=['date','name','distance','ownerfirst','ownerlast','duration','boattype','workouttype']) # Access tokens + training_plan_code = models.CharField(default='', max_length=200, blank=True, null=True) + training_plan_secret = models.CharField(default='', max_length=200, blank=True, null=True) c2token = models.CharField( default='', max_length=200, blank=True, null=True) tokenexpirydate = models.DateTimeField(blank=True, null=True) @@ -5205,6 +5211,47 @@ class RowerBillingAddressForm(ModelForm): super(RowerBillingAddressForm, self).__init__(*args, **kwargs) self.fields['country'].required = True +class NextWeekPlanForm(ModelForm): + # add some extra fields save_credentials and delete_existing to the form + delete_existing = forms.BooleanField(required=False, initial=False, label="Remove any existing sessions") + save_credentials = forms.BooleanField(required=False, initial=False, label="Save credentials for next time") + + class Meta: + model = Rower + fields = ['training_plan_code', + 'training_plan_secret', + 'actualfit', + 'actualfatigue'] + + def __init__(self, *args, **kwargs): + super(NextWeekPlanForm, self).__init__(*args, **kwargs) + + def clean(self): + cleaned_data = super(NextWeekPlanForm, self).clean() + plan = cleaned_data.get('training_plan_code') + secret = cleaned_data.get('training_plan_secret') + save_credentials = cleaned_data.get('save_credentials') + fitness = cleaned_data.get('actualfit') + fatigue = cleaned_data.get('actualfatigue') + + if not fitness or not fatigue: + raise forms.ValidationError("You need to fill in fitness and fatigue") + + r = self.instance + r.actualfit = fitness + r.actualfatigue = fatigue + w = Workout.objects.filter(user=r).order_by('-date').exclude(duplicate=True) + r.last_workout = w.last().id + r.save() + + if not plan or not secret: + raise forms.ValidationError("Plan Code and Secret are required") + if save_credentials: + r.training_plan_code = plan + r.training_plan_secret = secret + r.save() + + return cleaned_data # Form to set rower's Email and Weight category class AccountRowerForm(ModelForm): diff --git a/rowers/templates/loadcurrentweek.html b/rowers/templates/loadcurrentweek.html new file mode 100644 index 00000000..62e78d5d --- /dev/null +++ b/rowers/templates/loadcurrentweek.html @@ -0,0 +1,24 @@ +{% extends "newbase.html" %} +{% load static %} +{% load rowerfilters %} + +{% block title %}Planned Sessions{% endblock %} + +{% block main %} + +