diff --git a/rowers/dataprep.py b/rowers/dataprep.py
index 31720733..ad1d5ccb 100644
--- a/rowers/dataprep.py
+++ b/rowers/dataprep.py
@@ -350,6 +350,16 @@ def dataprep(rowdatadf,id=0,bands=True,barchart=True,otwpower=True,
driveenergy = rowdatadf.ix[:,'driveenergy']
drivelength = driveenergy/(averageforce*4.44822)
slip = rowdatadf.ix[:,'slip']
+ if windowsize > 3:
+ wash = savgol_filter(wash,windowsize,3)
+ slip = savgol_filter(slip,windowsize,3)
+ catch = savgol_filter(catch,windowsize,3)
+ finish = savgol_filter(finish,windowsize,3)
+ peakforce = savgol_filter(peakforce,windowsize,3)
+ averageforce = savgol_filter(averageforce,windowsize,3)
+ peakforceangle = savgol_filter(peakforceangle,windowsize,3)
+ driveenergy = savgol_filter(driveenergy,windowsize,3)
+ drivelength = savgol_filter(drivelength,windowsize,3)
data['wash'] = wash
data['catch'] = catch
data['slip'] = slip
diff --git a/rowers/interactiveplots.py b/rowers/interactiveplots.py
index 12bcbecb..c476e051 100644
--- a/rowers/interactiveplots.py
+++ b/rowers/interactiveplots.py
@@ -885,6 +885,11 @@ def interactive_flex_chart2(id=0,promember=0,
'forceratio': 'Average/Peak Drive Force Ratio',
'driveenergy': 'Work per Stroke (J)',
'drivespeed': 'Drive Speed (m/s)',
+ 'slip': 'Slip (degrees)',
+ 'catch': 'Catch (degrees)',
+ 'finish': 'Finish (degrees)',
+ 'wash': 'Wash (degrees)',
+ 'peakforceangle': 'Peak Force Angle (degrees)',
'None': '',
}
@@ -899,12 +904,17 @@ def interactive_flex_chart2(id=0,promember=0,
'drivelength':0.5,
'driveenergy': 0,
'drivespeed': 0,
+ 'slip': 0,
+ 'catch': -70,
+ 'finish': 30,
+ 'wash': 0,
+ 'peakforceangle': -20,
}
yaxmaxima = {
'hr':200,
'spm':45,
- 'pace': 1.0e3*90,
+ 'pace': 1.0e3*75,
'power': 600,
'averageforce':200,
'peakforce':400,
@@ -912,9 +922,20 @@ def interactive_flex_chart2(id=0,promember=0,
'drivelength':2.0,
'driveenergy': 1000,
'drivespeed':4,
+ 'slip': 30,
+ 'catch': -30,
+ 'finish': 70,
+ 'wash': 30,
+ 'peakforceangle': 20,
}
rowdata,row = dataprep.getrowdata_db(id=id)
+ #columns = [xparam,yparam1,yparam2,
+ # 'ftime','distance','fpace',
+ # 'power','hr','spm',
+ # 'time','pace']
+ #rowdata = dataprep.getsmallrowdata_db(columns,ids=[id])
+ #row = Workout.objects.get(id=id)
if rowdata.empty:
return "","CSV Data File Not Found"
diff --git a/rowers/templates/about_us.html b/rowers/templates/about_us.html
index f12f636b..c7c998c7 100644
--- a/rowers/templates/about_us.html
+++ b/rowers/templates/about_us.html
@@ -94,14 +94,18 @@ and inspired by the RowPro Dan Burpee spreadsheet
Beyond the basics, rowsandall.com provides a rich tool set for
OTW rowing. You can use it to estimate stroke power and to correct
- for the effects of wind and current. For indoor rowing, when used
- with painsled, the tools enable graphical analsis of stroke metrics
+ for the effects of wind and current. For indoor rowing, when
+ used with painsled, and OTW rowing, when used
+ with a NK Empower Oarlock,
+ the tools enable graphical analsis of stroke metrics
including:
- Peak and average force
- drive length
- work per stroke
- drive and recovery time
+- catch and finish angles (OTW)
+- slip and wash (OTW)
These can be analyzed versus time, distance, stroke rate or other
@@ -138,6 +142,8 @@ You will be taken to the secure PayPal payment site.
+ - 2016-12-01 Support for NK Empower Oarlock parameters (catch and
+ finish angles, slip and wash, and power as measured by the Oarlock
- 2016-11-10 Power based Pie Charts
- 2016-11-01 Sliders to select subsets of data on some plots
- 2016-11-01 Emailing workouts to workouts@rowsandall.com
@@ -155,7 +161,7 @@ You will be taken to the secure PayPal payment site.
- 2016-06-08 Added possibility to upload CrewNerd summary CSV file for Premium Members
- 2016-06-08 Added workout summaries
- 2016-06-05 Export to Strava is working
- - 2016-06-01 We're approved on the Concept2 logbook!!!!
+
- 2016-06-01 We're approved on the Concept2 logbook!!!!
diff --git a/rowers/templates/flexchart3otw.html b/rowers/templates/flexchart3otw.html
new file mode 100644
index 00000000..812361c5
--- /dev/null
+++ b/rowers/templates/flexchart3otw.html
@@ -0,0 +1,203 @@
+{% extends "base.html" %}
+{% load staticfiles %}
+{% load rowerfilters %}
+{% load tz %}
+
+{% block title %} Flexible Plot {% endblock %}
+
+{% localtime on %}
+{% block content %}
+
+{{ js_res | safe }}
+{{ css_res| safe }}
+
+
+
+
+
+{{ the_script |safe }}
+
+
+
+
+
+ {% if user.is_authenticated and mayedit %}
+
+
+ {% endif %}
+
+
+
+
+
+
+
+
+
+
+ {{ the_div|safe }}
+
+
+
+
+{% endblock %}
+{% endlocaltime %}
diff --git a/rowers/tests.py b/rowers/tests.py
index 0e0c4acd..2ee797c7 100644
--- a/rowers/tests.py
+++ b/rowers/tests.py
@@ -690,6 +690,37 @@ class ViewTest(TestCase):
os.remove(f_to_be_deleted)
+ def test_upload_view_SpeedCoach2v127intervals(self):
+ self.c.login(username='john',password='koeinsloot')
+
+ filename = 'C:\\python\\rowingdata\\testdata\\SpeedCoach2Link_interval.csv'
+ f = open(filename,'rb')
+ file_data = {'file': f}
+
+ form_data = {
+ 'title':'test',
+ 'workouttype':'water',
+ 'notes':'aap noot mies',
+ 'make_plot':False,
+ 'upload_to_c2':False,
+ 'plottype':'timeplot',
+ 'file': f,
+ }
+
+ form = DocumentsForm(form_data,file_data)
+
+ response = self.c.post('/rowers/workout/upload/', form_data, follow=True)
+ f.close()
+ self.assertRedirects(response, expected_url='/rowers/workout/1/edit',
+ status_code=302,target_status_code=200)
+
+ self.assertEqual(response.status_code, 200)
+
+ w = Workout.objects.get(id=1)
+ f_to_be_deleted = w.csvfilename
+ os.remove(f_to_be_deleted)
+
+
def test_upload_view_TCX_NoHR(self):
self.c.login(username='john',password='koeinsloot')
diff --git a/rowers/views.py b/rowers/views.py
index c10eae6d..64a53cc5 100644
--- a/rowers/views.py
+++ b/rowers/views.py
@@ -2610,22 +2610,39 @@ def workout_flexchart3_view(request,id=0,xparam='distance',yparam1='pace',
div = res[1]
js_resources = res[2]
css_resources = res[3]
-
- return render(request,
- 'flexchart3.html',
- {'the_script':script,
- 'the_div':div,
- 'js_res': js_resources,
- 'css_res':css_resources,
- 'id':id,
- 'xparam':xparam,
- 'yparam1':yparam1,
- 'yparam2':yparam2,
- 'plottype':plottype,
- 'mayedit':mayedit,
- 'promember':promember,
- 'workstrokesonly': not workstrokesonly,
- })
+
+ if row.workouttype == 'water':
+ return render(request,
+ 'flexchart3otw.html',
+ {'the_script':script,
+ 'the_div':div,
+ 'js_res': js_resources,
+ 'css_res':css_resources,
+ 'id':id,
+ 'xparam':xparam,
+ 'yparam1':yparam1,
+ 'yparam2':yparam2,
+ 'plottype':plottype,
+ 'mayedit':mayedit,
+ 'promember':promember,
+ 'workstrokesonly': not workstrokesonly,
+ })
+ else:
+ return render(request,
+ 'flexchart3.html',
+ {'the_script':script,
+ 'the_div':div,
+ 'js_res': js_resources,
+ 'css_res':css_resources,
+ 'id':id,
+ 'xparam':xparam,
+ 'yparam1':yparam1,
+ 'yparam2':yparam2,
+ 'plottype':plottype,
+ 'mayedit':mayedit,
+ 'promember':promember,
+ 'workstrokesonly': not workstrokesonly,
+ })
def testbokeh(request):