Wednesday, January 16, 2013

Tri-Replicator - free app on google app engine

I am lazy and try to avoid doing things that I do not *absolutely* have to do. I guess this is not unlike most people. Especially I do not like doing the same thing twice when I know it could be done once. Where am I going with this you ask?

USA Triathlon runs a winter competition for athletes, but this one is unusual. It is all done via Internet and people compete by entering the amount of swim, bike and run miles they did in training. This is quite funny because in a real race it does not matter how far you ran over the past year, or how much you biked and swam. All that matters is your performance on a race day. This USAT competition is called USAT National Challenge Competition (NCC). The goal is to motivate folks to maintain active lifestyle over cold months of winter. People must enter their training miles into the USA website and can see where they are relative to other athletes.

The problem is that most athletes already enter their miles into the special sites, and the most popular one is Trainingpeaks.com. In fact, I do not even enter my miles manually. I just upload  my workouts right from the Garmin GPS Watch and it automatically adds them to the training log on the trainingpeaks website.

The idea of entering my training miles by hand into yet another website was not very appealing, so I decided to write a program that would automatically copy my data from one website to another. Sounds familiar? Yes, this is what I do for work. I sell IBM WebSphere integration software. The problem I faced with this NCC for the winter could be solved by integrating two websites.

I decided to create a program that would automatically take my data from one site to another. After some further consideration I decided other folks would like to use that too. After all, there are 4,000 plus people participating in this NCC this winter. I am guessing about half of those folks are using trainingpeaks. Assuming 4 minutes per person per day entering data manually into USAT site, times 2,000 people, times 3 months, times 30 days, divided by 60 minutes in 1 hour: 4*2,000*3*30/60=12,000 hours.  WOW. If I made this application available on Dec 1, I could have saved 12,000 hours of triathlete's time (about 6 hours per person for entire winter). This is definitely worth a try!

Here is the final version up and running on the google app engine: https://tri-replicator.appspot.com.




Where to run it?


Since the application had to be available for anyone to use, I needed a runtime environment outside of my home network. After looking around, I decided to use Google App Engine as it offers up to 5 million requests per month for free, supports Java runtime, offers nice Eclipse plugin, etc. Hosting cost would be $0. Nice.

As I was learning specifics of Google App Engine, GWT, etc. I found EXTREMELY useful free online resource - check it out. There are many great tutorials - very well written, all work and get you started very quickly.


How to access sites?

Trainingpeaks.com has a well defined API. In fact they offer full WSDL with SOAP-HTTP and also simple XML over HTTP API. I used Jersey REST and JAXB to access and parse data from the trainingpeaks site.

USAT NCC site does not have any API and is only available via their old-looking HTML interface. After googling around I decided to use open source HtmlUnit library. It made it quite easy to parse HTML from USAT site and convert it into my own Java Plain Java Objects (POJOs).


Where and how to store data?

I needed to keep user accounts, passwords and a history of workouts that have already been replicated. For that I decided to use google database which offers JPA API and is well supported. I also used Java Cryptography Extension (JCE) to encrypt user data stored in the database, and encoding that data as Base64. I had to use secret key for encryption as building PKI or other advanced security measures seemed like a lot of work. This security part was perhaps the most time consuming part of the development process. Not to mention that USAT NCC site does not even support HTTPS, so all passwords flow in clear over HTTP anyway... At least I made all access to my application forced via HTTPS.


What user interface?

For the UI I decided to use Google Web Toolkit. It comes with excellent Eclipse support, is very easy to use and quite powerful. Not having used it before, I was surprised how easy it was to learn and implement. Perhaps in the future I build an Android native UI, just for kicks.


Going social

For promoting the app, I have added Java Script from the http://www.addthis.com,  - now it shows floating social sharing buttons on the page.


Making money?

Just for the heck of it, I also added "Donate" button from PayPal in the "About" part of the app. I wonder if anyone bothers to use it? My wife bet that not a single person will contribute. I said at least one will. We shall see who wins this bet :-). This was not made to make money anyway, but I always wondered how those buttons worked as I have never used one before. Took me about 5 min to add the button to the app. This was probably the easiest part of the whole project.


Does it work?

I posted the link to the app on Facebook and a couple of forums yesterday, hoping that people will jump at the opportunity to avoid manual typing of data. It has been 24 hours and not a single person started to use the app, except for me. Hmm... I wonder if all that logic about saving 12,000 hours of people's time was flawed? ...

This USAT NCC competition runs every year, so the app can be used for many years to come. If it worked for 10 years, it can save 120,000 hours. If it worked for 100 years.......... Oh, wait, Google App Engine may not be around for that long :-), or perhaps USAT folks will bother to add this feature to their website.


What's next? Open Source it!

I suspect my assumption about half of athletes using Trainingpeaks.com to log their workouts is not entirely correct and there are many more different sites where people keep their training logs. It seems that Garmin Connect is quite popular as well. I can't build connectors to all those 3rd party websites that I am not using myself, but I architected the app in a way that it is trivial to add new connectors via generic interface I called TrainingAPI with methods like
  • void setupTrainingLog(String username, String password) throws TrainingLogException;
  • boolean login(...) throws TrainingLogException;
  • List<WorkoutSession> getWorkoutsBetweenDates(Date startDate, Date endDate) throws TrainingLogException;
  • List<WorkoutSession> addWorkouts(List<WorkoutSession> listOfSessions) throws TrainingLogException;
I think the next step is to open source the app and have other people contribute connectors, so that replication can happen between any and all systems. Say even between Garmin Connect and Trainingpeaks.com? An ESB for traininglogs, huh?

If you are interested to become a contributor to this project, add new features, connectors to other online training log systems, etc. - please let me know! 

You can find the source for the project here: https://github.com/romankhar/Tri-Replicator. Feel free to make changes to the code and contribute back to the project!

Tuesday, January 1, 2013

Training and racing summary for 2012

Happy New Year 2013 folks! What a wonderful and productive year it was. looking back, I feel like it was one of the best years of my life - in many respects it was. Especially in terms of fitness and racing. In 2012 I did two Sprint and two Olympic distance races (won overall in Sprint and Won in my age group in Olympic) - the results are listed on the RACING page of this blog. I also did MS150 ride. In 2013 plan on doing two Sprints, two Olympic and two Half Ironman distances.
This year 95% of all of my biking I did on the indoor trainer - on my recumbent Schwinn 230i bike (circa 2001) - I will post a picture of it someday. I did some 95% of running outdoors and about 85% of that on trails and off pavement. My height is 172 cm (5'7'') and weight this year was between 69 to 75 kg (152 to 165 lbs). I had no injuries this year, except for a bit of light pain and "sensations" in the right foot and knee - especially after races. Nutritionally I think I did well and made fruit and berry smoothies on my Vitamix blender several times a week. I must admit that this Vitamix is the most important "fitness" equipment I own :-).





Some additional stats for the season (Jan 1 - Dec 31, 2012):
  • total training + racing time - 541 hours
  • total bike - 6,259 miles (adjusted 10% down from trainer miles)
  • total run - 822 miles
  • total swim - 117 miles
  • crosstrain - 65 hours
  • longest swim - 3,100 yards (2 min per 100 yards average pace)
  • longest run - 13.6 miles
  • longest bike - 101.85 miles (MS150 ride)
  • longest training bike ride - 2 hr 20 min (on trainer ~45 miles)
  • Power for the 1 - 2 hours training rides was 120 to 210 Watts (on trainer)
  • best 100 yard swim - 1 min 30 sec
  • best 50 yard swim - 40 sec
  • best 500 yard swim - 9 min 10 sec
  • best run pace at Sprint tri - 6:27 min per mile  (5K in 19m 20 sec)
  • crosstraining - I usually do it in the morning before work and it takes ~25 min. I do use stability ball for abs, back, pushups and separately do pull-ups and dynamic side planks
Since most of my cycling is done on the trainer indoors, almost all of it is long steady ride with no intervals - after initial warmup of about 15 min, building up power to the steady level of 150 to 200 Watts and maintain it for the period of the ride (usually 90 min to 2 hrs), then cool down for 10 min at the end.

In  2012 I generally followed the following schedule of training and kept my log in the TrainingPeaks.com:
  • Monday
    Recovery day or light bike
  • Tuesday
    Crosstraining + bike + swim (3,000 yards, half drills and half normal swim)
  • Wednesday
    Crosstraining + bike + run (hill repeats in the second half of the year, 4-7 miles total)
  • Thursday
    Crosstraining + bike + swim (same as above)
  • Friday
    Crosstraining + bike + run (usually 400 or 800 yard intervals in the second half of the year, 4-7 miles total)
  • Saturday
    Swim (same as above)
  • Sunday
    Long run (on the trail in North Park, easy to moderate pace, 7-13 miles total)