Saturday, May 23, 2009

iPhone as a Universal Remote Using SqueezeBox Duet Controller IR

After the grand machinations I described in my last post to enable me to use Apple's Remote iPhone application to control music around my house through the SqueezeBox Duet Receiver, a commenter pointed out the then-new iPeng application. That app lets my iPod Touch directly control SqueezeCenter on my PC to manage my various SqueezeBox Receivers, and is exactly what I was pining for. In the ensuing months, I transitioned exclusively to using the iPeng application, which left me with the question: what do I do with my now oh-so-dusty SqueezeBox Duet Controllers.

The answer was easy once I took a closer look at the hardware of those controllers... something I'd not noticed before jumped out at me: an Infrared (IR) transmitter! The IR transmitter in its shipped configuration doesn't do anything -- an intron component -- but thanks to Google and various threads like this one on the slimdevices community forums, I discovered that there is rudimentary driver support for the IR device and some trivial samples of using that device. Given that I already knew the controller runs a BusyBox-based embedded Linux, I knew how I'd challenge myself that evening --- no turning my Sony IR-controlled TV on until I could do so from my PC!

I spent the next while reading a bit about Infrared signalling protocols and conventions, and then I built a trivial little script that just called the Duet Controller's /bin/testir via ssh with a command line full of hex codes that I carefully crafted based on my new-found partial competence. I announced to the room "Here we go!" as I dramatically pressed [Enter]......

Nothing.

I rinsed and repeated many times, alternating between worry that the degrees of freedom in command specifications were too great and celebrating short-lived epiphanies that narrowed that search space dramatically. Finally, I decided to pay more attention to the "repeat" parameter that the Linux Infrared Config files mention in passing -- that some devices only recognize an IR command when sent two or more times juxtaposed. I saw that my Sony LIRC file used that option, so I doubled the hex codes corresponding to the command part in the line I was trying, and gave a surprisingly hopeful and still dramatic "And then there was..." as I once again lowered my hand onto [Enter]....

POWER!

The hum of my (awesome, but now 6 years dated) Sony HD CRT Monitor warming up was music to my ears! How cool! With that magical ~200 character command line, I then knew that I could use the SqueezeBox Duet Controller as the IP-controlled IR transmitter portion of an iPod-Touch (or iPhone) Infrared Universal Remote solution!

The rest of the path was simple compared to the reverse-engineering and experimental IR learnings. I educated myself on Lua and Jive (now known as SqueezeOS), the embedded programming language and the Framework, respectively, used by the SqueezeBox controllers. Then I set out to code a small Lua applet to run on the controller. I called it IRServer and the design was simple: an HTTP-like server that just accepts simple commands on a TCP port, strips them of their HTTP artifacts (if any) and issues the appropriate os.exec call to run the C program that drives the IR device driver. By making the server understand HTTP just enough, I knew I could even just write a static HTML page that issued commands when links or buttons were clicked (e.g., just requesting an Image object at a URL corresponding to the command I wanted to issue to IrServer).

I spent a good part of the following weekend pulling the above little design together, along with a simple Perl script that takes a set of Linux IR Config files and turns them into HTML with a link per defined IR button (don't worry, links on that page won't control my devices when you click -- the page assumes you're on the LAN with the controller). I even played around with IUI, the iPhone User Interface framework, and started making a much more iPhone-friendly UI for a bunch of the devices in my living room.

Of course, the good news is I put this project -- IrServerSB (SB for SqueezeBox) -- up on code.google.com. The README file at http://code.google.com/p/irserversb/wiki/IrServerSBReadme has more information about how to try it, and I've set up a Google Groups mailing mailing list (or use the code project page, or comments here) for feedback.

The better news will be if others from the community can take this the rest of the way towards being a complete solution. In particular, RC5/RC6 remotes are reportedly not supported by the Jive IR platform and I can confirm that numerous attempts to turn on my RC6-controlled XBox 360 left me without a satisfying Eureka moment. I'd love to have that supported, and perhaps even build the server as a background-running C server.

Enjoy!