Latitude is (almost-)dead – how do I go on?

I’ve espoused the virtues of Latitude as it relates to my Home Automation obsession.  While Google’s Location service once provided a critical means to validate home/way state, it was always critical in the determination of “occupant prediction” – that is, setting up a home-automation posture in anticipation of homeward-bound residents.

It’s no news anymore that Google is shuttering Latitude on August 9th.  It’s something that I predicted on my twitter feed, and I wasn’t alone in feeling that the end was near.

Google attempted to placate the masses by adding a Location feature to Google+, but from a developer perspective it was the retirement of the Latitude API that hurt the most – never mind the giveth/taketh soreness that has come out of Google’s decision to maintain Location History but close it off to 3rd-party developers going forward.

Whatever.  That ship has sailed (or soon will).  The bigger question for me was – how the heck do I keep location-awareness as a staple in my home-automation system?

I was pretty sure that 3rd-party solutions would crop up, ala the Google Reader debacle.  But unlike RSS feeds, there’s something very personal about location data.  Obviously I was (am) placing a large amount of trust in Google to hand over my location data to them, but I was very loathe to do the same for any other entity on the face of the planet.

So I enlisted my go-to man Tasker to fill the void.

Tasker always had a close relationship with Latify on my smartphone.  Tasker would determine which of three Latify profiles were most suitable at any given time.  So it wasn’t a huge stretch to rip out Latify and have Tasker poll location itself, sending that information to my home server so it could Do Something(tm).

And in a nutshell… that’s all there is to it.  With the help of the Tasker App Factory, I’ve produced an .apk that’s been installed on the wifey’s phone and – voila – the home automation system will remain location-aware after August 9.

So that’s part one.  And a very important part it is.

Part two encompasses what to do about sharing location information with friends, whcih is what one traditionally thinks of when they think of Google Latitude.  And in all honesty, I’ve only ever really seen that as valuable in the context of family, where each member probably wants to know where the other is for safety reasons.  To that end I whipped together a page on my intranet which takes Tasker’s reported location data and puts it on a lovely map.  As with all things intranet, this page is accessible from the Internet at large – for authorized users – and works on a laptop as well as it does on a smartphone.  It uses the Google Maps API for all the map-py stuff, AJAX so that locations update dynamically, and it’s generally Very Cool(tm).

So there it is – I’m quite happy with the current solution.  So a heartfelt “Thanks!” to Google for $crewing developers the world over once again.

Wifey say, wifey do: zone drag/drop active

I don’t really know what to say about the titles that I come up with.  I mean, they’re my ideas, so I can’t sit here and shake my head in disbelief or some mild form of pity.  But really, what the heck does this one mean?

Well, at least the second part is fairly self-explanatory – to a degree.  It’s now possible to drag-and-drop an album or song directly onto a zone while in the browse view.  The idea is that you can queue up – or begin playing – an album/song without going through the steps that previously existed (and still exist) to perform this apparently arduous task.

Yes – “apparently” – and this is where the first part of our interesting title is explained.  One day, a long long time ago, Shelly said that it really should be possible to drag-and-drop an album onto a zone.  I believe that I was in the midst of showing her the ability to drag-and-drop an album/song onto the working list and have the item added to the list.

I’m not sure what prompted her to make this suggestion.  The thing is, the drag/drop facility is only available on platforms that support dragging – like a laptop or desktop – and not at all on platforms like smartphones which have no concept of how to perform a drag/drop action.  And – you guessed it – Shelly users her smartphone to interact with the system.

Nevertheless, I said “yes ma’am” and eventually got to work.  And the fruits were fully realized today (well, a couple of days ago but polished a bit today) with code that makes Shelly’s suggestion a reality.  As I said, from the browse view, you can drag an album/song over the existing play icon, which will cause a popup to be dynamically created containing all of the zones.  Finish the drag/drop operation by dropping the album/song on one of these zones, et voila, Something Happens(tm).

That “something” is dependent on a few things.  For an unloaded/unlinked zone, the operation will always end with the zone being shown and playback started.  Depending on your prefs, you may be asked if you want the zone to be linked.

For a zone that is already linked, the operation will cause the dragged item to be added to the linked list.  You remain on the browse view, but there is a helpful popup that says “Added” just to confirm that, indeed, Something Was Done(tm).

Now, the 5-billion-dollar question is: is this really necessary?

Well let’s look at the title for the most obvious answer: Wifey say, wifey do.  Wifey said “Do it”, and now wifey can do it.  Easy breezy.

Okay, how about a more general discussion?

I’ll oblige.  If you have the ability to perform this drag/drop operation, then you have the ability to use the other nifty features presented by the interface – most notably, the ability to take advantage of dynamically-loaded popups and inline information.  Previously – and currently – the steps to play an album or song (we’ll just say an “entry”) could most easily be performed by clicking the popup icon for that entry, clicking the play icon in the resulting popup, and then clicking the zone in the resulting zone list that got dynamically loaded into the popup.  This operation would always result in you getting transferred to the zone, where playback would have been started.  In the case of a zone that was previously linked, the linked list would be overwritten (unless the list was not an auto-generated linked list – in which case you’d get an error).

So if anything, that’s three clicks and waiting around for two dynamic operations to complete (the popup and the inline zone list) before anything could happen.

With the new drag/drop ability, you really only click once and you have to wait for one dynamic operation to complete – ie, the popup containing the zone list.

So from that point of view, I suppose I can agree that the new method is indeed more efficient.  I have to wonder how many times in one session a user is likely to load an entry to a zone – or in other words, how much impact this increased efficiency would have in the real world – but I suppose one can’t argue when it comes to the inherent goodness that is “increasing efficiency”.

But wait… perhaps there’s more to this.

What really makes this worthwhile is that the code is linked-status-aware.  Meaning, it does different things depending on the linked status of the destination zone.  This was alluded to earlier, but allow me to focus on it in more detail.

While it’s all well and good to drop an album on a zone and call it a day for the next 60 minutes, what happens if you’re putting together a 4-hour playlist of albums – or a 60-minute playlist of songs?  Now we’re no longer talking about loading a single entry to a list.

The previous (and still existent) optimal method for doing this would have been to create a new playlist and select it as the working list – or perhaps to load the first entry to the zone, then select the resulting list as the working list.  This doesn’t always work well if you’re working with albums, as the system isn’t guaranteed to create a linked list for a single album depending on how your prefs are set.  But supposing that it’s set appropriately, either of these methods would get you pointed in the correct direction.

Then, you could drag/drop additional entries to the list – or use a pulldown, or a checkmark,  or whatever other method you liked.  But the point is that you’d want to select the list that ended up getting linked to the zone of interest.  Or, if you manually created the list, then you’d select this list as the one that you will eventually load to the zone of interest.

With this new method, the only thing you need to know is what zone you want to work with.  You could have an entirely different list selected, or no list at all.  The list is not important – only the zone.  So the new sequence of events becomes: drag/drop an entry to the zone, return to your browse results, and drag/drop more entries to the zone.  The backend will take those additional entries and add them to the list associated with the zone.

You can see that this method offers clear benefits.  Again, there’s no need to work with or even know which list is linked to the zone.  This is especially useful if your current working list was used as part of the criteria in your current search.  Changing your working list to become the linked list would alter your search results, which may make it difficult to select more entries to add to the working list.

But most crucially, you get to take advantage of the increased efficiency that we discovered previously.  Yes, you could already drag/drop entries onto your working list – ie, the same efficiency that drag/drop onto a zone offers (better efficiency in fact, since there’s even less dynamic loading going on) but again, this only factors in if you select the linked list as your working list.  Now, even without selecting the relevant linked list, you can drag/drop and end up at the same place.

So ya, that’s cool.  I did some initial work in the backend to allow the user to drop a search result onto a zone as well.  I don’t have  draggable defined for this, but once I define one then it should Just Work(tm).  Truthfully it would also be nice to be able to drag/drop multiple items at once.   This may be straightforward for the backend to handle, but I imagine the frontend would need some serious work.  I’ll hold off on getting that going, but I suppose it is a project to look forward to.

From a technical point of view, I will say that getting this to work took a few days, but the hooks were mostly present to make it all go.  The stuff that I added amounted to handling a new breed of popups, which are non-modal and presented more as a menu anchored by an element on the page.  This comes with the need to define a relationship to that anchor, manage timers (which close the menu appropriately), clean up everything when a drop occurs or a drag is cancelled, and defined special “action” elements to overcome z-index issues.  The action elements – “actionables”, as I call them – were already necessary for regular drag/drop operations (again, due to z-index issues) but needed to be extended to work with menu-ish popups.

C’est tout.

In-car USB flash drive vs. in-car A2DP

Last time I was here I talked about a custom modification that I had made to GSPlayer – an MP3 player on my WinMo smartphone – to allow limited, transparent control of a Home Audio streaming zone from within GSPlayer itself.  And it has proven quite handy.  The first trial went well, but then I was dismayed to discover that the stream was skipping.  It wasn’t happening regularly, and it would only skip for about 0.5 seconds each time… but it was enough to be noticeable.

I was beginning to wonder if perhaps this was the main reason why I had switched from GSPlayer to PocketMusic.

Perhaps I’d have to dig into the code.  But after thinking about it overnight it dawned on me that this may be a simple buffering issue.  It wasn’t behaving strictly like a buffering issue – the display wasn’t showing that the player was rebuffering, and it wouldn’t make sense that it would take 0.5 seconds to rebuffer each and every time – but what the hey, I figured it was worth a shot.

So I up’d the buffer from 128k to 1024k (1MB) and that seems to have fixed it 🙂  The prebuffer is still 32k so playback begins just as quickly as before.

Anyhow, everything up to this point has been a digression.  But I mentioned it all because; 1) it’s related, and (2) when taken with the real intent of this article, it serves as a nice illustration of the logical progression of this sort of project.

So… here’s what happened last Friday.

I left work, and decided to play some songs off the flash drive.  But after 5 minutes or so I decided that I would rather listen to the queued tracks on a streaming zone.  So I connected my phone to home and started playback, only to realize that music was coming out of the phone’s speaker itself…???  As it turns out, the USB drive was still plugged in under the armrest meaning the Bluetooth music gateway was not.

Well that certainly sucked.  And while it would have been physically possible to remove one and insert the other, there were two overriding thoughts which nagged me incessantly:

1) Those cables are inconvenient to reach, especially when driving

2) Why should I have to physically switch anything???

So on that Friday I decided to listen to nothing at all for the duration.  But the experience served to solidify and accelerate an idea I had from the very moment I decided to power the gateway off the USB port – which was, to split the port so I could power the gateway and leave a flash drive connected at the same time.

Normally you’ll find USB cables that wire two ports in parallel for the purposes of drawing combined current from both ports.  Only the power wires are connected together; the data wires are connected to one port only.  This allows you to connect devices that might exceed the 500mA that a single USB port can provide.

In my case, I needed a cable that could take one port and split the power to two USB devices, while again providing data connectivity to only one of those devices.  And I figured I’d be okay in the power department, since people regularly power USB hard drives off their BMW USB ports without issue; certainly a lowly flash drive and bluetooth A2DP adapter would be less power-hungry than a hard drive.

After looking around for a suitable cable it became apparent I wouldn’t find one.  I would have to make one myself.  And while I had a spare USB-to-mini-USB cable that I could hack (which would provide power to the A2DP adapter via mini-USB) I had no USB cable with a male plug on one end and a female receptacle on the other.

As luck would have it, I found just such a cable this weekend… for $2!  Perfect price.

So I spliced in my other cable and I’ve now got a 6″ USB extension with a spliced-in 2.5′ cable ending in a mini-USB connector.  I did multiple tests along the way to make sure that everything would work.  And once in the car, everything worked.

One comment I have to make – the wires inside said cables are t-i-n-y.  I had to use an X-acto knife to slice the sheathing off, and in 10 cuts I think I managed to sever one strand.  And because the wires were made up of 5 or 6 such tiny strands, I had to tin them with solder.  After twisting them together I soldered them again to solidify the splices, wrapped each splice individually in electrical tape, and then wrapped the whole shebang with more tape.

So there it is – I can play tunage off the flash drive or off the phone without having to reach under the armrest.

The particular flash drive I’m using – an 8GB Kingston C10 that I scored for $20 off Dell – is loaded with all the tracks from my “fav’s” list on the Home Audio system.  Syncing the two is fairly trivial, and in the process the system generates genre playlists since… well, I’ll explain.

Some of my tracks have “compound” genres.  For example: “R&B/Reggae”.  While the car has the ability to read these genres, the problem occurs when such a track is not listed in the R&B genre or the Reggae genre.  Personally, I’d want it to be listed in both.

The solution therefore was to gen my own playlists – which the car can read – and make sure that the track is listed in both playlists.  Done – this occurs during the syncing process.  This also allows me to group other genres – Dance, House, Techno, Electronica all get grouped as Dance – so that I can play them all while still keeping the original genres intact (and indeed, the sync will gen playlists for the original genres but name the playlist as, say, “Dance (House)” for house tracks)

So that’s cool.  But you know me, always wondering what the next step can be.

Here’s the thing – the car can control iPod’s and, apparently, certain other MP3 players.  How does this work, this “control”?  For the iPod I believe it’s a special set of code specifically designed to work with the iPod and act as an interface for the iPod.  But for all other devices, the car looks at the device as a storage container housing tracks.  Those devices can either be a Mass Storage device – so, a USB flash drive – or they can be a Media Transfer Protocol compliant device.

The difference between the two is  down to semantics, at the higher level at least.  Again, the car sees both as a storage of files.  In the case of Mass Storage, the device is a drive that the car mounts.  When you want to play a track the car opens the file and reads the data off the drive.  In the case of MTP, the car queries the device via MTP commands; when you want to play a track, the car asks the device for the data and the device sends it over.

So you can see that, to the end user, they both seem to operate the same way.  And indeed, the iPod appears to as well.  But the iPod’s interface is proprietary, and there may be more going on than I’m aware.

Actually I’m guessing about MTP as well, but it’s an educated guess.  And here’s where the magic would happen:

Unlike Mass Storage, there’s no reason why the files on an MTP device have to be on the device itself.  When the car queries for a list of tracks, or genres, or whatever, the MTP device can act as a mere proxy and query some other device for that info, then report back to the car.  When the car wants to play a track, the MTP device proxies the file from some other device and feeds the data back to the car.

Surely you see where I’m heading.  A full blown, customized implementation of this protocol would have me plug my phone into the USB port, then have an application that talks to the car via MTP on one “side” and on the other “side” it talks to my Home Audio system via VPN over 3G.  All of the constructs – albums, songs, playlists – exist on the Home Audio system.

That’s not the approach I’d take though, if only because I can just imagine what would happen trying to proxy metadata for 30,000 tracks.  Rather, you’d likely proxy metadata for a single playlist, or perhaps for the playlists only.  Something like that.

But the whole point of the exercise would be to provide a seamless way to connect back to the Home Audio system and use the car’s media system to playback songs and browse the collection.  Imagine seeing my list of fav tracks on my I-Drive screen, being pulled in realtime from my network at home.  With MTP this would be possible!

How much work is required?  Well, I can wrap my head around the concept and interaction of all the moving parts.  The good news is that we wouldn’t need to worry about decoding/encoding MP3 in the app, since we’d just be proxying song data.  The great unknown is the amount of work (or feasibility) of coding a WinMo app that can take over the USB port.

Useful, or crammed?

New article on Piper’s Pages:

Something was bothering me with my fancy-shmancy AJAX/DHTML popups in the Home Audio interface.

It manifested itself mostly when adjusting track BPMs for a new album.  Basically, one has the ability to browse on an album’s tracks, then get the track popup for any particular track and – using forward/back navigation in the popup – move around the browse entries via the track popup.

This is cool in practice.  You can see more detailed deets for browse entries (as well as options like track suggestions) and quickly compare between tracks by clicking prev/next.  No need to display the popup, close it, then display the popup for another track in the results.  Same goes for albums, of course.

So when BPM’ing an album, I had two options: 1) use the quick-edit links so that I could get the edit popup straight from the browse results, or (2) display track details and use the edit link from the popup which then loaded the edit popup.

It was kinda nice using the second option, because sometimes you don’t need to edit the BPM and you can just next-next-next through the entire list – no need to scroll the list, figure out which track you’re working on, then click to get the details popup or the edit popup.

BUT… sometimes you’re not sure if the BPM that’s in the DBMS is correct, you want to use the edit popup so that you can tap out the beats and see if it’s a match.  If it’s a match, you close the edit popup – but the entry doesn’t highlight since you didn’t change anything, so you lose visual reference as to where you are in the list.

You could use the details popup, then go to the edit popup, but same problem – once you closed the edit popup you were back to a list of tracks with no visual reference as to what you last looked at.

And this underlined a more general problem – with all these dynamic popups, what happens if you want to go back one popup?  What happens if you want to display the details popup, then the edit popup, but then go back to the details popup so you can “next” to the next entry?

One way to do this is to keep a history in the backend of popups you’ve looked at.  Problem is – and this has cropped up before – the application is purposely free-flowing, and you can have multiple windows/tabs open all using the same session (sharing the same search history, context, etc.)  If you’ve got popups going in two windows, the history will be intermingled and thus useless.

So I took a different approach.  Instead of a popup yielding more popups, I decided that additional popups could be dynamically loaded into the first popup.  So for example, you get track details in a popup, then click to edit BPMs and the edit dialog is loaded into the current popup rather than appearing as a new popup.  Submit your changes and the main popup remains.

Works a treat.

The only problem is that the popup is meant to be somewhat small relative to the main interface, and when we start dynamically inserting some of these other popups – ie, the zone selector – the popup gets to be a little large and looks a little “crammed” – hence the title of this article.  But I think that’s a small price to pay for the increased usefulness (again, linking back to the title of this article), and I can probably make it more palatable with careful application of visual styling elements (via CSS).

Yup, so that’s that yo.

I also added the ability to start a new search using a popup – not just a saved search as before, but actually specifying search conditions.  Not all of the fields are displayed in the popup as they are when you actually navigate over to the search page, but in concert with dynamic search fields it offers a handy way of firing off a quick search.

Werd up.

Eat my shorts! AJAX drag-and-drop baby!

New article on Piper’s Pages:

In my neverending quest to learn (everything?) AJAX, I decided to dip my fingertips into the pond that is drag-and-drop.

Probably the most famous of AJAX techniques, it allows you to grab something on a page and move it somewhere else – either because you like to assert your creativity, or because you want to Do Something(tm) (like add an item to shopping cart).

Well ladies and gents, we’ve taken our implementation of drag-and-drop to a Whole New Level(tm).

You may recall that we’ve had AJAX popups for ages now (ages <= 1 year) and you could grab those popups and move ’em around, just cause they might be covering stuff you want to see. Cool, but… that didn’t DO anything really.

So here’s what I envisioned.

I envisioned an interface with multiple panes – one for browsing, one may contain a zone, and another may contain a list. It would be wicked and wild if you could drag an album on your list or onto the zone to queue that album.

This obviously requires more kung-fu than just moving popups around the screen.

So…. if I’m not mistaken I’ve been using Scriptaculous for the popup dragging, and after trying to bake my own more-advanced solution I realized that Scriptaculous could do what I wanted (and it was even using the same terminology I was using – “draggables” and “droppables”).

So the first crack at this yielded the ability to drag stuff from the browse view onto the link that indicates your working list. That causes the album/song to be added (or removed) from said list, which also happens to flick the checkmark for that item (this happens as a result of existing code).

Okay, so that’s cool I guess, but said checkmark could simply be clicked to achieve the same results. Nothing really new here folks, so move along!

My pleasure. My next effort was to enable drag-and-drop table reordering. Currently, in list view, you’ve got teeny weeny icons that you can use to move a row up or down, one at a time. Sure, you can select a bunch of rows and move them all up or down at once, but again they’ll move one at a time.

With these handy dandy scrolling tables, it sure would be nice to grab a row by the scruff of its neck and manhandle it into a new position, right?

Yes, it would. And while Scriptaculous provides an easy breezy way to get this done, fact is that my implementation of dynamic tables is slightly incompatible with Scriptaculous. If I had to actually take time to explain why, I would say that it has to do with my padding process – which means that in any given table, some of the rows have actual data and some do not. I use different DOM ID prefixes to track this, but even if I used a seperate array to do the same thing I’m pretty sure we’d run into context issues: does it make sense to reorder a row that hasn’t been filled in yet?

Sure, the way I’m registering draggable items means those rows wouldn’t be considered draggable by Scriptaculous until they were force-fed useable data by backend, but… why are you trying to convince me to use Scriptaculous for this??? Look, the fact is I wanted to keep my DOM ID convention, and I don’t like the way Scriptaculous reports the new ordering to the backend. When you’ve got a table that can contain, oh, 30000 rows the last thing you want to do is iterate through a serialized list of row IDs and tell a DBMS to reorder based on that list. Ugh.

So I baked my own solution, which was based on the work I did (and partially abandoned) for effort 1.

And… it works!

At least in Firefox. It looks like it wants to work in Chrome and Opera, but I’ve got stoopid text selection issues to overcome still. But at least the concept works, and admittedly it’s quite handy.

So ya – drag-and-drop/table-reordering with backend updates. Funky fresh.