A new Garmin Communicator plugin

As part of my plan to create a workout editor, I had to look into the method of communicating between the Garmin plugin and the browser.

It feels like a Java application. It’s documented like it, too. But, it’s written in Prototype, and includes a whole stack of other tools, like XML handling, Ajax communication, and messaging. Things that should belong in seperate parts, IMHO.

So, after a fair bit of plugging around, I was able to make enough sense of it to figure out exactly how it works:

  1. You unlock the plugin with a key-pair
  2. You get a list of devices
  3. If this is a send, then you set the value of a certain property.
  4. You start an Async communication.
  5. You poll the ‘finish’ version of that communication.
  6. When the communication is finished, if this was a receive, you load the data from a property.

I understand why they have made the plugin handle it’s communication in an async manner, but seriously: why not allow for a callback function when the communication is finished? To me, that feels like it would make so much more sense.

Anyway, my other main criticism is that it is inherently unsafe for multiple operations. Instead of, as would be possible with a callback that gets executed when the communication is finished, returning the data, it puts it into a property within the plugin. Which does mean that any bit of code can read it, but also means it’s possible to accidentally overwrite it, as the same property is used for writes.

So, the API for replacing it looks more like:

var plugin = new Garmin.Communicator();
plugin.selectDevice(0);
plugin.readActivities(function(data) {
  // data contains the XML activity data.
});

It’s actually a little more complicated than this: we can pass in delegates, that will have callback methods called when certain events occur. These events are also pushed (using jQuery) onto the HTML element that is the plugin object. But, due to a jQuery bug, you need to listen further up the chain: so you can listen for these events on body.

This script will also add the plugin to the page if it cannot find it, and will run as a singleton: calling the constructor a second time will return the original object, but also add a new delegate to the list of delegates.

I’m tempted to remove the delegate handling, and simply have it as callback-based, but this is sort-of a transition from the way the Garmin team have done it. I’m concerned there may be issues with non-UI initiated read/write events (ie, those that happen on page load) ‘beating’ the plugin being ready, but that is a job for another day.

I’ve also written some Knockout bindings for this: but those are not quite ready for public consumption. I may actually write parsing code for the Training Center Database XML file, and the types it contains, and include that with this project. But, then I may be approaching the bloat seen in the actual Garmin plugin. At this stage, if you have a server that accepts TCX files, then this should be enough.

The project is on BitBucket, as usual: garmin-plugin.

Belair Hill Climb

Since I bought my Garmin Forerunner 405cx in November 2010, I’ve gradually gotten more and more into running. Having a computer that tracks when, where, and how fast I run appeals to me, and has probably been the biggest motivator to me running as much as I do now.

I was tracking my running using Garmin Connect, but recently, thanks to my good friend Travis, got hooked on Strava. The key feature for me is the segments, and how competitive they enable me to be. Mostly against myself (my hard running occurs on the same track each week, which no-one else using Strava seems to have discovered).

Technically, I’m in training for this year’s City to Bay, although that is a long way away, so I’m spending the time working on getting faster over that type of distance. Last year I finished in 1490th place, with a time of 00:54:43. My target time had been 00:54:00, so I was a little disappointed to miss that by such a short margin. I did speed up a little too early (2km out), which nearly killed me, and I needed to back off. Also, I was absolutely exhausted by the end.

In fact, if I look at my performance, at the 47 minute mark I sped up, increasing my pace from 4:30 to 4:00 min/km, and promptly had to slow to a walk. There may have been some dry retching going on there too.

So, I set a target time for this year’s race of 00:48:00, with the possibility of reducing that to 00:44:00 if I could get to my target time 12 weeks before the race. Now, it does occur to me that my target pace is the one that forced me to stop early last year, but I think I’m already in much better shape now than I was then.

To improve my speed, I determined that first I needed to reduce my heart-rate. In last year’s City to Bay, my heartrate was basically in the Threshold zone (Z4) for the entire race. It did get a little higher when I sped up, but otherwise was fairly constant, which means I probably did run that race as fast as I could have then.

So, my training plan of late has been to run a lot more with my HR in zone 3, and see if I can get my speed up. So far, it seems to be working. I’ve been doing lots of 30 and 60 minute easy runs, where my Forerunner will beep at me if I get my HR above Z3. I’m finding that lately I’ve been running at around the same pace, but find my HR sometimes dips below Z3, so perhaps I can speed up a little.

Tonight, I ran faster up the Belair Hill Climb than I had ever done so before. Not only that, but each Strava segment was faster, too. More importantly, my Strava “Suffer Score” was only 44, as compared to a 62 on my previous PB up the hill. When done, I was all primed to then run some more hill climbs (6x600m uphill), but it started to rain, and it was time for dinner.

Perhaps the only thing that’s missing from Strava for me was the ability to track my weight: Garmin Connect has it’s “Health” tab, which enables you to enter a weight manually, or accepts data from a supported scale. This information is useful to me, as I can see that my weight increased significantly over the leadup to NTL, where I was training much harder, but obviously bulking up a bit too. Lots more speed and strength work there: I do recall having pants that no longer fit my thighs. I’m now down to 78.1kg, after a high of 84.6, and I’d love to be able to import this data into Strava too.

Something that even Garmin Connect doesn’t do, and which I need to keep Garmin Training Center around for is the advanced workouts. Oh, you can enter them into Garmin Connect, but the interface is slow and clunky, and I was never able to get more than one to upload to my watch at a time. Not that useful when I was in a more free-form mode, and would pick workouts based on how I felt. Now, I have a pre-programmed schedule for the next 20-odd weeks, all stored in there. I think I’ll look at a web-app that improves on the process though, as GTC is a bit rubbish.

Oh, and I have my eye on the Garmin Forerunner 610. Not sure when I will get around to upgrading. The 405cx still works really well for my needs, but there are a few nice new features in the 610.