adding apprimxate_rscore
This commit is contained in:
@@ -43,7 +43,7 @@ def get_contacts(rower):
|
||||
return r['id']
|
||||
|
||||
|
||||
return None
|
||||
return None # pragma: no cover
|
||||
|
||||
# this should be triggered on braintree payment
|
||||
def create_contact(rower):
|
||||
|
||||
@@ -2357,6 +2357,7 @@ class PlannedSession(models.Model):
|
||||
|
||||
approximate_distance = models.IntegerField(default=0,verbose_name='Approximate Distance')
|
||||
approximate_duration = models.IntegerField(default=0,verbose_name='Approximate Duration')
|
||||
approximate_rscore = models.IntegerField(default=0,verbose_name='Approximate rScore')
|
||||
|
||||
max_nr_of_workouts = models.IntegerField(
|
||||
default=0,verbose_name='Maximum number of workouts'
|
||||
@@ -2508,14 +2509,17 @@ class PlannedSession(models.Model):
|
||||
|
||||
# calculate approximate distance
|
||||
if self.steps:
|
||||
sdict, totalmeters, totalseconds = ps_dict_order(self.steps)
|
||||
sdict, totalmeters, totalseconds, totalrscore = ps_dict_order(self.steps)
|
||||
self.approximate_distance = int(totalmeters)
|
||||
self.approximate_duration = int(totalseconds/60.)
|
||||
self.approximate_rscore = int(totalrscore)
|
||||
self.criterium = 'none'
|
||||
if self.sessionmode == 'time':
|
||||
self.sessionvalue = self.approximate_duration
|
||||
elif self.sessionmode == 'distance': # pragma: no cover
|
||||
self.sessionvalue = self.approximate_distance
|
||||
elif self.sessionmode == 'rscore': # pragma: no cover
|
||||
self.sessionvalue = self.approximate_rscore
|
||||
|
||||
|
||||
super(PlannedSession,self).save(*args, **kwargs)
|
||||
|
||||
@@ -86,7 +86,7 @@ from rowers.tasks import (
|
||||
from rowers.utils import totaltime_sec_to_string
|
||||
|
||||
def ps_dict_get_description(d,short=False): # pragma: no cover
|
||||
sdict,totalmeters,totalseconds = ps_dict_order(d,short=short)
|
||||
sdict,totalmeters,totalseconds,totalrscore = ps_dict_order(d,short=short)
|
||||
s = ''
|
||||
for item in sdict:
|
||||
s += item['string']+'\n'
|
||||
@@ -94,7 +94,7 @@ def ps_dict_get_description(d,short=False): # pragma: no cover
|
||||
return s
|
||||
|
||||
def ps_dict_get_description_html(d,short=False):
|
||||
sdict,totalmeters,totalseconds = ps_dict_order(d,short=short)
|
||||
sdict,totalmeters,totalseconds,totalrscore = ps_dict_order(d,short=short)
|
||||
|
||||
s = '<ul>'
|
||||
|
||||
|
||||
@@ -144,7 +144,7 @@ def createsporttracksworkoutdata(w):
|
||||
duration += w.duration.minute*60
|
||||
duration += w.duration.second
|
||||
duration += +1.0e-6*w.duration.microsecond
|
||||
except AttributeError:
|
||||
except AttributeError: # pragma: no cover
|
||||
return 0
|
||||
|
||||
# adding diff, trying to see if this is valid
|
||||
|
||||
@@ -1912,6 +1912,24 @@ description: ""
|
||||
response = download_fit(request,filename=self.ps_trimp.fitfile)
|
||||
self.assertTrue('File not found' in context.exception)
|
||||
|
||||
@patch('rowers.garmin_stuff.requests.post', side_effect=mocked_requests)
|
||||
@patch('rowers.utils.requests.post', side_effect=mocked_requests)
|
||||
@patch('rowers.garmin_stuff.OAuth1Session', side_effect=MockOAuth1Session)
|
||||
def test_plannedsession_steps_power(self,mockpost,mock_post,MockOAuth1Session):
|
||||
self.ps_trimp.interval_string = '30min@200W'
|
||||
self.ps_trimp.save()
|
||||
|
||||
self.assertEqual(self.ps_trimp.approximate_rscore,50)
|
||||
|
||||
@patch('rowers.garmin_stuff.requests.post', side_effect=mocked_requests)
|
||||
@patch('rowers.utils.requests.post', side_effect=mocked_requests)
|
||||
@patch('rowers.garmin_stuff.OAuth1Session', side_effect=MockOAuth1Session)
|
||||
def test_plannedsession_steps_spm(self,mockpost,mock_post,MockOAuth1Session):
|
||||
self.ps_trimp.interval_string = '60min@18spm'
|
||||
self.ps_trimp.save()
|
||||
|
||||
self.assertEqual(self.ps_trimp.approximate_rscore,72)
|
||||
|
||||
|
||||
def test_plannedsessions_dateform_view(self):
|
||||
login = self.c.login(username=self.u.username, password=self.password)
|
||||
|
||||
204
rowers/utils.py
204
rowers/utils.py
@@ -585,13 +585,14 @@ def steps_write_fit(steps):
|
||||
|
||||
return filename
|
||||
|
||||
def step_to_time_dist(step,avgspeed = 3.7):
|
||||
def step_to_time_dist(step,avgspeed = 3.2,ftp=200,ftspm=25,ftv=3.7):
|
||||
seconds = 0
|
||||
distance = 0
|
||||
rscore = 0
|
||||
durationtype = step['durationType']
|
||||
|
||||
if step['durationValue'] == 0: # pragma: no cover
|
||||
return 0,0
|
||||
return 0,0,0
|
||||
|
||||
try:
|
||||
targettype = step['targetType']
|
||||
@@ -607,39 +608,125 @@ def step_to_time_dist(step,avgspeed = 3.7):
|
||||
|
||||
|
||||
if targettype == 'Speed':
|
||||
value = step['targetValue']
|
||||
valuelow = step['targetValueLow']
|
||||
valuehigh = step['targetValueHigh']
|
||||
|
||||
if value != 0: # pragma: no cover
|
||||
distance = seconds*value
|
||||
value = step.get('targetValue',0)
|
||||
valuelow = step.get('targetValueLow',0)
|
||||
valuehigh = step.get('targetValueHigh',0)
|
||||
velomid = 0.
|
||||
if value != 0:
|
||||
distance = seconds*value/1000.
|
||||
velomid = value/1000.
|
||||
elif valuelow != 0 and valuehigh != 0: # pragma: no cover
|
||||
distance = seconds*(valuelow+valuehigh)/2.
|
||||
velomid = (valuelow+valuehigh)/2000.
|
||||
|
||||
return seconds,distance
|
||||
veloratio = (velomid/ftv)**(3.0)
|
||||
rscoreperhour = 100.*veloratio
|
||||
rscore = rscoreperhour*seconds/3600.
|
||||
|
||||
if targettype == 'Power':
|
||||
value = step.get('targetValue',0)
|
||||
valuelow = step.get('targetValueLow',0)
|
||||
valuehigh = step.get('targetValueHigh',0)
|
||||
|
||||
if value != 0:
|
||||
if value < 10 and value > 0: # pragma: no cover
|
||||
targetpower = ftp*0.6
|
||||
elif value > 10 and value < 1000: # pragma: no cover
|
||||
targetpower = value*ftp/100.
|
||||
elif value > 1000:
|
||||
targetpower = value-1000
|
||||
avgspeed = ftv*(targetpower/ftp)**(1./3.)
|
||||
distance = avgspeed*seconds
|
||||
avgpower = targetpower
|
||||
if valuelow != 0 and valuehigh != 0: # pragma: no cover
|
||||
avgpower = (valuelow+valuehigh)/2.
|
||||
avgspeed = ftv*(avgspeed/ftv)**(1./3.)
|
||||
distance = avgspeed*seconds
|
||||
|
||||
rscore = 100.*(avgpower/ftp)*seconds/3600.
|
||||
|
||||
if targettype == 'Cadence':
|
||||
value = step.get('targetValue',0)
|
||||
valuelow = step.get('targetValueLow',0)
|
||||
valuehigh = step.get('targetValueHigh',0)
|
||||
|
||||
if value != 0:
|
||||
avgpower = ftp*value/ftspm
|
||||
if valuelow != 0 and valuehigh != 0: # pragma: no cover
|
||||
avgspm = (valuelow+valuehigh)/2.
|
||||
avgpower = ftp*avgspm/ftspm
|
||||
|
||||
rscore = 100*(avgpower/ftp)*seconds/3600.
|
||||
|
||||
return seconds,distance,rscore
|
||||
elif durationtype == 'Distance': # pragma: no cover
|
||||
value = step['durationValue']
|
||||
distance = value/100.
|
||||
seconds = distance/avgspeed
|
||||
|
||||
if targettype == 'Speed':
|
||||
value = step['targetValue']
|
||||
valuelow = step['targetValueLow']
|
||||
valuehigh = step['targetValueHigh']
|
||||
value = step.get('targetValue',0)
|
||||
valuelow = step.get('targetValueLow',0)
|
||||
valuehigh = step.get('targetValueHigh',0)
|
||||
velomid = 0
|
||||
|
||||
if value != 0: # pragma: no cover
|
||||
seconds = distance/value
|
||||
velomid = value/1000.
|
||||
elif valuelow != 0 and valuehigh != 0: # pragma: no cover
|
||||
midspeed = (valuelow+valuehigh)/2.
|
||||
seconds = distance/midspeed
|
||||
velomid = (valuelow+valuehigh)/2000.
|
||||
seconds = distance/velomid
|
||||
|
||||
return seconds, distance
|
||||
veloratio = (velomid/ftv)**(3.0)
|
||||
rscoreperhour = 100.*veloratio
|
||||
rscore = rscoreperhour*seconds/3600.
|
||||
|
||||
if targettype == 'Power':
|
||||
value = step.get('targetValue',0)
|
||||
valuelow = step.get('targetValueLow',0)
|
||||
valuehigh = step.get('targetValueHigh',0)
|
||||
|
||||
if value != 0:
|
||||
if value < 10 and value > 0:
|
||||
targetpower = ftp*0.6
|
||||
elif value > 10 and value < 1000:
|
||||
targetpower = value*ftp/100.
|
||||
elif value > 1000:
|
||||
targetpower = value-1000
|
||||
avgspeed = ftv*(targetpower/ftp)**(1./3.)
|
||||
seconds = distance/avgspeed
|
||||
avgpower = targetpower
|
||||
if valuelow != 0 and valuehigh != 0:
|
||||
avgpower = (valuelow+valuehigh)/2.
|
||||
avgspeed = ftv*(avgspeed/ftv)**(1./3.)
|
||||
seconds = distance/avgspeed
|
||||
|
||||
rscore = 100.*(avgpower/ftp)*seconds/3600.
|
||||
|
||||
if targettype == 'Cadence':
|
||||
value = step.get('targetValue',0)
|
||||
valuelow = step.get('targetValueLow',0)
|
||||
valuehigh = step.get('targetValueHigh',0)
|
||||
|
||||
if value != 0:
|
||||
avgpower = ftp*value/ftspm
|
||||
if valuelow != 0 and valuehigh != 0:
|
||||
avgspm = (valuelow+valuehigh)/2.
|
||||
avgpower = ftp*avgspm/ftspm
|
||||
|
||||
rscore = 100*(avgpower/ftp)*seconds/3600.
|
||||
|
||||
return seconds, distance, rscore
|
||||
elif durationtype in ['PowerLessThan','PowerGreaterThan','HrLessThan','HrGreaterThan']: # pragma: no cover
|
||||
seconds = 600
|
||||
distance = seconds*avgspeed
|
||||
return seconds,distance
|
||||
veloratio = (avgspeed/ftv)**(3.0)
|
||||
rscoreperhour = 100.*veloratio
|
||||
rscore = rscoreperhour*seconds/3600.
|
||||
|
||||
return seconds,distance
|
||||
return seconds,distance,rscore
|
||||
|
||||
return seconds,distance, rscore
|
||||
|
||||
def get_step_type(step): # pragma: no cover
|
||||
t = 'WorkoutStep'
|
||||
@@ -677,7 +764,7 @@ def ps_dict_order_dict(d,short=False):
|
||||
sdicts = []
|
||||
for step in steps:
|
||||
sstring, type, stepID, repeatID, repeatValue = step_to_string(step,short=short)
|
||||
seconds, meters = step_to_time_dist(step)
|
||||
seconds, meters,rscore = step_to_time_dist(step)
|
||||
|
||||
sdict = {
|
||||
'type':type,
|
||||
@@ -698,7 +785,7 @@ def ps_dict_order(d,short=False):
|
||||
|
||||
for step in steps:
|
||||
sstring, type, stepID, repeatID, repeatValue = step_to_string(step,short=short)
|
||||
seconds, meters = step_to_time_dist(step)
|
||||
seconds, meters,rscore = step_to_time_dist(step)
|
||||
|
||||
sdict[stepID] = {
|
||||
'string':sstring,
|
||||
@@ -708,6 +795,7 @@ def ps_dict_order(d,short=False):
|
||||
'repeatValue': repeatValue,
|
||||
'seconds': seconds,
|
||||
'meters': meters,
|
||||
'rscore': rscore,
|
||||
}
|
||||
|
||||
|
||||
@@ -715,7 +803,7 @@ def ps_dict_order(d,short=False):
|
||||
|
||||
for step in steps:
|
||||
sstring, type, stepID, repeatID, repeatValue = step_to_string(step,short=short)
|
||||
seconds, meters = step_to_time_dist(step)
|
||||
seconds, meters, rscore = step_to_time_dist(step)
|
||||
|
||||
sdict[stepID] = {
|
||||
'string':sstring,
|
||||
@@ -725,6 +813,7 @@ def ps_dict_order(d,short=False):
|
||||
'repeatValue': repeatValue,
|
||||
'seconds': seconds,
|
||||
'meters': meters,
|
||||
'rscore': rscore,
|
||||
}
|
||||
|
||||
sdict2 = collections.OrderedDict(reversed(list(sdict.items())))
|
||||
@@ -736,6 +825,7 @@ def ps_dict_order(d,short=False):
|
||||
spaces = ''
|
||||
totalmeters = 0
|
||||
totalseconds = 0
|
||||
totalrscore = 0
|
||||
factor = 1
|
||||
|
||||
for key, item in sdict2.items():
|
||||
@@ -750,6 +840,7 @@ def ps_dict_order(d,short=False):
|
||||
sdict3.append(item)
|
||||
totalmeters += factor*item['meters']
|
||||
totalseconds += factor*item['seconds']
|
||||
totalrscore += factor*item['rscore']
|
||||
if len(holduntil)>0 and item['stepID'] <= holduntil[-1]:
|
||||
if item['stepID'] == holduntil[-1]:
|
||||
sdict3.append(hold.pop())
|
||||
@@ -772,7 +863,7 @@ def ps_dict_order(d,short=False):
|
||||
|
||||
sdict = list(reversed(sdict3))
|
||||
|
||||
return sdict,totalmeters,totalseconds
|
||||
return sdict,totalmeters,totalseconds,totalrscore
|
||||
|
||||
def step_to_string(step,short=False):
|
||||
type = 'Step'
|
||||
@@ -827,7 +918,7 @@ def step_to_string(step,short=False):
|
||||
duration = 'until HR>{v}'.format(v=value/100)
|
||||
elif durationtype == 'PowerLessThan': # pragma: no cover
|
||||
value = step['durationValue']
|
||||
targetvalue = step['targetvalue']
|
||||
targetvalue = step.get('targetValue',0)
|
||||
if value <= 1000:
|
||||
duration = 'Repeat until Power is less than {targetvalue} % of FTP'.format(
|
||||
targetvalue=targetvalue
|
||||
@@ -842,7 +933,7 @@ def step_to_string(step,short=False):
|
||||
'until < {targetvalue} W'.format(targetvalue=targetvalue-1000)
|
||||
elif durationtype == 'PowerGreaterThan': # pragma: no cover
|
||||
value = step['durationValue']
|
||||
targetvalue = step['targetvalue']
|
||||
targetvalue = step.get('targetValue',0)
|
||||
if value <= 1000:
|
||||
duration = 'Repeat until Power is greater than {targetvalue} % of FTP'.format(
|
||||
targetvalue=targetvalue
|
||||
@@ -860,10 +951,10 @@ def step_to_string(step,short=False):
|
||||
ntimes = ': {v}x'.format(v=step['targetValue'])
|
||||
repeatID = step['durationValue']
|
||||
duration =ntimes
|
||||
repeatValue = step['targetValue']
|
||||
repeatValue = step.get('targetValue',0)
|
||||
elif durationtype == 'RepeatUntilHrGreaterThan': # pragma: no cover
|
||||
type = 'RepeatStep'
|
||||
targetvalue = step['targetValue']
|
||||
targetvalue = step.get('targetValue',0)
|
||||
if targetvalue <= 100:
|
||||
duration = 'Repeat until Heart Rate is greater than {targetvalue} % of max'.format(
|
||||
targetvalue=targetvalue
|
||||
@@ -879,7 +970,7 @@ def step_to_string(step,short=False):
|
||||
repeatID = step['durationValue']
|
||||
elif durationtype == 'RepeatUntilHrLessThan': # pragma: no cover
|
||||
type = 'RepeatStep'
|
||||
targetvalue = step['targetValue']
|
||||
targetvalue = step.get('targetValue',0)
|
||||
if targetvalue <= 100:
|
||||
duration = 'Repeat until Heart Rate is less than {targetvalue} % of max'.format(
|
||||
targetvalue=targetvalue
|
||||
@@ -903,18 +994,9 @@ def step_to_string(step,short=False):
|
||||
targettype = None
|
||||
|
||||
if targettype == 'HeartRate': # pragma: no cover
|
||||
try:
|
||||
value = step['targetValue']
|
||||
except KeyError:
|
||||
value = 0
|
||||
try:
|
||||
valuelow = step['targetValueLow']
|
||||
except KeyError:
|
||||
valuelow = 0
|
||||
try:
|
||||
valuehigh = step['targetValueHigh']
|
||||
except KeyError:
|
||||
valuehigh = 0
|
||||
value = step.get('targetValue',0)
|
||||
valuelow = step.get('targetValueLow',0)
|
||||
valuehigh = step.get('targetValueHigh',0)
|
||||
|
||||
if value < 10 and value>0:
|
||||
target = '@ HR zone {v}'.format(v=value)
|
||||
@@ -930,18 +1012,9 @@ def step_to_string(step,short=False):
|
||||
h = valuehigh - 100,
|
||||
)
|
||||
elif targettype == 'Power': # pragma: no cover
|
||||
try:
|
||||
value = step['targetValue']
|
||||
except KeyError:
|
||||
value = 0
|
||||
try:
|
||||
valuelow = step['targetValueLow']
|
||||
except KeyError:
|
||||
valuelow = 0
|
||||
try:
|
||||
valuehigh = step['targetValueHigh']
|
||||
except KeyError:
|
||||
valuehigh = 0
|
||||
value = step.get('targetValue',0)
|
||||
valuelow = step.get('targetValueLow',0)
|
||||
valuehigh = step.get('targetValueHigh',0)
|
||||
|
||||
if value < 10 and value>0:
|
||||
target = '@ Power zone {v}'.format(v=value)
|
||||
@@ -961,18 +1034,10 @@ def step_to_string(step,short=False):
|
||||
h = valuehigh-1000,
|
||||
)
|
||||
elif targettype == 'Speed': # pragma: no cover
|
||||
try:
|
||||
value = step['targetValue']
|
||||
except KeyError:
|
||||
value = 0
|
||||
try:
|
||||
valuelow = step['targetValueLow']
|
||||
except KeyError:
|
||||
valuelow = 0
|
||||
try:
|
||||
valuehigh = step['targetValueHigh']
|
||||
except KeyError:
|
||||
valuehigh = 0
|
||||
|
||||
value = step.get('targetValue',0)
|
||||
valuelow = step.get('targetValueLow',0)
|
||||
valuehigh = step.get('targetValueHigh',0)
|
||||
|
||||
if value != 0:
|
||||
v = value/1000.
|
||||
@@ -1004,18 +1069,9 @@ def step_to_string(step,short=False):
|
||||
ph = pacestringhigh,
|
||||
)
|
||||
elif targettype == 'Cadence': # pragma: no cover
|
||||
try:
|
||||
value = step['targetValue']
|
||||
except KeyError:
|
||||
value = 0
|
||||
try:
|
||||
valuelow = step['targetValueLow']
|
||||
except KeyError:
|
||||
valuelow = 0
|
||||
try:
|
||||
valuehigh = step['targetValueHigh']
|
||||
except KeyError:
|
||||
valuehigh = 0
|
||||
value = step.get('targetValue',0)
|
||||
valuelow = step.get('targetValueLow',0)
|
||||
valuehigh = step.get('targetValueHigh',0)
|
||||
|
||||
if value != 0:
|
||||
target = '@ {v} SPM'.format(v=value)
|
||||
|
||||
@@ -2380,6 +2380,7 @@ def plannedsession_view(request,id=0,userid=0):
|
||||
'sessionmode','criterium',
|
||||
'sessionvalue','sessionunit',
|
||||
'approximate_distance','approximate_duration',
|
||||
'approximate_rscore',
|
||||
'comment',
|
||||
],
|
||||
'workouts': ws,
|
||||
|
||||
Reference in New Issue
Block a user