monitoring ftp
This commit is contained in:
@@ -721,23 +721,33 @@ def update_rolling_cp(r, types, mode='water'):
|
||||
powerdf.drop_duplicates(subset='Delta', keep='first', inplace=True)
|
||||
|
||||
res2 = datautils.cpfit(powerdf)
|
||||
p1 = res2[0]
|
||||
# calculate FTP
|
||||
hourseconds = 3600.
|
||||
pwr = p1[0]/(1+hourseconds/p1[2])
|
||||
pwr += p1[1]/(1+hourseconds/p1[3])
|
||||
|
||||
if len(powerdf) != 0:
|
||||
if mode == 'water':
|
||||
p1 = res2[0]
|
||||
r.p0 = p1[0]
|
||||
r.p1 = p1[1]
|
||||
r.p2 = p1[2]
|
||||
r.p3 = p1[3]
|
||||
r.cpratio = res2[3]
|
||||
r.save()
|
||||
if pwr > r.ftp*(100.-r.otwslack)/100. and r.getemailnotifications and not r.emailbounced:
|
||||
_ = myqueue(queuehigh, handle_sendemail_newftp(r,pwr,'water'))
|
||||
|
||||
else:
|
||||
p1 = res2[0]
|
||||
r.ep0 = p1[0]
|
||||
r.ep1 = p1[1]
|
||||
r.ep2 = p1[2]
|
||||
r.ep3 = p1[3]
|
||||
r.ecpratio = res2[3]
|
||||
r.save()
|
||||
if pwr > r.ftp and r.getemailnotifications and not r.emailbounced:
|
||||
_ = myqueue(queuehigh, handle_sendemail_newftp(r,pwr,'water'))
|
||||
|
||||
|
||||
return True
|
||||
return False
|
||||
|
||||
@@ -4237,9 +4237,21 @@ class SimpleRowerPowerForm(ModelForm):
|
||||
return super(SimpleRowerPowerForm, self).save(*args, **kwargs)
|
||||
|
||||
class RowerPowerForm(ModelForm):
|
||||
otwftp = forms.IntegerField(initial=0,required=False, label='FTP on water')
|
||||
class Meta:
|
||||
model = Rower
|
||||
fields = ['hrftp', 'ftp', 'otwslack','cogganzones']
|
||||
fields = ['hrftp', 'ftp','cogganzones']
|
||||
|
||||
field_order = ['hrftp', 'ftp', 'otwftp', 'cogganzones']
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(RowerPowerForm, self).__init__(*args, **kwargs)
|
||||
self.initial['otwftp'] = int((1-0.01*self.instance.otwslack)*self.instance.ftp)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
otwslack = -100.*(self.cleaned_data['otwftp']-self.cleaned_data['ftp'])/(self.cleaned_data['ftp'])
|
||||
self.instance.otwslack = otwslack
|
||||
return super(RowerPowerForm, self).save(*args, **kwargs)
|
||||
|
||||
|
||||
class RowerCPForm(ModelForm):
|
||||
|
||||
@@ -1712,6 +1712,24 @@ def handle_sendemail_expired(useremail, userfirstname, userlastname, expireddate
|
||||
d, cc=['support@rowsandall.com'], **kwargs)
|
||||
return 1
|
||||
|
||||
@app.task
|
||||
def handle_sendemail_newftp(power,rower,mode, **kwargs):
|
||||
subject = "You may want to update your FTP on rowsandall.com"
|
||||
from_email = 'Rowsandall <info@rowsandall.com>'
|
||||
|
||||
d = {
|
||||
'first_name': rower.user.first_name,
|
||||
'last_name': rower.user.last_name,
|
||||
'siteurl': siteurl,
|
||||
'ftp': r.ftp,
|
||||
'newftp': power,
|
||||
}
|
||||
|
||||
_ = send_template_email(from_email, [r.user.email],
|
||||
subject, 'newftpemail.html',
|
||||
d, **kwargs)
|
||||
|
||||
return 1
|
||||
|
||||
@app.task
|
||||
def handle_sendemail_breakthrough(workoutid, useremail,
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
{% load rowerfilters %}
|
||||
<h1><a href="/rowers/me/edit/">Profile</a></h1>
|
||||
<ul class="cd-accordion-menu animated">
|
||||
<li id="manage-prefs">
|
||||
<a href="/rowers/me/preferences/">
|
||||
<i class="fas fa-cog fa-fw"></i> Zones & Fitness
|
||||
<li id="manage-prefs-simple">
|
||||
<a href="/rowers/me/prefs/">
|
||||
<i class="fas fa-sliders-v-square fa-fw"></i> Threshold
|
||||
</a>
|
||||
</li>
|
||||
<li id="manage-impex">
|
||||
@@ -27,6 +27,11 @@
|
||||
<i class="fas fa-tachometer-alt-slow fa-fw"></i> Manage Workflow
|
||||
</a>
|
||||
</li>
|
||||
<li id="manage-prefs">
|
||||
<a href="/rowers/me/preferences/">
|
||||
<i class="fas fa-cog fa-fw"></i> Zones & Fitness, detailed
|
||||
</a>
|
||||
</li>
|
||||
{% if user.is_authenticated and user.is_staff %}
|
||||
<li id="manage-transactions">
|
||||
<a href="/rowers/me/transactions/">
|
||||
|
||||
@@ -17,6 +17,19 @@
|
||||
<input type="submit" value="Update">
|
||||
</form>
|
||||
</li>
|
||||
<li class="grid_2">
|
||||
<p>
|
||||
The Functional Threshold Power (FTP) is the power you can hold
|
||||
for an hour all out. If you haven't done a full out hour, you
|
||||
can also take a full out 20 minutes effort and take 95% of it.
|
||||
</p>
|
||||
<p>
|
||||
If you do not row with a power meter on the water, the FTP on
|
||||
water is irrelevant. If you do not know your 20 minute or full
|
||||
hour full out power value on the water, take 85% of your indoor
|
||||
rowing value.
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
@@ -234,7 +234,7 @@ class UserPreferencesTest(TestCase):
|
||||
form_data = {
|
||||
'hrftp': 160,
|
||||
'ftp':230,
|
||||
'otwslack':14
|
||||
'otwftp':224
|
||||
}
|
||||
|
||||
form = RowerPowerForm(form_data)
|
||||
|
||||
@@ -242,6 +242,7 @@ from rowers.rows import handle_uploaded_file, handle_uploaded_image
|
||||
from rowers.plannedsessions import *
|
||||
from rowers.tasks import handle_makeplot, handle_otwsetpower, handle_sendemailtcx, handle_sendemailcsv
|
||||
from rowers.tasks import (
|
||||
handle_sendemail_newftp,
|
||||
instroke_static,
|
||||
fetch_rojabo_session,
|
||||
handle_sendemail_unrecognized, handle_sendemailnewcomment,
|
||||
|
||||
@@ -650,14 +650,13 @@ def rower_prefs_view(request, userid=0, message=""):
|
||||
successmessage = "Your Heart Rate data were changed"
|
||||
messages.info(request, successmessage)
|
||||
elif request.method == 'POST' and "ftp" in request.POST:
|
||||
powerform = RowerPowerForm(request.POST)
|
||||
powerform = RowerPowerForm(request.POST, instance=r)
|
||||
if powerform.is_valid():
|
||||
powerform.save(commit=True)
|
||||
cd = powerform.cleaned_data
|
||||
hrftp = cd['hrftp']
|
||||
if hrftp == 0: # pragma: no cover
|
||||
hrftp = int((r.an+r.tr)/2.)
|
||||
ftp = cd['ftp']
|
||||
otwslack = cd['otwslack']
|
||||
cogganzones = cd['cogganzones']
|
||||
|
||||
powerfrac = 100*np.array([r.pw_ut2,
|
||||
@@ -674,7 +673,6 @@ def rower_prefs_view(request, userid=0, message=""):
|
||||
'Anaerobic']
|
||||
r.powerzones = powerzones
|
||||
|
||||
r.ftp = max(min(ftp, 650), 50)
|
||||
ut2, ut1, at, tr, an = (r.ftp*powerfrac/100.).astype(int)
|
||||
r.pw_ut2 = ut2
|
||||
r.pw_ut1 = ut1
|
||||
@@ -682,7 +680,6 @@ def rower_prefs_view(request, userid=0, message=""):
|
||||
r.pw_tr = tr
|
||||
r.pw_an = an
|
||||
r.hrftp = hrftp
|
||||
r.otwslack = max(min(otwslack, 50), 0)
|
||||
r.save()
|
||||
powerzonesform = RowerPowerZonesForm(instance=r)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user