Some Strava sensors

I have been having a play around to see what kind of information can be gathered from the strava api for us that cycle.

This is far from what i want to be able to do with the API, but i see this as a start.

If anyone else is interested in helping me please drop me a pm. I would love to make a component that we can easily integrate into HAS.

Get yourself to [https://www.strava.com/settings/api]

The access token retrieved via settings -> My API Application this has the default permission.Which means we can only read public activities.

I am working on writing some simple scripts to delete and upload new activities, which requires an access token with write permission.

This guide details how to quickly get a Strava access token with write access.

  1. Log into the strava website https://www.strava.com/settings/api

  2. Create an application “My Api Application”

  3. Make sure that you set the callback URL a localhost. We will need to to obtain an authorization token.

Take note of your client ID, these will be needed later

Leave strava tab open

Create a request URL for Strava authorization, where the base URL is https://www.strava.com/oauth/authorize and parameters are:

client_id:	your application’s ID, obtained during registration
redirect_uri:	URL to which the user will be redirected with the authorization code. 
response_type:	must be 'code'
scope:	'public', 'write', 'view_private', 'view_private,write'

Example

"http://www.strava.com/oauth/authorize?client_id="CLIENT_ID_FROM_API_SETTINGS"&response_type=code&redirect_uri=http://localhost/exchange_token&approval_prompt=force&scope=write"

  1. Copy the above URL with your “Client_id” into a browser.
  2. Browser will 404 as http://localhost/exchange_token does not exist.
  3. Authorize the app on Strava.
  4. Copy the authorization URL from previous step and take note of the code.

Example
http://localhost/exchange_token?state=&code=43534534534543gfgfdgdfgdfgd43563

Authentication

Use a rest client. Perform a POST to https://www.strava.com/oauth/token as documented in the API. ]

client_id: your application’s ID, obtained during registration
client_secret: your application’s secret, obtained during registration
code: authorization code from last step

Example
$ curl -X POST https://www.strava.com/oauth/token
-F client_id="CLIENT_ID_FROM_API_SETTINGS
-F client_secret="CLIENT_SECRET_FROM_API_SETTINGS
-F code=“CODE_FROM_PREVIOUS_STEP”

Retreiving data.

Strava offers many endpoints, i have only played around with a couple at the moment.

/v3/oauth
/v3/athlete
/v3/athletes/:id
/v3/activities/:id
/v3/activities/:id/streams
/v3/clubs/:id
/v3/segments/:id
/v3/segments/:id/leaderboard
/v3/segments/:id/all_efforts
/v3/uploads

Example using v3/activities

Using a rest client perform a GET with the following

https://www.strava.com/api/v3/activities?access_token=“YOUR_API_KEY”

Information returned from the api

Any of the fields can be used and brought into the front end in HomeAssistant using the rest platform. It is worth referring to the documentation when picking up fields in Home assistant. https://strava.github.io/api/v3/activities/

As an example elevation_gain is reported in meters, but on my mobile app it is reported in ft. It bugged me the wrong measurement being reported in Home Assistant on the front end.

total_elevation_gain:	float 
meters

Using a value template you can convert metres to feet and vice versa.

value_template: '{{ value_json[0].elev_high | multiply(3.280839895) | round(1) }}'

1 Meter = 3.28084 feet

Home Assistant Configuration
Sensor.yaml sample
Picking up the elev_high parameter from the api which is reported in metres, but converted to FT
sensor.yaml

- platform: rest
  name: strava_elev_high
  resource:  https://www.strava.com/api/v3/activities
  method: GET
  headers:
    Authorization:YOUR_API_TOKEN
  value_template: '{{ value_json[0].elev_high | multiply(3.280839895) | round(1) }}'
  unit_of_measurement: ft
  scan_interval: 300

stravahas

Automation based on sensor

- alias: Notify Last Ride Mileage
  trigger:
    - platform: state
      entity_id: sensor.strava_last_ride_milage
  condition:
    condition: template
    value_template: "{{ states('sensor.strava_last_ride_mileage) != 'unknown' }}"
  action:
    - service: notify.notifier_telegram
      data_template:
        message: Ride uploaded to strava

i hope to add more sensors so that when a message is sent to a notifier we can have a summary of information such as heart rate, average, speed etc. These sensors can then be used with tts script.

Very quick write up so apologies for any mistakes

6 Likes

Hi,
̶g̶r̶e̶a̶t̶ ̶w̶o̶r̶k̶,̶ ̶b̶u̶t̶ ̶I̶ ̶t̶h̶i̶n̶k̶ ̶y̶o̶u̶ ̶a̶r̶e̶ ̶g̶o̶i̶n̶g̶ ̶t̶o̶ ̶r̶u̶n̶ ̶i̶n̶t̶o̶ ̶t̶r̶o̶u̶b̶l̶e̶ ̶w̶i̶t̶h̶ ̶t̶h̶i̶s̶ ̶a̶p̶p̶r̶o̶a̶c̶h̶.̶ ̶T̶h̶e̶ ̶a̶u̶t̶h̶o̶r̶i̶z̶a̶t̶i̶o̶n̶ ̶y̶o̶u̶ ̶a̶r̶e̶ ̶g̶e̶t̶t̶i̶n̶g̶ ̶w̶i̶l̶l̶ ̶e̶x̶p̶i̶r̶e̶,̶ ̶y̶o̶u̶ ̶w̶i̶l̶l̶ ̶h̶a̶v̶e̶ ̶t̶o̶ ̶s̶t̶a̶r̶t̶ ̶o̶v̶e̶r̶ ̶a̶g̶a̶i̶n̶ ̶t̶h̶e̶n̶.̶

There is a python library for the strava api (didn’t check it). You might want to check that out and write a component. Should be easier and reliable.


Will be looking into the component soon.

Had a look at stravalib it authenticates in the same way

@Dean_James
Do you have a working custom_component?

In progress at the moment!

4 Likes

Any update on this? I’d love to add some Strava stats.

None i am afraid been tied up with other stuff.

You can still add some stats with the above what are you looking at adding ?

@Dean_James Great that you documented your steps, was up an running with this in a few minutes, and it was exactly what I needed for my new automation (“if I cycled to work this morning, open the garage cover when I arrive back home after work”).

1 Like

@eithe Glad it was of some help. I need to pull my finger out and revisit this.

Happy Cycling !

1 Like

The Strava API Team will release an upgraded activity-update webhook events system to all apps with a webhook events subscription on January 15, 2018; all existing subscriptions will be converted to the new system on that date. The new system will enable apps to receive webhook events when an activity has been created, deleted, or updated:
Activity title change
Activity type change
Photos added/removed
Activity privacy change, only for apps with a view_private access token
If you’re interested in beta testing the new webhooks system, please respond to this email and you will receive additional information about this process.
Between now and January 15, 2018, we will primarily use our developer Google group and our new documentation website to communicate these webhook events changes.
We hope this change will satisfy your existing needs and give us the chance to extend support for subscriptions.

Hi

Thank you @Dean_James for the code.
Can you advise what to do to eliminate the error I’ve got when checking config after sensor was added like in your post above?

  • platform: rest
    name: strava_distance
    resource: https://www.strava.com/api/v3/activities
    method: GET
    headers:
    Authorization:My_token_here
    value_template: ‘{{ value_json[0].distance }}’
    unit_of_measurement: meter
    scan_interval: 6000

The error message is as follow:
2017-11-24 23:58:53 ERROR (MainThread) [homeassistant.config] Invalid config for [sensor.rest]: expected a dictionary for dictionary value @ data[‘headers’]. Got 'Authoriz
ation:my_token_here’. (See ?, line ?). Please check the docs at https://home-assistant.io/components/sensor.rest/

Hi

Had the same issue, put “Authorization: Bearer MY_API_TOKEN” and it worked. Don’t know why.

RB

Hello again,

I’m trying to use the sensor template to avoid calling multiple times the API. Here’s what I tried.

  - platform: rest
    name: strava_last_distance
    friendly_name : Distance parcourue
    resource: https://www.strava.com/api/v3/activities
    method: GET
    headers:
      Authorization: !secret strava_token
    json_attributes:
      - 
      - moving_time
      - average_speed
      - average_heartrate
    value_template: '{{ value_json[0].distance | multiply(0.001)}}'
    unit_of_measurement: km
    scan_interval: 300
  - platform: template
    sensors:
      strava_last_elevation:
        friendly_name: Dénivelé
        value_template: '{{ states.sensor.strava_last_distance.attributes["total_elevation_gain"] }}'
        unit_of_measurement: m
        entity_id: sensor.strava_last_distance

This code return nothing for “strava_last_elevation”.

I think my mistake comes from “value_template” because it doesn’t call the first value of the array. I don’t find the proper way to do that.

Does anyone done something like that ?

I have this for last elevation @Naxxos

indent preformatted text by 4 spaces
- platform: rest
name: strava__last_ride_total_elevation_gain
resource:  https://www.strava.com/api/v3/activities?
access_token=&per_page=200
method: GET
headers:
Authorization:
value_template: '{{ value_json[0].total_elevation_gain | multiply(3.280839895) | round(1)  }}'
unit_of_measurement: ft
scan_interval: 300

Just done a ride this morning and elevation is reported correctly

Have any of you tried to get the activity from one of your followers?

Are you guys thinking about creating an official component which would be easier for “normal” person to use?

1 Like

@godinperson i started with a component but struggling for time.

Maybe someone can help? What are you struggling with?

Can’t find anything in the API documentation about monthly run totals for a sensor I’m trying to configure. Any idea how to retrieve these values?

have you tried

ActivityTotal
A roll-up of metrics pertaining to a set of activities.

count
integer The number of activities considered in this total.
distance
float The total distance covered by the considered activiti