Private
Public Access
1
0

adding splits to C2 workout export

This commit is contained in:
Sander Roosendaal
2019-10-31 11:45:44 +01:00
parent 102efa2cf2
commit d4f311c612

View File

@@ -120,7 +120,7 @@ def c2_open(user):
if (timezone.now()>r.tokenexpirydate):
res = rower_c2_token_refresh(user)
if res == None:
raise NoTokenError("User has no token")
raise NoTokenError("User has no token")
if res[0] != None:
thetoken = res[0]
else:
@@ -156,7 +156,7 @@ def get_c2_workouts(rower):
if not isprorower(rower):
return 0
try:
thetoken = c2_open(rower.user)
except NoTokenError:
@@ -181,7 +181,7 @@ def get_c2_workouts(rower):
]
knownc2ids = uniqify(knownc2ids+tombstones)
newids = [c2id for c2id in c2ids if not c2id in knownc2ids]
for c2id in newids:
@@ -267,7 +267,7 @@ def c2wc(weightclass):
# Concept2 logbook sends over split data for each interval
# We use it here to generate a custom summary
# Some users complained about small differences
# Some users complained about small differences
def summaryfromsplitdata(splitdata,data,filename,sep='|'):
totaldist = data['distance']
@@ -310,17 +310,17 @@ def summaryfromsplitdata(splitdata,data,filename,sep='|'):
restvelo = restdistance/resttime
except (ZeroDivisionError,OverflowError):
restvelo = 0
restpower = 2.8*restvelo**(3.0)
try:
avgdps = totaldist/data['stroke_count']
except (ZeroDivisionError,OverflowError,KeyError):
avgdps = 0
from rowingdata import summarystring,workstring,interval_string
sums = summarystring(totaldist,totaltime,avgpace,spm,avghr,maxhr,
avgdps,avgpower,readFile=filename,
separator=sep)
@@ -336,16 +336,16 @@ def summaryfromsplitdata(splitdata,data,filename,sep='|'):
sums += '#-{sep}SDist{sep}-Split-{sep}-SPace-{sep}-Pwr-{sep}SPM-{sep}AvgHR{sep}MaxHR{sep}DPS-\n'.format(
sep=sep
)
intervalnr=0
sa = []
results = []
try:
timebased = data['workout_type'] in ['FixedTimeSplits','FixedTimeInterval']
except KeyError:
timebased = False
for interval in splitdata:
idist = interval['distance']
itime = interval['time']/10.
@@ -373,7 +373,7 @@ def summaryfromsplitdata(splitdata,data,filename,sep='|'):
if timebased:
iarr = [itime,'seconds','work']
resarr = [idist]
if irest_time > 0:
iarr += [irest_time,'seconds','rest']
try:
@@ -390,7 +390,7 @@ def summaryfromsplitdata(splitdata,data,filename,sep='|'):
else:
ivelo = 0
ipower = 0
sums += interval_string(intervalnr,idist,itime,ipace,ispm,
iavghr,imaxhr,0,ipower,separator=sep)
intervalnr+=1
@@ -398,14 +398,14 @@ def summaryfromsplitdata(splitdata,data,filename,sep='|'):
return sums,sa,results
# Not used now. Could be used to add workout split data to Concept2
# logbook but needs to be reviewed.
# logbook but needs to be reviewed.
def createc2workoutdata_as_splits(w):
filename = w.csvfilename
row = rowingdata(csvfile=filename)
# resize per minute
df = row.df.groupby(lambda x:x/60).mean()
averagehr = int(df[' HRCur (bpm)'].mean())
maxhr = int(df[' HRCur (bpm)'].max())
@@ -443,7 +443,7 @@ def createc2workoutdata_as_splits(w):
wtype = w.workouttype
if wtype in otwtypes:
wtype = 'water'
data = {
"type": wtype,
"date": w.startdatetime.isoformat(),
@@ -467,7 +467,7 @@ def createc2workoutdata_as_splits(w):
def createc2workoutdata(w):
filename = w.csvfilename
try:
row = rowingdata(filename)
row = rowingdata(csvfile=filename)
except IOError:
return 0
@@ -478,19 +478,45 @@ def createc2workoutdata(w):
averagehr = 0
maxhr = 0
# Calculate intervalstats
itime, idist, itype = row.intervalstats_values()
lapnames = row.df[' lapIdx'].unique()
nrintervals = len(itime)
if len(lapnames != nrintervals):
newlapnames = []
for name in lapnames:
newlapnames += [name,name]
lapnames = newlapnames
intervaldata = []
for i in range(nrintervals):
if itime[i]>0:
mask = (row.df[' lapIdx'] == lapnames[i]) & (row.df[' WorkoutState'] == itype[i])
spmav = int(row.df[' Cadence (stokes/min)'][mask].mean().astype(int))
hrav = int(row.df[' HRCur (bpm)'][mask].mean().astype(int))
intervaldict = {
'type': 'distance',
'time': int(10*itime[i]),
'distance': int(idist[i]),
'heart_rate': {
'average':hrav,
},
'stroke_rate': spmav,
}
intervaldata.append(intervaldict)
# adding diff, trying to see if this is valid
t = 10*row.df.loc[:,'TimeStamp (sec)'].values-10*row.df.loc[:,'TimeStamp (sec)'].iloc[0]
try:
t[0] = t[1]
except IndexError:
pass
d = 10*row.df.loc[:,' Horizontal (meters)'].values
try:
d[0] = d[1]
except IndexError:
pass
p = abs(10*row.df.loc[:,' Stroke500mPace (sec/500m)'].values)
p = np.clip(p,0,3600)
if w.workouttype == 'bike':
@@ -516,7 +542,7 @@ def createc2workoutdata(w):
p = p.tolist()
spm = spm.tolist()
hr = hr.tolist()
for i in range(len(t)):
thisrecord = {"t":t[i],
"d":d[i],
@@ -547,14 +573,18 @@ def createc2workoutdata(w):
"time": int(10*makeseconds(durationstr)),
"weight_class": c2wc(w.weightcategory),
"comments": w.notes,
'stroke_rate': int(row.df[' Cadence (stokes/min)'].mean()),
'drag_factor': int(row.dragfactor),
"heart_rate": {
"average": averagehr,
"max": maxhr,
},
"stroke_data": stroke_data,
'workout': {
'splits': intervaldata,
}
}
return data
# Refresh Concept2 authorization token
@@ -570,7 +600,7 @@ def do_refresh_token(refreshtoken):
url = "https://log.concept2.com/oauth/access_token"
s = Session()
req = Request('POST',url, data=post_data, headers=headers)
prepped = req.prepare()
prepped.body+="&scope="
prepped.body+=scope
@@ -672,7 +702,7 @@ def get_workout(user,c2id):
url = "https://log.concept2.com/api/users/me/results/"+str(c2id)
s = requests.get(url,headers=headers)
data = s.json()['data']
splitdata = None
@@ -694,7 +724,7 @@ def get_workout(user,c2id):
strokedata = pd.DataFrame()
else:
strokedata = pd.DataFrame()
return data,strokedata
# Get stroke data belonging to C2 ID
@@ -740,7 +770,7 @@ def get_c2_workout_list(user,page=1):
return s
# Get username, having access token.
# Handy for checking if the API access is working
def get_username(access_token):
@@ -751,7 +781,7 @@ def get_username(access_token):
import urllib
url = "https://log.concept2.com/api/users/me"
response = requests.get(url,headers=headers)
me_json = response.json()
@@ -776,14 +806,14 @@ def get_userid(access_token):
response = requests.get(url,headers=headers)
except:
return 0
me_json = response.json()
try:
res = me_json['data']['id']
except KeyError:
res = 0
return res
# For debugging purposes
@@ -799,7 +829,7 @@ def process_callback(request):
return HttpResponse("got a user name: %s" % username)
def default(o):
if isinstance(o, numpy.int64): return int(o)
if isinstance(o, numpy.int64): return int(o)
raise TypeError
# Uploading workout
@@ -810,7 +840,7 @@ def workout_c2_upload(user,w):
return "This workout type cannot be uploaded to Concept2",0
except KeyError:
return "This workout type cannot be uploaded to Concept2",0
thetoken = c2_open(user)
r = Rower.objects.get(user=user)
@@ -825,7 +855,7 @@ def workout_c2_upload(user,w):
if data == 0:
return "Error: No data file. Contact info@rowsandall.com if the problem persists",0
authorizationstring = str('Bearer ' + r.c2token)
headers = {'Authorization': authorizationstring,
'user-agent': 'sanderroosendaal',
@@ -849,7 +879,7 @@ def workout_c2_upload(user,w):
else:
message = "Something went wrong in workout_c2_upload_view. Response code 200/201 but C2 sync failed: "+response.text
c2id = 0
return message,c2id
@@ -882,7 +912,7 @@ def add_workout_from_data(user,importid,data,strokedata,
workouttype = mytypes.c2mappinginv[data['type']]
except KeyError:
workouttype = 'rower'
if workouttype not in [x[0] for x in Workout.workouttypes]:
workouttype = 'other'
try:
@@ -902,14 +932,14 @@ def add_workout_from_data(user,importid,data,strokedata,
rowdatetime = iso8601.parse_date(data['start_date'])
except ParseError:
rowdatetime = iso8601.parse_date(data['date'])
try:
c2intervaltype = data['workout_type']
except KeyError:
c2intervaltype = ''
try:
title = data['name']
except KeyError:
@@ -951,7 +981,7 @@ def add_workout_from_data(user,importid,data,strokedata,
spm = strokedata.loc[:,'spm']
except KeyError:
spm = 0*dist2
try:
hr = strokedata.loc[:,'hr']
except KeyError:
@@ -966,7 +996,7 @@ def add_workout_from_data(user,importid,data,strokedata,
velo = 1000./pace
pace = 500./velo
# save csv
# Create data frame with all necessary data to write to csv
df = pd.DataFrame({'TimeStamp (sec)':unixtime,
@@ -988,9 +1018,9 @@ def add_workout_from_data(user,importid,data,strokedata,
' ElapsedTime (sec)':seconds
})
df.sort_values(by='TimeStamp (sec)',ascending=True)
timestr = strftime("%Y%m%d-%H%M%S")
@@ -1024,6 +1054,6 @@ def add_workout_from_data(user,importid,data,strokedata,
dosummary=True
)
return id,message