works except for target cadence
This commit is contained in:
115
garminscript.py
115
garminscript.py
@@ -28,23 +28,24 @@ payload = {
|
||||
'workoutSourceId': 'Rowsandall.com',
|
||||
'steps': [
|
||||
{
|
||||
'type': 'WorkoutStep', 'stepOrder': 0,
|
||||
'type': 'WorkoutStep',
|
||||
'stepOrder': 0,
|
||||
#'repeatType': 'Step',
|
||||
'repeatValue': 1,
|
||||
#'repeatValue': 1,
|
||||
'intensity': 'ACTIVE',
|
||||
'description': '0',
|
||||
'description': 'At 220W',
|
||||
'durationType': 'TIME',
|
||||
'durationValue': 1800,
|
||||
'durationValueType': 'METER',
|
||||
'durationValueType': None,
|
||||
'targetType': 'POWER',
|
||||
'targetValue': 1226,
|
||||
'targetValue': 226,
|
||||
'targetValueLow': None,
|
||||
'targetValueHigh': None,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
payload = {
|
||||
payload2 = {
|
||||
"workoutName": "Test",
|
||||
"description": "Test",
|
||||
"sport": "CYCLING",
|
||||
@@ -55,16 +56,93 @@ payload = {
|
||||
"intensity": "INTERVAL",
|
||||
"description": "Free Ride",
|
||||
"durationType": "TIME",
|
||||
"durationValue": 300,
|
||||
"durationValue": 1800,
|
||||
"durationValueType": None,
|
||||
"targetType": "POWER",
|
||||
"targetValue": None,
|
||||
"targetValueLow": 0,
|
||||
"targetValueHigh": 0.7,
|
||||
"targetValueType": "PERCENT",
|
||||
"targetValue": 226,
|
||||
"targetValueLow": None,
|
||||
"targetValueHigh": None,
|
||||
"targetValueType": None,
|
||||
"exerciseCategory": None
|
||||
}]}
|
||||
|
||||
payload = {'workoutName': '4x1000m',
|
||||
'sport': 'GENERIC',
|
||||
'description': 'Uploaded from Rowsandall.com',
|
||||
'estimatedDurationInSecs': 2700,
|
||||
'estimatedDistanceInMeters': 8768,
|
||||
'workoutProvider': 'Rowsandall.com',
|
||||
'workoutSourceId': 'Rowsandall.com',
|
||||
'steps': [{'type': 'WorkoutStep',
|
||||
'stepOrder': 0,
|
||||
'repeatType': None,
|
||||
'repeatValue': 1,
|
||||
'intensity': 'INTERVAL',
|
||||
'description': '0',
|
||||
'durationType': 'DISTANCE',
|
||||
'durationValue': 2000,
|
||||
'durationValueType': 'METER',
|
||||
'targetType': None,
|
||||
'targetValue': None,
|
||||
'targetValueLow': None,
|
||||
'targetValueHigh': None},
|
||||
{'type': 'WorkoutRepeatStep',
|
||||
'stepOrder': 1,
|
||||
'repeatType': 'REPEAT_UNTIL_STEPS_CMPLT',
|
||||
'repeatValue': 4,
|
||||
'intensity': 'INTERVAL',
|
||||
'description': '3',
|
||||
'durationType': 'REPS',
|
||||
'durationValue': None,
|
||||
'durationValueType': None,
|
||||
'targetType': None,
|
||||
'targetValue': None,
|
||||
'targetValueLow': None,
|
||||
'targetValueHigh': None,
|
||||
'steps': [{'type': 'WorkoutStep',
|
||||
'stepOrder': 2,
|
||||
'repeatType': None,
|
||||
'repeatValue': 1,
|
||||
'intensity': 'INTERVAL',
|
||||
'description': '1',
|
||||
'durationType': 'DISTANCE',
|
||||
'durationValue': 1000,
|
||||
'durationValueType': 'METER',
|
||||
#'targetType': 'CADENCE',
|
||||
#'targetValue': 25,
|
||||
#'targetValueLow': None,
|
||||
#'targetValueHigh': None
|
||||
},
|
||||
{'type': 'WorkoutStep',
|
||||
'stepOrder': 3,
|
||||
'repeatType': None,
|
||||
'repeatValue': 1,
|
||||
'intensity': 'REST',
|
||||
'description': '2',
|
||||
'durationType': 'TIME',
|
||||
'durationValue': 60,
|
||||
'durationValueType': None,
|
||||
'targetType': None,
|
||||
'targetValue': None,
|
||||
'targetValueLow': None,
|
||||
'targetValueHigh': None}]},
|
||||
{'type': 'WorkoutStep',
|
||||
'stepOrder': 4,
|
||||
'repeatType': None,
|
||||
'repeatValue': 1,
|
||||
'intensity': 'INTERVAL',
|
||||
'description': '4',
|
||||
'durationType': 'DISTANCE',
|
||||
'durationValue': 2000,
|
||||
'durationValueType': 'METER',
|
||||
'targetType': None,
|
||||
'targetValue': None,
|
||||
'targetValueLow': None,
|
||||
'targetValueHigh': None}]}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
print(json.dumps(payload))
|
||||
|
||||
@@ -95,4 +173,17 @@ response = requests.post(url,auth=authheaders,json=payload)
|
||||
# build base_string
|
||||
|
||||
print(response.status_code)
|
||||
print(response.text)
|
||||
|
||||
print(response.json())
|
||||
garmin_workout_id = response.json()['workoutId']
|
||||
url = 'http://apis.garmin.com/training-api/schedule'
|
||||
|
||||
payload = {
|
||||
'workoutId': garmin_workout_id,
|
||||
'date': '2021-05-16'
|
||||
}
|
||||
|
||||
|
||||
response = requests.post(url,auth=authheaders,json=payload)
|
||||
print(response.status_code)
|
||||
print(response.json())
|
||||
|
||||
@@ -27,13 +27,6 @@ from rowsandall_app.settings import (
|
||||
|
||||
from pytz import timezone as tz, utc
|
||||
|
||||
#try:
|
||||
# import http.client as http_client
|
||||
#except ImportError:
|
||||
# Python 2
|
||||
# import httplib as http_client
|
||||
#http_client.HTTPConnection.debuglevel = 1
|
||||
|
||||
# You must initialize logging, otherwise you'll not see debug output.
|
||||
#logging.basicConfig()
|
||||
#logging.getLogger().setLevel(logging.DEBUG)
|
||||
@@ -82,6 +75,36 @@ columns = {
|
||||
'bikeCadenceInRPM':' Cadence (stokes/min)',
|
||||
}
|
||||
|
||||
targettypes = {
|
||||
"Speed": "SPEED",
|
||||
"HeartRate": "HEART_RATE",
|
||||
"Open": "OPEN",
|
||||
"Cadence": "CADENCE",
|
||||
"Power": "POWER",
|
||||
"Grade": "GRADE",
|
||||
"Resistance": "RESISTANCE",
|
||||
"Power3s": "POWER_3S",
|
||||
"Power10s": "POWER_10S",
|
||||
"Power30s": "POWER_30S",
|
||||
"PowerLap": "POWER_LAP",
|
||||
"SwimStroke": "SWIM_STROKE",
|
||||
"SpeedLap": "SPEED_LAP",
|
||||
"HeartRateLap": "HEART_RATE_LAP"
|
||||
}
|
||||
|
||||
repeattypes = {
|
||||
"RepeatUntilStepsCmplt": "REPEAT_UNTIL_STEPS_CMPLT",
|
||||
"RepeatUntilTime": "REPEAT_UNTIL_TIME",
|
||||
"RepeatUntilDistance": "REPEAT_UNTIL_TIME",
|
||||
"RepeatUntilCalories": "REPEAT_UNTIL_CALORIES" ,
|
||||
"RepeatUntilHrLessThan": "REPEAT_UNTIL_HR_LESS_THAN" ,
|
||||
"RepeatUntilHrGreaterThan": "REPEAT_UNTIL_HR_GREATER_THAN",
|
||||
"RepeatUntilPowerLessThan": "REPEAT_UNTIL_POWER_LESS_THAN",
|
||||
"RepeatUntilPowerGreaterThan": "REPEAT_UNTIL_POWER_GREATER_THAN",
|
||||
"RepeatUntilPowerLapLessThan": "REPEAT_UNTIL_POWER_LAP_LESS_THAN",
|
||||
"RepeatUntilPowerLapGreaterThan": "REPEAT_UNTIL_POWER_LAP_GREATER_THAN",
|
||||
}
|
||||
|
||||
def garmin_authorize(): # pragma: no cover
|
||||
redirect_uri = oauth_data['redirect_uri']
|
||||
client_secret = oauth_data['client_secret']
|
||||
@@ -179,9 +202,11 @@ from rowers import utils
|
||||
def step_to_garmin(step,order=0):
|
||||
durationtype = step['dict']['durationType']
|
||||
durationvalue = step['dict']['durationValue']
|
||||
durationvaluetype = ''
|
||||
durationvaluetype = None
|
||||
try:
|
||||
intensity = step['dict']['intensity']
|
||||
intensity = step['dict']['intensity'].upper()
|
||||
if intensity.lower() == 'active':
|
||||
intensity = 'INTERVAL'
|
||||
except KeyError:
|
||||
intensity = None
|
||||
#durationvaluetype = ''
|
||||
@@ -197,56 +222,87 @@ def step_to_garmin(step,order=0):
|
||||
if durationvalue <= 100:
|
||||
durationvaluetype = 'PERCENT'
|
||||
else:
|
||||
durationvaluetype = ''
|
||||
durationvaluetype = None
|
||||
durationvalue -= 100
|
||||
elif durationtype == 'HrGreaterThan': # pragma: no cover
|
||||
durationtype = 'HR_GREATER_THAN'
|
||||
if durationvalue <= 100:
|
||||
durationvaluetype = 'PERCENT'
|
||||
else:
|
||||
durationvaluetype = ''
|
||||
durationvaluetype = None
|
||||
durationvalue -= 100
|
||||
elif durationtype == 'PowerLessThan': # pragma: no cover
|
||||
durationtype = 'POWER_LESS_THAN'
|
||||
if durationvalue <= 1000:
|
||||
durationvaluetype = 'PERCENT'
|
||||
else:
|
||||
durationvaluetype = ''
|
||||
durationvaluetype = None
|
||||
durationvalue -= 1000
|
||||
elif durationtype == 'PowerGreaterThan': # pragma: no cover
|
||||
durationtype = 'POWER_GREATER_THAN'
|
||||
if durationvalue <= 1000:
|
||||
durationvaluetype = 'PERCENT'
|
||||
else:
|
||||
durationvaluetype = ''
|
||||
durationvaluetype = None
|
||||
durationvalue -= 1000
|
||||
elif durationtype == 'Reps': # pragma: no cover
|
||||
durationtype = 'REPS'
|
||||
|
||||
try:
|
||||
targetType = step['dict']['targetType']
|
||||
targetType = targettypes[targetType]
|
||||
except KeyError:
|
||||
targetType = None
|
||||
|
||||
|
||||
try:
|
||||
targetValue = step['dict']['targetValue']
|
||||
if targetValue == 0:
|
||||
targetValue = None
|
||||
except KeyError:
|
||||
targetValue = None
|
||||
try:
|
||||
targetValueLow = step['dict']['targetValueLow']
|
||||
if targetValueLow == 0:
|
||||
targetValueLow = None
|
||||
except KeyError:
|
||||
targetValueLow = None
|
||||
try:
|
||||
targetValueHigh = step['dict']['targetValueHigh'],
|
||||
targetValueHigh = step['dict']['targetValueHigh']
|
||||
if targetValueHigh == 0:
|
||||
targetValueHigh = None
|
||||
except KeyError:
|
||||
targetValueHigh = None
|
||||
|
||||
if targetType.lower() == "power":
|
||||
targetType = 'POWER'
|
||||
if targetValue is not None and targetValue > 1000:
|
||||
targetValue -= 1000
|
||||
if targetValueHigh is not None and targetValueHigh > 1000:
|
||||
targetValueHigh -= 1000
|
||||
if targetValueLow is not None and targetValueLow > 1000:
|
||||
targetValueLow -= 1000
|
||||
|
||||
if targetValue is None and targetValueLow is None and targetValueHigh is None:
|
||||
targetType = None
|
||||
|
||||
steptype = 'WorkoutRepeatStep'
|
||||
if step['type'].lower() == 'step':
|
||||
steptype = 'WorkoutStep'
|
||||
|
||||
repeattype = None
|
||||
if steptype == 'WorkoutRepeatStep':
|
||||
repeattype = repeattypes[step['dict']['durationType']]
|
||||
durationtype = 'REPS'
|
||||
durationvalue = None
|
||||
durationvaluetype = None
|
||||
targetType = None
|
||||
targetValue = None
|
||||
|
||||
out = {
|
||||
'type': step['type'],
|
||||
'type': steptype,
|
||||
'stepOrder':order,
|
||||
'repeatType':step['type'],
|
||||
'repeatType':repeattype,
|
||||
'repeatValue':step['repeatValue'],
|
||||
'intensity':intensity,
|
||||
'description':step['dict']['wkt_step_name'],
|
||||
@@ -303,30 +359,10 @@ def ps_to_garmin(ps,r):
|
||||
lijst.append(gstep)
|
||||
|
||||
payload['steps'] = lijst
|
||||
url = 'https://apis.garmin.com/training-api/workout/'
|
||||
|
||||
garmin = OAuth1Session(oauth_data['client_id'],
|
||||
client_secret=oauth_data['client_secret'],
|
||||
resource_owner_key=r.garmintoken,
|
||||
resource_owner_secret=r.garminrefreshtoken,
|
||||
signature_method='HMAC-SHA1',
|
||||
encoding='base64'
|
||||
)
|
||||
return payload
|
||||
|
||||
|
||||
response = garmin.post(url,data=payload)
|
||||
|
||||
#POST /training-api/workout?undefined HTTP/1.1
|
||||
#Authorization: OAuth oauth_nonce="3347376452", oauth_signature="jM8%2BCsflDfmB6SGYFIEFa%2BKRBOU%3D", oauth_token="673806b7-aa7b-4064-8290-2dd1b0236ae6", oauth_consumer_key="ca29ba5e-6868-4468-987d-4ee60a1f04bf", oauth_timestamp="1616050850", oauth_signature_method="HMAC-SHA1", oauth_version="1.0"
|
||||
#Host: apis.garmin.com
|
||||
#Accept: */*
|
||||
|
||||
#curl -v --header 'Authorization: OAuth oauth_nonce="3347376452", oauth_signature="jM8%2BCsflDfmB6SGYFIEFa%2BKRBOU%3D", oauth_token="673806b7-aa7b-4064-8290-2dd1b0236ae6", oauth_consumer_key="ca29ba5e-6868-4468-987d-4ee60a1f04bf", oauth_timestamp="1616050850", oauth_signature_method="HMAC-SHA1", oauth_version="1.0"' 'https://apis.garmin.com/training-api/workout'
|
||||
|
||||
#Authorization: OAuth oauth_nonce="3347376452", oauth_signature="jM8%2BCsflDfmB6SGYFIEFa%2BKRBOU%3D", oauth_token="673806b7-aa7b-4064-8290-2dd1b0236ae6", oauth_consumer_key="ca29ba5e-6868-4468-987d-4ee60a1f04bf", oauth_timestamp="1616050850", oauth_signature_method="HMAC-SHA1", oauth_version="1.0"
|
||||
|
||||
return response
|
||||
|
||||
|
||||
def get_garmin_permissions(user): # pragma: no cover
|
||||
r = Rower.objects.get(user=user)
|
||||
@@ -334,15 +370,18 @@ def get_garmin_permissions(user): # pragma: no cover
|
||||
s = "Token doesn't exist. Need to authorize"
|
||||
return custom_exception_handler(401,s)
|
||||
|
||||
garmin = OAuth1Session(oauth_data['client_id'],
|
||||
client_secret=oauth_data['client_secret'],
|
||||
resource_owner_key=r.garmintoken,
|
||||
resource_owner_secret=r.garminrefreshtoken,
|
||||
)
|
||||
garminheaders = OAuth1(
|
||||
client_key = oauth_data['client_id'],
|
||||
client_secret=oauth_data['client_secret'],
|
||||
resource_owner_key=r.garmintoken,
|
||||
resource_owner_secret=r.garminrefreshtoken,
|
||||
signature_method='HMAC-SHA1',
|
||||
)
|
||||
|
||||
url = 'https://apis.garmin.com/userPermissions/'
|
||||
|
||||
result = garmin.get(url)
|
||||
url = 'https://apis.garmin.com/userPermissions'
|
||||
|
||||
result = requests.get(url,auth=garminheaders)
|
||||
|
||||
if result.status_code == 200:
|
||||
return result.json()
|
||||
@@ -351,31 +390,58 @@ def get_garmin_permissions(user): # pragma: no cover
|
||||
|
||||
def garmin_session_create(ps,user): # pragma: no cover
|
||||
if not ps.steps:
|
||||
print('aap')
|
||||
return 0
|
||||
if not garmin_can_export_session(user):
|
||||
print('noot')
|
||||
return 0
|
||||
|
||||
garmindict = ps_to_garmin(ps)
|
||||
|
||||
r = Rower.objects.get(user=user)
|
||||
if (r.garmintoken == '') or (r.garmintoken is None):
|
||||
s = "Token doesn't exist. Need to authorize"
|
||||
return custom_exception_handler(401,s)
|
||||
|
||||
garmin = OAuth1Session(oauth_data['client_id'],
|
||||
client_secret=oauth_data['client_secret'],
|
||||
resource_owner_key=r.garmintoken,
|
||||
resource_owner_secret=r.garminrefreshtoken,
|
||||
)
|
||||
payload = ps_to_garmin(ps,r)
|
||||
|
||||
url = 'http://apis.garmin.com/training-api/schedule/'
|
||||
url = 'https://apis.garmin.com/training-api/workout'
|
||||
|
||||
garminheaders = OAuth1(
|
||||
client_key = oauth_data['client_id'],
|
||||
client_secret=oauth_data['client_secret'],
|
||||
resource_owner_key=r.garmintoken,
|
||||
resource_owner_secret=r.garminrefreshtoken,
|
||||
signature_method='HMAC-SHA1',
|
||||
)
|
||||
|
||||
response = requests.post(url,auth=garminheaders,json=payload)
|
||||
print(response.status_code,response.text)
|
||||
|
||||
response = garmin.post(url,data=garmindict)
|
||||
|
||||
if response.status_code != 200:
|
||||
return 0
|
||||
|
||||
return response.json()['workoutId']
|
||||
garmin_workout_id = response.json()['workoutId']
|
||||
|
||||
|
||||
url = 'http://apis.garmin.com/training-api/schedule'
|
||||
|
||||
payload = {
|
||||
'workoutId': garmin_workout_id,
|
||||
'date': ps.preferreddate.strftime('%Y-%m-%d')
|
||||
}
|
||||
|
||||
|
||||
response = requests.post(url,auth=garminheaders,json=payload)
|
||||
print(response.status_code,response.text)
|
||||
|
||||
if response.status_code != 200:
|
||||
return 0
|
||||
|
||||
ps.garmin_schedule_id = response.json()
|
||||
ps.garmin_workout_id = garmin_workout_id
|
||||
ps.save()
|
||||
|
||||
return garmin_workout_id
|
||||
|
||||
def garmin_getworkout(garminid,r,activity):
|
||||
starttime = activity['startTimeInSeconds']
|
||||
|
||||
@@ -2399,6 +2399,8 @@ class PlannedSession(models.Model):
|
||||
steps = PlannedSessionStepField(default={},null=True)
|
||||
interval_string = models.TextField(max_length=1000,default=None,blank=True,null=True,
|
||||
verbose_name='Interval String (optional)')
|
||||
garmin_workout_id = models.BigIntegerField(default=0)
|
||||
garmin_schedule_id = models.BigIntegerField(default=0)
|
||||
|
||||
tags = TaggableManager(blank=True)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user