-->

11.03.10

Categories: Data visualisation, Flash

Hacking Nike Plus – part 1

I love my Nike Sportband. As a training aid, it meets my needs perfectly, small and light, and readable as a stopwatch while out running. I used it extensively in training for last year’s London Marathon, where I was regularly doing 3 hour long weekend training runs, and a number of shorter, faster runs during the week.

sportband

The Sportband records your runs onto its flash drive, which are then automatically uploaded to the Nike Plus site when you plug the Nike Sportsband into the USB of a PC or Mac running the NikePlusUtil.

nikeplus_01

nikeplus_02

nikeplus_03

The key areas that I feel could be improved are:

  1. For individual runs, better definition of where you ran faster and where you ran slower
  2. More accurate split times, eg each km, or each mile.
  3. Better transitions between displays of data.
  4. Over a period, whether that be for a week, or a month, better comparison and a better sense of your progress.
  5. With these improved analyses, better goal setting that isn’t just about logging miles.
  6. API, encryption and security.

Getting started

I first started by seeing what information I could get out of the Sportband by itself. The answer is not alot.

Unlike with the Nike+ iPod connector, it is not possible (as far as I know) to retrieve the data of your workouts without first uploading it to Nike Plus. The device is recognised by the computer as a Human Interface Device, in the same fashion as a keyboard or mouse, rather than as a USB drive. Using an app like iHid for the Mac reveals only information about the device. Run data is deleted from the device once it has been uploaded to Nike Plus.

However, it is not mandatory to only use the Nike Plus web site to view your run data. It is possible to access your workout data, once it has been uploaded to Nike Plus. There is a semblance of an API that lets you retrieve data about your runs via HTTP requests. It’s not exactly public, and there’s no official documentation, which means that it is subject to change at no notice, but it seems to be happy to return results regardless of where it is called.

For Nike+ with an iPod, it is possible to retrieve run data without first uploading your run to Nike Plus. However, the since the Nike Plus API is doing most of the heavy lifting for us, it makes sense to work with it. While I managed to figure out this just by looking at the Activity Monitor of Safari to see what requests were being passed, there is some good work online from people such as Eric Wroolie and Paul Richards. There’s even a Wordpress plug-in (untested by me as yet) which enables you to display your runs within a Wordpress blog. However, as the Nike Plus site URL’s and the API seem to have changed at certain times, there is no guarantee that these will still be working.

Data mining Nike Plus

Run data on Nike Plus seems to be accessible to anyone, if the user has made their run data publicly accessible. Looking at a URL, for instance:

http://nikerunning.nike.com/nikeos/p/nikeplus/en_GB/plus/#//runs/history/417671841/

You can see all my runs over history. The number 417671841 is my userID, putting another userID can pull out someone else’s data, eg 955634643 is another valid ID.

You can find out your own userID by logging in to the Nike Plus site.If you click the link to “All my Runs”, it will direct you to :

http://nikerunning.nike.com/nikeos/p/nikeplus/en_GB/plus/#//runs/history/417671841/all//
The number is your userID.

You will need to make sure your privacy settings allow the data to be accessed outside of the Nike Plus site:

http://nikerunning.nike.com/nikeos/p/nikeplus/en_GB/plus/profile?page=privacy_settings

I used the Activity Monitor in Safari to see the requests that are being made to the Nike server. There are a number of .jsp requests that grab the data which is then parsed by the Nike Plus flash application.

Looking at the activity monitor shows a number of jsp calls used to retrieve data, eg:

http://nikerunning.nike.com/nikeplus/v1/services/app/run_list.jsp?userID=417671841

This retrieves all runs by a user, me

Doing a view source on this data shows that this is an XML file. Each individual run is given a runID, such as 1211505962

Again, looking at the activity monitor shows that the data for the individual run is retrieved from a query of the format:

http://nikerunning.nike.com/nikeplus/v1/services/app/get_run.jsp?id=1076405728&userID=417671841

where the ID is the run ID.

Looking at the source of this data again reveals the XML structure of an individual run. There’s a lot of empty tags in there, such as BPM which indicate possible future Nike products such as integrated heart-rate monitors, or may be used by Nike+ iPod connector but not the Sportband. As well as the actual run data, there is additional data that might be added by the user once uploaded to Nike Plus, such as how they felt, weather condiitions, terrain, and other notes.

The key data is the snapshots, of the time at each mile and each kilometer. There is also the extendedData which consists of distances recorded every second. My guess is that this is probably the raw data that the Sportband generates.


<?xml version="1.0" encoding="UTF-8"?>
<plusService>
  <status>success</status>
  <sportsData>
    <template>
      <templateName>
        <![CDATA[Basic]]&gt;
      </templateName>
    </template>
    <userInfo>
      <weight>80.0</weight>
      <device>SportBand</device>
      <empedID>4H811T0EVSX</empedID>
    </userInfo>
    <runSummary hasHRS="false" workoutType="standard">
      <distance>18.8589</distance>
      <duration>5189000</duration>
      <calories>1563.0</calories>
      <equipmentType>sportband</equipmentType>
      <heartrate>
        <average>0</average>
        <maximum>
          <bpm>0</bpm>
          <duration>0</duration>
          <distance>0.0</distance>
<pace>0</pace>
        </maximum>
        <minimum>
          <bpm>0</bpm>
          <duration>0</duration>
          <distance>0.0</distance>
<pace>0</pace>
        </minimum>
      </heartrate>
    </runSummary>
    <batteryLifetime>0</batteryLifetime>
    <startTime>2009-01-29T07:26:30+00:00</startTime>
    <snapShotList snapShotType="userClick">
      <snapShot event="stop" id="661803145">
        <distance>18.859</distance>
        <duration>5189000</duration>
<pace>275148</pace>
        <bpm>0.0</bpm>
      </snapShot>
    </snapShotList>
    <snapShotList snapShotType="kmSplit">
      <snapShot event="" id="661803146">
        <distance>1.0</distance>
        <duration>275000</duration>
<pace>210190</pace>
        <bpm>0.0</bpm>
      </snapShot>
      <snapShot event="" id="661803147">
        <distance>2.0</distance>
        <duration>541000</duration>
<pace>245222</pace>
        <bpm>0.0</bpm>
      </snapShot>
      ....
    </snapShotList>
    <snapShotList snapShotType="mileSplit">
      <snapShot event="" id="661803164">
        <distance>1.609</distance>
        <duration>443000</duration>
<pace>294266</pace>
        <bpm>0.0</bpm>
      </snapShot>
      <snapShot event="" id="661803165">
        <distance>3.219</distance>
        <duration>848000</duration>
<pace>245222</pace>
        <bpm>0.0</bpm>
      </snapShot>
      ....
    </snapShotList>
    <extendedDataList>
      <extendedData dataType="distance" intervalType="time"
intervalUnit="s" intervalValue="10">
0.0000,0.0204,0.0612,0.1019,0.1427,
0.1835,0.2175,0.2515,0.2990,0.3330,0.3738,0.4010,
0.4213,0.4553,0.4961,0.5369,0.5776,0.6048,0.6388,
0.6796,0.7136,0.7543,0.7951,0.8359,0.8767,0.9107,
0.9379,0.9854,1.0194,1.0602,1.1010,1.1417,1.1621,
1.2029,1.2369,1.2777,1.3253,1.3592,1.4000,1.4408,
1.4680,1.4884,1.5292,1.5631,1.5971,1.6379,1.6855,
1.7263,1.7602,1.8010,1.8350,1.8826,1.9234,1.9641,
1.9981,2.0389,2.0797,2.1205,2.1680,2.2020,2.2428,
2.2836,2.3244,2.3651,2.3991,2.4399,2.4739,2.5147,
2.5554,2.5962,2.6370,2.6710,2.7050,2.7457,2.7865,
2.8273,2.8681,2.9089,2.9428,2.9836,3.0312,3.0720,
3.1060,3.1535,3.1875,3.2283,3.2691,3.3167,3.3506,
3.3914,3.4322,3.4730,3.5138,3.5477,3.5953,3.6293,
3.6633,3.7041,3.7448,3.7584,3.7992,3.8400,3.8740,
3.9012,3.9215,3.9215,3.9487,3.9894,4.0302,4.0642,
4.1118,4.1525,4.1933,4.2205,4.2477,4.2953,4.3157,
4.3632,4.4040,4.4448,4.4788,4.5264,4.5671,4.6079,
4.6283,4.6691,4.7099,4.7506,4.7846,4.8254,4.8662,
4.9070,4.9477,4.9885,5.0157,5.0565,5.0973,5.1244,
5.1652,5.2060,5.2468,5.2876,5.3283,5.3555,5.3827,
5.4235,5.4711,5.5050,5.5526,5.5866,5.6274,5.6682,
5.7157,5.7497,5.7837,5.8177,5.8585,5.9060,5.9468,
5.9740,6.0078,6.0486,6.0826,6.1234,6.1709,6.1981,
6.2457,6.2797,6.3205,6.3612,6.3952,6.4292,6.4768,
6.5108,6.5515,6.5787,6.5991,6.6331,6.6739,6.7147,
6.7487,6.7894,6.8370, ....</extendedData>
    </extendedDataList>
    <bestComparableRun/>
    <name/>
    <description/>
    <signatureValidationStatus>0</signatureValidationStatus>
    <howFelt/>
    <weather/>
    <terrain/>
    <isHumanRaceRun>false</isHumanRaceRun>
    <isFirstHeartRun>false</isFirstHeartRun>
    <intensity/>
<previousRun id="1411967596"/>
    <nextRun id="808019914"/>
  </sportsData>
</plusService>

Pulling out the runs for a particular period, you can use startIndex and endIndex parameters.

http://nikerunning.nike.com/nikeplus/v1/services/app/run_list.jsp?userID=417671841&startIndex=20&endIndex=40

Building an initial data parser

As it’s XML, we can do what we want with it, and choose whatever technology to parse the data and display the results. I’m going to stick with Flash, and see if I can work on some of the aspects listed at the beginning of this article.

I first created a classes to import the data for all runs, display a summary, and then import the run data for a selected run.

Here’s an initial AIR app which retrieves all the runs for a userID (by default it has my user ID), and then grabs the run data for an individual run once clicked upon. It’s not possible to run as a Flash movie within a browser due to Flash security restrictions (on which more in part 2).

Nike+ Parser

I used the ISO8601Util class from Brooks Andrus to help display the date in a more user friendly way, though some more date manipulation is still required.

So far, so good. In Part 2, coming shortly, I’ll look at how we can work with the Nike Plus data, to create a class for individual runs, and see what we can do to create new visualisations and transitions.

Share your love for this story

  • Print this article!
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks

8 Comments

  1. Hi, this is pretty cool. did you ever figure out if its possible to feed the data back to Nike+. For example, if it loaded the wrong number of miles, and i’d want to change it?

    Thank you!
    marina

    Marina 24.04.10
  2. Marina, thanks, we’ll be adding the second part soon. We’ve not uncovered any part of the API that allows edits to be fed back into the Nike+ system, that would be pretty cool though. If you are using an iPod (ie not a Sportband), it is possible to amend the data before it is submitted to NikeRunning, but as far as I know, once it’s been uploaded, it can’t be changed.

    We’ll keep on digging.

    Marty 27.04.10
  3. adding data back to nike+ is really simple. all you need is your iPod with paired sensor to your account. The next steps is simple. the XML file you get from data mining process (link http://nikerunning.nike.com/nikeplus/v1/services/app/get_run.jsp?id=1076405728&userID=417671841) you have to put on your iPod. Easily save this file from Safari (File/Save as…) and save it like XML (or then change the extension from .html to .xml).

    In Finder enable Show Invisible Items (or Show Hidden Files) – use google how to do it. Next open iPod from Finder, and go to folder Ipod_Control/Device/Trainer/Workouts/Empeds/”folder with ID of your sensor (is only one)”/latest/

    and put your XML file into it.

    Then unplug your iPod, wait a few seconds and then plug it again. The run will be synced to nikerunning.com!

    Enjoy :)

    palo 11.05.10
  4. Thanks Palo, that’s really good info. Hopefully we’ll be able to add an ‘update run’ feature to the app I’m creating, for users with Nike + iPod & iPhone 3GS.

    Marty 12.05.10
  5. thanks so much palo! i corrected an erroneous record in iPod nano & uploaded to nike+ in 10 minutes. you saved my 7.2 km! =)

    jackie 20.06.10
  6. oh, also, if there’re already records on your iPod nano, you don’t even need to do data mining to find the xml files, they’re already there, most likely in the /synched folder. you do need to turn on the hidden files to see them though. i used houdini for that.

    jackie 20.06.10
  7. [...] 100 Beginner Runing Tips (CompleteRunning.com) How To Start Running Without Feeling Like A Failure Hacking Nike Plus, Part 1Creating Your Own Nike Plus Sensor holder in any running shoe sole Nike Plus Sensor Mod [...]

    Vibes and Scribes » Blog Archive » 1st Run – Nike+ iPod (Nike Plus) 10.07.10
  8. Hi
    I got your parser to work but it didn’t show splits or anything for runs recorded on an Ipod Touch. Only date, distance, duration, and calories.

    Am I doing something wrong?

    Stew 08.08.10

Have your say

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>