Monday, 1 December 2014

Raspberry Pi and Strava API #2

In a previous post blogged on how I've managed to cross the streams of two of my hobbies, geekery and exercise, using my Raspberry Pi and the Strava API.  I've extended this by creating a capability to use Strava API data to see if I am getting fitter through exercise activities.

One key part of this is having an exercise regime that is repeatable in a controlled fashion to allow the likes of me, who lacks an exercise lab, to do some analysis.  With half a mind on the geek potential it provided, back in September I started to do HIIT sessions using the same bike setup and the same exercise protocol.

Now generally I am skeptical of exercise fads but HIIT:
  • Seemed to have a number of reputable scientific studies backing it.
  • Enabled me to fit in sessions in very short time windows.
  • Is very basic, no HIIT specific equipment provided so no one trying to sell you kit or DVDs or exercise programmes.
So my bike is setup on a turbo trainer and I always have it in the same gear and on the same turbo resistance setting.  I know that things like tyre pressure could vary (thus changing rolling resistance) but by and large the conditions are similar.

I have a heart rate monitor and speed/cadence sensor on my bike so I can log these things as I exercise.  I don't have a fancy-dan power meter.

My exercise regime is as follows:
  • 4 minute warm up
  • 6 lots of flat out for 20 seconds followed by 10 seconds rest.
  • 3 minute warm down.
...so all done in 10 minutes flat.

So in Strava I get these sort of results:


So you can see my speed and cadence peak for every interval and my heart rate increase gently during the warm-up, goes up quickly (in steps) during the flat-out periods and then drops during the warm-down.

So all good stuff but as a geek I need to know whether the results above are any better than this other session below:


Looks like a better first couple of reps but tailed off at the end.  The Strava UI didn't seem to give me a good way to compare and contrast my ~20 HIIT sessions so I decided to find a geeky way!  A quick look at the Strava API documentation showed that there is a "laps" resource in the API so I decided to use it as my Garmin logs each section of the HIIT activity as a lap.

First you identify the Strava activity in question by listing all activities:

https://www.strava.com/api/v3/activities?access_token=<your token here>&per_page=200

You then list the laps for a specific activity using this URL:

https://www.strava.com/api/v3/activities/331779633/laps?access_token=<your token here>&per_page=200

Which gives you easily parsable json output like this (just 2 laps shown for clarity):

[{"id":744754123,"resource_state":2,"name":"Lap 1","activity":{"id":331779633},"athlete":{"id":4309532},"elapsed_time":240,"moving_time":241,"start_date":"2014-11-18T19:49:59Z","start_date_local":"2014-11-18T19:49:59Z","distance":1527.27,"start_index":0,"end_index":36,"total_elevation_gain":0.0,"average_speed":6.4,"max_speed":6.7,"average_cadence":69.1,"average_watts":70.7,"average_heartrate":85.2,"max_heartrate":116.0,"lap_index":1},{"id":744744535,"resource_state":2,"name":"Lap 2","activity":{"id":220668522},"athlete":{"id":4309532},"elapsed_time":20,"moving_time":19,"start_date":"2014-11-18T19:54:04Z","start_date_local":"2014-11-18T19:54:04Z","distance":245.38,"start_index":37,"end_index":45,"total_elevation_gain":0.0,"average_speed":12.3,"max_speed":12.4,"average_cadence":124.5,"average_watts":320.2,"average_heartrate":134.8,"max_heartrate":148.0,"lap_index":2}

So for each lap you get a range of interesting information such as:
  • average_cadence
  • average_watts (which I assume to be estimated as I don't have a power meter)
  • average_heartrate
  • max_heartrate
So for every HIIT session I've done I've given it a name in Strava using the format "HIIT YYYYMMDD" so it was easy to write some PHP to:

  • List all activities and put the resulting json into an array.
  • Loop through the array and pick out each of the HIIT activities.
  • For each HIIT session, call the API to get lap resource information.
  • Parse the json to pick out measurements for each lap.
  • Print the results into a web page.

Full code listing is at the bottom of this blog post.  The output I get within a browser window is shown below:


So a very raw CSV print out of 3 key metrics per lap.  So I could easily take this CSV data and pull it into Excel for data analysis.  For example I could put together this graph showing average cadence per lap:


So laps 2,4,6,8,10 and 12 are the laps where I put in a lot of effort for 20 seconds.  (Lap 1 is warm up, lap 13 is the final 10 seconds after a hard effort 6 and lap 14 is warm down).

I first put this graph together a couple of weeks ago and one initial observation was that in previous HIIT sessions that was a lot of variance, both within a session and from session to session. This was because I had no real targets for hard efforts, I just did it as hard as I could and held on for the last couple of efforts.  Hence in the last two weeks I've focussed on doing "tighter" sessions where the target is 130rpm across all the efforts. You can see this on the graph where there's much less of a spread from lap 2 to lap 12 and they're clustered in the 120 to 135 range.

Next: More HIIT sessions, more analysis and attempting to draw graphs on web page rather than nasty old Excel.

Full code (remember I'm new to PHP):

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Weeks Family Strava Fun</title>
    <link rel="stylesheet" type="text/css" href="/stylesheet/style1.css">
  </head>
  <body>
   <!-- Get the value from Strava-->
   <?php
     //Use cURL to get the value from Strava.  Max 200 actvities per file.  After that will need to play with pages...
     $curl = curl_init();
     curl_setopt ($curl, CURLOPT_URL, "https://www.strava.com/api/v3/activities?access_token=<your token here>&per_page=200");
     curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
     $result = curl_exec ($curl);
     curl_close ($curl);
     $json_a=json_decode($result,true);
     //Good debug code
     //foreach($json_a as $num)
     //{
     //print $num[start_date]."-".$num[name]."-".$num[type]."-".$num[distance]."-".$num[total_elevation_gain]."-".$num[average_speed]."<br>";
     //}

     //Now itterate through the main results, picking out the HIITs and summarising them
     foreach($json_a as $num)
     {
       if (substr($num[name],0,4) == "HIIT") //Check for HIIT sessions
       {
       //This is an entry with a HIIT
       $hiitNameDate = $num[name].",".$num[start_date_local].",";
       //Download the associated lap
       $activityNumber = $num[id];
       //Form the URL
       $lapURL = "https://www.strava.com/api/v3/activities/".$activityNumber."/laps?access_token=<your token here>";
       //Do cURL with this URL
       $curl = curl_init();
       curl_setopt ($curl, CURLOPT_URL, $lapURL);
       curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
       $lapResult = curl_exec ($curl);
       curl_close ($curl);
       //Turn into an array we can parse
       $json_b=json_decode($lapResult,true);
       foreach($json_b as $lapNum)
         {
         echo $hiitNameDate.$lapNum[name].",Ave Cadence,".$lapNum[average_cadence]."<br>";
         echo $hiitNameDate.$lapNum[name].",Ave Heart,".$lapNum[average_heartrate]."<br>";
         echo $hiitNameDate.$lapNum[name].",Max Heart,".$lapNum[max_heartrate]."<br>";
         }
       }
     }
   ?>
      <h1>Summary of HIIT Activity</h1>
      <p><?php echo $hiitSummary ?></p>
    <p>Warning: This only shows a max of 200 Stravas!  Will have to play with  pages after that...</p>
  </body>
</html>