Archive

Author Archive

Hacking Polar Watch WebSync Software

January 12th, 2010 tobint 1 comment

I recently purchased a Polar FT-40 watch to monitor my fitness level and track my workouts better. I like the watch so far although I’m not ready to give a thorough review on it just yet. Today, I received the Polar FlowLink data transfer unit that allows me to transfer the data on my watch to Polar’s website. It allows you to chart your progress and do all sorts of interesting things with the data. I was surprised how easy and smoothly the software worked. However, I wanted the data on my desktop so I could do more with it. I wanted to provide my own charts and data views in Excel. I wanted to be able to post it to my blog easily or write a WordPress widget to display my data. That said, I decided to look at what the WebSync software was written in. I had a sneaking suspicion that it might be .NET — I was right!

So, I decided to look under the hood and see if I could tackle writing my own front end to their devices. What I found should horrify anyone who has ever read past Chapter 1 of a reasonable “C#” book.

I started by pulling in the obvious assemblies to see what was built. The project looked reasonably well built. There was enough evidence ot see that there was at least SOME design put into the application. I even found some tests in tone assembly — at least there were some tests (checked that off on their requirements eh?). When I took a look at the EXE, however, what I saw shocked me. So I started drilling down into WebSync.exe. I found a Polar.WebSync.Program class with a static Main() method. Bingo – my entry point. I immediately saw some minor concerns. For instance, they were using a Mutex to provide the functionality of a Singleton pattern. Worse yet, they were calling GC.KeepAlive() on the Mutex. Interesting. They did, however, have what looked like an external exception reporting framework, so that at least gave me SOME hope.

I found Application.Run that was starting a new WebSyncTrayForm() so I naturally followed to the form constructor. In a big Try/Catch block (with no code executing in the “catch” portion), I found a TextBox-style TraceListener was added to the form — mmkay. That’s a decent idea I suppose, but let’s look at the form’s Load event. Oh my! I closed my eyes and looked again. I closed then and then looked one more time. Oh, these folks must have written some VB code with “DoEvents” called more than a few times in their past history. Tell me what you see wrong with this:

WARNING: Not good example code!!

private void WebSyncTrayForm_Load(object sender, EventArgs e)
{
    base.Visible = false;
    this.notifyIcon.Tag = this.notifyIcon.Icon;
    this.toolTip = this.notifyIcon.Text;
    this.notifyIcon.Text = this.toolTip + "\n" +
        Resources.StatusInitializing;
    this.timerDaemon = new Timer();
    this.timerDaemon.Interval = 0x2710;
    this.timerDaemon.Tick += new EventHandler(this.timerDaemon_Tick);
    this.timerDaemon.Start();
    this.timerDaemon_Tick(this.timerDaemon, EventArgs.Empty);
}

Seriously? These guys set up a timer, and then start it, and then MANUALLY call the Tick function they just set up! (how do they know it hasn’t been executed already between the start call and a thread interuption that might have caused the Tick event to get executed next.

Then I looked at the tick event and I couldn’t believe what I was seeing.

WARNING: Not good example code!!

private void timerDaemon_Tick(object sender, EventArgs e)
{
    this.retryCount++;
    try
    {
        if (this.retryCount == 6)
        {
            this.timerDaemon.Interval = 0xea60;
        }
        this.mounter = new WristUnitListener();
        this.mounter.WristUnitMounted +=
                new WristUnitConnectionEventHandler(this.WristUnitMounted);
        this.mounter.WristUnitUnmounted +=
                new WristUnitConnectionEventHandler(this.WristUnitUnmounted);
        this.mounter.Start();
        this.DoInitialConfig(null);
        this.timerDaemon.Stop();
        this.timerDaemon.Dispose();
        this.timerDaemon = null;
        this.notifyIcon.Icon = this.notifyIcon.Tag as Icon;
        this.notifyIcon.Text = this.toolTip + "\n"
                + Resources.StatusRunning;
        Trace.WriteLine("Connected to Polar Daemon.", "WebSync");
    }
    catch (ConnectionException exception)
    {
        if (this.retryCount < 6)
        {
            Trace.WriteLine(
               string.Format("Couldn't connect to Polar Daemon ({0})",
                              exception.CodeString),
                             "WebSync");
        }
        if (this.retryCount == 6)
        {
            Trace.WriteLine(
               string.Format("Couldn't connect to Polar Daemon ({0})",
                             exception.CodeString),
                             "WebSync");
            Trace.WriteLine(
               string.Format("WebSync couldn't initialize properly." +
                             "Please check that Polar Daemon service is running.",
                              new object[0]), "WebSync");
            this.notifyIcon.Icon = Resources.IconExclamation;
            this.notifyIcon.Text = this.toolTip + "\n" + Resources.StatusInitError;
            this.notifyIcon.ShowBalloonTip(0x2710, Resources.ToolTipProblemTitle,
                              Resources.ToolTipInitError, ToolTipIcon.Warning);
            this.notifyIcon.BalloonTipClicked +=
                new EventHandler(this.notifyIcon_BalloonTipClicked);
        }
    }
}

OK. These guys are on crack! They have a retry counter that apparently will never be more than 1. Because the tick event will go away and there is no loop in this code, the retryCount will always be 1 (taking note that they decided to start with a 1-based counting system rather than zero because n-1 is a bit complex). That at didn’t stop them from checking to see if it was equal to 6, and if so, changing the interval.

In the tick event, they create a new instance of a WristUnitListener and hook up events to it EACH time. They call start on the WristUnitListener instance and then STOP the timer and dispose of it! Never mind the fact that this timer execution is owned by the main thread rather than the timer tick function — when a timer stops itself, disposes of itself, and then nulls itself, it’s time to reevaluate your understanding of background-thread polling. This is insane! I have no idea how this even works. I can only hope that, as I dig in further WristUnitListener actually works the way it is supposed to and the only thing that sucks is the WebForms code.

Update January 13th, 2010 1:15AM PST:

I was able to successfully hack around with the API and get data off the watch with little effort. The trick was to working around some wonky and non-working APIs. To their defense 1) this API and software has to work with multiple watches 2) wasn’t intended to be consumed by other devs 3) was written with interop for the native libraries accessing the hardware, 4) does show signs of some intelligent thinking (although does need considerable amounts of re-work). As you can see by the image, I can even pull the bitmap logo off of the watch and, if I so desire, set it.

This is far from complete but I will work it over some this week and this weekend before publishing the source on Codeplex. Let me know if there is something in particular that you’d like to see.

Poll: Where would you categorize SQL Azure?

January 7th, 2010 tobint 1 comment

I own the sites for all of the data stack on MSDN. I’m trying to categorize the SQL Azure technology where it makes the most sense to put it. I can obviously categorize this under SQL Server (as it currently sits), or I can move it to the Azure development center. Obviously I can link to it from either place, but I’m trying to decide where it belongs in the overall scheme of things. Your thoughts are appreciated. Vote, comment, do whatever you want, but please speak up and retweet this (link above) so others can too!

If you had ONE BUCKET to categorize SQL Azure, where would you put it: SQL Server or Azure?

View Results

Loading ... Loading ...

Thanks for your assistance!

Categories: technical Tags:

Life hack: Getting better gas mileage

January 5th, 2010 tobint 3 comments

On my way to a metric-based lifestyle, I started taking a closer look at my gas mileage. This was a metric that I have been collecting for a while and thought I should be able to improve rather easily – lending itself to improved daily discretionary spending.

I recently purchased a 2010 Ford Fusion Sport. According to Ford’s specs I should be getting 18mpg in the city and 27mpg on the highway. I’ve put 11,000 miles on my car in 6 months – most of them highway driving so I should be getting near that top MPG range in this car. However, I rarely broke 300 miles on a single 17.5 gallon fuel tank (I usually filled up with 14-15 gallons). In fact, most of my fuel-ups netted me 270 miles. For the longest time, I couldn’t get above 18.x miles per gallon according to the sensor on my car. This left lots of room for improvement in a car that says it can do a lot better.

I keep a journal of my gas fuel-ups. Here are the metrics before my changes:

Avg Miles/Tank Avg Gallons/Fuel-up Avg Miles/Gallon Est. Gallons/Year* Est. Fuel Cost/Year**
272 14.53 18.71989 1282.059 $3,653.87

* Based on 24,000 miles a year (my current pace)
** Based on $2.85/gallon average price tag

I just had to do better. I used to get a thrill out of getting 300 miles out of a tank of gas. I wanted to know what it was like to get 350 miles — maybe more. Without any research on the web, I just tried a few things – things that might be common sense for others, but were just not a big deal for me. Here is what I decided to do.

No More Distracted Driving

I have a ton of gadgets that can vie for my attention while I’m driving. In the past, those gadgets would get my attention – particularly if I was in stop and go traffic. I decided to make a habit of ignoring everything but driving. After driving through three tanks of gas, I noticed that I was consistently getting around 300 miles per tank. Distracted driving seems to have cost me about 10% of my fuel efficiency!

No More Aggressive Driving

I’ve lived in a lot of big cities where it was eat-or-be-eaten when it comes to driving. Again, in stop and go traffic, I would tend to stay very close to the bumper of the next car so others wouldn’t cut me off. I made a conscious decision once again to start driving far less aggressively. I use my cruise control when I can. I stay far behind the cars in front of me. A defensive driving instructor would be proud! Oddly enough, I feel a lot less stressed when I just acknowledge that people are going to keep cutting me off and that’s ok. The result? My last two fill-ups gave me over 350 miles per tank and my current tank is on target to give me about 365 if it keeps on pace! This is amazing.

Results

I’ve nearly squeezed an extra 100 miles out of every tank just by changing driving behavior! Let’s put this in perspective. Here are the metrics after my changes (assuming I get the 365 miles out of this tank):

Avg Miles/Tank Avg Gallons/Fuel-up Avg Miles/Gallon Est. Gallons/Year* Est. Fuel Cost/Year**
357.5 14.53 24.60427 975.4406 $2,780.01

If you compare that against my previous cost, I’m on track to save $873.86 this year – and that’s if I don’t change anything else. Being that this is an iterative process, I’m going to try more behavior tweaking to try and get my MPG up.

Categories: life-hack Tags: , , ,

Life Hack: A metrics-based lifestyle this decade

January 1st, 2010 tobint 1 comment

I’ve never considered myself to be a “life hacker” by any means. I have been concentrated on my career and comfort in the past decade and that came at some great costs. So, I decided to start formulating a plan to make changes to my life based on metrics. I will become a life hacker — for better or worse.

Metrics imply measurability and that’s what I intend to concentrate on at first — things that I can measure, change behavior, then measure again. While there is non-empirical consequence to many decisions that I make on a daily basis, I decided to start here. For instance, my first metric-based decision of the decade was to avoid stopping at Starbucks this morning. I estimate that a stop at Starbucks averages 15 minutes of my time, $5 of my wealth, and a negative drag on my health (250 calories, 47 carbs, and 180mg of sodium taken from my daily allowances of those items).  A case could be made that this has decreased my momentary happiness. I’m not measuring that. In fact, I’m trying to do away with decisions based on immediacy. While my short-term aggrivation is great, I am speculating that over time this will turn into a net-positive for my happiness.

There are a lot of things that I want to change in my life this decade. But I’m going to concentrate on a few major areas, and break them down further as it makes sense to do so. Hopefully at some point I’ll be able to come up with an automated process to view my progress and give myself “triggers” to remind me when I’m slipping. Eventually, I’d like every decision I make to tigger a flurry of facts in my head before moving forward. That should also make its way into my structured planning for the day, week, month, quarter and year.

So here are the areas where I’m going to concentrate:

  • Health – I’d like to improve my health through better nutrician, exercise, and sleeping habits. I will be measuring:
    • Daily intake of calories, carbohydrates, protein, fat, fiber, sodium, and water.
    • Daily exercise in the form of pedometer-tracked steps, cardio minutes, weight lifted and reps per exercise, and stretching minutes.
    • Weekly weight
    • Hour slept and number of times I woke up
  • Wealth – I need to start planning and budgeting better. While I’m not exactly a spend-aholic, I can do better in my planning and spending decisions. I will track:
    • Monthly savings contribution as a $ amount and a percentage of income
    • Weekly investment changes
    • Daily discretionary spending
    • Quarterly credit score
  • Time – This is where I hurt the most. I don’t have enough time in the day to do everything I want. I’m hoping making metric-based decisions will free up some time and help me better plan. I will track:
    • Time spent blogging
    • Time spent learning
    • Time spent on household chores
    • Time spent commuting
  • Others – I will add additional metrics as I think of them or as I see a need to improve this process.

Obviously each of these are going to need base-lined for a month or so. I will be using whatever tools I can to accomplish this base-line. I’m planning on using an Omron HJ-720ITC Pocket Pedometer with Health Management Software to track my steps. I’m using the iPhone LiveStrong app as well as CalorieKing to track my daily nutrition and exercise metrics. I’m considering the Zeo Sleep Coach after Scott Hanselman recommended it, but for now I’ll just use some plain old pen/paper tracking, so to speak. I may also pick up on the Nike+iPhone app at some point, but not just yet.

If you are interested in tracking my progress and keeping me honest, I will be posting what I can under the “life hack” category on this site.

Happy new year everyone!

Categories: life-hack Tags: , , ,

Government:origin,growth& form in the United States

December 30th, 2009 tobint 3 comments

I received a very thoughtful Christmas gift from Kamila this year. It was a book titled “Government : its origin, growth, and form in the United States, Ohio Edition“. The book showed an amazing amount of perspective into who I am. Books are very valuable to me — particularly books of this age (printed in 1902) with regards to government.

Governement: Its origin, growth and form in the United States - Ohio EditionFirst, the book is a historical view of government in the United States. Anyone that knows me well knows this is important to me. I love history , and more specifically United States history.

Second, it was entertaining that it was an Ohio edition since that is where I grew up.

Third, I love the book’s perspective. The book still describes our founders as men with character and conviction — men who put country first. While I’m interested in truthful historical perspective, I don’t like the concentration placed solely on the negative information we can find about our founders.

For instance, I’m well aware that Ben Franklin was womanizer. I don’t overlook it. I take in Ballot insertperspective, however, with my admiration for the man. He was one of America’s biggest life-hackers in history. He was an inventor. While today LifeHacker.com might point to iPhone apps developed to improve your life, others were and still are pointing to Franklin’s inventions as aides in every day life. I also consider the fact that to the day he died many ridiculed Franklin (in spite of his obvious contribution to the country) for being an abolitionist (after owning slaves earlier in life). I admire a man who can examine his own beliefs and take difficult positions after careful introspection.

All of that points out that while I am aware of how Mr. Franklin behaved in the presence of women, I am more prone to talk about the positive. I would want me kids to emulate the positive, not the negative.

Lastly, I love this book because it demonstrates her understanding that I don’t need expensive gifts — thoughtfulness was key here. I only wish I could return that sentiment – I’m a horrible gift giver. I’ll endeavor to do better next year!

This book was the perfect gift for me. Thanks Kami!

Setting up iPhone Wordpress app

December 28th, 2009 tobint 2 comments

I am writing my first blog post from my iPhone using the Wordpress App I downloaded yesterday. It is an interesting idea to want to blog from your phone. It seems it would be good for those posts that are too big for Twitter but demand immediate blogging so you (and the rest of the world) don’t lose the thought.

I downloaded this app with low expectations. I expected to be able to view some basic settings and do some basic management from the app with an occasional blog post to boot. This appdoes all of this rather flawlessly– that is, flawlessly after you manage to get it set up properly. When I set up the Wordpress app, I used “http://” in the URL field for the setup wizard. This allowed me to log in but then gave me errors after that when retrieving data. I removed the prefix an all was well.

While typing this last paragraph I also note that typing in “http://” a message pops up asking I you need help making a link. This is a bit annoying but not too bad.

This app ha a lot of potential. The fact that it is free prevents me from providing too much in the way of criticism. I’m happy to have found the app — an to have found it suitable for my needs. You can find it at http://iphone.wordpress.org.

UPDATE: Now that the post was completed, I decided to come back here and update the site with a few missing details that I’d like to see added.

Photos:
When I blogged this, I was able to add photographs of the app to the post, but I wasn’t able to insert them where I wanted. This was a bit of a disappointment.

HTML only:
Blogging in the Wordpress app requires that you code every bit of HTML out with the exception of a few helper methods such as adding links, etc. I would like to see more helpers added that allow me to pick photos that I’ve already uploaded.

Voice Blogging:
It only seems natural that if you are using an iPhone, you might want to incorporate voice dictation. It would be nice to have the clarity of voice-to-text that Dragon Dictation has but without having to switch apps — particularly if you have helper methods. Imagine blogging by simply speaking. When you say “atch tee tee pee” the app nows to pop up the link helper. WHen you say “image source” it knows to pop up the picture selection dialog.  You could blog so quickly using your iPhone if a little effort went into this feature.

That’s all I have for now.

Categories: technical Tags: , ,

Indexers as Extension Methods?

December 28th, 2009 tobint No comments

So I’ve had this nagging issue for a little while. It’s not necessarily a huge issue because I have a workaround, but that said, it still nags at me now and again. That issue is that I cannot create an indexer as an extension method. This isn’t possible for a number of reasons that make sense, but I thought I’d blog about it anyway and solicit thoughts on the idea.

First, let’s talk about what we can do. I can create an extension method for any existing class. Let’s say I have the following class already created:

public class SomeClass{
   public int SomeProperty { get; set; }
}

 

I can then extend a List of SomeClass pretty easily like this:

public static class Extensions{
   public static string SomeListExtensionProperty(this List<SomeClass> classes)   {
      //… provide implementation here …
   }
}

 

Notice that I’ve scoped my extension to only extend a generic List of SomeClass. For instance I can do this:

var sc = new List<SomeClass>();string s = sc.SomeListExtensionProperty();

 

but I cannot do this:

var soc = new List<SomeOtherClass>();
string s = soc.SomeListExtensionProperty();

 

So what would happen if I tried to extend the List of SomeClass with an indexer like this:

public static string this[int index](this List<SomeClass> classes){
 return classes[i].SomeProperty;
}

 

We wouldn’t get past compilation. First of all, the word “this” and “static” don’t mix or tend to make sense together in most cases. That is because “this” refers to an instance of a class while “static” refers to type itself. In general, mixing these two wouldn’t make sense. That said, we already mix these two keywords when we create extension methods. So that isn’t the only reason this wouldn’t work. The next reason is that the generic List class already provides an indexer. Since you can’t override existing members with extensions, you are left without the ability to create an indexer with an extension.

Our only recourse would be to provide extension methods that provide the same functionality as a method.

public static string GetSomeProperty(this List<SomeClass> classes, int index){
   return classes[index].SomeProperty;
}

 

We can then call something like this:

var sc = new List<SomeClass>();
string s = sc.GetSomeProperty(index);

 

This isn’t quite as abbreviated as an indexer and in fact doesn’t save me anything over what I would get with the out-of-the-box generic List indexer:

var sc = new List<SomeClass>();
string s = sc[index].SomeProperty;

 

That said, the “nagging issue” is more of a request for a solution looking for a problem. Obviously indexers are great shorthand that ‘can’ provide a ‘default property’ so-to-speak. However, it is very easy to get what you want without much work.

Categories: technical Tags: , ,

Life Hack: Working around ADHD-like Symptoms

December 23rd, 2009 tobint 2 comments

For years, it has become more and more difficult for me to concentrate when I am trying to study. I try repeatedly to block everything out and just concentrate on reading a book/article/webcast, follow along with the examples, and get through the material. Each attempt fails miserably with my frustration that I got absolutely nothing done. I’ve attempted to integrate methodologies like Getting Things Done to my routine. However, all of this means nothing if I can’t even concentrate on the task GTD lays before me. I didn’t always have this problem. I stayed very focused and on task as a child. While I could easily get distracted from a task, I also had the ability to block everything out and focus like a laser on anything I wanted to. Things have changed. I’ve gotten older. My career has taken a different path. I’m in a different place. My personal life has changed drastically. I’m constantly worried about and distracted by politics. I need to make a change.

I’ve tried everything to correct my problem. People have given me recommendations41SSqGcuXbL._SL160_[1]. However there are so many issues at hand. When I’m studying, I need internet access to look up an occasional tidbit. However, internet is a huge distraction. If I open a browser, you can bet 30 minutes from the time I open it I’ll have about 10 browser sessions open with multiple tabs reading about topics I have no business reading about during my study time. I need my phone as I’m in constant contact with people I rely upon and who rely upon me. Silence is killer and the mere idea of realizing I’ve been in the same spot for an hour sends me into severe displeasure and I feel like I’m wasting the day. However, if I’m amongst people I know, I tend to want to talk to them. It’s all a disaster. I realized I needed to solve these problems so I attacked them one by one.

Desired Outcome

  1. I need internet access, but I don’t want the distraction of browsing.
  2. I need to stay in touch with people without having constant non-critical conversations interrupt me.
  3. I need to be around activity to prevent me from being stir crazy but I can’t sit around chatting with people I know all day.

Solution Proposed

  1. Go somewhere without free internet access. Use my phone to access the internet. The slower connection and smaller screen keep my browsing targeted at solutions when I need them.
  2. Turns out the iPhone is perfect for this. Since the iPhone is single-application-centric, it prevents me from getting interrupted by email and twitter. So I keep my phone with me, but I just keep my non-critical communication tools closed. Better still, I have moved all of my task-oriented applications like “Remember the Milk”, “Shopper”, “Evernote” and “Bing” on my main page of my cell phone. When I look at the phone, all the red “todo” circles showing up on the page remind me every time I open the phone that I’m on task.
  3. I go to Starbucks to study. Sounds crazy, I know, but it works for me. I have the non-specific white noise of people I don’t know chatting in the background without the temptation to join in a conversation. I’m not going stir crazy as I’m out of the house. Working on my laptop rather than my multi-screen monitor helps me stay focused on the software studying task at hand. Starbucks/AT&T charge for internet access through my laptop so I’m not distracted easily.

Implementation

So far all of my proposals have worked. I find it very natural to stay focused. If I have to “think” about staying focused, that thought in and of itself will distract me. This method currently keeps me on task without having to think about what task it is I’m performing. Too much monitor real-estate leads me to distractions and a quickly responding system leaves me to run down multiple rabbit trails. I tend to think the large number of us who claim “ADD” or “ADHD” are not inflicted with anything other than reinforcing poor habits and living years of distracted lifestyles. That said, I think it should be possible to relearn to properly focus through some hard work.

Let me know what your life hack is. How do you stay on task?

Categories: life-hack Tags: , ,

Hacking jQuery Slider into Wordpress Theme

December 23rd, 2009 tobint 3 comments

I have just finished converting most (all?) of my posts from various blogs around the intertubes into Wordpress. My previous blog on this domain was running Oxite. I created a theme called ‘Titus’ (yeah, I know) for Oxite that included a little jQuery ‘Slider’ plugin that I wrote. The control shows my last ‘n’ number of twitter posts, one at a time in a rotating fashion. I named it slider because I originally intended for the content to ’slide’ up from the bottom continuously. Instead, I decided to fade them in/out. I was too lazy to rename it after I decided on my desired effect. After moving to wordpress, I was slightly upset that I was losing my hard work. However, this was a jQuery plugin so I didn’t see why this couldn’t just plug into my Wordpress theme. I’m NOT a PHP developer, nor do I pretend to know how to do anything in WordPress. That said, I forged forward in my attempt to get this plugin working. You should see this plugin working right now on this site (unless you are reading this through RSS).

First let’s define the content of my plugin. I have a Javascript file containing my plugin, a CSS file containing the styling I’m using on the site, a little HTML markup to add my ‘placeholder’ for twitter feed, and of course the dependency on jQuery.

Installing jQuery into your Theme

First let’s tackle the jQuery item.  A current version of the Wordpress distribution includes jQuery. The trick is to include jQuery in your site. After a little investigation I found that jQuery was already ‘registered’ in Wordpress code, but does not, by default, render to the browser.  Somewhere in /wp-includes/script-loader.php you’ll find:

$scripts->add( 'jquery', '/wp-includes/js/jquery/jquery.js', false, '1.3.2');

This line registers the script we want in a dictionary with the key ‘jquery’. After digging further, I found a funcation called ‘wp_enqueue_script’ in /wp-includes/functions.wp-scripts.php.

/**
 * Enqueues script.
 *
 * Registers the script if src provided (does NOT overwrite) and enqueues.
 *
 * @since r16
 * @see WP_Script::add(), WP_Script::enqueue()
*/
function wp_enqueue_script( $handle, $src = false,
                            $deps = array(),
                            $ver = false,
                            $in_footer = false ) {
   global $wp_scripts;
   if ( !is_a($wp_scripts, 'WP_Scripts') )
      $wp_scripts = new WP_Scripts();
   if ( $src ) {
      $_handle = explode('?', $handle);
      $wp_scripts->add( $_handle[0], $src, $deps, $ver );
      if ( $in_footer )
         $wp_scripts->add_data( $_handle[0], 'group', 1 );
   }
   $wp_scripts->enqueue( $handle );
}

I put two-and-two together and with a little trial and error, I added the following line to /wp-content/themes/inove/header.php right before the call to wp_head():

<?php wp_enqueue_script('jquery'); ?>

This method gets the script location from the dictionary and renders a script tag with the location details.

Installing the slider jQuery Plugin

If the core did not register our script in the dictionary, we can provide the location details ourself with a second parameter. That is precisely what I needed to do to get the slider.js file added to the template. I added the following line just after the previous line I added in header.php.

<?php wp_enqueue_script('slider',
                      (get_bloginfo('template_url') . '/js/slider.js') ); ?>

The contents of this file are:

function($) {
   $.fn.twitterClient = $.fn.twitterClient = function(params) {
      var t = $.extend({}, $.fn.twitterClient.defaults, params);
      $(this).append('<ul id="twitter_update_list"><li></li></ul>');
      $.getScript("http://twitter.com/javascripts/blogger.js");
      $.getScript("http://twitter.com/statuses/user_timeline/"
                   + t.userName
                   + ".json?callback=twitterCallback2&count="
                   + t.tweetCount,
                   function() {
                      var list = $("ul#twitter_update_list");
                      stopTick(list);
                      list.items = $("li", list);
                      list.items.not(":eq(0)").hide().end();
                      list.currentitem = 0;
                      startTick(list);
                  }
      );
      startTick = function(list) {
         list.tick = setInterval(
            function() { tickFunction(list) },
            (t.delaySeconds * 1000)
         )};
      stopTick = function(list) {
         clearInterval(list.tick);
         };
      tickFunction = function(list) {
         if (list.pause) return;
         list.pause = true;
         $(list.items[list.currentitem]).fadeOut("slow",
            function() {
               $(this).hide();
               list.currentitem = ++list.currentitem % (list.items.size());
               $(list.items[list.currentitem]).fadeIn( "slow",
                  function() {
                     list.pause = false;
                  });
        });
     };
     this.each( function() {
                 if (this.nodeName.toLowerCase() != "ul") return;
                }).addClass(t.cssClass)
             return $("ul#twitter_update_list");
     };
     $.fn.twitterClient.defaults = {
         userName: null,
         tweetCount: 10,
         delaySeconds: 5,
         cssClass: "twitterClient"
     };
})(jQuery);

Next, I needed to add my styles for the twitter stream into my template. A method intuitively similar to that for scripts was found called ‘wp_enqueue_style’ that allowed me to register my CSS for rendering:

<?php wp_enqueue_style('slider',
                     (get_bloginfo('template_url') . '/js/slider.css') ); ?>

The contents of this file were:

/*ID:   slider  Elements: slider UL, slider LI, slider LI A */
#slider {
      position: relative; top: 5px;  width: 470px;  color: #bbbbbb;
}
#slider ul, #slider li{
   margin:0;  padding:0;  list-style:none;
}
#slider li {
   width:470px;  height:70px;  overflow:hidden;
}
#slider li a {
   text-decoration: none;
}

I saved the header file and closed it.

Add the jQuery plug-in Placeholder

All of our infrastructure is in place. Now I need to add a placeholder, and tell jQuery to call my plugin against the placeholder. Luckily, this style already has the ability to add content to the header region of the template. I simply went into Wordpress addmen, and went to “Current Theme Options” under ‘Appearance’ and added the following to the “Banner” section:

<!-- Slider -->
 <div id="slider"><div id="twitterClient"></div></div>
 <script type="text/javascript">
  jQuery(document).ready(function($) {
    $("#twitterClient").twitterClient({
                        userName: "tobint",
                        tweetCount: 10,
                        delaySeconds: 5
                        });
    });
 </script>
<!-- /Slider -->

I also checked the boxes above to display this content for registered users, commenters, and visitors. I saved the file header options and viewed my site. Much to my glee, everything worked just great. My next steps are to turn this into a widget so others can just add this to any registered sidebar for a given theme.

Let me know if you have any questions.

Categories: technical Tags: , , ,

Review: Bose Wave music system with SoundLink

December 23rd, 2009 tobint 5 comments

My parents sent me a Bose® Wave® music system with SoundLink for Christmas. It arrived a bit early so I took it into my office and set it up. I listen to music while writing software into the early hours of the morning. This isn’t something I would have bought for myself, but it was a well-appreciated gift as I’m listening through some small Altec Lansing speakers currently.

I took a couple of notes about the product below:

  • Aesthetics – The system looks like an oversided alarm clock. If I were frozen in the 80’s to be thawed out today, I would have reason to believe that nothing had changed as far as alarm clocks go. That said, this is more than just an alarm clock so this is slightly forgiven. I was surprised to see that the SoundLink device was an external device. It seems to me that a SoundLink receiver could easily be internalized into the main radio appliance. While the Wave music system is more than an alarm clock, you wouldn’t know that much by the clock interface on the front. The big LED numbers with an AM/PM indicator and accompanying LED indicator of the source seem out of touch with the realitiy of a device this costly in this modern era. Compare the aesthetics of this device vs the elegance of other devices costing the same. I think you’ll agree that ‘looks’ were likely the last thing on the Bose technicians’ minds.
  • Setup – This was likely one of the easiest devices I’ve set up in ages. I expected there to be, at the minimum, some software to install and some cumbersome UI to work through to get sound pumping from my computer to the appliance. This wasn’t the case. I literally plugged the power and the SoundLink device into the appliance, plugged the USB transmitter into my computer and I was off to the races! That said, I was confused why the SoundLink device had a DC power input, but no DC power cord. Perhaps there is something I’m missing in why the input is needed but it wasn’t a big deal since the system works without one.
  • Use – The appliance itself has no buttons on it which bothers me a bit. Perhaps Bose was trying to avoid the complete appearance that this was just an alarm-clock radio. That said, the concern is that if I lose my remote control, I’m screwed till I find a replacement. Since this device is sitting on my side desk (literally right beside me) the effect of using my remote control to use the device seems absurd. This wouldn’t be so bad if Bose had thought to make the remote control dockable to the system and allow you to use the remote as a front or top panel control when docked as such. Setting the time and alarms on the system is also very archaic. This uses that same tired ‘rewind/fast forward’ type alarm setting that your clock radio does — again reinforcing that this is just an expensive version of the same. Apart from that, I was happy with how easily my music just seemlessly streams from my computer to the appliance. I don’t need to configure my software. I just run my normal apps (Zune Software, iTunes, etc) and it just works!
  • Sound Quality – When I first plugged this in, I was quite happy with the sound. However, shortly into my first song, I started hearing frequent cracking and popping. I didn’t have the device cranked. I’m at work so I couldn’t possibly put it above 50% output on my computer with 30-50 on the device itself without the music starting to waft out of my office and into the hallways. That said, the cracking and popping was actually louder than the music which makes the device output more annoying than soothing. I tried listening to a variety of music from classical to heavy metal. I tried adjusting the volumn. I even tried cranking it a bit higher at other times of the night when no one else is here. No matter the volumn levels on the computer or the radio, the crackling and popping persists making this device practically useless for my purposes. Looking at the website, this appears to be a regularly enough occuring event that they included it in the FAQ. Their solution was to ‘reset’ the device by recycling the power. I tried this and the popping persisted. Lest you think this is was just a bad unit, start searching the internet for other unhappy users and you won’t have to look far. On top of the cracking and popping there appears to be an occasional ’skip’ in sound. I haven’t yet determined if this is caused by the SoundLink transmission or the radio itself.
  • Summary – The Bose Wave radio is, in my opinion overpriced for what it provides. The aesthetics are behind the times. Their is no ‘wow’ feature to the device and that unfortunately includes the sound which is the primary purpose of the system. The remote-only controll of the device is scary. There is a lot of wasted potential here.

My recommendation to you :

Buy a regular clock radio. At least if it crackles and pops, you won’t be out so much money.

My recommendations for Bose: 

  1. Integrate the SoundLink receiver into the main appliance or make it work over Bluetooth or WiFi. No reason to have a proprietary extra device just for transmission — particularly since it doesn’t appear to be doing your sound quality any good.
  2. Make the remote control dockable/lockable into the top of the system so it can be used as a front/top panel input on the device itself .
  3. Bring the front-instrumentation of the device into the modern era with some music visualization options and a less static LCD-centric display.
  4. Fix the primary purpose of the system. There is absolutely no reason why I should spend several hundred dollars to hear this when there are many other lower-cost music-listening options at my disposal.
  5. Allow me to set alarms a bit more reasonably than scrolling through a 60-minute-times-24-hour-rolling interface. Perhaps put Bluetooth (again) in the device and let me set it through my phone or computer. Or just give me an easy hour-then-minute-then-am/pm interface.
Categories: product reviews Tags: , , ,