I am getting an error trying to Link Strava Account. I see the correct client_id in the URL. Don’t see reference to the client_secret.
{"message":"Bad Request","errors":[{"resource":"Application","field":"redirect_uri","code":"invalid"}]}
I am getting an error trying to Link Strava Account. I see the correct client_id in the URL. Don’t see reference to the client_secret.
{"message":"Bad Request","errors":[{"resource":"Application","field":"redirect_uri","code":"invalid"}]}
Hi @popboxgun,
You will need to change the “Auhtorization Callback Domain” setting for your App at the Strava Developer website to the IP address or hostname of your HA instance:
Thanks, the problem appeared to be that the redirection is getting the ip 10.72.10.6 from somewhere as the callback domain. Not sure where that IP came from, it’s not on my local network.
This error was solved, I keep for other’s reference.
Hi
not sure if I’m doing well.
I created custom_components/strava/init.py and sensor.py files from your repo (just those two). Also, added this into configuration.yaml:
strava:
client_id: myaccesstoken
client_secret: myclientsecret
Finally I added some sensors, and configured My Applitcation API at Strava Developer website as you indicated above. I got at the site an Access Token and ClientSecret, and I set them in my config as indicated (not sure if they are OK…¿?)
I still get "
{“message”:“Bad Request”,“errors”:[{“resource”:“Application”,“field”:“redirect_uri”,“code”:“invalid”}]}
"
I guess I’m missing something in my setup.
Any help is much appreciated!
KR
Got it- Though I got the 500, sensors were present at <> in HA
–
changed client_ID to 12345 (as retrned in Strava Developer website). Then at HA I followed the “Link Strava Account” link and got to Authorize (great!).
Unfortunatelly, then I got an “500 Internal Server Error. Server got itself in trouble” message.
Ummm…not sure what else I can try ?
Does this still work ?
This was working fine for me for 2 years plus but noticed thats todays ride was not showing up in HA. After checking my API I noticed that this all stopped on 15th Oct 2019 and a search on Strava’s site I found this
## Update: The migration period ended on October 15, 2019
The migration period ended on October 15, 2019 and forever tokens will no longer work. If you did not migrate you will need to reauthorize your users in order to get new tokens. When your users log in, we recommend sending them to authorize with Strava again. If you are having trouble implementing OAuth, please view this guide: https://developers.strava.com/docs/getting-started/#oauth
Looks as if we will need a new way to get to this data - with no known Add-on that I can see it will stop working until a new way is found to exchange tokens on a regular basis.
You just need to create a new token and give it access to a specific scope i had the same error.
@stv0g: Sorry for coming here “begging” but it is still almost x-mas Any plans to pick up the Strava sensor again (https://github.com/home-assistant/home-assistant/pull/22151)? I do of course understand you have a busy life. A completed component in HA would have been much appreciated. I don’t know where to start myself, but if I can be of any help let me know. Happy new year!
Just picked up my HA project on the side. Got HA with Appdeamon. I am familiar (albeit still class myself as a beginner/hobbyist) with Python. I suspect this has died because of the switch to OAuth2 which will require either programmatic login or a program to request refresh every 6 hours. I’d be keen to get this working. Anyone had another go at this?
As far as I understand this has been completely abandoned. I have recently linked strava to HA using IFTTT webhooks to send data to Home Assistant variables then use a few automation a to interpret and arrange that data nicely.
It looks great!
Just yesterday I started looking for information to integrate strava into HA, and it seems that the issue is stopped by Strava API changes. Can anyone still read the Strava data? Could you share how you did it with IFTTT?
Cheers!
Hello,
I think this can be managed with some steps in order to obtain a long-time token. I am not pretty sure but I have obtained the distance. I will monitor it some days to see if the token expires.
Perfect! I hope you explain your results as soon as possible
Agur!
Well, looks like there are no “long-time” tokens any more. Strava has replaced them for short-time tokens. The good news are that there is a refresh token to reauthorize the app periodically. I am not sure if I can write an app for this but it looks feasible for someone with experience.
agur!
Hey I got Strava working, with a couple of python scripts:
You need to get all necessary tokens, here is a really good video that explains how to get them
(you need to install Postman, but curl should also work)
https://www.youtube.com/watch?v=sgscChKfGyg&t=791s
for the Python Script: https://www.youtube.com/watch?v=2FPNb1XECGs&t=611s
make sure you have python_script: in your configuration.yaml and folder named python_scripts
create a python script for each data, for example, distance of last ride is called strava_distance.py,
with this content: (replace all three XXX with your data)
import requests
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
auth_url = "https://www.strava.com/oauth/token"
activites_url = "https://www.strava.com/api/v3/athlete/activities"
payload = {
'client_id': "XXX",
'client_secret': 'XXX',
'refresh_token': 'XXX',
'grant_type': "refresh_token",
'f': 'json'
}
# print("Requesting Token...\n")
res = requests.post(auth_url, data=payload, verify=False)
access_token = res.json()['access_token']
# print("Access Token = {}\n".format(access_token))
header = {'Authorization': 'Bearer ' + access_token}
param = {'per_page': 200, 'page': 1}
my_dataset = requests.get(activites_url, headers=header, params=param).json()
print(my_dataset[0]["distance"])
- platform: command_line
name: Strava Distanz
command: "python3 /config/python_scripts/strava_distance.py"
command_timeout: 60
scan_interval: 180
that’s it! you need to restart Home Assistant but all sensors should work, tested it now for a couple of weeks and it works without problems or API errors
–
here some useful template sensors:
distance in kilometers:
- platform: template
sensors:
strava_distanz_km:
friendly_name: "Strava Distanz Km"
value_template: >
{{ (states('sensor.strava_distanz') |int / 1000) | round(2) }}
average speed in km/h:
- platform: command_line
name: Strava Average Speed
command: "python3 /config/python_scripts/strava_average_speed.py"
value_template: '{{ (value | multiply(3600) / 1000) | round(2) }}'
unit_of_measurement: km/h
command_timeout: 60
scan_interval: 180
duration time in HH:MM:SS:
- platform: template
sensors:
strava_duration_insgesamt_hh_mm_ss:
friendly_name: Strecke Insgesamt
icon_template: mdi:bike
entity_id: sensor.time
value_template: >-
{% set t = states('sensor.strava_elapsed_time') | int %}
{{ '{:02d}:{:02d}:{:02d}'.format((t // 3600) % 24, (t % 3600) // 60, (t % 3600) % 60) }}
arrive time in HH:MM:SS:
- platform: template
sensors:
strava_ankunft_uhrzeit:
friendly_name: Startzeit
icon_template: mdi:timer-off-outline
entity_id: sensor.time
value_template: >-
{% set minutes = states('sensor.strava_elapsed_time') | int %}
{{ (as_timestamp(strptime(states.sensor.strava_start_time.state, "%Y-%m-%dT%XZ")) + (minutes)) | timestamp_custom('%H:%M:%S') }}
Great! I was doing the same thing but inside an addon. Have you think about putting that in one of them?
I will continue doing it but it is my first one.
Continuing with the idea of @drimpart, I have done the following to avoid creating several python files and many sensors.
import requests
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
import logging
logging.basicConfig(level=logging.DEBUG)
auth_url = "https://www.strava.com/oauth/token"
activites_url = "https://www.strava.com/api/v3/athlete/activities"
payload = {
'client_id': "XXXXX",
'client_secret': 'XXXXX',
'refresh_token': 'XXXXX',
'grant_type': "refresh_token",
'f': 'json'
}
res = requests.post(auth_url, data=payload, verify=False)
access_token = res.json()['access_token']
print(access_token)
- platform: command_line
name: Strava Access Token
command: "python3 /config/python_scripts/strava.py"
scan_interval: 900
- platform: rest
name: Strava Last Activity
json_attributes_path: "$.[0]"
json_attributes:
- distance
- total_elevation_gain
- average_speed
- average_heartrate
- moving_time
resource_template: https://www.strava.com/api/v3/athlete/activities?access_token={{ states('sensor.strava_access_token') }}
method: GET
value_template: '{{ value_json[0].name }}'
scan_interval: 300
- platform: template
sensors:
strava_last_distance:
friendly_name: 'Strava Last Distance'
value_template: "{{ ((state_attr('sensor.strava_last_activity', 'distance'))/1000) | round(2) }}"
unit_of_measurement: "km"
entity_id: sensor.strava_last_activity
strava_last_elevation:
friendly_name: 'Strava Last Elevation'
value_template: "{{ (state_attr('sensor.strava_last_activity', 'total_elevation_gain')) | round(1) }}"
unit_of_measurement: "m"
entity_id: sensor.strava_last_activity
Thank you @drimpart for sharing.
I think the pro of this way is that requires less files and lines, the contra is that you expose the token in a sensor value.
I am still thinking about doing an addon for the first step (granting authorization).
EDIT: I have seen that there are two limits: 100 requests per 15min and 1000 requests per day.
Check the “scan_interval” of your py script files and rest commands, to avoid reaching the daily limit.
If you have 2 urls (one for last activity and another for your total stats), you could have an interval of 300s = 5min -> 288 times a day * 2 urls = 576 requests for the rest + 96 more for the refresh token.
thanks @icaballero, the json_attributes makes it definitely more compact and easier, I tried something similar, but id didn’t work out, I might change it to this version.
Unfortunately, I have no idea how to create an addon, but it would make the whole process definitely easier to have one, maybe somebody else can help.
Also, it seems I have different request limits (Premium Account), so my scan_interval of 180 seconds is no problem. you can always check if you are on the limit on your profile https://www.strava.com/settings/api
Is the Premium Account the same as having a summit subscription?
I have one but my limits are the standard ones.
Rhythm (min per km) for runners using the speed:
- platform: template
sensors:
strava_last_rhythm:
friendly_name: 'Strava Last Rhythm'
value_template: >-
{% set t = (100/ (state_attr('sensor.strava_last_activity', 'average_speed')|multiply(0.06)) ) %}
{{ '{:02d}:{:02d}'.format((t//100)|int,((t%100)*0.6) |int) }}
unit_of_measurement: "min/km"