757 lines
26 KiB
HTML
757 lines
26 KiB
HTML
|
|
{% extends "newbase.html" %}
|
|
{% block title %}Rowsandall Developers Info{% endblock title %}
|
|
{% block main %}
|
|
|
|
<h1>Resources for developers</h1>
|
|
|
|
<ul class="main-content">
|
|
<li class="grid_4">
|
|
|
|
<p>On this page, a work in progress, I will collect useful information
|
|
for developers of rowing data apps and hardware.</p>
|
|
|
|
<p>I presume you have an app (smartphone app, dedicated hardware, web site)
|
|
where your users (customers) generate, collect or store their rowing
|
|
related workout data. You can now offer your users easy ways to get
|
|
their data on this site.</p>
|
|
|
|
</li>
|
|
|
|
<li class="grid_4">
|
|
<p>There are three ways to allow your users to get data to Rowsandall.com.</p>
|
|
<h2>File based export from your app</h2>
|
|
|
|
<p>Enable export of TCX, FIT or CSV formatted files from your app.
|
|
The users
|
|
upload the file to Rowsandall.com.</p>
|
|
|
|
<p><ul class="contentli">
|
|
<li>Advantages
|
|
<p><ul class="contentli">
|
|
<li>User sees immediate results</li>
|
|
</ul></p>
|
|
</li>
|
|
<li>Disadvantages
|
|
<p><ul class="contentli">
|
|
<li>It is a multi-step process: Download from your
|
|
app, store, upload.</li>
|
|
</ul></p>
|
|
</li>
|
|
</ul></p>
|
|
<h2>Email from your app</h2>
|
|
|
|
<p>Similar as above, generate TCX, FIT or CSV formatted files and
|
|
email them
|
|
to <em>workouts@rowsandall.com</em> directly from your app. The From: field
|
|
should be the email address of the registered user.</p>
|
|
|
|
<p><ul class="contentli">
|
|
<li>Advantages
|
|
<p><ul class="contentli">
|
|
<li>It's a simple process, which can be automated.</li>
|
|
</ul></p>
|
|
</li>
|
|
<li>Disadvantages
|
|
<p><ul class="contentli">
|
|
<li>It may take up to five minutes for the workout to show up
|
|
on the site.</li>
|
|
</ul></p>
|
|
</li>
|
|
</ul></p>
|
|
<h2>Using the REST API</h2>
|
|
|
|
<p>We are building a REST API which will allow you to post and
|
|
receive stroke
|
|
data from the site directly.</p>
|
|
|
|
<p>The REST API is a work in progress. We are open to improvement
|
|
suggestions (provided they don't break existing apps). Please send
|
|
email to <a href="mailto:info@rowsandall.com">info@rowsandall.com</a>
|
|
with questions and/or suggestions. We
|
|
will get back to you as soon as possible.</p>
|
|
|
|
<p><ul class="contentli">
|
|
<li>Advantages
|
|
<p><ul class="contentli">
|
|
<li>Once it is set up, this is a one-click operation.</li>
|
|
<li>You can read a user's workout data from the site and use
|
|
them in your app.</li>
|
|
<li>This is not limited to workout data. You could make a full mobile
|
|
version of our site.</li>
|
|
</ul></p>
|
|
</li>
|
|
|
|
<li>Disadvantages
|
|
<p><ul class="contentli">
|
|
<li>The API is not stable and not fully tested yet.</li>
|
|
<li>You need to register your app with us. We can revoke your
|
|
permissions if you misuse them.</li>
|
|
<li>The user user must grant permissions to your app.</li>
|
|
<li>You need to manage authorization tokens.</li>
|
|
</ul></p>
|
|
</li>
|
|
</ul></p>
|
|
|
|
</li>
|
|
<li class="grid_4">
|
|
<h2>Quick Links</h2>
|
|
|
|
<h3>Accepted file formats</h3>
|
|
|
|
<p>All files adhering to the standards <a href="http://www8.garmin.com/xmlschemas/TrainingCenterDatabasev2.xsd">TCX</a> and <a href="https://www.thisisant.com/resources/fit/">FIT</a> formats will be parsed.</p>
|
|
|
|
<p>However, some rowing related parameters are not supported by TCX and FIT. Therefore, we are supporting the CSV format that is documented in the following link.</p>
|
|
|
|
<p><ul class="contentli"><li><a href="http://rowingdata.readthedocs.io/en/latest/#csv-file-standard">Our standard rowing CSV file</a></li></ul></p>
|
|
|
|
<p>Using this standard will guarantee that your user's data are accepted
|
|
without complaints.</p>
|
|
|
|
<h2>API related documentation</h2>
|
|
|
|
<h3>Registering an app</h3>
|
|
|
|
|
|
<p>We have disabled the self service app link for security reasons.
|
|
We will replace it with a secure self service app link soon. If you
|
|
need to register an app, please send email to info@rowsandall.com</p>
|
|
|
|
<h3>Authentication</h3>
|
|
|
|
<p>Standard <a href="https://oauth.net/2/">Oauth2</a> authentication.
|
|
Get authorization code by pointing your user to the authorization URL.
|
|
Exchange authorization code for an access token. When access token
|
|
expires,
|
|
use the refresh token to refresh it.</p>
|
|
|
|
<p>The redirect URI for user authentication has to be <em>https</em>.
|
|
Developers of iOS or Android apps should contact me directly if
|
|
this doesn't work for them. I can add exceptions.</p>
|
|
|
|
<p>
|
|
<ul class="contentli">
|
|
<li>Authorization URL: <b>https://{{ request.get_host }}/rowers/o/authorize</b></li>
|
|
<li>Access Token request: <b>https://{{ request.get_host }}/rowers/o/token/</b></li>
|
|
<li>Access Token refresh: <b>https://{{ request.get_host }}/rowers/o/token/</b></li>
|
|
<li>Handy utility for testing: <b><a href="http://django-oauth-toolkit.herokuapp.com/consumer/">http://django-oauth-toolkit.herokuapp.com/consumer/</a></b></li>
|
|
</ul>
|
|
</p>
|
|
|
|
<h3>API endpoints</h3>
|
|
|
|
<p>Once you have a registered app, you have gone through the authorization
|
|
and have successfully obtained an access token, you can use it to place
|
|
POST, GET and PUT requests.</p>
|
|
|
|
<p>The workout summary data and the stroke data are obtained and sent
|
|
separately.</p>
|
|
|
|
<p>
|
|
In the table below {id} indicates the ID of the item.
|
|
<table width="100%" class="shortpadded">
|
|
<thead>
|
|
<tr>
|
|
<th>Item</th><th>Access Points</th><th>Permissions</th><th>Example</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td>Workout</td>
|
|
<td><a href="/rowers/api/workouts/">/rowers/api/workouts/</a>
|
|
<br>
|
|
<a href="/rowers/api/workouts/1">/rowers/api/workouts/{id}</a></td>
|
|
<td>GET, POST, DELETE</td>
|
|
<td>
|
|
<pre>{
|
|
"id": 18,
|
|
"name": "2x",
|
|
"date": "2020-10-15",
|
|
"workouttype": "water",
|
|
"starttime": "08:40:50",
|
|
"distance": 9751,
|
|
"duration": "00:52:40",
|
|
"averagehr": 104,
|
|
"maxhr": 122,
|
|
"notes": "",
|
|
"summary": "Workout Summary - media/97ec07a851-20201015-192157-95763ffd-fd4e-4b5f-bf5f-8a8495c16639.csv\n--|Total|-Total----|--Avg--|-Avg-|Avg-|-Avg-|-Max-|-Avg\n--|Dist-|-Time-----|-Pace--|-Pwr-|SPM-|-HR--|-HR--|-DPS\n--|09751|00:52:40.0|02:42.0|173.0|18.0|104.4|122.0|10.3\nW-|09751|00:52:40.0|02:42.0|173.0|18.0|104.4|122.0|10.3\nR-|00000|00:00:00.0|00:00.0|000.0|00.0|000.0|122.0|00.0\nWorkout Details\n#-|SDist|-Split-|-SPace-|-Pwr-|SPM-|AvgHR|MaxHR|DPS-\n00|09751|52:40.0|02:42.0|173.0|18.0|104.4|122.0|10.3\n",
|
|
"boattype": "2x",
|
|
"timezone": "Europe/Amsterdam",
|
|
"forceunit": "N",
|
|
"inboard": 0.88,
|
|
"oarlength": 2.89,
|
|
"privacy": "visible",
|
|
"rankingpiece": false
|
|
}
|
|
</pre>
|
|
</td>
|
|
|
|
</tr>
|
|
<tr>
|
|
<td>Favorite Chart</td>
|
|
<td><a href="/rowers/api/charts/">/rowers/api/charts/</a>
|
|
<br>
|
|
<a href="/rowers/api/charts/1">/rowers/api/charts/{id}</a></td>
|
|
<td>GET, DELETE</td>
|
|
<td>
|
|
<pre>{
|
|
"id": 7,
|
|
"xparam": "time",
|
|
"yparam1": "hr",
|
|
"yparam2": "power",
|
|
"plottype": "line",
|
|
"workouttype": "otw",
|
|
"reststrokes": true,
|
|
"user": 1
|
|
}
|
|
</pre>
|
|
</td>
|
|
|
|
</tr>
|
|
<tr>
|
|
<td>Planned Session</td>
|
|
<td><a href="/rowers/api/plannedsessions/">/rowers/api/plannedsessions/</a>
|
|
<br>
|
|
<a href="/rowers/api/plannedsessions/1">/rowers/api/plannedsessions/{id}</a></td>
|
|
<td>GET, POST, DELETE</td>
|
|
<td>
|
|
<pre>{
|
|
"id": 103,
|
|
"name": "ExampleSession",
|
|
"comment": "",
|
|
"startdate": "2021-03-01",
|
|
"enddate": "2021-03-06",
|
|
"preferreddate": "2021-03-01",
|
|
"sessiontype": "session",
|
|
"sessionvalue": 74,
|
|
"sessionunit": "min",
|
|
"sessionmode": "time",
|
|
"course": null,
|
|
"approximate_distance": 16440,
|
|
"approximate_duration": 74,
|
|
"fitfile": "https://rowsandall.com/media/a7a7a621ad-20210302-074033-tmp2zcd7i_0.fit"
|
|
}
|
|
</pre>
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>Challenge</td>
|
|
<td><a href="/rowers/api/challenges/">/rowers/api/challenges/</a>
|
|
<br>
|
|
<a href="/rowers/api/challenges/1">/rowers/api/challenges/{id}</a></td>
|
|
<td>GET</td>
|
|
<td>
|
|
<pre>
|
|
{
|
|
"id": 1,
|
|
"name": "Alphen",
|
|
"course": 1,
|
|
"registration_closure": "2020-10-18T08:45:00+02:00",
|
|
"evaluation_closure": "2020-10-18T12:16:00+02:00",
|
|
"start_time": "08:45:00",
|
|
"end_time": "12:00:00",
|
|
"country": "Nederland",
|
|
"timezone": "Europe/Amsterdam",
|
|
"contact_phone": "",
|
|
"contact_email": "",
|
|
"entries": [
|
|
{
|
|
"id": 1,
|
|
"username": "Sander Roosendaal",
|
|
"teamname": null,
|
|
"boattype": "1x",
|
|
"sex": "male",
|
|
"age": 48,
|
|
"adaptiveclass": "None",
|
|
"skillclass": "Open",
|
|
"coursecompleted": false,
|
|
"distance": 0,
|
|
"duration": "00:00:00",
|
|
"points": 0.0,
|
|
"entrycategory": null
|
|
}
|
|
],
|
|
"coursestandards": null
|
|
}
|
|
</pre>
|
|
</td>
|
|
|
|
</tr>
|
|
<tr>
|
|
<td>Challenge Entry</td>
|
|
<td><a href="/rowers/api/entries/">/rowers/api/entries/</a>
|
|
<br>
|
|
<a href="/rowers/api/entries/1">/rowers/api/entries/{id}</a></td>
|
|
<td>GET, POST</td>
|
|
<td>
|
|
<pre>{
|
|
"id": 1,
|
|
"teamname": null,
|
|
"adaptiveclass": "None",
|
|
"skillclass": "Open",
|
|
"race": {
|
|
"id": 1,
|
|
"name": "Alphen",
|
|
"course": 1,
|
|
"registration_closure": "2020-10-18T08:45:00+02:00",
|
|
"evaluation_closure": "2020-10-18T12:16:00+02:00",
|
|
"start_time": "08:45:00",
|
|
"end_time": "12:00:00",
|
|
"country": "Nederland",
|
|
"timezone": "Europe/Amsterdam",
|
|
"contact_phone": "",
|
|
"contact_email": "",
|
|
"entries": [
|
|
{
|
|
"id": 1,
|
|
"username": "Sander Roosendaal",
|
|
"teamname": null,
|
|
"boattype": "1x",
|
|
"sex": "male",
|
|
"age": 48,
|
|
"adaptiveclass": "None",
|
|
"skillclass": "Open",
|
|
"coursecompleted": false,
|
|
"distance": 0,
|
|
"duration": "00:00:00",
|
|
"points": 0.0,
|
|
"entrycategory": null
|
|
}
|
|
],
|
|
"coursestandards": null
|
|
},
|
|
"distance": 0,
|
|
"duration": "00:00:00",
|
|
"points": 0.0,
|
|
"boattype": "1x",
|
|
"sex": "male",
|
|
"age": 48,
|
|
"entrycategory": null
|
|
}
|
|
</pre>
|
|
</td>
|
|
|
|
</tr>
|
|
<tr>
|
|
<td>Course</td>
|
|
<td><a href="/rowers/api/geocourses/">/rowers/api/geocourses/</a>
|
|
<br>
|
|
<a href="/rowers/api/geocourses/1">/rowers/api/geocourses/{id}</a></td>
|
|
<td>GET</td>
|
|
<td>
|
|
Example shortened for brevity (omitted gates 2-14):
|
|
<pre>
|
|
{
|
|
"id": 1,
|
|
"name": "Alphen - Alphen aan den Rijn",
|
|
"distance": 14847,
|
|
"country": "Nederland",
|
|
"notes": "\n\n",
|
|
"polygons": [
|
|
{
|
|
"id": 1,
|
|
"name": "Start",
|
|
"order_in_course": 0,
|
|
"points": [
|
|
{
|
|
"id": 1,
|
|
"latitude": 52.14611068342334,
|
|
"longitude": 4.704149601313898,
|
|
"order_in_poly": 0
|
|
},
|
|
{
|
|
"id": 2,
|
|
"latitude": 52.14606840788696,
|
|
"longitude": 4.704648516706039,
|
|
"order_in_poly": 1
|
|
},
|
|
{
|
|
"id": 3,
|
|
"latitude": 52.14626893773362,
|
|
"longitude": 4.704642182077736,
|
|
"order_in_poly": 2
|
|
},
|
|
{
|
|
"id": 4,
|
|
"latitude": 52.14628828501986,
|
|
"longitude": 4.704151599747837,
|
|
"order_in_poly": 3
|
|
},
|
|
{
|
|
"id": 5,
|
|
"latitude": 52.14611068342334,
|
|
"longitude": 4.704149601313898,
|
|
"order_in_poly": 4
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": 15,
|
|
"name": "Finish",
|
|
"order_in_course": 14,
|
|
"points": [
|
|
{
|
|
"id": 71,
|
|
"latitude": 52.1461319705247,
|
|
"longitude": 4.70414987291546,
|
|
"order_in_poly": 0
|
|
},
|
|
{
|
|
"id": 72,
|
|
"latitude": 52.14607111930849,
|
|
"longitude": 4.704561170436561,
|
|
"order_in_poly": 1
|
|
},
|
|
{
|
|
"id": 73,
|
|
"latitude": 52.14626893773362,
|
|
"longitude": 4.704642182077736,
|
|
"order_in_poly": 2
|
|
},
|
|
{
|
|
"id": 74,
|
|
"latitude": 52.14628831020436,
|
|
"longitude": 4.70415735390207,
|
|
"order_in_poly": 3
|
|
},
|
|
{
|
|
"id": 75,
|
|
"latitude": 52.1461319705247,
|
|
"longitude": 4.70414987291546,
|
|
"order_in_poly": 4
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
|
|
</pre>
|
|
</td>
|
|
|
|
</tr>
|
|
<tr>
|
|
<td>Course Time Standard Collection</td>
|
|
<td><a href="/rowers/api/standardcollections/">/rowers/api/standardcollections/</a>
|
|
<br>
|
|
<a href="/rowers/api/standardcollections/1">/rowers/api/standarcollections/{id}</a></td>
|
|
<td>GET</td>
|
|
<td>
|
|
Example shortened for brevity (showing only first three):
|
|
<pre>{
|
|
"id": 1,
|
|
"name": "Charles River Times Standards",
|
|
"notes": "",
|
|
"active": true,
|
|
"standards": [
|
|
{
|
|
"id": 1,
|
|
"name": "M1x",
|
|
"coursedistance": 4700,
|
|
"coursetime": "17:15.0",
|
|
"agemin": 0,
|
|
"agemax": 120,
|
|
"boatclass": "water",
|
|
"boattype": "1x",
|
|
"sex": "male",
|
|
"weightclass": "hwt",
|
|
"adaptiveclass": "None",
|
|
"skillclass": "Open",
|
|
"standardcollection": 1
|
|
},
|
|
{
|
|
"id": 2,
|
|
"name": "MLW1x",
|
|
"coursedistance": 4700,
|
|
"coursetime": "17:15.0",
|
|
"agemin": 0,
|
|
"agemax": 120,
|
|
"boatclass": "water",
|
|
"boattype": "1x",
|
|
"sex": "male",
|
|
"weightclass": "lwt",
|
|
"adaptiveclass": "None",
|
|
"skillclass": "Open",
|
|
"standardcollection": 1
|
|
},
|
|
{
|
|
"id": 3,
|
|
"name": "MYouth1x",
|
|
"coursedistance": 4700,
|
|
"coursetime": "18:30.0",
|
|
"agemin": 15,
|
|
"agemax": 18,
|
|
"boatclass": "water",
|
|
"boattype": "1x",
|
|
"sex": "male",
|
|
"weightclass": "hwt",
|
|
"adaptiveclass": "None",
|
|
"skillclass": "Open",
|
|
"standardcollection": 1
|
|
},
|
|
]
|
|
}
|
|
</pre>
|
|
</td>
|
|
|
|
</tr>
|
|
<tr>
|
|
<td>Individual Course Time Standard</td>
|
|
<td><a href="/rowers/api/standards/">/rowers/api/standards/</a>
|
|
<br>
|
|
<a href="/rowers/api/standards/1">/rowers/api/standards/{id}</a></td>
|
|
<td>GET, POST
|
|
<td>
|
|
<pre>{
|
|
"id": 1,
|
|
"name": "M1x",
|
|
"coursedistance": 4700,
|
|
"coursetime": "17:15.0",
|
|
"agemin": 0,
|
|
"agemax": 120,
|
|
"boatclass": "water",
|
|
"boattype": "1x",
|
|
"sex": "male",
|
|
"weightclass": "hwt",
|
|
"adaptiveclass": "None",
|
|
"skillclass": "Open",
|
|
"standardcollection": 1
|
|
}
|
|
</pre>
|
|
</td>
|
|
|
|
</tr>
|
|
<tr>
|
|
<td>Stroke Data (v1)</td>
|
|
<td><a href="/rowers/api/workouts/1/strokedata">/rowers/api/workouts/{id}/strokedata</a>
|
|
</td>
|
|
<td>GET, POST</td>
|
|
<td>
|
|
<pre>{
|
|
"distance": [23, 46, 48],
|
|
"time": [3200, 6700, 10099],
|
|
"spm": [16.4, 21.2, 19.8],
|
|
"pace": [155068, 144402, 138830],
|
|
"power": [84.6, 117.2, 141.3],
|
|
"hr": [85, 91, 95]
|
|
}
|
|
</pre>
|
|
You can only post stroke data to an existing workout with
|
|
workout number {id}. If the workout already has stroke data, you
|
|
will get a duplication error. This functionality will be expanded in the
|
|
future to enable updating stroke data.
|
|
<br>
|
|
<p>For both v1 and v2, mandatory data fields are:</p>
|
|
<p>
|
|
<ul class="contentli">
|
|
<li><b>time</b>: Time (milliseconds since workout start)</li>
|
|
<li><b>distance</b>: Distance (meters)</li>
|
|
<li><b>pace</b>: Pace (milliseconds per 500m)</li>
|
|
<li><b>spm</b> Stroke rate (strokes per minute)</li>
|
|
</ul>
|
|
</p>
|
|
<p>Optional data fiels are:</p>
|
|
<p>
|
|
<ul class="contentli">
|
|
<li><b>power</b>: Power (Watt)</li>
|
|
<li><b>latitude</b>: GPS position (latitude)</li>
|
|
<li><b>longitude</b>: GPS position (longitude)</li>
|
|
<li><b>drivelength</b>: Drive length (meters)</li>
|
|
<li><b>dragfactor</b>: Drag factor</li>
|
|
<li><b>drivetime</b>: Drive time (ms)</li>
|
|
<li><b>strokerecoverytime</b>: Recovery time (ms)</li>
|
|
<li><b>averagedriveforce</b>: Average handle force (lbs)</li>
|
|
<li><b>peakdriveforce</b>: Peak handle force (lbs)</li>
|
|
<li><b>lapidx</b>: Lap identifier</li>
|
|
<li><b>hr</b>: Heart rate (beats per minute)</li>
|
|
<li><b>wash</b>: Wash as defined per Empower oarlock (degrees)</li>
|
|
<li><b>catch</b>: Catch angle per Empower oarlock (degrees)</li>
|
|
<li><b>finish</b>: Finish angle per Empower oarlock (degrees)</li>
|
|
<li><b>peakforceangle</b>: Peak Force Angle per Empower oarlock (degrees)</li>
|
|
<li><b>slip</b>: Slip as defined per Empower oarlock (degrees)</li>
|
|
|
|
</ul>
|
|
</p>
|
|
<p>For both API versions, consistency checks will be done and the stroke data will be
|
|
refused if the mandatory data fields don't pass the checks.
|
|
All mandatory data fields
|
|
must have the same number of records. If an optional data field
|
|
fails a test, its values are silently replaced by zeros.</p>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Stroke Data (v2)</td>
|
|
<td><a href="/rowers/api/v2/workouts/1/strokedata">/rowers/api/v2/workouts/{id}/strokedata</a>
|
|
</td>
|
|
<td>GET, POST</td>
|
|
<td>
|
|
<pre>{
|
|
"data": [
|
|
{
|
|
"time": 3200.0000476837,
|
|
"pace": 155068.4885951763,
|
|
"hr": 85.7857142857,
|
|
"power": 84.6531131591,
|
|
"distance": 23,
|
|
"spm": 16.380952381
|
|
},
|
|
{
|
|
"time": 6700.0000476837,
|
|
"pace" : 144402.6407586741,
|
|
"hr": 91.2142857143,
|
|
"power": 117.458827834,
|
|
"distance": 36,
|
|
"spm": 21.1666666667
|
|
},
|
|
{
|
|
"time": 10099.9999046326,
|
|
"pace": 138830.8712654931,
|
|
"hr": 95.7142857143,
|
|
"power": 141.31057207,
|
|
"distance": 48,
|
|
"spm": 19.8095238095
|
|
}
|
|
]
|
|
}
|
|
</pre>
|
|
You can only post stroke data to an existing workout with
|
|
workout number {id}. If the workout already has stroke data, you
|
|
will get a duplication error. This functionality will be expanded in the
|
|
future to enable updating stroke data.
|
|
<br>
|
|
<p>For both v1 and v2, mandatory data fields are:</p>
|
|
<p>
|
|
<ul class="contentli">
|
|
<li><b>time</b>: Time (milliseconds since workout start)</li>
|
|
<li><b>distance</b>: Distance (meters)</li>
|
|
<li><b>pace</b>: Pace (milliseconds per 500m)</li>
|
|
<li><b>spm</b> Stroke rate (strokes per minute)</li>
|
|
</ul>
|
|
</p>
|
|
<p>Optional data fiels are:</p>
|
|
<p>
|
|
<ul class="contentli">
|
|
<li><b>power</b>: Power (Watt)</li>
|
|
<li><b>latitude</b>: GPS position (latitude)</li>
|
|
<li><b>longitude</b>: GPS position (longitude)</li>
|
|
<li><b>drivelength</b>: Drive length (meters)</li>
|
|
<li><b>dragfactor</b>: Drag factor</li>
|
|
<li><b>drivetime</b>: Drive time (ms)</li>
|
|
<li><b>strokerecoverytime</b>: Recovery time (ms)</li>
|
|
<li><b>averagedriveforce</b>: Average handle force (lbs)</li>
|
|
<li><b>peakdriveforce</b>: Peak handle force (lbs)</li>
|
|
<li><b>lapidx</b>: Lap identifier</li>
|
|
<li><b>hr</b>: Heart rate (beats per minute)</li>
|
|
<li><b>wash</b>: Wash as defined per Empower oarlock (degrees)</li>
|
|
<li><b>catch</b>: Catch angle per Empower oarlock (degrees)</li>
|
|
<li><b>finish</b>: Finish angle per Empower oarlock (degrees)</li>
|
|
<li><b>peakforceangle</b>: Peak Force Angle per Empower oarlock (degrees)</li>
|
|
<li><b>slip</b>: Slip as defined per Empower oarlock (degrees)</li>
|
|
|
|
</ul>
|
|
</p>
|
|
<p>For both API versions, consistency checks will be done and the stroke data will be
|
|
refused if the mandatory data fields don't pass the checks.
|
|
All mandatory data fields
|
|
must have the same number of records. If an optional data field
|
|
fails a test, its values are silently replaced by zeros.</p>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Stroke Data (v3)</td>
|
|
<td><a href="/rowers/api/v3/workouts/">/rowers/api/v3/workouts/</a>
|
|
</td>
|
|
<td>POST</td>
|
|
<td>
|
|
<pre>{
|
|
"distance": 100,
|
|
"elapsedTime": 29000,
|
|
"duration": "0:00:29.0",
|
|
"name": "Test Workout (GO)",
|
|
"startdatetime": "2023-01-16 17:54:35.588838+00:00",
|
|
"workouttype": "water",
|
|
"boattype": "1x",
|
|
"notes": "some\nnotes",
|
|
"strokes": {
|
|
"data": [
|
|
{
|
|
"time": 3200.0000476837,
|
|
"pace": 155068.4885951763,
|
|
"hr": 85.7857142857,
|
|
"power": 84.6531131591,
|
|
"distance": 23,
|
|
"spm": 16.380952381
|
|
},
|
|
{
|
|
"time": 6700.0000476837,
|
|
"pace" : 144402.6407586741,
|
|
"hr": 91.2142857143,
|
|
"power": 117.458827834,
|
|
"distance": 36,
|
|
"spm": 21.1666666667
|
|
},
|
|
{
|
|
"time": 10099.9999046326,
|
|
"pace": 138830.8712654931,
|
|
"hr": 95.7142857143,
|
|
"power": 141.31057207,
|
|
"distance": 48,
|
|
"spm": 19.8095238095
|
|
}
|
|
]
|
|
}
|
|
}
|
|
</pre>
|
|
With v3, you can post stroke data and workout metadata in one JSON object.
|
|
<br>
|
|
<p>For v3, mandatory data fields are:</p>
|
|
<p>
|
|
<ul class="contentli">
|
|
<li><b>time</b>: Time (milliseconds since workout start)</li>
|
|
<li><b>distance</b>: Distance (meters)</li>
|
|
<li><b>pace</b>: Pace (milliseconds per 500m)</li>
|
|
<li><b>spm</b> Stroke rate (strokes per minute)</li>
|
|
</ul>
|
|
</p>
|
|
<p>Optional data fiels are:</p>
|
|
<p>
|
|
<ul class="contentli">
|
|
<li><b>power</b>: Power (Watt)</li>
|
|
<li><b>latitude</b>: GPS position (latitude)</li>
|
|
<li><b>longitude</b>: GPS position (longitude)</li>
|
|
<li><b>drivelength</b>: Drive length (meters)</li>
|
|
<li><b>dragfactor</b>: Drag factor</li>
|
|
<li><b>drivetime</b>: Drive time (ms)</li>
|
|
<li><b>strokerecoverytime</b>: Recovery time (ms)</li>
|
|
<li><b>averagedriveforce</b>: Average handle force (lbs)</li>
|
|
<li><b>peakdriveforce</b>: Peak handle force (lbs)</li>
|
|
<li><b>lapidx</b>: Lap identifier</li>
|
|
<li><b>hr</b>: Heart rate (beats per minute)</li>
|
|
<li><b>wash</b>: Wash as defined per Empower oarlock (degrees)</li>
|
|
<li><b>catch</b>: Catch angle per Empower oarlock (degrees)</li>
|
|
<li><b>finish</b>: Finish angle per Empower oarlock (degrees)</li>
|
|
<li><b>peakforceangle</b>: Peak Force Angle per Empower oarlock (degrees)</li>
|
|
<li><b>slip</b>: Slip as defined per Empower oarlock (degrees)</li>
|
|
|
|
</ul>
|
|
</p>
|
|
<p>Also for this API version, consistency checks will be done and the stroke data will be
|
|
refused if the mandatory data fields don't pass the checks.
|
|
All mandatory data fields
|
|
must have the same number of records. If an optional data field
|
|
fails a test, its values are silently replaced by zeros.</p>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</p>
|
|
</li>
|
|
</ul>
|
|
|
|
{% endblock %}
|
|
|
|
{% block sidebar %}
|
|
{% include 'menu_help.html' %}
|
|
{% endblock %}
|