st half implemented
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
from .c2 import C2Integration
|
from .c2 import C2Integration
|
||||||
from .strava import StravaIntegration
|
from .strava import StravaIntegration
|
||||||
from .nk import NKIntegration
|
from .nk import NKIntegration
|
||||||
|
from .sporttracks import SportTracksIntegration
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ def c2wc(weightclass):
|
|||||||
|
|
||||||
class C2Integration(SyncIntegration):
|
class C2Integration(SyncIntegration):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(C2Integration, self).__init__(self, *args, **kwargs)
|
super(C2Integration, self).__init__(*args, **kwargs)
|
||||||
self.oauth_data = {
|
self.oauth_data = {
|
||||||
'client_id': C2_CLIENT_ID,
|
'client_id': C2_CLIENT_ID,
|
||||||
'client_secret': C2_CLIENT_SECRET,
|
'client_secret': C2_CLIENT_SECRET,
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ class SyncIntegration(metaclass=ABCMeta):
|
|||||||
rower = Rower()
|
rower = Rower()
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
user = args[1]
|
user = args[0]
|
||||||
self.user = user
|
self.user = user
|
||||||
self.rower = user.rower
|
self.rower = user.rower
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
from .integrations import SyncIntegration, NoTokenError
|
from .integrations import SyncIntegration, NoTokenError
|
||||||
from rowers.models import User, Rower, Workout, TombStone
|
from rowers.models import User, Rower, Workout, TombStone
|
||||||
|
|
||||||
from rowingdata import rowingdata
|
|
||||||
|
|
||||||
from rowers import mytypes
|
from rowers import mytypes
|
||||||
from rowers.nkimportutils import *
|
from rowers.nkimportutils import *
|
||||||
from rowers.tasks import handle_nk_async_workout
|
from rowers.tasks import handle_nk_async_workout
|
||||||
@@ -31,7 +29,7 @@ queuehigh = django_rq.get_queue('low')
|
|||||||
|
|
||||||
class NKIntegration(SyncIntegration):
|
class NKIntegration(SyncIntegration):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(NKIntegration, self).__init__(self, *args, **kwargs)
|
super(NKIntegration, self).__init__(*args, **kwargs)
|
||||||
self.oauth_data = {
|
self.oauth_data = {
|
||||||
'client_id': NK_CLIENT_ID,
|
'client_id': NK_CLIENT_ID,
|
||||||
'client_secret': NK_CLIENT_SECRET,
|
'client_secret': NK_CLIENT_SECRET,
|
||||||
@@ -310,7 +308,3 @@ class NKIntegration(SyncIntegration):
|
|||||||
|
|
||||||
return r.nktoken
|
return r.nktoken
|
||||||
|
|
||||||
# just as a quick test during development
|
|
||||||
u = User.objects.get(id=1)
|
|
||||||
|
|
||||||
nk_integration_1 = NKIntegration(u)
|
|
||||||
|
|||||||
143
rowers/integrations/sporttracks.py
Normal file
143
rowers/integrations/sporttracks.py
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
from .integrations import SyncIntegration, NoTokenError
|
||||||
|
from rowers.models import User, Rower, Workout, TombStone
|
||||||
|
|
||||||
|
from rowers.tasks import handle_sporttracks_sync
|
||||||
|
from rowers.rower_rules import is_workout_user
|
||||||
|
import rowers.mytypes as mytypes
|
||||||
|
from rowsandall_app.settings import (
|
||||||
|
SPORTTRACKS_CLIENT_SECRET, SPORTTRACKS_CLIENT_ID,
|
||||||
|
SPORTTRACKS_REDIRECT_URI
|
||||||
|
)
|
||||||
|
|
||||||
|
import re
|
||||||
|
import numpy
|
||||||
|
|
||||||
|
import django_rq
|
||||||
|
queue = django_rq.get_queue('default')
|
||||||
|
queuelow = django_rq.get_queue('low')
|
||||||
|
queuehigh = django_rq.get_queue('high')
|
||||||
|
|
||||||
|
from rowers.utils import myqueue, dologging
|
||||||
|
|
||||||
|
class SportTracksIntegration(SyncIntegration):
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super(SportTracksIntegration, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
self.oauth_data = {
|
||||||
|
'client_id': SPORTTRACKS_CLIENT_ID,
|
||||||
|
'client_secret': SPORTTRACKS_CLIENT_SECRET,
|
||||||
|
'redirect_uri': SPORTTRACKS_REDIRECT_URI,
|
||||||
|
'autorization_uri': "https://api.sporttracks.mobi/oauth2/authorize",
|
||||||
|
'content_type': 'application/json',
|
||||||
|
'tokenname': 'sporttrackstoken',
|
||||||
|
'refreshtokenname': 'sporttracksrefreshtoken',
|
||||||
|
'expirydatename': 'sporttrackstokenexpirydate',
|
||||||
|
'bearer_auth': False,
|
||||||
|
'base_url': "https://api.sporttracks.mobi/oauth2/token",
|
||||||
|
'scope': 'write',
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def open(self, *args, **kwargs) -> str:
|
||||||
|
return super(SportTracksIntegration, self).open(*args, **kwargs)
|
||||||
|
|
||||||
|
def createworkoutdata(self, w, *args, **kwargs):
|
||||||
|
return None
|
||||||
|
|
||||||
|
def workout_export(self, workout, *args, **kwargs) -> str:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_workouts(self, *args, **kwargs) -> int:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def get_workout(self, id) -> int:
|
||||||
|
_ = self.open()
|
||||||
|
|
||||||
|
r = self.rower
|
||||||
|
|
||||||
|
authorizationstring = str('Bearer ' + r.sporttrackstoken)
|
||||||
|
headers = {'Authorization': authorizationstring,
|
||||||
|
'user-agent': 'sanderroosendaal',
|
||||||
|
'Content-Type': 'application/json'}
|
||||||
|
url = "https://api.sporttracks.mobi/api/v2/fitnessActivities/" + \
|
||||||
|
str(sporttracksid)
|
||||||
|
s = requests.get(url, headers=headers)
|
||||||
|
|
||||||
|
data = s.json()
|
||||||
|
|
||||||
|
strokedata = pd.DataFrame.from_dict({
|
||||||
|
key: pd.Series(value, dtype='object') for key, value in data.items()
|
||||||
|
})
|
||||||
|
|
||||||
|
id = myqueue(
|
||||||
|
queue,
|
||||||
|
handle_sporttracks_workout_from_data,
|
||||||
|
self.user,
|
||||||
|
sporttracksid, data,
|
||||||
|
strokedata,
|
||||||
|
'sporttracks',
|
||||||
|
'sporttracks'
|
||||||
|
)
|
||||||
|
return id
|
||||||
|
|
||||||
|
|
||||||
|
def get_workout_list(self, *args, **kwargs) -> list:
|
||||||
|
_ = self.open()
|
||||||
|
r = self.rower
|
||||||
|
|
||||||
|
authorizationstring = str('Bearer ' + r.sporttrackstoken)
|
||||||
|
headers = {'Authorization': authorizationstring,
|
||||||
|
'user-agent': 'sanderroosendaal',
|
||||||
|
'Content-Type': 'application/json'}
|
||||||
|
url = "https://api.sporttracks.mobi/api/v2/fitnessActivities"
|
||||||
|
res = requests.get(url, headers=headers)
|
||||||
|
|
||||||
|
if (res.status_code != 200):
|
||||||
|
s = "Token doesn't exist. Need to authorize"
|
||||||
|
raise NoTokenError(s)
|
||||||
|
|
||||||
|
|
||||||
|
workouts = []
|
||||||
|
|
||||||
|
knownstids = uniqify([
|
||||||
|
w.uploadedtosporttracks for w in Workout.objects.filter(user=r)
|
||||||
|
])
|
||||||
|
for item in res.json()['items']:
|
||||||
|
d = int(float(item['total_distance']))
|
||||||
|
i = int(getidfromuri(item['uri']))
|
||||||
|
if i in knownstids: # pragma: no cover
|
||||||
|
nnn = ''
|
||||||
|
else:
|
||||||
|
nnn = 'NEW'
|
||||||
|
n = item['name']
|
||||||
|
ttot = str(datetime.timedelta(seconds=int(float(item['duration']))))
|
||||||
|
s = item['start_time']
|
||||||
|
r = item['type']
|
||||||
|
keys = ['id', 'distance', 'duration',
|
||||||
|
'starttime', 'rowtype', 'source', 'name', 'new']
|
||||||
|
values = [i, d, ttot, s, r, None, n, nnn]
|
||||||
|
res = dict(zip(keys, values))
|
||||||
|
workouts.append(res)
|
||||||
|
|
||||||
|
return workouts
|
||||||
|
|
||||||
|
def make_authorization_url(self, *args, **kwargs) -> str: # pragma: no cover
|
||||||
|
return super(SportTracksIntegration, self).make_authorization_url(*args, **kwargs)
|
||||||
|
|
||||||
|
def get_token(self, code, *args, **kwargs) -> (str, int, str):
|
||||||
|
return ""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def token_refresh(self, *args, **kwargs) -> str:
|
||||||
|
return super(SportTracksIntegration, self).token_refresh(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# just as a quick test during development
|
||||||
|
u = User.objects.get(id=1)
|
||||||
|
|
||||||
|
nk_integration_1 = SportTracksIntegration(u)
|
||||||
|
|
||||||
@@ -79,7 +79,7 @@ def strava_push_delete(id): # pragma: no cover
|
|||||||
|
|
||||||
class StravaIntegration(SyncIntegration):
|
class StravaIntegration(SyncIntegration):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(StravaIntegration, self).__init__(self, *args, **kwargs)
|
super(StravaIntegration, self).__init__(*args, **kwargs)
|
||||||
self.oauth_data = {
|
self.oauth_data = {
|
||||||
'client_id': STRAVA_CLIENT_ID,
|
'client_id': STRAVA_CLIENT_ID,
|
||||||
'client_secret': STRAVA_CLIENT_SECRET,
|
'client_secret': STRAVA_CLIENT_SECRET,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
from rowers.tasks import handle_sporttracks_sync
|
from rowers.tasks import handle_sporttracks_sync, handle_sporttracks_workout_from_data
|
||||||
from rowers.rower_rules import is_workout_user
|
from rowers.rower_rules import is_workout_user
|
||||||
import rowers.mytypes as mytypes
|
import rowers.mytypes as mytypes
|
||||||
from rowsandall_app.settings import (
|
from rowsandall_app.settings import (
|
||||||
@@ -127,12 +127,14 @@ def get_workout(user, sporttracksid, do_async=False):
|
|||||||
key: pd.Series(value, dtype='object') for key, value in data.items()
|
key: pd.Series(value, dtype='object') for key, value in data.items()
|
||||||
})
|
})
|
||||||
|
|
||||||
id, message = add_workout_from_data(
|
id= myqueue(
|
||||||
|
queue,
|
||||||
|
handle_sporttracks_workout_from_data,
|
||||||
user,
|
user,
|
||||||
sporttracksid, data,
|
sporttracksid, data,
|
||||||
strokedata,
|
strokedata,
|
||||||
source='sporttracks',
|
'sporttracks',
|
||||||
workoutsource='sporttracks')
|
'sporttracks')
|
||||||
|
|
||||||
return id
|
return id
|
||||||
|
|
||||||
@@ -346,165 +348,3 @@ def workout_sporttracks_upload(user, w, asynchron=False): # pragma: no cover
|
|||||||
# Create workout from SportTracks Data, which are slightly different
|
# Create workout from SportTracks Data, which are slightly different
|
||||||
# than Strava or Concept2 data
|
# than Strava or Concept2 data
|
||||||
|
|
||||||
|
|
||||||
def add_workout_from_data(user, importid, data, strokedata, source='sporttracks',
|
|
||||||
workoutsource='sporttracks'):
|
|
||||||
try:
|
|
||||||
workouttype = data['type']
|
|
||||||
except KeyError: # pragma: no cover
|
|
||||||
workouttype = 'other'
|
|
||||||
|
|
||||||
if workouttype not in [x[0] for x in Workout.workouttypes]:
|
|
||||||
workouttype = 'other'
|
|
||||||
try:
|
|
||||||
comments = data['comments']
|
|
||||||
except:
|
|
||||||
comments = ''
|
|
||||||
|
|
||||||
r = Rower.objects.get(user=user)
|
|
||||||
try:
|
|
||||||
rowdatetime = iso8601.parse_date(data['start_time'])
|
|
||||||
except iso8601.ParseError: # pragma: no cover
|
|
||||||
try:
|
|
||||||
rowdatetime = datetime.datetime.strptime(
|
|
||||||
data['start_time'], "%Y-%m-%d %H:%M:%S")
|
|
||||||
rowdatetime = thetimezone.localize(rowdatetime).astimezone(utc)
|
|
||||||
except:
|
|
||||||
try:
|
|
||||||
rowdatetime = dateutil.parser.parse(data['start_time'])
|
|
||||||
rowdatetime = thetimezone.localize(rowdatetime).astimezone(utc)
|
|
||||||
except:
|
|
||||||
rowdatetime = datetime.datetime.strptime(
|
|
||||||
data['date'], "%Y-%m-%d %H:%M:%S")
|
|
||||||
rowdatetime = thetimezone.localize(rowdatetime).astimezone(utc)
|
|
||||||
starttimeunix = arrow.get(rowdatetime).timestamp()
|
|
||||||
|
|
||||||
try:
|
|
||||||
title = data['name']
|
|
||||||
except: # pragma: no cover
|
|
||||||
title = "Imported data"
|
|
||||||
|
|
||||||
try:
|
|
||||||
res = splitstdata(data['distance'])
|
|
||||||
distance = res[1]
|
|
||||||
times_distance = res[0]
|
|
||||||
except KeyError: # pragma: no cover
|
|
||||||
try:
|
|
||||||
res = splitstdata(data['heartrate'])
|
|
||||||
times_distance = res[0]
|
|
||||||
distance = 0*times_distance
|
|
||||||
except KeyError:
|
|
||||||
return (0, "No distance or heart rate data in the workout")
|
|
||||||
|
|
||||||
try:
|
|
||||||
locs = data['location']
|
|
||||||
|
|
||||||
res = splitstdata(locs)
|
|
||||||
times_location = res[0]
|
|
||||||
latlong = res[1]
|
|
||||||
latcoord = []
|
|
||||||
loncoord = []
|
|
||||||
|
|
||||||
for coord in latlong:
|
|
||||||
lat = coord[0]
|
|
||||||
lon = coord[1]
|
|
||||||
latcoord.append(lat)
|
|
||||||
loncoord.append(lon)
|
|
||||||
except:
|
|
||||||
times_location = times_distance
|
|
||||||
latcoord = np.zeros(len(times_distance))
|
|
||||||
loncoord = np.zeros(len(times_distance))
|
|
||||||
if workouttype in mytypes.otwtypes: # pragma: no cover
|
|
||||||
workouttype = 'rower'
|
|
||||||
|
|
||||||
try:
|
|
||||||
res = splitstdata(data['cadence'])
|
|
||||||
times_spm = res[0]
|
|
||||||
spm = res[1]
|
|
||||||
except KeyError: # pragma: no cover
|
|
||||||
times_spm = times_distance
|
|
||||||
spm = 0*times_distance
|
|
||||||
|
|
||||||
try:
|
|
||||||
res = splitstdata(data['heartrate'])
|
|
||||||
hr = res[1]
|
|
||||||
times_hr = res[0]
|
|
||||||
except KeyError:
|
|
||||||
times_hr = times_distance
|
|
||||||
hr = 0*times_distance
|
|
||||||
|
|
||||||
# create data series and remove duplicates
|
|
||||||
distseries = pd.Series(distance, index=times_distance)
|
|
||||||
distseries = distseries.groupby(distseries.index).first()
|
|
||||||
latseries = pd.Series(latcoord, index=times_location)
|
|
||||||
latseries = latseries.groupby(latseries.index).first()
|
|
||||||
lonseries = pd.Series(loncoord, index=times_location)
|
|
||||||
lonseries = lonseries.groupby(lonseries.index).first()
|
|
||||||
spmseries = pd.Series(spm, index=times_spm)
|
|
||||||
spmseries = spmseries.groupby(spmseries.index).first()
|
|
||||||
hrseries = pd.Series(hr, index=times_hr)
|
|
||||||
hrseries = hrseries.groupby(hrseries.index).first()
|
|
||||||
|
|
||||||
# Create dicts and big dataframe
|
|
||||||
d = {
|
|
||||||
' Horizontal (meters)': distseries,
|
|
||||||
' latitude': latseries,
|
|
||||||
' longitude': lonseries,
|
|
||||||
' Cadence (stokes/min)': spmseries,
|
|
||||||
' HRCur (bpm)': hrseries,
|
|
||||||
}
|
|
||||||
|
|
||||||
df = pd.DataFrame(d)
|
|
||||||
|
|
||||||
df = df.groupby(level=0).last()
|
|
||||||
|
|
||||||
cum_time = df.index.values
|
|
||||||
df[' ElapsedTime (sec)'] = cum_time
|
|
||||||
|
|
||||||
velo = df[' Horizontal (meters)'].diff()/df[' ElapsedTime (sec)'].diff()
|
|
||||||
|
|
||||||
df[' Power (watts)'] = 0.0*velo
|
|
||||||
|
|
||||||
nr_rows = len(velo.values)
|
|
||||||
|
|
||||||
df[' DriveLength (meters)'] = np.zeros(nr_rows)
|
|
||||||
df[' StrokeDistance (meters)'] = np.zeros(nr_rows)
|
|
||||||
df[' DriveTime (ms)'] = np.zeros(nr_rows)
|
|
||||||
df[' StrokeRecoveryTime (ms)'] = np.zeros(nr_rows)
|
|
||||||
df[' AverageDriveForce (lbs)'] = np.zeros(nr_rows)
|
|
||||||
df[' PeakDriveForce (lbs)'] = np.zeros(nr_rows)
|
|
||||||
df[' lapIdx'] = np.zeros(nr_rows)
|
|
||||||
|
|
||||||
unixtime = cum_time+starttimeunix
|
|
||||||
unixtime[0] = starttimeunix
|
|
||||||
|
|
||||||
df['TimeStamp (sec)'] = unixtime
|
|
||||||
|
|
||||||
dt = np.diff(cum_time).mean()
|
|
||||||
wsize = round(5./dt)
|
|
||||||
|
|
||||||
velo2 = ewmovingaverage(velo, wsize)
|
|
||||||
|
|
||||||
df[' Stroke500mPace (sec/500m)'] = 500./velo2
|
|
||||||
|
|
||||||
df = df.fillna(0)
|
|
||||||
|
|
||||||
df.sort_values(by='TimeStamp (sec)', ascending=True)
|
|
||||||
|
|
||||||
# csvfilename ='media/Import_'+str(importid)+'.csv'
|
|
||||||
csvfilename = 'media/{code}_{importid}.csv'.format(
|
|
||||||
importid=importid,
|
|
||||||
code=uuid4().hex[:16]
|
|
||||||
)
|
|
||||||
|
|
||||||
res = df.to_csv(csvfilename+'.gz', index_label='index',
|
|
||||||
compression='gzip')
|
|
||||||
|
|
||||||
id, message = dataprep.save_workout_database(csvfilename, r,
|
|
||||||
workouttype=workouttype,
|
|
||||||
title=title,
|
|
||||||
notes=comments,
|
|
||||||
dosmooth=r.dosmooth,
|
|
||||||
workoutsource='sporttracks')
|
|
||||||
|
|
||||||
return (id, message)
|
|
||||||
|
|||||||
168
rowers/tasks.py
168
rowers/tasks.py
@@ -447,6 +447,174 @@ def handle_c2_sync(workoutid, url, headers, data, debug=False, **kwargs):
|
|||||||
|
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
def splitstdata(lijst):
|
||||||
|
t = []
|
||||||
|
latlong = []
|
||||||
|
while len(lijst) >= 2:
|
||||||
|
t.append(lijst[0])
|
||||||
|
latlong.append(lijst[1])
|
||||||
|
lijst = lijst[2:]
|
||||||
|
|
||||||
|
return [np.array(t), np.array(latlong)]
|
||||||
|
|
||||||
|
@app.task
|
||||||
|
def handle_sporttracks_workout_from_data(user, importid, data, strokedata, source,
|
||||||
|
workoutsource, debug=False, **kwargs):
|
||||||
|
|
||||||
|
try:
|
||||||
|
workouttype = data['type']
|
||||||
|
except KeyError: # pragma: no cover
|
||||||
|
workouttype = 'other'
|
||||||
|
|
||||||
|
if workouttype not in [x[0] for x in Workout.workouttypes]:
|
||||||
|
workouttype = 'other'
|
||||||
|
try:
|
||||||
|
comments = data['comments']
|
||||||
|
except:
|
||||||
|
comments = ''
|
||||||
|
|
||||||
|
r = Rower.objects.get(user=user)
|
||||||
|
rowdatetime = iso8601.parse_date(data['start_time'])
|
||||||
|
starttimeunix = arrow.get(rowdatetime).timestamp()
|
||||||
|
|
||||||
|
try:
|
||||||
|
title = data['name']
|
||||||
|
except: # pragma: no cover
|
||||||
|
title = "Imported data"
|
||||||
|
|
||||||
|
try:
|
||||||
|
res = splitstdata(data['distance'])
|
||||||
|
distance = res[1]
|
||||||
|
times_distance = res[0]
|
||||||
|
except KeyError: # pragma: no cover
|
||||||
|
try:
|
||||||
|
res = splitstdata(data['heartrate'])
|
||||||
|
times_distance = res[0]
|
||||||
|
distance = 0*times_distance
|
||||||
|
except KeyError:
|
||||||
|
return (0, "No distance or heart rate data in the workout")
|
||||||
|
|
||||||
|
try:
|
||||||
|
locs = data['location']
|
||||||
|
|
||||||
|
res = splitstdata(locs)
|
||||||
|
times_location = res[0]
|
||||||
|
latlong = res[1]
|
||||||
|
latcoord = []
|
||||||
|
loncoord = []
|
||||||
|
|
||||||
|
for coord in latlong:
|
||||||
|
lat = coord[0]
|
||||||
|
lon = coord[1]
|
||||||
|
latcoord.append(lat)
|
||||||
|
loncoord.append(lon)
|
||||||
|
except:
|
||||||
|
times_location = times_distance
|
||||||
|
latcoord = np.zeros(len(times_distance))
|
||||||
|
loncoord = np.zeros(len(times_distance))
|
||||||
|
if workouttype in mytypes.otwtypes: # pragma: no cover
|
||||||
|
workouttype = 'rower'
|
||||||
|
|
||||||
|
try:
|
||||||
|
res = splitstdata(data['cadence'])
|
||||||
|
times_spm = res[0]
|
||||||
|
spm = res[1]
|
||||||
|
except KeyError: # pragma: no cover
|
||||||
|
times_spm = times_distance
|
||||||
|
spm = 0*times_distance
|
||||||
|
|
||||||
|
try:
|
||||||
|
res = splitstdata(data['heartrate'])
|
||||||
|
hr = res[1]
|
||||||
|
times_hr = res[0]
|
||||||
|
except KeyError:
|
||||||
|
times_hr = times_distance
|
||||||
|
hr = 0*times_distance
|
||||||
|
|
||||||
|
# create data series and remove duplicates
|
||||||
|
distseries = pd.Series(distance, index=times_distance)
|
||||||
|
distseries = distseries.groupby(distseries.index).first()
|
||||||
|
latseries = pd.Series(latcoord, index=times_location)
|
||||||
|
latseries = latseries.groupby(latseries.index).first()
|
||||||
|
lonseries = pd.Series(loncoord, index=times_location)
|
||||||
|
lonseries = lonseries.groupby(lonseries.index).first()
|
||||||
|
spmseries = pd.Series(spm, index=times_spm)
|
||||||
|
spmseries = spmseries.groupby(spmseries.index).first()
|
||||||
|
hrseries = pd.Series(hr, index=times_hr)
|
||||||
|
hrseries = hrseries.groupby(hrseries.index).first()
|
||||||
|
|
||||||
|
# Create dicts and big dataframe
|
||||||
|
d = {
|
||||||
|
' Horizontal (meters)': distseries,
|
||||||
|
' latitude': latseries,
|
||||||
|
' longitude': lonseries,
|
||||||
|
' Cadence (stokes/min)': spmseries,
|
||||||
|
' HRCur (bpm)': hrseries,
|
||||||
|
}
|
||||||
|
|
||||||
|
df = pd.DataFrame(d)
|
||||||
|
|
||||||
|
df = df.groupby(level=0).last()
|
||||||
|
|
||||||
|
cum_time = df.index.values
|
||||||
|
df[' ElapsedTime (sec)'] = cum_time
|
||||||
|
|
||||||
|
velo = df[' Horizontal (meters)'].diff()/df[' ElapsedTime (sec)'].diff()
|
||||||
|
|
||||||
|
df[' Power (watts)'] = 0.0*velo
|
||||||
|
|
||||||
|
nr_rows = len(velo.values)
|
||||||
|
|
||||||
|
df[' DriveLength (meters)'] = np.zeros(nr_rows)
|
||||||
|
df[' StrokeDistance (meters)'] = np.zeros(nr_rows)
|
||||||
|
df[' DriveTime (ms)'] = np.zeros(nr_rows)
|
||||||
|
df[' StrokeRecoveryTime (ms)'] = np.zeros(nr_rows)
|
||||||
|
df[' AverageDriveForce (lbs)'] = np.zeros(nr_rows)
|
||||||
|
df[' PeakDriveForce (lbs)'] = np.zeros(nr_rows)
|
||||||
|
df[' lapIdx'] = np.zeros(nr_rows)
|
||||||
|
|
||||||
|
unixtime = cum_time+starttimeunix
|
||||||
|
unixtime[0] = starttimeunix
|
||||||
|
|
||||||
|
df['TimeStamp (sec)'] = unixtime
|
||||||
|
|
||||||
|
dt = np.diff(cum_time).mean()
|
||||||
|
wsize = round(5./dt)
|
||||||
|
|
||||||
|
velo2 = ewmovingaverage(velo, wsize)
|
||||||
|
|
||||||
|
df[' Stroke500mPace (sec/500m)'] = 500./velo2
|
||||||
|
|
||||||
|
df = df.fillna(0)
|
||||||
|
|
||||||
|
df.sort_values(by='TimeStamp (sec)', ascending=True)
|
||||||
|
|
||||||
|
|
||||||
|
csvfilename = 'media/{code}_{importid}.csv'.format(
|
||||||
|
importid=importid,
|
||||||
|
code=uuid4().hex[:16]
|
||||||
|
)
|
||||||
|
|
||||||
|
res = df.to_csv(csvfilename+'.gz', index_label='index',
|
||||||
|
compression='gzip')
|
||||||
|
|
||||||
|
uploadoptions = {
|
||||||
|
'secret': UPLOAD_SERVICE_SECRET,
|
||||||
|
'user': user.id,
|
||||||
|
'file': csvfilename+'.gz',
|
||||||
|
'title': '',
|
||||||
|
'workouttype': workouttype,
|
||||||
|
'boattype': '1x',
|
||||||
|
'sporttracksid': importid,
|
||||||
|
'title':title,
|
||||||
|
}
|
||||||
|
session = requests.session()
|
||||||
|
newHeaders = {'Content-type': 'application/json', 'Accept': 'text/plain'}
|
||||||
|
session.headers.update(newHeaders)
|
||||||
|
_ = session.post(UPLOAD_SERVICE_URL, json=uploadoptions)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
|
||||||
|
|
||||||
@app.task
|
@app.task
|
||||||
def handle_sporttracks_sync(workoutid, url, headers, data, debug=False, **kwargs):
|
def handle_sporttracks_sync(workoutid, url, headers, data, debug=False, **kwargs):
|
||||||
|
|||||||
@@ -236,6 +236,10 @@ def do_sync(w, options, quick=False):
|
|||||||
f.write(str(e))
|
f.write(str(e))
|
||||||
|
|
||||||
do_st_export = w.user.sporttracks_auto_export
|
do_st_export = w.user.sporttracks_auto_export
|
||||||
|
if options['sporttracksid'] != 0 and options['sporttracksid'] != '':
|
||||||
|
w.uploadedtost = options['sporttracksid']
|
||||||
|
w.save()
|
||||||
|
do_st_export = False
|
||||||
try: # pragma: no cover
|
try: # pragma: no cover
|
||||||
upload_to_st = options['upload_to_SportTracks'] or do_st_export
|
upload_to_st = options['upload_to_SportTracks'] or do_st_export
|
||||||
do_st_export = upload_to_st
|
do_st_export = upload_to_st
|
||||||
|
|||||||
@@ -5209,6 +5209,7 @@ def workout_upload_api(request):
|
|||||||
|
|
||||||
|
|
||||||
# sync related IDs
|
# sync related IDs
|
||||||
|
sporttracksid = post_data.get('sporttracksid','')
|
||||||
c2id = post_data.get('c2id', '')
|
c2id = post_data.get('c2id', '')
|
||||||
workoutid = post_data.get('id','')
|
workoutid = post_data.get('id','')
|
||||||
startdatetime = post_data.get('startdatetime', '')
|
startdatetime = post_data.get('startdatetime', '')
|
||||||
|
|||||||
Reference in New Issue
Block a user