diff --git a/rowers/c2stuff.py b/rowers/c2stuff.py index 6b193151..be2d1fae 100644 --- a/rowers/c2stuff.py +++ b/rowers/c2stuff.py @@ -196,7 +196,6 @@ def get_c2_workouts(rower,do_async=True): knownc2ids = uniqify(knownc2ids+tombstones+parkedids) newids = [c2id for c2id in c2ids if not c2id in knownc2ids] - print(newids,'aap') newparkedids = uniqify(newids+parkedids) @@ -215,6 +214,7 @@ def get_c2_workouts(rower,do_async=True): c2id, counter ) + #res = handle_c2_async_workout(alldata,rower.user.id,rower.c2token,c2id,counter) counter = counter+1 else: workoutid = create_async_workout(alldata, @@ -405,6 +405,37 @@ def create_async_workout(alldata,user,c2id): c2blocked.seek(0) json.dump(data,c2blocked) + # summary + if 'workout' in data: + if 'splits' in data['workout']: + splitdata = data['workout']['splits'] + elif 'intervals' in data['workout']: + splitdata = data['workout']['intervals'] + else: + splitdata = False + else: + splitdata = False + + if splitdata: + summary,sa,results = c2stuff.summaryfromsplitdata(splitdata,data,csvfilename,workouttype=workouttype) + w = Workout.objects.get(id=workoutid) + w.summary = summary + w.save() + + from rowingdata.trainingparser import getlist + if sa: + values = getlist(sa) + units = getlist(sa,sel='unit') + types = getlist(sa,sel='type') + + rowdata = rdata(w.csvfilename) + if rowdata: + rowdata.updateintervaldata(values, + units,types,results) + + rowdata.write_csv(w.csvfilename,gzip=True) + dataprep.update_strokedata(w.id,rowdata.df) + return workoutid diff --git a/rowers/tasks.py b/rowers/tasks.py index aa5ef4dd..8d09fb63 100644 --- a/rowers/tasks.py +++ b/rowers/tasks.py @@ -79,6 +79,7 @@ from rowers.dataprepnodjango import ( # create_strava_stroke_data_db ) + from rowers.opaque import encoder from django.core.mail import ( @@ -118,6 +119,162 @@ from rowers.courseutils import ( ) +# Concept2 logbook sends over split data for each interval +# We use it here to generate a custom summary +# Some users complained about small differences +def summaryfromsplitdata(splitdata,data,filename,sep='|',workouttype='rower'): + workouttype = workouttype.lower() + + totaldist = data['distance'] + totaltime = data['time']/10. + try: + spm = data['stroke_rate'] + except KeyError: + spm = 0 + try: + resttime = data['rest_time']/10. + except KeyError: + resttime = 0 + try: + restdistance = data['rest_distance'] + except KeyError: + restdistance = 0 + try: + avghr = data['heart_rate']['average'] + except KeyError: + avghr = 0 + try: + maxhr = data['heart_rate']['max'] + except KeyError: + maxhr = 0 + + try: + avgpace = 500.*totaltime/totaldist + except (ZeroDivisionError,OverflowError): + avgpace = 0. + + try: + restpace = 500.*resttime/restdistance + except (ZeroDivisionError,OverflowError): + restpace = 0. + + velo = totaldist/totaltime + avgpower = 2.8*velo**(3.0) + if workouttype in ['bike','bikeerg']: + velo = velo/2. + avgpower = 2.8*velo**(3.0) + velo = velo*2 + + + try: + restvelo = restdistance/resttime + except (ZeroDivisionError,OverflowError): + restvelo = 0 + + restpower = 2.8*restvelo**(3.0) + if workouttype in ['bike','bikeerg']: + restvelo = restvelo/2. + restpower = 2.8*restvelo**(3.0) + restvelo = restvelo*2 + + 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) + + sums += workstring(totaldist,totaltime,avgpace,spm,avghr,maxhr, + avgdps,avgpower,separator=sep,symbol='W') + + sums += workstring(restdistance,resttime,restpace,0,0,0,0,restpower, + separator=sep, + symbol='R') + + sums += '\nWorkout Details\n' + 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: + try: + idist = interval['distance'] + except KeyError: + idist = 0 + + try: + itime = interval['time']/10. + except KeyError: + itime = 0 + try: + ipace = 500.*itime/idist + except (ZeroDivisionError,OverflowError): + ipace = 180. + + try: + ispm = interval['stroke_rate'] + except KeyError: + ispm = 0 + try: + irest_time = interval['rest_time']/10. + except KeyError: + irest_time = 0 + try: + iavghr = interval['heart_rate']['average'] + except KeyError: + iavghr = 0 + try: + imaxhr = interval['heart_rate']['average'] + except KeyError: + imaxhr = 0 + + # create interval values + iarr = [idist,'meters','work'] + resarr = [itime] + if timebased: + iarr = [itime,'seconds','work'] + resarr = [idist] + + if irest_time > 0: + iarr += [irest_time,'seconds','rest'] + try: + resarr += [interval['rest_distance']] + except KeyError: + resarr += [np.nan] + + sa += iarr + results += resarr + + if itime != 0: + ivelo = idist/itime + ipower = 2.8*ivelo**(3.0) + if workouttype in ['bike','bikeerg']: + ipower = 2.8*(ivelo/2.)**(3.0) + else: + ivelo = 0 + ipower = 0 + + sums += interval_string(intervalnr,idist,itime,ipace,ispm, + iavghr,imaxhr,0,ipower,separator=sep) + intervalnr+=1 + + return sums,sa,results + + @app.task def add(x, y): return x + y @@ -2965,8 +3122,9 @@ def handle_c2_async_workout(alldata,userid,c2token,c2id,delaysec,debug=False,**k newc2id = 0 with engine.connect() as conn, conn.begin(): result = conn.execute(query) - data = result.fetchall() - newc2id = data[0][0] + tdata = result.fetchall() + if tdata: + newc2id = tdata[0][0] conn.close() @@ -2977,9 +3135,54 @@ def handle_c2_async_workout(alldata,userid,c2token,c2id,delaysec,debug=False,**k newparkedids = [id for id in parkedids if id != newc2id] with open('c2blocked.json','wt') as c2blocked: - data = {'ids':newparkedids} + tdata = {'ids':newparkedids} c2blocked.seek(0) - json.dump(data,c2blocked) + json.dump(tdata,c2blocked) + + # set distance, time + query = "UPDATE `rowers_workout` SET `distance` = '%s', `duration` = '%s' WHERE `id` = '%s'" % (distance, duration, workoutid) + + with engine.connect() as conn, conn.begin(): + result = conn.execute(query) + + conn.close() + engine.dispose() + + # summary + if 'workout' in data: + if 'splits' in data['workout']: + splitdata = data['workout']['splits'] + elif 'intervals' in data['workout']: + splitdata = data['workout']['intervals'] + else: + splitdata = False + else: + splitdata = False + + if splitdata: + summary,sa,results = summaryfromsplitdata(splitdata,data,csvfilename,workouttype=workouttype) + + query = "UPDATE `rowers_workout` SET `summary` = '%s' WHERE `id` = %s" % (summary, workoutid) + + with engine.connect() as conn, conn.begin(): + result = conn.execute(query) + + conn.close() + engine.dispose() + + from rowingdata.trainingparser import getlist + if sa: + values = getlist(sa) + units = getlist(sa,sel='unit') + types = getlist(sa,sel='type') + + rowdata = rdata(csvfilename) + if rowdata: + rowdata.updateintervaldata(values, + units,types,results) + + rowdata.write_csv(csvfilename,gzip=True) + dataprepnodjango.update_strokedata(w.id,rowdata.df) return workoutid