Private
Public Access
1
0

Merge branch 'feature/wps' into develop

This commit is contained in:
Sander Roosendaal
2021-05-25 08:53:28 +02:00
6 changed files with 339900 additions and 5 deletions

View File

@@ -28,7 +28,7 @@ from rowingdata import (
from rowers.tasks import (
handle_sendemail_unrecognized,handle_setcp,
handle_getagegrouprecords
handle_getagegrouprecords, handle_update_wps
)
from rowers.tasks import handle_zip_file
@@ -135,7 +135,6 @@ from scipy.signal import savgol_filter
import datetime
def get_video_data(w,groups=['basic'],mode='water'):
modes = [mode,'both','basic']
columns = ['time','velo','spm']
@@ -1263,6 +1262,44 @@ def setcp(workout,background=False,recurrance=True):
return pd.DataFrame({'delta':[],'cp':[]}),pd.Series(dtype='float'),pd.Series(dtype='float')
def update_wps(r,types,mode='water',asynchron=True):
firstdate = datetime.date.today()-datetime.timedelta(days=r.cprange)
workouts = Workout.objects.filter(
date__gte=firstdate,
workouttype__in=types,
user = r
)
ids = [w.id for w in workouts]
if asynchron:
job = myqueue(
queue,
handle_update_wps,
r.id,
types,
ids,
mode
)
df = getsmallrowdata_db(['time','driveenergy'],ids=ids)
try:
mask = df['driveenergy'] > 100
except (KeyError, TypeError):
return False
wps_median = int(df.loc[mask,'driveenergy'].median())
if mode == 'water':
r.median_wps = wps_median
else:# pragma: no cover
r.median_wps_erg = wps_median
r.save()
return True
def update_rolling_cp(r,types,mode='water'):
firstdate = datetime.date.today()-datetime.timedelta(days=r.cprange)
workouts = Workout.objects.filter(
@@ -1801,6 +1838,8 @@ def save_workout_database(f2, r, dosmooth=True, workouttype='rower',
isbreakthrough, ishard = checkbreakthrough(w, r)
marker = check_marker(w)
result = update_wps(r,mytypes.otwtypes)
result = update_wps(r,mytypes.otetypes)
job = myqueue(queuehigh,handle_calctrimp,w.id,f2,r.ftp,r.sex,r.hrftp,r.max,r.rest)
@@ -2436,7 +2475,7 @@ def getsmallrowdata_db(columns, ids=[], doclean=True,workstrokesonly=True,comput
#df = dd.read_parquet(f,columns=columns,engine='pyarrow')
df = pd.read_parquet(f,columns=columns)
data.append(df)
except OSError: # pragma: no cover
except (OSError,ArrowInvalid): # pragma: no cover
rowdata, row = getrowdata(id=id)
if rowdata and len(rowdata.df):
datadf = dataprep(rowdata.df,id=id,bands=True,otwpower=True,barchart=True)

View File

@@ -940,6 +940,7 @@ class Rower(models.Model):
cprange = models.IntegerField(default=42,verbose_name="Range for calculation of breakthrough workouts and fitness (CP)",
choices=cppresets)
otwslack = models.IntegerField(default=0,verbose_name="OTW Power slack")
# performance manager stuff
@@ -968,6 +969,9 @@ class Rower(models.Model):
'TR',
'AN','max'])
# median WpS
median_wps = models.IntegerField(default=400,verbose_name='Median Work per Stroke (OTW)')
median_wps_erg = models.IntegerField(default=400,verbose_name='Median Work per Stroke (ergometer)')
# Site Settings
workflowleftpanel = TemplateListField(default=defaultleft)

View File

@@ -2797,6 +2797,33 @@ def add2(x, y,debug=False,**kwargs): # pragma: no cover
graphql_url = "https://rp3rowing-app.com/graphql"
@app.task
def handle_update_wps(rid,types,ids,mode,debug=False,**kwargs):
df = getsmallrowdata_db(['time','driveenergy'],ids=ids)
try:
mask = df['driveenergy'] > 100
except (KeyError, TypeError): # pragma: no cover
return 0
wps_median = int(df.loc[mask,'driveenergy'].median())
if mode == 'water':
query = "UPDATE `rowers_rower` SET `median_wps` = '%s' WHERE `id` = '%s'" % (wps_median,rid)
else:
query = "UPDATE `rowers_rower` SET `median_wps_erg` = '%s' WHERE `id` = '%s'" % (wps_median,rid)
if debug: # pragma: no cover
engine = create_engine(database_url_debug, echo=False)
else:
engine = create_engine(database_url, echo=False)
with engine.connect() as conn, conn.begin():
result = conn.execute(query)
conn.close()
engine.dispose()
return wps_median
@app.task
def handle_rp3_async_workout(userid,rp3token,rp3id,startdatetime,max_attempts,debug=False,**kwargs):
headers = {'Authorization': 'Bearer ' + rp3token }
@@ -2894,7 +2921,10 @@ def handle_nk_async_workout(alldata,userid,nktoken,nkid,delaysec,defaulttimezone
try:
data = alldata[nkid]
except KeyError: # pragma: no cover
data = alldata[int(nkid)]
try:
data = alldata[int(nkid)]
except KeyError:
return 0
params = {
'sessionIds': nkid,

View File

@@ -350,6 +350,11 @@ def mocked_getsmallrowdata_db_water(*args, **kwargs):
return df
def mocked_getsmallrowdata_db_wps(*args, **kwargs):
df = pd.read_csv('rowers/tests/testdata/driveenergies.csv')
return df
def mocked_getpowerdata_db(*args, **kwargs):
df = pd.read_csv('rowers/tests/testdata/fake_powerdata.csv')

View File

@@ -510,7 +510,7 @@ class AsyncTaskTests(TestCase):
self.assertEqual(res,1)
@patch('rowers.dataprepnodjango.getsmallrowdata_db')
def test_handle_setcp(self,mocked_getsmallrowdata_db_db_setcp):
def test_handle_setcp(self,mocked_getsmallrowdata_db_setcp):
strokesdf = pd.read_csv('rowers/tests/testdata/uhfull.csv')
filename = 'rowers/tests/testdata/temp/pq.gz'
workoutids = 1
@@ -520,3 +520,11 @@ class AsyncTaskTests(TestCase):
os.remove(filename)
except FileNotFoundError:
pass
@patch('rowers.dataprepnodjango.getsmallrowdata_db')
def test_handle_update_wps(self,mocked_getsmallrowdata_db_wps):
ids = [1,2,3]
result = tasks.handle_update_wps(self.r.id,['water'],ids,mode='water')
self.assertTrue(result>0)
result = tasks.handle_update_wps(self.r.id,['water'],ids,mode='erg')

339809
rowers/tests/testdata/driveenergies.csv vendored Normal file

File diff suppressed because it is too large Load Diff