Merge branch 'release/v6.40'
This commit is contained in:
+5
-1
@@ -2305,13 +2305,17 @@ def dataprep(rowdatadf, id=0, bands=True, barchart=True, otwpower=True,
|
|||||||
|
|
||||||
def workout_trimp(workout):
|
def workout_trimp(workout):
|
||||||
r = workout.user
|
r = workout.user
|
||||||
|
if r.hrftp == 0:
|
||||||
hrftp = (r.an+r.tr)/2.
|
hrftp = (r.an+r.tr)/2.
|
||||||
|
r.hrftp = hrftp
|
||||||
|
r.save()
|
||||||
|
|
||||||
df,row = getrowdata_db(id=workout.id)
|
df,row = getrowdata_db(id=workout.id)
|
||||||
df = clean_df_stats(df,workstrokesonly=False)
|
df = clean_df_stats(df,workstrokesonly=False)
|
||||||
if df.empty:
|
if df.empty:
|
||||||
df,row = getrowdata_db(id=workout.id)
|
df,row = getrowdata_db(id=workout.id)
|
||||||
df = clean_df_stats(df,workstrokesonly=False)
|
df = clean_df_stats(df,workstrokesonly=False)
|
||||||
trimp,hrtss = calc_trimp(df,r.sex,r.max,r.rest,hrftp)
|
trimp,hrtss = calc_trimp(df,r.sex,r.max,r.rest,r.hrftp)
|
||||||
trimp = int(trimp)
|
trimp = int(trimp)
|
||||||
hrtss = int(hrtss)
|
hrtss = int(hrtss)
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,15 @@ nometrics = [
|
|||||||
'totalangle',
|
'totalangle',
|
||||||
'hr_bottom',
|
'hr_bottom',
|
||||||
'x_right',
|
'x_right',
|
||||||
|
'Position',
|
||||||
|
'Extensions',
|
||||||
|
'GPS Speed',
|
||||||
|
'Split (IMP)',
|
||||||
|
'Speed (IMP)',
|
||||||
|
'driveenergy',
|
||||||
|
'Distance/Stroke (IMP)',
|
||||||
|
'Distance/Stroke (GPS)',
|
||||||
|
'Distance (IMP)',
|
||||||
'equivergpower',
|
'equivergpower',
|
||||||
'cum_dist.1'
|
'cum_dist.1'
|
||||||
]
|
]
|
||||||
|
|||||||
+2
-1
@@ -478,6 +478,7 @@ class Rower(models.Model):
|
|||||||
at = models.IntegerField(default=160,verbose_name="AT band lower HR")
|
at = models.IntegerField(default=160,verbose_name="AT band lower HR")
|
||||||
tr = models.IntegerField(default=167,verbose_name="TR band lower HR")
|
tr = models.IntegerField(default=167,verbose_name="TR band lower HR")
|
||||||
an = models.IntegerField(default=180,verbose_name="AN band lower HR")
|
an = models.IntegerField(default=180,verbose_name="AN band lower HR")
|
||||||
|
hrftp = models.IntegerField(default=0,verbose_name="FTP heart rate")
|
||||||
|
|
||||||
# Weight Category (for sync to C2)
|
# Weight Category (for sync to C2)
|
||||||
weightcategory = models.CharField(default="hwt",
|
weightcategory = models.CharField(default="hwt",
|
||||||
@@ -1427,7 +1428,7 @@ class RowerExportForm(ModelForm):
|
|||||||
class RowerPowerForm(ModelForm):
|
class RowerPowerForm(ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Rower
|
model = Rower
|
||||||
fields = ['ftp','otwslack']
|
fields = ['hrftp','ftp','otwslack']
|
||||||
|
|
||||||
# Form to set rower's Power zones, including test routines
|
# Form to set rower's Power zones, including test routines
|
||||||
# to enable consistency
|
# to enable consistency
|
||||||
|
|||||||
@@ -52,10 +52,11 @@
|
|||||||
<div id="plotbuttons" class="grid_12 alpha">
|
<div id="plotbuttons" class="grid_12 alpha">
|
||||||
|
|
||||||
|
|
||||||
<div id="x-axis" class="grid_6 alpha">
|
<div id="x-axis" class="grid_9 alpha">
|
||||||
<div class="grid_2 alpha dropdown">
|
<div class="grid_3 alpha dropdown">
|
||||||
<button class="grid_2 alpha button blue small dropbtn">X-axis</button>
|
<button class="grid_2 alpha button blue small dropbtn">X-axis</button>
|
||||||
<div class="dropdown-content">
|
<div class="dropdown-content">
|
||||||
|
<div style="float: left; width:67%;">
|
||||||
{% for key, value in axchoicesbasic.items %}
|
{% for key, value in axchoicesbasic.items %}
|
||||||
{% if key != 'None' %}
|
{% if key != 'None' %}
|
||||||
<a class="button blue small alpha" href="/rowers/workout/{{ id }}/flexchart/{{ key }}/{{ yparam1 }}/{{ yparam2 }}/{{ plottype }}">{{ value }}</a>
|
<a class="button blue small alpha" href="/rowers/workout/{{ id }}/flexchart/{{ key }}/{{ yparam1 }}/{{ yparam2 }}/{{ plottype }}">{{ value }}</a>
|
||||||
@@ -70,6 +71,8 @@
|
|||||||
<a class="button rosy small" href="/rowers/promembership">{{ value }}</a>
|
<a class="button rosy small" href="/rowers/promembership">{{ value }}</a>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div style="float: right; width: 33%;">
|
||||||
{% if promember %}
|
{% if promember %}
|
||||||
{% for key, value in extrametrics.items %}
|
{% for key, value in extrametrics.items %}
|
||||||
<a class="button orange small" href="/rowers/workout/{{ id }}/flexchart/{{ key }}/{{ yparam1 }}/{{ yparam2 }}/{{ plottype }}">{{ value }}</a>
|
<a class="button orange small" href="/rowers/workout/{{ id }}/flexchart/{{ key }}/{{ yparam1 }}/{{ yparam2 }}/{{ plottype }}">{{ value }}</a>
|
||||||
@@ -81,10 +84,12 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="left-y" class="grid_2 dropdown">
|
<div id="left-y" class="grid_3 dropdown">
|
||||||
<button class="grid_2 alpha button blue small dropbtn">Left</button>
|
<button class="grid_2 alpha button blue small dropbtn">Left</button>
|
||||||
<div class="dropdown-content">
|
<div class="dropdown-content">
|
||||||
|
<div style="float: left; width:67%;">
|
||||||
{% for key, value in axchoicesbasic.items %}
|
{% for key, value in axchoicesbasic.items %}
|
||||||
{% if key not in noylist and key != 'None' %}
|
{% if key not in noylist and key != 'None' %}
|
||||||
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ key }}/{{ yparam2 }}/{{ plottype }}">{{ value }}</a>
|
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ key }}/{{ yparam2 }}/{{ plottype }}">{{ value }}</a>
|
||||||
@@ -103,6 +108,8 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div style="float: right; width:33%;">
|
||||||
{% if promember %}
|
{% if promember %}
|
||||||
{% for key, value in extrametrics.items %}
|
{% for key, value in extrametrics.items %}
|
||||||
<a class="button orange small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ key }}/{{ yparam2 }}/{{ plottype }}">{{ value }}</a>
|
<a class="button orange small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ key }}/{{ yparam2 }}/{{ plottype }}">{{ value }}</a>
|
||||||
@@ -114,10 +121,12 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="right-y" class="grid_2 dropdown omega">
|
<div id="right-y" class="grid_3 dropdown omega">
|
||||||
<button class="grid_2 alpha button blue small dropbtn">Right</button>
|
<button class="grid_2 alpha button blue small dropbtn">Right</button>
|
||||||
<div class="dropdown-content">
|
<div class="dropdown-content">
|
||||||
|
<div style="float: left; width:67%;">
|
||||||
{% for key, value in axchoicesbasic.items %}
|
{% for key, value in axchoicesbasic.items %}
|
||||||
{% if key not in noylist %}
|
{% if key not in noylist %}
|
||||||
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/{{ key }}/{{ plottype }}">{{ value }}</a>
|
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/{{ key }}/{{ plottype }}">{{ value }}</a>
|
||||||
@@ -136,6 +145,8 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div style="float: right; width:33%;">
|
||||||
{% if promember %}
|
{% if promember %}
|
||||||
{% for key, value in extrametrics.items %}
|
{% for key, value in extrametrics.items %}
|
||||||
<a class="button orange small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/{{ key }}/{{ plottype }}">{{ value }}</a>
|
<a class="button orange small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/{{ key }}/{{ plottype }}">{{ value }}</a>
|
||||||
@@ -145,13 +156,13 @@
|
|||||||
<a class="button rosy small" href="/rowers/promembership">{{ value }} (Pro)</a>
|
<a class="button rosy small" href="/rowers/promembership">{{ value }} (Pro)</a>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="y-axis" class="grid_6 omega">
|
<div id="y-axis" class="grid_3 omega">
|
||||||
<div class="grid_2 alpha tooltip">
|
<div class="grid_2 alpha tooltip">
|
||||||
<form enctype="multipart/form-data" action="{{ formloc }}" method="post">
|
<form enctype="multipart/form-data" action="{{ formloc }}" method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
@@ -165,11 +176,12 @@
|
|||||||
</form>
|
</form>
|
||||||
<span class="tooltiptext">If your data source allows, this will show or hide strokes taken during rest intervals.</span>
|
<span class="tooltiptext">If your data source allows, this will show or hide strokes taken during rest intervals.</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="grid_2">
|
<div class="grid_1 omega">
|
||||||
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/{{ yparam2 }}/line">Line Plot</a>
|
{% if plottype == 'scatter' %}
|
||||||
</div>
|
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/{{ yparam2 }}/line">Line</a>
|
||||||
<div class="grid_2 omega">
|
{% else %}
|
||||||
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/{{ yparam2 }}/scatter">Scatter Plot</a>
|
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/{{ yparam2 }}/scatter">Scatter</a>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
+9
-1
@@ -7336,9 +7336,11 @@ def instroke_view(request,id=0):
|
|||||||
|
|
||||||
return HttpResponseRedirect(url)
|
return HttpResponseRedirect(url)
|
||||||
|
|
||||||
|
from metrics import nometrics
|
||||||
rowdata = rrdata(csvfile=row.csvfilename)
|
rowdata = rrdata(csvfile=row.csvfilename)
|
||||||
try:
|
try:
|
||||||
instrokemetrics = rowdata.get_instroke_columns()
|
instrokemetrics = rowdata.get_instroke_columns()
|
||||||
|
instrokemetrics = [m for m in instrokemetrics if not m in nometrics]
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
instrokemetrics = []
|
instrokemetrics = []
|
||||||
|
|
||||||
@@ -7427,6 +7429,7 @@ def instroke_chart(request,id=0,metric=''):
|
|||||||
rowdata = rrdata(csvfile=w.csvfilename)
|
rowdata = rrdata(csvfile=w.csvfilename)
|
||||||
instrokemetrics = rowdata.get_instroke_columns()
|
instrokemetrics = rowdata.get_instroke_columns()
|
||||||
|
|
||||||
|
|
||||||
if metric in instrokemetrics:
|
if metric in instrokemetrics:
|
||||||
f1 = w.csvfilename[6:-4]
|
f1 = w.csvfilename[6:-4]
|
||||||
timestr = strftime("%Y%m%d-%H%M%S")
|
timestr = strftime("%Y%m%d-%H%M%S")
|
||||||
@@ -8456,6 +8459,7 @@ def workout_flexchart3_view(request,*args,**kwargs):
|
|||||||
if d['mode'] == 'water':
|
if d['mode'] == 'water':
|
||||||
axchoicespro.pop(name)
|
axchoicespro.pop(name)
|
||||||
|
|
||||||
|
from rowers.metrics import nometrics
|
||||||
|
|
||||||
rowdata = rdata(row.csvfilename)
|
rowdata = rdata(row.csvfilename)
|
||||||
try:
|
try:
|
||||||
@@ -8464,6 +8468,7 @@ def workout_flexchart3_view(request,*args,**kwargs):
|
|||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
additionalmetrics = rowdata.get_additional_metrics()
|
additionalmetrics = rowdata.get_additional_metrics()
|
||||||
|
additionalmetrics = [m for m in additionalmetrics if not m in nometrics]
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
additionalmetrics = []
|
additionalmetrics = []
|
||||||
|
|
||||||
@@ -8474,7 +8479,6 @@ def workout_flexchart3_view(request,*args,**kwargs):
|
|||||||
yparam1 = yparam1.replace('/','_slsh_')
|
yparam1 = yparam1.replace('/','_slsh_')
|
||||||
yparam2 = yparam2.replace('/','_slsh_')
|
yparam2 = yparam2.replace('/','_slsh_')
|
||||||
|
|
||||||
from rowers.metrics import nometrics
|
|
||||||
|
|
||||||
for metric in nometrics:
|
for metric in nometrics:
|
||||||
try:
|
try:
|
||||||
@@ -11298,6 +11302,9 @@ def rower_edit_view(request,rowerid=0,message=""):
|
|||||||
powerform = RowerPowerForm(request.POST)
|
powerform = RowerPowerForm(request.POST)
|
||||||
if powerform.is_valid():
|
if powerform.is_valid():
|
||||||
cd = powerform.cleaned_data
|
cd = powerform.cleaned_data
|
||||||
|
hrftp = cd['hrftp']
|
||||||
|
if hrftp == 0:
|
||||||
|
hrftp = int((r.an+r.tr)/2.)
|
||||||
ftp = cd['ftp']
|
ftp = cd['ftp']
|
||||||
otwslack = cd['otwslack']
|
otwslack = cd['otwslack']
|
||||||
try:
|
try:
|
||||||
@@ -11313,6 +11320,7 @@ def rower_edit_view(request,rowerid=0,message=""):
|
|||||||
r.pw_at = at
|
r.pw_at = at
|
||||||
r.pw_tr = tr
|
r.pw_tr = tr
|
||||||
r.pw_an = an
|
r.pw_an = an
|
||||||
|
r.hrftp = hrftp
|
||||||
r.save()
|
r.save()
|
||||||
message = "FTP and/or OTW slack values changed."
|
message = "FTP and/or OTW slack values changed."
|
||||||
messages.info(request,message)
|
messages.info(request,message)
|
||||||
|
|||||||
Reference in New Issue
Block a user