Saturday, 26 September 2015

Cadence Analysis Using Fitbit API Per Minute Data

Arghhh - the curse of my injured calf muscles has struck again :-(.  Avid Geek Dad blog readers will remember how back in 2013 I used a Raspberry Pi camera to video myself and spot calf injury causing strength in-balances between my left and right sides.

Well the injury is back and a visit to a specialist gave me two tips as to what to do to resolve the problem:

  1. Strengthen my calf muscles.  Depressingly as a gentlemen such as myself enters middle age he will generally lose 10% of muscle strength per year.  Hence I need to work ever harder to keep my muscles strong and injury free.
  2. Shorten my running stride.  Video analysis showed I was over-striding; my front foot was landing in front of my hip putting extra strain on my calf muscles for every stride.  

When it comes to strengthening, that's fine.  I just need to do more heel raises etc.

It's shortening my running stride that has the best geek potential.  Optimally my foot should land under my hip and apparently the best way to do this is to increase my running cadence, i.e. take shorter steps but do more of them.

So the challenge is to increase my cadence but what's the baseline here?  What do I do naturally and by how many should I increase this?  Sounds like I need some data...

As described in previous posts, I've got a Fitbit Charge HR and can use the Fitbit API to access my data.  The plan was to use Fitbit activity data (specifically steps data) to see how many steps I'm taking during specific runs.  Initially this looked to be a non-starter as:

  1. The API by default only gives you daily data.
  2. The only data analysis tool provided by Fitbit only provides data for 15 minute intervals (see below).

...however I needed per minute data (as cadence = steps per minute).


The answer came from the Fitbit API online documentation set.  Specifically that if you request it, Fitbit will allow people to "intraday" data via the API.  Apparently they look particularly favourably on people looking to use data for personal projects.  A quick email interchange later with the awesome people from Fitbit and I had access to delicious per minute data.

So an example URL to access the one minute step data resource is:
https://api.fitbit.com/1/user/-/activities/steps/date/2015-07-11/1d/1min/time/09:00/09:30.json

What I did find is that the Python Fitbit API wrapper that I'd previously used didn't work when trying to access this resource; the Python script threw an error every time.  Hence I had to work out how to directly access the API.

This tool provided by Fitbit provides a step by step guide to accessing the Fitbit API via OAUTH 1.0.  The final step allows you to formulate the API call to be made and even specifies the cURL command to use (which I executed with my Raspberry Pi).  Typical API output is:

{"activities-steps":[{"dateTime":"2015-09-26","value":"4761"}],"activities-steps-intraday":{"dataset":[{"time":"09:00:00","value":108},{"time":"09:01:00","value":169},{"time":"09:02:00","value":154},{"time":"09:03:00","value":56},{"time":"09:04:00","value":10},{"time":"09:05:00","value":43},{"time":"09:06:00","value":158},{"time":"09:07:00","value":173},{"time":"09:08:00","value":173},{"time":"09:09:00","value":175},{"time":"09:10:00","value":175},{"time":"09:11:00","value":174},{"time":"09:12:00","value":173},{"time":"09:13:00","value":171},{"time":"09:14:00","value":174},{"time":"09:15:00","value":175},{"time":"09:16:00","value":171},{"time":"09:17:00","value":174},{"time":"09:18:00","value":172},{"time":"09:19:00","value":174},{"time":"09:20:00","value":171},{"time":"09:21:00","value":171},{"time":"09:22:00","value":171},{"time":"09:23:00","value":172},{"time":"09:24:00","value":173},{"time":"09:25:00","value":174},{"time":"09:26:00","value":170},{"time":"09:27:00","value":173},{"time":"09:28:00","value":173},{"time":"09:29:00","value":154},{"time":"09:30:00","value":107}],"datasetInterval":1,"datasetType":"minute"}}

So you get a summary then one data point per minute for the time period specified.  Now in the 10 minutes I gave it I tried to work out how to programatically create the URLs to be used to pull back multiple results from the Fitbit API.  The API is non-trivial (you have to compute a HMAC of the fields you specify and add it to the URL) so, with all that sumptuous geek data waiting for me I wimped out and just used the Fitbit tool to extract all the data I needed (bad geek).  I'll crack it one day and write a blog post on it.

To the analysis!  As a creature of habit I've run the same 5K run at the same time on Saturday morning 18 times this year.  (It's Parkrun - I recommend doing it if there's one near you).  I've worn my Fitbit for nearly everyone of these so getting the API data should provide me with a reliable source of cadence information.  I simply changesdthe data criteria, fired a load of API calls using cURL and stored the results in an Excel spreadsheet.  So that this isn't a totally code free post I did write some Excel VBA to pull out the steps into individual cells so I could graph the results.  Here it is:

Option Explicit

Sub SplitAndWrite()
  Dim i As Integer
  Dim GeekString As String
  Dim MyArray() As String
  Dim WriteRow As Integer
  Dim SplitItArray() As String
    
  WriteRow = 5
  
  GeekString = ActiveSheet.Cells(1, 1).Value

  MyArray = Split(GeekString, ",")
    
  For i = 0 To UBound(MyArray)
    If InStr(MyArray(i), "value") <> 0 Then
      'This be a value entity.  Split on the colon
      SplitItArray = Split(MyArray(i), ":")
      If InStr(SplitItArray(1), "]") = 0 Then
        ActiveSheet.Cells(WriteRow, 1).Value = MyArray(i)
        ActiveSheet.Cells(WriteRow, 2).Value = Left(SplitItArray(1), Len(SplitItArray(1)) - 1)
        WriteRow = WriteRow + 1
      End If
      
    End If
  Next i

End Sub

So I extracted, parsed and graphed 9 runs worth of data.  Here's the resulting graph:


Here you can see:
  • Seven runs prior to when I saw the specialist where my cadence was in the 160 to 170 range and generally diminished during the run.
  • The first run after seeing the specialist (pink series at the top) where I consciously tried to increase my cadence but didn't use anything to aid this and so saw a fast start (180 steps per min) but the usual decrease during the run.
  • The second run after seeing the specialist (green series) where I used a simple metronome app on my phone (I listened using headphones) set at 175 beats per minute.

As can be seen, using the metronome provided the best result.  It was weird listening to it going click, click, click but I soon managed to work out how to run in time with the metronome.  It also resulted inconsistent splits of ~4m50s per KM and no calf muscle pain.  Next week I'll try and increase the  metronome frequency and see what happens to the splits...

So big-up the Fitbit API and per minute data.  Fingers crossed it will really help me in my quest to cure my old man calf muscles....