diff --git a/rowers/dataprep.py b/rowers/dataprep.py index 0059162f..a68e288e 100644 --- a/rowers/dataprep.py +++ b/rowers/dataprep.py @@ -428,7 +428,8 @@ def save_workout_database(f2,r,dosmooth=True,workouttype='rower', isbreakthrough = False if workouttype == 'water': delta,cpvalues,avgpower = datautils.getsinglecp(row.df) - if utils.isbreakthrough(delta,cpvalues,r.p0,r.p1,r.p2,r.p3,r.cpratio): + res,btvalues = utils.isbreakthrough(delta,cpvalues,r.p0,r.p1,r.p2,r.p3,r.cpratio) + if res: isbreakthrough = True res = datautils.updatecp(delta,cpvalues,r) @@ -595,14 +596,16 @@ def save_workout_database(f2,r,dosmooth=True,workouttype='rower', if settings.DEBUG and r.getemailnotifications: res = handle_sendemail_breakthrough.delay(w.id,r.user.email, r.user.first_name, - r.user.last_name) + r.user.last_name, + btvalues=btvalues.to_json()) elif r.getemailnotifications: try: res = queuehigh.enqueue( handle_sendemail_breakthrough(w.id, r.user.email, r.user.first_name, - r.user.last_name)) + r.user.last_name, + btvalues=btvalues.to_json())) except AttributeError: pass else: diff --git a/rowers/datautils.py b/rowers/datautils.py index ca4cbff1..8cdde524 100644 --- a/rowers/datautils.py +++ b/rowers/datautils.py @@ -77,8 +77,8 @@ def cpfit(powerdf): def getlogarr(maxt): maxlog10 = np.log10(maxt-5) - logarr = np.log10(5.)+np.arange(50)*maxlog10/50. - logarr = [int(10.**(la)) for la in logarr] + logarr = np.arange(50)*maxlog10/50. + logarr = [5+int(10.**(la)) for la in logarr] logarr = pd.Series(logarr) logarr.drop_duplicates(keep='first',inplace=True) @@ -88,7 +88,7 @@ def getlogarr(maxt): def getsinglecp(df): thesecs = df['TimeStamp (sec)'].max()-df['TimeStamp (sec)'].min() if thesecs != 0: - maxt = 2*thesecs + maxt = 1.05*thesecs else: maxt = 1000. @@ -152,7 +152,6 @@ def getcp(dfgrouped,logarr): dt = pd.Series(dt) cpw = pd.Series(cpw) if len(dt): - cpvalues = griddata(dt.values, cpw.values, logarr,method='linear', diff --git a/rowers/tasks.py b/rowers/tasks.py index 03f7ece1..9b98a4e8 100644 --- a/rowers/tasks.py +++ b/rowers/tasks.py @@ -18,7 +18,8 @@ import matplotlib.pyplot as plt from matplotlib import figure import stravalib - +import pandas as pd + from django_rq import job from utils import serialize_list,deserialize_list @@ -49,7 +50,9 @@ def handle_new_workout_from_file(r,f2, # send email when a breakthrough workout is uploaded @app.task -def handle_sendemail_breakthrough(workoutid,useremail,userfirstname,userlastname): +def handle_sendemail_breakthrough(workoutid,useremail, + userfirstname,userlastname, + btvalues = pd.DataFrame().to_json()): # send email with attachment subject = "A breakthrough workout on rowsandall.com" @@ -60,7 +63,7 @@ def handle_sendemail_breakthrough(workoutid,useremail,userfirstname,userlastname message += " Critical Power (CP) is the power that you can " message += "sustain for a given duration. For more, see this " message += " article in the analytics blog:\n\n" - message += " [link to article to be written]\n\n" + message += " http://analytics.rowsandall.com/2017/06/17/how-do-we-calculate-critical-power/ \n\n" message += "Link to the workout http://rowsandall.com/rowers/workout/" message += str(workoutid) message +="/edit\n\n" @@ -69,6 +72,27 @@ def handle_sendemail_breakthrough(workoutid,useremail,userfirstname,userlastname message += str(workoutid) message += "/updatecp\n\n" + btvalues = pd.read_json(btvalues) + btvalues.sort_values('delta',axis=0,inplace=True) + + if not btvalues.empty: + message += "These were the breakthrough values:\n" + for t in btvalues.itertuples(): + delta = t.delta + cpvalue = t.cpvalues + pwr = t.pwr + + message += "Time: {delta} seconds\n".format( + delta=delta + ) + message += "New: {cpvalue:.0f} Watt\n".format( + cpvalue=cpvalue + ) + message += "Old: {pwr:.0f} Watt\n\n".format( + pwr=pwr + ) + + message += "To opt out of these email notifications, deselect the checkbox on your Profile page under Account Information.\n\n" message += "Best Regards, the Rowsandall Team" @@ -222,10 +246,11 @@ def handle_otwsetpower(f1,boattype,weightvalue, update_strokedata(workoutid,rowdata.df,debug=debug) delta,cpvalues,avgpower = datautils.getsinglecp(rowdata.df) - if utils.isbreakthrough(delta,cpvalues,ps[0],ps[1],ps[2],ps[3],ratio): + res,btvalues = utils.isbreakthrough(delta,cpvalues,ps[0],ps[1],ps[2],ps[3],ratio) + if res: handle_sendemail_breakthrough(workoutid,email, first_name, - last_name) + last_name,btvalues=btvalues.to_json()) # send email fullemail = first_name + " " + last_name + " " + "<" + email + ">" diff --git a/rowers/templates/streamedit.html b/rowers/templates/streamedit.html index 56079e4d..1e4ba1a0 100644 --- a/rowers/templates/streamedit.html +++ b/rowers/templates/streamedit.html @@ -7,49 +7,57 @@ {% block content %}
- Edit Workout -
-- Advanced Edit -
- -- Edit river Stream between turning points in your row. - Use positive (+) values to denote rowing with the stream, - negative (-) values to denote rowing against the stream. -
- ++ Edit Workout +
++ Advanced Edit +
+ ++ Edit river Stream between turning points in your row. + Use positive (+) values to denote rowing with the stream, + negative (-) values to denote rowing against the stream. +
+
-
+ {% if form.errors %}
+ + Please correct the error{{ form.errors|pluralize }} below. +
+ {% endif %} + +
+
- Edit Workout -
-- Advanced Edit -
- -- Update wind between distance 1 and distance 2. Submit wind strength - and direction at start and end of segment. Blank the form for values - you want to keep intact. -
- -- Check www.wunderground.com - to find historical weather data from an on-line weather station near - the location of your row. -
- -
+